Snap for 8730993 from 9f54fe5a3b9a93d723e320ec5e5413f55ea0e7aa to mainline-tzdata3-release

Change-Id: I4733dd9017e5e502f0bf5114a0a7dd4d4f00e21d
diff --git a/.config-device b/.config-device
index 196378e..c871d24 100644
--- a/.config-device
+++ b/.config-device
@@ -8,7 +8,6 @@
 
 CONFIG_TOYBOX=y
 CONFIG_TOYBOX_CONTAINER=y
-# CONFIG_TOYBOX_COPYFILERANGE is not set
 # CONFIG_TOYBOX_DEBUG is not set
 CONFIG_TOYBOX_FALLOCATE=y
 CONFIG_TOYBOX_FIFREEZE=y
@@ -135,11 +134,6 @@
 CONFIG_GETFATTR=y
 CONFIG_GETOPT=y
 # CONFIG_GETTY is not set
-# CONFIG_GPIODETECT is not set
-# CONFIG_GPIOFIND is not set
-# CONFIG_GPIOGET is not set
-# CONFIG_GPIOINFO is not set
-# CONFIG_GPIOSET is not set
 CONFIG_GREP=y
 # CONFIG_GROUPADD is not set
 # CONFIG_GROUPDEL is not set
@@ -150,9 +144,7 @@
 # CONFIG_HELLO is not set
 CONFIG_HELP_EXTRAS=y
 CONFIG_HELP=y
-# CONFIG_HEXDUMP is not set
 # CONFIG_HEXEDIT is not set
-# CONFIG_HD is not set
 # CONFIG_HOSTID is not set
 # CONFIG_HOST is not set
 CONFIG_HOSTNAME=y
@@ -182,13 +174,11 @@
 # CONFIG_KLOGD_SOURCE_RING_BUFFER is not set
 # CONFIG_LAST is not set
 # CONFIG_LINK is not set
-# CONFIG_LINUX32 is not set
 CONFIG_LN=y
 CONFIG_LOAD_POLICY=y
 # CONFIG_LOGGER is not set
 # CONFIG_LOGIN is not set
 CONFIG_LOGNAME=y
-# CONFIG_LOGPATH is not set
 CONFIG_LOG=y
 # CONFIG_LOGWRAPPER is not set
 CONFIG_LOSETUP=y
@@ -197,7 +187,7 @@
 CONFIG_LSMOD=y
 CONFIG_LSOF=y
 CONFIG_LSPCI=y
-CONFIG_LSPCI_TEXT=y
+# CONFIG_LSPCI_TEXT is not set
 CONFIG_LSUSB=y
 CONFIG_LS=y
 CONFIG_LS_Z=y
@@ -300,7 +290,6 @@
 CONFIG_SORT=y
 CONFIG_SPLIT=y
 CONFIG_STAT=y
-# CONFIG_STRACE is not set
 CONFIG_STRINGS=y
 CONFIG_STTY=y
 # CONFIG_SU is not set
@@ -336,7 +325,6 @@
 # CONFIG_TTOP is not set
 CONFIG_TTY=y
 CONFIG_TUNCTL=y
-CONFIG_UCLAMPSET=y
 CONFIG_ULIMIT=y
 CONFIG_UMOUNT=y
 CONFIG_UNAME=y
diff --git a/.config-linux b/.config-linux
index 0a54259..a2aab08 100644
--- a/.config-linux
+++ b/.config-linux
@@ -8,7 +8,6 @@
 
 # CONFIG_TOYBOX_ANDROID_SCHEDPOLICY is not set
 # CONFIG_TOYBOX_CONTAINER is not set
-# CONFIG_TOYBOX_COPYFILERANGE is not set
 # CONFIG_TOYBOX_DEBUG is not set
 # CONFIG_TOYBOX_FALLOCATE is not set
 # CONFIG_TOYBOX_FIFREEZE is not set
@@ -133,11 +132,6 @@
 # CONFIG_GETFATTR is not set
 CONFIG_GETOPT=y
 # CONFIG_GETTY is not set
-# CONFIG_GPIODETECT is not set
-# CONFIG_GPIOFIND is not set
-# CONFIG_GPIOGET is not set
-# CONFIG_GPIOINFO is not set
-# CONFIG_GPIOSET is not set
 CONFIG_GREP=y
 # CONFIG_GROUPADD is not set
 # CONFIG_GROUPDEL is not set
@@ -148,9 +142,7 @@
 # CONFIG_HELLO is not set
 # CONFIG_HELP_EXTRAS is not set
 # CONFIG_HELP is not set
-# CONFIG_HEXDUMP is not set
 # CONFIG_HEXEDIT is not set
-# CONFIG_HD is not set
 # CONFIG_HOSTID is not set
 # CONFIG_HOST is not set
 CONFIG_HOSTNAME=y
@@ -166,7 +158,7 @@
 # CONFIG_INIT is not set
 # CONFIG_INOTIFYD is not set
 # CONFIG_INSMOD is not set
-CONFIG_INSTALL=y
+# CONFIG_INSTALL is not set
 # CONFIG_IONICE is not set
 # CONFIG_IORENICE is not set
 # CONFIG_IOTOP is not set
@@ -180,14 +172,12 @@
 # CONFIG_KLOGD_SOURCE_RING_BUFFER is not set
 # CONFIG_LAST is not set
 # CONFIG_LINK is not set
-# CONFIG_LINUX32 is not set
 CONFIG_LN=y
 # CONFIG_LOAD_POLICY is not set
 # CONFIG_LOGGER is not set
 # CONFIG_LOGIN is not set
 # CONFIG_LOG is not set
 # CONFIG_LOGNAME is not set
-# CONFIG_LOGPATH is not set
 # CONFIG_LOGWRAPPER is not set
 # CONFIG_LOSETUP is not set
 # CONFIG_LSATTR is not set
@@ -292,7 +282,6 @@
 CONFIG_SORT=y
 # CONFIG_SPLIT is not set
 CONFIG_STAT=y
-# CONFIG_STRACE is not set
 # CONFIG_STRINGS is not set
 # CONFIG_STTY is not set
 # CONFIG_SU is not set
@@ -325,7 +314,6 @@
 CONFIG_TR=y
 # CONFIG_TTY is not set
 # CONFIG_TUNCTL is not set
-# CONFIG_UCLAMPSET is not set
 # CONFIG_ULIMIT is not set
 # CONFIG_UMOUNT is not set
 CONFIG_UNAME=y
diff --git a/.config-mac b/.config-mac
index 3770579..db2d134 100644
--- a/.config-mac
+++ b/.config-mac
@@ -8,7 +8,6 @@
 
 # CONFIG_TOYBOX_ANDROID_SCHEDPOLICY is not set
 # CONFIG_TOYBOX_CONTAINER is not set
-# CONFIG_TOYBOX_COPYFILERANGE is not set
 # CONFIG_TOYBOX_DEBUG is not set
 # CONFIG_TOYBOX_FALLOCATE is not set
 # CONFIG_TOYBOX_FIFREEZE is not set
@@ -133,11 +132,6 @@
 # CONFIG_GETFATTR is not set
 CONFIG_GETOPT=y
 # CONFIG_GETTY is not set
-# CONFIG_GPIODETECT is not set
-# CONFIG_GPIOFIND is not set
-# CONFIG_GPIOGET is not set
-# CONFIG_GPIOINFO is not set
-# CONFIG_GPIOSET is not set
 CONFIG_GREP=y
 # CONFIG_GROUPADD is not set
 # CONFIG_GROUPDEL is not set
@@ -148,9 +142,7 @@
 # CONFIG_HELLO is not set
 # CONFIG_HELP_EXTRAS is not set
 # CONFIG_HELP is not set
-# CONFIG_HEXDUMP is not set
 # CONFIG_HEXEDIT is not set
-# CONFIG_HD is not set
 # CONFIG_HOSTID is not set
 # CONFIG_HOST is not set
 CONFIG_HOSTNAME=y
@@ -166,7 +158,7 @@
 # CONFIG_INIT is not set
 # CONFIG_INOTIFYD is not set
 # CONFIG_INSMOD is not set
-CONFIG_INSTALL=y
+# CONFIG_INSTALL is not set
 # CONFIG_IONICE is not set
 # CONFIG_IORENICE is not set
 # CONFIG_IOTOP is not set
@@ -180,14 +172,12 @@
 # CONFIG_KLOGD_SOURCE_RING_BUFFER is not set
 # CONFIG_LAST is not set
 # CONFIG_LINK is not set
-# CONFIG_LINUX32 is not set
 CONFIG_LN=y
 # CONFIG_LOAD_POLICY is not set
 # CONFIG_LOGGER is not set
 # CONFIG_LOGIN is not set
 # CONFIG_LOG is not set
 # CONFIG_LOGNAME is not set
-# CONFIG_LOGPATH is not set
 # CONFIG_LOGWRAPPER is not set
 # CONFIG_LOSETUP is not set
 # CONFIG_LSATTR is not set
@@ -292,7 +282,6 @@
 CONFIG_SORT=y
 # CONFIG_SPLIT is not set
 CONFIG_STAT=y
-# CONFIG_STRACE is not set
 # CONFIG_STRINGS is not set
 # CONFIG_STTY is not set
 # CONFIG_SU is not set
@@ -325,7 +314,6 @@
 CONFIG_TR=y
 # CONFIG_TTY is not set
 # CONFIG_TUNCTL is not set
-# CONFIG_UCLAMPSET is not set
 # CONFIG_ULIMIT is not set
 # CONFIG_UMOUNT is not set
 CONFIG_UNAME=y
diff --git a/.github/workflows/toybox.yml b/.github/workflows/toybox.yml
index 7940321..1b463b2 100644
--- a/.github/workflows/toybox.yml
+++ b/.github/workflows/toybox.yml
@@ -19,7 +19,7 @@
     - name: Build
       run: make
     - name: Test
-      run: VERBOSE=all make tests
+      run: VERBOSE=1 make tests
 
   MacOS-10_15:
     runs-on: macos-10.15
@@ -33,7 +33,7 @@
     - name: Build
       run: make
     - name: Test
-      run: VERBOSE=all make tests
+      run: VERBOSE=1 make tests
 
   Ubuntu-20_04:
     runs-on: ubuntu-20.04
@@ -47,4 +47,4 @@
     - name: Build
       run: make
     - name: Test
-      run: VERBOSE=all make tests
+      run: VERBOSE=1 make tests
diff --git a/Android.bp b/Android.bp
index a8e7491..3beb024 100644
--- a/Android.bp
+++ b/Android.bp
@@ -57,12 +57,13 @@
     "lib/commas.c",
     "lib/dirtree.c",
     "lib/env.c",
+    "lib/help.c",
     "lib/lib.c",
+    "lib/linestack.c",
     "lib/llist.c",
     "lib/net.c",
     "lib/portability.c",
     "lib/tty.c",
-    "lib/utf8.c",
     "lib/xwrap.c",
     "main.c",
     "toys/lsb/gzip.c",
@@ -181,6 +182,7 @@
     "toys/other/losetup.c",
     "toys/other/lsattr.c",
     "toys/other/lsmod.c",
+    "toys/other/lspci.c",
     "toys/other/lsusb.c",
     "toys/other/makedevs.c",
     "toys/other/mkswap.c",
@@ -193,7 +195,6 @@
     "toys/other/pmap.c",
     "toys/other/printenv.c",
     "toys/other/pwdx.c",
-    "toys/other/readelf.c",
     "toys/other/rev.c",
     "toys/other/rmmod.c",
     "toys/other/rtcwake.c",
@@ -202,7 +203,6 @@
     "toys/other/swapon.c",
     "toys/other/sysctl.c",
     "toys/other/tac.c",
-    "toys/other/uclampset.c",
     "toys/other/uptime.c",
     "toys/other/usleep.c",
     "toys/other/uuidgen.c",
@@ -213,6 +213,7 @@
     "toys/pending/lsof.c",
     "toys/pending/modprobe.c",
     "toys/pending/more.c",
+    "toys/pending/readelf.c",
     "toys/pending/stty.c",
     "toys/pending/traceroute.c",
     "toys/pending/vi.c",
@@ -393,7 +394,6 @@
     "true",
     "truncate",
     "tty",
-    "uclampset",
     "ulimit",
     "umount",
     "uname",
@@ -441,7 +441,11 @@
     ],
 
     target: {
-        host_linux: {
+        linux_glibc: {
+            local_include_dirs: ["android/linux"],
+        },
+
+        linux_bionic: {
             local_include_dirs: ["android/linux"],
         },
 
@@ -458,9 +462,6 @@
                 // also getting from <sys/param.h>.
                 "-Wno-macro-redefined",
             ],
-            ldflags: [
-                "-Wl,-dead_strip",
-            ],
         },
 
         linux: {
diff --git a/Config.in b/Config.in
index 62185df..b626f3c 100644
--- a/Config.in
+++ b/Config.in
@@ -136,6 +136,12 @@
 	  Enable extra checks for debugging purposes. All of them catch
 	  things that can only go wrong at development time, not runtime.
 
+config TOYBOX_PEDANTIC_ARGS
+	bool "Pedantic argument checking"
+	default n
+	help
+	  Check arguments for commands that have no arguments.
+
 config TOYBOX_UID_SYS
 	int "First system UID"
 	default 100
diff --git a/METADATA b/METADATA
index 191882c..313792c 100644
--- a/METADATA
+++ b/METADATA
@@ -1,19 +1,3 @@
-name: "toybox"
-description: "Toybox: all-in-one Linux command line."
 third_party {
-  url {
-    type: HOMEPAGE
-    value: "https://landley.net/toybox/"
-  }
-  url {
-    type: GIT
-    value: "https://github.com/landley/toybox"
-  }
-  version: "8b97a1fb86b06e329c77c64cdbef29d7738f5840"
   license_type: UNENCUMBERED
-  last_upgrade_date {
-    year: 2022
-    month: 4
-    day: 18
-  }
 }
diff --git a/Makefile b/Makefile
index 4098702..52602d2 100644
--- a/Makefile
+++ b/Makefile
@@ -3,7 +3,7 @@
 
 # If people set these on the make command line, use 'em
 # Note that CC defaults to "cc" so the one in configure doesn't get
-# used when scripts/make.sh and such called through "make".
+# used when scripts/make.sh and care called through "make".
 
 HOSTCC?=cc
 
@@ -19,7 +19,6 @@
 .PHONY: clean distclean baseline bloatcheck install install_flat \
 	uninstall uninstall_flat tests help change \
 	list list_working list_pending root run_root
-.SUFFIXES: # Disable legacy behavior
 
 include kconfig/Makefile
 -include .singlemake
@@ -41,13 +40,13 @@
 bloatcheck: generated/unstripped/toybox_old generated/unstripped/toybox
 	@scripts/bloatcheck generated/unstripped/toybox_old generated/unstripped/toybox
 
-install_flat: toybox
+install_flat:
 	scripts/install.sh --symlink --force
 
-install_airlock: toybox
+install_airlock:
 	scripts/install.sh --symlink --force --airlock
 
-install: toybox
+install:
 	scripts/install.sh --long --symlink --force
 
 uninstall_flat:
@@ -65,7 +64,7 @@
 
 clean::
 	@chmod -fR 700 generated || true
-	@rm -rf toybox generated change install .singleconfig*
+	@rm -rf toybox generated change .singleconfig*
 	@echo cleaned
 
 # If singlemake was in generated/ "make clean; make test_ls" wouldn't work.
diff --git a/README b/README
index f39c921..d24936f 100644
--- a/README
+++ b/README
@@ -31,7 +31,7 @@
   PREFIX=/path/to/root/filesystem/bin make install_flat
 
 The file "configure" defines default values for many environment variables
-that control the toybox build; if you export any of these variables into your
+that control the toybox build; if export any these variables into your
 environment, your value is used instead of the default in that file.
 
 The CROSS_COMPILE argument above is optional, the default builds a version of
diff --git a/TEST_MAPPING b/TEST_MAPPING
index cdb4934..7353838 100644
--- a/TEST_MAPPING
+++ b/TEST_MAPPING
@@ -3,10 +3,5 @@
     {
       "name": "toybox-tests"
     }
-  ],
-  "hwasan-postsubmit": [
-    {
-      "name": "toybox-tests"
-    }
   ]
 }
diff --git a/android/device/generated/config.h b/android/device/generated/config.h
index 415d99e..d7d0b83 100644
--- a/android/device/generated/config.h
+++ b/android/device/generated/config.h
@@ -2,8 +2,6 @@
 #define USE_TOYBOX(...) __VA_ARGS__
 #define CFG_TOYBOX_CONTAINER 1
 #define USE_TOYBOX_CONTAINER(...) __VA_ARGS__
-#define CFG_TOYBOX_COPYFILERANGE 0
-#define USE_TOYBOX_COPYFILERANGE(...)
 #define CFG_TOYBOX_DEBUG 0
 #define USE_TOYBOX_DEBUG(...)
 #define CFG_TOYBOX_FALLOCATE 1
@@ -244,16 +242,6 @@
 #define USE_GETOPT(...) __VA_ARGS__
 #define CFG_GETTY 0
 #define USE_GETTY(...)
-#define CFG_GPIODETECT 0
-#define USE_GPIODETECT(...)
-#define CFG_GPIOFIND 0
-#define USE_GPIOFIND(...)
-#define CFG_GPIOGET 0
-#define USE_GPIOGET(...)
-#define CFG_GPIOINFO 0
-#define USE_GPIOINFO(...)
-#define CFG_GPIOSET 0
-#define USE_GPIOSET(...)
 #define CFG_GREP 1
 #define USE_GREP(...) __VA_ARGS__
 #define CFG_GROUPADD 0
@@ -274,12 +262,8 @@
 #define USE_HELP_EXTRAS(...) __VA_ARGS__
 #define CFG_HELP 1
 #define USE_HELP(...) __VA_ARGS__
-#define CFG_HEXDUMP 0
-#define USE_HEXDUMP(...)
 #define CFG_HEXEDIT 0
 #define USE_HEXEDIT(...)
-#define CFG_HD 0
-#define USE_HD(...)
 #define CFG_HOSTID 0
 #define USE_HOSTID(...)
 #define CFG_HOST 0
@@ -338,8 +322,6 @@
 #define USE_LAST(...)
 #define CFG_LINK 0
 #define USE_LINK(...)
-#define CFG_LINUX32 0
-#define USE_LINUX32(...)
 #define CFG_LN 1
 #define USE_LN(...) __VA_ARGS__
 #define CFG_LOAD_POLICY 1
@@ -350,8 +332,6 @@
 #define USE_LOGIN(...)
 #define CFG_LOGNAME 1
 #define USE_LOGNAME(...) __VA_ARGS__
-#define CFG_LOGPATH 0
-#define USE_LOGPATH(...)
 #define CFG_LOG 1
 #define USE_LOG(...) __VA_ARGS__
 #define CFG_LOGWRAPPER 0
@@ -368,8 +348,8 @@
 #define USE_LSOF(...) __VA_ARGS__
 #define CFG_LSPCI 1
 #define USE_LSPCI(...) __VA_ARGS__
-#define CFG_LSPCI_TEXT 1
-#define USE_LSPCI_TEXT(...) __VA_ARGS__
+#define CFG_LSPCI_TEXT 0
+#define USE_LSPCI_TEXT(...)
 #define CFG_LSUSB 1
 #define USE_LSUSB(...) __VA_ARGS__
 #define CFG_LS 1
@@ -574,8 +554,6 @@
 #define USE_SPLIT(...) __VA_ARGS__
 #define CFG_STAT 1
 #define USE_STAT(...) __VA_ARGS__
-#define CFG_STRACE 0
-#define USE_STRACE(...)
 #define CFG_STRINGS 1
 #define USE_STRINGS(...) __VA_ARGS__
 #define CFG_STTY 1
@@ -646,8 +624,6 @@
 #define USE_TTY(...) __VA_ARGS__
 #define CFG_TUNCTL 1
 #define USE_TUNCTL(...) __VA_ARGS__
-#define CFG_UCLAMPSET 1
-#define USE_UCLAMPSET(...) __VA_ARGS__
 #define CFG_ULIMIT 1
 #define USE_ULIMIT(...) __VA_ARGS__
 #define CFG_UMOUNT 1
diff --git a/android/device/generated/flags.h b/android/device/generated/flags.h
index ced393d..6a71e69 100644
--- a/android/device/generated/flags.h
+++ b/android/device/generated/flags.h
@@ -5,7 +5,7 @@
 #define FORCED_FLAGLL 1ULL
 #else
 #define FORCED_FLAG 0
-#define FORCED_FLAGLL 0LL
+#define FORCED_FLAGLL 0
 #endif
 
 // acpi abctV abctV
@@ -200,9 +200,9 @@
 #undef FOR_bzcat
 #endif
 
-// cal >3h >3h
+// cal >2h >2h
 #undef OPTSTR_cal
-#define OPTSTR_cal ">3h"
+#define OPTSTR_cal ">2h"
 #ifdef CLEANUP_cal
 #undef CLEANUP_cal
 #undef FOR_cal
@@ -352,13 +352,12 @@
 #undef FOR_clear
 #endif
 
-// cmp <1>4ls(silent)(quiet)n#<1[!ls] <1>4ls(silent)(quiet)n#<1[!ls]
+// cmp <1>2ls(silent)(quiet)[!ls] <1>2ls(silent)(quiet)[!ls]
 #undef OPTSTR_cmp
-#define OPTSTR_cmp "<1>4ls(silent)(quiet)n#<1[!ls]"
+#define OPTSTR_cmp "<1>2ls(silent)(quiet)[!ls]"
 #ifdef CLEANUP_cmp
 #undef CLEANUP_cmp
 #undef FOR_cmp
-#undef FLAG_n
 #undef FLAG_s
 #undef FLAG_l
 #endif
@@ -382,9 +381,9 @@
 #undef FOR_count
 #endif
 
-// cp <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr] <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]
+// cp <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu] <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]
 #undef OPTSTR_cp
-#define OPTSTR_cp "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]"
+#define OPTSTR_cp "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]"
 #ifdef CLEANUP_cp
 #undef CLEANUP_cp
 #undef FOR_cp
@@ -410,9 +409,9 @@
 #undef FLAG_preserve
 #endif
 
-// cpio (ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF] (ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]
+// cpio (quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF] (quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]
 #undef OPTSTR_cpio
-#define OPTSTR_cpio "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]"
+#define OPTSTR_cpio "(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]"
 #ifdef CLEANUP_cpio
 #undef CLEANUP_cpio
 #undef FOR_cpio
@@ -428,8 +427,6 @@
 #undef FLAG_m
 #undef FLAG_no_preserve_owner
 #undef FLAG_quiet
-#undef FLAG_renumber_inodes
-#undef FLAG_ignore_devno
 #endif
 
 // crc32    
@@ -468,9 +465,9 @@
 #undef FLAG_c
 #endif
 
-// cut b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF] b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF]
+// cut b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf] b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]
 #undef OPTSTR_cut
-#define OPTSTR_cut "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF]"
+#define OPTSTR_cut "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]"
 #ifdef CLEANUP_cut
 #undef CLEANUP_cut
 #undef FOR_cut
@@ -486,14 +483,13 @@
 #undef FLAG_b
 #endif
 
-// date d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr] d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr]
+// date d:D:I(iso)(iso-8601):;r:u(utc)[!dr] d:D:I(iso)(iso-8601):;r:u(utc)[!dr]
 #undef OPTSTR_date
-#define OPTSTR_date "d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr]"
+#define OPTSTR_date "d:D:I(iso)(iso-8601):;r:u(utc)[!dr]"
 #ifdef CLEANUP_date
 #undef CLEANUP_date
 #undef FOR_date
 #undef FLAG_u
-#undef FLAG_s
 #undef FLAG_r
 #undef FLAG_I
 #undef FLAG_D
@@ -516,23 +512,6 @@
 #undef FOR_deallocvt
 #endif
 
-// declare   pAailunxr
-#undef OPTSTR_declare
-#define OPTSTR_declare "pAailunxr"
-#ifdef CLEANUP_declare
-#undef CLEANUP_declare
-#undef FOR_declare
-#undef FLAG_r
-#undef FLAG_x
-#undef FLAG_n
-#undef FLAG_u
-#undef FLAG_l
-#undef FLAG_i
-#undef FLAG_a
-#undef FLAG_A
-#undef FLAG_p
-#endif
-
 // demo_many_options   ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba
 #undef OPTSTR_demo_many_options
 #define OPTSTR_demo_many_options "ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
@@ -995,9 +974,9 @@
 #undef FLAG_b
 #endif
 
-// free hgmkb[!hgmkb] hgmkb[!hgmkb]
+// free htgmkb[!htgmkb] htgmkb[!htgmkb]
 #undef OPTSTR_free
-#define OPTSTR_free "hgmkb[!hgmkb]"
+#define OPTSTR_free "htgmkb[!htgmkb]"
 #ifdef CLEANUP_free
 #undef CLEANUP_free
 #undef FOR_free
@@ -1005,6 +984,7 @@
 #undef FLAG_k
 #undef FLAG_m
 #undef FLAG_g
+#undef FLAG_t
 #undef FLAG_h
 #endif
 
@@ -1144,51 +1124,9 @@
 #undef FLAG_t
 #endif
 
-// gpiodetect   >0
-#undef OPTSTR_gpiodetect
-#define OPTSTR_gpiodetect ">0"
-#ifdef CLEANUP_gpiodetect
-#undef CLEANUP_gpiodetect
-#undef FOR_gpiodetect
-#endif
-
-// gpiofind   <1>1
-#undef OPTSTR_gpiofind
-#define OPTSTR_gpiofind "<1>1"
-#ifdef CLEANUP_gpiofind
-#undef CLEANUP_gpiofind
-#undef FOR_gpiofind
-#endif
-
-// gpioget   <2l
-#undef OPTSTR_gpioget
-#define OPTSTR_gpioget "<2l"
-#ifdef CLEANUP_gpioget
-#undef CLEANUP_gpioget
-#undef FOR_gpioget
-#undef FLAG_l
-#endif
-
-// gpioinfo    
-#undef OPTSTR_gpioinfo
-#define OPTSTR_gpioinfo 0
-#ifdef CLEANUP_gpioinfo
-#undef CLEANUP_gpioinfo
-#undef FOR_gpioinfo
-#endif
-
-// gpioset   <2l
-#undef OPTSTR_gpioset
-#define OPTSTR_gpioset "<2l"
-#ifdef CLEANUP_gpioset
-#undef CLEANUP_gpioset
-#undef FOR_gpioset
-#undef FLAG_l
-#endif
-
-// grep (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF] (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF]
+// grep (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw] (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw]
 #undef OPTSTR_grep
-#define OPTSTR_grep "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF]"
+#define OPTSTR_grep "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw]"
 #ifdef CLEANUP_grep
 #undef CLEANUP_grep
 #undef FOR_grep
@@ -1201,7 +1139,6 @@
 #undef FLAG_e
 #undef FLAG_q
 #undef FLAG_l
-#undef FLAG_L
 #undef FLAG_c
 #undef FLAG_w
 #undef FLAG_v
@@ -1327,23 +1264,6 @@
 #undef FLAG_a
 #endif
 
-// hexdump   bcCdn#<0os#<0vx[!bcCdox]
-#undef OPTSTR_hexdump
-#define OPTSTR_hexdump "bcCdn#<0os#<0vx[!bcCdox]"
-#ifdef CLEANUP_hexdump
-#undef CLEANUP_hexdump
-#undef FOR_hexdump
-#undef FLAG_x
-#undef FLAG_v
-#undef FLAG_s
-#undef FLAG_o
-#undef FLAG_n
-#undef FLAG_d
-#undef FLAG_C
-#undef FLAG_c
-#undef FLAG_b
-#endif
-
 // hexedit   <1>1r
 #undef OPTSTR_hexedit
 #define OPTSTR_hexedit "<1>1r"
@@ -1401,15 +1321,13 @@
 #undef FLAG_fast
 #endif
 
-// i2cdetect >3aFlqry[!qr] >3aFlqry[!qr]
+// i2cdetect >3aFly >3aFly
 #undef OPTSTR_i2cdetect
-#define OPTSTR_i2cdetect ">3aFlqry[!qr]"
+#define OPTSTR_i2cdetect ">3aFly"
 #ifdef CLEANUP_i2cdetect
 #undef CLEANUP_i2cdetect
 #undef FOR_i2cdetect
 #undef FLAG_y
-#undef FLAG_r
-#undef FLAG_q
 #undef FLAG_l
 #undef FLAG_F
 #undef FLAG_a
@@ -1535,9 +1453,9 @@
 #undef FLAG_t
 #endif
 
-// iorenice <1>3 <1>3
+// iorenice ?<1>3 ?<1>3
 #undef OPTSTR_iorenice
-#define OPTSTR_iorenice "<1>3"
+#define OPTSTR_iorenice "?<1>3"
 #ifdef CLEANUP_iorenice
 #undef CLEANUP_iorenice
 #undef FOR_iorenice
@@ -1682,14 +1600,6 @@
 #undef FOR_link
 #endif
 
-// linux32    
-#undef OPTSTR_linux32
-#define OPTSTR_linux32 0
-#ifdef CLEANUP_linux32
-#undef CLEANUP_linux32
-#undef FOR_linux32
-#endif
-
 // ln <1rt:Tvnfs <1rt:Tvnfs
 #undef OPTSTR_ln
 #define OPTSTR_ln "<1rt:Tvnfs"
@@ -1713,9 +1623,9 @@
 #undef FOR_load_policy
 #endif
 
-// log p:t: p:t:
+// log <1p:t: <1p:t:
 #undef OPTSTR_log
-#define OPTSTR_log "p:t:"
+#define OPTSTR_log "<1p:t:"
 #ifdef CLEANUP_log
 #undef CLEANUP_log
 #undef FOR_log
@@ -1753,12 +1663,12 @@
 #undef FOR_logname
 #endif
 
-// logpath    
-#undef OPTSTR_logpath
-#define OPTSTR_logpath 0
-#ifdef CLEANUP_logpath
-#undef CLEANUP_logpath
-#undef FOR_logpath
+// logwrapper    
+#undef OPTSTR_logwrapper
+#define OPTSTR_logwrapper 0
+#ifdef CLEANUP_logwrapper
+#undef CLEANUP_logwrapper
+#undef FOR_logwrapper
 #endif
 
 // losetup >2S(sizelimit)#s(show)ro#j:fdcaD[!afj] >2S(sizelimit)#s(show)ro#j:fdcaD[!afj]
@@ -1853,9 +1763,9 @@
 #undef FLAG_l
 #endif
 
-// lspci emkn@i: emkn@i:
+// lspci emkn emkn@i:
 #undef OPTSTR_lspci
-#define OPTSTR_lspci "emkn@i:"
+#define OPTSTR_lspci "emkn"
 #ifdef CLEANUP_lspci
 #undef CLEANUP_lspci
 #undef FOR_lspci
@@ -1866,13 +1776,12 @@
 #undef FLAG_e
 #endif
 
-// lsusb i: i:
+// lsusb    
 #undef OPTSTR_lsusb
-#define OPTSTR_lsusb "i:"
+#define OPTSTR_lsusb 0
 #ifdef CLEANUP_lsusb
 #undef CLEANUP_lsusb
 #undef FOR_lsusb
-#undef FLAG_i
 #endif
 
 // makedevs <1>1d: <1>1d:
@@ -2168,16 +2077,16 @@
 #undef FLAG_n
 #endif
 
-// nl v#=1l#w#<0=6b:n:s:E v#=1l#w#<0=6b:n:s:E
+// nl v#=1l#w#<0=6Eb:n:s: v#=1l#w#<0=6Eb:n:s:
 #undef OPTSTR_nl
-#define OPTSTR_nl "v#=1l#w#<0=6b:n:s:E"
+#define OPTSTR_nl "v#=1l#w#<0=6Eb:n:s:"
 #ifdef CLEANUP_nl
 #undef CLEANUP_nl
 #undef FOR_nl
-#undef FLAG_E
 #undef FLAG_s
 #undef FLAG_n
 #undef FLAG_b
+#undef FLAG_E
 #undef FLAG_w
 #undef FLAG_l
 #undef FLAG_v
@@ -2248,9 +2157,9 @@
 #undef FLAG_n
 #endif
 
-// openvt   ^<1c#<1>63sw
+// openvt   c#<1>63sw
 #undef OPTSTR_openvt
-#define OPTSTR_openvt "^<1c#<1>63sw"
+#define OPTSTR_openvt "c#<1>63sw"
 #ifdef CLEANUP_openvt
 #undef CLEANUP_openvt
 #undef FOR_openvt
@@ -2334,9 +2243,9 @@
 #undef FLAG_c
 #endif
 
-// pidof so:x so:x
+// pidof <1so:x <1so:x
 #undef OPTSTR_pidof
-#define OPTSTR_pidof "so:x"
+#define OPTSTR_pidof "<1so:x"
 #ifdef CLEANUP_pidof
 #undef CLEANUP_pidof
 #undef FOR_pidof
@@ -2395,15 +2304,14 @@
 #undef FLAG_V
 #endif
 
-// pmap <1pqx <1pqx
+// pmap <1xq <1xq
 #undef OPTSTR_pmap
-#define OPTSTR_pmap "<1pqx"
+#define OPTSTR_pmap "<1xq"
 #ifdef CLEANUP_pmap
 #undef CLEANUP_pmap
 #undef FOR_pmap
-#undef FLAG_x
 #undef FLAG_q
-#undef FLAG_p
+#undef FLAG_x
 #endif
 
 // printenv (null)0 (null)0
@@ -2534,15 +2442,22 @@
 #undef FLAG_n
 #endif
 
-// reboot   d:fn
+// realpath <1 <1
+#undef OPTSTR_realpath
+#define OPTSTR_realpath "<1"
+#ifdef CLEANUP_realpath
+#undef CLEANUP_realpath
+#undef FOR_realpath
+#endif
+
+// reboot   fn
 #undef OPTSTR_reboot
-#define OPTSTR_reboot "d:fn"
+#define OPTSTR_reboot "fn"
 #ifdef CLEANUP_reboot
 #undef CLEANUP_reboot
 #undef FOR_reboot
 #undef FLAG_n
 #undef FLAG_f
-#undef FLAG_d
 #endif
 
 // renice <1gpun#| <1gpun#|
@@ -2755,6 +2670,17 @@
 #undef FLAG_noediting
 #endif
 
+// sha1sum bc(check)s(status)[!bc] bc(check)s(status)[!bc]
+#undef OPTSTR_sha1sum
+#define OPTSTR_sha1sum "bc(check)s(status)[!bc]"
+#ifdef CLEANUP_sha1sum
+#undef CLEANUP_sha1sum
+#undef FOR_sha1sum
+#undef FLAG_s
+#undef FLAG_c
+#undef FLAG_b
+#endif
+
 // sha3sum   bSa#<128>512=224
 #undef OPTSTR_sha3sum
 #define OPTSTR_sha3sum "bSa#<128>512=224"
@@ -2879,13 +2805,12 @@
 #undef FOR_source
 #endif
 
-// split >2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln] >2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln]
+// split >2a#<1=2>9b#<1l#<1[!bl] >2a#<1=2>9b#<1l#<1[!bl]
 #undef OPTSTR_split
-#define OPTSTR_split ">2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln]"
+#define OPTSTR_split ">2a#<1=2>9b#<1l#<1[!bl]"
 #ifdef CLEANUP_split
 #undef CLEANUP_split
 #undef FOR_split
-#undef FLAG_n
 #undef FLAG_l
 #undef FLAG_b
 #undef FLAG_a
@@ -2903,17 +2828,6 @@
 #undef FLAG_c
 #endif
 
-// strace   ^p#s#v
-#undef OPTSTR_strace
-#define OPTSTR_strace "^p#s#v"
-#ifdef CLEANUP_strace
-#undef CLEANUP_strace
-#undef FOR_strace
-#undef FLAG_v
-#undef FLAG_s
-#undef FLAG_p
-#endif
-
 // strings t:an#=4<1fo t:an#=4<1fo
 #undef OPTSTR_strings
 #define OPTSTR_strings "t:an#=4<1fo"
@@ -3044,22 +2958,20 @@
 #undef FOR_tac
 #endif
 
-// tail ?fFs:c(bytes)-n(lines)-[-cn][-fF] ?fFs:c(bytes)-n(lines)-[-cn][-fF]
+// tail ?fc-n-[-cn] ?fc-n-[-cn]
 #undef OPTSTR_tail
-#define OPTSTR_tail "?fFs:c(bytes)-n(lines)-[-cn][-fF]"
+#define OPTSTR_tail "?fc-n-[-cn]"
 #ifdef CLEANUP_tail
 #undef CLEANUP_tail
 #undef FOR_tail
 #undef FLAG_n
 #undef FLAG_c
-#undef FLAG_s
-#undef FLAG_F
 #undef FLAG_f
 #endif
 
-// tar &(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa] &(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]
+// tar &(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa] &(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]
 #undef OPTSTR_tar
-#define OPTSTR_tar "&(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]"
+#define OPTSTR_tar "&(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]"
 #ifdef CLEANUP_tar
 #undef CLEANUP_tar
 #undef FOR_tar
@@ -3096,8 +3008,6 @@
 #undef FLAG_no_recursion
 #undef FLAG_full_time
 #undef FLAG_restrict
-#undef FLAG_selinux
-#undef FLAG_strip_components
 #endif
 
 // taskset <1^pa <1^pa
@@ -3194,9 +3104,9 @@
 #undef FLAG_r
 #endif
 
-// time <1^pv[-pv] <1^pv[-pv]
+// time <1^pv <1^pv
 #undef OPTSTR_time
-#define OPTSTR_time "<1^pv[-pv]"
+#define OPTSTR_time "<1^pv"
 #ifdef CLEANUP_time
 #undef CLEANUP_time
 #undef FOR_time
@@ -3217,9 +3127,9 @@
 #undef FLAG_foreground
 #endif
 
-// top >0O*hHk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO] >0O*hHk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]
+// top >0O*Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO] >0O*Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]
 #undef OPTSTR_top
-#define OPTSTR_top ">0O*hHk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]"
+#define OPTSTR_top ">0O*Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]"
 #ifdef CLEANUP_top
 #undef CLEANUP_top
 #undef FOR_top
@@ -3234,7 +3144,6 @@
 #undef FLAG_o
 #undef FLAG_k
 #undef FLAG_H
-#undef FLAG_h
 #undef FLAG_O
 #endif
 
@@ -3341,19 +3250,6 @@
 #undef FLAG_t
 #endif
 
-// uclampset p#am#<-1>1024M#<-1>1024R p#am#<-1>1024M#<-1>1024R
-#undef OPTSTR_uclampset
-#define OPTSTR_uclampset "p#am#<-1>1024M#<-1>1024R"
-#ifdef CLEANUP_uclampset
-#undef CLEANUP_uclampset
-#undef FOR_uclampset
-#undef FLAG_R
-#undef FLAG_M
-#undef FLAG_m
-#undef FLAG_a
-#undef FLAG_p
-#endif
-
 // ulimit >1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc] >1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]
 #undef OPTSTR_ulimit
 #define OPTSTR_ulimit ">1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]"
@@ -3400,9 +3296,9 @@
 #undef FLAG_c
 #endif
 
-// uname aomvrns aomvrns
+// uname oamvrns[+os] oamvrns[+os]
 #undef OPTSTR_uname
-#define OPTSTR_uname "aomvrns"
+#define OPTSTR_uname "oamvrns[+os]"
 #ifdef CLEANUP_uname
 #undef CLEANUP_uname
 #undef FOR_uname
@@ -3411,8 +3307,8 @@
 #undef FLAG_r
 #undef FLAG_v
 #undef FLAG_m
-#undef FLAG_o
 #undef FLAG_a
+#undef FLAG_o
 #endif
 
 // unicode   <1
@@ -3631,16 +3527,14 @@
 #undef FLAG_m
 #endif
 
-// wget   <1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):
+// wget   (no-check-certificate)O:
 #undef OPTSTR_wget
-#define OPTSTR_wget "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):"
+#define OPTSTR_wget "(no-check-certificate)O:"
 #ifdef CLEANUP_wget
 #undef CLEANUP_wget
 #undef FOR_wget
-#undef FLAG_p
 #undef FLAG_O
-#undef FLAG_d
-#undef FLAG_max_redirect
+#undef FLAG_no_check_certificate
 #endif
 
 // which <1a <1a
@@ -3678,9 +3572,9 @@
 #undef FLAG_E
 #endif
 
-// xxd >1c#<0>256l#o#g#<1=2iprs#[!rs] >1c#<0>256l#o#g#<1=2iprs#[!rs]
+// xxd >1c#l#o#g#<1=2iprs#[!rs] >1c#l#o#g#<1=2iprs#[!rs]
 #undef OPTSTR_xxd
-#define OPTSTR_xxd ">1c#<0>256l#o#g#<1=2iprs#[!rs]"
+#define OPTSTR_xxd ">1c#l#o#g#<1=2iprs#[!rs]"
 #ifdef CLEANUP_xxd
 #undef CLEANUP_xxd
 #undef FOR_xxd
@@ -3732,7 +3626,6 @@
 #endif
 
 #ifdef FOR_acpi
-#define CLEANUP_acpi
 #ifndef TT
 #define TT this.acpi
 #endif
@@ -3744,14 +3637,12 @@
 #endif
 
 #ifdef FOR_arch
-#define CLEANUP_arch
 #ifndef TT
 #define TT this.arch
 #endif
 #endif
 
 #ifdef FOR_arp
-#define CLEANUP_arp
 #ifndef TT
 #define TT this.arp
 #endif
@@ -3768,7 +3659,6 @@
 #endif
 
 #ifdef FOR_arping
-#define CLEANUP_arping
 #ifndef TT
 #define TT this.arping
 #endif
@@ -3785,14 +3675,12 @@
 #endif
 
 #ifdef FOR_ascii
-#define CLEANUP_ascii
 #ifndef TT
 #define TT this.ascii
 #endif
 #endif
 
 #ifdef FOR_base32
-#define CLEANUP_base32
 #ifndef TT
 #define TT this.base32
 #endif
@@ -3802,7 +3690,6 @@
 #endif
 
 #ifdef FOR_base64
-#define CLEANUP_base64
 #ifndef TT
 #define TT this.base64
 #endif
@@ -3812,7 +3699,6 @@
 #endif
 
 #ifdef FOR_basename
-#define CLEANUP_basename
 #ifndef TT
 #define TT this.basename
 #endif
@@ -3821,7 +3707,6 @@
 #endif
 
 #ifdef FOR_bc
-#define CLEANUP_bc
 #ifndef TT
 #define TT this.bc
 #endif
@@ -3833,7 +3718,6 @@
 #endif
 
 #ifdef FOR_blkdiscard
-#define CLEANUP_blkdiscard
 #ifndef TT
 #define TT this.blkdiscard
 #endif
@@ -3845,7 +3729,6 @@
 #endif
 
 #ifdef FOR_blkid
-#define CLEANUP_blkid
 #ifndef TT
 #define TT this.blkid
 #endif
@@ -3855,7 +3738,6 @@
 #endif
 
 #ifdef FOR_blockdev
-#define CLEANUP_blockdev
 #ifndef TT
 #define TT this.blockdev
 #endif
@@ -3875,21 +3757,18 @@
 #endif
 
 #ifdef FOR_bootchartd
-#define CLEANUP_bootchartd
 #ifndef TT
 #define TT this.bootchartd
 #endif
 #endif
 
 #ifdef FOR_brctl
-#define CLEANUP_brctl
 #ifndef TT
 #define TT this.brctl
 #endif
 #endif
 
 #ifdef FOR_bunzip2
-#define CLEANUP_bunzip2
 #ifndef TT
 #define TT this.bunzip2
 #endif
@@ -3901,14 +3780,12 @@
 #endif
 
 #ifdef FOR_bzcat
-#define CLEANUP_bzcat
 #ifndef TT
 #define TT this.bzcat
 #endif
 #endif
 
 #ifdef FOR_cal
-#define CLEANUP_cal
 #ifndef TT
 #define TT this.cal
 #endif
@@ -3916,7 +3793,6 @@
 #endif
 
 #ifdef FOR_cat
-#define CLEANUP_cat
 #ifndef TT
 #define TT this.cat
 #endif
@@ -3927,7 +3803,6 @@
 #endif
 
 #ifdef FOR_catv
-#define CLEANUP_catv
 #ifndef TT
 #define TT this.catv
 #endif
@@ -3937,7 +3812,6 @@
 #endif
 
 #ifdef FOR_cd
-#define CLEANUP_cd
 #ifndef TT
 #define TT this.cd
 #endif
@@ -3946,7 +3820,6 @@
 #endif
 
 #ifdef FOR_chattr
-#define CLEANUP_chattr
 #ifndef TT
 #define TT this.chattr
 #endif
@@ -3956,7 +3829,6 @@
 #endif
 
 #ifdef FOR_chcon
-#define CLEANUP_chcon
 #ifndef TT
 #define TT this.chcon
 #endif
@@ -3966,7 +3838,6 @@
 #endif
 
 #ifdef FOR_chgrp
-#define CLEANUP_chgrp
 #ifndef TT
 #define TT this.chgrp
 #endif
@@ -3980,7 +3851,6 @@
 #endif
 
 #ifdef FOR_chmod
-#define CLEANUP_chmod
 #ifndef TT
 #define TT this.chmod
 #endif
@@ -3990,14 +3860,12 @@
 #endif
 
 #ifdef FOR_chroot
-#define CLEANUP_chroot
 #ifndef TT
 #define TT this.chroot
 #endif
 #endif
 
 #ifdef FOR_chrt
-#define CLEANUP_chrt
 #ifndef TT
 #define TT this.chrt
 #endif
@@ -4012,7 +3880,6 @@
 #endif
 
 #ifdef FOR_chsh
-#define CLEANUP_chsh
 #ifndef TT
 #define TT this.chsh
 #endif
@@ -4020,14 +3887,12 @@
 #endif
 
 #ifdef FOR_chvt
-#define CLEANUP_chvt
 #ifndef TT
 #define TT this.chvt
 #endif
 #endif
 
 #ifdef FOR_cksum
-#define CLEANUP_cksum
 #ifndef TT
 #define TT this.cksum
 #endif
@@ -4039,24 +3904,20 @@
 #endif
 
 #ifdef FOR_clear
-#define CLEANUP_clear
 #ifndef TT
 #define TT this.clear
 #endif
 #endif
 
 #ifdef FOR_cmp
-#define CLEANUP_cmp
 #ifndef TT
 #define TT this.cmp
 #endif
-#define FLAG_n (1<<0)
-#define FLAG_s (1<<1)
-#define FLAG_l (1<<2)
+#define FLAG_s (1<<0)
+#define FLAG_l (1<<1)
 #endif
 
 #ifdef FOR_comm
-#define CLEANUP_comm
 #ifndef TT
 #define TT this.comm
 #endif
@@ -4066,14 +3927,12 @@
 #endif
 
 #ifdef FOR_count
-#define CLEANUP_count
 #ifndef TT
 #define TT this.count
 #endif
 #endif
 
 #ifdef FOR_cp
-#define CLEANUP_cp
 #ifndef TT
 #define TT this.cp
 #endif
@@ -4100,7 +3959,6 @@
 #endif
 
 #ifdef FOR_cpio
-#define CLEANUP_cpio
 #ifndef TT
 #define TT this.cpio
 #endif
@@ -4116,19 +3974,15 @@
 #define FLAG_m (1<<9)
 #define FLAG_no_preserve_owner (1<<10)
 #define FLAG_quiet (1<<11)
-#define FLAG_renumber_inodes (1<<12)
-#define FLAG_ignore_devno (1<<13)
 #endif
 
 #ifdef FOR_crc32
-#define CLEANUP_crc32
 #ifndef TT
 #define TT this.crc32
 #endif
 #endif
 
 #ifdef FOR_crond
-#define CLEANUP_crond
 #ifndef TT
 #define TT this.crond
 #endif
@@ -4142,7 +3996,6 @@
 #endif
 
 #ifdef FOR_crontab
-#define CLEANUP_crontab
 #ifndef TT
 #define TT this.crontab
 #endif
@@ -4154,7 +4007,6 @@
 #endif
 
 #ifdef FOR_cut
-#define CLEANUP_cut
 #ifndef TT
 #define TT this.cut
 #endif
@@ -4171,50 +4023,29 @@
 #endif
 
 #ifdef FOR_date
-#define CLEANUP_date
 #ifndef TT
 #define TT this.date
 #endif
 #define FLAG_u (1<<0)
-#define FLAG_s (1<<1)
-#define FLAG_r (1<<2)
-#define FLAG_I (1<<3)
-#define FLAG_D (1<<4)
-#define FLAG_d (1<<5)
+#define FLAG_r (1<<1)
+#define FLAG_I (1<<2)
+#define FLAG_D (1<<3)
+#define FLAG_d (1<<4)
 #endif
 
 #ifdef FOR_dd
-#define CLEANUP_dd
 #ifndef TT
 #define TT this.dd
 #endif
 #endif
 
 #ifdef FOR_deallocvt
-#define CLEANUP_deallocvt
 #ifndef TT
 #define TT this.deallocvt
 #endif
 #endif
 
-#ifdef FOR_declare
-#define CLEANUP_declare
-#ifndef TT
-#define TT this.declare
-#endif
-#define FLAG_r (FORCED_FLAG<<0)
-#define FLAG_x (FORCED_FLAG<<1)
-#define FLAG_n (FORCED_FLAG<<2)
-#define FLAG_u (FORCED_FLAG<<3)
-#define FLAG_l (FORCED_FLAG<<4)
-#define FLAG_i (FORCED_FLAG<<5)
-#define FLAG_a (FORCED_FLAG<<6)
-#define FLAG_A (FORCED_FLAG<<7)
-#define FLAG_p (FORCED_FLAG<<8)
-#endif
-
 #ifdef FOR_demo_many_options
-#define CLEANUP_demo_many_options
 #ifndef TT
 #define TT this.demo_many_options
 #endif
@@ -4273,7 +4104,6 @@
 #endif
 
 #ifdef FOR_demo_number
-#define CLEANUP_demo_number
 #ifndef TT
 #define TT this.demo_number
 #endif
@@ -4287,28 +4117,24 @@
 #endif
 
 #ifdef FOR_demo_scankey
-#define CLEANUP_demo_scankey
 #ifndef TT
 #define TT this.demo_scankey
 #endif
 #endif
 
 #ifdef FOR_demo_utf8towc
-#define CLEANUP_demo_utf8towc
 #ifndef TT
 #define TT this.demo_utf8towc
 #endif
 #endif
 
 #ifdef FOR_devmem
-#define CLEANUP_devmem
 #ifndef TT
 #define TT this.devmem
 #endif
 #endif
 
 #ifdef FOR_df
-#define CLEANUP_df
 #ifndef TT
 #define TT this.df
 #endif
@@ -4322,7 +4148,6 @@
 #endif
 
 #ifdef FOR_dhcp
-#define CLEANUP_dhcp
 #ifndef TT
 #define TT this.dhcp
 #endif
@@ -4352,7 +4177,6 @@
 #endif
 
 #ifdef FOR_dhcp6
-#define CLEANUP_dhcp6
 #ifndef TT
 #define TT this.dhcp6
 #endif
@@ -4373,7 +4197,6 @@
 #endif
 
 #ifdef FOR_dhcpd
-#define CLEANUP_dhcpd
 #ifndef TT
 #define TT this.dhcpd
 #endif
@@ -4386,7 +4209,6 @@
 #endif
 
 #ifdef FOR_diff
-#define CLEANUP_diff
 #ifndef TT
 #define TT this.diff
 #endif
@@ -4411,14 +4233,12 @@
 #endif
 
 #ifdef FOR_dirname
-#define CLEANUP_dirname
 #ifndef TT
 #define TT this.dirname
 #endif
 #endif
 
 #ifdef FOR_dmesg
-#define CLEANUP_dmesg
 #ifndef TT
 #define TT this.dmesg
 #endif
@@ -4434,21 +4254,18 @@
 #endif
 
 #ifdef FOR_dnsdomainname
-#define CLEANUP_dnsdomainname
 #ifndef TT
 #define TT this.dnsdomainname
 #endif
 #endif
 
 #ifdef FOR_dos2unix
-#define CLEANUP_dos2unix
 #ifndef TT
 #define TT this.dos2unix
 #endif
 #endif
 
 #ifdef FOR_du
-#define CLEANUP_du
 #ifndef TT
 #define TT this.du
 #endif
@@ -4468,7 +4285,6 @@
 #endif
 
 #ifdef FOR_dumpleases
-#define CLEANUP_dumpleases
 #ifndef TT
 #define TT this.dumpleases
 #endif
@@ -4478,7 +4294,6 @@
 #endif
 
 #ifdef FOR_echo
-#define CLEANUP_echo
 #ifndef TT
 #define TT this.echo
 #endif
@@ -4488,7 +4303,6 @@
 #endif
 
 #ifdef FOR_eject
-#define CLEANUP_eject
 #ifndef TT
 #define TT this.eject
 #endif
@@ -4498,7 +4312,6 @@
 #endif
 
 #ifdef FOR_env
-#define CLEANUP_env
 #ifndef TT
 #define TT this.env
 #endif
@@ -4508,14 +4321,12 @@
 #endif
 
 #ifdef FOR_eval
-#define CLEANUP_eval
 #ifndef TT
 #define TT this.eval
 #endif
 #endif
 
 #ifdef FOR_exec
-#define CLEANUP_exec
 #ifndef TT
 #define TT this.exec
 #endif
@@ -4525,14 +4336,12 @@
 #endif
 
 #ifdef FOR_exit
-#define CLEANUP_exit
 #ifndef TT
 #define TT this.exit
 #endif
 #endif
 
 #ifdef FOR_expand
-#define CLEANUP_expand
 #ifndef TT
 #define TT this.expand
 #endif
@@ -4540,7 +4349,6 @@
 #endif
 
 #ifdef FOR_export
-#define CLEANUP_export
 #ifndef TT
 #define TT this.export
 #endif
@@ -4549,21 +4357,18 @@
 #endif
 
 #ifdef FOR_expr
-#define CLEANUP_expr
 #ifndef TT
 #define TT this.expr
 #endif
 #endif
 
 #ifdef FOR_factor
-#define CLEANUP_factor
 #ifndef TT
 #define TT this.factor
 #endif
 #endif
 
 #ifdef FOR_fallocate
-#define CLEANUP_fallocate
 #ifndef TT
 #define TT this.fallocate
 #endif
@@ -4572,14 +4377,12 @@
 #endif
 
 #ifdef FOR_false
-#define CLEANUP_false
 #ifndef TT
 #define TT this.false
 #endif
 #endif
 
 #ifdef FOR_fdisk
-#define CLEANUP_fdisk
 #ifndef TT
 #define TT this.fdisk
 #endif
@@ -4592,7 +4395,6 @@
 #endif
 
 #ifdef FOR_file
-#define CLEANUP_file
 #ifndef TT
 #define TT this.file
 #endif
@@ -4603,7 +4405,6 @@
 #endif
 
 #ifdef FOR_find
-#define CLEANUP_find
 #ifndef TT
 #define TT this.find
 #endif
@@ -4612,7 +4413,6 @@
 #endif
 
 #ifdef FOR_flock
-#define CLEANUP_flock
 #ifndef TT
 #define TT this.flock
 #endif
@@ -4623,7 +4423,6 @@
 #endif
 
 #ifdef FOR_fmt
-#define CLEANUP_fmt
 #ifndef TT
 #define TT this.fmt
 #endif
@@ -4631,7 +4430,6 @@
 #endif
 
 #ifdef FOR_fold
-#define CLEANUP_fold
 #ifndef TT
 #define TT this.fold
 #endif
@@ -4642,7 +4440,6 @@
 #endif
 
 #ifdef FOR_free
-#define CLEANUP_free
 #ifndef TT
 #define TT this.free
 #endif
@@ -4650,18 +4447,17 @@
 #define FLAG_k (1<<1)
 #define FLAG_m (1<<2)
 #define FLAG_g (1<<3)
-#define FLAG_h (1<<4)
+#define FLAG_t (1<<4)
+#define FLAG_h (1<<5)
 #endif
 
 #ifdef FOR_freeramdisk
-#define CLEANUP_freeramdisk
 #ifndef TT
 #define TT this.freeramdisk
 #endif
 #endif
 
 #ifdef FOR_fsck
-#define CLEANUP_fsck
 #ifndef TT
 #define TT this.fsck
 #endif
@@ -4677,7 +4473,6 @@
 #endif
 
 #ifdef FOR_fsfreeze
-#define CLEANUP_fsfreeze
 #ifndef TT
 #define TT this.fsfreeze
 #endif
@@ -4686,14 +4481,12 @@
 #endif
 
 #ifdef FOR_fstype
-#define CLEANUP_fstype
 #ifndef TT
 #define TT this.fstype
 #endif
 #endif
 
 #ifdef FOR_fsync
-#define CLEANUP_fsync
 #ifndef TT
 #define TT this.fsync
 #endif
@@ -4701,7 +4494,6 @@
 #endif
 
 #ifdef FOR_ftpget
-#define CLEANUP_ftpget
 #ifndef TT
 #define TT this.ftpget
 #endif
@@ -4721,7 +4513,6 @@
 #endif
 
 #ifdef FOR_getconf
-#define CLEANUP_getconf
 #ifndef TT
 #define TT this.getconf
 #endif
@@ -4730,14 +4521,12 @@
 #endif
 
 #ifdef FOR_getenforce
-#define CLEANUP_getenforce
 #ifndef TT
 #define TT this.getenforce
 #endif
 #endif
 
 #ifdef FOR_getfattr
-#define CLEANUP_getfattr
 #ifndef TT
 #define TT this.getfattr
 #endif
@@ -4748,7 +4537,6 @@
 #endif
 
 #ifdef FOR_getopt
-#define CLEANUP_getopt
 #ifndef TT
 #define TT this.getopt
 #endif
@@ -4761,7 +4549,6 @@
 #endif
 
 #ifdef FOR_getty
-#define CLEANUP_getty
 #ifndef TT
 #define TT this.getty
 #endif
@@ -4778,45 +4565,7 @@
 #define FLAG_t (FORCED_FLAG<<10)
 #endif
 
-#ifdef FOR_gpiodetect
-#define CLEANUP_gpiodetect
-#ifndef TT
-#define TT this.gpiodetect
-#endif
-#endif
-
-#ifdef FOR_gpiofind
-#define CLEANUP_gpiofind
-#ifndef TT
-#define TT this.gpiofind
-#endif
-#endif
-
-#ifdef FOR_gpioget
-#define CLEANUP_gpioget
-#ifndef TT
-#define TT this.gpioget
-#endif
-#define FLAG_l (FORCED_FLAG<<0)
-#endif
-
-#ifdef FOR_gpioinfo
-#define CLEANUP_gpioinfo
-#ifndef TT
-#define TT this.gpioinfo
-#endif
-#endif
-
-#ifdef FOR_gpioset
-#define CLEANUP_gpioset
-#ifndef TT
-#define TT this.gpioset
-#endif
-#define FLAG_l (FORCED_FLAG<<0)
-#endif
-
 #ifdef FOR_grep
-#define CLEANUP_grep
 #ifndef TT
 #define TT this.grep
 #endif
@@ -4829,34 +4578,32 @@
 #define FLAG_e (1<<6)
 #define FLAG_q (1<<7)
 #define FLAG_l (1<<8)
-#define FLAG_L (1<<9)
-#define FLAG_c (1<<10)
-#define FLAG_w (1<<11)
-#define FLAG_v (1<<12)
-#define FLAG_s (1<<13)
-#define FLAG_R (1<<14)
-#define FLAG_r (1<<15)
-#define FLAG_o (1<<16)
-#define FLAG_n (1<<17)
-#define FLAG_i (1<<18)
-#define FLAG_h (1<<19)
-#define FLAG_b (1<<20)
-#define FLAG_a (1<<21)
-#define FLAG_I (1<<22)
-#define FLAG_H (1<<23)
-#define FLAG_F (1<<24)
-#define FLAG_E (1<<25)
-#define FLAG_z (1<<26)
-#define FLAG_Z (1<<27)
-#define FLAG_M (1<<28)
-#define FLAG_S (1<<29)
-#define FLAG_exclude_dir (1<<30)
-#define FLAG_color (1LL<<31)
-#define FLAG_line_buffered (1LL<<32)
+#define FLAG_c (1<<9)
+#define FLAG_w (1<<10)
+#define FLAG_v (1<<11)
+#define FLAG_s (1<<12)
+#define FLAG_R (1<<13)
+#define FLAG_r (1<<14)
+#define FLAG_o (1<<15)
+#define FLAG_n (1<<16)
+#define FLAG_i (1<<17)
+#define FLAG_h (1<<18)
+#define FLAG_b (1<<19)
+#define FLAG_a (1<<20)
+#define FLAG_I (1<<21)
+#define FLAG_H (1<<22)
+#define FLAG_F (1<<23)
+#define FLAG_E (1<<24)
+#define FLAG_z (1<<25)
+#define FLAG_Z (1<<26)
+#define FLAG_M (1<<27)
+#define FLAG_S (1<<28)
+#define FLAG_exclude_dir (1<<29)
+#define FLAG_color (1<<30)
+#define FLAG_line_buffered (1LL<<31)
 #endif
 
 #ifdef FOR_groupadd
-#define CLEANUP_groupadd
 #ifndef TT
 #define TT this.groupadd
 #endif
@@ -4865,21 +4612,18 @@
 #endif
 
 #ifdef FOR_groupdel
-#define CLEANUP_groupdel
 #ifndef TT
 #define TT this.groupdel
 #endif
 #endif
 
 #ifdef FOR_groups
-#define CLEANUP_groups
 #ifndef TT
 #define TT this.groups
 #endif
 #endif
 
 #ifdef FOR_gunzip
-#define CLEANUP_gunzip
 #ifndef TT
 #define TT this.gunzip
 #endif
@@ -4899,7 +4643,6 @@
 #endif
 
 #ifdef FOR_gzip
-#define CLEANUP_gzip
 #ifndef TT
 #define TT this.gzip
 #endif
@@ -4920,7 +4663,6 @@
 #endif
 
 #ifdef FOR_head
-#define CLEANUP_head
 #ifndef TT
 #define TT this.head
 #endif
@@ -4931,14 +4673,12 @@
 #endif
 
 #ifdef FOR_hello
-#define CLEANUP_hello
 #ifndef TT
 #define TT this.hello
 #endif
 #endif
 
 #ifdef FOR_help
-#define CLEANUP_help
 #ifndef TT
 #define TT this.help
 #endif
@@ -4947,24 +4687,7 @@
 #define FLAG_a (1<<2)
 #endif
 
-#ifdef FOR_hexdump
-#define CLEANUP_hexdump
-#ifndef TT
-#define TT this.hexdump
-#endif
-#define FLAG_x (FORCED_FLAG<<0)
-#define FLAG_v (FORCED_FLAG<<1)
-#define FLAG_s (FORCED_FLAG<<2)
-#define FLAG_o (FORCED_FLAG<<3)
-#define FLAG_n (FORCED_FLAG<<4)
-#define FLAG_d (FORCED_FLAG<<5)
-#define FLAG_C (FORCED_FLAG<<6)
-#define FLAG_c (FORCED_FLAG<<7)
-#define FLAG_b (FORCED_FLAG<<8)
-#endif
-
 #ifdef FOR_hexedit
-#define CLEANUP_hexedit
 #ifndef TT
 #define TT this.hexedit
 #endif
@@ -4972,7 +4695,6 @@
 #endif
 
 #ifdef FOR_host
-#define CLEANUP_host
 #ifndef TT
 #define TT this.host
 #endif
@@ -4982,14 +4704,12 @@
 #endif
 
 #ifdef FOR_hostid
-#define CLEANUP_hostid
 #ifndef TT
 #define TT this.hostid
 #endif
 #endif
 
 #ifdef FOR_hostname
-#define CLEANUP_hostname
 #ifndef TT
 #define TT this.hostname
 #endif
@@ -5001,7 +4721,6 @@
 #endif
 
 #ifdef FOR_hwclock
-#define CLEANUP_hwclock
 #ifndef TT
 #define TT this.hwclock
 #endif
@@ -5016,20 +4735,16 @@
 #endif
 
 #ifdef FOR_i2cdetect
-#define CLEANUP_i2cdetect
 #ifndef TT
 #define TT this.i2cdetect
 #endif
 #define FLAG_y (1<<0)
-#define FLAG_r (1<<1)
-#define FLAG_q (1<<2)
-#define FLAG_l (1<<3)
-#define FLAG_F (1<<4)
-#define FLAG_a (1<<5)
+#define FLAG_l (1<<1)
+#define FLAG_F (1<<2)
+#define FLAG_a (1<<3)
 #endif
 
 #ifdef FOR_i2cdump
-#define CLEANUP_i2cdump
 #ifndef TT
 #define TT this.i2cdump
 #endif
@@ -5038,7 +4753,6 @@
 #endif
 
 #ifdef FOR_i2cget
-#define CLEANUP_i2cget
 #ifndef TT
 #define TT this.i2cget
 #endif
@@ -5047,7 +4761,6 @@
 #endif
 
 #ifdef FOR_i2cset
-#define CLEANUP_i2cset
 #ifndef TT
 #define TT this.i2cset
 #endif
@@ -5056,7 +4769,6 @@
 #endif
 
 #ifdef FOR_iconv
-#define CLEANUP_iconv
 #ifndef TT
 #define TT this.iconv
 #endif
@@ -5067,7 +4779,6 @@
 #endif
 
 #ifdef FOR_id
-#define CLEANUP_id
 #ifndef TT
 #define TT this.id
 #endif
@@ -5080,7 +4791,6 @@
 #endif
 
 #ifdef FOR_ifconfig
-#define CLEANUP_ifconfig
 #ifndef TT
 #define TT this.ifconfig
 #endif
@@ -5089,28 +4799,24 @@
 #endif
 
 #ifdef FOR_init
-#define CLEANUP_init
 #ifndef TT
 #define TT this.init
 #endif
 #endif
 
 #ifdef FOR_inotifyd
-#define CLEANUP_inotifyd
 #ifndef TT
 #define TT this.inotifyd
 #endif
 #endif
 
 #ifdef FOR_insmod
-#define CLEANUP_insmod
 #ifndef TT
 #define TT this.insmod
 #endif
 #endif
 
 #ifdef FOR_install
-#define CLEANUP_install
 #ifndef TT
 #define TT this.install
 #endif
@@ -5127,7 +4833,6 @@
 #endif
 
 #ifdef FOR_ionice
-#define CLEANUP_ionice
 #ifndef TT
 #define TT this.ionice
 #endif
@@ -5138,14 +4843,12 @@
 #endif
 
 #ifdef FOR_iorenice
-#define CLEANUP_iorenice
 #ifndef TT
 #define TT this.iorenice
 #endif
 #endif
 
 #ifdef FOR_iotop
-#define CLEANUP_iotop
 #ifndef TT
 #define TT this.iotop
 #endif
@@ -5167,14 +4870,12 @@
 #endif
 
 #ifdef FOR_ip
-#define CLEANUP_ip
 #ifndef TT
 #define TT this.ip
 #endif
 #endif
 
 #ifdef FOR_ipcrm
-#define CLEANUP_ipcrm
 #ifndef TT
 #define TT this.ipcrm
 #endif
@@ -5187,7 +4888,6 @@
 #endif
 
 #ifdef FOR_ipcs
-#define CLEANUP_ipcs
 #ifndef TT
 #define TT this.ipcs
 #endif
@@ -5204,7 +4904,6 @@
 #endif
 
 #ifdef FOR_jobs
-#define CLEANUP_jobs
 #ifndef TT
 #define TT this.jobs
 #endif
@@ -5216,7 +4915,6 @@
 #endif
 
 #ifdef FOR_kill
-#define CLEANUP_kill
 #ifndef TT
 #define TT this.kill
 #endif
@@ -5225,7 +4923,6 @@
 #endif
 
 #ifdef FOR_killall
-#define CLEANUP_killall
 #ifndef TT
 #define TT this.killall
 #endif
@@ -5238,7 +4935,6 @@
 #endif
 
 #ifdef FOR_killall5
-#define CLEANUP_killall5
 #ifndef TT
 #define TT this.killall5
 #endif
@@ -5248,7 +4944,6 @@
 #endif
 
 #ifdef FOR_klogd
-#define CLEANUP_klogd
 #ifndef TT
 #define TT this.klogd
 #endif
@@ -5257,7 +4952,6 @@
 #endif
 
 #ifdef FOR_last
-#define CLEANUP_last
 #ifndef TT
 #define TT this.last
 #endif
@@ -5266,21 +4960,12 @@
 #endif
 
 #ifdef FOR_link
-#define CLEANUP_link
 #ifndef TT
 #define TT this.link
 #endif
 #endif
 
-#ifdef FOR_linux32
-#define CLEANUP_linux32
-#ifndef TT
-#define TT this.linux32
-#endif
-#endif
-
 #ifdef FOR_ln
-#define CLEANUP_ln
 #ifndef TT
 #define TT this.ln
 #endif
@@ -5294,14 +4979,12 @@
 #endif
 
 #ifdef FOR_load_policy
-#define CLEANUP_load_policy
 #ifndef TT
 #define TT this.load_policy
 #endif
 #endif
 
 #ifdef FOR_log
-#define CLEANUP_log
 #ifndef TT
 #define TT this.log
 #endif
@@ -5310,7 +4993,6 @@
 #endif
 
 #ifdef FOR_logger
-#define CLEANUP_logger
 #ifndef TT
 #define TT this.logger
 #endif
@@ -5320,7 +5002,6 @@
 #endif
 
 #ifdef FOR_login
-#define CLEANUP_login
 #ifndef TT
 #define TT this.login
 #endif
@@ -5330,21 +5011,18 @@
 #endif
 
 #ifdef FOR_logname
-#define CLEANUP_logname
 #ifndef TT
 #define TT this.logname
 #endif
 #endif
 
-#ifdef FOR_logpath
-#define CLEANUP_logpath
+#ifdef FOR_logwrapper
 #ifndef TT
-#define TT this.logpath
+#define TT this.logwrapper
 #endif
 #endif
 
 #ifdef FOR_losetup
-#define CLEANUP_losetup
 #ifndef TT
 #define TT this.losetup
 #endif
@@ -5361,7 +5039,6 @@
 #endif
 
 #ifdef FOR_ls
-#define CLEANUP_ls
 #ifndef TT
 #define TT this.ls
 #endif
@@ -5401,7 +5078,6 @@
 #endif
 
 #ifdef FOR_lsattr
-#define CLEANUP_lsattr
 #ifndef TT
 #define TT this.lsattr
 #endif
@@ -5414,14 +5090,12 @@
 #endif
 
 #ifdef FOR_lsmod
-#define CLEANUP_lsmod
 #ifndef TT
 #define TT this.lsmod
 #endif
 #endif
 
 #ifdef FOR_lsof
-#define CLEANUP_lsof
 #ifndef TT
 #define TT this.lsof
 #endif
@@ -5431,11 +5105,10 @@
 #endif
 
 #ifdef FOR_lspci
-#define CLEANUP_lspci
 #ifndef TT
 #define TT this.lspci
 #endif
-#define FLAG_i (1<<0)
+#define FLAG_i (FORCED_FLAG<<0)
 #define FLAG_n (1<<1)
 #define FLAG_k (1<<2)
 #define FLAG_m (1<<3)
@@ -5443,15 +5116,12 @@
 #endif
 
 #ifdef FOR_lsusb
-#define CLEANUP_lsusb
 #ifndef TT
 #define TT this.lsusb
 #endif
-#define FLAG_i (1<<0)
 #endif
 
 #ifdef FOR_makedevs
-#define CLEANUP_makedevs
 #ifndef TT
 #define TT this.makedevs
 #endif
@@ -5459,7 +5129,6 @@
 #endif
 
 #ifdef FOR_man
-#define CLEANUP_man
 #ifndef TT
 #define TT this.man
 #endif
@@ -5468,7 +5137,6 @@
 #endif
 
 #ifdef FOR_mcookie
-#define CLEANUP_mcookie
 #ifndef TT
 #define TT this.mcookie
 #endif
@@ -5477,7 +5145,6 @@
 #endif
 
 #ifdef FOR_md5sum
-#define CLEANUP_md5sum
 #ifndef TT
 #define TT this.md5sum
 #endif
@@ -5487,7 +5154,6 @@
 #endif
 
 #ifdef FOR_mdev
-#define CLEANUP_mdev
 #ifndef TT
 #define TT this.mdev
 #endif
@@ -5495,7 +5161,6 @@
 #endif
 
 #ifdef FOR_microcom
-#define CLEANUP_microcom
 #ifndef TT
 #define TT this.microcom
 #endif
@@ -5504,7 +5169,6 @@
 #endif
 
 #ifdef FOR_mix
-#define CLEANUP_mix
 #ifndef TT
 #define TT this.mix
 #endif
@@ -5515,7 +5179,6 @@
 #endif
 
 #ifdef FOR_mkdir
-#define CLEANUP_mkdir
 #ifndef TT
 #define TT this.mkdir
 #endif
@@ -5526,7 +5189,6 @@
 #endif
 
 #ifdef FOR_mke2fs
-#define CLEANUP_mke2fs
 #ifndef TT
 #define TT this.mke2fs
 #endif
@@ -5541,7 +5203,6 @@
 #endif
 
 #ifdef FOR_mkfifo
-#define CLEANUP_mkfifo
 #ifndef TT
 #define TT this.mkfifo
 #endif
@@ -5550,7 +5211,6 @@
 #endif
 
 #ifdef FOR_mknod
-#define CLEANUP_mknod
 #ifndef TT
 #define TT this.mknod
 #endif
@@ -5559,7 +5219,6 @@
 #endif
 
 #ifdef FOR_mkpasswd
-#define CLEANUP_mkpasswd
 #ifndef TT
 #define TT this.mkpasswd
 #endif
@@ -5569,7 +5228,6 @@
 #endif
 
 #ifdef FOR_mkswap
-#define CLEANUP_mkswap
 #ifndef TT
 #define TT this.mkswap
 #endif
@@ -5577,7 +5235,6 @@
 #endif
 
 #ifdef FOR_mktemp
-#define CLEANUP_mktemp
 #ifndef TT
 #define TT this.mktemp
 #endif
@@ -5590,7 +5247,6 @@
 #endif
 
 #ifdef FOR_modinfo
-#define CLEANUP_modinfo
 #ifndef TT
 #define TT this.modinfo
 #endif
@@ -5601,7 +5257,6 @@
 #endif
 
 #ifdef FOR_modprobe
-#define CLEANUP_modprobe
 #ifndef TT
 #define TT this.modprobe
 #endif
@@ -5617,14 +5272,12 @@
 #endif
 
 #ifdef FOR_more
-#define CLEANUP_more
 #ifndef TT
 #define TT this.more
 #endif
 #endif
 
 #ifdef FOR_mount
-#define CLEANUP_mount
 #ifndef TT
 #define TT this.mount
 #endif
@@ -5640,7 +5293,6 @@
 #endif
 
 #ifdef FOR_mountpoint
-#define CLEANUP_mountpoint
 #ifndef TT
 #define TT this.mountpoint
 #endif
@@ -5650,7 +5302,6 @@
 #endif
 
 #ifdef FOR_mv
-#define CLEANUP_mv
 #ifndef TT
 #define TT this.mv
 #endif
@@ -5664,7 +5315,6 @@
 #endif
 
 #ifdef FOR_nbd_client
-#define CLEANUP_nbd_client
 #ifndef TT
 #define TT this.nbd_client
 #endif
@@ -5673,7 +5323,6 @@
 #endif
 
 #ifdef FOR_netcat
-#define CLEANUP_netcat
 #ifndef TT
 #define TT this.netcat
 #endif
@@ -5694,7 +5343,6 @@
 #endif
 
 #ifdef FOR_netstat
-#define CLEANUP_netstat
 #ifndef TT
 #define TT this.netstat
 #endif
@@ -5712,7 +5360,6 @@
 #endif
 
 #ifdef FOR_nice
-#define CLEANUP_nice
 #ifndef TT
 #define TT this.nice
 #endif
@@ -5720,28 +5367,25 @@
 #endif
 
 #ifdef FOR_nl
-#define CLEANUP_nl
 #ifndef TT
 #define TT this.nl
 #endif
-#define FLAG_E (1<<0)
-#define FLAG_s (1<<1)
-#define FLAG_n (1<<2)
-#define FLAG_b (1<<3)
+#define FLAG_s (1<<0)
+#define FLAG_n (1<<1)
+#define FLAG_b (1<<2)
+#define FLAG_E (1<<3)
 #define FLAG_w (1<<4)
 #define FLAG_l (1<<5)
 #define FLAG_v (1<<6)
 #endif
 
 #ifdef FOR_nohup
-#define CLEANUP_nohup
 #ifndef TT
 #define TT this.nohup
 #endif
 #endif
 
 #ifdef FOR_nproc
-#define CLEANUP_nproc
 #ifndef TT
 #define TT this.nproc
 #endif
@@ -5749,7 +5393,6 @@
 #endif
 
 #ifdef FOR_nsenter
-#define CLEANUP_nsenter
 #ifndef TT
 #define TT this.nsenter
 #endif
@@ -5764,7 +5407,6 @@
 #endif
 
 #ifdef FOR_od
-#define CLEANUP_od
 #ifndef TT
 #define TT this.od
 #endif
@@ -5783,7 +5425,6 @@
 #endif
 
 #ifdef FOR_oneit
-#define CLEANUP_oneit
 #ifndef TT
 #define TT this.oneit
 #endif
@@ -5794,7 +5435,6 @@
 #endif
 
 #ifdef FOR_openvt
-#define CLEANUP_openvt
 #ifndef TT
 #define TT this.openvt
 #endif
@@ -5804,14 +5444,12 @@
 #endif
 
 #ifdef FOR_partprobe
-#define CLEANUP_partprobe
 #ifndef TT
 #define TT this.partprobe
 #endif
 #endif
 
 #ifdef FOR_passwd
-#define CLEANUP_passwd
 #ifndef TT
 #define TT this.passwd
 #endif
@@ -5822,7 +5460,6 @@
 #endif
 
 #ifdef FOR_paste
-#define CLEANUP_paste
 #ifndef TT
 #define TT this.paste
 #endif
@@ -5831,7 +5468,6 @@
 #endif
 
 #ifdef FOR_patch
-#define CLEANUP_patch
 #ifndef TT
 #define TT this.patch
 #endif
@@ -5851,7 +5487,6 @@
 #endif
 
 #ifdef FOR_pgrep
-#define CLEANUP_pgrep
 #ifndef TT
 #define TT this.pgrep
 #endif
@@ -5874,7 +5509,6 @@
 #endif
 
 #ifdef FOR_pidof
-#define CLEANUP_pidof
 #ifndef TT
 #define TT this.pidof
 #endif
@@ -5884,7 +5518,6 @@
 #endif
 
 #ifdef FOR_ping
-#define CLEANUP_ping
 #ifndef TT
 #define TT this.ping
 #endif
@@ -5903,14 +5536,12 @@
 #endif
 
 #ifdef FOR_pivot_root
-#define CLEANUP_pivot_root
 #ifndef TT
 #define TT this.pivot_root
 #endif
 #endif
 
 #ifdef FOR_pkill
-#define CLEANUP_pkill
 #ifndef TT
 #define TT this.pkill
 #endif
@@ -5931,17 +5562,14 @@
 #endif
 
 #ifdef FOR_pmap
-#define CLEANUP_pmap
 #ifndef TT
 #define TT this.pmap
 #endif
-#define FLAG_x (1<<0)
-#define FLAG_q (1<<1)
-#define FLAG_p (1<<2)
+#define FLAG_q (1<<0)
+#define FLAG_x (1<<1)
 #endif
 
 #ifdef FOR_printenv
-#define CLEANUP_printenv
 #ifndef TT
 #define TT this.printenv
 #endif
@@ -5950,14 +5578,12 @@
 #endif
 
 #ifdef FOR_printf
-#define CLEANUP_printf
 #ifndef TT
 #define TT this.printf
 #endif
 #endif
 
 #ifdef FOR_ps
-#define CLEANUP_ps
 #ifndef TT
 #define TT this.ps
 #endif
@@ -5986,7 +5612,6 @@
 #endif
 
 #ifdef FOR_pwd
-#define CLEANUP_pwd
 #ifndef TT
 #define TT this.pwd
 #endif
@@ -5995,7 +5620,6 @@
 #endif
 
 #ifdef FOR_pwdx
-#define CLEANUP_pwdx
 #ifndef TT
 #define TT this.pwdx
 #endif
@@ -6003,7 +5627,6 @@
 #endif
 
 #ifdef FOR_pwgen
-#define CLEANUP_pwgen
 #ifndef TT
 #define TT this.pwgen
 #endif
@@ -6022,14 +5645,12 @@
 #endif
 
 #ifdef FOR_readahead
-#define CLEANUP_readahead
 #ifndef TT
 #define TT this.readahead
 #endif
 #endif
 
 #ifdef FOR_readelf
-#define CLEANUP_readelf
 #ifndef TT
 #define TT this.readelf
 #endif
@@ -6048,7 +5669,6 @@
 #endif
 
 #ifdef FOR_readlink
-#define CLEANUP_readlink
 #ifndef TT
 #define TT this.readlink
 #endif
@@ -6059,18 +5679,21 @@
 #define FLAG_n (1<<4)
 #endif
 
+#ifdef FOR_realpath
+#ifndef TT
+#define TT this.realpath
+#endif
+#endif
+
 #ifdef FOR_reboot
-#define CLEANUP_reboot
 #ifndef TT
 #define TT this.reboot
 #endif
 #define FLAG_n (FORCED_FLAG<<0)
 #define FLAG_f (FORCED_FLAG<<1)
-#define FLAG_d (FORCED_FLAG<<2)
 #endif
 
 #ifdef FOR_renice
-#define CLEANUP_renice
 #ifndef TT
 #define TT this.renice
 #endif
@@ -6081,14 +5704,12 @@
 #endif
 
 #ifdef FOR_reset
-#define CLEANUP_reset
 #ifndef TT
 #define TT this.reset
 #endif
 #endif
 
 #ifdef FOR_restorecon
-#define CLEANUP_restorecon
 #ifndef TT
 #define TT this.restorecon
 #endif
@@ -6101,21 +5722,18 @@
 #endif
 
 #ifdef FOR_rev
-#define CLEANUP_rev
 #ifndef TT
 #define TT this.rev
 #endif
 #endif
 
 #ifdef FOR_rfkill
-#define CLEANUP_rfkill
 #ifndef TT
 #define TT this.rfkill
 #endif
 #endif
 
 #ifdef FOR_rm
-#define CLEANUP_rm
 #ifndef TT
 #define TT this.rm
 #endif
@@ -6127,7 +5745,6 @@
 #endif
 
 #ifdef FOR_rmdir
-#define CLEANUP_rmdir
 #ifndef TT
 #define TT this.rmdir
 #endif
@@ -6136,7 +5753,6 @@
 #endif
 
 #ifdef FOR_rmmod
-#define CLEANUP_rmmod
 #ifndef TT
 #define TT this.rmmod
 #endif
@@ -6145,7 +5761,6 @@
 #endif
 
 #ifdef FOR_route
-#define CLEANUP_route
 #ifndef TT
 #define TT this.route
 #endif
@@ -6155,7 +5770,6 @@
 #endif
 
 #ifdef FOR_rtcwake
-#define CLEANUP_rtcwake
 #ifndef TT
 #define TT this.rtcwake
 #endif
@@ -6172,14 +5786,12 @@
 #endif
 
 #ifdef FOR_runcon
-#define CLEANUP_runcon
 #ifndef TT
 #define TT this.runcon
 #endif
 #endif
 
 #ifdef FOR_sed
-#define CLEANUP_sed
 #ifndef TT
 #define TT this.sed
 #endif
@@ -6196,14 +5808,12 @@
 #endif
 
 #ifdef FOR_sendevent
-#define CLEANUP_sendevent
 #ifndef TT
 #define TT this.sendevent
 #endif
 #endif
 
 #ifdef FOR_seq
-#define CLEANUP_seq
 #ifndef TT
 #define TT this.seq
 #endif
@@ -6213,21 +5823,18 @@
 #endif
 
 #ifdef FOR_set
-#define CLEANUP_set
 #ifndef TT
 #define TT this.set
 #endif
 #endif
 
 #ifdef FOR_setenforce
-#define CLEANUP_setenforce
 #ifndef TT
 #define TT this.setenforce
 #endif
 #endif
 
 #ifdef FOR_setfattr
-#define CLEANUP_setfattr
 #ifndef TT
 #define TT this.setfattr
 #endif
@@ -6238,7 +5845,6 @@
 #endif
 
 #ifdef FOR_setsid
-#define CLEANUP_setsid
 #ifndef TT
 #define TT this.setsid
 #endif
@@ -6248,7 +5854,6 @@
 #endif
 
 #ifdef FOR_sh
-#define CLEANUP_sh
 #ifndef TT
 #define TT this.sh
 #endif
@@ -6260,8 +5865,16 @@
 #define FLAG_noediting (FORCED_FLAG<<5)
 #endif
 
+#ifdef FOR_sha1sum
+#ifndef TT
+#define TT this.sha1sum
+#endif
+#define FLAG_s (1<<0)
+#define FLAG_c (1<<1)
+#define FLAG_b (1<<2)
+#endif
+
 #ifdef FOR_sha3sum
-#define CLEANUP_sha3sum
 #ifndef TT
 #define TT this.sha3sum
 #endif
@@ -6271,14 +5884,12 @@
 #endif
 
 #ifdef FOR_shift
-#define CLEANUP_shift
 #ifndef TT
 #define TT this.shift
 #endif
 #endif
 
 #ifdef FOR_shred
-#define CLEANUP_shred
 #ifndef TT
 #define TT this.shred
 #endif
@@ -6292,7 +5903,6 @@
 #endif
 
 #ifdef FOR_skeleton
-#define CLEANUP_skeleton
 #ifndef TT
 #define TT this.skeleton
 #endif
@@ -6307,7 +5917,6 @@
 #endif
 
 #ifdef FOR_skeleton_alias
-#define CLEANUP_skeleton_alias
 #ifndef TT
 #define TT this.skeleton_alias
 #endif
@@ -6317,14 +5926,12 @@
 #endif
 
 #ifdef FOR_sleep
-#define CLEANUP_sleep
 #ifndef TT
 #define TT this.sleep
 #endif
 #endif
 
 #ifdef FOR_sntp
-#define CLEANUP_sntp
 #ifndef TT
 #define TT this.sntp
 #endif
@@ -6342,7 +5949,6 @@
 #endif
 
 #ifdef FOR_sort
-#define CLEANUP_sort
 #ifndef TT
 #define TT this.sort
 #endif
@@ -6369,25 +5975,21 @@
 #endif
 
 #ifdef FOR_source
-#define CLEANUP_source
 #ifndef TT
 #define TT this.source
 #endif
 #endif
 
 #ifdef FOR_split
-#define CLEANUP_split
 #ifndef TT
 #define TT this.split
 #endif
-#define FLAG_n (1<<0)
-#define FLAG_l (1<<1)
-#define FLAG_b (1<<2)
-#define FLAG_a (1<<3)
+#define FLAG_l (1<<0)
+#define FLAG_b (1<<1)
+#define FLAG_a (1<<2)
 #endif
 
 #ifdef FOR_stat
-#define CLEANUP_stat
 #ifndef TT
 #define TT this.stat
 #endif
@@ -6397,18 +5999,7 @@
 #define FLAG_c (1<<3)
 #endif
 
-#ifdef FOR_strace
-#define CLEANUP_strace
-#ifndef TT
-#define TT this.strace
-#endif
-#define FLAG_v (FORCED_FLAG<<0)
-#define FLAG_s (FORCED_FLAG<<1)
-#define FLAG_p (FORCED_FLAG<<2)
-#endif
-
 #ifdef FOR_strings
-#define CLEANUP_strings
 #ifndef TT
 #define TT this.strings
 #endif
@@ -6420,7 +6011,6 @@
 #endif
 
 #ifdef FOR_stty
-#define CLEANUP_stty
 #ifndef TT
 #define TT this.stty
 #endif
@@ -6430,7 +6020,6 @@
 #endif
 
 #ifdef FOR_su
-#define CLEANUP_su
 #ifndef TT
 #define TT this.su
 #endif
@@ -6444,7 +6033,6 @@
 #endif
 
 #ifdef FOR_sulogin
-#define CLEANUP_sulogin
 #ifndef TT
 #define TT this.sulogin
 #endif
@@ -6452,14 +6040,12 @@
 #endif
 
 #ifdef FOR_swapoff
-#define CLEANUP_swapoff
 #ifndef TT
 #define TT this.swapoff
 #endif
 #endif
 
 #ifdef FOR_swapon
-#define CLEANUP_swapon
 #ifndef TT
 #define TT this.swapon
 #endif
@@ -6468,7 +6054,6 @@
 #endif
 
 #ifdef FOR_switch_root
-#define CLEANUP_switch_root
 #ifndef TT
 #define TT this.switch_root
 #endif
@@ -6477,14 +6062,12 @@
 #endif
 
 #ifdef FOR_sync
-#define CLEANUP_sync
 #ifndef TT
 #define TT this.sync
 #endif
 #endif
 
 #ifdef FOR_sysctl
-#define CLEANUP_sysctl
 #ifndef TT
 #define TT this.sysctl
 #endif
@@ -6499,7 +6082,6 @@
 #endif
 
 #ifdef FOR_syslogd
-#define CLEANUP_syslogd
 #ifndef TT
 #define TT this.syslogd
 #endif
@@ -6520,26 +6102,21 @@
 #endif
 
 #ifdef FOR_tac
-#define CLEANUP_tac
 #ifndef TT
 #define TT this.tac
 #endif
 #endif
 
 #ifdef FOR_tail
-#define CLEANUP_tail
 #ifndef TT
 #define TT this.tail
 #endif
 #define FLAG_n (1<<0)
 #define FLAG_c (1<<1)
-#define FLAG_s (1<<2)
-#define FLAG_F (1<<3)
-#define FLAG_f (1<<4)
+#define FLAG_f (1<<2)
 #endif
 
 #ifdef FOR_tar
-#define CLEANUP_tar
 #ifndef TT
 #define TT this.tar
 #endif
@@ -6576,12 +6153,9 @@
 #define FLAG_no_recursion (1<<30)
 #define FLAG_full_time (1LL<<31)
 #define FLAG_restrict (1LL<<32)
-#define FLAG_selinux (1LL<<33)
-#define FLAG_strip_components (1LL<<34)
 #endif
 
 #ifdef FOR_taskset
-#define CLEANUP_taskset
 #ifndef TT
 #define TT this.taskset
 #endif
@@ -6590,7 +6164,6 @@
 #endif
 
 #ifdef FOR_tcpsvd
-#define CLEANUP_tcpsvd
 #ifndef TT
 #define TT this.tcpsvd
 #endif
@@ -6605,7 +6178,6 @@
 #endif
 
 #ifdef FOR_tee
-#define CLEANUP_tee
 #ifndef TT
 #define TT this.tee
 #endif
@@ -6614,14 +6186,12 @@
 #endif
 
 #ifdef FOR_telnet
-#define CLEANUP_telnet
 #ifndef TT
 #define TT this.telnet
 #endif
 #endif
 
 #ifdef FOR_telnetd
-#define CLEANUP_telnetd
 #ifndef TT
 #define TT this.telnetd
 #endif
@@ -6637,14 +6207,12 @@
 #endif
 
 #ifdef FOR_test
-#define CLEANUP_test
 #ifndef TT
 #define TT this.test
 #endif
 #endif
 
 #ifdef FOR_tftp
-#define CLEANUP_tftp
 #ifndef TT
 #define TT this.tftp
 #endif
@@ -6656,7 +6224,6 @@
 #endif
 
 #ifdef FOR_tftpd
-#define CLEANUP_tftpd
 #ifndef TT
 #define TT this.tftpd
 #endif
@@ -6667,7 +6234,6 @@
 #endif
 
 #ifdef FOR_time
-#define CLEANUP_time
 #ifndef TT
 #define TT this.time
 #endif
@@ -6676,7 +6242,6 @@
 #endif
 
 #ifdef FOR_timeout
-#define CLEANUP_timeout
 #ifndef TT
 #define TT this.timeout
 #endif
@@ -6688,7 +6253,6 @@
 #endif
 
 #ifdef FOR_top
-#define CLEANUP_top
 #ifndef TT
 #define TT this.top
 #endif
@@ -6703,12 +6267,10 @@
 #define FLAG_o (1<<8)
 #define FLAG_k (1<<9)
 #define FLAG_H (1<<10)
-#define FLAG_h (1<<11)
-#define FLAG_O (1<<12)
+#define FLAG_O (1<<11)
 #endif
 
 #ifdef FOR_touch
-#define CLEANUP_touch
 #ifndef TT
 #define TT this.touch
 #endif
@@ -6723,14 +6285,12 @@
 #endif
 
 #ifdef FOR_toybox
-#define CLEANUP_toybox
 #ifndef TT
 #define TT this.toybox
 #endif
 #endif
 
 #ifdef FOR_tr
-#define CLEANUP_tr
 #ifndef TT
 #define TT this.tr
 #endif
@@ -6741,7 +6301,6 @@
 #endif
 
 #ifdef FOR_traceroute
-#define CLEANUP_traceroute
 #ifndef TT
 #define TT this.traceroute
 #endif
@@ -6768,14 +6327,12 @@
 #endif
 
 #ifdef FOR_true
-#define CLEANUP_true
 #ifndef TT
 #define TT this.true
 #endif
 #endif
 
 #ifdef FOR_truncate
-#define CLEANUP_truncate
 #ifndef TT
 #define TT this.truncate
 #endif
@@ -6784,7 +6341,6 @@
 #endif
 
 #ifdef FOR_tty
-#define CLEANUP_tty
 #ifndef TT
 #define TT this.tty
 #endif
@@ -6792,7 +6348,6 @@
 #endif
 
 #ifdef FOR_tunctl
-#define CLEANUP_tunctl
 #ifndef TT
 #define TT this.tunctl
 #endif
@@ -6802,20 +6357,7 @@
 #define FLAG_t (1<<3)
 #endif
 
-#ifdef FOR_uclampset
-#define CLEANUP_uclampset
-#ifndef TT
-#define TT this.uclampset
-#endif
-#define FLAG_R (1<<0)
-#define FLAG_M (1<<1)
-#define FLAG_m (1<<2)
-#define FLAG_a (1<<3)
-#define FLAG_p (1<<4)
-#endif
-
 #ifdef FOR_ulimit
-#define CLEANUP_ulimit
 #ifndef TT
 #define TT this.ulimit
 #endif
@@ -6842,7 +6384,6 @@
 #endif
 
 #ifdef FOR_umount
-#define CLEANUP_umount
 #ifndef TT
 #define TT this.umount
 #endif
@@ -6859,7 +6400,6 @@
 #endif
 
 #ifdef FOR_uname
-#define CLEANUP_uname
 #ifndef TT
 #define TT this.uname
 #endif
@@ -6868,19 +6408,17 @@
 #define FLAG_r (1<<2)
 #define FLAG_v (1<<3)
 #define FLAG_m (1<<4)
-#define FLAG_o (1<<5)
-#define FLAG_a (1<<6)
+#define FLAG_a (1<<5)
+#define FLAG_o (1<<6)
 #endif
 
 #ifdef FOR_unicode
-#define CLEANUP_unicode
 #ifndef TT
 #define TT this.unicode
 #endif
 #endif
 
 #ifdef FOR_uniq
-#define CLEANUP_uniq
 #ifndef TT
 #define TT this.uniq
 #endif
@@ -6895,21 +6433,18 @@
 #endif
 
 #ifdef FOR_unix2dos
-#define CLEANUP_unix2dos
 #ifndef TT
 #define TT this.unix2dos
 #endif
 #endif
 
 #ifdef FOR_unlink
-#define CLEANUP_unlink
 #ifndef TT
 #define TT this.unlink
 #endif
 #endif
 
 #ifdef FOR_unset
-#define CLEANUP_unset
 #ifndef TT
 #define TT this.unset
 #endif
@@ -6919,7 +6454,6 @@
 #endif
 
 #ifdef FOR_unshare
-#define CLEANUP_unshare
 #ifndef TT
 #define TT this.unshare
 #endif
@@ -6934,7 +6468,6 @@
 #endif
 
 #ifdef FOR_uptime
-#define CLEANUP_uptime
 #ifndef TT
 #define TT this.uptime
 #endif
@@ -6943,7 +6476,6 @@
 #endif
 
 #ifdef FOR_useradd
-#define CLEANUP_useradd
 #ifndef TT
 #define TT this.useradd
 #endif
@@ -6958,7 +6490,6 @@
 #endif
 
 #ifdef FOR_userdel
-#define CLEANUP_userdel
 #ifndef TT
 #define TT this.userdel
 #endif
@@ -6966,14 +6497,12 @@
 #endif
 
 #ifdef FOR_usleep
-#define CLEANUP_usleep
 #ifndef TT
 #define TT this.usleep
 #endif
 #endif
 
 #ifdef FOR_uudecode
-#define CLEANUP_uudecode
 #ifndef TT
 #define TT this.uudecode
 #endif
@@ -6981,7 +6510,6 @@
 #endif
 
 #ifdef FOR_uuencode
-#define CLEANUP_uuencode
 #ifndef TT
 #define TT this.uuencode
 #endif
@@ -6989,7 +6517,6 @@
 #endif
 
 #ifdef FOR_uuidgen
-#define CLEANUP_uuidgen
 #ifndef TT
 #define TT this.uuidgen
 #endif
@@ -6997,14 +6524,12 @@
 #endif
 
 #ifdef FOR_vconfig
-#define CLEANUP_vconfig
 #ifndef TT
 #define TT this.vconfig
 #endif
 #endif
 
 #ifdef FOR_vi
-#define CLEANUP_vi
 #ifndef TT
 #define TT this.vi
 #endif
@@ -7012,7 +6537,6 @@
 #endif
 
 #ifdef FOR_vmstat
-#define CLEANUP_vmstat
 #ifndef TT
 #define TT this.vmstat
 #endif
@@ -7020,14 +6544,12 @@
 #endif
 
 #ifdef FOR_w
-#define CLEANUP_w
 #ifndef TT
 #define TT this.w
 #endif
 #endif
 
 #ifdef FOR_wait
-#define CLEANUP_wait
 #ifndef TT
 #define TT this.wait
 #endif
@@ -7035,7 +6557,6 @@
 #endif
 
 #ifdef FOR_watch
-#define CLEANUP_watch
 #ifndef TT
 #define TT this.watch
 #endif
@@ -7047,7 +6568,6 @@
 #endif
 
 #ifdef FOR_watchdog
-#define CLEANUP_watchdog
 #ifndef TT
 #define TT this.watchdog
 #endif
@@ -7057,7 +6577,6 @@
 #endif
 
 #ifdef FOR_wc
-#define CLEANUP_wc
 #ifndef TT
 #define TT this.wc
 #endif
@@ -7068,18 +6587,14 @@
 #endif
 
 #ifdef FOR_wget
-#define CLEANUP_wget
 #ifndef TT
 #define TT this.wget
 #endif
-#define FLAG_p (FORCED_FLAG<<0)
-#define FLAG_O (FORCED_FLAG<<1)
-#define FLAG_d (FORCED_FLAG<<2)
-#define FLAG_max_redirect (FORCED_FLAG<<3)
+#define FLAG_O (FORCED_FLAG<<0)
+#define FLAG_no_check_certificate (FORCED_FLAG<<1)
 #endif
 
 #ifdef FOR_which
-#define CLEANUP_which
 #ifndef TT
 #define TT this.which
 #endif
@@ -7087,7 +6602,6 @@
 #endif
 
 #ifdef FOR_who
-#define CLEANUP_who
 #ifndef TT
 #define TT this.who
 #endif
@@ -7095,7 +6609,6 @@
 #endif
 
 #ifdef FOR_xargs
-#define CLEANUP_xargs
 #ifndef TT
 #define TT this.xargs
 #endif
@@ -7111,7 +6624,6 @@
 #endif
 
 #ifdef FOR_xxd
-#define CLEANUP_xxd
 #ifndef TT
 #define TT this.xxd
 #endif
@@ -7126,21 +6638,18 @@
 #endif
 
 #ifdef FOR_xzcat
-#define CLEANUP_xzcat
 #ifndef TT
 #define TT this.xzcat
 #endif
 #endif
 
 #ifdef FOR_yes
-#define CLEANUP_yes
 #ifndef TT
 #define TT this.yes
 #endif
 #endif
 
 #ifdef FOR_zcat
-#define CLEANUP_zcat
 #ifndef TT
 #define TT this.zcat
 #endif
diff --git a/android/device/generated/globals.h b/android/device/generated/globals.h
index 403077b..7d5e3be 100644
--- a/android/device/generated/globals.h
+++ b/android/device/generated/globals.h
@@ -72,16 +72,15 @@
 
 struct md5sum_data {
   int sawline;
-  unsigned *rconsttable32;
-  unsigned long long *rconsttable64; // for sha384,sha512
 
+  unsigned *md5table;
   // Crypto variables blanked after summing
-  unsigned long long count, overflow;
+  unsigned state[5], oldstate[5];
+  unsigned long long count;
   union {
-    char c[128]; // bytes, 1024 bits
-    unsigned i32[16]; // 512 bits for md5,sha1,sha224,sha256
-    unsigned long long i64[16]; // 1024 bits for sha384,sha512
-  } state, buffer;
+    char c[64];
+    unsigned i[16];
+  } buffer;
 };
 
 // toys/lsb/mknod.c
@@ -117,7 +116,7 @@
 // toys/lsb/pidof.c
 
 struct pidof_data {
-  char *o;
+  char *omit;
 };
 
 // toys/lsb/seq.c
@@ -151,15 +150,6 @@
   int fd;
 };
 
-// toys/net/host.c
-
-struct host_data {
-  char *t;
-
-  char **nsname;
-  unsigned nslen;
-};
-
 // toys/net/ifconfig.c
 
 struct ifconfig_data {
@@ -281,20 +271,17 @@
   char *buf;
 };
 
-// toys/other/gpiod.c
-
-struct gpiod_data {
-  struct double_list *chips;
-  int chip_count;
-};
-
 // toys/other/hexedit.c
 
 struct hexedit_data {
-  char *data, *search, keybuf[16], input[80];
-  long long len, base, pos;
-  int numlen, undo, undolen, mode;
+  char *data;
+  long long len, base;
+  int numlen, undo, undolen;
   unsigned rows, cols;
+  long long pos;
+  char keybuf[16];
+  char input[80];
+  char *search;
 };
 
 // toys/other/hwclock.c
@@ -332,21 +319,21 @@
 // toys/other/lsattr.c
 
 struct lsattr_data {
-  long v, p;
+  long v;
+  long p;
 
-  unsigned add, rm, set;
+  long add, rm, set;
   // !add and !rm tell us whether they were used, but `chattr =` is meaningful.
   int have_set;
 };
 
-// toys/other/lsusb.c
+// toys/other/lspci.c
 
-struct lsusb_data {
+struct lspci_data {
   char *i;
   long n;
 
-  void *ids, *class;
-  int count;
+  FILE *db;
 };
 
 // toys/other/makedevs.c
@@ -397,34 +384,12 @@
   char *c;
 };
 
-// toys/other/openvt.c
-
-struct openvt_data {
-  long c;
-};
-
 // toys/other/pwgen.c
 
 struct pwgen_data {
   char *r;
 };
 
-// toys/other/readelf.c
-
-struct readelf_data {
-  char *x, *p;
-
-  char *elf, *shstrtab, *f;
-  unsigned long long shoff, phoff, size, shstrtabsz;
-  int bits, endian, shnum, shentsize, phentsize;
-};
-
-// toys/other/reboot.c
-
-struct reboot_data {
-  char *d;
-};
-
 // toys/other/rtcwake.c
 
 struct rtcwake_data {
@@ -491,9 +456,8 @@
 
   int nextsig;
   pid_t pid;
-  struct timespec kts;
-  struct itimerspec its;
-  timer_t timer;
+  struct timeval ktv;
+  struct itimerval itv;
 };
 
 // toys/other/truncate.c
@@ -505,12 +469,6 @@
   int type;
 };
 
-// toys/other/uclampset.c
-
-struct uclampset_data {
-  long M, m, p;
-};
-
 // toys/other/watch.c
 
 struct watch_data {
@@ -540,7 +498,7 @@
     char *af_type_A;
     char *af_type_p;
     char *interface;
-
+    
     int sockfd;
     char *device;
 };
@@ -574,7 +532,7 @@
 // toys/pending/bootchartd.c
 
 struct bootchartd_data {
-  char timestamp[32];
+  char buf[32];
   long msec;
   int proc_accounting;
 
@@ -751,17 +709,10 @@
   long gid;
 };
 
-// toys/pending/hexdump.c
+// toys/pending/host.c
 
-struct hexdump_data {
-    long s, n;
-
-    long long len, pos, ppos;
-    const char *fmt;
-    unsigned int fn, bc;  // file number and byte count
-    char linebuf[16];  // line buffer - serves double duty for sqeezing repeat
-                       // lines and for accumulating full lines accross file
-                       // boundaries if necessesary.
+struct host_data {
+  char *type_str;
 };
 
 // toys/pending/ip.c
@@ -868,6 +819,22 @@
   int cin_fd;
 };
 
+// toys/pending/openvt.c
+
+struct openvt_data {
+  long c;
+};
+
+// toys/pending/readelf.c
+
+struct readelf_data {
+  char *x, *p;
+
+  char *elf, *shstrtab, *f;
+  unsigned long long shoff, phoff, size, shstrtabsz;
+  int bits, endian, shnum, shentsize, phentsize;
+};
+
 // toys/pending/route.c
 
 struct route_data {
@@ -890,7 +857,7 @@
   long long SECONDS;
   char *isexec, *wcpat;
   unsigned options, jobcnt, LINENO;
-  int hfd, pid, bangpid, varslen, srclvl, recursion;
+  int hfd, pid, bangpid, varslen, cdcount, srclvl, recursion;
 
   // Callable function array
   struct sh_function {
@@ -941,7 +908,7 @@
     struct sh_process *next, *prev; // | && ||
     struct arg_list *delete;   // expanded strings
     // undo redirects, a=b at start, child PID, exit status, has !, job #
-    int *urd, envlen, pid, exit, flags, job, dash;
+    int *urd, envlen, pid, exit, not, job, dash;
     long long when; // when job backgrounded/suspended
     struct sh_arg *raw, arg;
   } *pp; // currently running process
@@ -950,17 +917,6 @@
   struct sh_arg jobs, *wcdeck;
 };
 
-// toys/pending/strace.c
-
-struct strace_data {
-  long s, p;
-
-  char ioctl[32], *fmt;
-  long regs[256/sizeof(long)], syscall;
-  pid_t pid;
-  int arg;
-};
-
 // toys/pending/stty.c
 
 struct stty_data {
@@ -1159,17 +1115,7 @@
 // toys/pending/wget.c
 
 struct wget_data {
-  char *p, *O;
-  long max_redirect;
-
-  int sock, https;
-  char *url;
-#if CFG_WGET_LIBTLS
-  struct tls *tls;
-#elif CFG_WGET_OPENSSL
-  struct ssl_ctx_st *ctx;
-  struct ssl_st *ssl;
-#endif
+  char *filename;
 };
 
 // toys/posix/basename.c
@@ -1208,8 +1154,6 @@
 // toys/posix/cmp.c
 
 struct cmp_data {
-  long n;
-
   int fd;
   char *name;
 };
@@ -1248,7 +1192,6 @@
   char *d, *O;
   struct arg_list *select[5]; // we treat them the same, so loop through
 
-  unsigned line;
   int pairs;
   regex_t reg;
 };
@@ -1256,7 +1199,7 @@
 // toys/posix/date.c
 
 struct date_data {
-  char *s, *r, *I, *D, *d;
+  char *r, *I, *D, *d;
 
   unsigned nano;
 };
@@ -1297,6 +1240,7 @@
 
 struct file_data {
   int max_name_len;
+
   off_t len;
 };
 
@@ -1406,7 +1350,8 @@
   long w, l, v;
 
   // Count of consecutive blank lines for -l has to persist between files
-  long lcount, slen;
+  long lcount;
+  long slen;
 };
 
 // toys/posix/od.c
@@ -1467,7 +1412,7 @@
 
   struct ptr_len gg, GG, pp, PP, ss, tt, uu, UU;
   struct dirtree *threadparent;
-  unsigned width, height, scroll;
+  unsigned width, height;
   dev_t tty;
   void *fields, *kfields;
   long long ticks, bits, time;
@@ -1507,14 +1452,14 @@
   char *o, *T, S;
 
   void *key_list;
-  unsigned linecount;
+  int linecount;
   char **lines, *name;
 };
 
 // toys/posix/split.c
 
 struct split_data {
-  long n, l, b, a;
+  long l, b, a;
 
   char *outfile;
 };
@@ -1530,16 +1475,9 @@
 
 struct tail_data {
   long n, c;
-  char *s;
 
-  int file_no, last_fd, ss;
+  int file_no, last_fd;
   struct xnotify *not;
-  struct {
-    char *path;
-    int fd;
-    dev_t dev;
-    ino_t ino;
-  } *F;
 };
 
 // toys/posix/tar.c
@@ -1549,12 +1487,11 @@
   struct arg_list *T, *X;
   char *I, *to_command, *owner, *group, *mtime, *mode;
   struct arg_list *exclude;
-  long strip_components;
 
   struct double_list *incl, *excl, *seen;
   struct string_list *dirs;
   char *cwd;
-  int fd, ouid, ggid, hlc, warn, adev, aino, sparselen, pid;
+  int fd, ouid, ggid, hlc, warn, adev, aino, sparselen;
   long long *sparse;
   time_t mtt;
 
@@ -1646,7 +1583,6 @@
 	struct su_data su;
 	struct umount_data umount;
 	struct ftpget_data ftpget;
-	struct host_data host;
 	struct ifconfig_data ifconfig;
 	struct microcom_data microcom;
 	struct netcat_data netcat;
@@ -1664,14 +1600,13 @@
 	struct fallocate_data fallocate;
 	struct fmt_data fmt;
 	struct free_data free;
-	struct gpiod_data gpiod;
 	struct hexedit_data hexedit;
 	struct hwclock_data hwclock;
 	struct ionice_data ionice;
 	struct login_data login;
 	struct losetup_data losetup;
 	struct lsattr_data lsattr;
-	struct lsusb_data lsusb;
+	struct lspci_data lspci;
 	struct makedevs_data makedevs;
 	struct mix_data mix;
 	struct mkpasswd_data mkpasswd;
@@ -1679,10 +1614,7 @@
 	struct modinfo_data modinfo;
 	struct nsenter_data nsenter;
 	struct oneit_data oneit;
-	struct openvt_data openvt;
 	struct pwgen_data pwgen;
-	struct readelf_data readelf;
-	struct reboot_data reboot;
 	struct rtcwake_data rtcwake;
 	struct setfattr_data setfattr;
 	struct sha3sum_data sha3sum;
@@ -1693,7 +1625,6 @@
 	struct tac_data tac;
 	struct timeout_data timeout;
 	struct truncate_data truncate;
-	struct uclampset_data uclampset;
 	struct watch_data watch;
 	struct watchdog_data watchdog;
 	struct xxd_data xxd;
@@ -1719,7 +1650,7 @@
 	struct getopt_data getopt;
 	struct getty_data getty;
 	struct groupadd_data groupadd;
-	struct hexdump_data hexdump;
+	struct host_data host;
 	struct ip_data ip;
 	struct ipcrm_data ipcrm;
 	struct ipcs_data ipcs;
@@ -1730,9 +1661,10 @@
 	struct mke2fs_data mke2fs;
 	struct modprobe_data modprobe;
 	struct more_data more;
+	struct openvt_data openvt;
+	struct readelf_data readelf;
 	struct route_data route;
 	struct sh_data sh;
-	struct strace_data strace;
 	struct stty_data stty;
 	struct sulogin_data sulogin;
 	struct syslogd_data syslogd;
diff --git a/android/device/generated/help.h b/android/device/generated/help.h
index 04e6212..ebddd3b 100644
--- a/android/device/generated/help.h
+++ b/android/device/generated/help.h
@@ -4,6 +4,8 @@
 
 #define HELP_toybox_uid_sys "When commands like useradd/groupadd allocate system IDs, start here."
 
+#define HELP_toybox_pedantic_args "Check arguments for commands that have no arguments."
+
 #define HELP_toybox_debug "Enable extra checks for debugging purposes. All of them catch\nthings that can only go wrong at development time, not runtime."
 
 #define HELP_toybox_norecurse "When one toybox command calls another, usually it just calls the new\ncommand's main() function rather than searching the $PATH and calling\nexec on another file (which is much slower).\n\nThis disables that optimization, so toybox will run external commands\n       even when it has a built-in version of that command. This requires\n       toybox symlinks to be installed in the $PATH, or re-invoking the\n       \"toybox\" multiplexer command by name."
@@ -38,17 +40,17 @@
 
 #define HELP_restorecon "usage: restorecon [-D] [-F] [-R] [-n] [-v] FILE...\n\nRestores the default security contexts for the given files.\n\n-D	Apply to /data/data too\n-F	Force reset\n-R	Recurse into directories\n-n	Don't make any changes; useful with -v to see what would change\n-v	Verbose"
 
-#define HELP_log "usage: log [-p PRI] [-t TAG] [MESSAGE...]\n\nLogs message (or stdin) to logcat.\n\n-p	Use the given priority instead of INFO:\n	d: DEBUG  e: ERROR  f: FATAL  i: INFO  v: VERBOSE  w: WARN  s: SILENT\n-t	Use the given tag instead of \"log\""
+#define HELP_log "usage: log [-p PRI] [-t TAG] MESSAGE...\n\nLogs message to logcat.\n\n-p	Use the given priority instead of INFO:\n	d: DEBUG  e: ERROR  f: FATAL  i: INFO  v: VERBOSE  w: WARN  s: SILENT\n-t	Use the given tag instead of \"log\""
 
 #define HELP_load_policy "usage: load_policy FILE\n\nLoad the specified SELinux policy file."
 
 #define HELP_getenforce "usage: getenforce\n\nShows whether SELinux is disabled, enforcing, or permissive."
 
-#define HELP_skeleton_alias "usage: skeleton_alias [-dq] [-b NUMBER]\n\nExample of a second command with different arguments in the same source\nfile as the first. This allows shared infrastructure outside of lib/."
+#define HELP_skeleton_alias "usage: skeleton_alias [-dq] [-b NUMBER]\n\nExample of a second command with different arguments in the same source\nfile as the first. This allows shared infrastructure not added to lib/."
 
 #define HELP_skeleton "usage: skeleton [-a] [-b STRING] [-c NUMBER] [-d LIST] [-e COUNT] [...]\n\nTemplate for new commands. You don't need this.\n\nWhen creating a new command, copy this file and delete the parts you\ndon't need. Be sure to replace all instances of \"skeleton\" (upper and lower\ncase) with your new command name.\n\nFor simple commands, \"hello.c\" is probably a better starting point."
 
-#define HELP_logpath "usage: logpath ...\n\nAppend command line to $LOGPATH, then call second instance\nof command in $PATH."
+#define HELP_logwrapper "usage: logwrapper ...\n\nAppend command line to $WRAPLOG, then call second instance\nof command in $PATH."
 
 #define HELP_hostid "usage: hostid\n\nPrint the numeric identifier for the current host."
 
@@ -70,7 +72,7 @@
 
 #define HELP_seq "usage: seq [-w|-f fmt_str] [-s sep_str] [first] [increment] last\n\nCount from first to last, by increment. Omitted arguments default\nto 1. Two arguments are used as first and last. Arguments can be\nnegative or floating point.\n\n-f	Use fmt_str as a printf-style floating point format string\n-s	Use sep_str as separator, default is a newline character\n-w	Pad to equal width with leading zeroes"
 
-#define HELP_pidof "usage: pidof [-s] [-o omitpid[,omitpid...]] [NAME...]\n\nPrint the PIDs of all processes with the given names.\n\n-o	Omit PID(s)\n-s	Single shot, only return one pid\n-x	Match shell scripts too"
+#define HELP_pidof "usage: pidof [-s] [-o omitpid[,omitpid...]] [NAME]...\n\nPrint the PIDs of all processes with the given names.\n\n-s	Single shot, only return one pid\n-o	Omit PID(s)\n-x	Match shell scripts too"
 
 #define HELP_passwd_sad "Password changes are checked to make sure they're at least 6 chars long,\ndon't include the entire username (but not a subset of it), or the entire\nprevious password (but changing password1, password2, password3 is fine).\nThis heuristic accepts \"aaaaaa\" and \"123456\"."
 
@@ -84,17 +86,17 @@
 
 #define HELP_mknod "usage: mknod [-m MODE] NAME TYPE [MAJOR MINOR]\n\nCreate a special file NAME with a given type. TYPE is b for block device,\nc or u for character device, p for named pipe (which ignores MAJOR/MINOR).\n\n-m	Mode (file permissions) of new device, in octal or u+x format"
 
-#define HELP_sha512sum "See md5sum"
+#define HELP_sha512sum "See sha1sum"
 
-#define HELP_sha384sum "See md5sum"
+#define HELP_sha384sum "See sha1sum"
 
-#define HELP_sha256sum "See md5sum"
+#define HELP_sha256sum "See sha1sum"
 
-#define HELP_sha224sum "See md5sum"
+#define HELP_sha224sum "See sha1sum"
 
-#define HELP_sha1sum "See md5sum"
+#define HELP_sha1sum "usage: sha?sum [-bcs] [FILE]...\n\nCalculate sha hash for each input file, reading from stdin if none. Output\none hash (40 hex digits for sha1, 56 for sha224, 64 for sha256, 96 for sha384,\nand 128 for sha512) for each input file, followed by filename.\n\n-b	Brief (hash only, no filename)\n-c	Check each line of each FILE is the same hash+filename we'd output\n-s	No output, exit status 0 if all hashes match, 1 otherwise"
 
-#define HELP_md5sum "usage: ???sum [-bcs] [FILE]...\n\nCalculate hash for each input file, reading from stdin if none, writing\nhexadecimal digits to stdout for each input file (md5=32 hex digits,\nsha1=40, sha224=56, sha256=64, sha384=96, sha512=128) followed by filename.\n\n-b	Brief (hash only, no filename)\n-c	Check each line of each FILE is the same hash+filename we'd output\n-s	No output, exit status 0 if all hashes match, 1 otherwise"
+#define HELP_md5sum "usage: md5sum [-bcs] [FILE]...\n\nCalculate md5 hash for each input file, reading from stdin if none.\nOutput one hash (32 hex digits) for each input file, followed by filename.\n\n-b	Brief (hash only, no filename)\n-c	Check each line of each FILE is the same hash+filename we'd output\n-s	No output, exit status 0 if all hashes match, 1 otherwise"
 
 #define HELP_killall "usage: killall [-l] [-iqv] [-SIGNAL|-s SIGNAL] PROCESS_NAME...\n\nSend a signal (default: TERM) to all processes with the given names.\n\n-i	Ask for confirmation before killing\n-l	Print list of all available signals\n-q	Don't print any warnings or error messages\n-s	Send SIGNAL instead of SIGTERM\n-v	Report if the signal was successfully sent\n-w	Wait until all signaled processes are dead"
 
@@ -124,9 +126,7 @@
 
 #define HELP_microcom "usage: microcom [-s SPEED] [-X] DEVICE\n\nSimple serial console.\n\n-s	Set baud rate to SPEED (default 115200)\n-X	Ignore ^@ (send break) and ^] (exit)"
 
-#define HELP_ifconfig "usage: ifconfig [-aS] [INTERFACE [ACTION...]]\n\nDisplay or configure network interface.\n\nWith no arguments, display active interfaces. First argument is interface\nto operate on, one argument by itself displays that interface.\n\n-a	All interfaces displayed, not just active ones\n-S	Short view, one line per interface\n\nStandard ACTIONs to perform on an INTERFACE:\n\nADDR[/MASK]        - set IPv4 address (1.2.3.4/5) and activate interface\nadd|del ADDR[/LEN] - add/remove IPv6 address (1111::8888/128)\nup|down            - activate or deactivate interface\n\nAdvanced ACTIONs (default values usually suffice):\n\ndefault          - remove IPv4 address\nnetmask ADDR     - set IPv4 netmask via 255.255.255.0 instead of /24\ntxqueuelen LEN   - number of buffered packets before output blocks\nmtu LEN          - size of outgoing packets (Maximum Transmission Unit)\nbroadcast ADDR   - Set broadcast address\npointopoint ADDR - PPP and PPPOE use this instead of \"route add default gw\"\nhw TYPE ADDR     - set hardware (mac) address (type = ether|infiniband)\nrename NEWNAME   - rename interface\n\nFlags you can set on an interface (or -remove by prefixing with -):\n\narp       - don't use Address Resolution Protocol to map LAN routes\npromisc   - don't discard packets that aren't to this LAN hardware address\nmulticast - force interface into multicast mode if the driver doesn't\nallmulti  - promisc for multicast packets"
-
-#define HELP_host "usage: host [-v] [-t TYPE] NAME [SERVER]\n\nLook up DNS records for NAME, either domain name or IPv4/IPv6 address to\nreverse lookup, from SERVER or default DNS server(s).\n\n-a	All records\n-t TYPE	Record TYPE (number or ANY A AAAA CNAME MX NS PTR SOA SRV TXT)\n-v	Verbose"
+#define HELP_ifconfig "usage: ifconfig [-aS] [INTERFACE [ACTION...]]\n\nDisplay or configure network interface.\n\nWith no arguments, display active interfaces. First argument is interface\nto operate on, one argument by itself displays that interface.\n\n-a	All interfaces displayed, not just active ones\n-S	Short view, one line per interface\n\nStandard ACTIONs to perform on an INTERFACE:\n\nADDR[/MASK]        - set IPv4 address (1.2.3.4/5) and activate interface\nadd|del ADDR[/LEN] - add/remove IPv6 address (1111::8888/128)\nup|down            - activate or deactivate interface\n\nAdvanced ACTIONs (default values usually suffice):\n\ndefault          - remove IPv4 address\nnetmask ADDR     - set IPv4 netmask via 255.255.255.0 instead of /24\ntxqueuelen LEN   - number of buffered packets before output blocks\nmtu LEN          - size of outgoing packets (Maximum Transmission Unit)\nbroadcast ADDR   - Set broadcast address\npointopoint ADDR - PPP and PPPOE use this instead of \"route add default gw\"\nhw TYPE ADDR     - set hardware (mac) address (type = ether|infiniband)\n\nFlags you can set on an interface (or -remove by prefixing with -):\n\narp       - don't use Address Resolution Protocol to map LAN routes\npromisc   - don't discard packets that aren't to this LAN hardware address\nmulticast - force interface into multicast mode if the driver doesn't\nallmulti  - promisc for multicast packets"
 
 #define HELP_ftpput "An ftpget that defaults to -s instead of -g"
 
@@ -134,7 +134,7 @@
 
 #define HELP_yes "usage: yes [args...]\n\nRepeatedly output line until killed. If no args, output 'y'."
 
-#define HELP_xxd "usage: xxd [-c n] [-g n] [-i] [-l n] [-o n] [-p] [-r] [-s n] [file]\n\nHexdump a file to stdout. If no file is listed, copy from stdin.\nFilename \"-\" is a synonym for stdin.\n\n-c n	Show n bytes per line (default 16)\n-g n	Group bytes by adding a ' ' every n bytes (default 2)\n-i	Output include file (CSV hex bytes, plus C header/footer if not stdin)\n-l n	Limit of n bytes before stopping (default is no limit)\n-o n	Add n to display offset\n-p	Plain hexdump (30 bytes/line, no grouping)\n-r	Reverse operation: turn a hexdump into a binary file\n-s n	Skip to offset n"
+#define HELP_xxd "usage: xxd [-c n] [-g n] [-i] [-l n] [-o n] [-p] [-r] [-s n] [file]\n\nHexdump a file to stdout.  If no file is listed, copy from stdin.\nFilename \"-\" is a synonym for stdin.\n\n-c n	Show n bytes per line (default 16)\n-g n	Group bytes by adding a ' ' every n bytes (default 2)\n-i	Include file output format (comma-separated hex byte literals)\n-l n	Limit of n bytes before stopping (default is no limit)\n-o n	Add n to display offset\n-p	Plain hexdump (30 bytes/line, no grouping)\n-r	Reverse operation: turn a hexdump into a binary file\n-s n	Skip to offset n"
 
 #define HELP_which "usage: which [-a] filename ...\n\nSearch $PATH for executable files matching filename(s).\n\n-a	Show all matches"
 
@@ -154,8 +154,6 @@
 
 #define HELP_uptime "usage: uptime [-ps]\n\nTell the current time, how long the system has been running, the number\nof users, and the system load averages for the past 1, 5 and 15 minutes.\n\n-p	Pretty (human readable) uptime\n-s	Since when has the system been up?"
 
-#define HELP_uclampset "usage: uclampset [-m MIN] [-M MAX] {-p PID | COMMAND...}\n\nSet or query process utilization limits ranging from 0 to 1024, or -1 to\nreset to system default. With no arguments, prints current values.\n\n-m MIN      Reserve at least this much CPU utilization for task\n-M MAX      Limit task to at most this much CPU utilization\n-p PID	Apply to PID rather than new COMMAND\n-R	Reset child processes to default values on fork\n-a	Apply to all threads for the given PID"
-
 #define HELP_truncate "usage: truncate [-c] -s SIZE file...\n\nSet length of file(s), extending sparsely if necessary.\n\n-c	Don't create file if it doesn't exist\n-s	New size (with optional prefix and suffix)\n\nSIZE prefix: + add, - subtract, < shrink to, > expand to,\n             / multiple rounding down, % multiple rounding up\nSIZE suffix: k=1024, m=1024^2, g=1024^3, t=1024^4, p=1024^5, e=1024^6"
 
 #define HELP_timeout "usage: timeout [-k DURATION] [-s SIGNAL] DURATION COMMAND...\n\nRun command line as a child process, sending child a signal if the\ncommand doesn't exit soon enough.\n\nDURATION can be a decimal fraction. An optional suffix can be \"m\"\n(minutes), \"h\" (hours), \"d\" (days), or \"s\" (seconds, the default).\n\n-s	Send specified signal (default TERM)\n-k	Send KILL signal if child still running this long after first signal\n-v	Verbose\n--foreground       Don't create new process group\n--preserve-status  Exit with the child's exit status"
@@ -176,7 +174,7 @@
 
 #define HELP_stat "usage: stat [-tfL] [-c FORMAT] FILE...\n\nDisplay status of files or filesystems.\n\n-c	Output specified FORMAT string instead of default\n-f	Display filesystem status instead of file status\n-L	Follow symlinks\n-t	terse (-c \"%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\")\n	      (with -f = -c \"%n %i %l %t %s %S %b %f %a %c %d\")\n\nThe valid format escape sequences for files:\n%a  Access bits (octal) |%A  Access bits (flags)|%b  Size/512\n%B  Bytes per %b (512)  |%C  Security context   |%d  Device ID (dec)\n%D  Device ID (hex)     |%f  All mode bits (hex)|%F  File type\n%g  Group ID            |%G  Group name         |%h  Hard links\n%i  Inode               |%m  Mount point        |%n  Filename\n%N  Long filename       |%o  I/O block size     |%s  Size (bytes)\n%t  Devtype major (hex) |%T  Devtype minor (hex)|%u  User ID\n%U  User name           |%x  Access time        |%X  Access unix time\n%y  Modification time   |%Y  Mod unix time      |%z  Creation time\n%Z  Creation unix time\n\nThe valid format escape sequences for filesystems:\n%a  Available blocks    |%b  Total blocks       |%c  Total inodes\n%d  Free inodes         |%f  Free blocks        |%i  File system ID\n%l  Max filename length |%n  File name          |%s  Best transfer size\n%S  Actual block size   |%t  FS type (hex)      |%T  FS type (driver name)"
 
-#define HELP_shred "usage: shred [-fuxz] [-n COUNT] [-o OFFSET] [-s SIZE] FILE...\n\nSecurely delete a file by overwriting its contents with random data.\n\n-f		Force (chmod if necessary)\n-n COUNT	Random overwrite iterations (default 1)\n-o OFFSET	Start at OFFSET\n-s SIZE		Use SIZE instead of detecting file size\n-u		Unlink (actually delete file when done)\n-x		Use exact size (default without -s rounds up to next 4k)\n-z		Zero at end\n\nNote: data journaling filesystems render this command useless, you must\noverwrite all free space (fill up disk) to erase old data on those."
+#define HELP_shred "usage: shred [-fuz] [-n COUNT] [-s SIZE] FILE...\n\nSecurely delete a file by overwriting its contents with random data.\n\n-f		Force (chmod if necessary)\n-n COUNT	Random overwrite iterations (default 1)\n-o OFFSET	Start at OFFSET\n-s SIZE		Use SIZE instead of detecting file size\n-u		Unlink (actually delete file when done)\n-x		Use exact size (default without -s rounds up to next 4k)\n-z		Zero at end\n\nNote: data journaling filesystems render this command useless, you must\noverwrite all free space (fill up disk) to erase old data on those."
 
 #define HELP_sha3sum "usage: sha3sum [-S] [-a BITS] [FILE...]\n\nHash function du jour.\n\n-a	Produce a hash BITS long (default 224)\n-b	Brief (hash only, no filename)\n-S	Use SHAKE termination byte instead of SHA3 (ask FIPS why)"
 
@@ -186,20 +184,18 @@
 
 #define HELP_rtcwake "usage: rtcwake [-aluv] [-d FILE] [-m MODE] [-s SECS] [-t UNIX]\n\nEnter the given sleep state until the given time.\n\n-a	RTC uses time specified in /etc/adjtime\n-d FILE	Device to use (default /dev/rtc)\n-l	RTC uses local time\n-m	Mode (--list-modes to see those supported by your kernel):\n	  standby  S1: default              mem     S3: suspend to RAM\n	  disk     S4: suspend to disk      off     S5: power off\n	  disable  Cancel current alarm     freeze  stop processes/processors\n	  no       just set wakeup time     on      just poll RTC for alarm\n	  show     just show current alarm\n-s SECS	Wake SECS seconds from now\n-t UNIX	Wake UNIX seconds from epoch\n-u	RTC uses UTC\n-v	Verbose"
 
-#define HELP_rmmod "usage: rmmod [-wf] MODULE...\n\nUnload the given kernel modules.\n\n-f	Force unload of a module\n-w	Wait until the module is no longer used"
+#define HELP_rmmod "usage: rmmod [-wf] [MODULE]\n\nUnload the module named MODULE from the Linux kernel.\n-f	Force unload of a module\n-w	Wait until the module is no longer used"
 
 #define HELP_rev "usage: rev [FILE...]\n\nOutput each line reversed, when no files are given stdin is used."
 
 #define HELP_reset "usage: reset\n\nReset the terminal."
 
-#define HELP_reboot "usage: reboot/halt/poweroff [-fn] [-d DELAY]\n\nRestart, halt, or power off the system.\n\n-d	Wait DELAY before proceeding (in seconds or m/h/d suffix: -d 1.5m = 90s)\n-f	Force reboot (don't signal init, reboot directly)\n-n	Don't sync filesystems before reboot"
+#define HELP_reboot "usage: reboot/halt/poweroff [-fn]\n\nRestart, halt or powerdown the system.\n\n-f	Don't signal init\n-n	Don't sync before stopping the system"
 
 #define HELP_realpath "usage: realpath FILE...\n\nDisplay the canonical absolute pathname"
 
 #define HELP_readlink "usage: readlink FILE...\n\nWith no options, show what symlink points to, return error if not symlink.\n\nOptions for producing canonical paths (all symlinks/./.. resolved):\n\n-e	Canonical path to existing entry (fail if missing)\n-f	Full path (fail if directory missing)\n-m	Ignore missing entries, show where it would be\n-n	No trailing newline\n-q	Quiet (no output, just error code)"
 
-#define HELP_readelf "usage: readelf [-adehlnSs] [-p SECTION] [-x SECTION] [file...]\n\nDisplays information about ELF files.\n\n-a	Equivalent to -dhlnSs\n-d	Show dynamic section\n-e	Headers (equivalent to -hlS)\n-h	Show ELF header\n-l	Show program headers\n-n	Show notes\n-p S	Dump strings found in named/numbered section\n-S	Show section headers\n-s	Show symbol tables (.dynsym and .symtab)\n-x S	Hex dump of named/numbered section\n\n--dyn-syms	Show just .dynsym symbol table"
-
 #define HELP_readahead "usage: readahead FILE...\n\nPreload files into disk cache."
 
 #define HELP_pwgen "usage: pwgen [-cAn0yrsBhC1v] [LENGTH] [COUNT]\n\nGenerate human-readable random passwords. When output is to tty produces\na screenfull to defeat shoulder surfing (pick one and clear the screen).\n\n-c  --capitalize                  Permit capital letters.\n-A  --no-capitalize               Don't include capital letters.\n-n  --numerals                    Permit numbers.\n-0  --no-numerals                 Don't include numbers.\n-y  --symbols                     Permit special characters ($#%...).\n-r <chars>  --remove=<chars>      Don't include the given characters.\n-s  --secure                      Generate more random passwords.\n-B  --ambiguous                   Avoid ambiguous characters (e.g. 0, O).\n-h  --help                        Print this help message.\n-C                                Print the output in columns.\n-1                                Print the output one line each.\n-v                                Don't include vowels."
@@ -208,18 +204,12 @@
 
 #define HELP_printenv "usage: printenv [-0] [env_var...]\n\nPrint environment variables.\n\n-0	Use \\0 as delimiter instead of \\n"
 
-#define HELP_pmap "usage: pmap [-pqx] PID...\n\nReport the memory map of a process or processes.\n\n-q	Show full paths\n-q	Do not show header or footer\n-x	Show the extended format"
+#define HELP_pmap "usage: pmap [-xq] [pids...]\n\nReport the memory map of a process or processes.\n\n-x	Show the extended format\n-q	Do not display some header/footer lines"
 
 #define HELP_pivot_root "usage: pivot_root OLD NEW\n\nSwap OLD and NEW filesystems (as if by simultaneous mount --move), and\nmove all processes with chdir or chroot under OLD into NEW (including\nkernel threads) so OLD may be unmounted.\n\nThe directory NEW must exist under OLD. This doesn't work on initramfs,\nwhich can't be moved (about the same way PID 1 can't be killed; see\nswitch_root instead)."
 
 #define HELP_partprobe "usage: partprobe DEVICE...\n\nTell the kernel about partition table changes\n\nAsk the kernel to re-read the partition table on the specified devices."
 
-#define HELP_deallocvt "usage: deallocvt [NUM]\n\nDeallocate unused virtual terminals, either a specific /dev/ttyNUM, or all."
-
-#define HELP_chvt "usage: chvt NUM\n\nChange to virtual terminal number NUM. (This only works in text mode.)\n\nVirtual terminals are the Linux VGA text mode (or framebuffer) displays,\nswitched between via alt-F1, alt-F2, etc. Use ctrl-alt-F1 to switch\nfrom X11 to a virtual terminal, and alt-F6 (or F7, or F8) to get back."
-
-#define HELP_openvt "usage: openvt [-c NUM] [-sw] COMMAND...\n\nRun COMMAND on a new virtual terminal.\n\n-c NUM  Use VT NUM\n-s    Switch to the new VT\n-w    Wait for command to exit (with -s, deallocates VT on exit)"
-
 #define HELP_oneit "usage: oneit [-prn3] [-c CONSOLE] [COMMAND...]\n\nSimple init program that runs a single supplied command line with a\ncontrolling tty (so CTRL-C can kill it).\n\n-c	Which console device to use (/dev/console doesn't do CTRL-C, etc)\n-p	Power off instead of rebooting when command exits\n-r	Restart child when it exits\n-n	No reboot, just relaunch command line\n-3	Write 32 bit PID of each exiting reparented process to fd 3 of child\n	(Blocking writes, child must read to avoid eventual deadlock.)\n\nSpawns a single child process (because PID 1 has signals blocked)\nin its own session, reaps zombies until the child exits, then\nreboots the system (or powers off with -p, or restarts the child with -r).\n\nResponds to SIGUSR1 by halting the system, SIGUSR2 by powering off,\nand SIGTERM or SIGINT reboot."
 
 #define HELP_nsenter "usage: nsenter [-t pid] [-F] [-i] [-m] [-n] [-p] [-u] [-U] COMMAND...\n\nRun COMMAND in an existing (set of) namespace(s).\n\n-t	PID to take namespaces from    (--target)\n-F	don't fork, even if -p is used (--no-fork)\n\nThe namespaces to switch are:\n\n-i	SysV IPC: message queues, semaphores, shared memory (--ipc)\n-m	Mount/unmount tree (--mount)\n-n	Network address, sockets, routing, iptables (--net)\n-p	Process IDs and init, will fork unless -F is used (--pid)\n-u	Host and domain names (--uts)\n-U	UIDs, GIDs, capabilities (--user)\n\nIf -t isn't specified, each namespace argument must provide a path\nto a namespace file, ala \"-i=/proc/$PID/ns/ipc\""
@@ -242,9 +232,11 @@
 
 #define HELP_makedevs "usage: makedevs [-d device_table] rootdir\n\nCreate a range of special files as specified in a device table.\n\n-d	File containing device table (default reads from stdin)\n\nEach line of the device table has the fields:\n<name> <type> <mode> <uid> <gid> <major> <minor> <start> <increment> <count>\nWhere name is the file name, and type is one of the following:\n\nb	Block device\nc	Character device\nd	Directory\nf	Regular file\np	Named pipe (fifo)\n\nOther fields specify permissions, user and group id owning the file,\nand additional fields for device special files. Use '-' for blank entries,\nunspecified fields are treated as '-'."
 
-#define HELP_lsusb "usage: lsusb [-i]\n\nList USB hosts/devices.\n\n-i	ID database (default /etc/usb.ids[.gz])"
+#define HELP_lsusb "usage: lsusb\n\nList USB hosts/devices."
 
-#define HELP_lspci "usage: lspci [-ekmn] [-i FILE]\n\nList PCI devices.\n\n-e  Extended (6 digit) class\n-i  ID database (default /etc/pci.ids[.gz])\n-k  Show kernel driver\n-m  Machine readable\n-n  Numeric output (-nn for both)"
+#define HELP_lspci_text "usage: lspci [-n] [-i FILE ]\n\n-n	Numeric output (repeat for readable and numeric)\n-i	PCI ID database (default /usr/share/misc/pci.ids)"
+
+#define HELP_lspci "usage: lspci [-ekm]\n\nList PCI devices.\n\n-e	Print all 6 digits in class\n-k	Print kernel driver\n-m	Machine readable format"
 
 #define HELP_lsmod "usage: lsmod\n\nDisplay the currently loaded modules, their sizes and their dependencies."
 
@@ -260,7 +252,7 @@
 
 #define HELP_ionice "usage: ionice [-t] [-c CLASS] [-n LEVEL] [COMMAND...|-p PID]\n\nChange the I/O scheduling priority of a process. With no arguments\n(or just -p), display process' existing I/O class/priority.\n\n-c	CLASS = 1-3: 1(realtime), 2(best-effort, default), 3(when-idle)\n-n	LEVEL = 0-7: (0 is highest priority, default = 5)\n-p	Affect existing PID instead of spawning new child\n-t	Ignore failure to set I/O priority\n\nSystem default iopriority is generally -c 2 -n 4."
 
-#define HELP_insmod "usage: insmod MODULE [OPTION...]\n\nLoad the module named MODULE passing options if given."
+#define HELP_insmod "usage: insmod MODULE [MODULE_OPTIONS]\n\nLoad the module named MODULE passing options if given."
 
 #define HELP_inotifyd "usage: inotifyd PROG FILE[:MASK] ...\n\nWhen a filesystem event matching MASK occurs to a FILE, run PROG as:\n\n  PROG EVENTS FILE [DIRFILE]\n\nIf PROG is \"-\" events are sent to stdout.\n\nThis file is:\n  a  accessed    c  modified    e  metadata change  w  closed (writable)\n  r  opened      D  deleted     M  moved            0  closed (unwritable)\n  u  unmounted   o  overflow    x  unwatchable\n\nA file in this directory is:\n  m  moved in    y  moved out   n  created          d  deleted\n\nWhen x event happens for all FILEs, inotifyd exits (after waiting for PROG)."
 
@@ -270,31 +262,21 @@
 
 #define HELP_i2cdump "usage: i2cdump [-fy] BUS CHIP\n\nDump i2c registers.\n\n-f	Force access to busy devices\n-y	Answer \"yes\" to confirmation prompts (for script use)"
 
-#define HELP_i2cdetect "usage: i2cdetect [-aqry] BUS [FIRST LAST]\nusage: i2cdetect -F BUS\nusage: i2cdetect -l\n\nDetect i2c devices.\n\n-a	All addresses (0x00-0x7f rather than 0x03-0x77 or FIRST-LAST)\n-F	Show functionality\n-l	List available buses\n-q	Probe with SMBus Quick Write (default)\n-r	Probe with SMBus Read Byte\n-y	Answer \"yes\" to confirmation prompts (for script use)"
+#define HELP_i2cdetect "usage: i2cdetect [-ary] BUS [FIRST LAST]\nusage: i2cdetect -F BUS\nusage: i2cdetect -l\n\nDetect i2c devices.\n\n-a	All addresses (0x00-0x7f rather than 0x03-0x77)\n-F	Show functionality\n-l	List all buses\n-r	Probe with SMBus Read Byte\n-y	Answer \"yes\" to confirmation prompts (for script use)"
 
 #define HELP_hwclock "usage: hwclock [-rswtluf]\n\nGet/set the hardware clock.\n\n-f FILE	Use specified device file instead of /dev/rtc0 (--rtc)\n-l	Hardware clock uses localtime (--localtime)\n-r	Show hardware clock time (--show)\n-s	Set system time from hardware clock (--hctosys)\n-t	Set the system time based on the current timezone (--systz)\n-u	Hardware clock uses UTC (--utc)\n-w	Set hardware clock from system time (--systohc)"
 
-#define HELP_hexedit "usage: hexedit FILE\n\nHexadecimal file editor/viewer. All changes are written to disk immediately.\n\n-r	Read only (display but don't edit)\n\nKeys:\nArrows         Move left/right/up/down by one line/column\nPgUp/PgDn      Move up/down by one page\nHome/End       Start/end of line (start/end of file with ctrl)\n0-9, a-f       Change current half-byte to hexadecimal value\n^J or :        Jump (+/- for relative offset, otherwise absolute address)\n^F or /        Find string (^G/n: next, ^D/p: previous match)\nu              Undo\nx              Toggle bw/color display\nq/^C/^Q/Esc    Quit"
+#define HELP_hexedit "usage: hexedit FILE\n\nHexadecimal file editor/viewer. All changes are written to disk immediately.\n\n-r	Read only (display but don't edit)\n\nKeys:\nArrows         Move left/right/up/down by one line/column\nPgUp/PgDn      Move up/down by one page\nHome/End       Start/end of line (start/end of file with ctrl)\n0-9, a-f       Change current half-byte to hexadecimal value\n^J or :        Jump (+/- for relative offset, otherwise absolute address)\n^F or /        Find string (^G/n: next, ^D/p: previous match)\nu              Undo\nq/^C/^Q/Esc    Quit"
 
 #define HELP_help "usage: help [-ahu] [COMMAND]\n\n-a	All commands\n-u	Usage only\n-h	HTML output\n\nShow usage information for toybox commands.\nRun \"toybox\" with no arguments for a list of available commands."
 
-#define HELP_gpioset "usage: gpioset [-l] CHIP LINE=VALUE...\n\nSet the lines on CHIP to the given values. Use gpiofind to convert line\nnames to numbers.\n\n-l	Active low"
-
-#define HELP_gpioget "usage: gpioget [-l] CHIP LINE...\n\nGets the values of the given lines on CHIP. Use gpiofind to convert line\nnames to numbers.\n\n-l	Active low"
-
-#define HELP_gpioinfo "usage: gpioinfo [CHIP...]\n\nShow gpio chips' lines."
-
-#define HELP_gpiofind "usage: gpiofind NAME\n\nShow the chip and line number for the given line name."
-
-#define HELP_gpiodetect "usage: gpiodetect\n\nShow all gpio chips' names, labels, and number of lines."
-
-#define HELP_fsync "usage: fsync [-d] [FILE...]\n\nFlush disk cache for FILE(s), writing cached data to storage device.\n\n-d	Skip directory info (sync file contents only)."
+#define HELP_fsync "usage: fsync [-d] [FILE...]\n\nSynchronize a file's in-core state with storage device.\n\n-d	Avoid syncing metadata"
 
 #define HELP_fsfreeze "usage: fsfreeze {-f | -u} MOUNTPOINT\n\nFreeze or unfreeze a filesystem.\n\n-f	Freeze\n-u	Unfreeze"
 
 #define HELP_freeramdisk "usage: freeramdisk [RAM device]\n\nFree all memory allocated to specified ramdisk"
 
-#define HELP_free "usage: free [-bkmgt]\n\nDisplay the total, free and used amount of physical memory and swap space.\n\n-bkmg	Output units (default is bytes)\n-h	Human readable (K=1024)"
+#define HELP_free "usage: free [-bkmgt]\n\nDisplay the total, free and used amount of physical memory and swap space.\n\n-bkmgt	Output units (default is bytes)\n-h	Human readable (K=1024)"
 
 #define HELP_fmt "usage: fmt [-w WIDTH] [FILE...]\n\nReformat input to wordwrap at a given line length, preserving existing\nindentation level, writing to stdout.\n\n-w WIDTH	Maximum characters per line (default 75)"
 
@@ -316,6 +298,8 @@
 
 #define HELP_clear "Clear the screen."
 
+#define HELP_chvt "usage: chvt N\n\nChange to virtual terminal number N. (This only works in text mode.)\n\nVirtual terminals are the Linux VGA text mode displays, ordinarily\nswitched between via alt-F1, alt-F2, etc. Use ctrl-alt-F1 to switch\nfrom X to a virtual terminal, and alt-F6 (or F7, or F8) to get back."
+
 #define HELP_chrt "usage: chrt [-Rmofrbi] {-p PID [PRIORITY] | [PRIORITY COMMAND...]}\n\nGet/set a process' real-time scheduling policy and priority.\n\n-p	Set/query given pid (instead of running COMMAND)\n-R	Set SCHED_RESET_ON_FORK\n-m	Show min/max priorities available\n\nSet policy (default -r):\n\n  -o  SCHED_OTHER    -f  SCHED_FIFO    -r  SCHED_RR\n  -b  SCHED_BATCH    -i  SCHED_IDLE"
 
 #define HELP_chroot "usage: chroot NEWROOT [COMMAND [ARG...]]\n\nRun command within a new root directory. If no command, run /bin/sh."
@@ -338,19 +322,13 @@
 
 #define HELP_base64 "usage: base64 [-di] [-w COLUMNS] [FILE...]\n\nEncode or decode in base64.\n\n-d	Decode\n-i	Ignore non-alphabetic characters\n-w	Wrap output at COLUMNS (default 76 or 0 for no wrap)"
 
-#define HELP_unicode "usage: unicode CODE[-END]...\n\nConvert between Unicode code points and UTF-8, in both directions.\nCODE can be one or more characters (show U+XXXX), hex numbers\n(show character), or dash separated range."
-
 #define HELP_ascii "usage: ascii\n\nDisplay ascii character set."
 
 #define HELP_acpi "usage: acpi [-abctV]\n\nShow status of power sources and thermal devices.\n\n-a	Show power adapters\n-b	Show batteries\n-c	Show cooling device state\n-t	Show temperatures\n-V	Show everything"
 
 #define HELP_xzcat "usage: xzcat [filename...]\n\nDecompress listed files to stdout. Use stdin if no files listed."
 
-#define HELP_wget_openssl "Enable HTTPS support for wget by linking to OpenSSL."
-
-#define HELP_wget_libtls "Enable HTTPS support for wget by linking to LibTLS.\nSupports using libtls, libretls or libtls-bearssl."
-
-#define HELP_wget "usage: wget [OPTIONS]... [URL]\n    --max-redirect          maximum redirections allowed\n-d, --debug                 print lots of debugging information\n-O, --output-document=FILE  specify output filename\n-p, --post-data=DATA        send data in body of POST request\n\nexamples:\n  wget http://www.example.com"
+#define HELP_wget "usage: wget -O filename URL\n-O filename: specify output filename\nURL: uniform resource location, FTP/HTTP only, not HTTPS\n\nexamples:\n  wget -O index.html http://www.example.com\n  wget -O sample.jpg ftp://ftp.example.com:21/sample.jpg"
 
 #define HELP_vi "usage: vi [-s script] FILE\n-s script: run script file\nVisual text editor. Predates the existence of standardized cursor keys,\nso the controls are weird and historical."
 
@@ -358,6 +336,8 @@
 
 #define HELP_useradd "usage: useradd [-SDH] [-h DIR] [-s SHELL] [-G GRP] [-g NAME] [-u UID] USER [GROUP]\n\nCreate new user, or add USER to GROUP\n\n-D       Don't assign a password\n-g NAME  Real name\n-G GRP   Add user to existing group\n-h DIR   Home directory\n-H       Don't create home directory\n-s SHELL Login shell\n-S       Create a system user\n-u UID   User id"
 
+#define HELP_unicode "usage: unicode [[min]-max]\n\nConvert between Unicode code points and UTF-8, in both directions."
+
 #define HELP_traceroute "usage: traceroute [-46FUIldnvr] [-f 1ST_TTL] [-m MAXTTL] [-p PORT] [-q PROBES]\n[-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-g GATEWAY] [-i IFACE] [-z PAUSE_MSEC] HOST [BYTES]\n\ntraceroute6 [-dnrv] [-m MAXTTL] [-p PORT] [-q PROBES][-s SRC_IP] [-t TOS] [-w WAIT_SEC]\n  [-i IFACE] HOST [BYTES]\n\nTrace the route to HOST\n\n-4,-6 Force IP or IPv6 name resolution\n-F    Set the don't fragment bit (supports IPV4 only)\n-U    Use UDP datagrams instead of ICMP ECHO (supports IPV4 only)\n-I    Use ICMP ECHO instead of UDP datagrams (supports IPV4 only)\n-l    Display the TTL value of the returned packet (supports IPV4 only)\n-d    Set SO_DEBUG options to socket\n-n    Print numeric addresses\n-v    verbose\n-r    Bypass routing tables, send directly to HOST\n-m    Max time-to-live (max number of hops)(RANGE 1 to 255)\n-p    Base UDP port number used in probes(default 33434)(RANGE 1 to 65535)\n-q    Number of probes per TTL (default 3)(RANGE 1 to 255)\n-s    IP address to use as the source address\n-t    Type-of-service in probe packets (default 0)(RANGE 0 to 255)\n-w    Time in seconds to wait for a response (default 3)(RANGE 0 to 86400)\n-g    Loose source route gateway (8 max) (supports IPV4 only)\n-z    Pause Time in ms (default 0)(RANGE 0 to 86400) (supports IPV4 only)\n-f    Start from the 1ST_TTL hop (instead from 1)(RANGE 1 to 255) (supports IPV4 only)\n-i    Specify a network interface to operate with"
 
 #define HELP_tr "usage: tr [-cds] SET1 [SET2]\n\nTranslate, squeeze, or delete characters from stdin, writing to stdout\n\n-c/-C  Take complement of SET1\n-d     Delete input characters coded SET1\n-s     Squeeze multiple output characters of SET2 into one character"
@@ -378,8 +358,6 @@
 
 #define HELP_stty "usage: stty [-ag] [-F device] SETTING...\n\nGet/set terminal configuration.\n\n-F	Open device instead of stdin\n-a	Show all current settings (default differences from \"sane\")\n-g	Show all current settings usable as input to stty\n\nSpecial characters (syntax ^c or undef): intr quit erase kill eof eol eol2\nswtch start stop susp rprnt werase lnext discard\n\nControl/input/output/local settings as shown by -a, '-' prefix to disable\n\nCombo settings: cooked/raw, evenp/oddp/parity, nl, ek, sane\n\nN	set input and output speed (ispeed N or ospeed N for just one)\ncols N	set number of columns\nrows N	set number of rows\nline N	set line discipline\nmin N	set minimum chars per read\ntime N	set read timeout\nspeed	show speed only\nsize	show size only"
 
-#define HELP_strace "usage: strace [-fv] [-p PID] [-s NUM] COMMAND [ARGS...]\n\nTrace systems calls made by a process.\n\n-s	String length limit.\n-v	Dump all of large structs/arrays."
-
 #define HELP_wait "usage: wait [-n] [ID...]\n\nWait for background processes to exit, returning its exit code.\nID can be PID or job, with no IDs waits for all backgrounded processes.\n\n-n	Wait for next process to exit"
 
 #define HELP_source "usage: source FILE [ARGS...]\n\nRead FILE and execute commands. Any ARGS become positional parameters."
@@ -402,17 +380,21 @@
 
 #define HELP_exit "usage: exit [status]\n\nExit shell.  If no return value supplied on command line, use value\nof most recent command, or 0 if none."
 
-#define HELP_declare "usage: declare [-pAailunxr] [NAME...]\n\nSet or print variable attributes and values.\n\n-p	Print variables instead of setting\n-A	Associative array\n-a	Indexed array\n-i	Integer\n-l	Lower case\n-n	Name reference (symlink)\n-r	Readonly\n-u	Uppercase\n-x	Export"
-
-#define HELP_cd "usage: cd [-PL] [-] [path]\n\nChange current directory. With no arguments, go $HOME. Sets $OLDPWD to\nprevious directory: cd - to return to $OLDPWD.\n\n-P	Physical path: resolve symlinks in path\n-L	Local path: .. trims directories off $PWD (default)"
+#define HELP_cd "usage: cd [-PL] [path]\n\nChange current directory.  With no arguments, go $HOME.\n\n-P	Physical path: resolve symlinks in path\n-L	Local path: .. trims directories off $PWD (default)"
 
 #define HELP_sh "usage: sh [-c command] [script]\n\nCommand shell.  Runs a shell script, or reads input interactively\nand responds to it.\n\n-c	command line to execute\n-i	interactive mode (default when STDIN is a tty)"
 
 #define HELP_route "usage: route [-ne] [-A [inet|inet6]] [add|del TARGET [OPTIONS]]\n\nDisplay, add or delete network routes in the \"Forwarding Information Base\",\nwhich send packets out a network interface to an address.\n\n-n	Show numerical addresses (no DNS lookups)\n-e	display netstat fields\n\nAssigning an address to an interface automatically creates an appropriate\nnetwork route (\"ifconfig eth0 10.0.2.15/8\" does \"route add 10.0.0.0/8 eth0\"\nfor you), although some devices (such as loopback) won't show it in the\ntable. For machines more than one hop away, you need to specify a gateway\n(ala \"route add default gw 10.0.2.2\").\n\nThe address \"default\" is a wildcard address (0.0.0.0/0) matching all\npackets without a more specific route.\n\nAvailable OPTIONS include:\nreject   - blocking route (force match failure)\ndev NAME - force matching packets out this interface (ala \"eth0\")\nnetmask  - old way of saying things like ADDR/24\ngw ADDR  - forward packets to gateway ADDR"
 
+#define HELP_readelf "usage: readelf [-adehlnSs] [-p SECTION] [-x SECTION] [file...]\n\nDisplays information about ELF files.\n\n-a	Equivalent to -dhlnSs\n-d	Show dynamic section\n-e	Headers (equivalent to -hlS)\n-h	Show ELF header\n-l	Show program headers\n-n	Show notes\n-p S	Dump strings found in named/numbered section\n-S	Show section headers\n-s	Show symbol tables (.dynsym and .symtab)\n-x S	Hex dump of named/numbered section\n\n--dyn-syms	Show just .dynsym symbol table"
+
+#define HELP_deallocvt "usage: deallocvt [NUM]\n\nDeallocate unused virtual terminals, either a specific /dev/ttyNUM, or all."
+
+#define HELP_openvt "usage: openvt [-c NUM] [-sw] [COMMAND...]\n\nStart a program on a new virtual terminal.\n\n-c NUM  Use VT NUM\n-s    Switch to new VT\n-w    Wait for command to exit\n\nTogether -sw switch back to originating VT when command completes."
+
 #define HELP_more "usage: more [FILE...]\n\nView FILE(s) (or stdin) one screenfull at a time."
 
-#define HELP_modprobe "usage: modprobe [-alrqvsDb] [-d DIR] MODULE [symbol=value][...]\n\nmodprobe utility - inserts modules and dependencies.\n\n-a  Load multiple MODULEs\n-b  Apply blacklist to module names too\n-D  Show dependencies\n-d  Load modules from DIR, option may be used multiple times\n-l  List (MODULE is a pattern)\n-q  Quiet\n-r  Remove MODULE (stacks) or do autoclean\n-s  Log to syslog\n-v  Verbose"
+#define HELP_modprobe "usage: modprobe [-alrqvsDb] [-d DIR] MODULE [symbol=value][...]\n\nmodprobe utility - inserts modules and dependencies.\n\n-a  Load multiple MODULEs\n-d  Load modules from DIR, option may be used multiple times\n-l  List (MODULE is a pattern)\n-r  Remove MODULE (stacks) or do autoclean\n-q  Quiet\n-v  Verbose\n-s  Log to syslog\n-D  Show dependencies\n-b  Apply blacklist to module names too"
 
 #define HELP_mke2fs_extended "usage: mke2fs [-E stride=###] [-O option[,option]]\n\n-E stride= Set RAID stripe size (in blocks)\n-O [opts]  Specify fewer ext2 option flags (for old kernels)\n           All of these are on by default (as appropriate)\n   none         Clear default options (all but journaling)\n   dir_index    Use htree indexes for large directories\n   filetype     Store file type info in directory entry\n   has_journal  Set by -j\n   journal_dev  Set by -J device=XXX\n   sparse_super Don't allocate huge numbers of redundant superblocks"
 
@@ -444,9 +426,7 @@
 
 #define HELP_init "usage: init\n\nSystem V style init.\n\nFirst program to run (as PID 1) when the system comes up, reading\n/etc/inittab to determine actions."
 
-#define HELP_hd "usage: hd [FILE...]\n\nDisplay file(s) in cannonical hex+ASCII format."
-
-#define HELP_hexdump "usage: hexdump [-bcCdovx] [-n LEN] [-s SKIP] [FILE...]\n\nDump file(s) in hexadecimal format.\n\n-n LEN	Show LEN bytes of output\n-s SKIP	Skip bytes of input\n-v	Verbose (don't combine identical lines)\n\nDisplay type:\n-b One byte octal   -c One byte character -C Canonical (hex + ASCII)\n-d Two byte decimal -o Two byte octal     -x Two byte hexadecimal (default)"
+#define HELP_host "usage: host [-av] [-t TYPE] NAME [SERVER]\n\nPerform DNS lookup on NAME, which can be a domain name to lookup,\nor an IPv4 dotted or IPv6 colon-separated address to reverse lookup.\nSERVER (if present) is the DNS server to use.\n\n-a	-v -t ANY\n-t TYPE	query records of type TYPE\n-v	verbose"
 
 #define HELP_groupdel "usage: groupdel [USER] GROUP\n\nDelete a group or remove a user from a group"
 
@@ -492,7 +472,7 @@
 
 #define HELP_arping "usage: arping [-fqbDUA] [-c CNT] [-w TIMEOUT] [-I IFACE] [-s SRC_IP] DST_IP\n\nSend ARP requests/replies\n\n-f         Quit on first ARP reply\n-q         Quiet\n-b         Keep broadcasting, don't go unicast\n-D         Duplicated address detection mode\n-U         Unsolicited ARP mode, update your neighbors\n-A         ARP answer mode, update your neighbors\n-c N       Stop after sending N ARP requests\n-w TIMEOUT Time to wait for ARP reply, seconds\n-I IFACE   Interface to use (default eth0)\n-s SRC_IP  Sender IP address\nDST_IP     Target IP address"
 
-#define HELP_arp "usage: arp\n[-vn] [-H HWTYPE] [-i IF] -a [HOSTNAME]\n[-v]              [-i IF] -d HOSTNAME [pub]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub\n[-v]  [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub\n\nManipulate ARP cache.\n\n-a	Display (all) hosts\n-s	Set new ARP entry\n-d	Delete a specified entry\n-v	Verbose\n-n	Don't resolve names\n-i IFACE	Network interface\n-D	Read <hwaddr> from given device\n-A,-p AF	Protocol family\n-H HWTYPE	Hardware address type"
+#define HELP_arp "usage: arp\n[-vn] [-H HWTYPE] [-i IF] -a [HOSTNAME]\n[-v]              [-i IF] -d HOSTNAME [pub]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub\n[-v]  [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub\n\nManipulate ARP cache\n\n-a    Display (all) hosts\n-s    Set new ARP entry\n-d    Delete a specified entry\n-v    Verbose\n-n    Don't resolve names\n-i IF Network interface\n-D    Read <hwaddr> from given device\n-A,-p AF  Protocol family\n-H    HWTYPE Hardware address type"
 
 #define HELP_xargs "usage: xargs [-0prt] [-snE STR] COMMAND...\n\nRun command line one or more times, appending arguments from stdin.\n\nIf COMMAND exits with 255, don't launch another even if arguments remain.\n\n-0	Each argument is NULL terminated, no whitespace or quote processing\n-E	Stop at line matching string\n-n	Max number of arguments per command\n-o	Open tty for COMMAND's stdin (default /dev/null)\n-p	Prompt for y/n from tty before running each command\n-P	Parallel processes (default 1)\n-r	Don't run with empty input (otherwise always run command once)\n-s	Size in bytes per command line\n-t	Trace, print command line to stderr"
 
@@ -508,33 +488,31 @@
 
 #define HELP_uniq "usage: uniq [-cduiz] [-w MAXCHARS] [-f FIELDS] [-s CHAR] [INFILE [OUTFILE]]\n\nReport or filter out repeated lines in a file\n\n-c	Show counts before each line\n-d	Show only lines that are repeated\n-u	Show only lines that are unique\n-i	Ignore case when comparing lines\n-z	Lines end with \\0 not \\n\n-w	Compare maximum X chars per line\n-f	Ignore first X fields\n-s	Ignore first X chars"
 
-#define HELP_uname "usage: uname [-asnrvm]\n\nPrint system information.\n\n-s	System name\n-n	Network (domain) name\n-r	Kernel Release number\n-v	Kernel Version\n-m	Machine (hardware) name\n-o	Userspace type\n-a	All of the above (in order)"
-
-#define HELP_linux32 "usage: linux32 [COMMAND...]\n\nTell uname -m to line to autoconf (to build 32 bit binaries on 64 bit kernel)."
+#define HELP_uname "usage: uname [-asnrvm]\n\nPrint system information.\n\n-s	System name\n-n	Network (domain) name\n-r	Kernel Release number\n-v	Kernel Version\n-m	Machine (hardware) name\n-a	All of the above"
 
 #define HELP_arch "usage: arch\n\nPrint machine (hardware) name, same as uname -m."
 
 #define HELP_ulimit "usage: ulimit [-P PID] [-SHRacdefilmnpqrstuv] [LIMIT]\n\nPrint or set resource limits for process number PID. If no LIMIT specified\n(or read-only -ap selected) display current value (sizes in bytes).\nDefault is ulimit -P $PPID -Sf\" (show soft filesize of your shell).\n\n-P  PID to affect (default $PPID)  -a  Show all limits\n-S  Set/show soft limit            -H  Set/show hard (maximum) limit\n\n-c  Core file size (blocks)        -d  Process data segment (KiB)\n-e  Max scheduling priority        -f  File size (KiB)\n-i  Pending signal count           -l  Locked memory (KiB)\n-m  Resident Set Size (KiB)        -n  Number of open files\n-p  Pipe buffer (512 bytes)        -q  POSIX message queues\n-r  Max realtime priority          -R  Realtime latency (us)\n-s  Stack size (KiB)               -t  Total CPU time (s)\n-u  Maximum processes (this UID)   -v  Virtual memory size (KiB)"
 
-#define HELP_tty "usage: tty [-s]\n\nShow filename of terminal connected to stdin. If none print \"not a tty\"\nand exit with nonzero status.\n\n-s	Silent, exit code only"
+#define HELP_tty "usage: tty [-s]\n\nShow filename of terminal connected to stdin.\n\nPrints \"not a tty\" and exits with nonzero status if no terminal\nis connected to stdin.\n\n-s	Silent, exit code only"
 
 #define HELP_true "usage: true\n\nReturn zero."
 
 #define HELP_touch "usage: touch [-amch] [-d DATE] [-t TIME] [-r FILE] FILE...\n\nUpdate the access and modification times of each FILE to the current time.\n\n-a	Change access time\n-m	Change modification time\n-c	Don't create file\n-h	Change symlink\n-d	Set time to DATE (in YYYY-MM-DDThh:mm:SS[.frac][tz] format)\n-t	Set time to TIME (in [[CC]YY]MMDDhhmm[.ss][frac] format)\n-r	Set time same as reference FILE"
 
-#define HELP_time "usage: time [-pv] COMMAND...\n\nRun command line and report real, user, and system time elapsed in seconds.\n(real = clock on the wall, user = cpu used by command's code,\nsystem = cpu used by OS on behalf of command.)\n\n-p	POSIX format output\n-v	Verbose"
+#define HELP_time "usage: time [-pv] COMMAND...\n\nRun command line and report real, user, and system time elapsed in seconds.\n(real = clock on the wall, user = cpu used by command's code,\nsystem = cpu used by OS on behalf of command.)\n\n-p	POSIX format output (default)\n-v	Verbose"
 
 #define HELP_test "usage: test [-bcdefghLPrSsuwx PATH] [-nz STRING] [-t FD] [X ?? Y]\n\nReturn true or false by performing tests. (With no arguments return false.)\n\n--- Tests with a single argument (after the option):\nPATH is/has:\n  -b  block device   -f  regular file   -p  fifo           -u  setuid bit\n  -c  char device    -g  setgid         -r  read bit       -w  write bit\n  -d  directory      -h  symlink        -S  socket         -x  execute bit\n  -e  exists         -L  symlink        -s  nonzero size   -k  sticky bit\nSTRING is:\n  -n  nonzero size   -z  zero size      (STRING by itself implies -n)\nFD (integer file descriptor) is:\n  -t  a TTY\n\n--- Tests with one argument on each side of an operator:\nTwo strings:\n  =  are identical   !=  differ\n\nTwo integers:\n  -eq  equal         -gt  first > second    -lt  first < second\n  -ne  not equal     -ge  first >= second   -le  first <= second\n\n--- Modify or combine tests:\n  ! EXPR     not (swap true/false)   EXPR -a EXPR    and (are both true)\n  ( EXPR )   evaluate this first     EXPR -o EXPR    or (is either true)"
 
 #define HELP_tee "usage: tee [-ai] [FILE...]\n\nCopy stdin to each listed file, and also to stdout.\nFilename \"-\" is a synonym for stdout.\n\n-a	Append to files\n-i	Ignore SIGINT"
 
-#define HELP_tar "usage: tar [-cxt] [-fvohmjkOS] [-XTCf NAME] [--selinux] [FILE...]\n\nCreate, extract, or list files in a .tar (or compressed t?z) file.\n\nOptions:\nc  Create                x  Extract               t  Test (list)\nf  tar FILE (default -)  C  Change to DIR first   v  Verbose display\no  Ignore owner          h  Follow symlinks       m  Ignore mtime\nJ  xz compression        j  bzip2 compression     z  gzip compression\nO  Extract to stdout     X  exclude names in FILE T  include names in FILE\n\n--exclude        FILENAME to exclude  --full-time         Show seconds with -tv\n--mode MODE      Adjust permissions   --owner NAME[:UID]  Set file ownership\n--mtime TIME     Override timestamps  --group NAME[:GID]  Set file group\n--sparse         Record sparse files  --selinux           Save/restore labels\n--restrict       All under one dir    --no-recursion      Skip dir contents\n--numeric-owner  Use numeric uid/gid, not user/group names\n--strip-components NUM  Ignore first NUM directory components when extracting\n-I PROG          Filter through PROG to compress or PROG -d to decompress"
+#define HELP_tar "usage: tar [-cxt] [-fvohmjkOS] [-XTCf NAME] [FILE...]\n\nCreate, extract, or list files in a .tar (or compressed t?z) file.\n\nOptions:\nc  Create                x  Extract               t  Test (list)\nf  tar FILE (default -)  C  Change to DIR first   v  Verbose display\no  Ignore owner          h  Follow symlinks       m  Ignore mtime\nJ  xz compression        j  bzip2 compression     z  gzip compression\nO  Extract to stdout     X  exclude names in FILE T  include names in FILE\n\n--exclude        FILENAME to exclude    --full-time   Show seconds with -tv\n--mode MODE      Adjust modes           --mtime TIME  Override timestamps\n--owner NAME     Set file owner to NAME --group NAME  Set file group to NAME\n--sparse         Record sparse files\n--restrict       All archive contents must extract under one subdirectory\n--numeric-owner  Save/use/display uid and gid, not user/group name\n--no-recursion   Don't store directory contents\n-I PROG          Filter through PROG to compress or PROG -d to decompress"
 
-#define HELP_tail "usage: tail [-n|c NUMBER] [-f|F] [-s SECONDS] [FILE...]\n\nCopy last lines from files to stdout. If no files listed, copy from\nstdin. Filename \"-\" is a synonym for stdin.\n\n-n	Output the last NUMBER lines (default 10), +X counts from start\n-c	Output the last NUMBER bytes, +NUMBER counts from start\n-f	Follow FILE(s) by descriptor, waiting for more data to be appended\n-F	Follow FILE(s) by filename, waiting for more data, and retrying\n-s	Used with -F, sleep SECONDS between retries (default 1)"
+#define HELP_tail "usage: tail [-n|c NUMBER] [-f] [FILE...]\n\nCopy last lines from files to stdout. If no files listed, copy from\nstdin. Filename \"-\" is a synonym for stdin.\n\n-n	Output the last NUMBER lines (default 10), +X counts from start\n-c	Output the last NUMBER bytes, +NUMBER counts from start\n-f	Follow FILE(s), waiting for more data to be appended"
 
 #define HELP_strings "usage: strings [-fo] [-t oxd] [-n LEN] [FILE...]\n\nDisplay printable strings in a binary file\n\n-f	Show filename\n-n	At least LEN characters form a string (default 4)\n-o	Show offset (ala -t d)\n-t	Show offset type (o=octal, d=decimal, x=hexadecimal)"
 
-#define HELP_split "usage: split [-a SUFFIX_LEN] [-b BYTES] [-l LINES] [-n PARTS] [INPUT [OUTPUT]]\n\nCopy INPUT (or stdin) data to a series of OUTPUT (or \"x\") files with\nalphabetically increasing suffix (aa, ab, ac... az, ba, bb...).\n\n-a	Suffix length (default 2)\n-b	BYTES/file (10, 10k, 10m, 10g...)\n-l	LINES/file (default 1000)\n-n	PARTS many equal length files"
+#define HELP_split "usage: split [-a SUFFIX_LEN] [-b BYTES] [-l LINES] [INPUT [OUTPUT]]\n\nCopy INPUT (or stdin) data to a series of OUTPUT (or \"x\") files with\nalphabetically increasing suffix (aa, ab, ac... az, ba, bb...).\n\n-a	Suffix length (default 2)\n-b	BYTES/file (10, 10k, 10m, 10g...)\n-l	LINES/file (default 1000)"
 
 #define HELP_sort "usage: sort [-Mbcdfginrsuz] [FILE...] [-k#[,#[x]] [-t X]] [-o FILE]\n\nSort all lines of text from input files (or stdin) to stdout.\n-M	Month sort (jan, feb, etc)\n-V	Version numbers (name-1.234-rc6.5b.tgz)\n-b	Ignore leading blanks (or trailing blanks in second part of key)\n-c	Check whether input is sorted\n-d	Dictionary order (use alphanumeric and whitespace chars only)\n-f	Force uppercase (case insensitive sort)\n-g	General numeric sort (double precision with nan and inf)\n-i	Ignore nonprinting characters\n-k	Sort by \"key\" (see below)\n-n	Numeric order (instead of alphabetical)\n-o	Output to FILE instead of stdout\n-r	Reverse\n-s	Skip fallback sort (only sort with keys)\n-t	Use a key separator other than whitespace\n-u	Unique lines only\n-x	Hexadecimal numerical sort\n-z	Zero (null) terminated lines\n\nSorting by key looks at a subset of the words on each line. -k2 uses the\nsecond word to the end of the line, -k2,2 looks at only the second word,\n-k2,4 looks from the start of the second to the end of the fourth word.\n-k2.4,5 starts from the fourth character of the second word, to the end\nof the fifth word. Specifying multiple keys uses the later keys as tie\nbreakers, in order. A type specifier appended to a sort key (such as -2,2n)\napplies only to sorting that key."
 
@@ -556,13 +534,13 @@
 
 #define HELP_iotop "usage: iotop [-AaKObq] [-n NUMBER] [-d SECONDS] [-p PID,] [-u USER,]\n\nRank processes by I/O.\n\n-A	All I/O, not just disk\n-a	Accumulated I/O (not percentage)\n-H	Show threads\n-K	Kilobytes\n-k	Fallback sort FIELDS (default -[D]IO,-ETIME,-PID)\n-m	Maximum number of tasks to show\n-O	Only show processes doing I/O\n-o	Show FIELDS (default PID,PR,USER,[D]READ,[D]WRITE,SWAP,[D]IO,COMM)\n-s	Sort by field number (0-X, default 6)\n-b	Batch mode (no tty)\n-d	Delay SECONDS between each cycle (default 3)\n-n	Exit after NUMBER iterations\n-p	Show these PIDs\n-u	Show these USERs\n-q	Quiet (no header lines)\n\nCursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force\nupdate, R to reverse sort, Q to exit."
 
-#define HELP_top "usage: top [-Hhbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]\n\nShow process activity in real time.\n\n-H	Show threads\n-h	Usage graphs instead of text\n-k	Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)\n-o	Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)\n-O	Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)\n-s	Sort by field number (1-X, default 9)\n-b	Batch mode (no tty)\n-d	Delay SECONDS between each cycle (default 3)\n-m	Maximum number of tasks to show\n-n	Exit after NUMBER iterations\n-p	Show these PIDs\n-u	Show these USERs\n-q	Quiet (no header lines)\n\nCursor UP/DOWN or LEFT/RIGHT to move list, SHIFT LEFT/RIGHT to change sort,\nspace to force update, R to reverse sort, Q to exit."
+#define HELP_top "usage: top [-Hbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]\n\nShow process activity in real time.\n\n-H	Show threads\n-k	Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)\n-o	Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)\n-O	Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)\n-s	Sort by field number (1-X, default 9)\n-b	Batch mode (no tty)\n-d	Delay SECONDS between each cycle (default 3)\n-m	Maximum number of tasks to show\n-n	Exit after NUMBER iterations\n-p	Show these PIDs\n-u	Show these USERs\n-q	Quiet (no header lines)\n\nCursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force\nupdate, R to reverse sort, Q to exit."
 
 #define HELP_ps "usage: ps [-AadefLlnwZ] [-gG GROUP,] [-k FIELD,] [-o FIELD,] [-p PID,] [-t TTY,] [-uU USER,]\n\nList processes.\n\nWhich processes to show (-gGuUpPt selections may be comma separated lists):\n\n-A  All					-a  Has terminal not session leader\n-d  All but session leaders		-e  Synonym for -A\n-g  In GROUPs				-G  In real GROUPs (before sgid)\n-p  PIDs (--pid)			-P  Parent PIDs (--ppid)\n-s  In session IDs			-t  Attached to selected TTYs\n-T  Show threads also			-u  Owned by selected USERs\n-U  Real USERs (before suid)\n\nOutput modifiers:\n\n-k  Sort FIELDs (-FIELD to reverse)	-M  Measure/pad future field widths\n-n  Show numeric USER and GROUP		-w  Wide output (don't truncate fields)\n\nWhich FIELDs to show. (-o HELP for list, default = -o PID,TTY,TIME,CMD)\n\n-f  Full listing (-o USER:12=UID,PID,PPID,C,STIME,TTY,TIME,ARGS=CMD)\n-l  Long listing (-o F,S,UID,PID,PPID,C,PRI,NI,ADDR,SZ,WCHAN,TTY,TIME,CMD)\n-o  Output FIELDs instead of defaults, each with optional :size and =title\n-O  Add FIELDS to defaults\n-Z  Include LABEL"
 
 #define HELP_printf "usage: printf FORMAT [ARGUMENT...]\n\nFormat and print ARGUMENT(s) according to FORMAT, using C printf syntax\n(% escapes for cdeEfgGiosuxX, \\ escapes for abefnrtv0 or \\OCTAL or \\xHEX)."
 
-#define HELP_patch "usage: patch [-Rlsu] [-d DIR] [-i PATCH] [-p DEPTH] [-F FUZZ] [--dry-run] [FILE [PATCH]]\n\nApply a unified diff to one or more files.\n\n-d	Modify files in DIR\n-i	Input patch file (default=stdin)\n-l	Loose match (ignore whitespace)\n-p	Number of '/' to strip from start of file paths (default=all)\n-R	Reverse patch\n-s	Silent except for errors\n-u	Ignored (only handles \"unified\" diffs)\n--dry-run Don't change files, just confirm patch applies\n\nThis version of patch only handles unified diffs, and only modifies\na file when all hunks to that file apply. Patch prints failed hunks\nto stderr, and exits with nonzero status if any hunks fail.\n\nA file compared against /dev/null (or with a date <= the epoch) is\ncreated/deleted as appropriate."
+#define HELP_patch "usage: patch [-d DIR] [-i PATCH] [-p DEPTH] [-F FUZZ] [-Rlsu] [--dry-run] [FILE [PATCH]]\n\nApply a unified diff to one or more files.\n\n-d	Modify files in DIR\n-i	Input patch file (default=stdin)\n-l	Loose match (ignore whitespace)\n-p	Number of '/' to strip from start of file paths (default=all)\n-R	Reverse patch\n-s	Silent except for errors\n-u	Ignored (only handles \"unified\" diffs)\n--dry-run Don't change files, just confirm patch applies\n\nThis version of patch only handles unified diffs, and only modifies\na file when all hunks to that file apply. Patch prints failed hunks\nto stderr, and exits with nonzero status if any hunks fail.\n\nA file compared against /dev/null (or with a date <= the epoch) is\ncreated/deleted as appropriate."
 
 #define HELP_paste "usage: paste [-s] [-d DELIMITERS] [FILE...]\n\nMerge corresponding lines from each input file.\n\n-d	List of delimiter characters to separate fields with (default is \\t)\n-s	Sequential mode: turn each input file into one line of output"
 
@@ -604,11 +582,11 @@
 
 #define HELP_head "usage: head [-n NUM] [FILE...]\n\nCopy first lines from files to stdout. If no files listed, copy from\nstdin. Filename \"-\" is a synonym for stdin.\n\n-n	Number of lines to copy\n-c	Number of bytes to copy\n-q	Never print headers\n-v	Always print headers"
 
-#define HELP_grep "usage: grep [-EFrivwcloqsHbhn] [-ABC NUM] [-m MAX] [-e REGEX]... [-MS PATTERN]... [-f REGFILE] [FILE]...\n\nShow lines matching regular expressions. If no -e, first argument is\nregular expression to match. With no files (or \"-\" filename) read stdin.\nReturns 0 if matched, 1 if no match found, 2 for command errors.\n\n-e  Regex to match. (May be repeated.)\n-f  File listing regular expressions to match.\n\nfile search:\n-r  Recurse into subdirectories (defaults FILE to \".\")\n-R  Recurse into subdirectories and symlinks to directories\n-M  Match filename pattern (--include)\n-S  Skip filename pattern (--exclude)\n--exclude-dir=PATTERN  Skip directory pattern\n-I  Ignore binary files\n\nmatch type:\n-A  Show NUM lines after     -B  Show NUM lines before match\n-C  NUM lines context (A+B)  -E  extended regex syntax\n-F  fixed (literal match)    -a  always text (not binary)\n-i  case insensitive         -m  match MAX many lines\n-v  invert match             -w  whole word (implies -E)\n-x  whole line               -z  input NUL terminated\n\ndisplay modes: (default: matched line)\n-L  filenames with no match  -Z  output is NUL terminated\n-c  count of matching lines  -l  filenames with a match\n-o  only matching part       -q  quiet (errors only)\n-s  silent (no error msg)\n\noutput prefix (default: filename if checking more than 1 file)\n-H  force filename           -b  byte offset of match\n-h  hide filename            -n  line number of match"
+#define HELP_grep "usage: grep [-EFrivwcloqsHbhn] [-ABC NUM] [-m MAX] [-e REGEX]... [-MS PATTERN]... [-f REGFILE] [FILE]...\n\nShow lines matching regular expressions. If no -e, first argument is\nregular expression to match. With no files (or \"-\" filename) read stdin.\nReturns 0 if matched, 1 if no match found, 2 for command errors.\n\n-e  Regex to match. (May be repeated.)\n-f  File listing regular expressions to match.\n\nfile search:\n-r  Recurse into subdirectories (defaults FILE to \".\")\n-R  Recurse into subdirectories and symlinks to directories\n-M  Match filename pattern (--include)\n-S  Skip filename pattern (--exclude)\n--exclude-dir=PATTERN  Skip directory pattern\n-I  Ignore binary files\n\nmatch type:\n-A  Show NUM lines after     -B  Show NUM lines before match\n-C  NUM lines context (A+B)  -E  extended regex syntax\n-F  fixed (literal match)    -a  always text (not binary)\n-i  case insensitive         -m  match MAX many lines\n-v  invert match             -w  whole word (implies -E)\n-x  whole line               -z  input NUL terminated\n\ndisplay modes: (default: matched line)\n-c  count of matching lines  -l  show only matching filenames\n-o  only matching part       -q  quiet (errors only)\n-s  silent (no error msg)    -Z  output NUL terminated\n\noutput prefix (default: filename if checking more than 1 file)\n-H  force filename           -b  byte offset of match\n-h  hide filename            -n  line number of match"
 
 #define HELP_getconf "usage: getconf -a [PATH] | -l | NAME [PATH]\n\nGet system configuration values. Values from pathconf(3) require a path.\n\n-a	Show all (defaults to \"/\" if no path given)\n-l	List available value names (grouped by source)"
 
-#define HELP_find "usage: find [-HL] [DIR...] [<options>]\n\nSearch directories for matching files.\nDefault: search \".\", match all, -print matches.\n\n-H  Follow command line symlinks         -L  Follow all symlinks\n\nMatch filters:\n-name  PATTERN   filename with wildcards   -iname      ignore case -name\n-path  PATTERN   path name with wildcards  -ipath      ignore case -path\n-user  UNAME     belongs to user UNAME     -nouser     user ID not known\n-group GROUP     belongs to group GROUP    -nogroup    group ID not known\n-perm  [-/]MODE  permissions (-=min /=any) -prune      ignore dir contents\n-size  N[c]      512 byte blocks (c=bytes) -xdev       only this filesystem\n-links N         hardlink count            -atime N[u] accessed N units ago\n-ctime N[u]      created N units ago       -mtime N[u] modified N units ago\n-inum N          inode number N            -empty      empty files and dirs\n-true            always true               -false      always false\n-context PATTERN security context          -executable access(X_OK) perm+ACL\n-samefile FILE   hardlink to FILE          -quit       exit immediately\n-depth           ignore contents of dir    -maxdepth N at most N dirs down\n-newer FILE      newer mtime than FILE     -mindepth N at least N dirs down\n-newerXY FILE    X=acm time > FILE's Y=acm time (Y=t: FILE is literal time)\n-type [bcdflps]  type is (block, char, dir, file, symlink, pipe, socket)\n\nNumbers N may be prefixed by a - (less than) or + (greater than). Units for\n-Xtime are d (days, default), h (hours), m (minutes), or s (seconds).\n\nCombine matches with:\n!, -a, -o, ( )    not, and, or, group expressions\n\nActions:\n-print  Print match with newline  -print0        Print match with null\n-exec   Run command with path     -execdir       Run command in file's dir\n-ok     Ask before exec           -okdir         Ask before execdir\n-delete Remove matching file/dir  -printf FORMAT Print using format string\n\nCommands substitute \"{}\" with matched file. End with \";\" to run each file,\nor \"+\" (next argument after \"{}\") to collect and run with multiple files.\n\n-printf FORMAT characters are \\ escapes and:\n%b  512 byte blocks used\n%f  basename            %g  textual gid          %G  numeric gid\n%i  decimal inode       %l  target of symlink    %m  octal mode\n%M  ls format type/mode %p  path to file         %P  path to file minus DIR\n%s  size in bytes       %T@ mod time as unixtime\n%u  username            %U  numeric uid          %Z  security context"
+#define HELP_find "usage: find [-HL] [DIR...] [<options>]\n\nSearch directories for matching files.\nDefault: search \".\", match all, -print matches.\n\n-H  Follow command line symlinks         -L  Follow all symlinks\n\nMatch filters:\n-name  PATTERN   filename with wildcards  (-iname case insensitive)\n-path  PATTERN   path name with wildcards (-ipath case insensitive)\n-user  UNAME     belongs to user UNAME     -nouser     user ID not known\n-group GROUP     belongs to group GROUP    -nogroup    group ID not known\n-perm  [-/]MODE  permissions (-=min /=any) -prune      ignore dir contents\n-size  N[c]      512 byte blocks (c=bytes) -xdev       only this filesystem\n-links N         hardlink count            -atime N[u] accessed N units ago\n-ctime N[u]      created N units ago       -mtime N[u] modified N units ago\n-newer FILE      newer mtime than FILE     -mindepth N at least N dirs down\n-depth           ignore contents of dir    -maxdepth N at most N dirs down\n-inum N          inode number N            -empty      empty files and dirs\n-type [bcdflps]  type is (block, char, dir, file, symlink, pipe, socket)\n-true            always true               -false      always false\n-context PATTERN security context          -executable access(X_OK) perm+ACL\n-newerXY FILE    X=acm time > FILE's Y=acm time (Y=t: FILE is literal time)\n\nNumbers N may be prefixed by a - (less than) or + (greater than). Units for\n-Xtime are d (days, default), h (hours), m (minutes), or s (seconds).\n\nCombine matches with:\n!, -a, -o, ( )    not, and, or, group expressions\n\nActions:\n-print  Print match with newline  -print0        Print match with null\n-exec   Run command with path     -execdir       Run command in file's dir\n-ok     Ask before exec           -okdir         Ask before execdir\n-delete Remove matching file/dir  -printf FORMAT Print using format string\n\nCommands substitute \"{}\" with matched file. End with \";\" to run each file,\nor \"+\" (next argument after \"{}\") to collect and run with multiple files.\n\n-printf FORMAT characters are \\ escapes and:\n%b  512 byte blocks used\n%f  basename            %g  textual gid          %G  numeric gid\n%i  decimal inode       %l  target of symlink    %m  octal mode\n%M  ls format type/mode %p  path to file         %P  path to file minus DIR\n%s  size in bytes       %T@ mod time as unixtime\n%u  username            %U  numeric uid          %Z  security context"
 
 #define HELP_file "usage: file [-bhLs] [FILE...]\n\nExamine the given files and describe their content types.\n\n-b	Brief (no filename)\n-h	Don't follow symlinks (default)\n-L	Follow symlinks\n-s	Show block/char device contents"
 
@@ -618,7 +596,7 @@
 
 #define HELP_env "usage: env [-i] [-u NAME] [NAME=VALUE...] [COMMAND...]\n\nSet the environment for command invocation, or list environment variables.\n\n-i	Clear existing environment\n-u NAME	Remove NAME from the environment\n-0	Use null instead of newline in output"
 
-#define HELP_echo "usage: echo [-neE] [ARG...]\n\nWrite each argument to stdout, one space between each, followed by a newline.\n\n-n	No trailing newline\n-E	Print escape sequences literally (default)\n-e	Process the following escape sequences:\n	\\\\  Backslash		\\0NNN Octal (1-3 digit)	\\xHH Hex (1-2 digit)\n	\\a  Alert (beep/flash)	\\b  Backspace		\\c  Stop here (no \\n)\n	\\f  Form feed		\\n  Newline		\\r  Carriage return\n	\\t  Horizontal tab	\\v  Vertical tab"
+#define HELP_echo "usage: echo [-neE] [ARG...]\n\nWrite each argument to stdout, with one space between each, followed\nby a newline.\n\n-n	No trailing newline\n-E	Print escape sequences literally (default)\n-e	Process the following escape sequences:\n	\\\\	Backslash\n	\\0NNN	Octal values (1 to 3 digits)\n	\\a	Alert (beep/flash)\n	\\b	Backspace\n	\\c	Stop output here (avoids trailing newline)\n	\\f	Form feed\n	\\n	Newline\n	\\r	Carriage return\n	\\t	Horizontal tab\n	\\v	Vertical tab\n	\\xHH	Hexadecimal values (1 to 2 digits)"
 
 #define HELP_du "usage: du [-d N] [-askxHLlmc] [FILE...]\n\nShow disk usage, space consumed by files and directories.\n\nSize in:\n-b	Apparent bytes (directory listing size, not space used)\n-k	1024 byte blocks (default)\n-K	512 byte blocks (posix)\n-m	Megabytes\n-h	Human readable (e.g., 1K 243M 2G)\n\nWhat to show:\n-a	All files, not just directories\n-H	Follow symlinks on cmdline\n-L	Follow all symlinks\n-s	Only total size of each argument\n-x	Don't leave this filesystem\n-c	Cumulative total\n-d N	Only depth < N\n-l	Disable hardlink filter"
 
@@ -626,9 +604,9 @@
 
 #define HELP_df "usage: df [-HPkhi] [-t type] [FILE...]\n\nThe \"disk free\" command shows total/used/available disk space for\neach filesystem listed on the command line, or all currently mounted\nfilesystems.\n\n-a	Show all (including /proc and friends)\n-P	The SUSv3 \"Pedantic\" option\n-k	Sets units back to 1024 bytes (the default without -P)\n-h	Human readable (K=1024)\n-H	Human readable (k=1000)\n-i	Show inodes instead of blocks\n-t type	Display only filesystems of this type\n\nPedantic provides a slightly less useful output format dictated by POSIX,\nand sets the units to 512 bytes instead of the default 1024 bytes."
 
-#define HELP_date "usage: date [-u] [-I RES] [-r FILE] [-d DATE] [+DISPLAY_FORMAT] [-D SET_FORMAT] [SET]\n\nSet/get the current date/time. With no SET shows the current date.\n\n-d	Show DATE instead of current time (convert date format)\n-D	+FORMAT for SET or -d (instead of MMDDhhmm[[CC]YY][.ss])\n-I RES	ISO 8601 with RESolution d=date/h=hours/m=minutes/s=seconds/n=ns\n-r	Use modification time of FILE instead of current date\n-s DATE	Set the system clock to DATE.\n-u	Use UTC instead of current timezone\n\nSupported input formats:\n\nMMDDhhmm[[CC]YY][.ss]     POSIX\n@UNIXTIME[.FRACTION]      seconds since midnight 1970-01-01\nYYYY-MM-DD [hh:mm[:ss]]   ISO 8601\nhh:mm[:ss]                24-hour time today\n\nAll input formats can be followed by fractional seconds, and/or a UTC\noffset such as -0800.\n\nAll input formats can be preceded by TZ=\"id\" to set the input time zone\nseparately from the output time zone. Otherwise $TZ sets both.\n\n+FORMAT specifies display format string using strftime(3) syntax:\n\n%% literal %             %n newline              %t tab\n%S seconds (00-60)       %M minute (00-59)       %m month (01-12)\n%H hour (0-23)           %I hour (01-12)         %p AM/PM\n%y short year (00-99)    %Y year                 %C century\n%a short weekday name    %A weekday name         %u day of week (1-7, 1=mon)\n%b short month name      %B month name           %Z timezone name\n%j day of year (001-366) %d day of month (01-31) %e day of month ( 1-31)\n%N nanosec (output only)\n\n%U Week of year (0-53 start Sunday)   %W Week of year (0-53 start Monday)\n%V Week of year (1-53 start Monday, week < 4 days not part of this year)\n\n%F \"%Y-%m-%d\"   %R \"%H:%M\"        %T \"%H:%M:%S\"        %z  timezone (-0800)\n%D \"%m/%d/%y\"   %r \"%I:%M:%S %p\"  %h \"%b\"              %:z timezone (-08:00)\n%x locale date  %X locale time    %c locale date/time  %s  unix epoch time"
+#define HELP_date "usage: date [-u] [-I RES] [-r FILE] [-d DATE] [+DISPLAY_FORMAT] [-D SET_FORMAT] [SET]\n\nSet/get the current date/time. With no SET shows the current date.\n\n-d	Show DATE instead of current time (convert date format)\n-D	+FORMAT for SET or -d (instead of MMDDhhmm[[CC]YY][.ss])\n-I RES	ISO 8601 with RESolution d=date/h=hours/m=minutes/s=seconds/n=ns\n-r	Use modification time of FILE instead of current date\n-u	Use UTC instead of current timezone\n\nSupported input formats:\n\nMMDDhhmm[[CC]YY][.ss]     POSIX\n@UNIXTIME[.FRACTION]      seconds since midnight 1970-01-01\nYYYY-MM-DD [hh:mm[:ss]]   ISO 8601\nhh:mm[:ss]                24-hour time today\n\nAll input formats can be followed by fractional seconds, and/or a UTC\noffset such as -0800.\n\nAll input formats can be preceded by TZ=\"id\" to set the input time zone\nseparately from the output time zone. Otherwise $TZ sets both.\n\n+FORMAT specifies display format string using strftime(3) syntax:\n\n%% literal %             %n newline              %t tab\n%S seconds (00-60)       %M minute (00-59)       %m month (01-12)\n%H hour (0-23)           %I hour (01-12)         %p AM/PM\n%y short year (00-99)    %Y year                 %C century\n%a short weekday name    %A weekday name         %u day of week (1-7, 1=mon)\n%b short month name      %B month name           %Z timezone name\n%j day of year (001-366) %d day of month (01-31) %e day of month ( 1-31)\n%N nanosec (output only)\n\n%U Week of year (0-53 start Sunday)   %W Week of year (0-53 start Monday)\n%V Week of year (1-53 start Monday, week < 4 days not part of this year)\n\n%F \"%Y-%m-%d\"   %R \"%H:%M\"        %T \"%H:%M:%S\"        %z  timezone (-0800)\n%D \"%m/%d/%y\"   %r \"%I:%M:%S %p\"  %h \"%b\"              %:z timezone (-08:00)\n%x locale date  %X locale time    %c locale date/time  %s  unix epoch time"
 
-#define HELP_cut "usage: cut [-Ds] [-bcCfF LIST] [-dO DELIM] [FILE...]\n\nPrint selected parts of lines from each FILE to standard output.\n\nEach selection LIST is comma separated, either numbers (counting from 1)\nor dash separated ranges (inclusive, with X- meaning to end of line and -X\nfrom start). By default selection ranges are sorted and collated, use -D\nto prevent that.\n\n-b	Select bytes\n-c	Select UTF-8 characters\n-C	Select unicode columns\n-d	Use DELIM (default is TAB for -f, run of whitespace for -F)\n-D	Don't sort/collate selections or match -fF lines without delimiter\n-f	Select fields (words) separated by single DELIM character\n-F	Select fields separated by DELIM regex\n-O	Output delimiter (default one space for -F, input delim for -f)\n-s	Skip lines without delimiters"
+#define HELP_cut "usage: cut [-Ds] [-bcfF LIST] [-dO DELIM] [FILE...]\n\nPrint selected parts of lines from each FILE to standard output.\n\nEach selection LIST is comma separated, either numbers (counting from 1)\nor dash separated ranges (inclusive, with X- meaning to end of line and -X\nfrom start). By default selection ranges are sorted and collated, use -D\nto prevent that.\n\n-b	Select bytes\n-c	Select UTF-8 characters\n-C	Select unicode columns\n-d	Use DELIM (default is TAB for -f, run of whitespace for -F)\n-D	Don't sort/collate selections or match -fF lines without delimiter\n-f	Select fields (words) separated by single DELIM character\n-F	Select fields separated by DELIM regex\n-O	Output delimiter (default one space for -F, input delim for -f)\n-s	Skip lines without delimiters"
 
 #define HELP_cpio "usage: cpio -{o|t|i|p DEST} [-v] [--verbose] [-F FILE] [--no-preserve-owner]\n       [ignored: -m -H newc]\n\nCopy files into and out of a \"newc\" format cpio archive.\n\n-F FILE	Use archive FILE instead of stdin/stdout\n-p DEST	Copy-pass mode, copy stdin file list to directory DEST\n-i	Extract from archive into file system (stdin=archive)\n-o	Create archive (stdin=list of files, stdout=archive)\n-t	Test files (list only, stdin=archive, stdout=list of files)\n-d	Create directories if needed\n-u	unlink existing files when extracting\n-v	Verbose\n--no-preserve-owner (don't set ownership during extract)"
 
@@ -640,7 +618,7 @@
 
 #define HELP_comm "usage: comm [-123] FILE1 FILE2\n\nRead FILE1 and FILE2, which should be ordered, and produce three text\ncolumns as output: lines only in FILE1; lines only in FILE2; and lines\nin both files. Filename \"-\" is a synonym for stdin.\n\n-1	Suppress the output column of lines unique to FILE1\n-2	Suppress the output column of lines unique to FILE2\n-3	Suppress the output column of lines duplicated in FILE1 and FILE2"
 
-#define HELP_cmp "usage: cmp [-ls] [-n LEN] FILE1 [FILE2 [SKIP1 [SKIP2]]]\n\nCompare the contents of files (vs stdin if only one given), optionally\nskipping bytes at start.\n\n-l	Show all differing bytes\n-n LEN	Compare at most LEN bytes\n-s	Silent"
+#define HELP_cmp "usage: cmp [-l] [-s] FILE1 [FILE2 [SKIP1 [SKIP2]]]\n\nCompare the contents of two files. (Or stdin and file if only one given.)\n\n-l	Show all differing bytes\n-s	Silent"
 
 #define HELP_crc32 "usage: crc32 [file...]\n\nOutput crc32 checksum for each file."
 
@@ -656,7 +634,7 @@
 
 #define HELP_cat "usage: cat [-etuv] [FILE...]\n\nCopy (concatenate) files to stdout.  If no files listed, copy from stdin.\nFilename \"-\" is a synonym for stdin.\n\n-e	Mark each newline with $\n-t	Show tabs as ^I\n-u	Copy one byte at a time (slow)\n-v	Display nonprinting characters as escape sequences with M-x for\n	high ascii characters (>127), and ^x for other nonprinting chars"
 
-#define HELP_cal "usage: cal [[[DAY] MONTH] YEAR]\n\nPrint a calendar.\n\nWith one argument, prints all months of the specified year.\nWith two arguments, prints calendar for month and year.\nWith three arguments, highlights day within month and year.\n\n-h	Don't highlight today"
+#define HELP_cal "usage: cal [[MONTH] YEAR]\n\nPrint a calendar.\n\nWith one argument, prints all months of the specified year.\nWith two arguments, prints calendar for month and year.\n\n-h	Don't highlight today"
 
 #define HELP_basename "usage: basename [-a] [-s SUFFIX] NAME... | NAME [SUFFIX]\n\nReturn non-directory portion of a pathname removing suffix.\n\n-a		All arguments are names\n-s SUFFIX	Remove suffix (implies -a)"
 
diff --git a/android/device/generated/newtoys.h b/android/device/generated/newtoys.h
index ade8831..40ac3d4 100644
--- a/android/device/generated/newtoys.h
+++ b/android/device/generated/newtoys.h
@@ -1,4 +1,4 @@
-USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT|TOYFLAG_NOHELP))
+USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT))
 USE_SH(OLDTOY(-bash, sh, 0))
 USE_SH(OLDTOY(-sh, sh, 0))
 USE_SH(OLDTOY(-toysh, sh, 0))
@@ -11,7 +11,7 @@
 USE_ARCH(NEWTOY(arch, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_ARP(NEWTOY(arp, "vi:nDsdap:A:H:[+Ap][!sd]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_ARPING(NEWTOY(arping, "<1>1s:I:w#<0c#<0AUDbqf[+AU][+Df]", TOYFLAG_USR|TOYFLAG_SBIN))
-USE_ASCII(NEWTOY(ascii, 0, TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LINEBUF))
+USE_ASCII(NEWTOY(ascii, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_BASE32(NEWTOY(base32, "diw#<0=76[!dw]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_BASE64(NEWTOY(base64, "diw#<0=76[!dw]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_BASENAME(NEWTOY(basename, "^<1as:", TOYFLAG_USR|TOYFLAG_BIN))
@@ -24,7 +24,7 @@
 USE_BRCTL(NEWTOY(brctl, "<1", TOYFLAG_USR|TOYFLAG_SBIN))
 USE_BUNZIP2(NEWTOY(bunzip2, "cftkv", TOYFLAG_USR|TOYFLAG_BIN))
 USE_BZCAT(NEWTOY(bzcat, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_CAL(NEWTOY(cal, ">3h", TOYFLAG_USR|TOYFLAG_BIN))
+USE_CAL(NEWTOY(cal, ">2h", TOYFLAG_USR|TOYFLAG_BIN))
 USE_CAT(NEWTOY(cat, "u"USE_CAT_V("vte"), TOYFLAG_BIN))
 USE_CATV(NEWTOY(catv, USE_CATV("vte"), TOYFLAG_USR|TOYFLAG_BIN))
 USE_SH(NEWTOY(cd, ">1LP[-LP]", TOYFLAG_NOFORK))
@@ -39,19 +39,18 @@
 USE_CHVT(NEWTOY(chvt, "<1", TOYFLAG_USR|TOYFLAG_BIN))
 USE_CKSUM(NEWTOY(cksum, "HIPLN", TOYFLAG_BIN))
 USE_CLEAR(NEWTOY(clear, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_CMP(NEWTOY(cmp, "<1>4ls(silent)(quiet)n#<1[!ls]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
+USE_CMP(NEWTOY(cmp, "<1>2ls(silent)(quiet)[!ls]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
 USE_COMM(NEWTOY(comm, "<2>2321", TOYFLAG_USR|TOYFLAG_BIN))
 USE_COUNT(NEWTOY(count, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]", TOYFLAG_BIN))
-USE_CPIO(NEWTOY(cpio, "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
+USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]", TOYFLAG_BIN))
+USE_CPIO(NEWTOY(cpio, "(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
 USE_CRC32(NEWTOY(crc32, 0, TOYFLAG_BIN))
 USE_CROND(NEWTOY(crond, "fbSl#<0=8d#<0L:c:[-bf][-LS][-ld]", TOYFLAG_USR|TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_CRONTAB(NEWTOY(crontab, "c:u:elr[!elr]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
-USE_CUT(NEWTOY(cut, "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_DATE(NEWTOY(date, "d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr]", TOYFLAG_BIN))
+USE_CUT(NEWTOY(cut, "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_DATE(NEWTOY(date, "d:D:I(iso)(iso-8601):;r:u(utc)[!dr]", TOYFLAG_BIN))
 USE_DD(NEWTOY(dd, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_DEALLOCVT(NEWTOY(deallocvt, ">1", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NEEDROOT))
-USE_SH(NEWTOY(declare, "pAailunxr", TOYFLAG_NOFORK))
 USE_GROUPDEL(OLDTOY(delgroup, groupdel, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_USERDEL(OLDTOY(deluser, userdel, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_DEMO_MANY_OPTIONS(NEWTOY(demo_many_options, "ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba", TOYFLAG_BIN))
@@ -90,7 +89,7 @@
 USE_FLOCK(NEWTOY(flock, "<1>1nsux[-sux]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_FMT(NEWTOY(fmt, "w#<0=75", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_FOLD(NEWTOY(fold, "bsuw#<1", TOYFLAG_USR|TOYFLAG_BIN))
-USE_FREE(NEWTOY(free, "hgmkb[!hgmkb]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_FREE(NEWTOY(free, "htgmkb[!htgmkb]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_FREERAMDISK(NEWTOY(freeramdisk, "<1>1", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_FSCK(NEWTOY(fsck, "?t:ANPRTVsC#", TOYFLAG_USR|TOYFLAG_BIN))
 USE_FSFREEZE(NEWTOY(fsfreeze, "<1>1f|u|[!fu]", TOYFLAG_USR|TOYFLAG_SBIN))
@@ -103,29 +102,22 @@
 USE_GETFATTR(NEWTOY(getfattr, "(only-values)dhn:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_GETOPT(NEWTOY(getopt, "^a(alternative)n:(name)o:(options)l*(long)(longoptions)Tu", TOYFLAG_USR|TOYFLAG_BIN))
 USE_GETTY(NEWTOY(getty, "<2t#<0H:I:l:f:iwnmLh", TOYFLAG_SBIN))
-USE_GPIODETECT(NEWTOY(gpiodetect, ">0", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOINFO(NEWTOY(gpiofind, "<1>1", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOGET(NEWTOY(gpioget, "<2l", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOFIND(NEWTOY(gpioinfo, 0, TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOSET(NEWTOY(gpioset, "<2l", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GREP(NEWTOY(grep, "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF]", TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)|TOYFLAG_LINEBUF))
+USE_GREP(NEWTOY(grep, "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw]", TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)|TOYFLAG_LINEBUF))
 USE_GROUPADD(NEWTOY(groupadd, "<1>2g#<0S", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_GROUPDEL(NEWTOY(groupdel, "<1>2", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_GROUPS(NEWTOY(groups, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 USE_GUNZIP(NEWTOY(gunzip, "cdfk123456789[-123456789]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_GZIP(NEWTOY(gzip,    "ncdfk123456789[-123456789]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_REBOOT(OLDTOY(halt, reboot, TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
-USE_HD(OLDTOY(hd, hexdump, TOYFLAG_USR|TOYFLAG_BIN))
 USE_HEAD(NEWTOY(head, "?n(lines)#<0=10c(bytes)#<0qv[-nc]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HELLO(NEWTOY(hello, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_HELP(NEWTOY(help, "ahu", TOYFLAG_BIN|TOYFLAG_MAYFORK))
-USE_HEXDUMP(NEWTOY(hexdump, "bcCdn#<0os#<0vx[!bcCdox]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HEXEDIT(NEWTOY(hexedit, "<1>1r", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_HOST(NEWTOY(host, "<1>2avt:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HOSTID(NEWTOY(hostid, ">0", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HOSTNAME(NEWTOY(hostname, ">1bdsfF:[!bdsf]", TOYFLAG_BIN))
 USE_HWCLOCK(NEWTOY(hwclock, ">0(fast)f(rtc):u(utc)l(localtime)t(systz)s(hctosys)r(show)w(systohc)[-ul][!rtsw]", TOYFLAG_SBIN))
-USE_I2CDETECT(NEWTOY(i2cdetect, ">3aFlqry[!qr]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_I2CDETECT(NEWTOY(i2cdetect, ">3aFly", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CDUMP(NEWTOY(i2cdump, "<2>2fy", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CGET(NEWTOY(i2cget, "<3>3fy", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CSET(NEWTOY(i2cset, "<4fy", TOYFLAG_USR|TOYFLAG_BIN))
@@ -137,7 +129,7 @@
 USE_INSMOD(NEWTOY(insmod, "<1", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_INSTALL(NEWTOY(install, "<1cdDpsvt:m:o:g:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_IONICE(NEWTOY(ionice, "^tc#<0>3=2n#<0>7=5p#", TOYFLAG_USR|TOYFLAG_BIN))
-USE_IORENICE(NEWTOY(iorenice, "<1>3", TOYFLAG_USR|TOYFLAG_BIN))
+USE_IORENICE(NEWTOY(iorenice, "?<1>3", TOYFLAG_USR|TOYFLAG_BIN))
 USE_IOTOP(NEWTOY(iotop, ">0AaKO" "Hk*o*p*u*s#<1=7d%<100=3000m#n#<1bq", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT|TOYFLAG_LOCALE))
 USE_IP(NEWTOY(ip, NULL, TOYFLAG_SBIN))
 USE_IP(OLDTOY(ipaddr, ip, TOYFLAG_SBIN))
@@ -154,21 +146,20 @@
 USE_KLOGD(NEWTOY(klogd, "c#<1>8n", TOYFLAG_SBIN))
 USE_LAST(NEWTOY(last, "f:W", TOYFLAG_BIN))
 USE_LINK(NEWTOY(link, "<2>2", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LINUX32(NEWTOY(linux32, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_LN(NEWTOY(ln, "<1rt:Tvnfs", TOYFLAG_BIN))
 USE_LOAD_POLICY(NEWTOY(load_policy, "<1>1", TOYFLAG_USR|TOYFLAG_SBIN))
-USE_LOG(NEWTOY(log, "p:t:", TOYFLAG_USR|TOYFLAG_SBIN))
+USE_LOG(NEWTOY(log, "<1p:t:", TOYFLAG_USR|TOYFLAG_SBIN))
 USE_LOGGER(NEWTOY(logger, "t:p:s", TOYFLAG_USR|TOYFLAG_BIN))
 USE_LOGIN(NEWTOY(login, ">1f:ph:", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
 USE_LOGNAME(NEWTOY(logname, ">0", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LOGPATH(NEWTOY(logpath, 0, TOYFLAG_NOHELP|TOYFLAG_USR|TOYFLAG_BIN))
+USE_LOGWRAPPER(NEWTOY(logwrapper, 0, TOYFLAG_NOHELP|TOYFLAG_USR|TOYFLAG_BIN))
 USE_LOSETUP(NEWTOY(losetup, ">2S(sizelimit)#s(show)ro#j:fdcaD[!afj]", TOYFLAG_SBIN))
 USE_LS(NEWTOY(ls, "(color):;(full-time)(show-control-chars)ZgoACFHLRSabcdfhikl@mnpqrstuw#=80<0x1[-Cxm1][-Cxml][-Cxmo][-Cxmg][-cu][-ftS][-HL][!qb]", TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_LSATTR(NEWTOY(lsattr, "ldapvR", TOYFLAG_BIN))
 USE_LSMOD(NEWTOY(lsmod, NULL, TOYFLAG_SBIN))
 USE_LSOF(NEWTOY(lsof, "lp*t", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LSPCI(NEWTOY(lspci, "emkn@i:", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LSUSB(NEWTOY(lsusb, "i:", TOYFLAG_USR|TOYFLAG_BIN))
+USE_LSPCI(NEWTOY(lspci, "emkn"USE_LSPCI_TEXT("@i:"), TOYFLAG_USR|TOYFLAG_BIN))
+USE_LSUSB(NEWTOY(lsusb, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 USE_MAKEDEVS(NEWTOY(makedevs, "<1>1d:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_MAN(NEWTOY(man, "k:M:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_MCOOKIE(NEWTOY(mcookie, "v(verbose)V(version)", TOYFLAG_USR|TOYFLAG_BIN))
@@ -195,24 +186,24 @@
 USE_NETCAT(NEWTOY(netcat, USE_NETCAT_LISTEN("^tElL")"w#<1W#<1p#<1>65535q#<1s:f:46uU"USE_NETCAT_LISTEN("[!tlL][!Lw]")"[!46U]", TOYFLAG_BIN))
 USE_NETSTAT(NEWTOY(netstat, "pWrxwutneal", TOYFLAG_BIN))
 USE_NICE(NEWTOY(nice, "^<1n#", TOYFLAG_BIN))
-USE_NL(NEWTOY(nl, "v#=1l#w#<0=6b:n:s:E", TOYFLAG_USR|TOYFLAG_BIN))
+USE_NL(NEWTOY(nl, "v#=1l#w#<0=6Eb:n:s:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_NOHUP(NEWTOY(nohup, "<1^", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
 USE_NPROC(NEWTOY(nproc, "(all)", TOYFLAG_USR|TOYFLAG_BIN))
 USE_NSENTER(NEWTOY(nsenter, "<1F(no-fork)t#<1(target)i:(ipc);m:(mount);n:(net);p:(pid);u:(uts);U:(user);", TOYFLAG_USR|TOYFLAG_BIN))
 USE_OD(NEWTOY(od, "j#vw#<1=16N#xsodcbA:t*", TOYFLAG_USR|TOYFLAG_BIN))
 USE_ONEIT(NEWTOY(oneit, "^<1nc:p3[!pn]", TOYFLAG_SBIN))
-USE_OPENVT(NEWTOY(openvt, "^<1c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
+USE_OPENVT(NEWTOY(openvt, "c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
 USE_PARTPROBE(NEWTOY(partprobe, "<1", TOYFLAG_SBIN))
 USE_PASSWD(NEWTOY(passwd, ">1a:dlu", TOYFLAG_STAYROOT|TOYFLAG_USR|TOYFLAG_BIN))
 USE_PASTE(NEWTOY(paste, "d:s", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_PATCH(NEWTOY(patch, ">2(no-backup-if-mismatch)(dry-run)"USE_TOYBOX_DEBUG("x")"F#g#fulp#d:i:Rs(quiet)", TOYFLAG_USR|TOYFLAG_BIN))
 USE_PGREP(NEWTOY(pgrep, "?cld:u*U*t*s*P*g*G*fnovxL:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_PIDOF(NEWTOY(pidof, "so:x", TOYFLAG_BIN))
+USE_PIDOF(NEWTOY(pidof, "<1so:x", TOYFLAG_BIN))
 USE_PING(NEWTOY(ping, "<1>1m#t#<0>255=64c#<0=3s#<0>4064=56i%W#<0=3w#<0qf46I:[-46]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_PING(OLDTOY(ping6, ping, TOYFLAG_USR|TOYFLAG_BIN))
 USE_PIVOT_ROOT(NEWTOY(pivot_root, "<2>2", TOYFLAG_SBIN))
 USE_PKILL(NEWTOY(pkill,    "?Vu*U*t*s*P*g*G*fnovxl:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_PMAP(NEWTOY(pmap, "<1pqx", TOYFLAG_USR|TOYFLAG_BIN))
+USE_PMAP(NEWTOY(pmap, "<1xq", TOYFLAG_USR|TOYFLAG_BIN))
 USE_REBOOT(OLDTOY(poweroff, reboot, TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_PRINTENV(NEWTOY(printenv, "(null)0", TOYFLAG_BIN))
 USE_PRINTF(NEWTOY(printf, "<1?^", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
@@ -224,8 +215,8 @@
 USE_READAHEAD(NEWTOY(readahead, NULL, TOYFLAG_BIN))
 USE_READELF(NEWTOY(readelf, "<1(dyn-syms)adehlnp:SsWx:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_READLINK(NEWTOY(readlink, "<1nqmef(canonicalize)[-mef]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_REALPATH(OLDTOY(realpath, readlink, TOYFLAG_USR|TOYFLAG_BIN))
-USE_REBOOT(NEWTOY(reboot, "d:fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
+USE_REALPATH(NEWTOY(realpath, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+USE_REBOOT(NEWTOY(reboot, "fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_RENICE(NEWTOY(renice, "<1gpun#|", TOYFLAG_USR|TOYFLAG_BIN))
 USE_RESET(NEWTOY(reset, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_RESTORECON(NEWTOY(restorecon, "<1DFnRrv", TOYFLAG_USR|TOYFLAG_SBIN))
@@ -245,12 +236,12 @@
 USE_SETFATTR(NEWTOY(setfattr, "hn:|v:x:|[!xv]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SETSID(NEWTOY(setsid, "^<1wcd[!dc]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SH(NEWTOY(sh, "0(noediting)(noprofile)(norc)sc:i", TOYFLAG_BIN))
-USE_SHA1SUM(OLDTOY(sha1sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA224SUM(OLDTOY(sha224sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA256SUM(OLDTOY(sha256sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA384SUM(OLDTOY(sha384sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_SHA1SUM(NEWTOY(sha1sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TOYBOX_LIBCRYPTO(USE_SHA224SUM(OLDTOY(sha224sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
+USE_TOYBOX_LIBCRYPTO(USE_SHA256SUM(OLDTOY(sha256sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
+USE_TOYBOX_LIBCRYPTO(USE_SHA384SUM(OLDTOY(sha384sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
 USE_SHA3SUM(NEWTOY(sha3sum, "bSa#<128>512=224", TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA512SUM(OLDTOY(sha512sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_TOYBOX_LIBCRYPTO(USE_SHA512SUM(OLDTOY(sha512sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
 USE_SH(NEWTOY(shift, ">1", TOYFLAG_NOFORK))
 USE_SHRED(NEWTOY(shred, "<1zxus#<1n#<1o#<0f", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SKELETON(NEWTOY(skeleton, "(walrus)(blubber):;(also):e@d*c#b:a", TOYFLAG_USR|TOYFLAG_BIN))
@@ -259,9 +250,8 @@
 USE_SNTP(NEWTOY(sntp, ">1M :m :Sp:t#<0=1>16asdDqr#<4>17=10[!as]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SORT(NEWTOY(sort, USE_SORT_FLOAT("g")"S:T:m" "o:k*t:" "xVbMcszdfirun", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
 USE_SH(NEWTOY(source, "<1", TOYFLAG_NOFORK))
-USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1[!bl]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_STAT(NEWTOY(stat, "<1c:(format)fLt", TOYFLAG_BIN))
-USE_STRACE(NEWTOY(strace, "^p#s#v", TOYFLAG_USR|TOYFLAG_SBIN))
 USE_STRINGS(NEWTOY(strings, "t:an#=4<1fo", TOYFLAG_USR|TOYFLAG_BIN))
 USE_STTY(NEWTOY(stty, "?aF:g[!ag]", TOYFLAG_BIN))
 USE_SU(NEWTOY(su, "^lmpu:g:c:s:[!lmp]", TOYFLAG_BIN|TOYFLAG_ROOTONLY))
@@ -273,8 +263,8 @@
 USE_SYSCTL(NEWTOY(sysctl, "^neNqwpaA[!ap][!aq][!aw][+aA]", TOYFLAG_SBIN))
 USE_SYSLOGD(NEWTOY(syslogd,">0l#<1>8=8R:b#<0>99=1s#<0=200m#<0>71582787=20O:p:f:a:nSKLD", TOYFLAG_SBIN|TOYFLAG_STAYROOT))
 USE_TAC(NEWTOY(tac, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_TAIL(NEWTOY(tail, "?fFs:c(bytes)-n(lines)-[-cn][-fF]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_TAR(NEWTOY(tar, "&(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TAIL(NEWTOY(tail, "?fc-n-[-cn]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TAR(NEWTOY(tar, "&(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TASKSET(NEWTOY(taskset, "<1^pa", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
 USE_TCPSVD(NEWTOY(tcpsvd, "^<3c#=30<1C:b#=20<0u:l:hEv", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TEE(NEWTOY(tee, "ia", TOYFLAG_USR|TOYFLAG_BIN))
@@ -283,9 +273,9 @@
 USE_TEST(NEWTOY(test, 0, TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NOHELP|TOYFLAG_MAYFORK))
 USE_TFTP(NEWTOY(tftp, "<1b#<8>65464r:l:g|p|[!gp]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TFTPD(NEWTOY(tftpd, "rcu:l", TOYFLAG_BIN))
-USE_TIME(NEWTOY(time, "<1^pv[-pv]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
+USE_TIME(NEWTOY(time, "<1^pv", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
 USE_TIMEOUT(NEWTOY(timeout, "<2^(foreground)(preserve-status)vk:s(signal):", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
-USE_TOP(NEWTOY(top, ">0O*h" "Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
+USE_TOP(NEWTOY(top, ">0O*" "Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_TOUCH(NEWTOY(touch, "<1acd:fmr:t:h[!dtr]", TOYFLAG_BIN))
 USE_SH(OLDTOY(toysh, sh, TOYFLAG_BIN))
 USE_TR(NEWTOY(tr, "^>2<1Ccsd[+cC]", TOYFLAG_USR|TOYFLAG_BIN))
@@ -295,11 +285,10 @@
 USE_TRUNCATE(NEWTOY(truncate, "<1s:|c", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TTY(NEWTOY(tty, "s", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TUNCTL(NEWTOY(tunctl, "<1>1t|d|u:T[!td]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_UCLAMPSET(NEWTOY(uclampset, "p#am#<-1>1024M#<-1>1024R", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
 USE_TCPSVD(OLDTOY(udpsvd, tcpsvd, TOYFLAG_USR|TOYFLAG_BIN))
 USE_ULIMIT(NEWTOY(ulimit, ">1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_UMOUNT(NEWTOY(umount, "cndDflrat*v[!na]", TOYFLAG_BIN|TOYFLAG_STAYROOT))
-USE_UNAME(NEWTOY(uname, "aomvrns", TOYFLAG_BIN))
+USE_UNAME(NEWTOY(uname, "oamvrns[+os]", TOYFLAG_BIN))
 USE_UNICODE(NEWTOY(unicode, "<1", TOYFLAG_USR|TOYFLAG_BIN))
 USE_UNIQ(NEWTOY(uniq, "f#s#w#zicdu", TOYFLAG_USR|TOYFLAG_BIN))
 USE_UNIX2DOS(NEWTOY(unix2dos, 0, TOYFLAG_BIN))
@@ -321,12 +310,12 @@
 USE_WATCH(NEWTOY(watch, "^<1n%<100=2000tebx", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_WATCHDOG(NEWTOY(watchdog, "<1>1Ft#=4<1T#=60<1", TOYFLAG_NEEDROOT|TOYFLAG_BIN))
 USE_WC(NEWTOY(wc, "mcwl", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
-USE_WGET(NEWTOY(wget, "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):", TOYFLAG_USR|TOYFLAG_BIN))
+USE_WGET(NEWTOY(wget, "(no-check-certificate)O:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_WHICH(NEWTOY(which, "<1a", TOYFLAG_USR|TOYFLAG_BIN))
 USE_WHO(NEWTOY(who, "a", TOYFLAG_USR|TOYFLAG_BIN))
 USE_WHOAMI(OLDTOY(whoami, logname, TOYFLAG_USR|TOYFLAG_BIN))
 USE_XARGS(NEWTOY(xargs, "^E:P#<0=1optrn#<1(max-args)s#0[!0E]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_XXD(NEWTOY(xxd, ">1c#<0>256l#o#g#<1=2iprs#[!rs]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_XXD(NEWTOY(xxd, ">1c#l#o#g#<1=2iprs#[!rs]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_XZCAT(NEWTOY(xzcat, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 USE_YES(NEWTOY(yes, NULL, TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LINEBUF))
 USE_ZCAT(NEWTOY(zcat,     "cdfk123456789[-123456789]", TOYFLAG_USR|TOYFLAG_BIN))
diff --git a/android/linux/generated/config.h b/android/linux/generated/config.h
index 7d2c730..79502c0 100644
--- a/android/linux/generated/config.h
+++ b/android/linux/generated/config.h
@@ -2,8 +2,6 @@
 #define USE_TOYBOX_ANDROID_SCHEDPOLICY(...)
 #define CFG_TOYBOX_CONTAINER 0
 #define USE_TOYBOX_CONTAINER(...)
-#define CFG_TOYBOX_COPYFILERANGE 0
-#define USE_TOYBOX_COPYFILERANGE(...)
 #define CFG_TOYBOX_DEBUG 0
 #define USE_TOYBOX_DEBUG(...)
 #define CFG_TOYBOX_FALLOCATE 0
@@ -240,16 +238,6 @@
 #define USE_GETOPT(...) __VA_ARGS__
 #define CFG_GETTY 0
 #define USE_GETTY(...)
-#define CFG_GPIODETECT 0
-#define USE_GPIODETECT(...)
-#define CFG_GPIOFIND 0
-#define USE_GPIOFIND(...)
-#define CFG_GPIOGET 0
-#define USE_GPIOGET(...)
-#define CFG_GPIOINFO 0
-#define USE_GPIOINFO(...)
-#define CFG_GPIOSET 0
-#define USE_GPIOSET(...)
 #define CFG_GREP 1
 #define USE_GREP(...) __VA_ARGS__
 #define CFG_GROUPADD 0
@@ -270,12 +258,8 @@
 #define USE_HELP_EXTRAS(...)
 #define CFG_HELP 0
 #define USE_HELP(...)
-#define CFG_HEXDUMP 0
-#define USE_HEXDUMP(...)
 #define CFG_HEXEDIT 0
 #define USE_HEXEDIT(...)
-#define CFG_HD 0
-#define USE_HD(...)
 #define CFG_HOSTID 0
 #define USE_HOSTID(...)
 #define CFG_HOST 0
@@ -306,8 +290,8 @@
 #define USE_INOTIFYD(...)
 #define CFG_INSMOD 0
 #define USE_INSMOD(...)
-#define CFG_INSTALL 1
-#define USE_INSTALL(...) __VA_ARGS__
+#define CFG_INSTALL 0
+#define USE_INSTALL(...)
 #define CFG_IONICE 0
 #define USE_IONICE(...)
 #define CFG_IORENICE 0
@@ -334,8 +318,6 @@
 #define USE_LAST(...)
 #define CFG_LINK 0
 #define USE_LINK(...)
-#define CFG_LINUX32 0
-#define USE_LINUX32(...)
 #define CFG_LN 1
 #define USE_LN(...) __VA_ARGS__
 #define CFG_LOAD_POLICY 0
@@ -348,8 +330,6 @@
 #define USE_LOG(...)
 #define CFG_LOGNAME 0
 #define USE_LOGNAME(...)
-#define CFG_LOGPATH 0
-#define USE_LOGPATH(...)
 #define CFG_LOGWRAPPER 0
 #define USE_LOGWRAPPER(...)
 #define CFG_LOSETUP 0
@@ -558,8 +538,6 @@
 #define USE_SPLIT(...)
 #define CFG_STAT 1
 #define USE_STAT(...) __VA_ARGS__
-#define CFG_STRACE 0
-#define USE_STRACE(...)
 #define CFG_STRINGS 0
 #define USE_STRINGS(...)
 #define CFG_STTY 0
@@ -624,8 +602,6 @@
 #define USE_TTY(...)
 #define CFG_TUNCTL 0
 #define USE_TUNCTL(...)
-#define CFG_UCLAMPSET 0
-#define USE_UCLAMPSET(...)
 #define CFG_ULIMIT 0
 #define USE_ULIMIT(...)
 #define CFG_UMOUNT 0
diff --git a/android/linux/generated/flags.h b/android/linux/generated/flags.h
index 2ab033b..7f37168 100644
--- a/android/linux/generated/flags.h
+++ b/android/linux/generated/flags.h
@@ -5,7 +5,7 @@
 #define FORCED_FLAGLL 1ULL
 #else
 #define FORCED_FLAG 0
-#define FORCED_FLAGLL 0LL
+#define FORCED_FLAGLL 0
 #endif
 
 // acpi   abctV
@@ -200,9 +200,9 @@
 #undef FOR_bzcat
 #endif
 
-// cal   >3h
+// cal   >2h
 #undef OPTSTR_cal
-#define OPTSTR_cal ">3h"
+#define OPTSTR_cal ">2h"
 #ifdef CLEANUP_cal
 #undef CLEANUP_cal
 #undef FOR_cal
@@ -352,13 +352,12 @@
 #undef FOR_clear
 #endif
 
-// cmp <1>4ls(silent)(quiet)n#<1[!ls] <1>4ls(silent)(quiet)n#<1[!ls]
+// cmp <1>2ls(silent)(quiet)[!ls] <1>2ls(silent)(quiet)[!ls]
 #undef OPTSTR_cmp
-#define OPTSTR_cmp "<1>4ls(silent)(quiet)n#<1[!ls]"
+#define OPTSTR_cmp "<1>2ls(silent)(quiet)[!ls]"
 #ifdef CLEANUP_cmp
 #undef CLEANUP_cmp
 #undef FOR_cmp
-#undef FLAG_n
 #undef FLAG_s
 #undef FLAG_l
 #endif
@@ -382,9 +381,9 @@
 #undef FOR_count
 #endif
 
-// cp <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr] <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]
+// cp <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu] <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]
 #undef OPTSTR_cp
-#define OPTSTR_cp "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]"
+#define OPTSTR_cp "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]"
 #ifdef CLEANUP_cp
 #undef CLEANUP_cp
 #undef FOR_cp
@@ -410,9 +409,9 @@
 #undef FLAG_preserve
 #endif
 
-// cpio (ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF] (ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]
+// cpio (quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF] (quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]
 #undef OPTSTR_cpio
-#define OPTSTR_cpio "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]"
+#define OPTSTR_cpio "(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]"
 #ifdef CLEANUP_cpio
 #undef CLEANUP_cpio
 #undef FOR_cpio
@@ -428,8 +427,6 @@
 #undef FLAG_m
 #undef FLAG_no_preserve_owner
 #undef FLAG_quiet
-#undef FLAG_renumber_inodes
-#undef FLAG_ignore_devno
 #endif
 
 // crc32    
@@ -468,9 +465,9 @@
 #undef FLAG_c
 #endif
 
-// cut b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF] b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF]
+// cut b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf] b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]
 #undef OPTSTR_cut
-#define OPTSTR_cut "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF]"
+#define OPTSTR_cut "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]"
 #ifdef CLEANUP_cut
 #undef CLEANUP_cut
 #undef FOR_cut
@@ -486,14 +483,13 @@
 #undef FLAG_b
 #endif
 
-// date d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr] d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr]
+// date d:D:I(iso)(iso-8601):;r:u(utc)[!dr] d:D:I(iso)(iso-8601):;r:u(utc)[!dr]
 #undef OPTSTR_date
-#define OPTSTR_date "d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr]"
+#define OPTSTR_date "d:D:I(iso)(iso-8601):;r:u(utc)[!dr]"
 #ifdef CLEANUP_date
 #undef CLEANUP_date
 #undef FOR_date
 #undef FLAG_u
-#undef FLAG_s
 #undef FLAG_r
 #undef FLAG_I
 #undef FLAG_D
@@ -516,23 +512,6 @@
 #undef FOR_deallocvt
 #endif
 
-// declare   pAailunxr
-#undef OPTSTR_declare
-#define OPTSTR_declare "pAailunxr"
-#ifdef CLEANUP_declare
-#undef CLEANUP_declare
-#undef FOR_declare
-#undef FLAG_r
-#undef FLAG_x
-#undef FLAG_n
-#undef FLAG_u
-#undef FLAG_l
-#undef FLAG_i
-#undef FLAG_a
-#undef FLAG_A
-#undef FLAG_p
-#endif
-
 // demo_many_options   ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba
 #undef OPTSTR_demo_many_options
 #define OPTSTR_demo_many_options "ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
@@ -995,9 +974,9 @@
 #undef FLAG_b
 #endif
 
-// free   hgmkb[!hgmkb]
+// free   htgmkb[!htgmkb]
 #undef OPTSTR_free
-#define OPTSTR_free "hgmkb[!hgmkb]"
+#define OPTSTR_free "htgmkb[!htgmkb]"
 #ifdef CLEANUP_free
 #undef CLEANUP_free
 #undef FOR_free
@@ -1005,6 +984,7 @@
 #undef FLAG_k
 #undef FLAG_m
 #undef FLAG_g
+#undef FLAG_t
 #undef FLAG_h
 #endif
 
@@ -1144,51 +1124,9 @@
 #undef FLAG_t
 #endif
 
-// gpiodetect   >0
-#undef OPTSTR_gpiodetect
-#define OPTSTR_gpiodetect ">0"
-#ifdef CLEANUP_gpiodetect
-#undef CLEANUP_gpiodetect
-#undef FOR_gpiodetect
-#endif
-
-// gpiofind   <1>1
-#undef OPTSTR_gpiofind
-#define OPTSTR_gpiofind "<1>1"
-#ifdef CLEANUP_gpiofind
-#undef CLEANUP_gpiofind
-#undef FOR_gpiofind
-#endif
-
-// gpioget   <2l
-#undef OPTSTR_gpioget
-#define OPTSTR_gpioget "<2l"
-#ifdef CLEANUP_gpioget
-#undef CLEANUP_gpioget
-#undef FOR_gpioget
-#undef FLAG_l
-#endif
-
-// gpioinfo    
-#undef OPTSTR_gpioinfo
-#define OPTSTR_gpioinfo 0
-#ifdef CLEANUP_gpioinfo
-#undef CLEANUP_gpioinfo
-#undef FOR_gpioinfo
-#endif
-
-// gpioset   <2l
-#undef OPTSTR_gpioset
-#define OPTSTR_gpioset "<2l"
-#ifdef CLEANUP_gpioset
-#undef CLEANUP_gpioset
-#undef FOR_gpioset
-#undef FLAG_l
-#endif
-
-// grep (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF] (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF]
+// grep (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw] (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw]
 #undef OPTSTR_grep
-#define OPTSTR_grep "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF]"
+#define OPTSTR_grep "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw]"
 #ifdef CLEANUP_grep
 #undef CLEANUP_grep
 #undef FOR_grep
@@ -1201,7 +1139,6 @@
 #undef FLAG_e
 #undef FLAG_q
 #undef FLAG_l
-#undef FLAG_L
 #undef FLAG_c
 #undef FLAG_w
 #undef FLAG_v
@@ -1327,23 +1264,6 @@
 #undef FLAG_a
 #endif
 
-// hexdump   bcCdn#<0os#<0vx[!bcCdox]
-#undef OPTSTR_hexdump
-#define OPTSTR_hexdump "bcCdn#<0os#<0vx[!bcCdox]"
-#ifdef CLEANUP_hexdump
-#undef CLEANUP_hexdump
-#undef FOR_hexdump
-#undef FLAG_x
-#undef FLAG_v
-#undef FLAG_s
-#undef FLAG_o
-#undef FLAG_n
-#undef FLAG_d
-#undef FLAG_C
-#undef FLAG_c
-#undef FLAG_b
-#endif
-
 // hexedit   <1>1r
 #undef OPTSTR_hexedit
 #define OPTSTR_hexedit "<1>1r"
@@ -1401,15 +1321,13 @@
 #undef FLAG_fast
 #endif
 
-// i2cdetect   >3aFlqry[!qr]
+// i2cdetect   >3aFly
 #undef OPTSTR_i2cdetect
-#define OPTSTR_i2cdetect ">3aFlqry[!qr]"
+#define OPTSTR_i2cdetect ">3aFly"
 #ifdef CLEANUP_i2cdetect
 #undef CLEANUP_i2cdetect
 #undef FOR_i2cdetect
 #undef FLAG_y
-#undef FLAG_r
-#undef FLAG_q
 #undef FLAG_l
 #undef FLAG_F
 #undef FLAG_a
@@ -1505,7 +1423,7 @@
 #undef FOR_insmod
 #endif
 
-// install <1cdDpsvt:m:o:g: <1cdDpsvt:m:o:g:
+// install   <1cdDpsvt:m:o:g:
 #undef OPTSTR_install
 #define OPTSTR_install "<1cdDpsvt:m:o:g:"
 #ifdef CLEANUP_install
@@ -1535,9 +1453,9 @@
 #undef FLAG_t
 #endif
 
-// iorenice   <1>3
+// iorenice   ?<1>3
 #undef OPTSTR_iorenice
-#define OPTSTR_iorenice "<1>3"
+#define OPTSTR_iorenice "?<1>3"
 #ifdef CLEANUP_iorenice
 #undef CLEANUP_iorenice
 #undef FOR_iorenice
@@ -1682,14 +1600,6 @@
 #undef FOR_link
 #endif
 
-// linux32    
-#undef OPTSTR_linux32
-#define OPTSTR_linux32 0
-#ifdef CLEANUP_linux32
-#undef CLEANUP_linux32
-#undef FOR_linux32
-#endif
-
 // ln <1rt:Tvnfs <1rt:Tvnfs
 #undef OPTSTR_ln
 #define OPTSTR_ln "<1rt:Tvnfs"
@@ -1713,9 +1623,9 @@
 #undef FOR_load_policy
 #endif
 
-// log   p:t:
+// log   <1p:t:
 #undef OPTSTR_log
-#define OPTSTR_log "p:t:"
+#define OPTSTR_log "<1p:t:"
 #ifdef CLEANUP_log
 #undef CLEANUP_log
 #undef FOR_log
@@ -1753,12 +1663,12 @@
 #undef FOR_logname
 #endif
 
-// logpath    
-#undef OPTSTR_logpath
-#define OPTSTR_logpath 0
-#ifdef CLEANUP_logpath
-#undef CLEANUP_logpath
-#undef FOR_logpath
+// logwrapper    
+#undef OPTSTR_logwrapper
+#define OPTSTR_logwrapper 0
+#ifdef CLEANUP_logwrapper
+#undef CLEANUP_logwrapper
+#undef FOR_logwrapper
 #endif
 
 // losetup   >2S(sizelimit)#s(show)ro#j:fdcaD[!afj]
@@ -1866,13 +1776,12 @@
 #undef FLAG_e
 #endif
 
-// lsusb   i:
+// lsusb    
 #undef OPTSTR_lsusb
-#define OPTSTR_lsusb "i:"
+#define OPTSTR_lsusb 0
 #ifdef CLEANUP_lsusb
 #undef CLEANUP_lsusb
 #undef FOR_lsusb
-#undef FLAG_i
 #endif
 
 // makedevs   <1>1d:
@@ -2168,16 +2077,16 @@
 #undef FLAG_n
 #endif
 
-// nl v#=1l#w#<0=6b:n:s:E v#=1l#w#<0=6b:n:s:E
+// nl v#=1l#w#<0=6Eb:n:s: v#=1l#w#<0=6Eb:n:s:
 #undef OPTSTR_nl
-#define OPTSTR_nl "v#=1l#w#<0=6b:n:s:E"
+#define OPTSTR_nl "v#=1l#w#<0=6Eb:n:s:"
 #ifdef CLEANUP_nl
 #undef CLEANUP_nl
 #undef FOR_nl
-#undef FLAG_E
 #undef FLAG_s
 #undef FLAG_n
 #undef FLAG_b
+#undef FLAG_E
 #undef FLAG_w
 #undef FLAG_l
 #undef FLAG_v
@@ -2248,9 +2157,9 @@
 #undef FLAG_n
 #endif
 
-// openvt   ^<1c#<1>63sw
+// openvt   c#<1>63sw
 #undef OPTSTR_openvt
-#define OPTSTR_openvt "^<1c#<1>63sw"
+#define OPTSTR_openvt "c#<1>63sw"
 #ifdef CLEANUP_openvt
 #undef CLEANUP_openvt
 #undef FOR_openvt
@@ -2334,9 +2243,9 @@
 #undef FLAG_c
 #endif
 
-// pidof   so:x
+// pidof   <1so:x
 #undef OPTSTR_pidof
-#define OPTSTR_pidof "so:x"
+#define OPTSTR_pidof "<1so:x"
 #ifdef CLEANUP_pidof
 #undef CLEANUP_pidof
 #undef FOR_pidof
@@ -2395,15 +2304,14 @@
 #undef FLAG_V
 #endif
 
-// pmap   <1pqx
+// pmap   <1xq
 #undef OPTSTR_pmap
-#define OPTSTR_pmap "<1pqx"
+#define OPTSTR_pmap "<1xq"
 #ifdef CLEANUP_pmap
 #undef CLEANUP_pmap
 #undef FOR_pmap
-#undef FLAG_x
 #undef FLAG_q
-#undef FLAG_p
+#undef FLAG_x
 #endif
 
 // printenv   (null)0
@@ -2534,15 +2442,22 @@
 #undef FLAG_n
 #endif
 
-// reboot   d:fn
+// realpath <1 <1
+#undef OPTSTR_realpath
+#define OPTSTR_realpath "<1"
+#ifdef CLEANUP_realpath
+#undef CLEANUP_realpath
+#undef FOR_realpath
+#endif
+
+// reboot   fn
 #undef OPTSTR_reboot
-#define OPTSTR_reboot "d:fn"
+#define OPTSTR_reboot "fn"
 #ifdef CLEANUP_reboot
 #undef CLEANUP_reboot
 #undef FOR_reboot
 #undef FLAG_n
 #undef FLAG_f
-#undef FLAG_d
 #endif
 
 // renice   <1gpun#|
@@ -2755,6 +2670,17 @@
 #undef FLAG_noediting
 #endif
 
+// sha1sum bc(check)s(status)[!bc] bc(check)s(status)[!bc]
+#undef OPTSTR_sha1sum
+#define OPTSTR_sha1sum "bc(check)s(status)[!bc]"
+#ifdef CLEANUP_sha1sum
+#undef CLEANUP_sha1sum
+#undef FOR_sha1sum
+#undef FLAG_s
+#undef FLAG_c
+#undef FLAG_b
+#endif
+
 // sha3sum   bSa#<128>512=224
 #undef OPTSTR_sha3sum
 #define OPTSTR_sha3sum "bSa#<128>512=224"
@@ -2879,13 +2805,12 @@
 #undef FOR_source
 #endif
 
-// split   >2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln]
+// split   >2a#<1=2>9b#<1l#<1[!bl]
 #undef OPTSTR_split
-#define OPTSTR_split ">2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln]"
+#define OPTSTR_split ">2a#<1=2>9b#<1l#<1[!bl]"
 #ifdef CLEANUP_split
 #undef CLEANUP_split
 #undef FOR_split
-#undef FLAG_n
 #undef FLAG_l
 #undef FLAG_b
 #undef FLAG_a
@@ -2903,17 +2828,6 @@
 #undef FLAG_c
 #endif
 
-// strace   ^p#s#v
-#undef OPTSTR_strace
-#define OPTSTR_strace "^p#s#v"
-#ifdef CLEANUP_strace
-#undef CLEANUP_strace
-#undef FOR_strace
-#undef FLAG_v
-#undef FLAG_s
-#undef FLAG_p
-#endif
-
 // strings   t:an#=4<1fo
 #undef OPTSTR_strings
 #define OPTSTR_strings "t:an#=4<1fo"
@@ -3044,22 +2958,20 @@
 #undef FOR_tac
 #endif
 
-// tail ?fFs:c(bytes)-n(lines)-[-cn][-fF] ?fFs:c(bytes)-n(lines)-[-cn][-fF]
+// tail ?fc-n-[-cn] ?fc-n-[-cn]
 #undef OPTSTR_tail
-#define OPTSTR_tail "?fFs:c(bytes)-n(lines)-[-cn][-fF]"
+#define OPTSTR_tail "?fc-n-[-cn]"
 #ifdef CLEANUP_tail
 #undef CLEANUP_tail
 #undef FOR_tail
 #undef FLAG_n
 #undef FLAG_c
-#undef FLAG_s
-#undef FLAG_F
 #undef FLAG_f
 #endif
 
-// tar &(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa] &(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]
+// tar &(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa] &(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]
 #undef OPTSTR_tar
-#define OPTSTR_tar "&(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]"
+#define OPTSTR_tar "&(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]"
 #ifdef CLEANUP_tar
 #undef CLEANUP_tar
 #undef FOR_tar
@@ -3096,8 +3008,6 @@
 #undef FLAG_no_recursion
 #undef FLAG_full_time
 #undef FLAG_restrict
-#undef FLAG_selinux
-#undef FLAG_strip_components
 #endif
 
 // taskset   <1^pa
@@ -3194,9 +3104,9 @@
 #undef FLAG_r
 #endif
 
-// time   <1^pv[-pv]
+// time   <1^pv
 #undef OPTSTR_time
-#define OPTSTR_time "<1^pv[-pv]"
+#define OPTSTR_time "<1^pv"
 #ifdef CLEANUP_time
 #undef CLEANUP_time
 #undef FOR_time
@@ -3217,9 +3127,9 @@
 #undef FLAG_foreground
 #endif
 
-// top   >0O*hHk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]
+// top   >0O*Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]
 #undef OPTSTR_top
-#define OPTSTR_top ">0O*hHk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]"
+#define OPTSTR_top ">0O*Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]"
 #ifdef CLEANUP_top
 #undef CLEANUP_top
 #undef FOR_top
@@ -3234,7 +3144,6 @@
 #undef FLAG_o
 #undef FLAG_k
 #undef FLAG_H
-#undef FLAG_h
 #undef FLAG_O
 #endif
 
@@ -3341,19 +3250,6 @@
 #undef FLAG_t
 #endif
 
-// uclampset   p#am#<-1>1024M#<-1>1024R
-#undef OPTSTR_uclampset
-#define OPTSTR_uclampset "p#am#<-1>1024M#<-1>1024R"
-#ifdef CLEANUP_uclampset
-#undef CLEANUP_uclampset
-#undef FOR_uclampset
-#undef FLAG_R
-#undef FLAG_M
-#undef FLAG_m
-#undef FLAG_a
-#undef FLAG_p
-#endif
-
 // ulimit   >1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]
 #undef OPTSTR_ulimit
 #define OPTSTR_ulimit ">1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]"
@@ -3400,9 +3296,9 @@
 #undef FLAG_c
 #endif
 
-// uname aomvrns aomvrns
+// uname oamvrns[+os] oamvrns[+os]
 #undef OPTSTR_uname
-#define OPTSTR_uname "aomvrns"
+#define OPTSTR_uname "oamvrns[+os]"
 #ifdef CLEANUP_uname
 #undef CLEANUP_uname
 #undef FOR_uname
@@ -3411,8 +3307,8 @@
 #undef FLAG_r
 #undef FLAG_v
 #undef FLAG_m
-#undef FLAG_o
 #undef FLAG_a
+#undef FLAG_o
 #endif
 
 // unicode   <1
@@ -3631,16 +3527,14 @@
 #undef FLAG_m
 #endif
 
-// wget   <1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):
+// wget   (no-check-certificate)O:
 #undef OPTSTR_wget
-#define OPTSTR_wget "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):"
+#define OPTSTR_wget "(no-check-certificate)O:"
 #ifdef CLEANUP_wget
 #undef CLEANUP_wget
 #undef FOR_wget
-#undef FLAG_p
 #undef FLAG_O
-#undef FLAG_d
-#undef FLAG_max_redirect
+#undef FLAG_no_check_certificate
 #endif
 
 // which <1a <1a
@@ -3678,9 +3572,9 @@
 #undef FLAG_E
 #endif
 
-// xxd >1c#<0>256l#o#g#<1=2iprs#[!rs] >1c#<0>256l#o#g#<1=2iprs#[!rs]
+// xxd >1c#l#o#g#<1=2iprs#[!rs] >1c#l#o#g#<1=2iprs#[!rs]
 #undef OPTSTR_xxd
-#define OPTSTR_xxd ">1c#<0>256l#o#g#<1=2iprs#[!rs]"
+#define OPTSTR_xxd ">1c#l#o#g#<1=2iprs#[!rs]"
 #ifdef CLEANUP_xxd
 #undef CLEANUP_xxd
 #undef FOR_xxd
@@ -3732,7 +3626,6 @@
 #endif
 
 #ifdef FOR_acpi
-#define CLEANUP_acpi
 #ifndef TT
 #define TT this.acpi
 #endif
@@ -3744,14 +3637,12 @@
 #endif
 
 #ifdef FOR_arch
-#define CLEANUP_arch
 #ifndef TT
 #define TT this.arch
 #endif
 #endif
 
 #ifdef FOR_arp
-#define CLEANUP_arp
 #ifndef TT
 #define TT this.arp
 #endif
@@ -3768,7 +3659,6 @@
 #endif
 
 #ifdef FOR_arping
-#define CLEANUP_arping
 #ifndef TT
 #define TT this.arping
 #endif
@@ -3785,14 +3675,12 @@
 #endif
 
 #ifdef FOR_ascii
-#define CLEANUP_ascii
 #ifndef TT
 #define TT this.ascii
 #endif
 #endif
 
 #ifdef FOR_base32
-#define CLEANUP_base32
 #ifndef TT
 #define TT this.base32
 #endif
@@ -3802,7 +3690,6 @@
 #endif
 
 #ifdef FOR_base64
-#define CLEANUP_base64
 #ifndef TT
 #define TT this.base64
 #endif
@@ -3812,7 +3699,6 @@
 #endif
 
 #ifdef FOR_basename
-#define CLEANUP_basename
 #ifndef TT
 #define TT this.basename
 #endif
@@ -3821,7 +3707,6 @@
 #endif
 
 #ifdef FOR_bc
-#define CLEANUP_bc
 #ifndef TT
 #define TT this.bc
 #endif
@@ -3833,7 +3718,6 @@
 #endif
 
 #ifdef FOR_blkdiscard
-#define CLEANUP_blkdiscard
 #ifndef TT
 #define TT this.blkdiscard
 #endif
@@ -3845,7 +3729,6 @@
 #endif
 
 #ifdef FOR_blkid
-#define CLEANUP_blkid
 #ifndef TT
 #define TT this.blkid
 #endif
@@ -3855,7 +3738,6 @@
 #endif
 
 #ifdef FOR_blockdev
-#define CLEANUP_blockdev
 #ifndef TT
 #define TT this.blockdev
 #endif
@@ -3875,21 +3757,18 @@
 #endif
 
 #ifdef FOR_bootchartd
-#define CLEANUP_bootchartd
 #ifndef TT
 #define TT this.bootchartd
 #endif
 #endif
 
 #ifdef FOR_brctl
-#define CLEANUP_brctl
 #ifndef TT
 #define TT this.brctl
 #endif
 #endif
 
 #ifdef FOR_bunzip2
-#define CLEANUP_bunzip2
 #ifndef TT
 #define TT this.bunzip2
 #endif
@@ -3901,14 +3780,12 @@
 #endif
 
 #ifdef FOR_bzcat
-#define CLEANUP_bzcat
 #ifndef TT
 #define TT this.bzcat
 #endif
 #endif
 
 #ifdef FOR_cal
-#define CLEANUP_cal
 #ifndef TT
 #define TT this.cal
 #endif
@@ -3916,7 +3793,6 @@
 #endif
 
 #ifdef FOR_cat
-#define CLEANUP_cat
 #ifndef TT
 #define TT this.cat
 #endif
@@ -3927,7 +3803,6 @@
 #endif
 
 #ifdef FOR_catv
-#define CLEANUP_catv
 #ifndef TT
 #define TT this.catv
 #endif
@@ -3937,7 +3812,6 @@
 #endif
 
 #ifdef FOR_cd
-#define CLEANUP_cd
 #ifndef TT
 #define TT this.cd
 #endif
@@ -3946,7 +3820,6 @@
 #endif
 
 #ifdef FOR_chattr
-#define CLEANUP_chattr
 #ifndef TT
 #define TT this.chattr
 #endif
@@ -3956,7 +3829,6 @@
 #endif
 
 #ifdef FOR_chcon
-#define CLEANUP_chcon
 #ifndef TT
 #define TT this.chcon
 #endif
@@ -3966,7 +3838,6 @@
 #endif
 
 #ifdef FOR_chgrp
-#define CLEANUP_chgrp
 #ifndef TT
 #define TT this.chgrp
 #endif
@@ -3980,7 +3851,6 @@
 #endif
 
 #ifdef FOR_chmod
-#define CLEANUP_chmod
 #ifndef TT
 #define TT this.chmod
 #endif
@@ -3990,14 +3860,12 @@
 #endif
 
 #ifdef FOR_chroot
-#define CLEANUP_chroot
 #ifndef TT
 #define TT this.chroot
 #endif
 #endif
 
 #ifdef FOR_chrt
-#define CLEANUP_chrt
 #ifndef TT
 #define TT this.chrt
 #endif
@@ -4012,7 +3880,6 @@
 #endif
 
 #ifdef FOR_chsh
-#define CLEANUP_chsh
 #ifndef TT
 #define TT this.chsh
 #endif
@@ -4020,14 +3887,12 @@
 #endif
 
 #ifdef FOR_chvt
-#define CLEANUP_chvt
 #ifndef TT
 #define TT this.chvt
 #endif
 #endif
 
 #ifdef FOR_cksum
-#define CLEANUP_cksum
 #ifndef TT
 #define TT this.cksum
 #endif
@@ -4039,24 +3904,20 @@
 #endif
 
 #ifdef FOR_clear
-#define CLEANUP_clear
 #ifndef TT
 #define TT this.clear
 #endif
 #endif
 
 #ifdef FOR_cmp
-#define CLEANUP_cmp
 #ifndef TT
 #define TT this.cmp
 #endif
-#define FLAG_n (1<<0)
-#define FLAG_s (1<<1)
-#define FLAG_l (1<<2)
+#define FLAG_s (1<<0)
+#define FLAG_l (1<<1)
 #endif
 
 #ifdef FOR_comm
-#define CLEANUP_comm
 #ifndef TT
 #define TT this.comm
 #endif
@@ -4066,14 +3927,12 @@
 #endif
 
 #ifdef FOR_count
-#define CLEANUP_count
 #ifndef TT
 #define TT this.count
 #endif
 #endif
 
 #ifdef FOR_cp
-#define CLEANUP_cp
 #ifndef TT
 #define TT this.cp
 #endif
@@ -4100,7 +3959,6 @@
 #endif
 
 #ifdef FOR_cpio
-#define CLEANUP_cpio
 #ifndef TT
 #define TT this.cpio
 #endif
@@ -4116,19 +3974,15 @@
 #define FLAG_m (1<<9)
 #define FLAG_no_preserve_owner (1<<10)
 #define FLAG_quiet (1<<11)
-#define FLAG_renumber_inodes (1<<12)
-#define FLAG_ignore_devno (1<<13)
 #endif
 
 #ifdef FOR_crc32
-#define CLEANUP_crc32
 #ifndef TT
 #define TT this.crc32
 #endif
 #endif
 
 #ifdef FOR_crond
-#define CLEANUP_crond
 #ifndef TT
 #define TT this.crond
 #endif
@@ -4142,7 +3996,6 @@
 #endif
 
 #ifdef FOR_crontab
-#define CLEANUP_crontab
 #ifndef TT
 #define TT this.crontab
 #endif
@@ -4154,7 +4007,6 @@
 #endif
 
 #ifdef FOR_cut
-#define CLEANUP_cut
 #ifndef TT
 #define TT this.cut
 #endif
@@ -4171,50 +4023,29 @@
 #endif
 
 #ifdef FOR_date
-#define CLEANUP_date
 #ifndef TT
 #define TT this.date
 #endif
 #define FLAG_u (1<<0)
-#define FLAG_s (1<<1)
-#define FLAG_r (1<<2)
-#define FLAG_I (1<<3)
-#define FLAG_D (1<<4)
-#define FLAG_d (1<<5)
+#define FLAG_r (1<<1)
+#define FLAG_I (1<<2)
+#define FLAG_D (1<<3)
+#define FLAG_d (1<<4)
 #endif
 
 #ifdef FOR_dd
-#define CLEANUP_dd
 #ifndef TT
 #define TT this.dd
 #endif
 #endif
 
 #ifdef FOR_deallocvt
-#define CLEANUP_deallocvt
 #ifndef TT
 #define TT this.deallocvt
 #endif
 #endif
 
-#ifdef FOR_declare
-#define CLEANUP_declare
-#ifndef TT
-#define TT this.declare
-#endif
-#define FLAG_r (FORCED_FLAG<<0)
-#define FLAG_x (FORCED_FLAG<<1)
-#define FLAG_n (FORCED_FLAG<<2)
-#define FLAG_u (FORCED_FLAG<<3)
-#define FLAG_l (FORCED_FLAG<<4)
-#define FLAG_i (FORCED_FLAG<<5)
-#define FLAG_a (FORCED_FLAG<<6)
-#define FLAG_A (FORCED_FLAG<<7)
-#define FLAG_p (FORCED_FLAG<<8)
-#endif
-
 #ifdef FOR_demo_many_options
-#define CLEANUP_demo_many_options
 #ifndef TT
 #define TT this.demo_many_options
 #endif
@@ -4273,7 +4104,6 @@
 #endif
 
 #ifdef FOR_demo_number
-#define CLEANUP_demo_number
 #ifndef TT
 #define TT this.demo_number
 #endif
@@ -4287,28 +4117,24 @@
 #endif
 
 #ifdef FOR_demo_scankey
-#define CLEANUP_demo_scankey
 #ifndef TT
 #define TT this.demo_scankey
 #endif
 #endif
 
 #ifdef FOR_demo_utf8towc
-#define CLEANUP_demo_utf8towc
 #ifndef TT
 #define TT this.demo_utf8towc
 #endif
 #endif
 
 #ifdef FOR_devmem
-#define CLEANUP_devmem
 #ifndef TT
 #define TT this.devmem
 #endif
 #endif
 
 #ifdef FOR_df
-#define CLEANUP_df
 #ifndef TT
 #define TT this.df
 #endif
@@ -4322,7 +4148,6 @@
 #endif
 
 #ifdef FOR_dhcp
-#define CLEANUP_dhcp
 #ifndef TT
 #define TT this.dhcp
 #endif
@@ -4352,7 +4177,6 @@
 #endif
 
 #ifdef FOR_dhcp6
-#define CLEANUP_dhcp6
 #ifndef TT
 #define TT this.dhcp6
 #endif
@@ -4373,7 +4197,6 @@
 #endif
 
 #ifdef FOR_dhcpd
-#define CLEANUP_dhcpd
 #ifndef TT
 #define TT this.dhcpd
 #endif
@@ -4386,7 +4209,6 @@
 #endif
 
 #ifdef FOR_diff
-#define CLEANUP_diff
 #ifndef TT
 #define TT this.diff
 #endif
@@ -4411,14 +4233,12 @@
 #endif
 
 #ifdef FOR_dirname
-#define CLEANUP_dirname
 #ifndef TT
 #define TT this.dirname
 #endif
 #endif
 
 #ifdef FOR_dmesg
-#define CLEANUP_dmesg
 #ifndef TT
 #define TT this.dmesg
 #endif
@@ -4434,21 +4254,18 @@
 #endif
 
 #ifdef FOR_dnsdomainname
-#define CLEANUP_dnsdomainname
 #ifndef TT
 #define TT this.dnsdomainname
 #endif
 #endif
 
 #ifdef FOR_dos2unix
-#define CLEANUP_dos2unix
 #ifndef TT
 #define TT this.dos2unix
 #endif
 #endif
 
 #ifdef FOR_du
-#define CLEANUP_du
 #ifndef TT
 #define TT this.du
 #endif
@@ -4468,7 +4285,6 @@
 #endif
 
 #ifdef FOR_dumpleases
-#define CLEANUP_dumpleases
 #ifndef TT
 #define TT this.dumpleases
 #endif
@@ -4478,7 +4294,6 @@
 #endif
 
 #ifdef FOR_echo
-#define CLEANUP_echo
 #ifndef TT
 #define TT this.echo
 #endif
@@ -4488,7 +4303,6 @@
 #endif
 
 #ifdef FOR_eject
-#define CLEANUP_eject
 #ifndef TT
 #define TT this.eject
 #endif
@@ -4498,7 +4312,6 @@
 #endif
 
 #ifdef FOR_env
-#define CLEANUP_env
 #ifndef TT
 #define TT this.env
 #endif
@@ -4508,14 +4321,12 @@
 #endif
 
 #ifdef FOR_eval
-#define CLEANUP_eval
 #ifndef TT
 #define TT this.eval
 #endif
 #endif
 
 #ifdef FOR_exec
-#define CLEANUP_exec
 #ifndef TT
 #define TT this.exec
 #endif
@@ -4525,14 +4336,12 @@
 #endif
 
 #ifdef FOR_exit
-#define CLEANUP_exit
 #ifndef TT
 #define TT this.exit
 #endif
 #endif
 
 #ifdef FOR_expand
-#define CLEANUP_expand
 #ifndef TT
 #define TT this.expand
 #endif
@@ -4540,7 +4349,6 @@
 #endif
 
 #ifdef FOR_export
-#define CLEANUP_export
 #ifndef TT
 #define TT this.export
 #endif
@@ -4549,21 +4357,18 @@
 #endif
 
 #ifdef FOR_expr
-#define CLEANUP_expr
 #ifndef TT
 #define TT this.expr
 #endif
 #endif
 
 #ifdef FOR_factor
-#define CLEANUP_factor
 #ifndef TT
 #define TT this.factor
 #endif
 #endif
 
 #ifdef FOR_fallocate
-#define CLEANUP_fallocate
 #ifndef TT
 #define TT this.fallocate
 #endif
@@ -4572,14 +4377,12 @@
 #endif
 
 #ifdef FOR_false
-#define CLEANUP_false
 #ifndef TT
 #define TT this.false
 #endif
 #endif
 
 #ifdef FOR_fdisk
-#define CLEANUP_fdisk
 #ifndef TT
 #define TT this.fdisk
 #endif
@@ -4592,7 +4395,6 @@
 #endif
 
 #ifdef FOR_file
-#define CLEANUP_file
 #ifndef TT
 #define TT this.file
 #endif
@@ -4603,7 +4405,6 @@
 #endif
 
 #ifdef FOR_find
-#define CLEANUP_find
 #ifndef TT
 #define TT this.find
 #endif
@@ -4612,7 +4413,6 @@
 #endif
 
 #ifdef FOR_flock
-#define CLEANUP_flock
 #ifndef TT
 #define TT this.flock
 #endif
@@ -4623,7 +4423,6 @@
 #endif
 
 #ifdef FOR_fmt
-#define CLEANUP_fmt
 #ifndef TT
 #define TT this.fmt
 #endif
@@ -4631,7 +4430,6 @@
 #endif
 
 #ifdef FOR_fold
-#define CLEANUP_fold
 #ifndef TT
 #define TT this.fold
 #endif
@@ -4642,7 +4440,6 @@
 #endif
 
 #ifdef FOR_free
-#define CLEANUP_free
 #ifndef TT
 #define TT this.free
 #endif
@@ -4650,18 +4447,17 @@
 #define FLAG_k (FORCED_FLAG<<1)
 #define FLAG_m (FORCED_FLAG<<2)
 #define FLAG_g (FORCED_FLAG<<3)
-#define FLAG_h (FORCED_FLAG<<4)
+#define FLAG_t (FORCED_FLAG<<4)
+#define FLAG_h (FORCED_FLAG<<5)
 #endif
 
 #ifdef FOR_freeramdisk
-#define CLEANUP_freeramdisk
 #ifndef TT
 #define TT this.freeramdisk
 #endif
 #endif
 
 #ifdef FOR_fsck
-#define CLEANUP_fsck
 #ifndef TT
 #define TT this.fsck
 #endif
@@ -4677,7 +4473,6 @@
 #endif
 
 #ifdef FOR_fsfreeze
-#define CLEANUP_fsfreeze
 #ifndef TT
 #define TT this.fsfreeze
 #endif
@@ -4686,14 +4481,12 @@
 #endif
 
 #ifdef FOR_fstype
-#define CLEANUP_fstype
 #ifndef TT
 #define TT this.fstype
 #endif
 #endif
 
 #ifdef FOR_fsync
-#define CLEANUP_fsync
 #ifndef TT
 #define TT this.fsync
 #endif
@@ -4701,7 +4494,6 @@
 #endif
 
 #ifdef FOR_ftpget
-#define CLEANUP_ftpget
 #ifndef TT
 #define TT this.ftpget
 #endif
@@ -4721,7 +4513,6 @@
 #endif
 
 #ifdef FOR_getconf
-#define CLEANUP_getconf
 #ifndef TT
 #define TT this.getconf
 #endif
@@ -4730,14 +4521,12 @@
 #endif
 
 #ifdef FOR_getenforce
-#define CLEANUP_getenforce
 #ifndef TT
 #define TT this.getenforce
 #endif
 #endif
 
 #ifdef FOR_getfattr
-#define CLEANUP_getfattr
 #ifndef TT
 #define TT this.getfattr
 #endif
@@ -4748,7 +4537,6 @@
 #endif
 
 #ifdef FOR_getopt
-#define CLEANUP_getopt
 #ifndef TT
 #define TT this.getopt
 #endif
@@ -4761,7 +4549,6 @@
 #endif
 
 #ifdef FOR_getty
-#define CLEANUP_getty
 #ifndef TT
 #define TT this.getty
 #endif
@@ -4778,45 +4565,7 @@
 #define FLAG_t (FORCED_FLAG<<10)
 #endif
 
-#ifdef FOR_gpiodetect
-#define CLEANUP_gpiodetect
-#ifndef TT
-#define TT this.gpiodetect
-#endif
-#endif
-
-#ifdef FOR_gpiofind
-#define CLEANUP_gpiofind
-#ifndef TT
-#define TT this.gpiofind
-#endif
-#endif
-
-#ifdef FOR_gpioget
-#define CLEANUP_gpioget
-#ifndef TT
-#define TT this.gpioget
-#endif
-#define FLAG_l (FORCED_FLAG<<0)
-#endif
-
-#ifdef FOR_gpioinfo
-#define CLEANUP_gpioinfo
-#ifndef TT
-#define TT this.gpioinfo
-#endif
-#endif
-
-#ifdef FOR_gpioset
-#define CLEANUP_gpioset
-#ifndef TT
-#define TT this.gpioset
-#endif
-#define FLAG_l (FORCED_FLAG<<0)
-#endif
-
 #ifdef FOR_grep
-#define CLEANUP_grep
 #ifndef TT
 #define TT this.grep
 #endif
@@ -4829,34 +4578,32 @@
 #define FLAG_e (1<<6)
 #define FLAG_q (1<<7)
 #define FLAG_l (1<<8)
-#define FLAG_L (1<<9)
-#define FLAG_c (1<<10)
-#define FLAG_w (1<<11)
-#define FLAG_v (1<<12)
-#define FLAG_s (1<<13)
-#define FLAG_R (1<<14)
-#define FLAG_r (1<<15)
-#define FLAG_o (1<<16)
-#define FLAG_n (1<<17)
-#define FLAG_i (1<<18)
-#define FLAG_h (1<<19)
-#define FLAG_b (1<<20)
-#define FLAG_a (1<<21)
-#define FLAG_I (1<<22)
-#define FLAG_H (1<<23)
-#define FLAG_F (1<<24)
-#define FLAG_E (1<<25)
-#define FLAG_z (1<<26)
-#define FLAG_Z (1<<27)
-#define FLAG_M (1<<28)
-#define FLAG_S (1<<29)
-#define FLAG_exclude_dir (1<<30)
-#define FLAG_color (1LL<<31)
-#define FLAG_line_buffered (1LL<<32)
+#define FLAG_c (1<<9)
+#define FLAG_w (1<<10)
+#define FLAG_v (1<<11)
+#define FLAG_s (1<<12)
+#define FLAG_R (1<<13)
+#define FLAG_r (1<<14)
+#define FLAG_o (1<<15)
+#define FLAG_n (1<<16)
+#define FLAG_i (1<<17)
+#define FLAG_h (1<<18)
+#define FLAG_b (1<<19)
+#define FLAG_a (1<<20)
+#define FLAG_I (1<<21)
+#define FLAG_H (1<<22)
+#define FLAG_F (1<<23)
+#define FLAG_E (1<<24)
+#define FLAG_z (1<<25)
+#define FLAG_Z (1<<26)
+#define FLAG_M (1<<27)
+#define FLAG_S (1<<28)
+#define FLAG_exclude_dir (1<<29)
+#define FLAG_color (1<<30)
+#define FLAG_line_buffered (1LL<<31)
 #endif
 
 #ifdef FOR_groupadd
-#define CLEANUP_groupadd
 #ifndef TT
 #define TT this.groupadd
 #endif
@@ -4865,21 +4612,18 @@
 #endif
 
 #ifdef FOR_groupdel
-#define CLEANUP_groupdel
 #ifndef TT
 #define TT this.groupdel
 #endif
 #endif
 
 #ifdef FOR_groups
-#define CLEANUP_groups
 #ifndef TT
 #define TT this.groups
 #endif
 #endif
 
 #ifdef FOR_gunzip
-#define CLEANUP_gunzip
 #ifndef TT
 #define TT this.gunzip
 #endif
@@ -4899,7 +4643,6 @@
 #endif
 
 #ifdef FOR_gzip
-#define CLEANUP_gzip
 #ifndef TT
 #define TT this.gzip
 #endif
@@ -4920,7 +4663,6 @@
 #endif
 
 #ifdef FOR_head
-#define CLEANUP_head
 #ifndef TT
 #define TT this.head
 #endif
@@ -4931,14 +4673,12 @@
 #endif
 
 #ifdef FOR_hello
-#define CLEANUP_hello
 #ifndef TT
 #define TT this.hello
 #endif
 #endif
 
 #ifdef FOR_help
-#define CLEANUP_help
 #ifndef TT
 #define TT this.help
 #endif
@@ -4947,24 +4687,7 @@
 #define FLAG_a (FORCED_FLAG<<2)
 #endif
 
-#ifdef FOR_hexdump
-#define CLEANUP_hexdump
-#ifndef TT
-#define TT this.hexdump
-#endif
-#define FLAG_x (FORCED_FLAG<<0)
-#define FLAG_v (FORCED_FLAG<<1)
-#define FLAG_s (FORCED_FLAG<<2)
-#define FLAG_o (FORCED_FLAG<<3)
-#define FLAG_n (FORCED_FLAG<<4)
-#define FLAG_d (FORCED_FLAG<<5)
-#define FLAG_C (FORCED_FLAG<<6)
-#define FLAG_c (FORCED_FLAG<<7)
-#define FLAG_b (FORCED_FLAG<<8)
-#endif
-
 #ifdef FOR_hexedit
-#define CLEANUP_hexedit
 #ifndef TT
 #define TT this.hexedit
 #endif
@@ -4972,7 +4695,6 @@
 #endif
 
 #ifdef FOR_host
-#define CLEANUP_host
 #ifndef TT
 #define TT this.host
 #endif
@@ -4982,14 +4704,12 @@
 #endif
 
 #ifdef FOR_hostid
-#define CLEANUP_hostid
 #ifndef TT
 #define TT this.hostid
 #endif
 #endif
 
 #ifdef FOR_hostname
-#define CLEANUP_hostname
 #ifndef TT
 #define TT this.hostname
 #endif
@@ -5001,7 +4721,6 @@
 #endif
 
 #ifdef FOR_hwclock
-#define CLEANUP_hwclock
 #ifndef TT
 #define TT this.hwclock
 #endif
@@ -5016,20 +4735,16 @@
 #endif
 
 #ifdef FOR_i2cdetect
-#define CLEANUP_i2cdetect
 #ifndef TT
 #define TT this.i2cdetect
 #endif
 #define FLAG_y (FORCED_FLAG<<0)
-#define FLAG_r (FORCED_FLAG<<1)
-#define FLAG_q (FORCED_FLAG<<2)
-#define FLAG_l (FORCED_FLAG<<3)
-#define FLAG_F (FORCED_FLAG<<4)
-#define FLAG_a (FORCED_FLAG<<5)
+#define FLAG_l (FORCED_FLAG<<1)
+#define FLAG_F (FORCED_FLAG<<2)
+#define FLAG_a (FORCED_FLAG<<3)
 #endif
 
 #ifdef FOR_i2cdump
-#define CLEANUP_i2cdump
 #ifndef TT
 #define TT this.i2cdump
 #endif
@@ -5038,7 +4753,6 @@
 #endif
 
 #ifdef FOR_i2cget
-#define CLEANUP_i2cget
 #ifndef TT
 #define TT this.i2cget
 #endif
@@ -5047,7 +4761,6 @@
 #endif
 
 #ifdef FOR_i2cset
-#define CLEANUP_i2cset
 #ifndef TT
 #define TT this.i2cset
 #endif
@@ -5056,7 +4769,6 @@
 #endif
 
 #ifdef FOR_iconv
-#define CLEANUP_iconv
 #ifndef TT
 #define TT this.iconv
 #endif
@@ -5067,7 +4779,6 @@
 #endif
 
 #ifdef FOR_id
-#define CLEANUP_id
 #ifndef TT
 #define TT this.id
 #endif
@@ -5080,7 +4791,6 @@
 #endif
 
 #ifdef FOR_ifconfig
-#define CLEANUP_ifconfig
 #ifndef TT
 #define TT this.ifconfig
 #endif
@@ -5089,45 +4799,40 @@
 #endif
 
 #ifdef FOR_init
-#define CLEANUP_init
 #ifndef TT
 #define TT this.init
 #endif
 #endif
 
 #ifdef FOR_inotifyd
-#define CLEANUP_inotifyd
 #ifndef TT
 #define TT this.inotifyd
 #endif
 #endif
 
 #ifdef FOR_insmod
-#define CLEANUP_insmod
 #ifndef TT
 #define TT this.insmod
 #endif
 #endif
 
 #ifdef FOR_install
-#define CLEANUP_install
 #ifndef TT
 #define TT this.install
 #endif
-#define FLAG_g (1<<0)
-#define FLAG_o (1<<1)
-#define FLAG_m (1<<2)
-#define FLAG_t (1<<3)
-#define FLAG_v (1<<4)
-#define FLAG_s (1<<5)
-#define FLAG_p (1<<6)
-#define FLAG_D (1<<7)
-#define FLAG_d (1<<8)
-#define FLAG_c (1<<9)
+#define FLAG_g (FORCED_FLAG<<0)
+#define FLAG_o (FORCED_FLAG<<1)
+#define FLAG_m (FORCED_FLAG<<2)
+#define FLAG_t (FORCED_FLAG<<3)
+#define FLAG_v (FORCED_FLAG<<4)
+#define FLAG_s (FORCED_FLAG<<5)
+#define FLAG_p (FORCED_FLAG<<6)
+#define FLAG_D (FORCED_FLAG<<7)
+#define FLAG_d (FORCED_FLAG<<8)
+#define FLAG_c (FORCED_FLAG<<9)
 #endif
 
 #ifdef FOR_ionice
-#define CLEANUP_ionice
 #ifndef TT
 #define TT this.ionice
 #endif
@@ -5138,14 +4843,12 @@
 #endif
 
 #ifdef FOR_iorenice
-#define CLEANUP_iorenice
 #ifndef TT
 #define TT this.iorenice
 #endif
 #endif
 
 #ifdef FOR_iotop
-#define CLEANUP_iotop
 #ifndef TT
 #define TT this.iotop
 #endif
@@ -5167,14 +4870,12 @@
 #endif
 
 #ifdef FOR_ip
-#define CLEANUP_ip
 #ifndef TT
 #define TT this.ip
 #endif
 #endif
 
 #ifdef FOR_ipcrm
-#define CLEANUP_ipcrm
 #ifndef TT
 #define TT this.ipcrm
 #endif
@@ -5187,7 +4888,6 @@
 #endif
 
 #ifdef FOR_ipcs
-#define CLEANUP_ipcs
 #ifndef TT
 #define TT this.ipcs
 #endif
@@ -5204,7 +4904,6 @@
 #endif
 
 #ifdef FOR_jobs
-#define CLEANUP_jobs
 #ifndef TT
 #define TT this.jobs
 #endif
@@ -5216,7 +4915,6 @@
 #endif
 
 #ifdef FOR_kill
-#define CLEANUP_kill
 #ifndef TT
 #define TT this.kill
 #endif
@@ -5225,7 +4923,6 @@
 #endif
 
 #ifdef FOR_killall
-#define CLEANUP_killall
 #ifndef TT
 #define TT this.killall
 #endif
@@ -5238,7 +4935,6 @@
 #endif
 
 #ifdef FOR_killall5
-#define CLEANUP_killall5
 #ifndef TT
 #define TT this.killall5
 #endif
@@ -5248,7 +4944,6 @@
 #endif
 
 #ifdef FOR_klogd
-#define CLEANUP_klogd
 #ifndef TT
 #define TT this.klogd
 #endif
@@ -5257,7 +4952,6 @@
 #endif
 
 #ifdef FOR_last
-#define CLEANUP_last
 #ifndef TT
 #define TT this.last
 #endif
@@ -5266,21 +4960,12 @@
 #endif
 
 #ifdef FOR_link
-#define CLEANUP_link
 #ifndef TT
 #define TT this.link
 #endif
 #endif
 
-#ifdef FOR_linux32
-#define CLEANUP_linux32
-#ifndef TT
-#define TT this.linux32
-#endif
-#endif
-
 #ifdef FOR_ln
-#define CLEANUP_ln
 #ifndef TT
 #define TT this.ln
 #endif
@@ -5294,14 +4979,12 @@
 #endif
 
 #ifdef FOR_load_policy
-#define CLEANUP_load_policy
 #ifndef TT
 #define TT this.load_policy
 #endif
 #endif
 
 #ifdef FOR_log
-#define CLEANUP_log
 #ifndef TT
 #define TT this.log
 #endif
@@ -5310,7 +4993,6 @@
 #endif
 
 #ifdef FOR_logger
-#define CLEANUP_logger
 #ifndef TT
 #define TT this.logger
 #endif
@@ -5320,7 +5002,6 @@
 #endif
 
 #ifdef FOR_login
-#define CLEANUP_login
 #ifndef TT
 #define TT this.login
 #endif
@@ -5330,21 +5011,18 @@
 #endif
 
 #ifdef FOR_logname
-#define CLEANUP_logname
 #ifndef TT
 #define TT this.logname
 #endif
 #endif
 
-#ifdef FOR_logpath
-#define CLEANUP_logpath
+#ifdef FOR_logwrapper
 #ifndef TT
-#define TT this.logpath
+#define TT this.logwrapper
 #endif
 #endif
 
 #ifdef FOR_losetup
-#define CLEANUP_losetup
 #ifndef TT
 #define TT this.losetup
 #endif
@@ -5361,7 +5039,6 @@
 #endif
 
 #ifdef FOR_ls
-#define CLEANUP_ls
 #ifndef TT
 #define TT this.ls
 #endif
@@ -5401,7 +5078,6 @@
 #endif
 
 #ifdef FOR_lsattr
-#define CLEANUP_lsattr
 #ifndef TT
 #define TT this.lsattr
 #endif
@@ -5414,14 +5090,12 @@
 #endif
 
 #ifdef FOR_lsmod
-#define CLEANUP_lsmod
 #ifndef TT
 #define TT this.lsmod
 #endif
 #endif
 
 #ifdef FOR_lsof
-#define CLEANUP_lsof
 #ifndef TT
 #define TT this.lsof
 #endif
@@ -5431,7 +5105,6 @@
 #endif
 
 #ifdef FOR_lspci
-#define CLEANUP_lspci
 #ifndef TT
 #define TT this.lspci
 #endif
@@ -5443,15 +5116,12 @@
 #endif
 
 #ifdef FOR_lsusb
-#define CLEANUP_lsusb
 #ifndef TT
 #define TT this.lsusb
 #endif
-#define FLAG_i (FORCED_FLAG<<0)
 #endif
 
 #ifdef FOR_makedevs
-#define CLEANUP_makedevs
 #ifndef TT
 #define TT this.makedevs
 #endif
@@ -5459,7 +5129,6 @@
 #endif
 
 #ifdef FOR_man
-#define CLEANUP_man
 #ifndef TT
 #define TT this.man
 #endif
@@ -5468,7 +5137,6 @@
 #endif
 
 #ifdef FOR_mcookie
-#define CLEANUP_mcookie
 #ifndef TT
 #define TT this.mcookie
 #endif
@@ -5477,7 +5145,6 @@
 #endif
 
 #ifdef FOR_md5sum
-#define CLEANUP_md5sum
 #ifndef TT
 #define TT this.md5sum
 #endif
@@ -5487,7 +5154,6 @@
 #endif
 
 #ifdef FOR_mdev
-#define CLEANUP_mdev
 #ifndef TT
 #define TT this.mdev
 #endif
@@ -5495,7 +5161,6 @@
 #endif
 
 #ifdef FOR_microcom
-#define CLEANUP_microcom
 #ifndef TT
 #define TT this.microcom
 #endif
@@ -5504,7 +5169,6 @@
 #endif
 
 #ifdef FOR_mix
-#define CLEANUP_mix
 #ifndef TT
 #define TT this.mix
 #endif
@@ -5515,7 +5179,6 @@
 #endif
 
 #ifdef FOR_mkdir
-#define CLEANUP_mkdir
 #ifndef TT
 #define TT this.mkdir
 #endif
@@ -5526,7 +5189,6 @@
 #endif
 
 #ifdef FOR_mke2fs
-#define CLEANUP_mke2fs
 #ifndef TT
 #define TT this.mke2fs
 #endif
@@ -5541,7 +5203,6 @@
 #endif
 
 #ifdef FOR_mkfifo
-#define CLEANUP_mkfifo
 #ifndef TT
 #define TT this.mkfifo
 #endif
@@ -5550,7 +5211,6 @@
 #endif
 
 #ifdef FOR_mknod
-#define CLEANUP_mknod
 #ifndef TT
 #define TT this.mknod
 #endif
@@ -5559,7 +5219,6 @@
 #endif
 
 #ifdef FOR_mkpasswd
-#define CLEANUP_mkpasswd
 #ifndef TT
 #define TT this.mkpasswd
 #endif
@@ -5569,7 +5228,6 @@
 #endif
 
 #ifdef FOR_mkswap
-#define CLEANUP_mkswap
 #ifndef TT
 #define TT this.mkswap
 #endif
@@ -5577,7 +5235,6 @@
 #endif
 
 #ifdef FOR_mktemp
-#define CLEANUP_mktemp
 #ifndef TT
 #define TT this.mktemp
 #endif
@@ -5590,7 +5247,6 @@
 #endif
 
 #ifdef FOR_modinfo
-#define CLEANUP_modinfo
 #ifndef TT
 #define TT this.modinfo
 #endif
@@ -5601,7 +5257,6 @@
 #endif
 
 #ifdef FOR_modprobe
-#define CLEANUP_modprobe
 #ifndef TT
 #define TT this.modprobe
 #endif
@@ -5617,14 +5272,12 @@
 #endif
 
 #ifdef FOR_more
-#define CLEANUP_more
 #ifndef TT
 #define TT this.more
 #endif
 #endif
 
 #ifdef FOR_mount
-#define CLEANUP_mount
 #ifndef TT
 #define TT this.mount
 #endif
@@ -5640,7 +5293,6 @@
 #endif
 
 #ifdef FOR_mountpoint
-#define CLEANUP_mountpoint
 #ifndef TT
 #define TT this.mountpoint
 #endif
@@ -5650,7 +5302,6 @@
 #endif
 
 #ifdef FOR_mv
-#define CLEANUP_mv
 #ifndef TT
 #define TT this.mv
 #endif
@@ -5664,7 +5315,6 @@
 #endif
 
 #ifdef FOR_nbd_client
-#define CLEANUP_nbd_client
 #ifndef TT
 #define TT this.nbd_client
 #endif
@@ -5673,7 +5323,6 @@
 #endif
 
 #ifdef FOR_netcat
-#define CLEANUP_netcat
 #ifndef TT
 #define TT this.netcat
 #endif
@@ -5694,7 +5343,6 @@
 #endif
 
 #ifdef FOR_netstat
-#define CLEANUP_netstat
 #ifndef TT
 #define TT this.netstat
 #endif
@@ -5712,7 +5360,6 @@
 #endif
 
 #ifdef FOR_nice
-#define CLEANUP_nice
 #ifndef TT
 #define TT this.nice
 #endif
@@ -5720,28 +5367,25 @@
 #endif
 
 #ifdef FOR_nl
-#define CLEANUP_nl
 #ifndef TT
 #define TT this.nl
 #endif
-#define FLAG_E (1<<0)
-#define FLAG_s (1<<1)
-#define FLAG_n (1<<2)
-#define FLAG_b (1<<3)
+#define FLAG_s (1<<0)
+#define FLAG_n (1<<1)
+#define FLAG_b (1<<2)
+#define FLAG_E (1<<3)
 #define FLAG_w (1<<4)
 #define FLAG_l (1<<5)
 #define FLAG_v (1<<6)
 #endif
 
 #ifdef FOR_nohup
-#define CLEANUP_nohup
 #ifndef TT
 #define TT this.nohup
 #endif
 #endif
 
 #ifdef FOR_nproc
-#define CLEANUP_nproc
 #ifndef TT
 #define TT this.nproc
 #endif
@@ -5749,7 +5393,6 @@
 #endif
 
 #ifdef FOR_nsenter
-#define CLEANUP_nsenter
 #ifndef TT
 #define TT this.nsenter
 #endif
@@ -5764,7 +5407,6 @@
 #endif
 
 #ifdef FOR_od
-#define CLEANUP_od
 #ifndef TT
 #define TT this.od
 #endif
@@ -5783,7 +5425,6 @@
 #endif
 
 #ifdef FOR_oneit
-#define CLEANUP_oneit
 #ifndef TT
 #define TT this.oneit
 #endif
@@ -5794,7 +5435,6 @@
 #endif
 
 #ifdef FOR_openvt
-#define CLEANUP_openvt
 #ifndef TT
 #define TT this.openvt
 #endif
@@ -5804,14 +5444,12 @@
 #endif
 
 #ifdef FOR_partprobe
-#define CLEANUP_partprobe
 #ifndef TT
 #define TT this.partprobe
 #endif
 #endif
 
 #ifdef FOR_passwd
-#define CLEANUP_passwd
 #ifndef TT
 #define TT this.passwd
 #endif
@@ -5822,7 +5460,6 @@
 #endif
 
 #ifdef FOR_paste
-#define CLEANUP_paste
 #ifndef TT
 #define TT this.paste
 #endif
@@ -5831,7 +5468,6 @@
 #endif
 
 #ifdef FOR_patch
-#define CLEANUP_patch
 #ifndef TT
 #define TT this.patch
 #endif
@@ -5851,7 +5487,6 @@
 #endif
 
 #ifdef FOR_pgrep
-#define CLEANUP_pgrep
 #ifndef TT
 #define TT this.pgrep
 #endif
@@ -5874,7 +5509,6 @@
 #endif
 
 #ifdef FOR_pidof
-#define CLEANUP_pidof
 #ifndef TT
 #define TT this.pidof
 #endif
@@ -5884,7 +5518,6 @@
 #endif
 
 #ifdef FOR_ping
-#define CLEANUP_ping
 #ifndef TT
 #define TT this.ping
 #endif
@@ -5903,14 +5536,12 @@
 #endif
 
 #ifdef FOR_pivot_root
-#define CLEANUP_pivot_root
 #ifndef TT
 #define TT this.pivot_root
 #endif
 #endif
 
 #ifdef FOR_pkill
-#define CLEANUP_pkill
 #ifndef TT
 #define TT this.pkill
 #endif
@@ -5931,17 +5562,14 @@
 #endif
 
 #ifdef FOR_pmap
-#define CLEANUP_pmap
 #ifndef TT
 #define TT this.pmap
 #endif
-#define FLAG_x (FORCED_FLAG<<0)
-#define FLAG_q (FORCED_FLAG<<1)
-#define FLAG_p (FORCED_FLAG<<2)
+#define FLAG_q (FORCED_FLAG<<0)
+#define FLAG_x (FORCED_FLAG<<1)
 #endif
 
 #ifdef FOR_printenv
-#define CLEANUP_printenv
 #ifndef TT
 #define TT this.printenv
 #endif
@@ -5950,14 +5578,12 @@
 #endif
 
 #ifdef FOR_printf
-#define CLEANUP_printf
 #ifndef TT
 #define TT this.printf
 #endif
 #endif
 
 #ifdef FOR_ps
-#define CLEANUP_ps
 #ifndef TT
 #define TT this.ps
 #endif
@@ -5986,7 +5612,6 @@
 #endif
 
 #ifdef FOR_pwd
-#define CLEANUP_pwd
 #ifndef TT
 #define TT this.pwd
 #endif
@@ -5995,7 +5620,6 @@
 #endif
 
 #ifdef FOR_pwdx
-#define CLEANUP_pwdx
 #ifndef TT
 #define TT this.pwdx
 #endif
@@ -6003,7 +5627,6 @@
 #endif
 
 #ifdef FOR_pwgen
-#define CLEANUP_pwgen
 #ifndef TT
 #define TT this.pwgen
 #endif
@@ -6022,14 +5645,12 @@
 #endif
 
 #ifdef FOR_readahead
-#define CLEANUP_readahead
 #ifndef TT
 #define TT this.readahead
 #endif
 #endif
 
 #ifdef FOR_readelf
-#define CLEANUP_readelf
 #ifndef TT
 #define TT this.readelf
 #endif
@@ -6048,7 +5669,6 @@
 #endif
 
 #ifdef FOR_readlink
-#define CLEANUP_readlink
 #ifndef TT
 #define TT this.readlink
 #endif
@@ -6059,18 +5679,21 @@
 #define FLAG_n (1<<4)
 #endif
 
+#ifdef FOR_realpath
+#ifndef TT
+#define TT this.realpath
+#endif
+#endif
+
 #ifdef FOR_reboot
-#define CLEANUP_reboot
 #ifndef TT
 #define TT this.reboot
 #endif
 #define FLAG_n (FORCED_FLAG<<0)
 #define FLAG_f (FORCED_FLAG<<1)
-#define FLAG_d (FORCED_FLAG<<2)
 #endif
 
 #ifdef FOR_renice
-#define CLEANUP_renice
 #ifndef TT
 #define TT this.renice
 #endif
@@ -6081,14 +5704,12 @@
 #endif
 
 #ifdef FOR_reset
-#define CLEANUP_reset
 #ifndef TT
 #define TT this.reset
 #endif
 #endif
 
 #ifdef FOR_restorecon
-#define CLEANUP_restorecon
 #ifndef TT
 #define TT this.restorecon
 #endif
@@ -6101,21 +5722,18 @@
 #endif
 
 #ifdef FOR_rev
-#define CLEANUP_rev
 #ifndef TT
 #define TT this.rev
 #endif
 #endif
 
 #ifdef FOR_rfkill
-#define CLEANUP_rfkill
 #ifndef TT
 #define TT this.rfkill
 #endif
 #endif
 
 #ifdef FOR_rm
-#define CLEANUP_rm
 #ifndef TT
 #define TT this.rm
 #endif
@@ -6127,7 +5745,6 @@
 #endif
 
 #ifdef FOR_rmdir
-#define CLEANUP_rmdir
 #ifndef TT
 #define TT this.rmdir
 #endif
@@ -6136,7 +5753,6 @@
 #endif
 
 #ifdef FOR_rmmod
-#define CLEANUP_rmmod
 #ifndef TT
 #define TT this.rmmod
 #endif
@@ -6145,7 +5761,6 @@
 #endif
 
 #ifdef FOR_route
-#define CLEANUP_route
 #ifndef TT
 #define TT this.route
 #endif
@@ -6155,7 +5770,6 @@
 #endif
 
 #ifdef FOR_rtcwake
-#define CLEANUP_rtcwake
 #ifndef TT
 #define TT this.rtcwake
 #endif
@@ -6172,14 +5786,12 @@
 #endif
 
 #ifdef FOR_runcon
-#define CLEANUP_runcon
 #ifndef TT
 #define TT this.runcon
 #endif
 #endif
 
 #ifdef FOR_sed
-#define CLEANUP_sed
 #ifndef TT
 #define TT this.sed
 #endif
@@ -6196,14 +5808,12 @@
 #endif
 
 #ifdef FOR_sendevent
-#define CLEANUP_sendevent
 #ifndef TT
 #define TT this.sendevent
 #endif
 #endif
 
 #ifdef FOR_seq
-#define CLEANUP_seq
 #ifndef TT
 #define TT this.seq
 #endif
@@ -6213,21 +5823,18 @@
 #endif
 
 #ifdef FOR_set
-#define CLEANUP_set
 #ifndef TT
 #define TT this.set
 #endif
 #endif
 
 #ifdef FOR_setenforce
-#define CLEANUP_setenforce
 #ifndef TT
 #define TT this.setenforce
 #endif
 #endif
 
 #ifdef FOR_setfattr
-#define CLEANUP_setfattr
 #ifndef TT
 #define TT this.setfattr
 #endif
@@ -6238,7 +5845,6 @@
 #endif
 
 #ifdef FOR_setsid
-#define CLEANUP_setsid
 #ifndef TT
 #define TT this.setsid
 #endif
@@ -6248,7 +5854,6 @@
 #endif
 
 #ifdef FOR_sh
-#define CLEANUP_sh
 #ifndef TT
 #define TT this.sh
 #endif
@@ -6260,8 +5865,16 @@
 #define FLAG_noediting (FORCED_FLAG<<5)
 #endif
 
+#ifdef FOR_sha1sum
+#ifndef TT
+#define TT this.sha1sum
+#endif
+#define FLAG_s (1<<0)
+#define FLAG_c (1<<1)
+#define FLAG_b (1<<2)
+#endif
+
 #ifdef FOR_sha3sum
-#define CLEANUP_sha3sum
 #ifndef TT
 #define TT this.sha3sum
 #endif
@@ -6271,14 +5884,12 @@
 #endif
 
 #ifdef FOR_shift
-#define CLEANUP_shift
 #ifndef TT
 #define TT this.shift
 #endif
 #endif
 
 #ifdef FOR_shred
-#define CLEANUP_shred
 #ifndef TT
 #define TT this.shred
 #endif
@@ -6292,7 +5903,6 @@
 #endif
 
 #ifdef FOR_skeleton
-#define CLEANUP_skeleton
 #ifndef TT
 #define TT this.skeleton
 #endif
@@ -6307,7 +5917,6 @@
 #endif
 
 #ifdef FOR_skeleton_alias
-#define CLEANUP_skeleton_alias
 #ifndef TT
 #define TT this.skeleton_alias
 #endif
@@ -6317,14 +5926,12 @@
 #endif
 
 #ifdef FOR_sleep
-#define CLEANUP_sleep
 #ifndef TT
 #define TT this.sleep
 #endif
 #endif
 
 #ifdef FOR_sntp
-#define CLEANUP_sntp
 #ifndef TT
 #define TT this.sntp
 #endif
@@ -6342,7 +5949,6 @@
 #endif
 
 #ifdef FOR_sort
-#define CLEANUP_sort
 #ifndef TT
 #define TT this.sort
 #endif
@@ -6369,25 +5975,21 @@
 #endif
 
 #ifdef FOR_source
-#define CLEANUP_source
 #ifndef TT
 #define TT this.source
 #endif
 #endif
 
 #ifdef FOR_split
-#define CLEANUP_split
 #ifndef TT
 #define TT this.split
 #endif
-#define FLAG_n (FORCED_FLAG<<0)
-#define FLAG_l (FORCED_FLAG<<1)
-#define FLAG_b (FORCED_FLAG<<2)
-#define FLAG_a (FORCED_FLAG<<3)
+#define FLAG_l (FORCED_FLAG<<0)
+#define FLAG_b (FORCED_FLAG<<1)
+#define FLAG_a (FORCED_FLAG<<2)
 #endif
 
 #ifdef FOR_stat
-#define CLEANUP_stat
 #ifndef TT
 #define TT this.stat
 #endif
@@ -6397,18 +5999,7 @@
 #define FLAG_c (1<<3)
 #endif
 
-#ifdef FOR_strace
-#define CLEANUP_strace
-#ifndef TT
-#define TT this.strace
-#endif
-#define FLAG_v (FORCED_FLAG<<0)
-#define FLAG_s (FORCED_FLAG<<1)
-#define FLAG_p (FORCED_FLAG<<2)
-#endif
-
 #ifdef FOR_strings
-#define CLEANUP_strings
 #ifndef TT
 #define TT this.strings
 #endif
@@ -6420,7 +6011,6 @@
 #endif
 
 #ifdef FOR_stty
-#define CLEANUP_stty
 #ifndef TT
 #define TT this.stty
 #endif
@@ -6430,7 +6020,6 @@
 #endif
 
 #ifdef FOR_su
-#define CLEANUP_su
 #ifndef TT
 #define TT this.su
 #endif
@@ -6444,7 +6033,6 @@
 #endif
 
 #ifdef FOR_sulogin
-#define CLEANUP_sulogin
 #ifndef TT
 #define TT this.sulogin
 #endif
@@ -6452,14 +6040,12 @@
 #endif
 
 #ifdef FOR_swapoff
-#define CLEANUP_swapoff
 #ifndef TT
 #define TT this.swapoff
 #endif
 #endif
 
 #ifdef FOR_swapon
-#define CLEANUP_swapon
 #ifndef TT
 #define TT this.swapon
 #endif
@@ -6468,7 +6054,6 @@
 #endif
 
 #ifdef FOR_switch_root
-#define CLEANUP_switch_root
 #ifndef TT
 #define TT this.switch_root
 #endif
@@ -6477,14 +6062,12 @@
 #endif
 
 #ifdef FOR_sync
-#define CLEANUP_sync
 #ifndef TT
 #define TT this.sync
 #endif
 #endif
 
 #ifdef FOR_sysctl
-#define CLEANUP_sysctl
 #ifndef TT
 #define TT this.sysctl
 #endif
@@ -6499,7 +6082,6 @@
 #endif
 
 #ifdef FOR_syslogd
-#define CLEANUP_syslogd
 #ifndef TT
 #define TT this.syslogd
 #endif
@@ -6520,26 +6102,21 @@
 #endif
 
 #ifdef FOR_tac
-#define CLEANUP_tac
 #ifndef TT
 #define TT this.tac
 #endif
 #endif
 
 #ifdef FOR_tail
-#define CLEANUP_tail
 #ifndef TT
 #define TT this.tail
 #endif
 #define FLAG_n (1<<0)
 #define FLAG_c (1<<1)
-#define FLAG_s (1<<2)
-#define FLAG_F (1<<3)
-#define FLAG_f (1<<4)
+#define FLAG_f (1<<2)
 #endif
 
 #ifdef FOR_tar
-#define CLEANUP_tar
 #ifndef TT
 #define TT this.tar
 #endif
@@ -6576,12 +6153,9 @@
 #define FLAG_no_recursion (1<<30)
 #define FLAG_full_time (1LL<<31)
 #define FLAG_restrict (1LL<<32)
-#define FLAG_selinux (1LL<<33)
-#define FLAG_strip_components (1LL<<34)
 #endif
 
 #ifdef FOR_taskset
-#define CLEANUP_taskset
 #ifndef TT
 #define TT this.taskset
 #endif
@@ -6590,7 +6164,6 @@
 #endif
 
 #ifdef FOR_tcpsvd
-#define CLEANUP_tcpsvd
 #ifndef TT
 #define TT this.tcpsvd
 #endif
@@ -6605,7 +6178,6 @@
 #endif
 
 #ifdef FOR_tee
-#define CLEANUP_tee
 #ifndef TT
 #define TT this.tee
 #endif
@@ -6614,14 +6186,12 @@
 #endif
 
 #ifdef FOR_telnet
-#define CLEANUP_telnet
 #ifndef TT
 #define TT this.telnet
 #endif
 #endif
 
 #ifdef FOR_telnetd
-#define CLEANUP_telnetd
 #ifndef TT
 #define TT this.telnetd
 #endif
@@ -6637,14 +6207,12 @@
 #endif
 
 #ifdef FOR_test
-#define CLEANUP_test
 #ifndef TT
 #define TT this.test
 #endif
 #endif
 
 #ifdef FOR_tftp
-#define CLEANUP_tftp
 #ifndef TT
 #define TT this.tftp
 #endif
@@ -6656,7 +6224,6 @@
 #endif
 
 #ifdef FOR_tftpd
-#define CLEANUP_tftpd
 #ifndef TT
 #define TT this.tftpd
 #endif
@@ -6667,7 +6234,6 @@
 #endif
 
 #ifdef FOR_time
-#define CLEANUP_time
 #ifndef TT
 #define TT this.time
 #endif
@@ -6676,7 +6242,6 @@
 #endif
 
 #ifdef FOR_timeout
-#define CLEANUP_timeout
 #ifndef TT
 #define TT this.timeout
 #endif
@@ -6688,7 +6253,6 @@
 #endif
 
 #ifdef FOR_top
-#define CLEANUP_top
 #ifndef TT
 #define TT this.top
 #endif
@@ -6703,12 +6267,10 @@
 #define FLAG_o (FORCED_FLAG<<8)
 #define FLAG_k (FORCED_FLAG<<9)
 #define FLAG_H (FORCED_FLAG<<10)
-#define FLAG_h (FORCED_FLAG<<11)
-#define FLAG_O (FORCED_FLAG<<12)
+#define FLAG_O (FORCED_FLAG<<11)
 #endif
 
 #ifdef FOR_touch
-#define CLEANUP_touch
 #ifndef TT
 #define TT this.touch
 #endif
@@ -6723,14 +6285,12 @@
 #endif
 
 #ifdef FOR_toybox
-#define CLEANUP_toybox
 #ifndef TT
 #define TT this.toybox
 #endif
 #endif
 
 #ifdef FOR_tr
-#define CLEANUP_tr
 #ifndef TT
 #define TT this.tr
 #endif
@@ -6741,7 +6301,6 @@
 #endif
 
 #ifdef FOR_traceroute
-#define CLEANUP_traceroute
 #ifndef TT
 #define TT this.traceroute
 #endif
@@ -6768,14 +6327,12 @@
 #endif
 
 #ifdef FOR_true
-#define CLEANUP_true
 #ifndef TT
 #define TT this.true
 #endif
 #endif
 
 #ifdef FOR_truncate
-#define CLEANUP_truncate
 #ifndef TT
 #define TT this.truncate
 #endif
@@ -6784,7 +6341,6 @@
 #endif
 
 #ifdef FOR_tty
-#define CLEANUP_tty
 #ifndef TT
 #define TT this.tty
 #endif
@@ -6792,7 +6348,6 @@
 #endif
 
 #ifdef FOR_tunctl
-#define CLEANUP_tunctl
 #ifndef TT
 #define TT this.tunctl
 #endif
@@ -6802,20 +6357,7 @@
 #define FLAG_t (FORCED_FLAG<<3)
 #endif
 
-#ifdef FOR_uclampset
-#define CLEANUP_uclampset
-#ifndef TT
-#define TT this.uclampset
-#endif
-#define FLAG_R (FORCED_FLAG<<0)
-#define FLAG_M (FORCED_FLAG<<1)
-#define FLAG_m (FORCED_FLAG<<2)
-#define FLAG_a (FORCED_FLAG<<3)
-#define FLAG_p (FORCED_FLAG<<4)
-#endif
-
 #ifdef FOR_ulimit
-#define CLEANUP_ulimit
 #ifndef TT
 #define TT this.ulimit
 #endif
@@ -6842,7 +6384,6 @@
 #endif
 
 #ifdef FOR_umount
-#define CLEANUP_umount
 #ifndef TT
 #define TT this.umount
 #endif
@@ -6859,7 +6400,6 @@
 #endif
 
 #ifdef FOR_uname
-#define CLEANUP_uname
 #ifndef TT
 #define TT this.uname
 #endif
@@ -6868,19 +6408,17 @@
 #define FLAG_r (1<<2)
 #define FLAG_v (1<<3)
 #define FLAG_m (1<<4)
-#define FLAG_o (1<<5)
-#define FLAG_a (1<<6)
+#define FLAG_a (1<<5)
+#define FLAG_o (1<<6)
 #endif
 
 #ifdef FOR_unicode
-#define CLEANUP_unicode
 #ifndef TT
 #define TT this.unicode
 #endif
 #endif
 
 #ifdef FOR_uniq
-#define CLEANUP_uniq
 #ifndef TT
 #define TT this.uniq
 #endif
@@ -6895,21 +6433,18 @@
 #endif
 
 #ifdef FOR_unix2dos
-#define CLEANUP_unix2dos
 #ifndef TT
 #define TT this.unix2dos
 #endif
 #endif
 
 #ifdef FOR_unlink
-#define CLEANUP_unlink
 #ifndef TT
 #define TT this.unlink
 #endif
 #endif
 
 #ifdef FOR_unset
-#define CLEANUP_unset
 #ifndef TT
 #define TT this.unset
 #endif
@@ -6919,7 +6454,6 @@
 #endif
 
 #ifdef FOR_unshare
-#define CLEANUP_unshare
 #ifndef TT
 #define TT this.unshare
 #endif
@@ -6934,7 +6468,6 @@
 #endif
 
 #ifdef FOR_uptime
-#define CLEANUP_uptime
 #ifndef TT
 #define TT this.uptime
 #endif
@@ -6943,7 +6476,6 @@
 #endif
 
 #ifdef FOR_useradd
-#define CLEANUP_useradd
 #ifndef TT
 #define TT this.useradd
 #endif
@@ -6958,7 +6490,6 @@
 #endif
 
 #ifdef FOR_userdel
-#define CLEANUP_userdel
 #ifndef TT
 #define TT this.userdel
 #endif
@@ -6966,14 +6497,12 @@
 #endif
 
 #ifdef FOR_usleep
-#define CLEANUP_usleep
 #ifndef TT
 #define TT this.usleep
 #endif
 #endif
 
 #ifdef FOR_uudecode
-#define CLEANUP_uudecode
 #ifndef TT
 #define TT this.uudecode
 #endif
@@ -6981,7 +6510,6 @@
 #endif
 
 #ifdef FOR_uuencode
-#define CLEANUP_uuencode
 #ifndef TT
 #define TT this.uuencode
 #endif
@@ -6989,7 +6517,6 @@
 #endif
 
 #ifdef FOR_uuidgen
-#define CLEANUP_uuidgen
 #ifndef TT
 #define TT this.uuidgen
 #endif
@@ -6997,14 +6524,12 @@
 #endif
 
 #ifdef FOR_vconfig
-#define CLEANUP_vconfig
 #ifndef TT
 #define TT this.vconfig
 #endif
 #endif
 
 #ifdef FOR_vi
-#define CLEANUP_vi
 #ifndef TT
 #define TT this.vi
 #endif
@@ -7012,7 +6537,6 @@
 #endif
 
 #ifdef FOR_vmstat
-#define CLEANUP_vmstat
 #ifndef TT
 #define TT this.vmstat
 #endif
@@ -7020,14 +6544,12 @@
 #endif
 
 #ifdef FOR_w
-#define CLEANUP_w
 #ifndef TT
 #define TT this.w
 #endif
 #endif
 
 #ifdef FOR_wait
-#define CLEANUP_wait
 #ifndef TT
 #define TT this.wait
 #endif
@@ -7035,7 +6557,6 @@
 #endif
 
 #ifdef FOR_watch
-#define CLEANUP_watch
 #ifndef TT
 #define TT this.watch
 #endif
@@ -7047,7 +6568,6 @@
 #endif
 
 #ifdef FOR_watchdog
-#define CLEANUP_watchdog
 #ifndef TT
 #define TT this.watchdog
 #endif
@@ -7057,7 +6577,6 @@
 #endif
 
 #ifdef FOR_wc
-#define CLEANUP_wc
 #ifndef TT
 #define TT this.wc
 #endif
@@ -7068,18 +6587,14 @@
 #endif
 
 #ifdef FOR_wget
-#define CLEANUP_wget
 #ifndef TT
 #define TT this.wget
 #endif
-#define FLAG_p (FORCED_FLAG<<0)
-#define FLAG_O (FORCED_FLAG<<1)
-#define FLAG_d (FORCED_FLAG<<2)
-#define FLAG_max_redirect (FORCED_FLAG<<3)
+#define FLAG_O (FORCED_FLAG<<0)
+#define FLAG_no_check_certificate (FORCED_FLAG<<1)
 #endif
 
 #ifdef FOR_which
-#define CLEANUP_which
 #ifndef TT
 #define TT this.which
 #endif
@@ -7087,7 +6602,6 @@
 #endif
 
 #ifdef FOR_who
-#define CLEANUP_who
 #ifndef TT
 #define TT this.who
 #endif
@@ -7095,7 +6609,6 @@
 #endif
 
 #ifdef FOR_xargs
-#define CLEANUP_xargs
 #ifndef TT
 #define TT this.xargs
 #endif
@@ -7111,7 +6624,6 @@
 #endif
 
 #ifdef FOR_xxd
-#define CLEANUP_xxd
 #ifndef TT
 #define TT this.xxd
 #endif
@@ -7126,21 +6638,18 @@
 #endif
 
 #ifdef FOR_xzcat
-#define CLEANUP_xzcat
 #ifndef TT
 #define TT this.xzcat
 #endif
 #endif
 
 #ifdef FOR_yes
-#define CLEANUP_yes
 #ifndef TT
 #define TT this.yes
 #endif
 #endif
 
 #ifdef FOR_zcat
-#define CLEANUP_zcat
 #ifndef TT
 #define TT this.zcat
 #endif
diff --git a/android/linux/generated/globals.h b/android/linux/generated/globals.h
index 403077b..7d5e3be 100644
--- a/android/linux/generated/globals.h
+++ b/android/linux/generated/globals.h
@@ -72,16 +72,15 @@
 
 struct md5sum_data {
   int sawline;
-  unsigned *rconsttable32;
-  unsigned long long *rconsttable64; // for sha384,sha512
 
+  unsigned *md5table;
   // Crypto variables blanked after summing
-  unsigned long long count, overflow;
+  unsigned state[5], oldstate[5];
+  unsigned long long count;
   union {
-    char c[128]; // bytes, 1024 bits
-    unsigned i32[16]; // 512 bits for md5,sha1,sha224,sha256
-    unsigned long long i64[16]; // 1024 bits for sha384,sha512
-  } state, buffer;
+    char c[64];
+    unsigned i[16];
+  } buffer;
 };
 
 // toys/lsb/mknod.c
@@ -117,7 +116,7 @@
 // toys/lsb/pidof.c
 
 struct pidof_data {
-  char *o;
+  char *omit;
 };
 
 // toys/lsb/seq.c
@@ -151,15 +150,6 @@
   int fd;
 };
 
-// toys/net/host.c
-
-struct host_data {
-  char *t;
-
-  char **nsname;
-  unsigned nslen;
-};
-
 // toys/net/ifconfig.c
 
 struct ifconfig_data {
@@ -281,20 +271,17 @@
   char *buf;
 };
 
-// toys/other/gpiod.c
-
-struct gpiod_data {
-  struct double_list *chips;
-  int chip_count;
-};
-
 // toys/other/hexedit.c
 
 struct hexedit_data {
-  char *data, *search, keybuf[16], input[80];
-  long long len, base, pos;
-  int numlen, undo, undolen, mode;
+  char *data;
+  long long len, base;
+  int numlen, undo, undolen;
   unsigned rows, cols;
+  long long pos;
+  char keybuf[16];
+  char input[80];
+  char *search;
 };
 
 // toys/other/hwclock.c
@@ -332,21 +319,21 @@
 // toys/other/lsattr.c
 
 struct lsattr_data {
-  long v, p;
+  long v;
+  long p;
 
-  unsigned add, rm, set;
+  long add, rm, set;
   // !add and !rm tell us whether they were used, but `chattr =` is meaningful.
   int have_set;
 };
 
-// toys/other/lsusb.c
+// toys/other/lspci.c
 
-struct lsusb_data {
+struct lspci_data {
   char *i;
   long n;
 
-  void *ids, *class;
-  int count;
+  FILE *db;
 };
 
 // toys/other/makedevs.c
@@ -397,34 +384,12 @@
   char *c;
 };
 
-// toys/other/openvt.c
-
-struct openvt_data {
-  long c;
-};
-
 // toys/other/pwgen.c
 
 struct pwgen_data {
   char *r;
 };
 
-// toys/other/readelf.c
-
-struct readelf_data {
-  char *x, *p;
-
-  char *elf, *shstrtab, *f;
-  unsigned long long shoff, phoff, size, shstrtabsz;
-  int bits, endian, shnum, shentsize, phentsize;
-};
-
-// toys/other/reboot.c
-
-struct reboot_data {
-  char *d;
-};
-
 // toys/other/rtcwake.c
 
 struct rtcwake_data {
@@ -491,9 +456,8 @@
 
   int nextsig;
   pid_t pid;
-  struct timespec kts;
-  struct itimerspec its;
-  timer_t timer;
+  struct timeval ktv;
+  struct itimerval itv;
 };
 
 // toys/other/truncate.c
@@ -505,12 +469,6 @@
   int type;
 };
 
-// toys/other/uclampset.c
-
-struct uclampset_data {
-  long M, m, p;
-};
-
 // toys/other/watch.c
 
 struct watch_data {
@@ -540,7 +498,7 @@
     char *af_type_A;
     char *af_type_p;
     char *interface;
-
+    
     int sockfd;
     char *device;
 };
@@ -574,7 +532,7 @@
 // toys/pending/bootchartd.c
 
 struct bootchartd_data {
-  char timestamp[32];
+  char buf[32];
   long msec;
   int proc_accounting;
 
@@ -751,17 +709,10 @@
   long gid;
 };
 
-// toys/pending/hexdump.c
+// toys/pending/host.c
 
-struct hexdump_data {
-    long s, n;
-
-    long long len, pos, ppos;
-    const char *fmt;
-    unsigned int fn, bc;  // file number and byte count
-    char linebuf[16];  // line buffer - serves double duty for sqeezing repeat
-                       // lines and for accumulating full lines accross file
-                       // boundaries if necessesary.
+struct host_data {
+  char *type_str;
 };
 
 // toys/pending/ip.c
@@ -868,6 +819,22 @@
   int cin_fd;
 };
 
+// toys/pending/openvt.c
+
+struct openvt_data {
+  long c;
+};
+
+// toys/pending/readelf.c
+
+struct readelf_data {
+  char *x, *p;
+
+  char *elf, *shstrtab, *f;
+  unsigned long long shoff, phoff, size, shstrtabsz;
+  int bits, endian, shnum, shentsize, phentsize;
+};
+
 // toys/pending/route.c
 
 struct route_data {
@@ -890,7 +857,7 @@
   long long SECONDS;
   char *isexec, *wcpat;
   unsigned options, jobcnt, LINENO;
-  int hfd, pid, bangpid, varslen, srclvl, recursion;
+  int hfd, pid, bangpid, varslen, cdcount, srclvl, recursion;
 
   // Callable function array
   struct sh_function {
@@ -941,7 +908,7 @@
     struct sh_process *next, *prev; // | && ||
     struct arg_list *delete;   // expanded strings
     // undo redirects, a=b at start, child PID, exit status, has !, job #
-    int *urd, envlen, pid, exit, flags, job, dash;
+    int *urd, envlen, pid, exit, not, job, dash;
     long long when; // when job backgrounded/suspended
     struct sh_arg *raw, arg;
   } *pp; // currently running process
@@ -950,17 +917,6 @@
   struct sh_arg jobs, *wcdeck;
 };
 
-// toys/pending/strace.c
-
-struct strace_data {
-  long s, p;
-
-  char ioctl[32], *fmt;
-  long regs[256/sizeof(long)], syscall;
-  pid_t pid;
-  int arg;
-};
-
 // toys/pending/stty.c
 
 struct stty_data {
@@ -1159,17 +1115,7 @@
 // toys/pending/wget.c
 
 struct wget_data {
-  char *p, *O;
-  long max_redirect;
-
-  int sock, https;
-  char *url;
-#if CFG_WGET_LIBTLS
-  struct tls *tls;
-#elif CFG_WGET_OPENSSL
-  struct ssl_ctx_st *ctx;
-  struct ssl_st *ssl;
-#endif
+  char *filename;
 };
 
 // toys/posix/basename.c
@@ -1208,8 +1154,6 @@
 // toys/posix/cmp.c
 
 struct cmp_data {
-  long n;
-
   int fd;
   char *name;
 };
@@ -1248,7 +1192,6 @@
   char *d, *O;
   struct arg_list *select[5]; // we treat them the same, so loop through
 
-  unsigned line;
   int pairs;
   regex_t reg;
 };
@@ -1256,7 +1199,7 @@
 // toys/posix/date.c
 
 struct date_data {
-  char *s, *r, *I, *D, *d;
+  char *r, *I, *D, *d;
 
   unsigned nano;
 };
@@ -1297,6 +1240,7 @@
 
 struct file_data {
   int max_name_len;
+
   off_t len;
 };
 
@@ -1406,7 +1350,8 @@
   long w, l, v;
 
   // Count of consecutive blank lines for -l has to persist between files
-  long lcount, slen;
+  long lcount;
+  long slen;
 };
 
 // toys/posix/od.c
@@ -1467,7 +1412,7 @@
 
   struct ptr_len gg, GG, pp, PP, ss, tt, uu, UU;
   struct dirtree *threadparent;
-  unsigned width, height, scroll;
+  unsigned width, height;
   dev_t tty;
   void *fields, *kfields;
   long long ticks, bits, time;
@@ -1507,14 +1452,14 @@
   char *o, *T, S;
 
   void *key_list;
-  unsigned linecount;
+  int linecount;
   char **lines, *name;
 };
 
 // toys/posix/split.c
 
 struct split_data {
-  long n, l, b, a;
+  long l, b, a;
 
   char *outfile;
 };
@@ -1530,16 +1475,9 @@
 
 struct tail_data {
   long n, c;
-  char *s;
 
-  int file_no, last_fd, ss;
+  int file_no, last_fd;
   struct xnotify *not;
-  struct {
-    char *path;
-    int fd;
-    dev_t dev;
-    ino_t ino;
-  } *F;
 };
 
 // toys/posix/tar.c
@@ -1549,12 +1487,11 @@
   struct arg_list *T, *X;
   char *I, *to_command, *owner, *group, *mtime, *mode;
   struct arg_list *exclude;
-  long strip_components;
 
   struct double_list *incl, *excl, *seen;
   struct string_list *dirs;
   char *cwd;
-  int fd, ouid, ggid, hlc, warn, adev, aino, sparselen, pid;
+  int fd, ouid, ggid, hlc, warn, adev, aino, sparselen;
   long long *sparse;
   time_t mtt;
 
@@ -1646,7 +1583,6 @@
 	struct su_data su;
 	struct umount_data umount;
 	struct ftpget_data ftpget;
-	struct host_data host;
 	struct ifconfig_data ifconfig;
 	struct microcom_data microcom;
 	struct netcat_data netcat;
@@ -1664,14 +1600,13 @@
 	struct fallocate_data fallocate;
 	struct fmt_data fmt;
 	struct free_data free;
-	struct gpiod_data gpiod;
 	struct hexedit_data hexedit;
 	struct hwclock_data hwclock;
 	struct ionice_data ionice;
 	struct login_data login;
 	struct losetup_data losetup;
 	struct lsattr_data lsattr;
-	struct lsusb_data lsusb;
+	struct lspci_data lspci;
 	struct makedevs_data makedevs;
 	struct mix_data mix;
 	struct mkpasswd_data mkpasswd;
@@ -1679,10 +1614,7 @@
 	struct modinfo_data modinfo;
 	struct nsenter_data nsenter;
 	struct oneit_data oneit;
-	struct openvt_data openvt;
 	struct pwgen_data pwgen;
-	struct readelf_data readelf;
-	struct reboot_data reboot;
 	struct rtcwake_data rtcwake;
 	struct setfattr_data setfattr;
 	struct sha3sum_data sha3sum;
@@ -1693,7 +1625,6 @@
 	struct tac_data tac;
 	struct timeout_data timeout;
 	struct truncate_data truncate;
-	struct uclampset_data uclampset;
 	struct watch_data watch;
 	struct watchdog_data watchdog;
 	struct xxd_data xxd;
@@ -1719,7 +1650,7 @@
 	struct getopt_data getopt;
 	struct getty_data getty;
 	struct groupadd_data groupadd;
-	struct hexdump_data hexdump;
+	struct host_data host;
 	struct ip_data ip;
 	struct ipcrm_data ipcrm;
 	struct ipcs_data ipcs;
@@ -1730,9 +1661,10 @@
 	struct mke2fs_data mke2fs;
 	struct modprobe_data modprobe;
 	struct more_data more;
+	struct openvt_data openvt;
+	struct readelf_data readelf;
 	struct route_data route;
 	struct sh_data sh;
-	struct strace_data strace;
 	struct stty_data stty;
 	struct sulogin_data sulogin;
 	struct syslogd_data syslogd;
diff --git a/android/linux/generated/help.h b/android/linux/generated/help.h
index 30c24e9..86fbdbf 100644
--- a/android/linux/generated/help.h
+++ b/android/linux/generated/help.h
@@ -4,6 +4,8 @@
 
 #define HELP_toybox_uid_sys "When commands like useradd/groupadd allocate system IDs, start here."
 
+#define HELP_toybox_pedantic_args "Check arguments for commands that have no arguments."
+
 #define HELP_toybox_debug "Enable extra checks for debugging purposes. All of them catch\nthings that can only go wrong at development time, not runtime."
 
 #define HELP_toybox_norecurse "When one toybox command calls another, usually it just calls the new\ncommand's main() function rather than searching the $PATH and calling\nexec on another file (which is much slower).\n\nThis disables that optimization, so toybox will run external commands\n       even when it has a built-in version of that command. This requires\n       toybox symlinks to be installed in the $PATH, or re-invoking the\n       \"toybox\" multiplexer command by name."
@@ -38,17 +40,17 @@
 
 #define HELP_restorecon "usage: restorecon [-D] [-F] [-R] [-n] [-v] FILE...\n\nRestores the default security contexts for the given files.\n\n-D	Apply to /data/data too\n-F	Force reset\n-R	Recurse into directories\n-n	Don't make any changes; useful with -v to see what would change\n-v	Verbose"
 
-#define HELP_log "usage: log [-p PRI] [-t TAG] [MESSAGE...]\n\nLogs message (or stdin) to logcat.\n\n-p	Use the given priority instead of INFO:\n	d: DEBUG  e: ERROR  f: FATAL  i: INFO  v: VERBOSE  w: WARN  s: SILENT\n-t	Use the given tag instead of \"log\""
+#define HELP_log "usage: log [-p PRI] [-t TAG] MESSAGE...\n\nLogs message to logcat.\n\n-p	Use the given priority instead of INFO:\n	d: DEBUG  e: ERROR  f: FATAL  i: INFO  v: VERBOSE  w: WARN  s: SILENT\n-t	Use the given tag instead of \"log\""
 
 #define HELP_load_policy "usage: load_policy FILE\n\nLoad the specified SELinux policy file."
 
 #define HELP_getenforce "usage: getenforce\n\nShows whether SELinux is disabled, enforcing, or permissive."
 
-#define HELP_skeleton_alias "usage: skeleton_alias [-dq] [-b NUMBER]\n\nExample of a second command with different arguments in the same source\nfile as the first. This allows shared infrastructure outside of lib/."
+#define HELP_skeleton_alias "usage: skeleton_alias [-dq] [-b NUMBER]\n\nExample of a second command with different arguments in the same source\nfile as the first. This allows shared infrastructure not added to lib/."
 
 #define HELP_skeleton "usage: skeleton [-a] [-b STRING] [-c NUMBER] [-d LIST] [-e COUNT] [...]\n\nTemplate for new commands. You don't need this.\n\nWhen creating a new command, copy this file and delete the parts you\ndon't need. Be sure to replace all instances of \"skeleton\" (upper and lower\ncase) with your new command name.\n\nFor simple commands, \"hello.c\" is probably a better starting point."
 
-#define HELP_logpath "usage: logpath ...\n\nAppend command line to $LOGPATH, then call second instance\nof command in $PATH."
+#define HELP_logwrapper "usage: logwrapper ...\n\nAppend command line to $WRAPLOG, then call second instance\nof command in $PATH."
 
 #define HELP_hostid "usage: hostid\n\nPrint the numeric identifier for the current host."
 
@@ -70,7 +72,7 @@
 
 #define HELP_seq "usage: seq [-w|-f fmt_str] [-s sep_str] [first] [increment] last\n\nCount from first to last, by increment. Omitted arguments default\nto 1. Two arguments are used as first and last. Arguments can be\nnegative or floating point.\n\n-f	Use fmt_str as a printf-style floating point format string\n-s	Use sep_str as separator, default is a newline character\n-w	Pad to equal width with leading zeroes"
 
-#define HELP_pidof "usage: pidof [-s] [-o omitpid[,omitpid...]] [NAME...]\n\nPrint the PIDs of all processes with the given names.\n\n-o	Omit PID(s)\n-s	Single shot, only return one pid\n-x	Match shell scripts too"
+#define HELP_pidof "usage: pidof [-s] [-o omitpid[,omitpid...]] [NAME]...\n\nPrint the PIDs of all processes with the given names.\n\n-s	Single shot, only return one pid\n-o	Omit PID(s)\n-x	Match shell scripts too"
 
 #define HELP_passwd_sad "Password changes are checked to make sure they're at least 6 chars long,\ndon't include the entire username (but not a subset of it), or the entire\nprevious password (but changing password1, password2, password3 is fine).\nThis heuristic accepts \"aaaaaa\" and \"123456\"."
 
@@ -84,17 +86,17 @@
 
 #define HELP_mknod "usage: mknod [-m MODE] NAME TYPE [MAJOR MINOR]\n\nCreate a special file NAME with a given type. TYPE is b for block device,\nc or u for character device, p for named pipe (which ignores MAJOR/MINOR).\n\n-m	Mode (file permissions) of new device, in octal or u+x format"
 
-#define HELP_sha512sum "See md5sum"
+#define HELP_sha512sum "See sha1sum"
 
-#define HELP_sha384sum "See md5sum"
+#define HELP_sha384sum "See sha1sum"
 
-#define HELP_sha256sum "See md5sum"
+#define HELP_sha256sum "See sha1sum"
 
-#define HELP_sha224sum "See md5sum"
+#define HELP_sha224sum "See sha1sum"
 
-#define HELP_sha1sum "See md5sum"
+#define HELP_sha1sum "usage: sha?sum [-bcs] [FILE]...\n\nCalculate sha hash for each input file, reading from stdin if none. Output\none hash (40 hex digits for sha1, 56 for sha224, 64 for sha256, 96 for sha384,\nand 128 for sha512) for each input file, followed by filename.\n\n-b	Brief (hash only, no filename)\n-c	Check each line of each FILE is the same hash+filename we'd output\n-s	No output, exit status 0 if all hashes match, 1 otherwise"
 
-#define HELP_md5sum "usage: ???sum [-bcs] [FILE]...\n\nCalculate hash for each input file, reading from stdin if none, writing\nhexadecimal digits to stdout for each input file (md5=32 hex digits,\nsha1=40, sha224=56, sha256=64, sha384=96, sha512=128) followed by filename.\n\n-b	Brief (hash only, no filename)\n-c	Check each line of each FILE is the same hash+filename we'd output\n-s	No output, exit status 0 if all hashes match, 1 otherwise"
+#define HELP_md5sum "usage: md5sum [-bcs] [FILE]...\n\nCalculate md5 hash for each input file, reading from stdin if none.\nOutput one hash (32 hex digits) for each input file, followed by filename.\n\n-b	Brief (hash only, no filename)\n-c	Check each line of each FILE is the same hash+filename we'd output\n-s	No output, exit status 0 if all hashes match, 1 otherwise"
 
 #define HELP_killall "usage: killall [-l] [-iqv] [-SIGNAL|-s SIGNAL] PROCESS_NAME...\n\nSend a signal (default: TERM) to all processes with the given names.\n\n-i	Ask for confirmation before killing\n-l	Print list of all available signals\n-q	Don't print any warnings or error messages\n-s	Send SIGNAL instead of SIGTERM\n-v	Report if the signal was successfully sent\n-w	Wait until all signaled processes are dead"
 
@@ -126,9 +128,7 @@
 
 #define HELP_microcom "usage: microcom [-s SPEED] [-X] DEVICE\n\nSimple serial console.\n\n-s	Set baud rate to SPEED (default 115200)\n-X	Ignore ^@ (send break) and ^] (exit)"
 
-#define HELP_ifconfig "usage: ifconfig [-aS] [INTERFACE [ACTION...]]\n\nDisplay or configure network interface.\n\nWith no arguments, display active interfaces. First argument is interface\nto operate on, one argument by itself displays that interface.\n\n-a	All interfaces displayed, not just active ones\n-S	Short view, one line per interface\n\nStandard ACTIONs to perform on an INTERFACE:\n\nADDR[/MASK]        - set IPv4 address (1.2.3.4/5) and activate interface\nadd|del ADDR[/LEN] - add/remove IPv6 address (1111::8888/128)\nup|down            - activate or deactivate interface\n\nAdvanced ACTIONs (default values usually suffice):\n\ndefault          - remove IPv4 address\nnetmask ADDR     - set IPv4 netmask via 255.255.255.0 instead of /24\ntxqueuelen LEN   - number of buffered packets before output blocks\nmtu LEN          - size of outgoing packets (Maximum Transmission Unit)\nbroadcast ADDR   - Set broadcast address\npointopoint ADDR - PPP and PPPOE use this instead of \"route add default gw\"\nhw TYPE ADDR     - set hardware (mac) address (type = ether|infiniband)\nrename NEWNAME   - rename interface\n\nFlags you can set on an interface (or -remove by prefixing with -):\n\narp       - don't use Address Resolution Protocol to map LAN routes\npromisc   - don't discard packets that aren't to this LAN hardware address\nmulticast - force interface into multicast mode if the driver doesn't\nallmulti  - promisc for multicast packets"
-
-#define HELP_host "usage: host [-v] [-t TYPE] NAME [SERVER]\n\nLook up DNS records for NAME, either domain name or IPv4/IPv6 address to\nreverse lookup, from SERVER or default DNS server(s).\n\n-a	All records\n-t TYPE	Record TYPE (number or ANY A AAAA CNAME MX NS PTR SOA SRV TXT)\n-v	Verbose"
+#define HELP_ifconfig "usage: ifconfig [-aS] [INTERFACE [ACTION...]]\n\nDisplay or configure network interface.\n\nWith no arguments, display active interfaces. First argument is interface\nto operate on, one argument by itself displays that interface.\n\n-a	All interfaces displayed, not just active ones\n-S	Short view, one line per interface\n\nStandard ACTIONs to perform on an INTERFACE:\n\nADDR[/MASK]        - set IPv4 address (1.2.3.4/5) and activate interface\nadd|del ADDR[/LEN] - add/remove IPv6 address (1111::8888/128)\nup|down            - activate or deactivate interface\n\nAdvanced ACTIONs (default values usually suffice):\n\ndefault          - remove IPv4 address\nnetmask ADDR     - set IPv4 netmask via 255.255.255.0 instead of /24\ntxqueuelen LEN   - number of buffered packets before output blocks\nmtu LEN          - size of outgoing packets (Maximum Transmission Unit)\nbroadcast ADDR   - Set broadcast address\npointopoint ADDR - PPP and PPPOE use this instead of \"route add default gw\"\nhw TYPE ADDR     - set hardware (mac) address (type = ether|infiniband)\n\nFlags you can set on an interface (or -remove by prefixing with -):\n\narp       - don't use Address Resolution Protocol to map LAN routes\npromisc   - don't discard packets that aren't to this LAN hardware address\nmulticast - force interface into multicast mode if the driver doesn't\nallmulti  - promisc for multicast packets"
 
 #define HELP_ftpput "An ftpget that defaults to -s instead of -g"
 
@@ -136,7 +136,7 @@
 
 #define HELP_yes "usage: yes [args...]\n\nRepeatedly output line until killed. If no args, output 'y'."
 
-#define HELP_xxd "usage: xxd [-c n] [-g n] [-i] [-l n] [-o n] [-p] [-r] [-s n] [file]\n\nHexdump a file to stdout. If no file is listed, copy from stdin.\nFilename \"-\" is a synonym for stdin.\n\n-c n	Show n bytes per line (default 16)\n-g n	Group bytes by adding a ' ' every n bytes (default 2)\n-i	Output include file (CSV hex bytes, plus C header/footer if not stdin)\n-l n	Limit of n bytes before stopping (default is no limit)\n-o n	Add n to display offset\n-p	Plain hexdump (30 bytes/line, no grouping)\n-r	Reverse operation: turn a hexdump into a binary file\n-s n	Skip to offset n"
+#define HELP_xxd "usage: xxd [-c n] [-g n] [-i] [-l n] [-o n] [-p] [-r] [-s n] [file]\n\nHexdump a file to stdout.  If no file is listed, copy from stdin.\nFilename \"-\" is a synonym for stdin.\n\n-c n	Show n bytes per line (default 16)\n-g n	Group bytes by adding a ' ' every n bytes (default 2)\n-i	Include file output format (comma-separated hex byte literals)\n-l n	Limit of n bytes before stopping (default is no limit)\n-o n	Add n to display offset\n-p	Plain hexdump (30 bytes/line, no grouping)\n-r	Reverse operation: turn a hexdump into a binary file\n-s n	Skip to offset n"
 
 #define HELP_which "usage: which [-a] filename ...\n\nSearch $PATH for executable files matching filename(s).\n\n-a	Show all matches"
 
@@ -156,8 +156,6 @@
 
 #define HELP_uptime "usage: uptime [-ps]\n\nTell the current time, how long the system has been running, the number\nof users, and the system load averages for the past 1, 5 and 15 minutes.\n\n-p	Pretty (human readable) uptime\n-s	Since when has the system been up?"
 
-#define HELP_uclampset "usage: uclampset [-m MIN] [-M MAX] {-p PID | COMMAND...}\n\nSet or query process utilization limits ranging from 0 to 1024, or -1 to\nreset to system default. With no arguments, prints current values.\n\n-m MIN      Reserve at least this much CPU utilization for task\n-M MAX      Limit task to at most this much CPU utilization\n-p PID	Apply to PID rather than new COMMAND\n-R	Reset child processes to default values on fork\n-a	Apply to all threads for the given PID"
-
 #define HELP_truncate "usage: truncate [-c] -s SIZE file...\n\nSet length of file(s), extending sparsely if necessary.\n\n-c	Don't create file if it doesn't exist\n-s	New size (with optional prefix and suffix)\n\nSIZE prefix: + add, - subtract, < shrink to, > expand to,\n             / multiple rounding down, % multiple rounding up\nSIZE suffix: k=1024, m=1024^2, g=1024^3, t=1024^4, p=1024^5, e=1024^6"
 
 #define HELP_timeout "usage: timeout [-k DURATION] [-s SIGNAL] DURATION COMMAND...\n\nRun command line as a child process, sending child a signal if the\ncommand doesn't exit soon enough.\n\nDURATION can be a decimal fraction. An optional suffix can be \"m\"\n(minutes), \"h\" (hours), \"d\" (days), or \"s\" (seconds, the default).\n\n-s	Send specified signal (default TERM)\n-k	Send KILL signal if child still running this long after first signal\n-v	Verbose\n--foreground       Don't create new process group\n--preserve-status  Exit with the child's exit status"
@@ -178,7 +176,7 @@
 
 #define HELP_stat "usage: stat [-tfL] [-c FORMAT] FILE...\n\nDisplay status of files or filesystems.\n\n-c	Output specified FORMAT string instead of default\n-f	Display filesystem status instead of file status\n-L	Follow symlinks\n-t	terse (-c \"%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\")\n	      (with -f = -c \"%n %i %l %t %s %S %b %f %a %c %d\")\n\nThe valid format escape sequences for files:\n%a  Access bits (octal) |%A  Access bits (flags)|%b  Size/512\n%B  Bytes per %b (512)  |%C  Security context   |%d  Device ID (dec)\n%D  Device ID (hex)     |%f  All mode bits (hex)|%F  File type\n%g  Group ID            |%G  Group name         |%h  Hard links\n%i  Inode               |%m  Mount point        |%n  Filename\n%N  Long filename       |%o  I/O block size     |%s  Size (bytes)\n%t  Devtype major (hex) |%T  Devtype minor (hex)|%u  User ID\n%U  User name           |%x  Access time        |%X  Access unix time\n%y  Modification time   |%Y  Mod unix time      |%z  Creation time\n%Z  Creation unix time\n\nThe valid format escape sequences for filesystems:\n%a  Available blocks    |%b  Total blocks       |%c  Total inodes\n%d  Free inodes         |%f  Free blocks        |%i  File system ID\n%l  Max filename length |%n  File name          |%s  Best transfer size\n%S  Actual block size   |%t  FS type (hex)      |%T  FS type (driver name)"
 
-#define HELP_shred "usage: shred [-fuxz] [-n COUNT] [-o OFFSET] [-s SIZE] FILE...\n\nSecurely delete a file by overwriting its contents with random data.\n\n-f		Force (chmod if necessary)\n-n COUNT	Random overwrite iterations (default 1)\n-o OFFSET	Start at OFFSET\n-s SIZE		Use SIZE instead of detecting file size\n-u		Unlink (actually delete file when done)\n-x		Use exact size (default without -s rounds up to next 4k)\n-z		Zero at end\n\nNote: data journaling filesystems render this command useless, you must\noverwrite all free space (fill up disk) to erase old data on those."
+#define HELP_shred "usage: shred [-fuz] [-n COUNT] [-s SIZE] FILE...\n\nSecurely delete a file by overwriting its contents with random data.\n\n-f		Force (chmod if necessary)\n-n COUNT	Random overwrite iterations (default 1)\n-o OFFSET	Start at OFFSET\n-s SIZE		Use SIZE instead of detecting file size\n-u		Unlink (actually delete file when done)\n-x		Use exact size (default without -s rounds up to next 4k)\n-z		Zero at end\n\nNote: data journaling filesystems render this command useless, you must\noverwrite all free space (fill up disk) to erase old data on those."
 
 #define HELP_sha3sum "usage: sha3sum [-S] [-a BITS] [FILE...]\n\nHash function du jour.\n\n-a	Produce a hash BITS long (default 224)\n-b	Brief (hash only, no filename)\n-S	Use SHAKE termination byte instead of SHA3 (ask FIPS why)"
 
@@ -188,20 +186,18 @@
 
 #define HELP_rtcwake "usage: rtcwake [-aluv] [-d FILE] [-m MODE] [-s SECS] [-t UNIX]\n\nEnter the given sleep state until the given time.\n\n-a	RTC uses time specified in /etc/adjtime\n-d FILE	Device to use (default /dev/rtc)\n-l	RTC uses local time\n-m	Mode (--list-modes to see those supported by your kernel):\n	  standby  S1: default              mem     S3: suspend to RAM\n	  disk     S4: suspend to disk      off     S5: power off\n	  disable  Cancel current alarm     freeze  stop processes/processors\n	  no       just set wakeup time     on      just poll RTC for alarm\n	  show     just show current alarm\n-s SECS	Wake SECS seconds from now\n-t UNIX	Wake UNIX seconds from epoch\n-u	RTC uses UTC\n-v	Verbose"
 
-#define HELP_rmmod "usage: rmmod [-wf] MODULE...\n\nUnload the given kernel modules.\n\n-f	Force unload of a module\n-w	Wait until the module is no longer used"
+#define HELP_rmmod "usage: rmmod [-wf] [MODULE]\n\nUnload the module named MODULE from the Linux kernel.\n-f	Force unload of a module\n-w	Wait until the module is no longer used"
 
 #define HELP_rev "usage: rev [FILE...]\n\nOutput each line reversed, when no files are given stdin is used."
 
 #define HELP_reset "usage: reset\n\nReset the terminal."
 
-#define HELP_reboot "usage: reboot/halt/poweroff [-fn] [-d DELAY]\n\nRestart, halt, or power off the system.\n\n-d	Wait DELAY before proceeding (in seconds or m/h/d suffix: -d 1.5m = 90s)\n-f	Force reboot (don't signal init, reboot directly)\n-n	Don't sync filesystems before reboot"
+#define HELP_reboot "usage: reboot/halt/poweroff [-fn]\n\nRestart, halt or powerdown the system.\n\n-f	Don't signal init\n-n	Don't sync before stopping the system"
 
 #define HELP_realpath "usage: realpath FILE...\n\nDisplay the canonical absolute pathname"
 
 #define HELP_readlink "usage: readlink FILE...\n\nWith no options, show what symlink points to, return error if not symlink.\n\nOptions for producing canonical paths (all symlinks/./.. resolved):\n\n-e	Canonical path to existing entry (fail if missing)\n-f	Full path (fail if directory missing)\n-m	Ignore missing entries, show where it would be\n-n	No trailing newline\n-q	Quiet (no output, just error code)"
 
-#define HELP_readelf "usage: readelf [-adehlnSs] [-p SECTION] [-x SECTION] [file...]\n\nDisplays information about ELF files.\n\n-a	Equivalent to -dhlnSs\n-d	Show dynamic section\n-e	Headers (equivalent to -hlS)\n-h	Show ELF header\n-l	Show program headers\n-n	Show notes\n-p S	Dump strings found in named/numbered section\n-S	Show section headers\n-s	Show symbol tables (.dynsym and .symtab)\n-x S	Hex dump of named/numbered section\n\n--dyn-syms	Show just .dynsym symbol table"
-
 #define HELP_readahead "usage: readahead FILE...\n\nPreload files into disk cache."
 
 #define HELP_pwgen "usage: pwgen [-cAn0yrsBhC1v] [LENGTH] [COUNT]\n\nGenerate human-readable random passwords. When output is to tty produces\na screenfull to defeat shoulder surfing (pick one and clear the screen).\n\n-c  --capitalize                  Permit capital letters.\n-A  --no-capitalize               Don't include capital letters.\n-n  --numerals                    Permit numbers.\n-0  --no-numerals                 Don't include numbers.\n-y  --symbols                     Permit special characters ($#%...).\n-r <chars>  --remove=<chars>      Don't include the given characters.\n-s  --secure                      Generate more random passwords.\n-B  --ambiguous                   Avoid ambiguous characters (e.g. 0, O).\n-h  --help                        Print this help message.\n-C                                Print the output in columns.\n-1                                Print the output one line each.\n-v                                Don't include vowels."
@@ -210,18 +206,12 @@
 
 #define HELP_printenv "usage: printenv [-0] [env_var...]\n\nPrint environment variables.\n\n-0	Use \\0 as delimiter instead of \\n"
 
-#define HELP_pmap "usage: pmap [-pqx] PID...\n\nReport the memory map of a process or processes.\n\n-q	Show full paths\n-q	Do not show header or footer\n-x	Show the extended format"
+#define HELP_pmap "usage: pmap [-xq] [pids...]\n\nReport the memory map of a process or processes.\n\n-x	Show the extended format\n-q	Do not display some header/footer lines"
 
 #define HELP_pivot_root "usage: pivot_root OLD NEW\n\nSwap OLD and NEW filesystems (as if by simultaneous mount --move), and\nmove all processes with chdir or chroot under OLD into NEW (including\nkernel threads) so OLD may be unmounted.\n\nThe directory NEW must exist under OLD. This doesn't work on initramfs,\nwhich can't be moved (about the same way PID 1 can't be killed; see\nswitch_root instead)."
 
 #define HELP_partprobe "usage: partprobe DEVICE...\n\nTell the kernel about partition table changes\n\nAsk the kernel to re-read the partition table on the specified devices."
 
-#define HELP_deallocvt "usage: deallocvt [NUM]\n\nDeallocate unused virtual terminals, either a specific /dev/ttyNUM, or all."
-
-#define HELP_chvt "usage: chvt NUM\n\nChange to virtual terminal number NUM. (This only works in text mode.)\n\nVirtual terminals are the Linux VGA text mode (or framebuffer) displays,\nswitched between via alt-F1, alt-F2, etc. Use ctrl-alt-F1 to switch\nfrom X11 to a virtual terminal, and alt-F6 (or F7, or F8) to get back."
-
-#define HELP_openvt "usage: openvt [-c NUM] [-sw] COMMAND...\n\nRun COMMAND on a new virtual terminal.\n\n-c NUM  Use VT NUM\n-s    Switch to the new VT\n-w    Wait for command to exit (with -s, deallocates VT on exit)"
-
 #define HELP_oneit "usage: oneit [-prn3] [-c CONSOLE] [COMMAND...]\n\nSimple init program that runs a single supplied command line with a\ncontrolling tty (so CTRL-C can kill it).\n\n-c	Which console device to use (/dev/console doesn't do CTRL-C, etc)\n-p	Power off instead of rebooting when command exits\n-r	Restart child when it exits\n-n	No reboot, just relaunch command line\n-3	Write 32 bit PID of each exiting reparented process to fd 3 of child\n	(Blocking writes, child must read to avoid eventual deadlock.)\n\nSpawns a single child process (because PID 1 has signals blocked)\nin its own session, reaps zombies until the child exits, then\nreboots the system (or powers off with -p, or restarts the child with -r).\n\nResponds to SIGUSR1 by halting the system, SIGUSR2 by powering off,\nand SIGTERM or SIGINT reboot."
 
 #define HELP_nsenter "usage: nsenter [-t pid] [-F] [-i] [-m] [-n] [-p] [-u] [-U] COMMAND...\n\nRun COMMAND in an existing (set of) namespace(s).\n\n-t	PID to take namespaces from    (--target)\n-F	don't fork, even if -p is used (--no-fork)\n\nThe namespaces to switch are:\n\n-i	SysV IPC: message queues, semaphores, shared memory (--ipc)\n-m	Mount/unmount tree (--mount)\n-n	Network address, sockets, routing, iptables (--net)\n-p	Process IDs and init, will fork unless -F is used (--pid)\n-u	Host and domain names (--uts)\n-U	UIDs, GIDs, capabilities (--user)\n\nIf -t isn't specified, each namespace argument must provide a path\nto a namespace file, ala \"-i=/proc/$PID/ns/ipc\""
@@ -244,9 +234,11 @@
 
 #define HELP_makedevs "usage: makedevs [-d device_table] rootdir\n\nCreate a range of special files as specified in a device table.\n\n-d	File containing device table (default reads from stdin)\n\nEach line of the device table has the fields:\n<name> <type> <mode> <uid> <gid> <major> <minor> <start> <increment> <count>\nWhere name is the file name, and type is one of the following:\n\nb	Block device\nc	Character device\nd	Directory\nf	Regular file\np	Named pipe (fifo)\n\nOther fields specify permissions, user and group id owning the file,\nand additional fields for device special files. Use '-' for blank entries,\nunspecified fields are treated as '-'."
 
-#define HELP_lsusb "usage: lsusb [-i]\n\nList USB hosts/devices.\n\n-i	ID database (default /etc/usb.ids[.gz])"
+#define HELP_lsusb "usage: lsusb\n\nList USB hosts/devices."
 
-#define HELP_lspci "usage: lspci [-ekmn] [-i FILE]\n\nList PCI devices.\n\n-e  Extended (6 digit) class\n-i  ID database (default /etc/pci.ids[.gz])\n-k  Show kernel driver\n-m  Machine readable\n-n  Numeric output (-nn for both)"
+#define HELP_lspci_text "usage: lspci [-n] [-i FILE ]\n\n-n	Numeric output (repeat for readable and numeric)\n-i	PCI ID database (default /usr/share/misc/pci.ids)"
+
+#define HELP_lspci "usage: lspci [-ekm]\n\nList PCI devices.\n\n-e	Print all 6 digits in class\n-k	Print kernel driver\n-m	Machine readable format"
 
 #define HELP_lsmod "usage: lsmod\n\nDisplay the currently loaded modules, their sizes and their dependencies."
 
@@ -262,7 +254,7 @@
 
 #define HELP_ionice "usage: ionice [-t] [-c CLASS] [-n LEVEL] [COMMAND...|-p PID]\n\nChange the I/O scheduling priority of a process. With no arguments\n(or just -p), display process' existing I/O class/priority.\n\n-c	CLASS = 1-3: 1(realtime), 2(best-effort, default), 3(when-idle)\n-n	LEVEL = 0-7: (0 is highest priority, default = 5)\n-p	Affect existing PID instead of spawning new child\n-t	Ignore failure to set I/O priority\n\nSystem default iopriority is generally -c 2 -n 4."
 
-#define HELP_insmod "usage: insmod MODULE [OPTION...]\n\nLoad the module named MODULE passing options if given."
+#define HELP_insmod "usage: insmod MODULE [MODULE_OPTIONS]\n\nLoad the module named MODULE passing options if given."
 
 #define HELP_inotifyd "usage: inotifyd PROG FILE[:MASK] ...\n\nWhen a filesystem event matching MASK occurs to a FILE, run PROG as:\n\n  PROG EVENTS FILE [DIRFILE]\n\nIf PROG is \"-\" events are sent to stdout.\n\nThis file is:\n  a  accessed    c  modified    e  metadata change  w  closed (writable)\n  r  opened      D  deleted     M  moved            0  closed (unwritable)\n  u  unmounted   o  overflow    x  unwatchable\n\nA file in this directory is:\n  m  moved in    y  moved out   n  created          d  deleted\n\nWhen x event happens for all FILEs, inotifyd exits (after waiting for PROG)."
 
@@ -272,31 +264,21 @@
 
 #define HELP_i2cdump "usage: i2cdump [-fy] BUS CHIP\n\nDump i2c registers.\n\n-f	Force access to busy devices\n-y	Answer \"yes\" to confirmation prompts (for script use)"
 
-#define HELP_i2cdetect "usage: i2cdetect [-aqry] BUS [FIRST LAST]\nusage: i2cdetect -F BUS\nusage: i2cdetect -l\n\nDetect i2c devices.\n\n-a	All addresses (0x00-0x7f rather than 0x03-0x77 or FIRST-LAST)\n-F	Show functionality\n-l	List available buses\n-q	Probe with SMBus Quick Write (default)\n-r	Probe with SMBus Read Byte\n-y	Answer \"yes\" to confirmation prompts (for script use)"
+#define HELP_i2cdetect "usage: i2cdetect [-ary] BUS [FIRST LAST]\nusage: i2cdetect -F BUS\nusage: i2cdetect -l\n\nDetect i2c devices.\n\n-a	All addresses (0x00-0x7f rather than 0x03-0x77)\n-F	Show functionality\n-l	List all buses\n-r	Probe with SMBus Read Byte\n-y	Answer \"yes\" to confirmation prompts (for script use)"
 
 #define HELP_hwclock "usage: hwclock [-rswtluf]\n\nGet/set the hardware clock.\n\n-f FILE	Use specified device file instead of /dev/rtc0 (--rtc)\n-l	Hardware clock uses localtime (--localtime)\n-r	Show hardware clock time (--show)\n-s	Set system time from hardware clock (--hctosys)\n-t	Set the system time based on the current timezone (--systz)\n-u	Hardware clock uses UTC (--utc)\n-w	Set hardware clock from system time (--systohc)"
 
-#define HELP_hexedit "usage: hexedit FILE\n\nHexadecimal file editor/viewer. All changes are written to disk immediately.\n\n-r	Read only (display but don't edit)\n\nKeys:\nArrows         Move left/right/up/down by one line/column\nPgUp/PgDn      Move up/down by one page\nHome/End       Start/end of line (start/end of file with ctrl)\n0-9, a-f       Change current half-byte to hexadecimal value\n^J or :        Jump (+/- for relative offset, otherwise absolute address)\n^F or /        Find string (^G/n: next, ^D/p: previous match)\nu              Undo\nx              Toggle bw/color display\nq/^C/^Q/Esc    Quit"
+#define HELP_hexedit "usage: hexedit FILE\n\nHexadecimal file editor/viewer. All changes are written to disk immediately.\n\n-r	Read only (display but don't edit)\n\nKeys:\nArrows         Move left/right/up/down by one line/column\nPgUp/PgDn      Move up/down by one page\nHome/End       Start/end of line (start/end of file with ctrl)\n0-9, a-f       Change current half-byte to hexadecimal value\n^J or :        Jump (+/- for relative offset, otherwise absolute address)\n^F or /        Find string (^G/n: next, ^D/p: previous match)\nu              Undo\nq/^C/^Q/Esc    Quit"
 
 #define HELP_help "usage: help [-ahu] [COMMAND]\n\n-a	All commands\n-u	Usage only\n-h	HTML output\n\nShow usage information for toybox commands.\nRun \"toybox\" with no arguments for a list of available commands."
 
-#define HELP_gpioset "usage: gpioset [-l] CHIP LINE=VALUE...\n\nSet the lines on CHIP to the given values. Use gpiofind to convert line\nnames to numbers.\n\n-l	Active low"
-
-#define HELP_gpioget "usage: gpioget [-l] CHIP LINE...\n\nGets the values of the given lines on CHIP. Use gpiofind to convert line\nnames to numbers.\n\n-l	Active low"
-
-#define HELP_gpioinfo "usage: gpioinfo [CHIP...]\n\nShow gpio chips' lines."
-
-#define HELP_gpiofind "usage: gpiofind NAME\n\nShow the chip and line number for the given line name."
-
-#define HELP_gpiodetect "usage: gpiodetect\n\nShow all gpio chips' names, labels, and number of lines."
-
-#define HELP_fsync "usage: fsync [-d] [FILE...]\n\nFlush disk cache for FILE(s), writing cached data to storage device.\n\n-d	Skip directory info (sync file contents only)."
+#define HELP_fsync "usage: fsync [-d] [FILE...]\n\nSynchronize a file's in-core state with storage device.\n\n-d	Avoid syncing metadata"
 
 #define HELP_fsfreeze "usage: fsfreeze {-f | -u} MOUNTPOINT\n\nFreeze or unfreeze a filesystem.\n\n-f	Freeze\n-u	Unfreeze"
 
 #define HELP_freeramdisk "usage: freeramdisk [RAM device]\n\nFree all memory allocated to specified ramdisk"
 
-#define HELP_free "usage: free [-bkmgt]\n\nDisplay the total, free and used amount of physical memory and swap space.\n\n-bkmg	Output units (default is bytes)\n-h	Human readable (K=1024)"
+#define HELP_free "usage: free [-bkmgt]\n\nDisplay the total, free and used amount of physical memory and swap space.\n\n-bkmgt	Output units (default is bytes)\n-h	Human readable (K=1024)"
 
 #define HELP_fmt "usage: fmt [-w WIDTH] [FILE...]\n\nReformat input to wordwrap at a given line length, preserving existing\nindentation level, writing to stdout.\n\n-w WIDTH	Maximum characters per line (default 75)"
 
@@ -318,6 +300,8 @@
 
 #define HELP_clear "Clear the screen."
 
+#define HELP_chvt "usage: chvt N\n\nChange to virtual terminal number N. (This only works in text mode.)\n\nVirtual terminals are the Linux VGA text mode displays, ordinarily\nswitched between via alt-F1, alt-F2, etc. Use ctrl-alt-F1 to switch\nfrom X to a virtual terminal, and alt-F6 (or F7, or F8) to get back."
+
 #define HELP_chrt "usage: chrt [-Rmofrbi] {-p PID [PRIORITY] | [PRIORITY COMMAND...]}\n\nGet/set a process' real-time scheduling policy and priority.\n\n-p	Set/query given pid (instead of running COMMAND)\n-R	Set SCHED_RESET_ON_FORK\n-m	Show min/max priorities available\n\nSet policy (default -r):\n\n  -o  SCHED_OTHER    -f  SCHED_FIFO    -r  SCHED_RR\n  -b  SCHED_BATCH    -i  SCHED_IDLE"
 
 #define HELP_chroot "usage: chroot NEWROOT [COMMAND [ARG...]]\n\nRun command within a new root directory. If no command, run /bin/sh."
@@ -340,19 +324,13 @@
 
 #define HELP_base64 "usage: base64 [-di] [-w COLUMNS] [FILE...]\n\nEncode or decode in base64.\n\n-d	Decode\n-i	Ignore non-alphabetic characters\n-w	Wrap output at COLUMNS (default 76 or 0 for no wrap)"
 
-#define HELP_unicode "usage: unicode CODE[-END]...\n\nConvert between Unicode code points and UTF-8, in both directions.\nCODE can be one or more characters (show U+XXXX), hex numbers\n(show character), or dash separated range."
-
 #define HELP_ascii "usage: ascii\n\nDisplay ascii character set."
 
 #define HELP_acpi "usage: acpi [-abctV]\n\nShow status of power sources and thermal devices.\n\n-a	Show power adapters\n-b	Show batteries\n-c	Show cooling device state\n-t	Show temperatures\n-V	Show everything"
 
 #define HELP_xzcat "usage: xzcat [filename...]\n\nDecompress listed files to stdout. Use stdin if no files listed."
 
-#define HELP_wget_openssl "Enable HTTPS support for wget by linking to OpenSSL."
-
-#define HELP_wget_libtls "Enable HTTPS support for wget by linking to LibTLS.\nSupports using libtls, libretls or libtls-bearssl."
-
-#define HELP_wget "usage: wget [OPTIONS]... [URL]\n    --max-redirect          maximum redirections allowed\n-d, --debug                 print lots of debugging information\n-O, --output-document=FILE  specify output filename\n-p, --post-data=DATA        send data in body of POST request\n\nexamples:\n  wget http://www.example.com"
+#define HELP_wget "usage: wget -O filename URL\n-O filename: specify output filename\nURL: uniform resource location, FTP/HTTP only, not HTTPS\n\nexamples:\n  wget -O index.html http://www.example.com\n  wget -O sample.jpg ftp://ftp.example.com:21/sample.jpg"
 
 #define HELP_vi "usage: vi [-s script] FILE\n-s script: run script file\nVisual text editor. Predates the existence of standardized cursor keys,\nso the controls are weird and historical."
 
@@ -360,6 +338,8 @@
 
 #define HELP_useradd "usage: useradd [-SDH] [-h DIR] [-s SHELL] [-G GRP] [-g NAME] [-u UID] USER [GROUP]\n\nCreate new user, or add USER to GROUP\n\n-D       Don't assign a password\n-g NAME  Real name\n-G GRP   Add user to existing group\n-h DIR   Home directory\n-H       Don't create home directory\n-s SHELL Login shell\n-S       Create a system user\n-u UID   User id"
 
+#define HELP_unicode "usage: unicode [[min]-max]\n\nConvert between Unicode code points and UTF-8, in both directions."
+
 #define HELP_traceroute "usage: traceroute [-46FUIldnvr] [-f 1ST_TTL] [-m MAXTTL] [-p PORT] [-q PROBES]\n[-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-g GATEWAY] [-i IFACE] [-z PAUSE_MSEC] HOST [BYTES]\n\ntraceroute6 [-dnrv] [-m MAXTTL] [-p PORT] [-q PROBES][-s SRC_IP] [-t TOS] [-w WAIT_SEC]\n  [-i IFACE] HOST [BYTES]\n\nTrace the route to HOST\n\n-4,-6 Force IP or IPv6 name resolution\n-F    Set the don't fragment bit (supports IPV4 only)\n-U    Use UDP datagrams instead of ICMP ECHO (supports IPV4 only)\n-I    Use ICMP ECHO instead of UDP datagrams (supports IPV4 only)\n-l    Display the TTL value of the returned packet (supports IPV4 only)\n-d    Set SO_DEBUG options to socket\n-n    Print numeric addresses\n-v    verbose\n-r    Bypass routing tables, send directly to HOST\n-m    Max time-to-live (max number of hops)(RANGE 1 to 255)\n-p    Base UDP port number used in probes(default 33434)(RANGE 1 to 65535)\n-q    Number of probes per TTL (default 3)(RANGE 1 to 255)\n-s    IP address to use as the source address\n-t    Type-of-service in probe packets (default 0)(RANGE 0 to 255)\n-w    Time in seconds to wait for a response (default 3)(RANGE 0 to 86400)\n-g    Loose source route gateway (8 max) (supports IPV4 only)\n-z    Pause Time in ms (default 0)(RANGE 0 to 86400) (supports IPV4 only)\n-f    Start from the 1ST_TTL hop (instead from 1)(RANGE 1 to 255) (supports IPV4 only)\n-i    Specify a network interface to operate with"
 
 #define HELP_tr "usage: tr [-cds] SET1 [SET2]\n\nTranslate, squeeze, or delete characters from stdin, writing to stdout\n\n-c/-C  Take complement of SET1\n-d     Delete input characters coded SET1\n-s     Squeeze multiple output characters of SET2 into one character"
@@ -380,8 +360,6 @@
 
 #define HELP_stty "usage: stty [-ag] [-F device] SETTING...\n\nGet/set terminal configuration.\n\n-F	Open device instead of stdin\n-a	Show all current settings (default differences from \"sane\")\n-g	Show all current settings usable as input to stty\n\nSpecial characters (syntax ^c or undef): intr quit erase kill eof eol eol2\nswtch start stop susp rprnt werase lnext discard\n\nControl/input/output/local settings as shown by -a, '-' prefix to disable\n\nCombo settings: cooked/raw, evenp/oddp/parity, nl, ek, sane\n\nN	set input and output speed (ispeed N or ospeed N for just one)\ncols N	set number of columns\nrows N	set number of rows\nline N	set line discipline\nmin N	set minimum chars per read\ntime N	set read timeout\nspeed	show speed only\nsize	show size only"
 
-#define HELP_strace "usage: strace [-fv] [-p PID] [-s NUM] COMMAND [ARGS...]\n\nTrace systems calls made by a process.\n\n-s	String length limit.\n-v	Dump all of large structs/arrays."
-
 #define HELP_wait "usage: wait [-n] [ID...]\n\nWait for background processes to exit, returning its exit code.\nID can be PID or job, with no IDs waits for all backgrounded processes.\n\n-n	Wait for next process to exit"
 
 #define HELP_source "usage: source FILE [ARGS...]\n\nRead FILE and execute commands. Any ARGS become positional parameters."
@@ -404,17 +382,21 @@
 
 #define HELP_exit "usage: exit [status]\n\nExit shell.  If no return value supplied on command line, use value\nof most recent command, or 0 if none."
 
-#define HELP_declare "usage: declare [-pAailunxr] [NAME...]\n\nSet or print variable attributes and values.\n\n-p	Print variables instead of setting\n-A	Associative array\n-a	Indexed array\n-i	Integer\n-l	Lower case\n-n	Name reference (symlink)\n-r	Readonly\n-u	Uppercase\n-x	Export"
-
-#define HELP_cd "usage: cd [-PL] [-] [path]\n\nChange current directory. With no arguments, go $HOME. Sets $OLDPWD to\nprevious directory: cd - to return to $OLDPWD.\n\n-P	Physical path: resolve symlinks in path\n-L	Local path: .. trims directories off $PWD (default)"
+#define HELP_cd "usage: cd [-PL] [path]\n\nChange current directory.  With no arguments, go $HOME.\n\n-P	Physical path: resolve symlinks in path\n-L	Local path: .. trims directories off $PWD (default)"
 
 #define HELP_sh "usage: sh [-c command] [script]\n\nCommand shell.  Runs a shell script, or reads input interactively\nand responds to it.\n\n-c	command line to execute\n-i	interactive mode (default when STDIN is a tty)"
 
 #define HELP_route "usage: route [-ne] [-A [inet|inet6]] [add|del TARGET [OPTIONS]]\n\nDisplay, add or delete network routes in the \"Forwarding Information Base\",\nwhich send packets out a network interface to an address.\n\n-n	Show numerical addresses (no DNS lookups)\n-e	display netstat fields\n\nAssigning an address to an interface automatically creates an appropriate\nnetwork route (\"ifconfig eth0 10.0.2.15/8\" does \"route add 10.0.0.0/8 eth0\"\nfor you), although some devices (such as loopback) won't show it in the\ntable. For machines more than one hop away, you need to specify a gateway\n(ala \"route add default gw 10.0.2.2\").\n\nThe address \"default\" is a wildcard address (0.0.0.0/0) matching all\npackets without a more specific route.\n\nAvailable OPTIONS include:\nreject   - blocking route (force match failure)\ndev NAME - force matching packets out this interface (ala \"eth0\")\nnetmask  - old way of saying things like ADDR/24\ngw ADDR  - forward packets to gateway ADDR"
 
+#define HELP_readelf "usage: readelf [-adehlnSs] [-p SECTION] [-x SECTION] [file...]\n\nDisplays information about ELF files.\n\n-a	Equivalent to -dhlnSs\n-d	Show dynamic section\n-e	Headers (equivalent to -hlS)\n-h	Show ELF header\n-l	Show program headers\n-n	Show notes\n-p S	Dump strings found in named/numbered section\n-S	Show section headers\n-s	Show symbol tables (.dynsym and .symtab)\n-x S	Hex dump of named/numbered section\n\n--dyn-syms	Show just .dynsym symbol table"
+
+#define HELP_deallocvt "usage: deallocvt [NUM]\n\nDeallocate unused virtual terminals, either a specific /dev/ttyNUM, or all."
+
+#define HELP_openvt "usage: openvt [-c NUM] [-sw] [COMMAND...]\n\nStart a program on a new virtual terminal.\n\n-c NUM  Use VT NUM\n-s    Switch to new VT\n-w    Wait for command to exit\n\nTogether -sw switch back to originating VT when command completes."
+
 #define HELP_more "usage: more [FILE...]\n\nView FILE(s) (or stdin) one screenfull at a time."
 
-#define HELP_modprobe "usage: modprobe [-alrqvsDb] [-d DIR] MODULE [symbol=value][...]\n\nmodprobe utility - inserts modules and dependencies.\n\n-a  Load multiple MODULEs\n-b  Apply blacklist to module names too\n-D  Show dependencies\n-d  Load modules from DIR, option may be used multiple times\n-l  List (MODULE is a pattern)\n-q  Quiet\n-r  Remove MODULE (stacks) or do autoclean\n-s  Log to syslog\n-v  Verbose"
+#define HELP_modprobe "usage: modprobe [-alrqvsDb] [-d DIR] MODULE [symbol=value][...]\n\nmodprobe utility - inserts modules and dependencies.\n\n-a  Load multiple MODULEs\n-d  Load modules from DIR, option may be used multiple times\n-l  List (MODULE is a pattern)\n-r  Remove MODULE (stacks) or do autoclean\n-q  Quiet\n-v  Verbose\n-s  Log to syslog\n-D  Show dependencies\n-b  Apply blacklist to module names too"
 
 #define HELP_mke2fs_extended "usage: mke2fs [-E stride=###] [-O option[,option]]\n\n-E stride= Set RAID stripe size (in blocks)\n-O [opts]  Specify fewer ext2 option flags (for old kernels)\n           All of these are on by default (as appropriate)\n   none         Clear default options (all but journaling)\n   dir_index    Use htree indexes for large directories\n   filetype     Store file type info in directory entry\n   has_journal  Set by -j\n   journal_dev  Set by -J device=XXX\n   sparse_super Don't allocate huge numbers of redundant superblocks"
 
@@ -446,9 +428,7 @@
 
 #define HELP_init "usage: init\n\nSystem V style init.\n\nFirst program to run (as PID 1) when the system comes up, reading\n/etc/inittab to determine actions."
 
-#define HELP_hd "usage: hd [FILE...]\n\nDisplay file(s) in cannonical hex+ASCII format."
-
-#define HELP_hexdump "usage: hexdump [-bcCdovx] [-n LEN] [-s SKIP] [FILE...]\n\nDump file(s) in hexadecimal format.\n\n-n LEN	Show LEN bytes of output\n-s SKIP	Skip bytes of input\n-v	Verbose (don't combine identical lines)\n\nDisplay type:\n-b One byte octal   -c One byte character -C Canonical (hex + ASCII)\n-d Two byte decimal -o Two byte octal     -x Two byte hexadecimal (default)"
+#define HELP_host "usage: host [-av] [-t TYPE] NAME [SERVER]\n\nPerform DNS lookup on NAME, which can be a domain name to lookup,\nor an IPv4 dotted or IPv6 colon-separated address to reverse lookup.\nSERVER (if present) is the DNS server to use.\n\n-a	-v -t ANY\n-t TYPE	query records of type TYPE\n-v	verbose"
 
 #define HELP_groupdel "usage: groupdel [USER] GROUP\n\nDelete a group or remove a user from a group"
 
@@ -494,7 +474,7 @@
 
 #define HELP_arping "usage: arping [-fqbDUA] [-c CNT] [-w TIMEOUT] [-I IFACE] [-s SRC_IP] DST_IP\n\nSend ARP requests/replies\n\n-f         Quit on first ARP reply\n-q         Quiet\n-b         Keep broadcasting, don't go unicast\n-D         Duplicated address detection mode\n-U         Unsolicited ARP mode, update your neighbors\n-A         ARP answer mode, update your neighbors\n-c N       Stop after sending N ARP requests\n-w TIMEOUT Time to wait for ARP reply, seconds\n-I IFACE   Interface to use (default eth0)\n-s SRC_IP  Sender IP address\nDST_IP     Target IP address"
 
-#define HELP_arp "usage: arp\n[-vn] [-H HWTYPE] [-i IF] -a [HOSTNAME]\n[-v]              [-i IF] -d HOSTNAME [pub]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub\n[-v]  [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub\n\nManipulate ARP cache.\n\n-a	Display (all) hosts\n-s	Set new ARP entry\n-d	Delete a specified entry\n-v	Verbose\n-n	Don't resolve names\n-i IFACE	Network interface\n-D	Read <hwaddr> from given device\n-A,-p AF	Protocol family\n-H HWTYPE	Hardware address type"
+#define HELP_arp "usage: arp\n[-vn] [-H HWTYPE] [-i IF] -a [HOSTNAME]\n[-v]              [-i IF] -d HOSTNAME [pub]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub\n[-v]  [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub\n\nManipulate ARP cache\n\n-a    Display (all) hosts\n-s    Set new ARP entry\n-d    Delete a specified entry\n-v    Verbose\n-n    Don't resolve names\n-i IF Network interface\n-D    Read <hwaddr> from given device\n-A,-p AF  Protocol family\n-H    HWTYPE Hardware address type"
 
 #define HELP_xargs "usage: xargs [-0prt] [-snE STR] COMMAND...\n\nRun command line one or more times, appending arguments from stdin.\n\nIf COMMAND exits with 255, don't launch another even if arguments remain.\n\n-0	Each argument is NULL terminated, no whitespace or quote processing\n-E	Stop at line matching string\n-n	Max number of arguments per command\n-o	Open tty for COMMAND's stdin (default /dev/null)\n-p	Prompt for y/n from tty before running each command\n-P	Parallel processes (default 1)\n-r	Don't run with empty input (otherwise always run command once)\n-s	Size in bytes per command line\n-t	Trace, print command line to stderr"
 
@@ -510,33 +490,31 @@
 
 #define HELP_uniq "usage: uniq [-cduiz] [-w MAXCHARS] [-f FIELDS] [-s CHAR] [INFILE [OUTFILE]]\n\nReport or filter out repeated lines in a file\n\n-c	Show counts before each line\n-d	Show only lines that are repeated\n-u	Show only lines that are unique\n-i	Ignore case when comparing lines\n-z	Lines end with \\0 not \\n\n-w	Compare maximum X chars per line\n-f	Ignore first X fields\n-s	Ignore first X chars"
 
-#define HELP_uname "usage: uname [-asnrvm]\n\nPrint system information.\n\n-s	System name\n-n	Network (domain) name\n-r	Kernel Release number\n-v	Kernel Version\n-m	Machine (hardware) name\n-o	Userspace type\n-a	All of the above (in order)"
-
-#define HELP_linux32 "usage: linux32 [COMMAND...]\n\nTell uname -m to line to autoconf (to build 32 bit binaries on 64 bit kernel)."
+#define HELP_uname "usage: uname [-asnrvm]\n\nPrint system information.\n\n-s	System name\n-n	Network (domain) name\n-r	Kernel Release number\n-v	Kernel Version\n-m	Machine (hardware) name\n-a	All of the above"
 
 #define HELP_arch "usage: arch\n\nPrint machine (hardware) name, same as uname -m."
 
 #define HELP_ulimit "usage: ulimit [-P PID] [-SHRacdefilmnpqrstuv] [LIMIT]\n\nPrint or set resource limits for process number PID. If no LIMIT specified\n(or read-only -ap selected) display current value (sizes in bytes).\nDefault is ulimit -P $PPID -Sf\" (show soft filesize of your shell).\n\n-P  PID to affect (default $PPID)  -a  Show all limits\n-S  Set/show soft limit            -H  Set/show hard (maximum) limit\n\n-c  Core file size (blocks)        -d  Process data segment (KiB)\n-e  Max scheduling priority        -f  File size (KiB)\n-i  Pending signal count           -l  Locked memory (KiB)\n-m  Resident Set Size (KiB)        -n  Number of open files\n-p  Pipe buffer (512 bytes)        -q  POSIX message queues\n-r  Max realtime priority          -R  Realtime latency (us)\n-s  Stack size (KiB)               -t  Total CPU time (s)\n-u  Maximum processes (this UID)   -v  Virtual memory size (KiB)"
 
-#define HELP_tty "usage: tty [-s]\n\nShow filename of terminal connected to stdin. If none print \"not a tty\"\nand exit with nonzero status.\n\n-s	Silent, exit code only"
+#define HELP_tty "usage: tty [-s]\n\nShow filename of terminal connected to stdin.\n\nPrints \"not a tty\" and exits with nonzero status if no terminal\nis connected to stdin.\n\n-s	Silent, exit code only"
 
 #define HELP_true "usage: true\n\nReturn zero."
 
 #define HELP_touch "usage: touch [-amch] [-d DATE] [-t TIME] [-r FILE] FILE...\n\nUpdate the access and modification times of each FILE to the current time.\n\n-a	Change access time\n-m	Change modification time\n-c	Don't create file\n-h	Change symlink\n-d	Set time to DATE (in YYYY-MM-DDThh:mm:SS[.frac][tz] format)\n-t	Set time to TIME (in [[CC]YY]MMDDhhmm[.ss][frac] format)\n-r	Set time same as reference FILE"
 
-#define HELP_time "usage: time [-pv] COMMAND...\n\nRun command line and report real, user, and system time elapsed in seconds.\n(real = clock on the wall, user = cpu used by command's code,\nsystem = cpu used by OS on behalf of command.)\n\n-p	POSIX format output\n-v	Verbose"
+#define HELP_time "usage: time [-pv] COMMAND...\n\nRun command line and report real, user, and system time elapsed in seconds.\n(real = clock on the wall, user = cpu used by command's code,\nsystem = cpu used by OS on behalf of command.)\n\n-p	POSIX format output (default)\n-v	Verbose"
 
 #define HELP_test "usage: test [-bcdefghLPrSsuwx PATH] [-nz STRING] [-t FD] [X ?? Y]\n\nReturn true or false by performing tests. (With no arguments return false.)\n\n--- Tests with a single argument (after the option):\nPATH is/has:\n  -b  block device   -f  regular file   -p  fifo           -u  setuid bit\n  -c  char device    -g  setgid         -r  read bit       -w  write bit\n  -d  directory      -h  symlink        -S  socket         -x  execute bit\n  -e  exists         -L  symlink        -s  nonzero size   -k  sticky bit\nSTRING is:\n  -n  nonzero size   -z  zero size      (STRING by itself implies -n)\nFD (integer file descriptor) is:\n  -t  a TTY\n\n--- Tests with one argument on each side of an operator:\nTwo strings:\n  =  are identical   !=  differ\n\nTwo integers:\n  -eq  equal         -gt  first > second    -lt  first < second\n  -ne  not equal     -ge  first >= second   -le  first <= second\n\n--- Modify or combine tests:\n  ! EXPR     not (swap true/false)   EXPR -a EXPR    and (are both true)\n  ( EXPR )   evaluate this first     EXPR -o EXPR    or (is either true)"
 
 #define HELP_tee "usage: tee [-ai] [FILE...]\n\nCopy stdin to each listed file, and also to stdout.\nFilename \"-\" is a synonym for stdout.\n\n-a	Append to files\n-i	Ignore SIGINT"
 
-#define HELP_tar "usage: tar [-cxt] [-fvohmjkOS] [-XTCf NAME] [--selinux] [FILE...]\n\nCreate, extract, or list files in a .tar (or compressed t?z) file.\n\nOptions:\nc  Create                x  Extract               t  Test (list)\nf  tar FILE (default -)  C  Change to DIR first   v  Verbose display\no  Ignore owner          h  Follow symlinks       m  Ignore mtime\nJ  xz compression        j  bzip2 compression     z  gzip compression\nO  Extract to stdout     X  exclude names in FILE T  include names in FILE\n\n--exclude        FILENAME to exclude  --full-time         Show seconds with -tv\n--mode MODE      Adjust permissions   --owner NAME[:UID]  Set file ownership\n--mtime TIME     Override timestamps  --group NAME[:GID]  Set file group\n--sparse         Record sparse files  --selinux           Save/restore labels\n--restrict       All under one dir    --no-recursion      Skip dir contents\n--numeric-owner  Use numeric uid/gid, not user/group names\n--strip-components NUM  Ignore first NUM directory components when extracting\n-I PROG          Filter through PROG to compress or PROG -d to decompress"
+#define HELP_tar "usage: tar [-cxt] [-fvohmjkOS] [-XTCf NAME] [FILE...]\n\nCreate, extract, or list files in a .tar (or compressed t?z) file.\n\nOptions:\nc  Create                x  Extract               t  Test (list)\nf  tar FILE (default -)  C  Change to DIR first   v  Verbose display\no  Ignore owner          h  Follow symlinks       m  Ignore mtime\nJ  xz compression        j  bzip2 compression     z  gzip compression\nO  Extract to stdout     X  exclude names in FILE T  include names in FILE\n\n--exclude        FILENAME to exclude    --full-time   Show seconds with -tv\n--mode MODE      Adjust modes           --mtime TIME  Override timestamps\n--owner NAME     Set file owner to NAME --group NAME  Set file group to NAME\n--sparse         Record sparse files\n--restrict       All archive contents must extract under one subdirectory\n--numeric-owner  Save/use/display uid and gid, not user/group name\n--no-recursion   Don't store directory contents\n-I PROG          Filter through PROG to compress or PROG -d to decompress"
 
-#define HELP_tail "usage: tail [-n|c NUMBER] [-f|F] [-s SECONDS] [FILE...]\n\nCopy last lines from files to stdout. If no files listed, copy from\nstdin. Filename \"-\" is a synonym for stdin.\n\n-n	Output the last NUMBER lines (default 10), +X counts from start\n-c	Output the last NUMBER bytes, +NUMBER counts from start\n-f	Follow FILE(s) by descriptor, waiting for more data to be appended\n-F	Follow FILE(s) by filename, waiting for more data, and retrying\n-s	Used with -F, sleep SECONDS between retries (default 1)"
+#define HELP_tail "usage: tail [-n|c NUMBER] [-f] [FILE...]\n\nCopy last lines from files to stdout. If no files listed, copy from\nstdin. Filename \"-\" is a synonym for stdin.\n\n-n	Output the last NUMBER lines (default 10), +X counts from start\n-c	Output the last NUMBER bytes, +NUMBER counts from start\n-f	Follow FILE(s), waiting for more data to be appended"
 
 #define HELP_strings "usage: strings [-fo] [-t oxd] [-n LEN] [FILE...]\n\nDisplay printable strings in a binary file\n\n-f	Show filename\n-n	At least LEN characters form a string (default 4)\n-o	Show offset (ala -t d)\n-t	Show offset type (o=octal, d=decimal, x=hexadecimal)"
 
-#define HELP_split "usage: split [-a SUFFIX_LEN] [-b BYTES] [-l LINES] [-n PARTS] [INPUT [OUTPUT]]\n\nCopy INPUT (or stdin) data to a series of OUTPUT (or \"x\") files with\nalphabetically increasing suffix (aa, ab, ac... az, ba, bb...).\n\n-a	Suffix length (default 2)\n-b	BYTES/file (10, 10k, 10m, 10g...)\n-l	LINES/file (default 1000)\n-n	PARTS many equal length files"
+#define HELP_split "usage: split [-a SUFFIX_LEN] [-b BYTES] [-l LINES] [INPUT [OUTPUT]]\n\nCopy INPUT (or stdin) data to a series of OUTPUT (or \"x\") files with\nalphabetically increasing suffix (aa, ab, ac... az, ba, bb...).\n\n-a	Suffix length (default 2)\n-b	BYTES/file (10, 10k, 10m, 10g...)\n-l	LINES/file (default 1000)"
 
 #define HELP_sort "usage: sort [-Mbcdfginrsuz] [FILE...] [-k#[,#[x]] [-t X]] [-o FILE]\n\nSort all lines of text from input files (or stdin) to stdout.\n-M	Month sort (jan, feb, etc)\n-V	Version numbers (name-1.234-rc6.5b.tgz)\n-b	Ignore leading blanks (or trailing blanks in second part of key)\n-c	Check whether input is sorted\n-d	Dictionary order (use alphanumeric and whitespace chars only)\n-f	Force uppercase (case insensitive sort)\n-g	General numeric sort (double precision with nan and inf)\n-i	Ignore nonprinting characters\n-k	Sort by \"key\" (see below)\n-n	Numeric order (instead of alphabetical)\n-o	Output to FILE instead of stdout\n-r	Reverse\n-s	Skip fallback sort (only sort with keys)\n-t	Use a key separator other than whitespace\n-u	Unique lines only\n-x	Hexadecimal numerical sort\n-z	Zero (null) terminated lines\n\nSorting by key looks at a subset of the words on each line. -k2 uses the\nsecond word to the end of the line, -k2,2 looks at only the second word,\n-k2,4 looks from the start of the second to the end of the fourth word.\n-k2.4,5 starts from the fourth character of the second word, to the end\nof the fifth word. Specifying multiple keys uses the later keys as tie\nbreakers, in order. A type specifier appended to a sort key (such as -2,2n)\napplies only to sorting that key."
 
@@ -558,13 +536,13 @@
 
 #define HELP_iotop "usage: iotop [-AaKObq] [-n NUMBER] [-d SECONDS] [-p PID,] [-u USER,]\n\nRank processes by I/O.\n\n-A	All I/O, not just disk\n-a	Accumulated I/O (not percentage)\n-H	Show threads\n-K	Kilobytes\n-k	Fallback sort FIELDS (default -[D]IO,-ETIME,-PID)\n-m	Maximum number of tasks to show\n-O	Only show processes doing I/O\n-o	Show FIELDS (default PID,PR,USER,[D]READ,[D]WRITE,SWAP,[D]IO,COMM)\n-s	Sort by field number (0-X, default 6)\n-b	Batch mode (no tty)\n-d	Delay SECONDS between each cycle (default 3)\n-n	Exit after NUMBER iterations\n-p	Show these PIDs\n-u	Show these USERs\n-q	Quiet (no header lines)\n\nCursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force\nupdate, R to reverse sort, Q to exit."
 
-#define HELP_top "usage: top [-Hhbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]\n\nShow process activity in real time.\n\n-H	Show threads\n-h	Usage graphs instead of text\n-k	Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)\n-o	Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)\n-O	Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)\n-s	Sort by field number (1-X, default 9)\n-b	Batch mode (no tty)\n-d	Delay SECONDS between each cycle (default 3)\n-m	Maximum number of tasks to show\n-n	Exit after NUMBER iterations\n-p	Show these PIDs\n-u	Show these USERs\n-q	Quiet (no header lines)\n\nCursor UP/DOWN or LEFT/RIGHT to move list, SHIFT LEFT/RIGHT to change sort,\nspace to force update, R to reverse sort, Q to exit."
+#define HELP_top "usage: top [-Hbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]\n\nShow process activity in real time.\n\n-H	Show threads\n-k	Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)\n-o	Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)\n-O	Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)\n-s	Sort by field number (1-X, default 9)\n-b	Batch mode (no tty)\n-d	Delay SECONDS between each cycle (default 3)\n-m	Maximum number of tasks to show\n-n	Exit after NUMBER iterations\n-p	Show these PIDs\n-u	Show these USERs\n-q	Quiet (no header lines)\n\nCursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force\nupdate, R to reverse sort, Q to exit."
 
 #define HELP_ps "usage: ps [-AadefLlnwZ] [-gG GROUP,] [-k FIELD,] [-o FIELD,] [-p PID,] [-t TTY,] [-uU USER,]\n\nList processes.\n\nWhich processes to show (-gGuUpPt selections may be comma separated lists):\n\n-A  All					-a  Has terminal not session leader\n-d  All but session leaders		-e  Synonym for -A\n-g  In GROUPs				-G  In real GROUPs (before sgid)\n-p  PIDs (--pid)			-P  Parent PIDs (--ppid)\n-s  In session IDs			-t  Attached to selected TTYs\n-T  Show threads also			-u  Owned by selected USERs\n-U  Real USERs (before suid)\n\nOutput modifiers:\n\n-k  Sort FIELDs (-FIELD to reverse)	-M  Measure/pad future field widths\n-n  Show numeric USER and GROUP		-w  Wide output (don't truncate fields)\n\nWhich FIELDs to show. (-o HELP for list, default = -o PID,TTY,TIME,CMD)\n\n-f  Full listing (-o USER:12=UID,PID,PPID,C,STIME,TTY,TIME,ARGS=CMD)\n-l  Long listing (-o F,S,UID,PID,PPID,C,PRI,NI,ADDR,SZ,WCHAN,TTY,TIME,CMD)\n-o  Output FIELDs instead of defaults, each with optional :size and =title\n-O  Add FIELDS to defaults\n-Z  Include LABEL"
 
 #define HELP_printf "usage: printf FORMAT [ARGUMENT...]\n\nFormat and print ARGUMENT(s) according to FORMAT, using C printf syntax\n(% escapes for cdeEfgGiosuxX, \\ escapes for abefnrtv0 or \\OCTAL or \\xHEX)."
 
-#define HELP_patch "usage: patch [-Rlsu] [-d DIR] [-i PATCH] [-p DEPTH] [-F FUZZ] [--dry-run] [FILE [PATCH]]\n\nApply a unified diff to one or more files.\n\n-d	Modify files in DIR\n-i	Input patch file (default=stdin)\n-l	Loose match (ignore whitespace)\n-p	Number of '/' to strip from start of file paths (default=all)\n-R	Reverse patch\n-s	Silent except for errors\n-u	Ignored (only handles \"unified\" diffs)\n--dry-run Don't change files, just confirm patch applies\n\nThis version of patch only handles unified diffs, and only modifies\na file when all hunks to that file apply. Patch prints failed hunks\nto stderr, and exits with nonzero status if any hunks fail.\n\nA file compared against /dev/null (or with a date <= the epoch) is\ncreated/deleted as appropriate."
+#define HELP_patch "usage: patch [-d DIR] [-i PATCH] [-p DEPTH] [-F FUZZ] [-Rlsu] [--dry-run] [FILE [PATCH]]\n\nApply a unified diff to one or more files.\n\n-d	Modify files in DIR\n-i	Input patch file (default=stdin)\n-l	Loose match (ignore whitespace)\n-p	Number of '/' to strip from start of file paths (default=all)\n-R	Reverse patch\n-s	Silent except for errors\n-u	Ignored (only handles \"unified\" diffs)\n--dry-run Don't change files, just confirm patch applies\n\nThis version of patch only handles unified diffs, and only modifies\na file when all hunks to that file apply. Patch prints failed hunks\nto stderr, and exits with nonzero status if any hunks fail.\n\nA file compared against /dev/null (or with a date <= the epoch) is\ncreated/deleted as appropriate."
 
 #define HELP_paste "usage: paste [-s] [-d DELIMITERS] [FILE...]\n\nMerge corresponding lines from each input file.\n\n-d	List of delimiter characters to separate fields with (default is \\t)\n-s	Sequential mode: turn each input file into one line of output"
 
@@ -610,11 +588,11 @@
 
 #define HELP_head "usage: head [-n NUM] [FILE...]\n\nCopy first lines from files to stdout. If no files listed, copy from\nstdin. Filename \"-\" is a synonym for stdin.\n\n-n	Number of lines to copy\n-c	Number of bytes to copy\n-q	Never print headers\n-v	Always print headers"
 
-#define HELP_grep "usage: grep [-EFrivwcloqsHbhn] [-ABC NUM] [-m MAX] [-e REGEX]... [-MS PATTERN]... [-f REGFILE] [FILE]...\n\nShow lines matching regular expressions. If no -e, first argument is\nregular expression to match. With no files (or \"-\" filename) read stdin.\nReturns 0 if matched, 1 if no match found, 2 for command errors.\n\n-e  Regex to match. (May be repeated.)\n-f  File listing regular expressions to match.\n\nfile search:\n-r  Recurse into subdirectories (defaults FILE to \".\")\n-R  Recurse into subdirectories and symlinks to directories\n-M  Match filename pattern (--include)\n-S  Skip filename pattern (--exclude)\n--exclude-dir=PATTERN  Skip directory pattern\n-I  Ignore binary files\n\nmatch type:\n-A  Show NUM lines after     -B  Show NUM lines before match\n-C  NUM lines context (A+B)  -E  extended regex syntax\n-F  fixed (literal match)    -a  always text (not binary)\n-i  case insensitive         -m  match MAX many lines\n-v  invert match             -w  whole word (implies -E)\n-x  whole line               -z  input NUL terminated\n\ndisplay modes: (default: matched line)\n-L  filenames with no match  -Z  output is NUL terminated\n-c  count of matching lines  -l  filenames with a match\n-o  only matching part       -q  quiet (errors only)\n-s  silent (no error msg)\n\noutput prefix (default: filename if checking more than 1 file)\n-H  force filename           -b  byte offset of match\n-h  hide filename            -n  line number of match"
+#define HELP_grep "usage: grep [-EFrivwcloqsHbhn] [-ABC NUM] [-m MAX] [-e REGEX]... [-MS PATTERN]... [-f REGFILE] [FILE]...\n\nShow lines matching regular expressions. If no -e, first argument is\nregular expression to match. With no files (or \"-\" filename) read stdin.\nReturns 0 if matched, 1 if no match found, 2 for command errors.\n\n-e  Regex to match. (May be repeated.)\n-f  File listing regular expressions to match.\n\nfile search:\n-r  Recurse into subdirectories (defaults FILE to \".\")\n-R  Recurse into subdirectories and symlinks to directories\n-M  Match filename pattern (--include)\n-S  Skip filename pattern (--exclude)\n--exclude-dir=PATTERN  Skip directory pattern\n-I  Ignore binary files\n\nmatch type:\n-A  Show NUM lines after     -B  Show NUM lines before match\n-C  NUM lines context (A+B)  -E  extended regex syntax\n-F  fixed (literal match)    -a  always text (not binary)\n-i  case insensitive         -m  match MAX many lines\n-v  invert match             -w  whole word (implies -E)\n-x  whole line               -z  input NUL terminated\n\ndisplay modes: (default: matched line)\n-c  count of matching lines  -l  show only matching filenames\n-o  only matching part       -q  quiet (errors only)\n-s  silent (no error msg)    -Z  output NUL terminated\n\noutput prefix (default: filename if checking more than 1 file)\n-H  force filename           -b  byte offset of match\n-h  hide filename            -n  line number of match"
 
 #define HELP_getconf "usage: getconf -a [PATH] | -l | NAME [PATH]\n\nGet system configuration values. Values from pathconf(3) require a path.\n\n-a	Show all (defaults to \"/\" if no path given)\n-l	List available value names (grouped by source)"
 
-#define HELP_find "usage: find [-HL] [DIR...] [<options>]\n\nSearch directories for matching files.\nDefault: search \".\", match all, -print matches.\n\n-H  Follow command line symlinks         -L  Follow all symlinks\n\nMatch filters:\n-name  PATTERN   filename with wildcards   -iname      ignore case -name\n-path  PATTERN   path name with wildcards  -ipath      ignore case -path\n-user  UNAME     belongs to user UNAME     -nouser     user ID not known\n-group GROUP     belongs to group GROUP    -nogroup    group ID not known\n-perm  [-/]MODE  permissions (-=min /=any) -prune      ignore dir contents\n-size  N[c]      512 byte blocks (c=bytes) -xdev       only this filesystem\n-links N         hardlink count            -atime N[u] accessed N units ago\n-ctime N[u]      created N units ago       -mtime N[u] modified N units ago\n-inum N          inode number N            -empty      empty files and dirs\n-true            always true               -false      always false\n-context PATTERN security context          -executable access(X_OK) perm+ACL\n-samefile FILE   hardlink to FILE          -quit       exit immediately\n-depth           ignore contents of dir    -maxdepth N at most N dirs down\n-newer FILE      newer mtime than FILE     -mindepth N at least N dirs down\n-newerXY FILE    X=acm time > FILE's Y=acm time (Y=t: FILE is literal time)\n-type [bcdflps]  type is (block, char, dir, file, symlink, pipe, socket)\n\nNumbers N may be prefixed by a - (less than) or + (greater than). Units for\n-Xtime are d (days, default), h (hours), m (minutes), or s (seconds).\n\nCombine matches with:\n!, -a, -o, ( )    not, and, or, group expressions\n\nActions:\n-print  Print match with newline  -print0        Print match with null\n-exec   Run command with path     -execdir       Run command in file's dir\n-ok     Ask before exec           -okdir         Ask before execdir\n-delete Remove matching file/dir  -printf FORMAT Print using format string\n\nCommands substitute \"{}\" with matched file. End with \";\" to run each file,\nor \"+\" (next argument after \"{}\") to collect and run with multiple files.\n\n-printf FORMAT characters are \\ escapes and:\n%b  512 byte blocks used\n%f  basename            %g  textual gid          %G  numeric gid\n%i  decimal inode       %l  target of symlink    %m  octal mode\n%M  ls format type/mode %p  path to file         %P  path to file minus DIR\n%s  size in bytes       %T@ mod time as unixtime\n%u  username            %U  numeric uid          %Z  security context"
+#define HELP_find "usage: find [-HL] [DIR...] [<options>]\n\nSearch directories for matching files.\nDefault: search \".\", match all, -print matches.\n\n-H  Follow command line symlinks         -L  Follow all symlinks\n\nMatch filters:\n-name  PATTERN   filename with wildcards  (-iname case insensitive)\n-path  PATTERN   path name with wildcards (-ipath case insensitive)\n-user  UNAME     belongs to user UNAME     -nouser     user ID not known\n-group GROUP     belongs to group GROUP    -nogroup    group ID not known\n-perm  [-/]MODE  permissions (-=min /=any) -prune      ignore dir contents\n-size  N[c]      512 byte blocks (c=bytes) -xdev       only this filesystem\n-links N         hardlink count            -atime N[u] accessed N units ago\n-ctime N[u]      created N units ago       -mtime N[u] modified N units ago\n-newer FILE      newer mtime than FILE     -mindepth N at least N dirs down\n-depth           ignore contents of dir    -maxdepth N at most N dirs down\n-inum N          inode number N            -empty      empty files and dirs\n-type [bcdflps]  type is (block, char, dir, file, symlink, pipe, socket)\n-true            always true               -false      always false\n-context PATTERN security context          -executable access(X_OK) perm+ACL\n-newerXY FILE    X=acm time > FILE's Y=acm time (Y=t: FILE is literal time)\n\nNumbers N may be prefixed by a - (less than) or + (greater than). Units for\n-Xtime are d (days, default), h (hours), m (minutes), or s (seconds).\n\nCombine matches with:\n!, -a, -o, ( )    not, and, or, group expressions\n\nActions:\n-print  Print match with newline  -print0        Print match with null\n-exec   Run command with path     -execdir       Run command in file's dir\n-ok     Ask before exec           -okdir         Ask before execdir\n-delete Remove matching file/dir  -printf FORMAT Print using format string\n\nCommands substitute \"{}\" with matched file. End with \";\" to run each file,\nor \"+\" (next argument after \"{}\") to collect and run with multiple files.\n\n-printf FORMAT characters are \\ escapes and:\n%b  512 byte blocks used\n%f  basename            %g  textual gid          %G  numeric gid\n%i  decimal inode       %l  target of symlink    %m  octal mode\n%M  ls format type/mode %p  path to file         %P  path to file minus DIR\n%s  size in bytes       %T@ mod time as unixtime\n%u  username            %U  numeric uid          %Z  security context"
 
 #define HELP_file "usage: file [-bhLs] [FILE...]\n\nExamine the given files and describe their content types.\n\n-b	Brief (no filename)\n-h	Don't follow symlinks (default)\n-L	Follow symlinks\n-s	Show block/char device contents"
 
@@ -624,7 +602,7 @@
 
 #define HELP_env "usage: env [-i] [-u NAME] [NAME=VALUE...] [COMMAND...]\n\nSet the environment for command invocation, or list environment variables.\n\n-i	Clear existing environment\n-u NAME	Remove NAME from the environment\n-0	Use null instead of newline in output"
 
-#define HELP_echo "usage: echo [-neE] [ARG...]\n\nWrite each argument to stdout, one space between each, followed by a newline.\n\n-n	No trailing newline\n-E	Print escape sequences literally (default)\n-e	Process the following escape sequences:\n	\\\\  Backslash		\\0NNN Octal (1-3 digit)	\\xHH Hex (1-2 digit)\n	\\a  Alert (beep/flash)	\\b  Backspace		\\c  Stop here (no \\n)\n	\\f  Form feed		\\n  Newline		\\r  Carriage return\n	\\t  Horizontal tab	\\v  Vertical tab"
+#define HELP_echo "usage: echo [-neE] [ARG...]\n\nWrite each argument to stdout, with one space between each, followed\nby a newline.\n\n-n	No trailing newline\n-E	Print escape sequences literally (default)\n-e	Process the following escape sequences:\n	\\\\	Backslash\n	\\0NNN	Octal values (1 to 3 digits)\n	\\a	Alert (beep/flash)\n	\\b	Backspace\n	\\c	Stop output here (avoids trailing newline)\n	\\f	Form feed\n	\\n	Newline\n	\\r	Carriage return\n	\\t	Horizontal tab\n	\\v	Vertical tab\n	\\xHH	Hexadecimal values (1 to 2 digits)"
 
 #define HELP_du "usage: du [-d N] [-askxHLlmc] [FILE...]\n\nShow disk usage, space consumed by files and directories.\n\nSize in:\n-b	Apparent bytes (directory listing size, not space used)\n-k	1024 byte blocks (default)\n-K	512 byte blocks (posix)\n-m	Megabytes\n-h	Human readable (e.g., 1K 243M 2G)\n\nWhat to show:\n-a	All files, not just directories\n-H	Follow symlinks on cmdline\n-L	Follow all symlinks\n-s	Only total size of each argument\n-x	Don't leave this filesystem\n-c	Cumulative total\n-d N	Only depth < N\n-l	Disable hardlink filter"
 
@@ -632,9 +610,9 @@
 
 #define HELP_df "usage: df [-HPkhi] [-t type] [FILE...]\n\nThe \"disk free\" command shows total/used/available disk space for\neach filesystem listed on the command line, or all currently mounted\nfilesystems.\n\n-a	Show all (including /proc and friends)\n-P	The SUSv3 \"Pedantic\" option\n-k	Sets units back to 1024 bytes (the default without -P)\n-h	Human readable (K=1024)\n-H	Human readable (k=1000)\n-i	Show inodes instead of blocks\n-t type	Display only filesystems of this type\n\nPedantic provides a slightly less useful output format dictated by POSIX,\nand sets the units to 512 bytes instead of the default 1024 bytes."
 
-#define HELP_date "usage: date [-u] [-I RES] [-r FILE] [-d DATE] [+DISPLAY_FORMAT] [-D SET_FORMAT] [SET]\n\nSet/get the current date/time. With no SET shows the current date.\n\n-d	Show DATE instead of current time (convert date format)\n-D	+FORMAT for SET or -d (instead of MMDDhhmm[[CC]YY][.ss])\n-I RES	ISO 8601 with RESolution d=date/h=hours/m=minutes/s=seconds/n=ns\n-r	Use modification time of FILE instead of current date\n-s DATE	Set the system clock to DATE.\n-u	Use UTC instead of current timezone\n\nSupported input formats:\n\nMMDDhhmm[[CC]YY][.ss]     POSIX\n@UNIXTIME[.FRACTION]      seconds since midnight 1970-01-01\nYYYY-MM-DD [hh:mm[:ss]]   ISO 8601\nhh:mm[:ss]                24-hour time today\n\nAll input formats can be followed by fractional seconds, and/or a UTC\noffset such as -0800.\n\nAll input formats can be preceded by TZ=\"id\" to set the input time zone\nseparately from the output time zone. Otherwise $TZ sets both.\n\n+FORMAT specifies display format string using strftime(3) syntax:\n\n%% literal %             %n newline              %t tab\n%S seconds (00-60)       %M minute (00-59)       %m month (01-12)\n%H hour (0-23)           %I hour (01-12)         %p AM/PM\n%y short year (00-99)    %Y year                 %C century\n%a short weekday name    %A weekday name         %u day of week (1-7, 1=mon)\n%b short month name      %B month name           %Z timezone name\n%j day of year (001-366) %d day of month (01-31) %e day of month ( 1-31)\n%N nanosec (output only)\n\n%U Week of year (0-53 start Sunday)   %W Week of year (0-53 start Monday)\n%V Week of year (1-53 start Monday, week < 4 days not part of this year)\n\n%F \"%Y-%m-%d\"   %R \"%H:%M\"        %T \"%H:%M:%S\"        %z  timezone (-0800)\n%D \"%m/%d/%y\"   %r \"%I:%M:%S %p\"  %h \"%b\"              %:z timezone (-08:00)\n%x locale date  %X locale time    %c locale date/time  %s  unix epoch time"
+#define HELP_date "usage: date [-u] [-I RES] [-r FILE] [-d DATE] [+DISPLAY_FORMAT] [-D SET_FORMAT] [SET]\n\nSet/get the current date/time. With no SET shows the current date.\n\n-d	Show DATE instead of current time (convert date format)\n-D	+FORMAT for SET or -d (instead of MMDDhhmm[[CC]YY][.ss])\n-I RES	ISO 8601 with RESolution d=date/h=hours/m=minutes/s=seconds/n=ns\n-r	Use modification time of FILE instead of current date\n-u	Use UTC instead of current timezone\n\nSupported input formats:\n\nMMDDhhmm[[CC]YY][.ss]     POSIX\n@UNIXTIME[.FRACTION]      seconds since midnight 1970-01-01\nYYYY-MM-DD [hh:mm[:ss]]   ISO 8601\nhh:mm[:ss]                24-hour time today\n\nAll input formats can be followed by fractional seconds, and/or a UTC\noffset such as -0800.\n\nAll input formats can be preceded by TZ=\"id\" to set the input time zone\nseparately from the output time zone. Otherwise $TZ sets both.\n\n+FORMAT specifies display format string using strftime(3) syntax:\n\n%% literal %             %n newline              %t tab\n%S seconds (00-60)       %M minute (00-59)       %m month (01-12)\n%H hour (0-23)           %I hour (01-12)         %p AM/PM\n%y short year (00-99)    %Y year                 %C century\n%a short weekday name    %A weekday name         %u day of week (1-7, 1=mon)\n%b short month name      %B month name           %Z timezone name\n%j day of year (001-366) %d day of month (01-31) %e day of month ( 1-31)\n%N nanosec (output only)\n\n%U Week of year (0-53 start Sunday)   %W Week of year (0-53 start Monday)\n%V Week of year (1-53 start Monday, week < 4 days not part of this year)\n\n%F \"%Y-%m-%d\"   %R \"%H:%M\"        %T \"%H:%M:%S\"        %z  timezone (-0800)\n%D \"%m/%d/%y\"   %r \"%I:%M:%S %p\"  %h \"%b\"              %:z timezone (-08:00)\n%x locale date  %X locale time    %c locale date/time  %s  unix epoch time"
 
-#define HELP_cut "usage: cut [-Ds] [-bcCfF LIST] [-dO DELIM] [FILE...]\n\nPrint selected parts of lines from each FILE to standard output.\n\nEach selection LIST is comma separated, either numbers (counting from 1)\nor dash separated ranges (inclusive, with X- meaning to end of line and -X\nfrom start). By default selection ranges are sorted and collated, use -D\nto prevent that.\n\n-b	Select bytes\n-c	Select UTF-8 characters\n-C	Select unicode columns\n-d	Use DELIM (default is TAB for -f, run of whitespace for -F)\n-D	Don't sort/collate selections or match -fF lines without delimiter\n-f	Select fields (words) separated by single DELIM character\n-F	Select fields separated by DELIM regex\n-O	Output delimiter (default one space for -F, input delim for -f)\n-s	Skip lines without delimiters"
+#define HELP_cut "usage: cut [-Ds] [-bcfF LIST] [-dO DELIM] [FILE...]\n\nPrint selected parts of lines from each FILE to standard output.\n\nEach selection LIST is comma separated, either numbers (counting from 1)\nor dash separated ranges (inclusive, with X- meaning to end of line and -X\nfrom start). By default selection ranges are sorted and collated, use -D\nto prevent that.\n\n-b	Select bytes\n-c	Select UTF-8 characters\n-C	Select unicode columns\n-d	Use DELIM (default is TAB for -f, run of whitespace for -F)\n-D	Don't sort/collate selections or match -fF lines without delimiter\n-f	Select fields (words) separated by single DELIM character\n-F	Select fields separated by DELIM regex\n-O	Output delimiter (default one space for -F, input delim for -f)\n-s	Skip lines without delimiters"
 
 #define HELP_cpio "usage: cpio -{o|t|i|p DEST} [-v] [--verbose] [-F FILE] [--no-preserve-owner]\n       [ignored: -m -H newc]\n\nCopy files into and out of a \"newc\" format cpio archive.\n\n-F FILE	Use archive FILE instead of stdin/stdout\n-p DEST	Copy-pass mode, copy stdin file list to directory DEST\n-i	Extract from archive into file system (stdin=archive)\n-o	Create archive (stdin=list of files, stdout=archive)\n-t	Test files (list only, stdin=archive, stdout=list of files)\n-d	Create directories if needed\n-u	unlink existing files when extracting\n-v	Verbose\n--no-preserve-owner (don't set ownership during extract)"
 
@@ -646,7 +624,7 @@
 
 #define HELP_comm "usage: comm [-123] FILE1 FILE2\n\nRead FILE1 and FILE2, which should be ordered, and produce three text\ncolumns as output: lines only in FILE1; lines only in FILE2; and lines\nin both files. Filename \"-\" is a synonym for stdin.\n\n-1	Suppress the output column of lines unique to FILE1\n-2	Suppress the output column of lines unique to FILE2\n-3	Suppress the output column of lines duplicated in FILE1 and FILE2"
 
-#define HELP_cmp "usage: cmp [-ls] [-n LEN] FILE1 [FILE2 [SKIP1 [SKIP2]]]\n\nCompare the contents of files (vs stdin if only one given), optionally\nskipping bytes at start.\n\n-l	Show all differing bytes\n-n LEN	Compare at most LEN bytes\n-s	Silent"
+#define HELP_cmp "usage: cmp [-l] [-s] FILE1 [FILE2 [SKIP1 [SKIP2]]]\n\nCompare the contents of two files. (Or stdin and file if only one given.)\n\n-l	Show all differing bytes\n-s	Silent"
 
 #define HELP_crc32 "usage: crc32 [file...]\n\nOutput crc32 checksum for each file."
 
@@ -662,7 +640,7 @@
 
 #define HELP_cat "usage: cat [-etuv] [FILE...]\n\nCopy (concatenate) files to stdout.  If no files listed, copy from stdin.\nFilename \"-\" is a synonym for stdin.\n\n-e	Mark each newline with $\n-t	Show tabs as ^I\n-u	Copy one byte at a time (slow)\n-v	Display nonprinting characters as escape sequences with M-x for\n	high ascii characters (>127), and ^x for other nonprinting chars"
 
-#define HELP_cal "usage: cal [[[DAY] MONTH] YEAR]\n\nPrint a calendar.\n\nWith one argument, prints all months of the specified year.\nWith two arguments, prints calendar for month and year.\nWith three arguments, highlights day within month and year.\n\n-h	Don't highlight today"
+#define HELP_cal "usage: cal [[MONTH] YEAR]\n\nPrint a calendar.\n\nWith one argument, prints all months of the specified year.\nWith two arguments, prints calendar for month and year.\n\n-h	Don't highlight today"
 
 #define HELP_basename "usage: basename [-a] [-s SUFFIX] NAME... | NAME [SUFFIX]\n\nReturn non-directory portion of a pathname removing suffix.\n\n-a		All arguments are names\n-s SUFFIX	Remove suffix (implies -a)"
 
diff --git a/android/linux/generated/newtoys.h b/android/linux/generated/newtoys.h
index ade8831..40ac3d4 100644
--- a/android/linux/generated/newtoys.h
+++ b/android/linux/generated/newtoys.h
@@ -1,4 +1,4 @@
-USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT|TOYFLAG_NOHELP))
+USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT))
 USE_SH(OLDTOY(-bash, sh, 0))
 USE_SH(OLDTOY(-sh, sh, 0))
 USE_SH(OLDTOY(-toysh, sh, 0))
@@ -11,7 +11,7 @@
 USE_ARCH(NEWTOY(arch, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_ARP(NEWTOY(arp, "vi:nDsdap:A:H:[+Ap][!sd]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_ARPING(NEWTOY(arping, "<1>1s:I:w#<0c#<0AUDbqf[+AU][+Df]", TOYFLAG_USR|TOYFLAG_SBIN))
-USE_ASCII(NEWTOY(ascii, 0, TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LINEBUF))
+USE_ASCII(NEWTOY(ascii, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_BASE32(NEWTOY(base32, "diw#<0=76[!dw]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_BASE64(NEWTOY(base64, "diw#<0=76[!dw]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_BASENAME(NEWTOY(basename, "^<1as:", TOYFLAG_USR|TOYFLAG_BIN))
@@ -24,7 +24,7 @@
 USE_BRCTL(NEWTOY(brctl, "<1", TOYFLAG_USR|TOYFLAG_SBIN))
 USE_BUNZIP2(NEWTOY(bunzip2, "cftkv", TOYFLAG_USR|TOYFLAG_BIN))
 USE_BZCAT(NEWTOY(bzcat, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_CAL(NEWTOY(cal, ">3h", TOYFLAG_USR|TOYFLAG_BIN))
+USE_CAL(NEWTOY(cal, ">2h", TOYFLAG_USR|TOYFLAG_BIN))
 USE_CAT(NEWTOY(cat, "u"USE_CAT_V("vte"), TOYFLAG_BIN))
 USE_CATV(NEWTOY(catv, USE_CATV("vte"), TOYFLAG_USR|TOYFLAG_BIN))
 USE_SH(NEWTOY(cd, ">1LP[-LP]", TOYFLAG_NOFORK))
@@ -39,19 +39,18 @@
 USE_CHVT(NEWTOY(chvt, "<1", TOYFLAG_USR|TOYFLAG_BIN))
 USE_CKSUM(NEWTOY(cksum, "HIPLN", TOYFLAG_BIN))
 USE_CLEAR(NEWTOY(clear, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_CMP(NEWTOY(cmp, "<1>4ls(silent)(quiet)n#<1[!ls]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
+USE_CMP(NEWTOY(cmp, "<1>2ls(silent)(quiet)[!ls]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
 USE_COMM(NEWTOY(comm, "<2>2321", TOYFLAG_USR|TOYFLAG_BIN))
 USE_COUNT(NEWTOY(count, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]", TOYFLAG_BIN))
-USE_CPIO(NEWTOY(cpio, "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
+USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]", TOYFLAG_BIN))
+USE_CPIO(NEWTOY(cpio, "(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
 USE_CRC32(NEWTOY(crc32, 0, TOYFLAG_BIN))
 USE_CROND(NEWTOY(crond, "fbSl#<0=8d#<0L:c:[-bf][-LS][-ld]", TOYFLAG_USR|TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_CRONTAB(NEWTOY(crontab, "c:u:elr[!elr]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
-USE_CUT(NEWTOY(cut, "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_DATE(NEWTOY(date, "d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr]", TOYFLAG_BIN))
+USE_CUT(NEWTOY(cut, "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_DATE(NEWTOY(date, "d:D:I(iso)(iso-8601):;r:u(utc)[!dr]", TOYFLAG_BIN))
 USE_DD(NEWTOY(dd, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_DEALLOCVT(NEWTOY(deallocvt, ">1", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NEEDROOT))
-USE_SH(NEWTOY(declare, "pAailunxr", TOYFLAG_NOFORK))
 USE_GROUPDEL(OLDTOY(delgroup, groupdel, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_USERDEL(OLDTOY(deluser, userdel, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_DEMO_MANY_OPTIONS(NEWTOY(demo_many_options, "ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba", TOYFLAG_BIN))
@@ -90,7 +89,7 @@
 USE_FLOCK(NEWTOY(flock, "<1>1nsux[-sux]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_FMT(NEWTOY(fmt, "w#<0=75", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_FOLD(NEWTOY(fold, "bsuw#<1", TOYFLAG_USR|TOYFLAG_BIN))
-USE_FREE(NEWTOY(free, "hgmkb[!hgmkb]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_FREE(NEWTOY(free, "htgmkb[!htgmkb]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_FREERAMDISK(NEWTOY(freeramdisk, "<1>1", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_FSCK(NEWTOY(fsck, "?t:ANPRTVsC#", TOYFLAG_USR|TOYFLAG_BIN))
 USE_FSFREEZE(NEWTOY(fsfreeze, "<1>1f|u|[!fu]", TOYFLAG_USR|TOYFLAG_SBIN))
@@ -103,29 +102,22 @@
 USE_GETFATTR(NEWTOY(getfattr, "(only-values)dhn:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_GETOPT(NEWTOY(getopt, "^a(alternative)n:(name)o:(options)l*(long)(longoptions)Tu", TOYFLAG_USR|TOYFLAG_BIN))
 USE_GETTY(NEWTOY(getty, "<2t#<0H:I:l:f:iwnmLh", TOYFLAG_SBIN))
-USE_GPIODETECT(NEWTOY(gpiodetect, ">0", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOINFO(NEWTOY(gpiofind, "<1>1", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOGET(NEWTOY(gpioget, "<2l", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOFIND(NEWTOY(gpioinfo, 0, TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOSET(NEWTOY(gpioset, "<2l", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GREP(NEWTOY(grep, "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF]", TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)|TOYFLAG_LINEBUF))
+USE_GREP(NEWTOY(grep, "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw]", TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)|TOYFLAG_LINEBUF))
 USE_GROUPADD(NEWTOY(groupadd, "<1>2g#<0S", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_GROUPDEL(NEWTOY(groupdel, "<1>2", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_GROUPS(NEWTOY(groups, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 USE_GUNZIP(NEWTOY(gunzip, "cdfk123456789[-123456789]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_GZIP(NEWTOY(gzip,    "ncdfk123456789[-123456789]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_REBOOT(OLDTOY(halt, reboot, TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
-USE_HD(OLDTOY(hd, hexdump, TOYFLAG_USR|TOYFLAG_BIN))
 USE_HEAD(NEWTOY(head, "?n(lines)#<0=10c(bytes)#<0qv[-nc]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HELLO(NEWTOY(hello, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_HELP(NEWTOY(help, "ahu", TOYFLAG_BIN|TOYFLAG_MAYFORK))
-USE_HEXDUMP(NEWTOY(hexdump, "bcCdn#<0os#<0vx[!bcCdox]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HEXEDIT(NEWTOY(hexedit, "<1>1r", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_HOST(NEWTOY(host, "<1>2avt:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HOSTID(NEWTOY(hostid, ">0", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HOSTNAME(NEWTOY(hostname, ">1bdsfF:[!bdsf]", TOYFLAG_BIN))
 USE_HWCLOCK(NEWTOY(hwclock, ">0(fast)f(rtc):u(utc)l(localtime)t(systz)s(hctosys)r(show)w(systohc)[-ul][!rtsw]", TOYFLAG_SBIN))
-USE_I2CDETECT(NEWTOY(i2cdetect, ">3aFlqry[!qr]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_I2CDETECT(NEWTOY(i2cdetect, ">3aFly", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CDUMP(NEWTOY(i2cdump, "<2>2fy", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CGET(NEWTOY(i2cget, "<3>3fy", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CSET(NEWTOY(i2cset, "<4fy", TOYFLAG_USR|TOYFLAG_BIN))
@@ -137,7 +129,7 @@
 USE_INSMOD(NEWTOY(insmod, "<1", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_INSTALL(NEWTOY(install, "<1cdDpsvt:m:o:g:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_IONICE(NEWTOY(ionice, "^tc#<0>3=2n#<0>7=5p#", TOYFLAG_USR|TOYFLAG_BIN))
-USE_IORENICE(NEWTOY(iorenice, "<1>3", TOYFLAG_USR|TOYFLAG_BIN))
+USE_IORENICE(NEWTOY(iorenice, "?<1>3", TOYFLAG_USR|TOYFLAG_BIN))
 USE_IOTOP(NEWTOY(iotop, ">0AaKO" "Hk*o*p*u*s#<1=7d%<100=3000m#n#<1bq", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT|TOYFLAG_LOCALE))
 USE_IP(NEWTOY(ip, NULL, TOYFLAG_SBIN))
 USE_IP(OLDTOY(ipaddr, ip, TOYFLAG_SBIN))
@@ -154,21 +146,20 @@
 USE_KLOGD(NEWTOY(klogd, "c#<1>8n", TOYFLAG_SBIN))
 USE_LAST(NEWTOY(last, "f:W", TOYFLAG_BIN))
 USE_LINK(NEWTOY(link, "<2>2", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LINUX32(NEWTOY(linux32, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_LN(NEWTOY(ln, "<1rt:Tvnfs", TOYFLAG_BIN))
 USE_LOAD_POLICY(NEWTOY(load_policy, "<1>1", TOYFLAG_USR|TOYFLAG_SBIN))
-USE_LOG(NEWTOY(log, "p:t:", TOYFLAG_USR|TOYFLAG_SBIN))
+USE_LOG(NEWTOY(log, "<1p:t:", TOYFLAG_USR|TOYFLAG_SBIN))
 USE_LOGGER(NEWTOY(logger, "t:p:s", TOYFLAG_USR|TOYFLAG_BIN))
 USE_LOGIN(NEWTOY(login, ">1f:ph:", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
 USE_LOGNAME(NEWTOY(logname, ">0", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LOGPATH(NEWTOY(logpath, 0, TOYFLAG_NOHELP|TOYFLAG_USR|TOYFLAG_BIN))
+USE_LOGWRAPPER(NEWTOY(logwrapper, 0, TOYFLAG_NOHELP|TOYFLAG_USR|TOYFLAG_BIN))
 USE_LOSETUP(NEWTOY(losetup, ">2S(sizelimit)#s(show)ro#j:fdcaD[!afj]", TOYFLAG_SBIN))
 USE_LS(NEWTOY(ls, "(color):;(full-time)(show-control-chars)ZgoACFHLRSabcdfhikl@mnpqrstuw#=80<0x1[-Cxm1][-Cxml][-Cxmo][-Cxmg][-cu][-ftS][-HL][!qb]", TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_LSATTR(NEWTOY(lsattr, "ldapvR", TOYFLAG_BIN))
 USE_LSMOD(NEWTOY(lsmod, NULL, TOYFLAG_SBIN))
 USE_LSOF(NEWTOY(lsof, "lp*t", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LSPCI(NEWTOY(lspci, "emkn@i:", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LSUSB(NEWTOY(lsusb, "i:", TOYFLAG_USR|TOYFLAG_BIN))
+USE_LSPCI(NEWTOY(lspci, "emkn"USE_LSPCI_TEXT("@i:"), TOYFLAG_USR|TOYFLAG_BIN))
+USE_LSUSB(NEWTOY(lsusb, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 USE_MAKEDEVS(NEWTOY(makedevs, "<1>1d:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_MAN(NEWTOY(man, "k:M:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_MCOOKIE(NEWTOY(mcookie, "v(verbose)V(version)", TOYFLAG_USR|TOYFLAG_BIN))
@@ -195,24 +186,24 @@
 USE_NETCAT(NEWTOY(netcat, USE_NETCAT_LISTEN("^tElL")"w#<1W#<1p#<1>65535q#<1s:f:46uU"USE_NETCAT_LISTEN("[!tlL][!Lw]")"[!46U]", TOYFLAG_BIN))
 USE_NETSTAT(NEWTOY(netstat, "pWrxwutneal", TOYFLAG_BIN))
 USE_NICE(NEWTOY(nice, "^<1n#", TOYFLAG_BIN))
-USE_NL(NEWTOY(nl, "v#=1l#w#<0=6b:n:s:E", TOYFLAG_USR|TOYFLAG_BIN))
+USE_NL(NEWTOY(nl, "v#=1l#w#<0=6Eb:n:s:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_NOHUP(NEWTOY(nohup, "<1^", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
 USE_NPROC(NEWTOY(nproc, "(all)", TOYFLAG_USR|TOYFLAG_BIN))
 USE_NSENTER(NEWTOY(nsenter, "<1F(no-fork)t#<1(target)i:(ipc);m:(mount);n:(net);p:(pid);u:(uts);U:(user);", TOYFLAG_USR|TOYFLAG_BIN))
 USE_OD(NEWTOY(od, "j#vw#<1=16N#xsodcbA:t*", TOYFLAG_USR|TOYFLAG_BIN))
 USE_ONEIT(NEWTOY(oneit, "^<1nc:p3[!pn]", TOYFLAG_SBIN))
-USE_OPENVT(NEWTOY(openvt, "^<1c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
+USE_OPENVT(NEWTOY(openvt, "c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
 USE_PARTPROBE(NEWTOY(partprobe, "<1", TOYFLAG_SBIN))
 USE_PASSWD(NEWTOY(passwd, ">1a:dlu", TOYFLAG_STAYROOT|TOYFLAG_USR|TOYFLAG_BIN))
 USE_PASTE(NEWTOY(paste, "d:s", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_PATCH(NEWTOY(patch, ">2(no-backup-if-mismatch)(dry-run)"USE_TOYBOX_DEBUG("x")"F#g#fulp#d:i:Rs(quiet)", TOYFLAG_USR|TOYFLAG_BIN))
 USE_PGREP(NEWTOY(pgrep, "?cld:u*U*t*s*P*g*G*fnovxL:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_PIDOF(NEWTOY(pidof, "so:x", TOYFLAG_BIN))
+USE_PIDOF(NEWTOY(pidof, "<1so:x", TOYFLAG_BIN))
 USE_PING(NEWTOY(ping, "<1>1m#t#<0>255=64c#<0=3s#<0>4064=56i%W#<0=3w#<0qf46I:[-46]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_PING(OLDTOY(ping6, ping, TOYFLAG_USR|TOYFLAG_BIN))
 USE_PIVOT_ROOT(NEWTOY(pivot_root, "<2>2", TOYFLAG_SBIN))
 USE_PKILL(NEWTOY(pkill,    "?Vu*U*t*s*P*g*G*fnovxl:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_PMAP(NEWTOY(pmap, "<1pqx", TOYFLAG_USR|TOYFLAG_BIN))
+USE_PMAP(NEWTOY(pmap, "<1xq", TOYFLAG_USR|TOYFLAG_BIN))
 USE_REBOOT(OLDTOY(poweroff, reboot, TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_PRINTENV(NEWTOY(printenv, "(null)0", TOYFLAG_BIN))
 USE_PRINTF(NEWTOY(printf, "<1?^", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
@@ -224,8 +215,8 @@
 USE_READAHEAD(NEWTOY(readahead, NULL, TOYFLAG_BIN))
 USE_READELF(NEWTOY(readelf, "<1(dyn-syms)adehlnp:SsWx:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_READLINK(NEWTOY(readlink, "<1nqmef(canonicalize)[-mef]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_REALPATH(OLDTOY(realpath, readlink, TOYFLAG_USR|TOYFLAG_BIN))
-USE_REBOOT(NEWTOY(reboot, "d:fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
+USE_REALPATH(NEWTOY(realpath, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+USE_REBOOT(NEWTOY(reboot, "fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_RENICE(NEWTOY(renice, "<1gpun#|", TOYFLAG_USR|TOYFLAG_BIN))
 USE_RESET(NEWTOY(reset, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_RESTORECON(NEWTOY(restorecon, "<1DFnRrv", TOYFLAG_USR|TOYFLAG_SBIN))
@@ -245,12 +236,12 @@
 USE_SETFATTR(NEWTOY(setfattr, "hn:|v:x:|[!xv]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SETSID(NEWTOY(setsid, "^<1wcd[!dc]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SH(NEWTOY(sh, "0(noediting)(noprofile)(norc)sc:i", TOYFLAG_BIN))
-USE_SHA1SUM(OLDTOY(sha1sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA224SUM(OLDTOY(sha224sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA256SUM(OLDTOY(sha256sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA384SUM(OLDTOY(sha384sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_SHA1SUM(NEWTOY(sha1sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TOYBOX_LIBCRYPTO(USE_SHA224SUM(OLDTOY(sha224sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
+USE_TOYBOX_LIBCRYPTO(USE_SHA256SUM(OLDTOY(sha256sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
+USE_TOYBOX_LIBCRYPTO(USE_SHA384SUM(OLDTOY(sha384sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
 USE_SHA3SUM(NEWTOY(sha3sum, "bSa#<128>512=224", TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA512SUM(OLDTOY(sha512sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_TOYBOX_LIBCRYPTO(USE_SHA512SUM(OLDTOY(sha512sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
 USE_SH(NEWTOY(shift, ">1", TOYFLAG_NOFORK))
 USE_SHRED(NEWTOY(shred, "<1zxus#<1n#<1o#<0f", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SKELETON(NEWTOY(skeleton, "(walrus)(blubber):;(also):e@d*c#b:a", TOYFLAG_USR|TOYFLAG_BIN))
@@ -259,9 +250,8 @@
 USE_SNTP(NEWTOY(sntp, ">1M :m :Sp:t#<0=1>16asdDqr#<4>17=10[!as]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SORT(NEWTOY(sort, USE_SORT_FLOAT("g")"S:T:m" "o:k*t:" "xVbMcszdfirun", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
 USE_SH(NEWTOY(source, "<1", TOYFLAG_NOFORK))
-USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1[!bl]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_STAT(NEWTOY(stat, "<1c:(format)fLt", TOYFLAG_BIN))
-USE_STRACE(NEWTOY(strace, "^p#s#v", TOYFLAG_USR|TOYFLAG_SBIN))
 USE_STRINGS(NEWTOY(strings, "t:an#=4<1fo", TOYFLAG_USR|TOYFLAG_BIN))
 USE_STTY(NEWTOY(stty, "?aF:g[!ag]", TOYFLAG_BIN))
 USE_SU(NEWTOY(su, "^lmpu:g:c:s:[!lmp]", TOYFLAG_BIN|TOYFLAG_ROOTONLY))
@@ -273,8 +263,8 @@
 USE_SYSCTL(NEWTOY(sysctl, "^neNqwpaA[!ap][!aq][!aw][+aA]", TOYFLAG_SBIN))
 USE_SYSLOGD(NEWTOY(syslogd,">0l#<1>8=8R:b#<0>99=1s#<0=200m#<0>71582787=20O:p:f:a:nSKLD", TOYFLAG_SBIN|TOYFLAG_STAYROOT))
 USE_TAC(NEWTOY(tac, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_TAIL(NEWTOY(tail, "?fFs:c(bytes)-n(lines)-[-cn][-fF]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_TAR(NEWTOY(tar, "&(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TAIL(NEWTOY(tail, "?fc-n-[-cn]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TAR(NEWTOY(tar, "&(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TASKSET(NEWTOY(taskset, "<1^pa", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
 USE_TCPSVD(NEWTOY(tcpsvd, "^<3c#=30<1C:b#=20<0u:l:hEv", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TEE(NEWTOY(tee, "ia", TOYFLAG_USR|TOYFLAG_BIN))
@@ -283,9 +273,9 @@
 USE_TEST(NEWTOY(test, 0, TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NOHELP|TOYFLAG_MAYFORK))
 USE_TFTP(NEWTOY(tftp, "<1b#<8>65464r:l:g|p|[!gp]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TFTPD(NEWTOY(tftpd, "rcu:l", TOYFLAG_BIN))
-USE_TIME(NEWTOY(time, "<1^pv[-pv]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
+USE_TIME(NEWTOY(time, "<1^pv", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
 USE_TIMEOUT(NEWTOY(timeout, "<2^(foreground)(preserve-status)vk:s(signal):", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
-USE_TOP(NEWTOY(top, ">0O*h" "Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
+USE_TOP(NEWTOY(top, ">0O*" "Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_TOUCH(NEWTOY(touch, "<1acd:fmr:t:h[!dtr]", TOYFLAG_BIN))
 USE_SH(OLDTOY(toysh, sh, TOYFLAG_BIN))
 USE_TR(NEWTOY(tr, "^>2<1Ccsd[+cC]", TOYFLAG_USR|TOYFLAG_BIN))
@@ -295,11 +285,10 @@
 USE_TRUNCATE(NEWTOY(truncate, "<1s:|c", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TTY(NEWTOY(tty, "s", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TUNCTL(NEWTOY(tunctl, "<1>1t|d|u:T[!td]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_UCLAMPSET(NEWTOY(uclampset, "p#am#<-1>1024M#<-1>1024R", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
 USE_TCPSVD(OLDTOY(udpsvd, tcpsvd, TOYFLAG_USR|TOYFLAG_BIN))
 USE_ULIMIT(NEWTOY(ulimit, ">1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_UMOUNT(NEWTOY(umount, "cndDflrat*v[!na]", TOYFLAG_BIN|TOYFLAG_STAYROOT))
-USE_UNAME(NEWTOY(uname, "aomvrns", TOYFLAG_BIN))
+USE_UNAME(NEWTOY(uname, "oamvrns[+os]", TOYFLAG_BIN))
 USE_UNICODE(NEWTOY(unicode, "<1", TOYFLAG_USR|TOYFLAG_BIN))
 USE_UNIQ(NEWTOY(uniq, "f#s#w#zicdu", TOYFLAG_USR|TOYFLAG_BIN))
 USE_UNIX2DOS(NEWTOY(unix2dos, 0, TOYFLAG_BIN))
@@ -321,12 +310,12 @@
 USE_WATCH(NEWTOY(watch, "^<1n%<100=2000tebx", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_WATCHDOG(NEWTOY(watchdog, "<1>1Ft#=4<1T#=60<1", TOYFLAG_NEEDROOT|TOYFLAG_BIN))
 USE_WC(NEWTOY(wc, "mcwl", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
-USE_WGET(NEWTOY(wget, "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):", TOYFLAG_USR|TOYFLAG_BIN))
+USE_WGET(NEWTOY(wget, "(no-check-certificate)O:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_WHICH(NEWTOY(which, "<1a", TOYFLAG_USR|TOYFLAG_BIN))
 USE_WHO(NEWTOY(who, "a", TOYFLAG_USR|TOYFLAG_BIN))
 USE_WHOAMI(OLDTOY(whoami, logname, TOYFLAG_USR|TOYFLAG_BIN))
 USE_XARGS(NEWTOY(xargs, "^E:P#<0=1optrn#<1(max-args)s#0[!0E]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_XXD(NEWTOY(xxd, ">1c#<0>256l#o#g#<1=2iprs#[!rs]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_XXD(NEWTOY(xxd, ">1c#l#o#g#<1=2iprs#[!rs]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_XZCAT(NEWTOY(xzcat, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 USE_YES(NEWTOY(yes, NULL, TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LINEBUF))
 USE_ZCAT(NEWTOY(zcat,     "cdfk123456789[-123456789]", TOYFLAG_USR|TOYFLAG_BIN))
diff --git a/android/mac/generated/config.h b/android/mac/generated/config.h
index a9f4bdf..a3c54d8 100644
--- a/android/mac/generated/config.h
+++ b/android/mac/generated/config.h
@@ -2,8 +2,6 @@
 #define USE_TOYBOX_ANDROID_SCHEDPOLICY(...)
 #define CFG_TOYBOX_CONTAINER 0
 #define USE_TOYBOX_CONTAINER(...)
-#define CFG_TOYBOX_COPYFILERANGE 0
-#define USE_TOYBOX_COPYFILERANGE(...)
 #define CFG_TOYBOX_DEBUG 0
 #define USE_TOYBOX_DEBUG(...)
 #define CFG_TOYBOX_FALLOCATE 0
@@ -240,16 +238,6 @@
 #define USE_GETOPT(...) __VA_ARGS__
 #define CFG_GETTY 0
 #define USE_GETTY(...)
-#define CFG_GPIODETECT 0
-#define USE_GPIODETECT(...)
-#define CFG_GPIOFIND 0
-#define USE_GPIOFIND(...)
-#define CFG_GPIOGET 0
-#define USE_GPIOGET(...)
-#define CFG_GPIOINFO 0
-#define USE_GPIOINFO(...)
-#define CFG_GPIOSET 0
-#define USE_GPIOSET(...)
 #define CFG_GREP 1
 #define USE_GREP(...) __VA_ARGS__
 #define CFG_GROUPADD 0
@@ -270,12 +258,8 @@
 #define USE_HELP_EXTRAS(...)
 #define CFG_HELP 0
 #define USE_HELP(...)
-#define CFG_HEXDUMP 0
-#define USE_HEXDUMP(...)
 #define CFG_HEXEDIT 0
 #define USE_HEXEDIT(...)
-#define CFG_HD 0
-#define USE_HD(...)
 #define CFG_HOSTID 0
 #define USE_HOSTID(...)
 #define CFG_HOST 0
@@ -306,8 +290,8 @@
 #define USE_INOTIFYD(...)
 #define CFG_INSMOD 0
 #define USE_INSMOD(...)
-#define CFG_INSTALL 1
-#define USE_INSTALL(...) __VA_ARGS__
+#define CFG_INSTALL 0
+#define USE_INSTALL(...)
 #define CFG_IONICE 0
 #define USE_IONICE(...)
 #define CFG_IORENICE 0
@@ -334,8 +318,6 @@
 #define USE_LAST(...)
 #define CFG_LINK 0
 #define USE_LINK(...)
-#define CFG_LINUX32 0
-#define USE_LINUX32(...)
 #define CFG_LN 1
 #define USE_LN(...) __VA_ARGS__
 #define CFG_LOAD_POLICY 0
@@ -348,8 +330,6 @@
 #define USE_LOG(...)
 #define CFG_LOGNAME 0
 #define USE_LOGNAME(...)
-#define CFG_LOGPATH 0
-#define USE_LOGPATH(...)
 #define CFG_LOGWRAPPER 0
 #define USE_LOGWRAPPER(...)
 #define CFG_LOSETUP 0
@@ -558,8 +538,6 @@
 #define USE_SPLIT(...)
 #define CFG_STAT 1
 #define USE_STAT(...) __VA_ARGS__
-#define CFG_STRACE 0
-#define USE_STRACE(...)
 #define CFG_STRINGS 0
 #define USE_STRINGS(...)
 #define CFG_STTY 0
@@ -624,8 +602,6 @@
 #define USE_TTY(...)
 #define CFG_TUNCTL 0
 #define USE_TUNCTL(...)
-#define CFG_UCLAMPSET 0
-#define USE_UCLAMPSET(...)
 #define CFG_ULIMIT 0
 #define USE_ULIMIT(...)
 #define CFG_UMOUNT 0
diff --git a/android/mac/generated/flags.h b/android/mac/generated/flags.h
index 516ffc7..5f4854d 100644
--- a/android/mac/generated/flags.h
+++ b/android/mac/generated/flags.h
@@ -5,7 +5,7 @@
 #define FORCED_FLAGLL 1ULL
 #else
 #define FORCED_FLAG 0
-#define FORCED_FLAGLL 0LL
+#define FORCED_FLAGLL 0
 #endif
 
 // acpi   abctV
@@ -200,9 +200,9 @@
 #undef FOR_bzcat
 #endif
 
-// cal   >3h
+// cal   >2h
 #undef OPTSTR_cal
-#define OPTSTR_cal ">3h"
+#define OPTSTR_cal ">2h"
 #ifdef CLEANUP_cal
 #undef CLEANUP_cal
 #undef FOR_cal
@@ -352,13 +352,12 @@
 #undef FOR_clear
 #endif
 
-// cmp <1>4ls(silent)(quiet)n#<1[!ls] <1>4ls(silent)(quiet)n#<1[!ls]
+// cmp <1>2ls(silent)(quiet)[!ls] <1>2ls(silent)(quiet)[!ls]
 #undef OPTSTR_cmp
-#define OPTSTR_cmp "<1>4ls(silent)(quiet)n#<1[!ls]"
+#define OPTSTR_cmp "<1>2ls(silent)(quiet)[!ls]"
 #ifdef CLEANUP_cmp
 #undef CLEANUP_cmp
 #undef FOR_cmp
-#undef FLAG_n
 #undef FLAG_s
 #undef FLAG_l
 #endif
@@ -382,9 +381,9 @@
 #undef FOR_count
 #endif
 
-// cp <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr] <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]
+// cp <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu] <1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]
 #undef OPTSTR_cp
-#define OPTSTR_cp "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]"
+#define OPTSTR_cp "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]"
 #ifdef CLEANUP_cp
 #undef CLEANUP_cp
 #undef FOR_cp
@@ -410,9 +409,9 @@
 #undef FLAG_preserve
 #endif
 
-// cpio (ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF] (ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]
+// cpio (quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF] (quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]
 #undef OPTSTR_cpio
-#define OPTSTR_cpio "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]"
+#define OPTSTR_cpio "(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]"
 #ifdef CLEANUP_cpio
 #undef CLEANUP_cpio
 #undef FOR_cpio
@@ -428,8 +427,6 @@
 #undef FLAG_m
 #undef FLAG_no_preserve_owner
 #undef FLAG_quiet
-#undef FLAG_renumber_inodes
-#undef FLAG_ignore_devno
 #endif
 
 // crc32    
@@ -468,9 +465,9 @@
 #undef FLAG_c
 #endif
 
-// cut b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF] b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF]
+// cut b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf] b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]
 #undef OPTSTR_cut
-#define OPTSTR_cut "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF]"
+#define OPTSTR_cut "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]"
 #ifdef CLEANUP_cut
 #undef CLEANUP_cut
 #undef FOR_cut
@@ -486,14 +483,13 @@
 #undef FLAG_b
 #endif
 
-// date d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr] d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr]
+// date d:D:I(iso)(iso-8601):;r:u(utc)[!dr] d:D:I(iso)(iso-8601):;r:u(utc)[!dr]
 #undef OPTSTR_date
-#define OPTSTR_date "d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr]"
+#define OPTSTR_date "d:D:I(iso)(iso-8601):;r:u(utc)[!dr]"
 #ifdef CLEANUP_date
 #undef CLEANUP_date
 #undef FOR_date
 #undef FLAG_u
-#undef FLAG_s
 #undef FLAG_r
 #undef FLAG_I
 #undef FLAG_D
@@ -516,23 +512,6 @@
 #undef FOR_deallocvt
 #endif
 
-// declare   pAailunxr
-#undef OPTSTR_declare
-#define OPTSTR_declare "pAailunxr"
-#ifdef CLEANUP_declare
-#undef CLEANUP_declare
-#undef FOR_declare
-#undef FLAG_r
-#undef FLAG_x
-#undef FLAG_n
-#undef FLAG_u
-#undef FLAG_l
-#undef FLAG_i
-#undef FLAG_a
-#undef FLAG_A
-#undef FLAG_p
-#endif
-
 // demo_many_options   ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba
 #undef OPTSTR_demo_many_options
 #define OPTSTR_demo_many_options "ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
@@ -995,9 +974,9 @@
 #undef FLAG_b
 #endif
 
-// free   hgmkb[!hgmkb]
+// free   htgmkb[!htgmkb]
 #undef OPTSTR_free
-#define OPTSTR_free "hgmkb[!hgmkb]"
+#define OPTSTR_free "htgmkb[!htgmkb]"
 #ifdef CLEANUP_free
 #undef CLEANUP_free
 #undef FOR_free
@@ -1005,6 +984,7 @@
 #undef FLAG_k
 #undef FLAG_m
 #undef FLAG_g
+#undef FLAG_t
 #undef FLAG_h
 #endif
 
@@ -1144,51 +1124,9 @@
 #undef FLAG_t
 #endif
 
-// gpiodetect   >0
-#undef OPTSTR_gpiodetect
-#define OPTSTR_gpiodetect ">0"
-#ifdef CLEANUP_gpiodetect
-#undef CLEANUP_gpiodetect
-#undef FOR_gpiodetect
-#endif
-
-// gpiofind   <1>1
-#undef OPTSTR_gpiofind
-#define OPTSTR_gpiofind "<1>1"
-#ifdef CLEANUP_gpiofind
-#undef CLEANUP_gpiofind
-#undef FOR_gpiofind
-#endif
-
-// gpioget   <2l
-#undef OPTSTR_gpioget
-#define OPTSTR_gpioget "<2l"
-#ifdef CLEANUP_gpioget
-#undef CLEANUP_gpioget
-#undef FOR_gpioget
-#undef FLAG_l
-#endif
-
-// gpioinfo    
-#undef OPTSTR_gpioinfo
-#define OPTSTR_gpioinfo 0
-#ifdef CLEANUP_gpioinfo
-#undef CLEANUP_gpioinfo
-#undef FOR_gpioinfo
-#endif
-
-// gpioset   <2l
-#undef OPTSTR_gpioset
-#define OPTSTR_gpioset "<2l"
-#ifdef CLEANUP_gpioset
-#undef CLEANUP_gpioset
-#undef FOR_gpioset
-#undef FLAG_l
-#endif
-
-// grep (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF] (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF]
+// grep (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw] (line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw]
 #undef OPTSTR_grep
-#define OPTSTR_grep "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF]"
+#define OPTSTR_grep "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw]"
 #ifdef CLEANUP_grep
 #undef CLEANUP_grep
 #undef FOR_grep
@@ -1201,7 +1139,6 @@
 #undef FLAG_e
 #undef FLAG_q
 #undef FLAG_l
-#undef FLAG_L
 #undef FLAG_c
 #undef FLAG_w
 #undef FLAG_v
@@ -1327,23 +1264,6 @@
 #undef FLAG_a
 #endif
 
-// hexdump   bcCdn#<0os#<0vx[!bcCdox]
-#undef OPTSTR_hexdump
-#define OPTSTR_hexdump "bcCdn#<0os#<0vx[!bcCdox]"
-#ifdef CLEANUP_hexdump
-#undef CLEANUP_hexdump
-#undef FOR_hexdump
-#undef FLAG_x
-#undef FLAG_v
-#undef FLAG_s
-#undef FLAG_o
-#undef FLAG_n
-#undef FLAG_d
-#undef FLAG_C
-#undef FLAG_c
-#undef FLAG_b
-#endif
-
 // hexedit   <1>1r
 #undef OPTSTR_hexedit
 #define OPTSTR_hexedit "<1>1r"
@@ -1401,15 +1321,13 @@
 #undef FLAG_fast
 #endif
 
-// i2cdetect   >3aFlqry[!qr]
+// i2cdetect   >3aFly
 #undef OPTSTR_i2cdetect
-#define OPTSTR_i2cdetect ">3aFlqry[!qr]"
+#define OPTSTR_i2cdetect ">3aFly"
 #ifdef CLEANUP_i2cdetect
 #undef CLEANUP_i2cdetect
 #undef FOR_i2cdetect
 #undef FLAG_y
-#undef FLAG_r
-#undef FLAG_q
 #undef FLAG_l
 #undef FLAG_F
 #undef FLAG_a
@@ -1505,7 +1423,7 @@
 #undef FOR_insmod
 #endif
 
-// install <1cdDpsvt:m:o:g: <1cdDpsvt:m:o:g:
+// install   <1cdDpsvt:m:o:g:
 #undef OPTSTR_install
 #define OPTSTR_install "<1cdDpsvt:m:o:g:"
 #ifdef CLEANUP_install
@@ -1535,9 +1453,9 @@
 #undef FLAG_t
 #endif
 
-// iorenice   <1>3
+// iorenice   ?<1>3
 #undef OPTSTR_iorenice
-#define OPTSTR_iorenice "<1>3"
+#define OPTSTR_iorenice "?<1>3"
 #ifdef CLEANUP_iorenice
 #undef CLEANUP_iorenice
 #undef FOR_iorenice
@@ -1682,14 +1600,6 @@
 #undef FOR_link
 #endif
 
-// linux32    
-#undef OPTSTR_linux32
-#define OPTSTR_linux32 0
-#ifdef CLEANUP_linux32
-#undef CLEANUP_linux32
-#undef FOR_linux32
-#endif
-
 // ln <1rt:Tvnfs <1rt:Tvnfs
 #undef OPTSTR_ln
 #define OPTSTR_ln "<1rt:Tvnfs"
@@ -1713,9 +1623,9 @@
 #undef FOR_load_policy
 #endif
 
-// log   p:t:
+// log   <1p:t:
 #undef OPTSTR_log
-#define OPTSTR_log "p:t:"
+#define OPTSTR_log "<1p:t:"
 #ifdef CLEANUP_log
 #undef CLEANUP_log
 #undef FOR_log
@@ -1753,12 +1663,12 @@
 #undef FOR_logname
 #endif
 
-// logpath    
-#undef OPTSTR_logpath
-#define OPTSTR_logpath 0
-#ifdef CLEANUP_logpath
-#undef CLEANUP_logpath
-#undef FOR_logpath
+// logwrapper    
+#undef OPTSTR_logwrapper
+#define OPTSTR_logwrapper 0
+#ifdef CLEANUP_logwrapper
+#undef CLEANUP_logwrapper
+#undef FOR_logwrapper
 #endif
 
 // losetup   >2S(sizelimit)#s(show)ro#j:fdcaD[!afj]
@@ -1866,13 +1776,12 @@
 #undef FLAG_e
 #endif
 
-// lsusb   i:
+// lsusb    
 #undef OPTSTR_lsusb
-#define OPTSTR_lsusb "i:"
+#define OPTSTR_lsusb 0
 #ifdef CLEANUP_lsusb
 #undef CLEANUP_lsusb
 #undef FOR_lsusb
-#undef FLAG_i
 #endif
 
 // makedevs   <1>1d:
@@ -2168,16 +2077,16 @@
 #undef FLAG_n
 #endif
 
-// nl v#=1l#w#<0=6b:n:s:E v#=1l#w#<0=6b:n:s:E
+// nl v#=1l#w#<0=6Eb:n:s: v#=1l#w#<0=6Eb:n:s:
 #undef OPTSTR_nl
-#define OPTSTR_nl "v#=1l#w#<0=6b:n:s:E"
+#define OPTSTR_nl "v#=1l#w#<0=6Eb:n:s:"
 #ifdef CLEANUP_nl
 #undef CLEANUP_nl
 #undef FOR_nl
-#undef FLAG_E
 #undef FLAG_s
 #undef FLAG_n
 #undef FLAG_b
+#undef FLAG_E
 #undef FLAG_w
 #undef FLAG_l
 #undef FLAG_v
@@ -2248,9 +2157,9 @@
 #undef FLAG_n
 #endif
 
-// openvt   ^<1c#<1>63sw
+// openvt   c#<1>63sw
 #undef OPTSTR_openvt
-#define OPTSTR_openvt "^<1c#<1>63sw"
+#define OPTSTR_openvt "c#<1>63sw"
 #ifdef CLEANUP_openvt
 #undef CLEANUP_openvt
 #undef FOR_openvt
@@ -2334,9 +2243,9 @@
 #undef FLAG_c
 #endif
 
-// pidof   so:x
+// pidof   <1so:x
 #undef OPTSTR_pidof
-#define OPTSTR_pidof "so:x"
+#define OPTSTR_pidof "<1so:x"
 #ifdef CLEANUP_pidof
 #undef CLEANUP_pidof
 #undef FOR_pidof
@@ -2395,15 +2304,14 @@
 #undef FLAG_V
 #endif
 
-// pmap   <1pqx
+// pmap   <1xq
 #undef OPTSTR_pmap
-#define OPTSTR_pmap "<1pqx"
+#define OPTSTR_pmap "<1xq"
 #ifdef CLEANUP_pmap
 #undef CLEANUP_pmap
 #undef FOR_pmap
-#undef FLAG_x
 #undef FLAG_q
-#undef FLAG_p
+#undef FLAG_x
 #endif
 
 // printenv   (null)0
@@ -2534,15 +2442,22 @@
 #undef FLAG_n
 #endif
 
-// reboot   d:fn
+// realpath <1 <1
+#undef OPTSTR_realpath
+#define OPTSTR_realpath "<1"
+#ifdef CLEANUP_realpath
+#undef CLEANUP_realpath
+#undef FOR_realpath
+#endif
+
+// reboot   fn
 #undef OPTSTR_reboot
-#define OPTSTR_reboot "d:fn"
+#define OPTSTR_reboot "fn"
 #ifdef CLEANUP_reboot
 #undef CLEANUP_reboot
 #undef FOR_reboot
 #undef FLAG_n
 #undef FLAG_f
-#undef FLAG_d
 #endif
 
 // renice   <1gpun#|
@@ -2755,6 +2670,17 @@
 #undef FLAG_noediting
 #endif
 
+// sha1sum bc(check)s(status)[!bc] bc(check)s(status)[!bc]
+#undef OPTSTR_sha1sum
+#define OPTSTR_sha1sum "bc(check)s(status)[!bc]"
+#ifdef CLEANUP_sha1sum
+#undef CLEANUP_sha1sum
+#undef FOR_sha1sum
+#undef FLAG_s
+#undef FLAG_c
+#undef FLAG_b
+#endif
+
 // sha3sum   bSa#<128>512=224
 #undef OPTSTR_sha3sum
 #define OPTSTR_sha3sum "bSa#<128>512=224"
@@ -2879,13 +2805,12 @@
 #undef FOR_source
 #endif
 
-// split   >2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln]
+// split   >2a#<1=2>9b#<1l#<1[!bl]
 #undef OPTSTR_split
-#define OPTSTR_split ">2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln]"
+#define OPTSTR_split ">2a#<1=2>9b#<1l#<1[!bl]"
 #ifdef CLEANUP_split
 #undef CLEANUP_split
 #undef FOR_split
-#undef FLAG_n
 #undef FLAG_l
 #undef FLAG_b
 #undef FLAG_a
@@ -2903,17 +2828,6 @@
 #undef FLAG_c
 #endif
 
-// strace   ^p#s#v
-#undef OPTSTR_strace
-#define OPTSTR_strace "^p#s#v"
-#ifdef CLEANUP_strace
-#undef CLEANUP_strace
-#undef FOR_strace
-#undef FLAG_v
-#undef FLAG_s
-#undef FLAG_p
-#endif
-
 // strings   t:an#=4<1fo
 #undef OPTSTR_strings
 #define OPTSTR_strings "t:an#=4<1fo"
@@ -3044,22 +2958,20 @@
 #undef FOR_tac
 #endif
 
-// tail ?fFs:c(bytes)-n(lines)-[-cn][-fF] ?fFs:c(bytes)-n(lines)-[-cn][-fF]
+// tail ?fc-n-[-cn] ?fc-n-[-cn]
 #undef OPTSTR_tail
-#define OPTSTR_tail "?fFs:c(bytes)-n(lines)-[-cn][-fF]"
+#define OPTSTR_tail "?fc-n-[-cn]"
 #ifdef CLEANUP_tail
 #undef CLEANUP_tail
 #undef FOR_tail
 #undef FLAG_n
 #undef FLAG_c
-#undef FLAG_s
-#undef FLAG_F
 #undef FLAG_f
 #endif
 
-// tar &(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa] &(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]
+// tar &(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa] &(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]
 #undef OPTSTR_tar
-#define OPTSTR_tar "&(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]"
+#define OPTSTR_tar "&(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]"
 #ifdef CLEANUP_tar
 #undef CLEANUP_tar
 #undef FOR_tar
@@ -3096,8 +3008,6 @@
 #undef FLAG_no_recursion
 #undef FLAG_full_time
 #undef FLAG_restrict
-#undef FLAG_selinux
-#undef FLAG_strip_components
 #endif
 
 // taskset   <1^pa
@@ -3194,9 +3104,9 @@
 #undef FLAG_r
 #endif
 
-// time   <1^pv[-pv]
+// time   <1^pv
 #undef OPTSTR_time
-#define OPTSTR_time "<1^pv[-pv]"
+#define OPTSTR_time "<1^pv"
 #ifdef CLEANUP_time
 #undef CLEANUP_time
 #undef FOR_time
@@ -3217,9 +3127,9 @@
 #undef FLAG_foreground
 #endif
 
-// top   >0O*hHk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]
+// top   >0O*Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]
 #undef OPTSTR_top
-#define OPTSTR_top ">0O*hHk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]"
+#define OPTSTR_top ">0O*Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]"
 #ifdef CLEANUP_top
 #undef CLEANUP_top
 #undef FOR_top
@@ -3234,7 +3144,6 @@
 #undef FLAG_o
 #undef FLAG_k
 #undef FLAG_H
-#undef FLAG_h
 #undef FLAG_O
 #endif
 
@@ -3341,19 +3250,6 @@
 #undef FLAG_t
 #endif
 
-// uclampset   p#am#<-1>1024M#<-1>1024R
-#undef OPTSTR_uclampset
-#define OPTSTR_uclampset "p#am#<-1>1024M#<-1>1024R"
-#ifdef CLEANUP_uclampset
-#undef CLEANUP_uclampset
-#undef FOR_uclampset
-#undef FLAG_R
-#undef FLAG_M
-#undef FLAG_m
-#undef FLAG_a
-#undef FLAG_p
-#endif
-
 // ulimit   >1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]
 #undef OPTSTR_ulimit
 #define OPTSTR_ulimit ">1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]"
@@ -3400,9 +3296,9 @@
 #undef FLAG_c
 #endif
 
-// uname aomvrns aomvrns
+// uname oamvrns[+os] oamvrns[+os]
 #undef OPTSTR_uname
-#define OPTSTR_uname "aomvrns"
+#define OPTSTR_uname "oamvrns[+os]"
 #ifdef CLEANUP_uname
 #undef CLEANUP_uname
 #undef FOR_uname
@@ -3411,8 +3307,8 @@
 #undef FLAG_r
 #undef FLAG_v
 #undef FLAG_m
-#undef FLAG_o
 #undef FLAG_a
+#undef FLAG_o
 #endif
 
 // unicode   <1
@@ -3631,16 +3527,14 @@
 #undef FLAG_m
 #endif
 
-// wget   <1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):
+// wget   (no-check-certificate)O:
 #undef OPTSTR_wget
-#define OPTSTR_wget "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):"
+#define OPTSTR_wget "(no-check-certificate)O:"
 #ifdef CLEANUP_wget
 #undef CLEANUP_wget
 #undef FOR_wget
-#undef FLAG_p
 #undef FLAG_O
-#undef FLAG_d
-#undef FLAG_max_redirect
+#undef FLAG_no_check_certificate
 #endif
 
 // which <1a <1a
@@ -3678,9 +3572,9 @@
 #undef FLAG_E
 #endif
 
-// xxd >1c#<0>256l#o#g#<1=2iprs#[!rs] >1c#<0>256l#o#g#<1=2iprs#[!rs]
+// xxd >1c#l#o#g#<1=2iprs#[!rs] >1c#l#o#g#<1=2iprs#[!rs]
 #undef OPTSTR_xxd
-#define OPTSTR_xxd ">1c#<0>256l#o#g#<1=2iprs#[!rs]"
+#define OPTSTR_xxd ">1c#l#o#g#<1=2iprs#[!rs]"
 #ifdef CLEANUP_xxd
 #undef CLEANUP_xxd
 #undef FOR_xxd
@@ -3732,7 +3626,6 @@
 #endif
 
 #ifdef FOR_acpi
-#define CLEANUP_acpi
 #ifndef TT
 #define TT this.acpi
 #endif
@@ -3744,14 +3637,12 @@
 #endif
 
 #ifdef FOR_arch
-#define CLEANUP_arch
 #ifndef TT
 #define TT this.arch
 #endif
 #endif
 
 #ifdef FOR_arp
-#define CLEANUP_arp
 #ifndef TT
 #define TT this.arp
 #endif
@@ -3768,7 +3659,6 @@
 #endif
 
 #ifdef FOR_arping
-#define CLEANUP_arping
 #ifndef TT
 #define TT this.arping
 #endif
@@ -3785,14 +3675,12 @@
 #endif
 
 #ifdef FOR_ascii
-#define CLEANUP_ascii
 #ifndef TT
 #define TT this.ascii
 #endif
 #endif
 
 #ifdef FOR_base32
-#define CLEANUP_base32
 #ifndef TT
 #define TT this.base32
 #endif
@@ -3802,7 +3690,6 @@
 #endif
 
 #ifdef FOR_base64
-#define CLEANUP_base64
 #ifndef TT
 #define TT this.base64
 #endif
@@ -3812,7 +3699,6 @@
 #endif
 
 #ifdef FOR_basename
-#define CLEANUP_basename
 #ifndef TT
 #define TT this.basename
 #endif
@@ -3821,7 +3707,6 @@
 #endif
 
 #ifdef FOR_bc
-#define CLEANUP_bc
 #ifndef TT
 #define TT this.bc
 #endif
@@ -3833,7 +3718,6 @@
 #endif
 
 #ifdef FOR_blkdiscard
-#define CLEANUP_blkdiscard
 #ifndef TT
 #define TT this.blkdiscard
 #endif
@@ -3845,7 +3729,6 @@
 #endif
 
 #ifdef FOR_blkid
-#define CLEANUP_blkid
 #ifndef TT
 #define TT this.blkid
 #endif
@@ -3855,7 +3738,6 @@
 #endif
 
 #ifdef FOR_blockdev
-#define CLEANUP_blockdev
 #ifndef TT
 #define TT this.blockdev
 #endif
@@ -3875,21 +3757,18 @@
 #endif
 
 #ifdef FOR_bootchartd
-#define CLEANUP_bootchartd
 #ifndef TT
 #define TT this.bootchartd
 #endif
 #endif
 
 #ifdef FOR_brctl
-#define CLEANUP_brctl
 #ifndef TT
 #define TT this.brctl
 #endif
 #endif
 
 #ifdef FOR_bunzip2
-#define CLEANUP_bunzip2
 #ifndef TT
 #define TT this.bunzip2
 #endif
@@ -3901,14 +3780,12 @@
 #endif
 
 #ifdef FOR_bzcat
-#define CLEANUP_bzcat
 #ifndef TT
 #define TT this.bzcat
 #endif
 #endif
 
 #ifdef FOR_cal
-#define CLEANUP_cal
 #ifndef TT
 #define TT this.cal
 #endif
@@ -3916,7 +3793,6 @@
 #endif
 
 #ifdef FOR_cat
-#define CLEANUP_cat
 #ifndef TT
 #define TT this.cat
 #endif
@@ -3927,7 +3803,6 @@
 #endif
 
 #ifdef FOR_catv
-#define CLEANUP_catv
 #ifndef TT
 #define TT this.catv
 #endif
@@ -3937,7 +3812,6 @@
 #endif
 
 #ifdef FOR_cd
-#define CLEANUP_cd
 #ifndef TT
 #define TT this.cd
 #endif
@@ -3946,7 +3820,6 @@
 #endif
 
 #ifdef FOR_chattr
-#define CLEANUP_chattr
 #ifndef TT
 #define TT this.chattr
 #endif
@@ -3956,7 +3829,6 @@
 #endif
 
 #ifdef FOR_chcon
-#define CLEANUP_chcon
 #ifndef TT
 #define TT this.chcon
 #endif
@@ -3966,7 +3838,6 @@
 #endif
 
 #ifdef FOR_chgrp
-#define CLEANUP_chgrp
 #ifndef TT
 #define TT this.chgrp
 #endif
@@ -3980,7 +3851,6 @@
 #endif
 
 #ifdef FOR_chmod
-#define CLEANUP_chmod
 #ifndef TT
 #define TT this.chmod
 #endif
@@ -3990,14 +3860,12 @@
 #endif
 
 #ifdef FOR_chroot
-#define CLEANUP_chroot
 #ifndef TT
 #define TT this.chroot
 #endif
 #endif
 
 #ifdef FOR_chrt
-#define CLEANUP_chrt
 #ifndef TT
 #define TT this.chrt
 #endif
@@ -4012,7 +3880,6 @@
 #endif
 
 #ifdef FOR_chsh
-#define CLEANUP_chsh
 #ifndef TT
 #define TT this.chsh
 #endif
@@ -4020,14 +3887,12 @@
 #endif
 
 #ifdef FOR_chvt
-#define CLEANUP_chvt
 #ifndef TT
 #define TT this.chvt
 #endif
 #endif
 
 #ifdef FOR_cksum
-#define CLEANUP_cksum
 #ifndef TT
 #define TT this.cksum
 #endif
@@ -4039,24 +3904,20 @@
 #endif
 
 #ifdef FOR_clear
-#define CLEANUP_clear
 #ifndef TT
 #define TT this.clear
 #endif
 #endif
 
 #ifdef FOR_cmp
-#define CLEANUP_cmp
 #ifndef TT
 #define TT this.cmp
 #endif
-#define FLAG_n (1<<0)
-#define FLAG_s (1<<1)
-#define FLAG_l (1<<2)
+#define FLAG_s (1<<0)
+#define FLAG_l (1<<1)
 #endif
 
 #ifdef FOR_comm
-#define CLEANUP_comm
 #ifndef TT
 #define TT this.comm
 #endif
@@ -4066,14 +3927,12 @@
 #endif
 
 #ifdef FOR_count
-#define CLEANUP_count
 #ifndef TT
 #define TT this.count
 #endif
 #endif
 
 #ifdef FOR_cp
-#define CLEANUP_cp
 #ifndef TT
 #define TT this.cp
 #endif
@@ -4100,7 +3959,6 @@
 #endif
 
 #ifdef FOR_cpio
-#define CLEANUP_cpio
 #ifndef TT
 #define TT this.cpio
 #endif
@@ -4116,19 +3974,15 @@
 #define FLAG_m (1<<9)
 #define FLAG_no_preserve_owner (1<<10)
 #define FLAG_quiet (1<<11)
-#define FLAG_renumber_inodes (1<<12)
-#define FLAG_ignore_devno (1<<13)
 #endif
 
 #ifdef FOR_crc32
-#define CLEANUP_crc32
 #ifndef TT
 #define TT this.crc32
 #endif
 #endif
 
 #ifdef FOR_crond
-#define CLEANUP_crond
 #ifndef TT
 #define TT this.crond
 #endif
@@ -4142,7 +3996,6 @@
 #endif
 
 #ifdef FOR_crontab
-#define CLEANUP_crontab
 #ifndef TT
 #define TT this.crontab
 #endif
@@ -4154,7 +4007,6 @@
 #endif
 
 #ifdef FOR_cut
-#define CLEANUP_cut
 #ifndef TT
 #define TT this.cut
 #endif
@@ -4171,50 +4023,29 @@
 #endif
 
 #ifdef FOR_date
-#define CLEANUP_date
 #ifndef TT
 #define TT this.date
 #endif
 #define FLAG_u (1<<0)
-#define FLAG_s (1<<1)
-#define FLAG_r (1<<2)
-#define FLAG_I (1<<3)
-#define FLAG_D (1<<4)
-#define FLAG_d (1<<5)
+#define FLAG_r (1<<1)
+#define FLAG_I (1<<2)
+#define FLAG_D (1<<3)
+#define FLAG_d (1<<4)
 #endif
 
 #ifdef FOR_dd
-#define CLEANUP_dd
 #ifndef TT
 #define TT this.dd
 #endif
 #endif
 
 #ifdef FOR_deallocvt
-#define CLEANUP_deallocvt
 #ifndef TT
 #define TT this.deallocvt
 #endif
 #endif
 
-#ifdef FOR_declare
-#define CLEANUP_declare
-#ifndef TT
-#define TT this.declare
-#endif
-#define FLAG_r (FORCED_FLAG<<0)
-#define FLAG_x (FORCED_FLAG<<1)
-#define FLAG_n (FORCED_FLAG<<2)
-#define FLAG_u (FORCED_FLAG<<3)
-#define FLAG_l (FORCED_FLAG<<4)
-#define FLAG_i (FORCED_FLAG<<5)
-#define FLAG_a (FORCED_FLAG<<6)
-#define FLAG_A (FORCED_FLAG<<7)
-#define FLAG_p (FORCED_FLAG<<8)
-#endif
-
 #ifdef FOR_demo_many_options
-#define CLEANUP_demo_many_options
 #ifndef TT
 #define TT this.demo_many_options
 #endif
@@ -4273,7 +4104,6 @@
 #endif
 
 #ifdef FOR_demo_number
-#define CLEANUP_demo_number
 #ifndef TT
 #define TT this.demo_number
 #endif
@@ -4287,28 +4117,24 @@
 #endif
 
 #ifdef FOR_demo_scankey
-#define CLEANUP_demo_scankey
 #ifndef TT
 #define TT this.demo_scankey
 #endif
 #endif
 
 #ifdef FOR_demo_utf8towc
-#define CLEANUP_demo_utf8towc
 #ifndef TT
 #define TT this.demo_utf8towc
 #endif
 #endif
 
 #ifdef FOR_devmem
-#define CLEANUP_devmem
 #ifndef TT
 #define TT this.devmem
 #endif
 #endif
 
 #ifdef FOR_df
-#define CLEANUP_df
 #ifndef TT
 #define TT this.df
 #endif
@@ -4322,7 +4148,6 @@
 #endif
 
 #ifdef FOR_dhcp
-#define CLEANUP_dhcp
 #ifndef TT
 #define TT this.dhcp
 #endif
@@ -4352,7 +4177,6 @@
 #endif
 
 #ifdef FOR_dhcp6
-#define CLEANUP_dhcp6
 #ifndef TT
 #define TT this.dhcp6
 #endif
@@ -4373,7 +4197,6 @@
 #endif
 
 #ifdef FOR_dhcpd
-#define CLEANUP_dhcpd
 #ifndef TT
 #define TT this.dhcpd
 #endif
@@ -4386,7 +4209,6 @@
 #endif
 
 #ifdef FOR_diff
-#define CLEANUP_diff
 #ifndef TT
 #define TT this.diff
 #endif
@@ -4411,14 +4233,12 @@
 #endif
 
 #ifdef FOR_dirname
-#define CLEANUP_dirname
 #ifndef TT
 #define TT this.dirname
 #endif
 #endif
 
 #ifdef FOR_dmesg
-#define CLEANUP_dmesg
 #ifndef TT
 #define TT this.dmesg
 #endif
@@ -4434,21 +4254,18 @@
 #endif
 
 #ifdef FOR_dnsdomainname
-#define CLEANUP_dnsdomainname
 #ifndef TT
 #define TT this.dnsdomainname
 #endif
 #endif
 
 #ifdef FOR_dos2unix
-#define CLEANUP_dos2unix
 #ifndef TT
 #define TT this.dos2unix
 #endif
 #endif
 
 #ifdef FOR_du
-#define CLEANUP_du
 #ifndef TT
 #define TT this.du
 #endif
@@ -4468,7 +4285,6 @@
 #endif
 
 #ifdef FOR_dumpleases
-#define CLEANUP_dumpleases
 #ifndef TT
 #define TT this.dumpleases
 #endif
@@ -4478,7 +4294,6 @@
 #endif
 
 #ifdef FOR_echo
-#define CLEANUP_echo
 #ifndef TT
 #define TT this.echo
 #endif
@@ -4488,7 +4303,6 @@
 #endif
 
 #ifdef FOR_eject
-#define CLEANUP_eject
 #ifndef TT
 #define TT this.eject
 #endif
@@ -4498,7 +4312,6 @@
 #endif
 
 #ifdef FOR_env
-#define CLEANUP_env
 #ifndef TT
 #define TT this.env
 #endif
@@ -4508,14 +4321,12 @@
 #endif
 
 #ifdef FOR_eval
-#define CLEANUP_eval
 #ifndef TT
 #define TT this.eval
 #endif
 #endif
 
 #ifdef FOR_exec
-#define CLEANUP_exec
 #ifndef TT
 #define TT this.exec
 #endif
@@ -4525,14 +4336,12 @@
 #endif
 
 #ifdef FOR_exit
-#define CLEANUP_exit
 #ifndef TT
 #define TT this.exit
 #endif
 #endif
 
 #ifdef FOR_expand
-#define CLEANUP_expand
 #ifndef TT
 #define TT this.expand
 #endif
@@ -4540,7 +4349,6 @@
 #endif
 
 #ifdef FOR_export
-#define CLEANUP_export
 #ifndef TT
 #define TT this.export
 #endif
@@ -4549,21 +4357,18 @@
 #endif
 
 #ifdef FOR_expr
-#define CLEANUP_expr
 #ifndef TT
 #define TT this.expr
 #endif
 #endif
 
 #ifdef FOR_factor
-#define CLEANUP_factor
 #ifndef TT
 #define TT this.factor
 #endif
 #endif
 
 #ifdef FOR_fallocate
-#define CLEANUP_fallocate
 #ifndef TT
 #define TT this.fallocate
 #endif
@@ -4572,14 +4377,12 @@
 #endif
 
 #ifdef FOR_false
-#define CLEANUP_false
 #ifndef TT
 #define TT this.false
 #endif
 #endif
 
 #ifdef FOR_fdisk
-#define CLEANUP_fdisk
 #ifndef TT
 #define TT this.fdisk
 #endif
@@ -4592,7 +4395,6 @@
 #endif
 
 #ifdef FOR_file
-#define CLEANUP_file
 #ifndef TT
 #define TT this.file
 #endif
@@ -4603,7 +4405,6 @@
 #endif
 
 #ifdef FOR_find
-#define CLEANUP_find
 #ifndef TT
 #define TT this.find
 #endif
@@ -4612,7 +4413,6 @@
 #endif
 
 #ifdef FOR_flock
-#define CLEANUP_flock
 #ifndef TT
 #define TT this.flock
 #endif
@@ -4623,7 +4423,6 @@
 #endif
 
 #ifdef FOR_fmt
-#define CLEANUP_fmt
 #ifndef TT
 #define TT this.fmt
 #endif
@@ -4631,7 +4430,6 @@
 #endif
 
 #ifdef FOR_fold
-#define CLEANUP_fold
 #ifndef TT
 #define TT this.fold
 #endif
@@ -4642,7 +4440,6 @@
 #endif
 
 #ifdef FOR_free
-#define CLEANUP_free
 #ifndef TT
 #define TT this.free
 #endif
@@ -4650,18 +4447,17 @@
 #define FLAG_k (FORCED_FLAG<<1)
 #define FLAG_m (FORCED_FLAG<<2)
 #define FLAG_g (FORCED_FLAG<<3)
-#define FLAG_h (FORCED_FLAG<<4)
+#define FLAG_t (FORCED_FLAG<<4)
+#define FLAG_h (FORCED_FLAG<<5)
 #endif
 
 #ifdef FOR_freeramdisk
-#define CLEANUP_freeramdisk
 #ifndef TT
 #define TT this.freeramdisk
 #endif
 #endif
 
 #ifdef FOR_fsck
-#define CLEANUP_fsck
 #ifndef TT
 #define TT this.fsck
 #endif
@@ -4677,7 +4473,6 @@
 #endif
 
 #ifdef FOR_fsfreeze
-#define CLEANUP_fsfreeze
 #ifndef TT
 #define TT this.fsfreeze
 #endif
@@ -4686,14 +4481,12 @@
 #endif
 
 #ifdef FOR_fstype
-#define CLEANUP_fstype
 #ifndef TT
 #define TT this.fstype
 #endif
 #endif
 
 #ifdef FOR_fsync
-#define CLEANUP_fsync
 #ifndef TT
 #define TT this.fsync
 #endif
@@ -4701,7 +4494,6 @@
 #endif
 
 #ifdef FOR_ftpget
-#define CLEANUP_ftpget
 #ifndef TT
 #define TT this.ftpget
 #endif
@@ -4721,7 +4513,6 @@
 #endif
 
 #ifdef FOR_getconf
-#define CLEANUP_getconf
 #ifndef TT
 #define TT this.getconf
 #endif
@@ -4730,14 +4521,12 @@
 #endif
 
 #ifdef FOR_getenforce
-#define CLEANUP_getenforce
 #ifndef TT
 #define TT this.getenforce
 #endif
 #endif
 
 #ifdef FOR_getfattr
-#define CLEANUP_getfattr
 #ifndef TT
 #define TT this.getfattr
 #endif
@@ -4748,7 +4537,6 @@
 #endif
 
 #ifdef FOR_getopt
-#define CLEANUP_getopt
 #ifndef TT
 #define TT this.getopt
 #endif
@@ -4761,7 +4549,6 @@
 #endif
 
 #ifdef FOR_getty
-#define CLEANUP_getty
 #ifndef TT
 #define TT this.getty
 #endif
@@ -4778,45 +4565,7 @@
 #define FLAG_t (FORCED_FLAG<<10)
 #endif
 
-#ifdef FOR_gpiodetect
-#define CLEANUP_gpiodetect
-#ifndef TT
-#define TT this.gpiodetect
-#endif
-#endif
-
-#ifdef FOR_gpiofind
-#define CLEANUP_gpiofind
-#ifndef TT
-#define TT this.gpiofind
-#endif
-#endif
-
-#ifdef FOR_gpioget
-#define CLEANUP_gpioget
-#ifndef TT
-#define TT this.gpioget
-#endif
-#define FLAG_l (FORCED_FLAG<<0)
-#endif
-
-#ifdef FOR_gpioinfo
-#define CLEANUP_gpioinfo
-#ifndef TT
-#define TT this.gpioinfo
-#endif
-#endif
-
-#ifdef FOR_gpioset
-#define CLEANUP_gpioset
-#ifndef TT
-#define TT this.gpioset
-#endif
-#define FLAG_l (FORCED_FLAG<<0)
-#endif
-
 #ifdef FOR_grep
-#define CLEANUP_grep
 #ifndef TT
 #define TT this.grep
 #endif
@@ -4829,34 +4578,32 @@
 #define FLAG_e (1<<6)
 #define FLAG_q (1<<7)
 #define FLAG_l (1<<8)
-#define FLAG_L (1<<9)
-#define FLAG_c (1<<10)
-#define FLAG_w (1<<11)
-#define FLAG_v (1<<12)
-#define FLAG_s (1<<13)
-#define FLAG_R (1<<14)
-#define FLAG_r (1<<15)
-#define FLAG_o (1<<16)
-#define FLAG_n (1<<17)
-#define FLAG_i (1<<18)
-#define FLAG_h (1<<19)
-#define FLAG_b (1<<20)
-#define FLAG_a (1<<21)
-#define FLAG_I (1<<22)
-#define FLAG_H (1<<23)
-#define FLAG_F (1<<24)
-#define FLAG_E (1<<25)
-#define FLAG_z (1<<26)
-#define FLAG_Z (1<<27)
-#define FLAG_M (1<<28)
-#define FLAG_S (1<<29)
-#define FLAG_exclude_dir (1<<30)
-#define FLAG_color (1LL<<31)
-#define FLAG_line_buffered (1LL<<32)
+#define FLAG_c (1<<9)
+#define FLAG_w (1<<10)
+#define FLAG_v (1<<11)
+#define FLAG_s (1<<12)
+#define FLAG_R (1<<13)
+#define FLAG_r (1<<14)
+#define FLAG_o (1<<15)
+#define FLAG_n (1<<16)
+#define FLAG_i (1<<17)
+#define FLAG_h (1<<18)
+#define FLAG_b (1<<19)
+#define FLAG_a (1<<20)
+#define FLAG_I (1<<21)
+#define FLAG_H (1<<22)
+#define FLAG_F (1<<23)
+#define FLAG_E (1<<24)
+#define FLAG_z (1<<25)
+#define FLAG_Z (1<<26)
+#define FLAG_M (1<<27)
+#define FLAG_S (1<<28)
+#define FLAG_exclude_dir (1<<29)
+#define FLAG_color (1<<30)
+#define FLAG_line_buffered (1LL<<31)
 #endif
 
 #ifdef FOR_groupadd
-#define CLEANUP_groupadd
 #ifndef TT
 #define TT this.groupadd
 #endif
@@ -4865,21 +4612,18 @@
 #endif
 
 #ifdef FOR_groupdel
-#define CLEANUP_groupdel
 #ifndef TT
 #define TT this.groupdel
 #endif
 #endif
 
 #ifdef FOR_groups
-#define CLEANUP_groups
 #ifndef TT
 #define TT this.groups
 #endif
 #endif
 
 #ifdef FOR_gunzip
-#define CLEANUP_gunzip
 #ifndef TT
 #define TT this.gunzip
 #endif
@@ -4899,7 +4643,6 @@
 #endif
 
 #ifdef FOR_gzip
-#define CLEANUP_gzip
 #ifndef TT
 #define TT this.gzip
 #endif
@@ -4920,7 +4663,6 @@
 #endif
 
 #ifdef FOR_head
-#define CLEANUP_head
 #ifndef TT
 #define TT this.head
 #endif
@@ -4931,14 +4673,12 @@
 #endif
 
 #ifdef FOR_hello
-#define CLEANUP_hello
 #ifndef TT
 #define TT this.hello
 #endif
 #endif
 
 #ifdef FOR_help
-#define CLEANUP_help
 #ifndef TT
 #define TT this.help
 #endif
@@ -4947,24 +4687,7 @@
 #define FLAG_a (FORCED_FLAG<<2)
 #endif
 
-#ifdef FOR_hexdump
-#define CLEANUP_hexdump
-#ifndef TT
-#define TT this.hexdump
-#endif
-#define FLAG_x (FORCED_FLAG<<0)
-#define FLAG_v (FORCED_FLAG<<1)
-#define FLAG_s (FORCED_FLAG<<2)
-#define FLAG_o (FORCED_FLAG<<3)
-#define FLAG_n (FORCED_FLAG<<4)
-#define FLAG_d (FORCED_FLAG<<5)
-#define FLAG_C (FORCED_FLAG<<6)
-#define FLAG_c (FORCED_FLAG<<7)
-#define FLAG_b (FORCED_FLAG<<8)
-#endif
-
 #ifdef FOR_hexedit
-#define CLEANUP_hexedit
 #ifndef TT
 #define TT this.hexedit
 #endif
@@ -4972,7 +4695,6 @@
 #endif
 
 #ifdef FOR_host
-#define CLEANUP_host
 #ifndef TT
 #define TT this.host
 #endif
@@ -4982,14 +4704,12 @@
 #endif
 
 #ifdef FOR_hostid
-#define CLEANUP_hostid
 #ifndef TT
 #define TT this.hostid
 #endif
 #endif
 
 #ifdef FOR_hostname
-#define CLEANUP_hostname
 #ifndef TT
 #define TT this.hostname
 #endif
@@ -5001,7 +4721,6 @@
 #endif
 
 #ifdef FOR_hwclock
-#define CLEANUP_hwclock
 #ifndef TT
 #define TT this.hwclock
 #endif
@@ -5016,20 +4735,16 @@
 #endif
 
 #ifdef FOR_i2cdetect
-#define CLEANUP_i2cdetect
 #ifndef TT
 #define TT this.i2cdetect
 #endif
 #define FLAG_y (FORCED_FLAG<<0)
-#define FLAG_r (FORCED_FLAG<<1)
-#define FLAG_q (FORCED_FLAG<<2)
-#define FLAG_l (FORCED_FLAG<<3)
-#define FLAG_F (FORCED_FLAG<<4)
-#define FLAG_a (FORCED_FLAG<<5)
+#define FLAG_l (FORCED_FLAG<<1)
+#define FLAG_F (FORCED_FLAG<<2)
+#define FLAG_a (FORCED_FLAG<<3)
 #endif
 
 #ifdef FOR_i2cdump
-#define CLEANUP_i2cdump
 #ifndef TT
 #define TT this.i2cdump
 #endif
@@ -5038,7 +4753,6 @@
 #endif
 
 #ifdef FOR_i2cget
-#define CLEANUP_i2cget
 #ifndef TT
 #define TT this.i2cget
 #endif
@@ -5047,7 +4761,6 @@
 #endif
 
 #ifdef FOR_i2cset
-#define CLEANUP_i2cset
 #ifndef TT
 #define TT this.i2cset
 #endif
@@ -5056,7 +4769,6 @@
 #endif
 
 #ifdef FOR_iconv
-#define CLEANUP_iconv
 #ifndef TT
 #define TT this.iconv
 #endif
@@ -5067,7 +4779,6 @@
 #endif
 
 #ifdef FOR_id
-#define CLEANUP_id
 #ifndef TT
 #define TT this.id
 #endif
@@ -5080,7 +4791,6 @@
 #endif
 
 #ifdef FOR_ifconfig
-#define CLEANUP_ifconfig
 #ifndef TT
 #define TT this.ifconfig
 #endif
@@ -5089,45 +4799,40 @@
 #endif
 
 #ifdef FOR_init
-#define CLEANUP_init
 #ifndef TT
 #define TT this.init
 #endif
 #endif
 
 #ifdef FOR_inotifyd
-#define CLEANUP_inotifyd
 #ifndef TT
 #define TT this.inotifyd
 #endif
 #endif
 
 #ifdef FOR_insmod
-#define CLEANUP_insmod
 #ifndef TT
 #define TT this.insmod
 #endif
 #endif
 
 #ifdef FOR_install
-#define CLEANUP_install
 #ifndef TT
 #define TT this.install
 #endif
-#define FLAG_g (1<<0)
-#define FLAG_o (1<<1)
-#define FLAG_m (1<<2)
-#define FLAG_t (1<<3)
-#define FLAG_v (1<<4)
-#define FLAG_s (1<<5)
-#define FLAG_p (1<<6)
-#define FLAG_D (1<<7)
-#define FLAG_d (1<<8)
-#define FLAG_c (1<<9)
+#define FLAG_g (FORCED_FLAG<<0)
+#define FLAG_o (FORCED_FLAG<<1)
+#define FLAG_m (FORCED_FLAG<<2)
+#define FLAG_t (FORCED_FLAG<<3)
+#define FLAG_v (FORCED_FLAG<<4)
+#define FLAG_s (FORCED_FLAG<<5)
+#define FLAG_p (FORCED_FLAG<<6)
+#define FLAG_D (FORCED_FLAG<<7)
+#define FLAG_d (FORCED_FLAG<<8)
+#define FLAG_c (FORCED_FLAG<<9)
 #endif
 
 #ifdef FOR_ionice
-#define CLEANUP_ionice
 #ifndef TT
 #define TT this.ionice
 #endif
@@ -5138,14 +4843,12 @@
 #endif
 
 #ifdef FOR_iorenice
-#define CLEANUP_iorenice
 #ifndef TT
 #define TT this.iorenice
 #endif
 #endif
 
 #ifdef FOR_iotop
-#define CLEANUP_iotop
 #ifndef TT
 #define TT this.iotop
 #endif
@@ -5167,14 +4870,12 @@
 #endif
 
 #ifdef FOR_ip
-#define CLEANUP_ip
 #ifndef TT
 #define TT this.ip
 #endif
 #endif
 
 #ifdef FOR_ipcrm
-#define CLEANUP_ipcrm
 #ifndef TT
 #define TT this.ipcrm
 #endif
@@ -5187,7 +4888,6 @@
 #endif
 
 #ifdef FOR_ipcs
-#define CLEANUP_ipcs
 #ifndef TT
 #define TT this.ipcs
 #endif
@@ -5204,7 +4904,6 @@
 #endif
 
 #ifdef FOR_jobs
-#define CLEANUP_jobs
 #ifndef TT
 #define TT this.jobs
 #endif
@@ -5216,7 +4915,6 @@
 #endif
 
 #ifdef FOR_kill
-#define CLEANUP_kill
 #ifndef TT
 #define TT this.kill
 #endif
@@ -5225,7 +4923,6 @@
 #endif
 
 #ifdef FOR_killall
-#define CLEANUP_killall
 #ifndef TT
 #define TT this.killall
 #endif
@@ -5238,7 +4935,6 @@
 #endif
 
 #ifdef FOR_killall5
-#define CLEANUP_killall5
 #ifndef TT
 #define TT this.killall5
 #endif
@@ -5248,7 +4944,6 @@
 #endif
 
 #ifdef FOR_klogd
-#define CLEANUP_klogd
 #ifndef TT
 #define TT this.klogd
 #endif
@@ -5257,7 +4952,6 @@
 #endif
 
 #ifdef FOR_last
-#define CLEANUP_last
 #ifndef TT
 #define TT this.last
 #endif
@@ -5266,21 +4960,12 @@
 #endif
 
 #ifdef FOR_link
-#define CLEANUP_link
 #ifndef TT
 #define TT this.link
 #endif
 #endif
 
-#ifdef FOR_linux32
-#define CLEANUP_linux32
-#ifndef TT
-#define TT this.linux32
-#endif
-#endif
-
 #ifdef FOR_ln
-#define CLEANUP_ln
 #ifndef TT
 #define TT this.ln
 #endif
@@ -5294,14 +4979,12 @@
 #endif
 
 #ifdef FOR_load_policy
-#define CLEANUP_load_policy
 #ifndef TT
 #define TT this.load_policy
 #endif
 #endif
 
 #ifdef FOR_log
-#define CLEANUP_log
 #ifndef TT
 #define TT this.log
 #endif
@@ -5310,7 +4993,6 @@
 #endif
 
 #ifdef FOR_logger
-#define CLEANUP_logger
 #ifndef TT
 #define TT this.logger
 #endif
@@ -5320,7 +5002,6 @@
 #endif
 
 #ifdef FOR_login
-#define CLEANUP_login
 #ifndef TT
 #define TT this.login
 #endif
@@ -5330,21 +5011,18 @@
 #endif
 
 #ifdef FOR_logname
-#define CLEANUP_logname
 #ifndef TT
 #define TT this.logname
 #endif
 #endif
 
-#ifdef FOR_logpath
-#define CLEANUP_logpath
+#ifdef FOR_logwrapper
 #ifndef TT
-#define TT this.logpath
+#define TT this.logwrapper
 #endif
 #endif
 
 #ifdef FOR_losetup
-#define CLEANUP_losetup
 #ifndef TT
 #define TT this.losetup
 #endif
@@ -5361,7 +5039,6 @@
 #endif
 
 #ifdef FOR_ls
-#define CLEANUP_ls
 #ifndef TT
 #define TT this.ls
 #endif
@@ -5401,7 +5078,6 @@
 #endif
 
 #ifdef FOR_lsattr
-#define CLEANUP_lsattr
 #ifndef TT
 #define TT this.lsattr
 #endif
@@ -5414,14 +5090,12 @@
 #endif
 
 #ifdef FOR_lsmod
-#define CLEANUP_lsmod
 #ifndef TT
 #define TT this.lsmod
 #endif
 #endif
 
 #ifdef FOR_lsof
-#define CLEANUP_lsof
 #ifndef TT
 #define TT this.lsof
 #endif
@@ -5431,7 +5105,6 @@
 #endif
 
 #ifdef FOR_lspci
-#define CLEANUP_lspci
 #ifndef TT
 #define TT this.lspci
 #endif
@@ -5443,15 +5116,12 @@
 #endif
 
 #ifdef FOR_lsusb
-#define CLEANUP_lsusb
 #ifndef TT
 #define TT this.lsusb
 #endif
-#define FLAG_i (FORCED_FLAG<<0)
 #endif
 
 #ifdef FOR_makedevs
-#define CLEANUP_makedevs
 #ifndef TT
 #define TT this.makedevs
 #endif
@@ -5459,7 +5129,6 @@
 #endif
 
 #ifdef FOR_man
-#define CLEANUP_man
 #ifndef TT
 #define TT this.man
 #endif
@@ -5468,7 +5137,6 @@
 #endif
 
 #ifdef FOR_mcookie
-#define CLEANUP_mcookie
 #ifndef TT
 #define TT this.mcookie
 #endif
@@ -5477,7 +5145,6 @@
 #endif
 
 #ifdef FOR_md5sum
-#define CLEANUP_md5sum
 #ifndef TT
 #define TT this.md5sum
 #endif
@@ -5487,7 +5154,6 @@
 #endif
 
 #ifdef FOR_mdev
-#define CLEANUP_mdev
 #ifndef TT
 #define TT this.mdev
 #endif
@@ -5495,7 +5161,6 @@
 #endif
 
 #ifdef FOR_microcom
-#define CLEANUP_microcom
 #ifndef TT
 #define TT this.microcom
 #endif
@@ -5504,7 +5169,6 @@
 #endif
 
 #ifdef FOR_mix
-#define CLEANUP_mix
 #ifndef TT
 #define TT this.mix
 #endif
@@ -5515,7 +5179,6 @@
 #endif
 
 #ifdef FOR_mkdir
-#define CLEANUP_mkdir
 #ifndef TT
 #define TT this.mkdir
 #endif
@@ -5526,7 +5189,6 @@
 #endif
 
 #ifdef FOR_mke2fs
-#define CLEANUP_mke2fs
 #ifndef TT
 #define TT this.mke2fs
 #endif
@@ -5541,7 +5203,6 @@
 #endif
 
 #ifdef FOR_mkfifo
-#define CLEANUP_mkfifo
 #ifndef TT
 #define TT this.mkfifo
 #endif
@@ -5550,7 +5211,6 @@
 #endif
 
 #ifdef FOR_mknod
-#define CLEANUP_mknod
 #ifndef TT
 #define TT this.mknod
 #endif
@@ -5559,7 +5219,6 @@
 #endif
 
 #ifdef FOR_mkpasswd
-#define CLEANUP_mkpasswd
 #ifndef TT
 #define TT this.mkpasswd
 #endif
@@ -5569,7 +5228,6 @@
 #endif
 
 #ifdef FOR_mkswap
-#define CLEANUP_mkswap
 #ifndef TT
 #define TT this.mkswap
 #endif
@@ -5577,7 +5235,6 @@
 #endif
 
 #ifdef FOR_mktemp
-#define CLEANUP_mktemp
 #ifndef TT
 #define TT this.mktemp
 #endif
@@ -5590,7 +5247,6 @@
 #endif
 
 #ifdef FOR_modinfo
-#define CLEANUP_modinfo
 #ifndef TT
 #define TT this.modinfo
 #endif
@@ -5601,7 +5257,6 @@
 #endif
 
 #ifdef FOR_modprobe
-#define CLEANUP_modprobe
 #ifndef TT
 #define TT this.modprobe
 #endif
@@ -5617,14 +5272,12 @@
 #endif
 
 #ifdef FOR_more
-#define CLEANUP_more
 #ifndef TT
 #define TT this.more
 #endif
 #endif
 
 #ifdef FOR_mount
-#define CLEANUP_mount
 #ifndef TT
 #define TT this.mount
 #endif
@@ -5640,7 +5293,6 @@
 #endif
 
 #ifdef FOR_mountpoint
-#define CLEANUP_mountpoint
 #ifndef TT
 #define TT this.mountpoint
 #endif
@@ -5650,7 +5302,6 @@
 #endif
 
 #ifdef FOR_mv
-#define CLEANUP_mv
 #ifndef TT
 #define TT this.mv
 #endif
@@ -5664,7 +5315,6 @@
 #endif
 
 #ifdef FOR_nbd_client
-#define CLEANUP_nbd_client
 #ifndef TT
 #define TT this.nbd_client
 #endif
@@ -5673,7 +5323,6 @@
 #endif
 
 #ifdef FOR_netcat
-#define CLEANUP_netcat
 #ifndef TT
 #define TT this.netcat
 #endif
@@ -5694,7 +5343,6 @@
 #endif
 
 #ifdef FOR_netstat
-#define CLEANUP_netstat
 #ifndef TT
 #define TT this.netstat
 #endif
@@ -5712,7 +5360,6 @@
 #endif
 
 #ifdef FOR_nice
-#define CLEANUP_nice
 #ifndef TT
 #define TT this.nice
 #endif
@@ -5720,28 +5367,25 @@
 #endif
 
 #ifdef FOR_nl
-#define CLEANUP_nl
 #ifndef TT
 #define TT this.nl
 #endif
-#define FLAG_E (1<<0)
-#define FLAG_s (1<<1)
-#define FLAG_n (1<<2)
-#define FLAG_b (1<<3)
+#define FLAG_s (1<<0)
+#define FLAG_n (1<<1)
+#define FLAG_b (1<<2)
+#define FLAG_E (1<<3)
 #define FLAG_w (1<<4)
 #define FLAG_l (1<<5)
 #define FLAG_v (1<<6)
 #endif
 
 #ifdef FOR_nohup
-#define CLEANUP_nohup
 #ifndef TT
 #define TT this.nohup
 #endif
 #endif
 
 #ifdef FOR_nproc
-#define CLEANUP_nproc
 #ifndef TT
 #define TT this.nproc
 #endif
@@ -5749,7 +5393,6 @@
 #endif
 
 #ifdef FOR_nsenter
-#define CLEANUP_nsenter
 #ifndef TT
 #define TT this.nsenter
 #endif
@@ -5764,7 +5407,6 @@
 #endif
 
 #ifdef FOR_od
-#define CLEANUP_od
 #ifndef TT
 #define TT this.od
 #endif
@@ -5783,7 +5425,6 @@
 #endif
 
 #ifdef FOR_oneit
-#define CLEANUP_oneit
 #ifndef TT
 #define TT this.oneit
 #endif
@@ -5794,7 +5435,6 @@
 #endif
 
 #ifdef FOR_openvt
-#define CLEANUP_openvt
 #ifndef TT
 #define TT this.openvt
 #endif
@@ -5804,14 +5444,12 @@
 #endif
 
 #ifdef FOR_partprobe
-#define CLEANUP_partprobe
 #ifndef TT
 #define TT this.partprobe
 #endif
 #endif
 
 #ifdef FOR_passwd
-#define CLEANUP_passwd
 #ifndef TT
 #define TT this.passwd
 #endif
@@ -5822,7 +5460,6 @@
 #endif
 
 #ifdef FOR_paste
-#define CLEANUP_paste
 #ifndef TT
 #define TT this.paste
 #endif
@@ -5831,7 +5468,6 @@
 #endif
 
 #ifdef FOR_patch
-#define CLEANUP_patch
 #ifndef TT
 #define TT this.patch
 #endif
@@ -5851,7 +5487,6 @@
 #endif
 
 #ifdef FOR_pgrep
-#define CLEANUP_pgrep
 #ifndef TT
 #define TT this.pgrep
 #endif
@@ -5874,7 +5509,6 @@
 #endif
 
 #ifdef FOR_pidof
-#define CLEANUP_pidof
 #ifndef TT
 #define TT this.pidof
 #endif
@@ -5884,7 +5518,6 @@
 #endif
 
 #ifdef FOR_ping
-#define CLEANUP_ping
 #ifndef TT
 #define TT this.ping
 #endif
@@ -5903,14 +5536,12 @@
 #endif
 
 #ifdef FOR_pivot_root
-#define CLEANUP_pivot_root
 #ifndef TT
 #define TT this.pivot_root
 #endif
 #endif
 
 #ifdef FOR_pkill
-#define CLEANUP_pkill
 #ifndef TT
 #define TT this.pkill
 #endif
@@ -5931,17 +5562,14 @@
 #endif
 
 #ifdef FOR_pmap
-#define CLEANUP_pmap
 #ifndef TT
 #define TT this.pmap
 #endif
-#define FLAG_x (FORCED_FLAG<<0)
-#define FLAG_q (FORCED_FLAG<<1)
-#define FLAG_p (FORCED_FLAG<<2)
+#define FLAG_q (FORCED_FLAG<<0)
+#define FLAG_x (FORCED_FLAG<<1)
 #endif
 
 #ifdef FOR_printenv
-#define CLEANUP_printenv
 #ifndef TT
 #define TT this.printenv
 #endif
@@ -5950,14 +5578,12 @@
 #endif
 
 #ifdef FOR_printf
-#define CLEANUP_printf
 #ifndef TT
 #define TT this.printf
 #endif
 #endif
 
 #ifdef FOR_ps
-#define CLEANUP_ps
 #ifndef TT
 #define TT this.ps
 #endif
@@ -5986,7 +5612,6 @@
 #endif
 
 #ifdef FOR_pwd
-#define CLEANUP_pwd
 #ifndef TT
 #define TT this.pwd
 #endif
@@ -5995,7 +5620,6 @@
 #endif
 
 #ifdef FOR_pwdx
-#define CLEANUP_pwdx
 #ifndef TT
 #define TT this.pwdx
 #endif
@@ -6003,7 +5627,6 @@
 #endif
 
 #ifdef FOR_pwgen
-#define CLEANUP_pwgen
 #ifndef TT
 #define TT this.pwgen
 #endif
@@ -6022,14 +5645,12 @@
 #endif
 
 #ifdef FOR_readahead
-#define CLEANUP_readahead
 #ifndef TT
 #define TT this.readahead
 #endif
 #endif
 
 #ifdef FOR_readelf
-#define CLEANUP_readelf
 #ifndef TT
 #define TT this.readelf
 #endif
@@ -6048,7 +5669,6 @@
 #endif
 
 #ifdef FOR_readlink
-#define CLEANUP_readlink
 #ifndef TT
 #define TT this.readlink
 #endif
@@ -6059,18 +5679,21 @@
 #define FLAG_n (1<<4)
 #endif
 
+#ifdef FOR_realpath
+#ifndef TT
+#define TT this.realpath
+#endif
+#endif
+
 #ifdef FOR_reboot
-#define CLEANUP_reboot
 #ifndef TT
 #define TT this.reboot
 #endif
 #define FLAG_n (FORCED_FLAG<<0)
 #define FLAG_f (FORCED_FLAG<<1)
-#define FLAG_d (FORCED_FLAG<<2)
 #endif
 
 #ifdef FOR_renice
-#define CLEANUP_renice
 #ifndef TT
 #define TT this.renice
 #endif
@@ -6081,14 +5704,12 @@
 #endif
 
 #ifdef FOR_reset
-#define CLEANUP_reset
 #ifndef TT
 #define TT this.reset
 #endif
 #endif
 
 #ifdef FOR_restorecon
-#define CLEANUP_restorecon
 #ifndef TT
 #define TT this.restorecon
 #endif
@@ -6101,21 +5722,18 @@
 #endif
 
 #ifdef FOR_rev
-#define CLEANUP_rev
 #ifndef TT
 #define TT this.rev
 #endif
 #endif
 
 #ifdef FOR_rfkill
-#define CLEANUP_rfkill
 #ifndef TT
 #define TT this.rfkill
 #endif
 #endif
 
 #ifdef FOR_rm
-#define CLEANUP_rm
 #ifndef TT
 #define TT this.rm
 #endif
@@ -6127,7 +5745,6 @@
 #endif
 
 #ifdef FOR_rmdir
-#define CLEANUP_rmdir
 #ifndef TT
 #define TT this.rmdir
 #endif
@@ -6136,7 +5753,6 @@
 #endif
 
 #ifdef FOR_rmmod
-#define CLEANUP_rmmod
 #ifndef TT
 #define TT this.rmmod
 #endif
@@ -6145,7 +5761,6 @@
 #endif
 
 #ifdef FOR_route
-#define CLEANUP_route
 #ifndef TT
 #define TT this.route
 #endif
@@ -6155,7 +5770,6 @@
 #endif
 
 #ifdef FOR_rtcwake
-#define CLEANUP_rtcwake
 #ifndef TT
 #define TT this.rtcwake
 #endif
@@ -6172,14 +5786,12 @@
 #endif
 
 #ifdef FOR_runcon
-#define CLEANUP_runcon
 #ifndef TT
 #define TT this.runcon
 #endif
 #endif
 
 #ifdef FOR_sed
-#define CLEANUP_sed
 #ifndef TT
 #define TT this.sed
 #endif
@@ -6196,14 +5808,12 @@
 #endif
 
 #ifdef FOR_sendevent
-#define CLEANUP_sendevent
 #ifndef TT
 #define TT this.sendevent
 #endif
 #endif
 
 #ifdef FOR_seq
-#define CLEANUP_seq
 #ifndef TT
 #define TT this.seq
 #endif
@@ -6213,21 +5823,18 @@
 #endif
 
 #ifdef FOR_set
-#define CLEANUP_set
 #ifndef TT
 #define TT this.set
 #endif
 #endif
 
 #ifdef FOR_setenforce
-#define CLEANUP_setenforce
 #ifndef TT
 #define TT this.setenforce
 #endif
 #endif
 
 #ifdef FOR_setfattr
-#define CLEANUP_setfattr
 #ifndef TT
 #define TT this.setfattr
 #endif
@@ -6238,7 +5845,6 @@
 #endif
 
 #ifdef FOR_setsid
-#define CLEANUP_setsid
 #ifndef TT
 #define TT this.setsid
 #endif
@@ -6248,7 +5854,6 @@
 #endif
 
 #ifdef FOR_sh
-#define CLEANUP_sh
 #ifndef TT
 #define TT this.sh
 #endif
@@ -6260,8 +5865,16 @@
 #define FLAG_noediting (FORCED_FLAG<<5)
 #endif
 
+#ifdef FOR_sha1sum
+#ifndef TT
+#define TT this.sha1sum
+#endif
+#define FLAG_s (1<<0)
+#define FLAG_c (1<<1)
+#define FLAG_b (1<<2)
+#endif
+
 #ifdef FOR_sha3sum
-#define CLEANUP_sha3sum
 #ifndef TT
 #define TT this.sha3sum
 #endif
@@ -6271,14 +5884,12 @@
 #endif
 
 #ifdef FOR_shift
-#define CLEANUP_shift
 #ifndef TT
 #define TT this.shift
 #endif
 #endif
 
 #ifdef FOR_shred
-#define CLEANUP_shred
 #ifndef TT
 #define TT this.shred
 #endif
@@ -6292,7 +5903,6 @@
 #endif
 
 #ifdef FOR_skeleton
-#define CLEANUP_skeleton
 #ifndef TT
 #define TT this.skeleton
 #endif
@@ -6307,7 +5917,6 @@
 #endif
 
 #ifdef FOR_skeleton_alias
-#define CLEANUP_skeleton_alias
 #ifndef TT
 #define TT this.skeleton_alias
 #endif
@@ -6317,14 +5926,12 @@
 #endif
 
 #ifdef FOR_sleep
-#define CLEANUP_sleep
 #ifndef TT
 #define TT this.sleep
 #endif
 #endif
 
 #ifdef FOR_sntp
-#define CLEANUP_sntp
 #ifndef TT
 #define TT this.sntp
 #endif
@@ -6342,7 +5949,6 @@
 #endif
 
 #ifdef FOR_sort
-#define CLEANUP_sort
 #ifndef TT
 #define TT this.sort
 #endif
@@ -6369,25 +5975,21 @@
 #endif
 
 #ifdef FOR_source
-#define CLEANUP_source
 #ifndef TT
 #define TT this.source
 #endif
 #endif
 
 #ifdef FOR_split
-#define CLEANUP_split
 #ifndef TT
 #define TT this.split
 #endif
-#define FLAG_n (FORCED_FLAG<<0)
-#define FLAG_l (FORCED_FLAG<<1)
-#define FLAG_b (FORCED_FLAG<<2)
-#define FLAG_a (FORCED_FLAG<<3)
+#define FLAG_l (FORCED_FLAG<<0)
+#define FLAG_b (FORCED_FLAG<<1)
+#define FLAG_a (FORCED_FLAG<<2)
 #endif
 
 #ifdef FOR_stat
-#define CLEANUP_stat
 #ifndef TT
 #define TT this.stat
 #endif
@@ -6397,18 +5999,7 @@
 #define FLAG_c (1<<3)
 #endif
 
-#ifdef FOR_strace
-#define CLEANUP_strace
-#ifndef TT
-#define TT this.strace
-#endif
-#define FLAG_v (FORCED_FLAG<<0)
-#define FLAG_s (FORCED_FLAG<<1)
-#define FLAG_p (FORCED_FLAG<<2)
-#endif
-
 #ifdef FOR_strings
-#define CLEANUP_strings
 #ifndef TT
 #define TT this.strings
 #endif
@@ -6420,7 +6011,6 @@
 #endif
 
 #ifdef FOR_stty
-#define CLEANUP_stty
 #ifndef TT
 #define TT this.stty
 #endif
@@ -6430,7 +6020,6 @@
 #endif
 
 #ifdef FOR_su
-#define CLEANUP_su
 #ifndef TT
 #define TT this.su
 #endif
@@ -6444,7 +6033,6 @@
 #endif
 
 #ifdef FOR_sulogin
-#define CLEANUP_sulogin
 #ifndef TT
 #define TT this.sulogin
 #endif
@@ -6452,14 +6040,12 @@
 #endif
 
 #ifdef FOR_swapoff
-#define CLEANUP_swapoff
 #ifndef TT
 #define TT this.swapoff
 #endif
 #endif
 
 #ifdef FOR_swapon
-#define CLEANUP_swapon
 #ifndef TT
 #define TT this.swapon
 #endif
@@ -6468,7 +6054,6 @@
 #endif
 
 #ifdef FOR_switch_root
-#define CLEANUP_switch_root
 #ifndef TT
 #define TT this.switch_root
 #endif
@@ -6477,14 +6062,12 @@
 #endif
 
 #ifdef FOR_sync
-#define CLEANUP_sync
 #ifndef TT
 #define TT this.sync
 #endif
 #endif
 
 #ifdef FOR_sysctl
-#define CLEANUP_sysctl
 #ifndef TT
 #define TT this.sysctl
 #endif
@@ -6499,7 +6082,6 @@
 #endif
 
 #ifdef FOR_syslogd
-#define CLEANUP_syslogd
 #ifndef TT
 #define TT this.syslogd
 #endif
@@ -6520,26 +6102,21 @@
 #endif
 
 #ifdef FOR_tac
-#define CLEANUP_tac
 #ifndef TT
 #define TT this.tac
 #endif
 #endif
 
 #ifdef FOR_tail
-#define CLEANUP_tail
 #ifndef TT
 #define TT this.tail
 #endif
 #define FLAG_n (1<<0)
 #define FLAG_c (1<<1)
-#define FLAG_s (1<<2)
-#define FLAG_F (1<<3)
-#define FLAG_f (1<<4)
+#define FLAG_f (1<<2)
 #endif
 
 #ifdef FOR_tar
-#define CLEANUP_tar
 #ifndef TT
 #define TT this.tar
 #endif
@@ -6576,12 +6153,9 @@
 #define FLAG_no_recursion (1<<30)
 #define FLAG_full_time (1LL<<31)
 #define FLAG_restrict (1LL<<32)
-#define FLAG_selinux (1LL<<33)
-#define FLAG_strip_components (1LL<<34)
 #endif
 
 #ifdef FOR_taskset
-#define CLEANUP_taskset
 #ifndef TT
 #define TT this.taskset
 #endif
@@ -6590,7 +6164,6 @@
 #endif
 
 #ifdef FOR_tcpsvd
-#define CLEANUP_tcpsvd
 #ifndef TT
 #define TT this.tcpsvd
 #endif
@@ -6605,7 +6178,6 @@
 #endif
 
 #ifdef FOR_tee
-#define CLEANUP_tee
 #ifndef TT
 #define TT this.tee
 #endif
@@ -6614,14 +6186,12 @@
 #endif
 
 #ifdef FOR_telnet
-#define CLEANUP_telnet
 #ifndef TT
 #define TT this.telnet
 #endif
 #endif
 
 #ifdef FOR_telnetd
-#define CLEANUP_telnetd
 #ifndef TT
 #define TT this.telnetd
 #endif
@@ -6637,14 +6207,12 @@
 #endif
 
 #ifdef FOR_test
-#define CLEANUP_test
 #ifndef TT
 #define TT this.test
 #endif
 #endif
 
 #ifdef FOR_tftp
-#define CLEANUP_tftp
 #ifndef TT
 #define TT this.tftp
 #endif
@@ -6656,7 +6224,6 @@
 #endif
 
 #ifdef FOR_tftpd
-#define CLEANUP_tftpd
 #ifndef TT
 #define TT this.tftpd
 #endif
@@ -6667,7 +6234,6 @@
 #endif
 
 #ifdef FOR_time
-#define CLEANUP_time
 #ifndef TT
 #define TT this.time
 #endif
@@ -6676,7 +6242,6 @@
 #endif
 
 #ifdef FOR_timeout
-#define CLEANUP_timeout
 #ifndef TT
 #define TT this.timeout
 #endif
@@ -6688,7 +6253,6 @@
 #endif
 
 #ifdef FOR_top
-#define CLEANUP_top
 #ifndef TT
 #define TT this.top
 #endif
@@ -6703,12 +6267,10 @@
 #define FLAG_o (FORCED_FLAG<<8)
 #define FLAG_k (FORCED_FLAG<<9)
 #define FLAG_H (FORCED_FLAG<<10)
-#define FLAG_h (FORCED_FLAG<<11)
-#define FLAG_O (FORCED_FLAG<<12)
+#define FLAG_O (FORCED_FLAG<<11)
 #endif
 
 #ifdef FOR_touch
-#define CLEANUP_touch
 #ifndef TT
 #define TT this.touch
 #endif
@@ -6723,14 +6285,12 @@
 #endif
 
 #ifdef FOR_toybox
-#define CLEANUP_toybox
 #ifndef TT
 #define TT this.toybox
 #endif
 #endif
 
 #ifdef FOR_tr
-#define CLEANUP_tr
 #ifndef TT
 #define TT this.tr
 #endif
@@ -6741,7 +6301,6 @@
 #endif
 
 #ifdef FOR_traceroute
-#define CLEANUP_traceroute
 #ifndef TT
 #define TT this.traceroute
 #endif
@@ -6768,14 +6327,12 @@
 #endif
 
 #ifdef FOR_true
-#define CLEANUP_true
 #ifndef TT
 #define TT this.true
 #endif
 #endif
 
 #ifdef FOR_truncate
-#define CLEANUP_truncate
 #ifndef TT
 #define TT this.truncate
 #endif
@@ -6784,7 +6341,6 @@
 #endif
 
 #ifdef FOR_tty
-#define CLEANUP_tty
 #ifndef TT
 #define TT this.tty
 #endif
@@ -6792,7 +6348,6 @@
 #endif
 
 #ifdef FOR_tunctl
-#define CLEANUP_tunctl
 #ifndef TT
 #define TT this.tunctl
 #endif
@@ -6802,20 +6357,7 @@
 #define FLAG_t (FORCED_FLAG<<3)
 #endif
 
-#ifdef FOR_uclampset
-#define CLEANUP_uclampset
-#ifndef TT
-#define TT this.uclampset
-#endif
-#define FLAG_R (FORCED_FLAG<<0)
-#define FLAG_M (FORCED_FLAG<<1)
-#define FLAG_m (FORCED_FLAG<<2)
-#define FLAG_a (FORCED_FLAG<<3)
-#define FLAG_p (FORCED_FLAG<<4)
-#endif
-
 #ifdef FOR_ulimit
-#define CLEANUP_ulimit
 #ifndef TT
 #define TT this.ulimit
 #endif
@@ -6842,7 +6384,6 @@
 #endif
 
 #ifdef FOR_umount
-#define CLEANUP_umount
 #ifndef TT
 #define TT this.umount
 #endif
@@ -6859,7 +6400,6 @@
 #endif
 
 #ifdef FOR_uname
-#define CLEANUP_uname
 #ifndef TT
 #define TT this.uname
 #endif
@@ -6868,19 +6408,17 @@
 #define FLAG_r (1<<2)
 #define FLAG_v (1<<3)
 #define FLAG_m (1<<4)
-#define FLAG_o (1<<5)
-#define FLAG_a (1<<6)
+#define FLAG_a (1<<5)
+#define FLAG_o (1<<6)
 #endif
 
 #ifdef FOR_unicode
-#define CLEANUP_unicode
 #ifndef TT
 #define TT this.unicode
 #endif
 #endif
 
 #ifdef FOR_uniq
-#define CLEANUP_uniq
 #ifndef TT
 #define TT this.uniq
 #endif
@@ -6895,21 +6433,18 @@
 #endif
 
 #ifdef FOR_unix2dos
-#define CLEANUP_unix2dos
 #ifndef TT
 #define TT this.unix2dos
 #endif
 #endif
 
 #ifdef FOR_unlink
-#define CLEANUP_unlink
 #ifndef TT
 #define TT this.unlink
 #endif
 #endif
 
 #ifdef FOR_unset
-#define CLEANUP_unset
 #ifndef TT
 #define TT this.unset
 #endif
@@ -6919,7 +6454,6 @@
 #endif
 
 #ifdef FOR_unshare
-#define CLEANUP_unshare
 #ifndef TT
 #define TT this.unshare
 #endif
@@ -6934,7 +6468,6 @@
 #endif
 
 #ifdef FOR_uptime
-#define CLEANUP_uptime
 #ifndef TT
 #define TT this.uptime
 #endif
@@ -6943,7 +6476,6 @@
 #endif
 
 #ifdef FOR_useradd
-#define CLEANUP_useradd
 #ifndef TT
 #define TT this.useradd
 #endif
@@ -6958,7 +6490,6 @@
 #endif
 
 #ifdef FOR_userdel
-#define CLEANUP_userdel
 #ifndef TT
 #define TT this.userdel
 #endif
@@ -6966,14 +6497,12 @@
 #endif
 
 #ifdef FOR_usleep
-#define CLEANUP_usleep
 #ifndef TT
 #define TT this.usleep
 #endif
 #endif
 
 #ifdef FOR_uudecode
-#define CLEANUP_uudecode
 #ifndef TT
 #define TT this.uudecode
 #endif
@@ -6981,7 +6510,6 @@
 #endif
 
 #ifdef FOR_uuencode
-#define CLEANUP_uuencode
 #ifndef TT
 #define TT this.uuencode
 #endif
@@ -6989,7 +6517,6 @@
 #endif
 
 #ifdef FOR_uuidgen
-#define CLEANUP_uuidgen
 #ifndef TT
 #define TT this.uuidgen
 #endif
@@ -6997,14 +6524,12 @@
 #endif
 
 #ifdef FOR_vconfig
-#define CLEANUP_vconfig
 #ifndef TT
 #define TT this.vconfig
 #endif
 #endif
 
 #ifdef FOR_vi
-#define CLEANUP_vi
 #ifndef TT
 #define TT this.vi
 #endif
@@ -7012,7 +6537,6 @@
 #endif
 
 #ifdef FOR_vmstat
-#define CLEANUP_vmstat
 #ifndef TT
 #define TT this.vmstat
 #endif
@@ -7020,14 +6544,12 @@
 #endif
 
 #ifdef FOR_w
-#define CLEANUP_w
 #ifndef TT
 #define TT this.w
 #endif
 #endif
 
 #ifdef FOR_wait
-#define CLEANUP_wait
 #ifndef TT
 #define TT this.wait
 #endif
@@ -7035,7 +6557,6 @@
 #endif
 
 #ifdef FOR_watch
-#define CLEANUP_watch
 #ifndef TT
 #define TT this.watch
 #endif
@@ -7047,7 +6568,6 @@
 #endif
 
 #ifdef FOR_watchdog
-#define CLEANUP_watchdog
 #ifndef TT
 #define TT this.watchdog
 #endif
@@ -7057,7 +6577,6 @@
 #endif
 
 #ifdef FOR_wc
-#define CLEANUP_wc
 #ifndef TT
 #define TT this.wc
 #endif
@@ -7068,18 +6587,14 @@
 #endif
 
 #ifdef FOR_wget
-#define CLEANUP_wget
 #ifndef TT
 #define TT this.wget
 #endif
-#define FLAG_p (FORCED_FLAG<<0)
-#define FLAG_O (FORCED_FLAG<<1)
-#define FLAG_d (FORCED_FLAG<<2)
-#define FLAG_max_redirect (FORCED_FLAG<<3)
+#define FLAG_O (FORCED_FLAG<<0)
+#define FLAG_no_check_certificate (FORCED_FLAG<<1)
 #endif
 
 #ifdef FOR_which
-#define CLEANUP_which
 #ifndef TT
 #define TT this.which
 #endif
@@ -7087,7 +6602,6 @@
 #endif
 
 #ifdef FOR_who
-#define CLEANUP_who
 #ifndef TT
 #define TT this.who
 #endif
@@ -7095,7 +6609,6 @@
 #endif
 
 #ifdef FOR_xargs
-#define CLEANUP_xargs
 #ifndef TT
 #define TT this.xargs
 #endif
@@ -7111,7 +6624,6 @@
 #endif
 
 #ifdef FOR_xxd
-#define CLEANUP_xxd
 #ifndef TT
 #define TT this.xxd
 #endif
@@ -7126,21 +6638,18 @@
 #endif
 
 #ifdef FOR_xzcat
-#define CLEANUP_xzcat
 #ifndef TT
 #define TT this.xzcat
 #endif
 #endif
 
 #ifdef FOR_yes
-#define CLEANUP_yes
 #ifndef TT
 #define TT this.yes
 #endif
 #endif
 
 #ifdef FOR_zcat
-#define CLEANUP_zcat
 #ifndef TT
 #define TT this.zcat
 #endif
diff --git a/android/mac/generated/globals.h b/android/mac/generated/globals.h
index 403077b..7d5e3be 100644
--- a/android/mac/generated/globals.h
+++ b/android/mac/generated/globals.h
@@ -72,16 +72,15 @@
 
 struct md5sum_data {
   int sawline;
-  unsigned *rconsttable32;
-  unsigned long long *rconsttable64; // for sha384,sha512
 
+  unsigned *md5table;
   // Crypto variables blanked after summing
-  unsigned long long count, overflow;
+  unsigned state[5], oldstate[5];
+  unsigned long long count;
   union {
-    char c[128]; // bytes, 1024 bits
-    unsigned i32[16]; // 512 bits for md5,sha1,sha224,sha256
-    unsigned long long i64[16]; // 1024 bits for sha384,sha512
-  } state, buffer;
+    char c[64];
+    unsigned i[16];
+  } buffer;
 };
 
 // toys/lsb/mknod.c
@@ -117,7 +116,7 @@
 // toys/lsb/pidof.c
 
 struct pidof_data {
-  char *o;
+  char *omit;
 };
 
 // toys/lsb/seq.c
@@ -151,15 +150,6 @@
   int fd;
 };
 
-// toys/net/host.c
-
-struct host_data {
-  char *t;
-
-  char **nsname;
-  unsigned nslen;
-};
-
 // toys/net/ifconfig.c
 
 struct ifconfig_data {
@@ -281,20 +271,17 @@
   char *buf;
 };
 
-// toys/other/gpiod.c
-
-struct gpiod_data {
-  struct double_list *chips;
-  int chip_count;
-};
-
 // toys/other/hexedit.c
 
 struct hexedit_data {
-  char *data, *search, keybuf[16], input[80];
-  long long len, base, pos;
-  int numlen, undo, undolen, mode;
+  char *data;
+  long long len, base;
+  int numlen, undo, undolen;
   unsigned rows, cols;
+  long long pos;
+  char keybuf[16];
+  char input[80];
+  char *search;
 };
 
 // toys/other/hwclock.c
@@ -332,21 +319,21 @@
 // toys/other/lsattr.c
 
 struct lsattr_data {
-  long v, p;
+  long v;
+  long p;
 
-  unsigned add, rm, set;
+  long add, rm, set;
   // !add and !rm tell us whether they were used, but `chattr =` is meaningful.
   int have_set;
 };
 
-// toys/other/lsusb.c
+// toys/other/lspci.c
 
-struct lsusb_data {
+struct lspci_data {
   char *i;
   long n;
 
-  void *ids, *class;
-  int count;
+  FILE *db;
 };
 
 // toys/other/makedevs.c
@@ -397,34 +384,12 @@
   char *c;
 };
 
-// toys/other/openvt.c
-
-struct openvt_data {
-  long c;
-};
-
 // toys/other/pwgen.c
 
 struct pwgen_data {
   char *r;
 };
 
-// toys/other/readelf.c
-
-struct readelf_data {
-  char *x, *p;
-
-  char *elf, *shstrtab, *f;
-  unsigned long long shoff, phoff, size, shstrtabsz;
-  int bits, endian, shnum, shentsize, phentsize;
-};
-
-// toys/other/reboot.c
-
-struct reboot_data {
-  char *d;
-};
-
 // toys/other/rtcwake.c
 
 struct rtcwake_data {
@@ -491,9 +456,8 @@
 
   int nextsig;
   pid_t pid;
-  struct timespec kts;
-  struct itimerspec its;
-  timer_t timer;
+  struct timeval ktv;
+  struct itimerval itv;
 };
 
 // toys/other/truncate.c
@@ -505,12 +469,6 @@
   int type;
 };
 
-// toys/other/uclampset.c
-
-struct uclampset_data {
-  long M, m, p;
-};
-
 // toys/other/watch.c
 
 struct watch_data {
@@ -540,7 +498,7 @@
     char *af_type_A;
     char *af_type_p;
     char *interface;
-
+    
     int sockfd;
     char *device;
 };
@@ -574,7 +532,7 @@
 // toys/pending/bootchartd.c
 
 struct bootchartd_data {
-  char timestamp[32];
+  char buf[32];
   long msec;
   int proc_accounting;
 
@@ -751,17 +709,10 @@
   long gid;
 };
 
-// toys/pending/hexdump.c
+// toys/pending/host.c
 
-struct hexdump_data {
-    long s, n;
-
-    long long len, pos, ppos;
-    const char *fmt;
-    unsigned int fn, bc;  // file number and byte count
-    char linebuf[16];  // line buffer - serves double duty for sqeezing repeat
-                       // lines and for accumulating full lines accross file
-                       // boundaries if necessesary.
+struct host_data {
+  char *type_str;
 };
 
 // toys/pending/ip.c
@@ -868,6 +819,22 @@
   int cin_fd;
 };
 
+// toys/pending/openvt.c
+
+struct openvt_data {
+  long c;
+};
+
+// toys/pending/readelf.c
+
+struct readelf_data {
+  char *x, *p;
+
+  char *elf, *shstrtab, *f;
+  unsigned long long shoff, phoff, size, shstrtabsz;
+  int bits, endian, shnum, shentsize, phentsize;
+};
+
 // toys/pending/route.c
 
 struct route_data {
@@ -890,7 +857,7 @@
   long long SECONDS;
   char *isexec, *wcpat;
   unsigned options, jobcnt, LINENO;
-  int hfd, pid, bangpid, varslen, srclvl, recursion;
+  int hfd, pid, bangpid, varslen, cdcount, srclvl, recursion;
 
   // Callable function array
   struct sh_function {
@@ -941,7 +908,7 @@
     struct sh_process *next, *prev; // | && ||
     struct arg_list *delete;   // expanded strings
     // undo redirects, a=b at start, child PID, exit status, has !, job #
-    int *urd, envlen, pid, exit, flags, job, dash;
+    int *urd, envlen, pid, exit, not, job, dash;
     long long when; // when job backgrounded/suspended
     struct sh_arg *raw, arg;
   } *pp; // currently running process
@@ -950,17 +917,6 @@
   struct sh_arg jobs, *wcdeck;
 };
 
-// toys/pending/strace.c
-
-struct strace_data {
-  long s, p;
-
-  char ioctl[32], *fmt;
-  long regs[256/sizeof(long)], syscall;
-  pid_t pid;
-  int arg;
-};
-
 // toys/pending/stty.c
 
 struct stty_data {
@@ -1159,17 +1115,7 @@
 // toys/pending/wget.c
 
 struct wget_data {
-  char *p, *O;
-  long max_redirect;
-
-  int sock, https;
-  char *url;
-#if CFG_WGET_LIBTLS
-  struct tls *tls;
-#elif CFG_WGET_OPENSSL
-  struct ssl_ctx_st *ctx;
-  struct ssl_st *ssl;
-#endif
+  char *filename;
 };
 
 // toys/posix/basename.c
@@ -1208,8 +1154,6 @@
 // toys/posix/cmp.c
 
 struct cmp_data {
-  long n;
-
   int fd;
   char *name;
 };
@@ -1248,7 +1192,6 @@
   char *d, *O;
   struct arg_list *select[5]; // we treat them the same, so loop through
 
-  unsigned line;
   int pairs;
   regex_t reg;
 };
@@ -1256,7 +1199,7 @@
 // toys/posix/date.c
 
 struct date_data {
-  char *s, *r, *I, *D, *d;
+  char *r, *I, *D, *d;
 
   unsigned nano;
 };
@@ -1297,6 +1240,7 @@
 
 struct file_data {
   int max_name_len;
+
   off_t len;
 };
 
@@ -1406,7 +1350,8 @@
   long w, l, v;
 
   // Count of consecutive blank lines for -l has to persist between files
-  long lcount, slen;
+  long lcount;
+  long slen;
 };
 
 // toys/posix/od.c
@@ -1467,7 +1412,7 @@
 
   struct ptr_len gg, GG, pp, PP, ss, tt, uu, UU;
   struct dirtree *threadparent;
-  unsigned width, height, scroll;
+  unsigned width, height;
   dev_t tty;
   void *fields, *kfields;
   long long ticks, bits, time;
@@ -1507,14 +1452,14 @@
   char *o, *T, S;
 
   void *key_list;
-  unsigned linecount;
+  int linecount;
   char **lines, *name;
 };
 
 // toys/posix/split.c
 
 struct split_data {
-  long n, l, b, a;
+  long l, b, a;
 
   char *outfile;
 };
@@ -1530,16 +1475,9 @@
 
 struct tail_data {
   long n, c;
-  char *s;
 
-  int file_no, last_fd, ss;
+  int file_no, last_fd;
   struct xnotify *not;
-  struct {
-    char *path;
-    int fd;
-    dev_t dev;
-    ino_t ino;
-  } *F;
 };
 
 // toys/posix/tar.c
@@ -1549,12 +1487,11 @@
   struct arg_list *T, *X;
   char *I, *to_command, *owner, *group, *mtime, *mode;
   struct arg_list *exclude;
-  long strip_components;
 
   struct double_list *incl, *excl, *seen;
   struct string_list *dirs;
   char *cwd;
-  int fd, ouid, ggid, hlc, warn, adev, aino, sparselen, pid;
+  int fd, ouid, ggid, hlc, warn, adev, aino, sparselen;
   long long *sparse;
   time_t mtt;
 
@@ -1646,7 +1583,6 @@
 	struct su_data su;
 	struct umount_data umount;
 	struct ftpget_data ftpget;
-	struct host_data host;
 	struct ifconfig_data ifconfig;
 	struct microcom_data microcom;
 	struct netcat_data netcat;
@@ -1664,14 +1600,13 @@
 	struct fallocate_data fallocate;
 	struct fmt_data fmt;
 	struct free_data free;
-	struct gpiod_data gpiod;
 	struct hexedit_data hexedit;
 	struct hwclock_data hwclock;
 	struct ionice_data ionice;
 	struct login_data login;
 	struct losetup_data losetup;
 	struct lsattr_data lsattr;
-	struct lsusb_data lsusb;
+	struct lspci_data lspci;
 	struct makedevs_data makedevs;
 	struct mix_data mix;
 	struct mkpasswd_data mkpasswd;
@@ -1679,10 +1614,7 @@
 	struct modinfo_data modinfo;
 	struct nsenter_data nsenter;
 	struct oneit_data oneit;
-	struct openvt_data openvt;
 	struct pwgen_data pwgen;
-	struct readelf_data readelf;
-	struct reboot_data reboot;
 	struct rtcwake_data rtcwake;
 	struct setfattr_data setfattr;
 	struct sha3sum_data sha3sum;
@@ -1693,7 +1625,6 @@
 	struct tac_data tac;
 	struct timeout_data timeout;
 	struct truncate_data truncate;
-	struct uclampset_data uclampset;
 	struct watch_data watch;
 	struct watchdog_data watchdog;
 	struct xxd_data xxd;
@@ -1719,7 +1650,7 @@
 	struct getopt_data getopt;
 	struct getty_data getty;
 	struct groupadd_data groupadd;
-	struct hexdump_data hexdump;
+	struct host_data host;
 	struct ip_data ip;
 	struct ipcrm_data ipcrm;
 	struct ipcs_data ipcs;
@@ -1730,9 +1661,10 @@
 	struct mke2fs_data mke2fs;
 	struct modprobe_data modprobe;
 	struct more_data more;
+	struct openvt_data openvt;
+	struct readelf_data readelf;
 	struct route_data route;
 	struct sh_data sh;
-	struct strace_data strace;
 	struct stty_data stty;
 	struct sulogin_data sulogin;
 	struct syslogd_data syslogd;
diff --git a/android/mac/generated/help.h b/android/mac/generated/help.h
index 30c24e9..86fbdbf 100644
--- a/android/mac/generated/help.h
+++ b/android/mac/generated/help.h
@@ -4,6 +4,8 @@
 
 #define HELP_toybox_uid_sys "When commands like useradd/groupadd allocate system IDs, start here."
 
+#define HELP_toybox_pedantic_args "Check arguments for commands that have no arguments."
+
 #define HELP_toybox_debug "Enable extra checks for debugging purposes. All of them catch\nthings that can only go wrong at development time, not runtime."
 
 #define HELP_toybox_norecurse "When one toybox command calls another, usually it just calls the new\ncommand's main() function rather than searching the $PATH and calling\nexec on another file (which is much slower).\n\nThis disables that optimization, so toybox will run external commands\n       even when it has a built-in version of that command. This requires\n       toybox symlinks to be installed in the $PATH, or re-invoking the\n       \"toybox\" multiplexer command by name."
@@ -38,17 +40,17 @@
 
 #define HELP_restorecon "usage: restorecon [-D] [-F] [-R] [-n] [-v] FILE...\n\nRestores the default security contexts for the given files.\n\n-D	Apply to /data/data too\n-F	Force reset\n-R	Recurse into directories\n-n	Don't make any changes; useful with -v to see what would change\n-v	Verbose"
 
-#define HELP_log "usage: log [-p PRI] [-t TAG] [MESSAGE...]\n\nLogs message (or stdin) to logcat.\n\n-p	Use the given priority instead of INFO:\n	d: DEBUG  e: ERROR  f: FATAL  i: INFO  v: VERBOSE  w: WARN  s: SILENT\n-t	Use the given tag instead of \"log\""
+#define HELP_log "usage: log [-p PRI] [-t TAG] MESSAGE...\n\nLogs message to logcat.\n\n-p	Use the given priority instead of INFO:\n	d: DEBUG  e: ERROR  f: FATAL  i: INFO  v: VERBOSE  w: WARN  s: SILENT\n-t	Use the given tag instead of \"log\""
 
 #define HELP_load_policy "usage: load_policy FILE\n\nLoad the specified SELinux policy file."
 
 #define HELP_getenforce "usage: getenforce\n\nShows whether SELinux is disabled, enforcing, or permissive."
 
-#define HELP_skeleton_alias "usage: skeleton_alias [-dq] [-b NUMBER]\n\nExample of a second command with different arguments in the same source\nfile as the first. This allows shared infrastructure outside of lib/."
+#define HELP_skeleton_alias "usage: skeleton_alias [-dq] [-b NUMBER]\n\nExample of a second command with different arguments in the same source\nfile as the first. This allows shared infrastructure not added to lib/."
 
 #define HELP_skeleton "usage: skeleton [-a] [-b STRING] [-c NUMBER] [-d LIST] [-e COUNT] [...]\n\nTemplate for new commands. You don't need this.\n\nWhen creating a new command, copy this file and delete the parts you\ndon't need. Be sure to replace all instances of \"skeleton\" (upper and lower\ncase) with your new command name.\n\nFor simple commands, \"hello.c\" is probably a better starting point."
 
-#define HELP_logpath "usage: logpath ...\n\nAppend command line to $LOGPATH, then call second instance\nof command in $PATH."
+#define HELP_logwrapper "usage: logwrapper ...\n\nAppend command line to $WRAPLOG, then call second instance\nof command in $PATH."
 
 #define HELP_hostid "usage: hostid\n\nPrint the numeric identifier for the current host."
 
@@ -70,7 +72,7 @@
 
 #define HELP_seq "usage: seq [-w|-f fmt_str] [-s sep_str] [first] [increment] last\n\nCount from first to last, by increment. Omitted arguments default\nto 1. Two arguments are used as first and last. Arguments can be\nnegative or floating point.\n\n-f	Use fmt_str as a printf-style floating point format string\n-s	Use sep_str as separator, default is a newline character\n-w	Pad to equal width with leading zeroes"
 
-#define HELP_pidof "usage: pidof [-s] [-o omitpid[,omitpid...]] [NAME...]\n\nPrint the PIDs of all processes with the given names.\n\n-o	Omit PID(s)\n-s	Single shot, only return one pid\n-x	Match shell scripts too"
+#define HELP_pidof "usage: pidof [-s] [-o omitpid[,omitpid...]] [NAME]...\n\nPrint the PIDs of all processes with the given names.\n\n-s	Single shot, only return one pid\n-o	Omit PID(s)\n-x	Match shell scripts too"
 
 #define HELP_passwd_sad "Password changes are checked to make sure they're at least 6 chars long,\ndon't include the entire username (but not a subset of it), or the entire\nprevious password (but changing password1, password2, password3 is fine).\nThis heuristic accepts \"aaaaaa\" and \"123456\"."
 
@@ -84,17 +86,17 @@
 
 #define HELP_mknod "usage: mknod [-m MODE] NAME TYPE [MAJOR MINOR]\n\nCreate a special file NAME with a given type. TYPE is b for block device,\nc or u for character device, p for named pipe (which ignores MAJOR/MINOR).\n\n-m	Mode (file permissions) of new device, in octal or u+x format"
 
-#define HELP_sha512sum "See md5sum"
+#define HELP_sha512sum "See sha1sum"
 
-#define HELP_sha384sum "See md5sum"
+#define HELP_sha384sum "See sha1sum"
 
-#define HELP_sha256sum "See md5sum"
+#define HELP_sha256sum "See sha1sum"
 
-#define HELP_sha224sum "See md5sum"
+#define HELP_sha224sum "See sha1sum"
 
-#define HELP_sha1sum "See md5sum"
+#define HELP_sha1sum "usage: sha?sum [-bcs] [FILE]...\n\nCalculate sha hash for each input file, reading from stdin if none. Output\none hash (40 hex digits for sha1, 56 for sha224, 64 for sha256, 96 for sha384,\nand 128 for sha512) for each input file, followed by filename.\n\n-b	Brief (hash only, no filename)\n-c	Check each line of each FILE is the same hash+filename we'd output\n-s	No output, exit status 0 if all hashes match, 1 otherwise"
 
-#define HELP_md5sum "usage: ???sum [-bcs] [FILE]...\n\nCalculate hash for each input file, reading from stdin if none, writing\nhexadecimal digits to stdout for each input file (md5=32 hex digits,\nsha1=40, sha224=56, sha256=64, sha384=96, sha512=128) followed by filename.\n\n-b	Brief (hash only, no filename)\n-c	Check each line of each FILE is the same hash+filename we'd output\n-s	No output, exit status 0 if all hashes match, 1 otherwise"
+#define HELP_md5sum "usage: md5sum [-bcs] [FILE]...\n\nCalculate md5 hash for each input file, reading from stdin if none.\nOutput one hash (32 hex digits) for each input file, followed by filename.\n\n-b	Brief (hash only, no filename)\n-c	Check each line of each FILE is the same hash+filename we'd output\n-s	No output, exit status 0 if all hashes match, 1 otherwise"
 
 #define HELP_killall "usage: killall [-l] [-iqv] [-SIGNAL|-s SIGNAL] PROCESS_NAME...\n\nSend a signal (default: TERM) to all processes with the given names.\n\n-i	Ask for confirmation before killing\n-l	Print list of all available signals\n-q	Don't print any warnings or error messages\n-s	Send SIGNAL instead of SIGTERM\n-v	Report if the signal was successfully sent\n-w	Wait until all signaled processes are dead"
 
@@ -126,9 +128,7 @@
 
 #define HELP_microcom "usage: microcom [-s SPEED] [-X] DEVICE\n\nSimple serial console.\n\n-s	Set baud rate to SPEED (default 115200)\n-X	Ignore ^@ (send break) and ^] (exit)"
 
-#define HELP_ifconfig "usage: ifconfig [-aS] [INTERFACE [ACTION...]]\n\nDisplay or configure network interface.\n\nWith no arguments, display active interfaces. First argument is interface\nto operate on, one argument by itself displays that interface.\n\n-a	All interfaces displayed, not just active ones\n-S	Short view, one line per interface\n\nStandard ACTIONs to perform on an INTERFACE:\n\nADDR[/MASK]        - set IPv4 address (1.2.3.4/5) and activate interface\nadd|del ADDR[/LEN] - add/remove IPv6 address (1111::8888/128)\nup|down            - activate or deactivate interface\n\nAdvanced ACTIONs (default values usually suffice):\n\ndefault          - remove IPv4 address\nnetmask ADDR     - set IPv4 netmask via 255.255.255.0 instead of /24\ntxqueuelen LEN   - number of buffered packets before output blocks\nmtu LEN          - size of outgoing packets (Maximum Transmission Unit)\nbroadcast ADDR   - Set broadcast address\npointopoint ADDR - PPP and PPPOE use this instead of \"route add default gw\"\nhw TYPE ADDR     - set hardware (mac) address (type = ether|infiniband)\nrename NEWNAME   - rename interface\n\nFlags you can set on an interface (or -remove by prefixing with -):\n\narp       - don't use Address Resolution Protocol to map LAN routes\npromisc   - don't discard packets that aren't to this LAN hardware address\nmulticast - force interface into multicast mode if the driver doesn't\nallmulti  - promisc for multicast packets"
-
-#define HELP_host "usage: host [-v] [-t TYPE] NAME [SERVER]\n\nLook up DNS records for NAME, either domain name or IPv4/IPv6 address to\nreverse lookup, from SERVER or default DNS server(s).\n\n-a	All records\n-t TYPE	Record TYPE (number or ANY A AAAA CNAME MX NS PTR SOA SRV TXT)\n-v	Verbose"
+#define HELP_ifconfig "usage: ifconfig [-aS] [INTERFACE [ACTION...]]\n\nDisplay or configure network interface.\n\nWith no arguments, display active interfaces. First argument is interface\nto operate on, one argument by itself displays that interface.\n\n-a	All interfaces displayed, not just active ones\n-S	Short view, one line per interface\n\nStandard ACTIONs to perform on an INTERFACE:\n\nADDR[/MASK]        - set IPv4 address (1.2.3.4/5) and activate interface\nadd|del ADDR[/LEN] - add/remove IPv6 address (1111::8888/128)\nup|down            - activate or deactivate interface\n\nAdvanced ACTIONs (default values usually suffice):\n\ndefault          - remove IPv4 address\nnetmask ADDR     - set IPv4 netmask via 255.255.255.0 instead of /24\ntxqueuelen LEN   - number of buffered packets before output blocks\nmtu LEN          - size of outgoing packets (Maximum Transmission Unit)\nbroadcast ADDR   - Set broadcast address\npointopoint ADDR - PPP and PPPOE use this instead of \"route add default gw\"\nhw TYPE ADDR     - set hardware (mac) address (type = ether|infiniband)\n\nFlags you can set on an interface (or -remove by prefixing with -):\n\narp       - don't use Address Resolution Protocol to map LAN routes\npromisc   - don't discard packets that aren't to this LAN hardware address\nmulticast - force interface into multicast mode if the driver doesn't\nallmulti  - promisc for multicast packets"
 
 #define HELP_ftpput "An ftpget that defaults to -s instead of -g"
 
@@ -136,7 +136,7 @@
 
 #define HELP_yes "usage: yes [args...]\n\nRepeatedly output line until killed. If no args, output 'y'."
 
-#define HELP_xxd "usage: xxd [-c n] [-g n] [-i] [-l n] [-o n] [-p] [-r] [-s n] [file]\n\nHexdump a file to stdout. If no file is listed, copy from stdin.\nFilename \"-\" is a synonym for stdin.\n\n-c n	Show n bytes per line (default 16)\n-g n	Group bytes by adding a ' ' every n bytes (default 2)\n-i	Output include file (CSV hex bytes, plus C header/footer if not stdin)\n-l n	Limit of n bytes before stopping (default is no limit)\n-o n	Add n to display offset\n-p	Plain hexdump (30 bytes/line, no grouping)\n-r	Reverse operation: turn a hexdump into a binary file\n-s n	Skip to offset n"
+#define HELP_xxd "usage: xxd [-c n] [-g n] [-i] [-l n] [-o n] [-p] [-r] [-s n] [file]\n\nHexdump a file to stdout.  If no file is listed, copy from stdin.\nFilename \"-\" is a synonym for stdin.\n\n-c n	Show n bytes per line (default 16)\n-g n	Group bytes by adding a ' ' every n bytes (default 2)\n-i	Include file output format (comma-separated hex byte literals)\n-l n	Limit of n bytes before stopping (default is no limit)\n-o n	Add n to display offset\n-p	Plain hexdump (30 bytes/line, no grouping)\n-r	Reverse operation: turn a hexdump into a binary file\n-s n	Skip to offset n"
 
 #define HELP_which "usage: which [-a] filename ...\n\nSearch $PATH for executable files matching filename(s).\n\n-a	Show all matches"
 
@@ -156,8 +156,6 @@
 
 #define HELP_uptime "usage: uptime [-ps]\n\nTell the current time, how long the system has been running, the number\nof users, and the system load averages for the past 1, 5 and 15 minutes.\n\n-p	Pretty (human readable) uptime\n-s	Since when has the system been up?"
 
-#define HELP_uclampset "usage: uclampset [-m MIN] [-M MAX] {-p PID | COMMAND...}\n\nSet or query process utilization limits ranging from 0 to 1024, or -1 to\nreset to system default. With no arguments, prints current values.\n\n-m MIN      Reserve at least this much CPU utilization for task\n-M MAX      Limit task to at most this much CPU utilization\n-p PID	Apply to PID rather than new COMMAND\n-R	Reset child processes to default values on fork\n-a	Apply to all threads for the given PID"
-
 #define HELP_truncate "usage: truncate [-c] -s SIZE file...\n\nSet length of file(s), extending sparsely if necessary.\n\n-c	Don't create file if it doesn't exist\n-s	New size (with optional prefix and suffix)\n\nSIZE prefix: + add, - subtract, < shrink to, > expand to,\n             / multiple rounding down, % multiple rounding up\nSIZE suffix: k=1024, m=1024^2, g=1024^3, t=1024^4, p=1024^5, e=1024^6"
 
 #define HELP_timeout "usage: timeout [-k DURATION] [-s SIGNAL] DURATION COMMAND...\n\nRun command line as a child process, sending child a signal if the\ncommand doesn't exit soon enough.\n\nDURATION can be a decimal fraction. An optional suffix can be \"m\"\n(minutes), \"h\" (hours), \"d\" (days), or \"s\" (seconds, the default).\n\n-s	Send specified signal (default TERM)\n-k	Send KILL signal if child still running this long after first signal\n-v	Verbose\n--foreground       Don't create new process group\n--preserve-status  Exit with the child's exit status"
@@ -178,7 +176,7 @@
 
 #define HELP_stat "usage: stat [-tfL] [-c FORMAT] FILE...\n\nDisplay status of files or filesystems.\n\n-c	Output specified FORMAT string instead of default\n-f	Display filesystem status instead of file status\n-L	Follow symlinks\n-t	terse (-c \"%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\")\n	      (with -f = -c \"%n %i %l %t %s %S %b %f %a %c %d\")\n\nThe valid format escape sequences for files:\n%a  Access bits (octal) |%A  Access bits (flags)|%b  Size/512\n%B  Bytes per %b (512)  |%C  Security context   |%d  Device ID (dec)\n%D  Device ID (hex)     |%f  All mode bits (hex)|%F  File type\n%g  Group ID            |%G  Group name         |%h  Hard links\n%i  Inode               |%m  Mount point        |%n  Filename\n%N  Long filename       |%o  I/O block size     |%s  Size (bytes)\n%t  Devtype major (hex) |%T  Devtype minor (hex)|%u  User ID\n%U  User name           |%x  Access time        |%X  Access unix time\n%y  Modification time   |%Y  Mod unix time      |%z  Creation time\n%Z  Creation unix time\n\nThe valid format escape sequences for filesystems:\n%a  Available blocks    |%b  Total blocks       |%c  Total inodes\n%d  Free inodes         |%f  Free blocks        |%i  File system ID\n%l  Max filename length |%n  File name          |%s  Best transfer size\n%S  Actual block size   |%t  FS type (hex)      |%T  FS type (driver name)"
 
-#define HELP_shred "usage: shred [-fuxz] [-n COUNT] [-o OFFSET] [-s SIZE] FILE...\n\nSecurely delete a file by overwriting its contents with random data.\n\n-f		Force (chmod if necessary)\n-n COUNT	Random overwrite iterations (default 1)\n-o OFFSET	Start at OFFSET\n-s SIZE		Use SIZE instead of detecting file size\n-u		Unlink (actually delete file when done)\n-x		Use exact size (default without -s rounds up to next 4k)\n-z		Zero at end\n\nNote: data journaling filesystems render this command useless, you must\noverwrite all free space (fill up disk) to erase old data on those."
+#define HELP_shred "usage: shred [-fuz] [-n COUNT] [-s SIZE] FILE...\n\nSecurely delete a file by overwriting its contents with random data.\n\n-f		Force (chmod if necessary)\n-n COUNT	Random overwrite iterations (default 1)\n-o OFFSET	Start at OFFSET\n-s SIZE		Use SIZE instead of detecting file size\n-u		Unlink (actually delete file when done)\n-x		Use exact size (default without -s rounds up to next 4k)\n-z		Zero at end\n\nNote: data journaling filesystems render this command useless, you must\noverwrite all free space (fill up disk) to erase old data on those."
 
 #define HELP_sha3sum "usage: sha3sum [-S] [-a BITS] [FILE...]\n\nHash function du jour.\n\n-a	Produce a hash BITS long (default 224)\n-b	Brief (hash only, no filename)\n-S	Use SHAKE termination byte instead of SHA3 (ask FIPS why)"
 
@@ -188,20 +186,18 @@
 
 #define HELP_rtcwake "usage: rtcwake [-aluv] [-d FILE] [-m MODE] [-s SECS] [-t UNIX]\n\nEnter the given sleep state until the given time.\n\n-a	RTC uses time specified in /etc/adjtime\n-d FILE	Device to use (default /dev/rtc)\n-l	RTC uses local time\n-m	Mode (--list-modes to see those supported by your kernel):\n	  standby  S1: default              mem     S3: suspend to RAM\n	  disk     S4: suspend to disk      off     S5: power off\n	  disable  Cancel current alarm     freeze  stop processes/processors\n	  no       just set wakeup time     on      just poll RTC for alarm\n	  show     just show current alarm\n-s SECS	Wake SECS seconds from now\n-t UNIX	Wake UNIX seconds from epoch\n-u	RTC uses UTC\n-v	Verbose"
 
-#define HELP_rmmod "usage: rmmod [-wf] MODULE...\n\nUnload the given kernel modules.\n\n-f	Force unload of a module\n-w	Wait until the module is no longer used"
+#define HELP_rmmod "usage: rmmod [-wf] [MODULE]\n\nUnload the module named MODULE from the Linux kernel.\n-f	Force unload of a module\n-w	Wait until the module is no longer used"
 
 #define HELP_rev "usage: rev [FILE...]\n\nOutput each line reversed, when no files are given stdin is used."
 
 #define HELP_reset "usage: reset\n\nReset the terminal."
 
-#define HELP_reboot "usage: reboot/halt/poweroff [-fn] [-d DELAY]\n\nRestart, halt, or power off the system.\n\n-d	Wait DELAY before proceeding (in seconds or m/h/d suffix: -d 1.5m = 90s)\n-f	Force reboot (don't signal init, reboot directly)\n-n	Don't sync filesystems before reboot"
+#define HELP_reboot "usage: reboot/halt/poweroff [-fn]\n\nRestart, halt or powerdown the system.\n\n-f	Don't signal init\n-n	Don't sync before stopping the system"
 
 #define HELP_realpath "usage: realpath FILE...\n\nDisplay the canonical absolute pathname"
 
 #define HELP_readlink "usage: readlink FILE...\n\nWith no options, show what symlink points to, return error if not symlink.\n\nOptions for producing canonical paths (all symlinks/./.. resolved):\n\n-e	Canonical path to existing entry (fail if missing)\n-f	Full path (fail if directory missing)\n-m	Ignore missing entries, show where it would be\n-n	No trailing newline\n-q	Quiet (no output, just error code)"
 
-#define HELP_readelf "usage: readelf [-adehlnSs] [-p SECTION] [-x SECTION] [file...]\n\nDisplays information about ELF files.\n\n-a	Equivalent to -dhlnSs\n-d	Show dynamic section\n-e	Headers (equivalent to -hlS)\n-h	Show ELF header\n-l	Show program headers\n-n	Show notes\n-p S	Dump strings found in named/numbered section\n-S	Show section headers\n-s	Show symbol tables (.dynsym and .symtab)\n-x S	Hex dump of named/numbered section\n\n--dyn-syms	Show just .dynsym symbol table"
-
 #define HELP_readahead "usage: readahead FILE...\n\nPreload files into disk cache."
 
 #define HELP_pwgen "usage: pwgen [-cAn0yrsBhC1v] [LENGTH] [COUNT]\n\nGenerate human-readable random passwords. When output is to tty produces\na screenfull to defeat shoulder surfing (pick one and clear the screen).\n\n-c  --capitalize                  Permit capital letters.\n-A  --no-capitalize               Don't include capital letters.\n-n  --numerals                    Permit numbers.\n-0  --no-numerals                 Don't include numbers.\n-y  --symbols                     Permit special characters ($#%...).\n-r <chars>  --remove=<chars>      Don't include the given characters.\n-s  --secure                      Generate more random passwords.\n-B  --ambiguous                   Avoid ambiguous characters (e.g. 0, O).\n-h  --help                        Print this help message.\n-C                                Print the output in columns.\n-1                                Print the output one line each.\n-v                                Don't include vowels."
@@ -210,18 +206,12 @@
 
 #define HELP_printenv "usage: printenv [-0] [env_var...]\n\nPrint environment variables.\n\n-0	Use \\0 as delimiter instead of \\n"
 
-#define HELP_pmap "usage: pmap [-pqx] PID...\n\nReport the memory map of a process or processes.\n\n-q	Show full paths\n-q	Do not show header or footer\n-x	Show the extended format"
+#define HELP_pmap "usage: pmap [-xq] [pids...]\n\nReport the memory map of a process or processes.\n\n-x	Show the extended format\n-q	Do not display some header/footer lines"
 
 #define HELP_pivot_root "usage: pivot_root OLD NEW\n\nSwap OLD and NEW filesystems (as if by simultaneous mount --move), and\nmove all processes with chdir or chroot under OLD into NEW (including\nkernel threads) so OLD may be unmounted.\n\nThe directory NEW must exist under OLD. This doesn't work on initramfs,\nwhich can't be moved (about the same way PID 1 can't be killed; see\nswitch_root instead)."
 
 #define HELP_partprobe "usage: partprobe DEVICE...\n\nTell the kernel about partition table changes\n\nAsk the kernel to re-read the partition table on the specified devices."
 
-#define HELP_deallocvt "usage: deallocvt [NUM]\n\nDeallocate unused virtual terminals, either a specific /dev/ttyNUM, or all."
-
-#define HELP_chvt "usage: chvt NUM\n\nChange to virtual terminal number NUM. (This only works in text mode.)\n\nVirtual terminals are the Linux VGA text mode (or framebuffer) displays,\nswitched between via alt-F1, alt-F2, etc. Use ctrl-alt-F1 to switch\nfrom X11 to a virtual terminal, and alt-F6 (or F7, or F8) to get back."
-
-#define HELP_openvt "usage: openvt [-c NUM] [-sw] COMMAND...\n\nRun COMMAND on a new virtual terminal.\n\n-c NUM  Use VT NUM\n-s    Switch to the new VT\n-w    Wait for command to exit (with -s, deallocates VT on exit)"
-
 #define HELP_oneit "usage: oneit [-prn3] [-c CONSOLE] [COMMAND...]\n\nSimple init program that runs a single supplied command line with a\ncontrolling tty (so CTRL-C can kill it).\n\n-c	Which console device to use (/dev/console doesn't do CTRL-C, etc)\n-p	Power off instead of rebooting when command exits\n-r	Restart child when it exits\n-n	No reboot, just relaunch command line\n-3	Write 32 bit PID of each exiting reparented process to fd 3 of child\n	(Blocking writes, child must read to avoid eventual deadlock.)\n\nSpawns a single child process (because PID 1 has signals blocked)\nin its own session, reaps zombies until the child exits, then\nreboots the system (or powers off with -p, or restarts the child with -r).\n\nResponds to SIGUSR1 by halting the system, SIGUSR2 by powering off,\nand SIGTERM or SIGINT reboot."
 
 #define HELP_nsenter "usage: nsenter [-t pid] [-F] [-i] [-m] [-n] [-p] [-u] [-U] COMMAND...\n\nRun COMMAND in an existing (set of) namespace(s).\n\n-t	PID to take namespaces from    (--target)\n-F	don't fork, even if -p is used (--no-fork)\n\nThe namespaces to switch are:\n\n-i	SysV IPC: message queues, semaphores, shared memory (--ipc)\n-m	Mount/unmount tree (--mount)\n-n	Network address, sockets, routing, iptables (--net)\n-p	Process IDs and init, will fork unless -F is used (--pid)\n-u	Host and domain names (--uts)\n-U	UIDs, GIDs, capabilities (--user)\n\nIf -t isn't specified, each namespace argument must provide a path\nto a namespace file, ala \"-i=/proc/$PID/ns/ipc\""
@@ -244,9 +234,11 @@
 
 #define HELP_makedevs "usage: makedevs [-d device_table] rootdir\n\nCreate a range of special files as specified in a device table.\n\n-d	File containing device table (default reads from stdin)\n\nEach line of the device table has the fields:\n<name> <type> <mode> <uid> <gid> <major> <minor> <start> <increment> <count>\nWhere name is the file name, and type is one of the following:\n\nb	Block device\nc	Character device\nd	Directory\nf	Regular file\np	Named pipe (fifo)\n\nOther fields specify permissions, user and group id owning the file,\nand additional fields for device special files. Use '-' for blank entries,\nunspecified fields are treated as '-'."
 
-#define HELP_lsusb "usage: lsusb [-i]\n\nList USB hosts/devices.\n\n-i	ID database (default /etc/usb.ids[.gz])"
+#define HELP_lsusb "usage: lsusb\n\nList USB hosts/devices."
 
-#define HELP_lspci "usage: lspci [-ekmn] [-i FILE]\n\nList PCI devices.\n\n-e  Extended (6 digit) class\n-i  ID database (default /etc/pci.ids[.gz])\n-k  Show kernel driver\n-m  Machine readable\n-n  Numeric output (-nn for both)"
+#define HELP_lspci_text "usage: lspci [-n] [-i FILE ]\n\n-n	Numeric output (repeat for readable and numeric)\n-i	PCI ID database (default /usr/share/misc/pci.ids)"
+
+#define HELP_lspci "usage: lspci [-ekm]\n\nList PCI devices.\n\n-e	Print all 6 digits in class\n-k	Print kernel driver\n-m	Machine readable format"
 
 #define HELP_lsmod "usage: lsmod\n\nDisplay the currently loaded modules, their sizes and their dependencies."
 
@@ -262,7 +254,7 @@
 
 #define HELP_ionice "usage: ionice [-t] [-c CLASS] [-n LEVEL] [COMMAND...|-p PID]\n\nChange the I/O scheduling priority of a process. With no arguments\n(or just -p), display process' existing I/O class/priority.\n\n-c	CLASS = 1-3: 1(realtime), 2(best-effort, default), 3(when-idle)\n-n	LEVEL = 0-7: (0 is highest priority, default = 5)\n-p	Affect existing PID instead of spawning new child\n-t	Ignore failure to set I/O priority\n\nSystem default iopriority is generally -c 2 -n 4."
 
-#define HELP_insmod "usage: insmod MODULE [OPTION...]\n\nLoad the module named MODULE passing options if given."
+#define HELP_insmod "usage: insmod MODULE [MODULE_OPTIONS]\n\nLoad the module named MODULE passing options if given."
 
 #define HELP_inotifyd "usage: inotifyd PROG FILE[:MASK] ...\n\nWhen a filesystem event matching MASK occurs to a FILE, run PROG as:\n\n  PROG EVENTS FILE [DIRFILE]\n\nIf PROG is \"-\" events are sent to stdout.\n\nThis file is:\n  a  accessed    c  modified    e  metadata change  w  closed (writable)\n  r  opened      D  deleted     M  moved            0  closed (unwritable)\n  u  unmounted   o  overflow    x  unwatchable\n\nA file in this directory is:\n  m  moved in    y  moved out   n  created          d  deleted\n\nWhen x event happens for all FILEs, inotifyd exits (after waiting for PROG)."
 
@@ -272,31 +264,21 @@
 
 #define HELP_i2cdump "usage: i2cdump [-fy] BUS CHIP\n\nDump i2c registers.\n\n-f	Force access to busy devices\n-y	Answer \"yes\" to confirmation prompts (for script use)"
 
-#define HELP_i2cdetect "usage: i2cdetect [-aqry] BUS [FIRST LAST]\nusage: i2cdetect -F BUS\nusage: i2cdetect -l\n\nDetect i2c devices.\n\n-a	All addresses (0x00-0x7f rather than 0x03-0x77 or FIRST-LAST)\n-F	Show functionality\n-l	List available buses\n-q	Probe with SMBus Quick Write (default)\n-r	Probe with SMBus Read Byte\n-y	Answer \"yes\" to confirmation prompts (for script use)"
+#define HELP_i2cdetect "usage: i2cdetect [-ary] BUS [FIRST LAST]\nusage: i2cdetect -F BUS\nusage: i2cdetect -l\n\nDetect i2c devices.\n\n-a	All addresses (0x00-0x7f rather than 0x03-0x77)\n-F	Show functionality\n-l	List all buses\n-r	Probe with SMBus Read Byte\n-y	Answer \"yes\" to confirmation prompts (for script use)"
 
 #define HELP_hwclock "usage: hwclock [-rswtluf]\n\nGet/set the hardware clock.\n\n-f FILE	Use specified device file instead of /dev/rtc0 (--rtc)\n-l	Hardware clock uses localtime (--localtime)\n-r	Show hardware clock time (--show)\n-s	Set system time from hardware clock (--hctosys)\n-t	Set the system time based on the current timezone (--systz)\n-u	Hardware clock uses UTC (--utc)\n-w	Set hardware clock from system time (--systohc)"
 
-#define HELP_hexedit "usage: hexedit FILE\n\nHexadecimal file editor/viewer. All changes are written to disk immediately.\n\n-r	Read only (display but don't edit)\n\nKeys:\nArrows         Move left/right/up/down by one line/column\nPgUp/PgDn      Move up/down by one page\nHome/End       Start/end of line (start/end of file with ctrl)\n0-9, a-f       Change current half-byte to hexadecimal value\n^J or :        Jump (+/- for relative offset, otherwise absolute address)\n^F or /        Find string (^G/n: next, ^D/p: previous match)\nu              Undo\nx              Toggle bw/color display\nq/^C/^Q/Esc    Quit"
+#define HELP_hexedit "usage: hexedit FILE\n\nHexadecimal file editor/viewer. All changes are written to disk immediately.\n\n-r	Read only (display but don't edit)\n\nKeys:\nArrows         Move left/right/up/down by one line/column\nPgUp/PgDn      Move up/down by one page\nHome/End       Start/end of line (start/end of file with ctrl)\n0-9, a-f       Change current half-byte to hexadecimal value\n^J or :        Jump (+/- for relative offset, otherwise absolute address)\n^F or /        Find string (^G/n: next, ^D/p: previous match)\nu              Undo\nq/^C/^Q/Esc    Quit"
 
 #define HELP_help "usage: help [-ahu] [COMMAND]\n\n-a	All commands\n-u	Usage only\n-h	HTML output\n\nShow usage information for toybox commands.\nRun \"toybox\" with no arguments for a list of available commands."
 
-#define HELP_gpioset "usage: gpioset [-l] CHIP LINE=VALUE...\n\nSet the lines on CHIP to the given values. Use gpiofind to convert line\nnames to numbers.\n\n-l	Active low"
-
-#define HELP_gpioget "usage: gpioget [-l] CHIP LINE...\n\nGets the values of the given lines on CHIP. Use gpiofind to convert line\nnames to numbers.\n\n-l	Active low"
-
-#define HELP_gpioinfo "usage: gpioinfo [CHIP...]\n\nShow gpio chips' lines."
-
-#define HELP_gpiofind "usage: gpiofind NAME\n\nShow the chip and line number for the given line name."
-
-#define HELP_gpiodetect "usage: gpiodetect\n\nShow all gpio chips' names, labels, and number of lines."
-
-#define HELP_fsync "usage: fsync [-d] [FILE...]\n\nFlush disk cache for FILE(s), writing cached data to storage device.\n\n-d	Skip directory info (sync file contents only)."
+#define HELP_fsync "usage: fsync [-d] [FILE...]\n\nSynchronize a file's in-core state with storage device.\n\n-d	Avoid syncing metadata"
 
 #define HELP_fsfreeze "usage: fsfreeze {-f | -u} MOUNTPOINT\n\nFreeze or unfreeze a filesystem.\n\n-f	Freeze\n-u	Unfreeze"
 
 #define HELP_freeramdisk "usage: freeramdisk [RAM device]\n\nFree all memory allocated to specified ramdisk"
 
-#define HELP_free "usage: free [-bkmgt]\n\nDisplay the total, free and used amount of physical memory and swap space.\n\n-bkmg	Output units (default is bytes)\n-h	Human readable (K=1024)"
+#define HELP_free "usage: free [-bkmgt]\n\nDisplay the total, free and used amount of physical memory and swap space.\n\n-bkmgt	Output units (default is bytes)\n-h	Human readable (K=1024)"
 
 #define HELP_fmt "usage: fmt [-w WIDTH] [FILE...]\n\nReformat input to wordwrap at a given line length, preserving existing\nindentation level, writing to stdout.\n\n-w WIDTH	Maximum characters per line (default 75)"
 
@@ -318,6 +300,8 @@
 
 #define HELP_clear "Clear the screen."
 
+#define HELP_chvt "usage: chvt N\n\nChange to virtual terminal number N. (This only works in text mode.)\n\nVirtual terminals are the Linux VGA text mode displays, ordinarily\nswitched between via alt-F1, alt-F2, etc. Use ctrl-alt-F1 to switch\nfrom X to a virtual terminal, and alt-F6 (or F7, or F8) to get back."
+
 #define HELP_chrt "usage: chrt [-Rmofrbi] {-p PID [PRIORITY] | [PRIORITY COMMAND...]}\n\nGet/set a process' real-time scheduling policy and priority.\n\n-p	Set/query given pid (instead of running COMMAND)\n-R	Set SCHED_RESET_ON_FORK\n-m	Show min/max priorities available\n\nSet policy (default -r):\n\n  -o  SCHED_OTHER    -f  SCHED_FIFO    -r  SCHED_RR\n  -b  SCHED_BATCH    -i  SCHED_IDLE"
 
 #define HELP_chroot "usage: chroot NEWROOT [COMMAND [ARG...]]\n\nRun command within a new root directory. If no command, run /bin/sh."
@@ -340,19 +324,13 @@
 
 #define HELP_base64 "usage: base64 [-di] [-w COLUMNS] [FILE...]\n\nEncode or decode in base64.\n\n-d	Decode\n-i	Ignore non-alphabetic characters\n-w	Wrap output at COLUMNS (default 76 or 0 for no wrap)"
 
-#define HELP_unicode "usage: unicode CODE[-END]...\n\nConvert between Unicode code points and UTF-8, in both directions.\nCODE can be one or more characters (show U+XXXX), hex numbers\n(show character), or dash separated range."
-
 #define HELP_ascii "usage: ascii\n\nDisplay ascii character set."
 
 #define HELP_acpi "usage: acpi [-abctV]\n\nShow status of power sources and thermal devices.\n\n-a	Show power adapters\n-b	Show batteries\n-c	Show cooling device state\n-t	Show temperatures\n-V	Show everything"
 
 #define HELP_xzcat "usage: xzcat [filename...]\n\nDecompress listed files to stdout. Use stdin if no files listed."
 
-#define HELP_wget_openssl "Enable HTTPS support for wget by linking to OpenSSL."
-
-#define HELP_wget_libtls "Enable HTTPS support for wget by linking to LibTLS.\nSupports using libtls, libretls or libtls-bearssl."
-
-#define HELP_wget "usage: wget [OPTIONS]... [URL]\n    --max-redirect          maximum redirections allowed\n-d, --debug                 print lots of debugging information\n-O, --output-document=FILE  specify output filename\n-p, --post-data=DATA        send data in body of POST request\n\nexamples:\n  wget http://www.example.com"
+#define HELP_wget "usage: wget -O filename URL\n-O filename: specify output filename\nURL: uniform resource location, FTP/HTTP only, not HTTPS\n\nexamples:\n  wget -O index.html http://www.example.com\n  wget -O sample.jpg ftp://ftp.example.com:21/sample.jpg"
 
 #define HELP_vi "usage: vi [-s script] FILE\n-s script: run script file\nVisual text editor. Predates the existence of standardized cursor keys,\nso the controls are weird and historical."
 
@@ -360,6 +338,8 @@
 
 #define HELP_useradd "usage: useradd [-SDH] [-h DIR] [-s SHELL] [-G GRP] [-g NAME] [-u UID] USER [GROUP]\n\nCreate new user, or add USER to GROUP\n\n-D       Don't assign a password\n-g NAME  Real name\n-G GRP   Add user to existing group\n-h DIR   Home directory\n-H       Don't create home directory\n-s SHELL Login shell\n-S       Create a system user\n-u UID   User id"
 
+#define HELP_unicode "usage: unicode [[min]-max]\n\nConvert between Unicode code points and UTF-8, in both directions."
+
 #define HELP_traceroute "usage: traceroute [-46FUIldnvr] [-f 1ST_TTL] [-m MAXTTL] [-p PORT] [-q PROBES]\n[-s SRC_IP] [-t TOS] [-w WAIT_SEC] [-g GATEWAY] [-i IFACE] [-z PAUSE_MSEC] HOST [BYTES]\n\ntraceroute6 [-dnrv] [-m MAXTTL] [-p PORT] [-q PROBES][-s SRC_IP] [-t TOS] [-w WAIT_SEC]\n  [-i IFACE] HOST [BYTES]\n\nTrace the route to HOST\n\n-4,-6 Force IP or IPv6 name resolution\n-F    Set the don't fragment bit (supports IPV4 only)\n-U    Use UDP datagrams instead of ICMP ECHO (supports IPV4 only)\n-I    Use ICMP ECHO instead of UDP datagrams (supports IPV4 only)\n-l    Display the TTL value of the returned packet (supports IPV4 only)\n-d    Set SO_DEBUG options to socket\n-n    Print numeric addresses\n-v    verbose\n-r    Bypass routing tables, send directly to HOST\n-m    Max time-to-live (max number of hops)(RANGE 1 to 255)\n-p    Base UDP port number used in probes(default 33434)(RANGE 1 to 65535)\n-q    Number of probes per TTL (default 3)(RANGE 1 to 255)\n-s    IP address to use as the source address\n-t    Type-of-service in probe packets (default 0)(RANGE 0 to 255)\n-w    Time in seconds to wait for a response (default 3)(RANGE 0 to 86400)\n-g    Loose source route gateway (8 max) (supports IPV4 only)\n-z    Pause Time in ms (default 0)(RANGE 0 to 86400) (supports IPV4 only)\n-f    Start from the 1ST_TTL hop (instead from 1)(RANGE 1 to 255) (supports IPV4 only)\n-i    Specify a network interface to operate with"
 
 #define HELP_tr "usage: tr [-cds] SET1 [SET2]\n\nTranslate, squeeze, or delete characters from stdin, writing to stdout\n\n-c/-C  Take complement of SET1\n-d     Delete input characters coded SET1\n-s     Squeeze multiple output characters of SET2 into one character"
@@ -380,8 +360,6 @@
 
 #define HELP_stty "usage: stty [-ag] [-F device] SETTING...\n\nGet/set terminal configuration.\n\n-F	Open device instead of stdin\n-a	Show all current settings (default differences from \"sane\")\n-g	Show all current settings usable as input to stty\n\nSpecial characters (syntax ^c or undef): intr quit erase kill eof eol eol2\nswtch start stop susp rprnt werase lnext discard\n\nControl/input/output/local settings as shown by -a, '-' prefix to disable\n\nCombo settings: cooked/raw, evenp/oddp/parity, nl, ek, sane\n\nN	set input and output speed (ispeed N or ospeed N for just one)\ncols N	set number of columns\nrows N	set number of rows\nline N	set line discipline\nmin N	set minimum chars per read\ntime N	set read timeout\nspeed	show speed only\nsize	show size only"
 
-#define HELP_strace "usage: strace [-fv] [-p PID] [-s NUM] COMMAND [ARGS...]\n\nTrace systems calls made by a process.\n\n-s	String length limit.\n-v	Dump all of large structs/arrays."
-
 #define HELP_wait "usage: wait [-n] [ID...]\n\nWait for background processes to exit, returning its exit code.\nID can be PID or job, with no IDs waits for all backgrounded processes.\n\n-n	Wait for next process to exit"
 
 #define HELP_source "usage: source FILE [ARGS...]\n\nRead FILE and execute commands. Any ARGS become positional parameters."
@@ -404,17 +382,21 @@
 
 #define HELP_exit "usage: exit [status]\n\nExit shell.  If no return value supplied on command line, use value\nof most recent command, or 0 if none."
 
-#define HELP_declare "usage: declare [-pAailunxr] [NAME...]\n\nSet or print variable attributes and values.\n\n-p	Print variables instead of setting\n-A	Associative array\n-a	Indexed array\n-i	Integer\n-l	Lower case\n-n	Name reference (symlink)\n-r	Readonly\n-u	Uppercase\n-x	Export"
-
-#define HELP_cd "usage: cd [-PL] [-] [path]\n\nChange current directory. With no arguments, go $HOME. Sets $OLDPWD to\nprevious directory: cd - to return to $OLDPWD.\n\n-P	Physical path: resolve symlinks in path\n-L	Local path: .. trims directories off $PWD (default)"
+#define HELP_cd "usage: cd [-PL] [path]\n\nChange current directory.  With no arguments, go $HOME.\n\n-P	Physical path: resolve symlinks in path\n-L	Local path: .. trims directories off $PWD (default)"
 
 #define HELP_sh "usage: sh [-c command] [script]\n\nCommand shell.  Runs a shell script, or reads input interactively\nand responds to it.\n\n-c	command line to execute\n-i	interactive mode (default when STDIN is a tty)"
 
 #define HELP_route "usage: route [-ne] [-A [inet|inet6]] [add|del TARGET [OPTIONS]]\n\nDisplay, add or delete network routes in the \"Forwarding Information Base\",\nwhich send packets out a network interface to an address.\n\n-n	Show numerical addresses (no DNS lookups)\n-e	display netstat fields\n\nAssigning an address to an interface automatically creates an appropriate\nnetwork route (\"ifconfig eth0 10.0.2.15/8\" does \"route add 10.0.0.0/8 eth0\"\nfor you), although some devices (such as loopback) won't show it in the\ntable. For machines more than one hop away, you need to specify a gateway\n(ala \"route add default gw 10.0.2.2\").\n\nThe address \"default\" is a wildcard address (0.0.0.0/0) matching all\npackets without a more specific route.\n\nAvailable OPTIONS include:\nreject   - blocking route (force match failure)\ndev NAME - force matching packets out this interface (ala \"eth0\")\nnetmask  - old way of saying things like ADDR/24\ngw ADDR  - forward packets to gateway ADDR"
 
+#define HELP_readelf "usage: readelf [-adehlnSs] [-p SECTION] [-x SECTION] [file...]\n\nDisplays information about ELF files.\n\n-a	Equivalent to -dhlnSs\n-d	Show dynamic section\n-e	Headers (equivalent to -hlS)\n-h	Show ELF header\n-l	Show program headers\n-n	Show notes\n-p S	Dump strings found in named/numbered section\n-S	Show section headers\n-s	Show symbol tables (.dynsym and .symtab)\n-x S	Hex dump of named/numbered section\n\n--dyn-syms	Show just .dynsym symbol table"
+
+#define HELP_deallocvt "usage: deallocvt [NUM]\n\nDeallocate unused virtual terminals, either a specific /dev/ttyNUM, or all."
+
+#define HELP_openvt "usage: openvt [-c NUM] [-sw] [COMMAND...]\n\nStart a program on a new virtual terminal.\n\n-c NUM  Use VT NUM\n-s    Switch to new VT\n-w    Wait for command to exit\n\nTogether -sw switch back to originating VT when command completes."
+
 #define HELP_more "usage: more [FILE...]\n\nView FILE(s) (or stdin) one screenfull at a time."
 
-#define HELP_modprobe "usage: modprobe [-alrqvsDb] [-d DIR] MODULE [symbol=value][...]\n\nmodprobe utility - inserts modules and dependencies.\n\n-a  Load multiple MODULEs\n-b  Apply blacklist to module names too\n-D  Show dependencies\n-d  Load modules from DIR, option may be used multiple times\n-l  List (MODULE is a pattern)\n-q  Quiet\n-r  Remove MODULE (stacks) or do autoclean\n-s  Log to syslog\n-v  Verbose"
+#define HELP_modprobe "usage: modprobe [-alrqvsDb] [-d DIR] MODULE [symbol=value][...]\n\nmodprobe utility - inserts modules and dependencies.\n\n-a  Load multiple MODULEs\n-d  Load modules from DIR, option may be used multiple times\n-l  List (MODULE is a pattern)\n-r  Remove MODULE (stacks) or do autoclean\n-q  Quiet\n-v  Verbose\n-s  Log to syslog\n-D  Show dependencies\n-b  Apply blacklist to module names too"
 
 #define HELP_mke2fs_extended "usage: mke2fs [-E stride=###] [-O option[,option]]\n\n-E stride= Set RAID stripe size (in blocks)\n-O [opts]  Specify fewer ext2 option flags (for old kernels)\n           All of these are on by default (as appropriate)\n   none         Clear default options (all but journaling)\n   dir_index    Use htree indexes for large directories\n   filetype     Store file type info in directory entry\n   has_journal  Set by -j\n   journal_dev  Set by -J device=XXX\n   sparse_super Don't allocate huge numbers of redundant superblocks"
 
@@ -446,9 +428,7 @@
 
 #define HELP_init "usage: init\n\nSystem V style init.\n\nFirst program to run (as PID 1) when the system comes up, reading\n/etc/inittab to determine actions."
 
-#define HELP_hd "usage: hd [FILE...]\n\nDisplay file(s) in cannonical hex+ASCII format."
-
-#define HELP_hexdump "usage: hexdump [-bcCdovx] [-n LEN] [-s SKIP] [FILE...]\n\nDump file(s) in hexadecimal format.\n\n-n LEN	Show LEN bytes of output\n-s SKIP	Skip bytes of input\n-v	Verbose (don't combine identical lines)\n\nDisplay type:\n-b One byte octal   -c One byte character -C Canonical (hex + ASCII)\n-d Two byte decimal -o Two byte octal     -x Two byte hexadecimal (default)"
+#define HELP_host "usage: host [-av] [-t TYPE] NAME [SERVER]\n\nPerform DNS lookup on NAME, which can be a domain name to lookup,\nor an IPv4 dotted or IPv6 colon-separated address to reverse lookup.\nSERVER (if present) is the DNS server to use.\n\n-a	-v -t ANY\n-t TYPE	query records of type TYPE\n-v	verbose"
 
 #define HELP_groupdel "usage: groupdel [USER] GROUP\n\nDelete a group or remove a user from a group"
 
@@ -494,7 +474,7 @@
 
 #define HELP_arping "usage: arping [-fqbDUA] [-c CNT] [-w TIMEOUT] [-I IFACE] [-s SRC_IP] DST_IP\n\nSend ARP requests/replies\n\n-f         Quit on first ARP reply\n-q         Quiet\n-b         Keep broadcasting, don't go unicast\n-D         Duplicated address detection mode\n-U         Unsolicited ARP mode, update your neighbors\n-A         ARP answer mode, update your neighbors\n-c N       Stop after sending N ARP requests\n-w TIMEOUT Time to wait for ARP reply, seconds\n-I IFACE   Interface to use (default eth0)\n-s SRC_IP  Sender IP address\nDST_IP     Target IP address"
 
-#define HELP_arp "usage: arp\n[-vn] [-H HWTYPE] [-i IF] -a [HOSTNAME]\n[-v]              [-i IF] -d HOSTNAME [pub]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub\n[-v]  [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub\n\nManipulate ARP cache.\n\n-a	Display (all) hosts\n-s	Set new ARP entry\n-d	Delete a specified entry\n-v	Verbose\n-n	Don't resolve names\n-i IFACE	Network interface\n-D	Read <hwaddr> from given device\n-A,-p AF	Protocol family\n-H HWTYPE	Hardware address type"
+#define HELP_arp "usage: arp\n[-vn] [-H HWTYPE] [-i IF] -a [HOSTNAME]\n[-v]              [-i IF] -d HOSTNAME [pub]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [temp]\n[-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub\n[-v]  [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub\n\nManipulate ARP cache\n\n-a    Display (all) hosts\n-s    Set new ARP entry\n-d    Delete a specified entry\n-v    Verbose\n-n    Don't resolve names\n-i IF Network interface\n-D    Read <hwaddr> from given device\n-A,-p AF  Protocol family\n-H    HWTYPE Hardware address type"
 
 #define HELP_xargs "usage: xargs [-0prt] [-snE STR] COMMAND...\n\nRun command line one or more times, appending arguments from stdin.\n\nIf COMMAND exits with 255, don't launch another even if arguments remain.\n\n-0	Each argument is NULL terminated, no whitespace or quote processing\n-E	Stop at line matching string\n-n	Max number of arguments per command\n-o	Open tty for COMMAND's stdin (default /dev/null)\n-p	Prompt for y/n from tty before running each command\n-P	Parallel processes (default 1)\n-r	Don't run with empty input (otherwise always run command once)\n-s	Size in bytes per command line\n-t	Trace, print command line to stderr"
 
@@ -510,33 +490,31 @@
 
 #define HELP_uniq "usage: uniq [-cduiz] [-w MAXCHARS] [-f FIELDS] [-s CHAR] [INFILE [OUTFILE]]\n\nReport or filter out repeated lines in a file\n\n-c	Show counts before each line\n-d	Show only lines that are repeated\n-u	Show only lines that are unique\n-i	Ignore case when comparing lines\n-z	Lines end with \\0 not \\n\n-w	Compare maximum X chars per line\n-f	Ignore first X fields\n-s	Ignore first X chars"
 
-#define HELP_uname "usage: uname [-asnrvm]\n\nPrint system information.\n\n-s	System name\n-n	Network (domain) name\n-r	Kernel Release number\n-v	Kernel Version\n-m	Machine (hardware) name\n-o	Userspace type\n-a	All of the above (in order)"
-
-#define HELP_linux32 "usage: linux32 [COMMAND...]\n\nTell uname -m to line to autoconf (to build 32 bit binaries on 64 bit kernel)."
+#define HELP_uname "usage: uname [-asnrvm]\n\nPrint system information.\n\n-s	System name\n-n	Network (domain) name\n-r	Kernel Release number\n-v	Kernel Version\n-m	Machine (hardware) name\n-a	All of the above"
 
 #define HELP_arch "usage: arch\n\nPrint machine (hardware) name, same as uname -m."
 
 #define HELP_ulimit "usage: ulimit [-P PID] [-SHRacdefilmnpqrstuv] [LIMIT]\n\nPrint or set resource limits for process number PID. If no LIMIT specified\n(or read-only -ap selected) display current value (sizes in bytes).\nDefault is ulimit -P $PPID -Sf\" (show soft filesize of your shell).\n\n-P  PID to affect (default $PPID)  -a  Show all limits\n-S  Set/show soft limit            -H  Set/show hard (maximum) limit\n\n-c  Core file size (blocks)        -d  Process data segment (KiB)\n-e  Max scheduling priority        -f  File size (KiB)\n-i  Pending signal count           -l  Locked memory (KiB)\n-m  Resident Set Size (KiB)        -n  Number of open files\n-p  Pipe buffer (512 bytes)        -q  POSIX message queues\n-r  Max realtime priority          -R  Realtime latency (us)\n-s  Stack size (KiB)               -t  Total CPU time (s)\n-u  Maximum processes (this UID)   -v  Virtual memory size (KiB)"
 
-#define HELP_tty "usage: tty [-s]\n\nShow filename of terminal connected to stdin. If none print \"not a tty\"\nand exit with nonzero status.\n\n-s	Silent, exit code only"
+#define HELP_tty "usage: tty [-s]\n\nShow filename of terminal connected to stdin.\n\nPrints \"not a tty\" and exits with nonzero status if no terminal\nis connected to stdin.\n\n-s	Silent, exit code only"
 
 #define HELP_true "usage: true\n\nReturn zero."
 
 #define HELP_touch "usage: touch [-amch] [-d DATE] [-t TIME] [-r FILE] FILE...\n\nUpdate the access and modification times of each FILE to the current time.\n\n-a	Change access time\n-m	Change modification time\n-c	Don't create file\n-h	Change symlink\n-d	Set time to DATE (in YYYY-MM-DDThh:mm:SS[.frac][tz] format)\n-t	Set time to TIME (in [[CC]YY]MMDDhhmm[.ss][frac] format)\n-r	Set time same as reference FILE"
 
-#define HELP_time "usage: time [-pv] COMMAND...\n\nRun command line and report real, user, and system time elapsed in seconds.\n(real = clock on the wall, user = cpu used by command's code,\nsystem = cpu used by OS on behalf of command.)\n\n-p	POSIX format output\n-v	Verbose"
+#define HELP_time "usage: time [-pv] COMMAND...\n\nRun command line and report real, user, and system time elapsed in seconds.\n(real = clock on the wall, user = cpu used by command's code,\nsystem = cpu used by OS on behalf of command.)\n\n-p	POSIX format output (default)\n-v	Verbose"
 
 #define HELP_test "usage: test [-bcdefghLPrSsuwx PATH] [-nz STRING] [-t FD] [X ?? Y]\n\nReturn true or false by performing tests. (With no arguments return false.)\n\n--- Tests with a single argument (after the option):\nPATH is/has:\n  -b  block device   -f  regular file   -p  fifo           -u  setuid bit\n  -c  char device    -g  setgid         -r  read bit       -w  write bit\n  -d  directory      -h  symlink        -S  socket         -x  execute bit\n  -e  exists         -L  symlink        -s  nonzero size   -k  sticky bit\nSTRING is:\n  -n  nonzero size   -z  zero size      (STRING by itself implies -n)\nFD (integer file descriptor) is:\n  -t  a TTY\n\n--- Tests with one argument on each side of an operator:\nTwo strings:\n  =  are identical   !=  differ\n\nTwo integers:\n  -eq  equal         -gt  first > second    -lt  first < second\n  -ne  not equal     -ge  first >= second   -le  first <= second\n\n--- Modify or combine tests:\n  ! EXPR     not (swap true/false)   EXPR -a EXPR    and (are both true)\n  ( EXPR )   evaluate this first     EXPR -o EXPR    or (is either true)"
 
 #define HELP_tee "usage: tee [-ai] [FILE...]\n\nCopy stdin to each listed file, and also to stdout.\nFilename \"-\" is a synonym for stdout.\n\n-a	Append to files\n-i	Ignore SIGINT"
 
-#define HELP_tar "usage: tar [-cxt] [-fvohmjkOS] [-XTCf NAME] [--selinux] [FILE...]\n\nCreate, extract, or list files in a .tar (or compressed t?z) file.\n\nOptions:\nc  Create                x  Extract               t  Test (list)\nf  tar FILE (default -)  C  Change to DIR first   v  Verbose display\no  Ignore owner          h  Follow symlinks       m  Ignore mtime\nJ  xz compression        j  bzip2 compression     z  gzip compression\nO  Extract to stdout     X  exclude names in FILE T  include names in FILE\n\n--exclude        FILENAME to exclude  --full-time         Show seconds with -tv\n--mode MODE      Adjust permissions   --owner NAME[:UID]  Set file ownership\n--mtime TIME     Override timestamps  --group NAME[:GID]  Set file group\n--sparse         Record sparse files  --selinux           Save/restore labels\n--restrict       All under one dir    --no-recursion      Skip dir contents\n--numeric-owner  Use numeric uid/gid, not user/group names\n--strip-components NUM  Ignore first NUM directory components when extracting\n-I PROG          Filter through PROG to compress or PROG -d to decompress"
+#define HELP_tar "usage: tar [-cxt] [-fvohmjkOS] [-XTCf NAME] [FILE...]\n\nCreate, extract, or list files in a .tar (or compressed t?z) file.\n\nOptions:\nc  Create                x  Extract               t  Test (list)\nf  tar FILE (default -)  C  Change to DIR first   v  Verbose display\no  Ignore owner          h  Follow symlinks       m  Ignore mtime\nJ  xz compression        j  bzip2 compression     z  gzip compression\nO  Extract to stdout     X  exclude names in FILE T  include names in FILE\n\n--exclude        FILENAME to exclude    --full-time   Show seconds with -tv\n--mode MODE      Adjust modes           --mtime TIME  Override timestamps\n--owner NAME     Set file owner to NAME --group NAME  Set file group to NAME\n--sparse         Record sparse files\n--restrict       All archive contents must extract under one subdirectory\n--numeric-owner  Save/use/display uid and gid, not user/group name\n--no-recursion   Don't store directory contents\n-I PROG          Filter through PROG to compress or PROG -d to decompress"
 
-#define HELP_tail "usage: tail [-n|c NUMBER] [-f|F] [-s SECONDS] [FILE...]\n\nCopy last lines from files to stdout. If no files listed, copy from\nstdin. Filename \"-\" is a synonym for stdin.\n\n-n	Output the last NUMBER lines (default 10), +X counts from start\n-c	Output the last NUMBER bytes, +NUMBER counts from start\n-f	Follow FILE(s) by descriptor, waiting for more data to be appended\n-F	Follow FILE(s) by filename, waiting for more data, and retrying\n-s	Used with -F, sleep SECONDS between retries (default 1)"
+#define HELP_tail "usage: tail [-n|c NUMBER] [-f] [FILE...]\n\nCopy last lines from files to stdout. If no files listed, copy from\nstdin. Filename \"-\" is a synonym for stdin.\n\n-n	Output the last NUMBER lines (default 10), +X counts from start\n-c	Output the last NUMBER bytes, +NUMBER counts from start\n-f	Follow FILE(s), waiting for more data to be appended"
 
 #define HELP_strings "usage: strings [-fo] [-t oxd] [-n LEN] [FILE...]\n\nDisplay printable strings in a binary file\n\n-f	Show filename\n-n	At least LEN characters form a string (default 4)\n-o	Show offset (ala -t d)\n-t	Show offset type (o=octal, d=decimal, x=hexadecimal)"
 
-#define HELP_split "usage: split [-a SUFFIX_LEN] [-b BYTES] [-l LINES] [-n PARTS] [INPUT [OUTPUT]]\n\nCopy INPUT (or stdin) data to a series of OUTPUT (or \"x\") files with\nalphabetically increasing suffix (aa, ab, ac... az, ba, bb...).\n\n-a	Suffix length (default 2)\n-b	BYTES/file (10, 10k, 10m, 10g...)\n-l	LINES/file (default 1000)\n-n	PARTS many equal length files"
+#define HELP_split "usage: split [-a SUFFIX_LEN] [-b BYTES] [-l LINES] [INPUT [OUTPUT]]\n\nCopy INPUT (or stdin) data to a series of OUTPUT (or \"x\") files with\nalphabetically increasing suffix (aa, ab, ac... az, ba, bb...).\n\n-a	Suffix length (default 2)\n-b	BYTES/file (10, 10k, 10m, 10g...)\n-l	LINES/file (default 1000)"
 
 #define HELP_sort "usage: sort [-Mbcdfginrsuz] [FILE...] [-k#[,#[x]] [-t X]] [-o FILE]\n\nSort all lines of text from input files (or stdin) to stdout.\n-M	Month sort (jan, feb, etc)\n-V	Version numbers (name-1.234-rc6.5b.tgz)\n-b	Ignore leading blanks (or trailing blanks in second part of key)\n-c	Check whether input is sorted\n-d	Dictionary order (use alphanumeric and whitespace chars only)\n-f	Force uppercase (case insensitive sort)\n-g	General numeric sort (double precision with nan and inf)\n-i	Ignore nonprinting characters\n-k	Sort by \"key\" (see below)\n-n	Numeric order (instead of alphabetical)\n-o	Output to FILE instead of stdout\n-r	Reverse\n-s	Skip fallback sort (only sort with keys)\n-t	Use a key separator other than whitespace\n-u	Unique lines only\n-x	Hexadecimal numerical sort\n-z	Zero (null) terminated lines\n\nSorting by key looks at a subset of the words on each line. -k2 uses the\nsecond word to the end of the line, -k2,2 looks at only the second word,\n-k2,4 looks from the start of the second to the end of the fourth word.\n-k2.4,5 starts from the fourth character of the second word, to the end\nof the fifth word. Specifying multiple keys uses the later keys as tie\nbreakers, in order. A type specifier appended to a sort key (such as -2,2n)\napplies only to sorting that key."
 
@@ -558,13 +536,13 @@
 
 #define HELP_iotop "usage: iotop [-AaKObq] [-n NUMBER] [-d SECONDS] [-p PID,] [-u USER,]\n\nRank processes by I/O.\n\n-A	All I/O, not just disk\n-a	Accumulated I/O (not percentage)\n-H	Show threads\n-K	Kilobytes\n-k	Fallback sort FIELDS (default -[D]IO,-ETIME,-PID)\n-m	Maximum number of tasks to show\n-O	Only show processes doing I/O\n-o	Show FIELDS (default PID,PR,USER,[D]READ,[D]WRITE,SWAP,[D]IO,COMM)\n-s	Sort by field number (0-X, default 6)\n-b	Batch mode (no tty)\n-d	Delay SECONDS between each cycle (default 3)\n-n	Exit after NUMBER iterations\n-p	Show these PIDs\n-u	Show these USERs\n-q	Quiet (no header lines)\n\nCursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force\nupdate, R to reverse sort, Q to exit."
 
-#define HELP_top "usage: top [-Hhbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]\n\nShow process activity in real time.\n\n-H	Show threads\n-h	Usage graphs instead of text\n-k	Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)\n-o	Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)\n-O	Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)\n-s	Sort by field number (1-X, default 9)\n-b	Batch mode (no tty)\n-d	Delay SECONDS between each cycle (default 3)\n-m	Maximum number of tasks to show\n-n	Exit after NUMBER iterations\n-p	Show these PIDs\n-u	Show these USERs\n-q	Quiet (no header lines)\n\nCursor UP/DOWN or LEFT/RIGHT to move list, SHIFT LEFT/RIGHT to change sort,\nspace to force update, R to reverse sort, Q to exit."
+#define HELP_top "usage: top [-Hbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]\n\nShow process activity in real time.\n\n-H	Show threads\n-k	Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)\n-o	Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)\n-O	Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)\n-s	Sort by field number (1-X, default 9)\n-b	Batch mode (no tty)\n-d	Delay SECONDS between each cycle (default 3)\n-m	Maximum number of tasks to show\n-n	Exit after NUMBER iterations\n-p	Show these PIDs\n-u	Show these USERs\n-q	Quiet (no header lines)\n\nCursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force\nupdate, R to reverse sort, Q to exit."
 
 #define HELP_ps "usage: ps [-AadefLlnwZ] [-gG GROUP,] [-k FIELD,] [-o FIELD,] [-p PID,] [-t TTY,] [-uU USER,]\n\nList processes.\n\nWhich processes to show (-gGuUpPt selections may be comma separated lists):\n\n-A  All					-a  Has terminal not session leader\n-d  All but session leaders		-e  Synonym for -A\n-g  In GROUPs				-G  In real GROUPs (before sgid)\n-p  PIDs (--pid)			-P  Parent PIDs (--ppid)\n-s  In session IDs			-t  Attached to selected TTYs\n-T  Show threads also			-u  Owned by selected USERs\n-U  Real USERs (before suid)\n\nOutput modifiers:\n\n-k  Sort FIELDs (-FIELD to reverse)	-M  Measure/pad future field widths\n-n  Show numeric USER and GROUP		-w  Wide output (don't truncate fields)\n\nWhich FIELDs to show. (-o HELP for list, default = -o PID,TTY,TIME,CMD)\n\n-f  Full listing (-o USER:12=UID,PID,PPID,C,STIME,TTY,TIME,ARGS=CMD)\n-l  Long listing (-o F,S,UID,PID,PPID,C,PRI,NI,ADDR,SZ,WCHAN,TTY,TIME,CMD)\n-o  Output FIELDs instead of defaults, each with optional :size and =title\n-O  Add FIELDS to defaults\n-Z  Include LABEL"
 
 #define HELP_printf "usage: printf FORMAT [ARGUMENT...]\n\nFormat and print ARGUMENT(s) according to FORMAT, using C printf syntax\n(% escapes for cdeEfgGiosuxX, \\ escapes for abefnrtv0 or \\OCTAL or \\xHEX)."
 
-#define HELP_patch "usage: patch [-Rlsu] [-d DIR] [-i PATCH] [-p DEPTH] [-F FUZZ] [--dry-run] [FILE [PATCH]]\n\nApply a unified diff to one or more files.\n\n-d	Modify files in DIR\n-i	Input patch file (default=stdin)\n-l	Loose match (ignore whitespace)\n-p	Number of '/' to strip from start of file paths (default=all)\n-R	Reverse patch\n-s	Silent except for errors\n-u	Ignored (only handles \"unified\" diffs)\n--dry-run Don't change files, just confirm patch applies\n\nThis version of patch only handles unified diffs, and only modifies\na file when all hunks to that file apply. Patch prints failed hunks\nto stderr, and exits with nonzero status if any hunks fail.\n\nA file compared against /dev/null (or with a date <= the epoch) is\ncreated/deleted as appropriate."
+#define HELP_patch "usage: patch [-d DIR] [-i PATCH] [-p DEPTH] [-F FUZZ] [-Rlsu] [--dry-run] [FILE [PATCH]]\n\nApply a unified diff to one or more files.\n\n-d	Modify files in DIR\n-i	Input patch file (default=stdin)\n-l	Loose match (ignore whitespace)\n-p	Number of '/' to strip from start of file paths (default=all)\n-R	Reverse patch\n-s	Silent except for errors\n-u	Ignored (only handles \"unified\" diffs)\n--dry-run Don't change files, just confirm patch applies\n\nThis version of patch only handles unified diffs, and only modifies\na file when all hunks to that file apply. Patch prints failed hunks\nto stderr, and exits with nonzero status if any hunks fail.\n\nA file compared against /dev/null (or with a date <= the epoch) is\ncreated/deleted as appropriate."
 
 #define HELP_paste "usage: paste [-s] [-d DELIMITERS] [FILE...]\n\nMerge corresponding lines from each input file.\n\n-d	List of delimiter characters to separate fields with (default is \\t)\n-s	Sequential mode: turn each input file into one line of output"
 
@@ -610,11 +588,11 @@
 
 #define HELP_head "usage: head [-n NUM] [FILE...]\n\nCopy first lines from files to stdout. If no files listed, copy from\nstdin. Filename \"-\" is a synonym for stdin.\n\n-n	Number of lines to copy\n-c	Number of bytes to copy\n-q	Never print headers\n-v	Always print headers"
 
-#define HELP_grep "usage: grep [-EFrivwcloqsHbhn] [-ABC NUM] [-m MAX] [-e REGEX]... [-MS PATTERN]... [-f REGFILE] [FILE]...\n\nShow lines matching regular expressions. If no -e, first argument is\nregular expression to match. With no files (or \"-\" filename) read stdin.\nReturns 0 if matched, 1 if no match found, 2 for command errors.\n\n-e  Regex to match. (May be repeated.)\n-f  File listing regular expressions to match.\n\nfile search:\n-r  Recurse into subdirectories (defaults FILE to \".\")\n-R  Recurse into subdirectories and symlinks to directories\n-M  Match filename pattern (--include)\n-S  Skip filename pattern (--exclude)\n--exclude-dir=PATTERN  Skip directory pattern\n-I  Ignore binary files\n\nmatch type:\n-A  Show NUM lines after     -B  Show NUM lines before match\n-C  NUM lines context (A+B)  -E  extended regex syntax\n-F  fixed (literal match)    -a  always text (not binary)\n-i  case insensitive         -m  match MAX many lines\n-v  invert match             -w  whole word (implies -E)\n-x  whole line               -z  input NUL terminated\n\ndisplay modes: (default: matched line)\n-L  filenames with no match  -Z  output is NUL terminated\n-c  count of matching lines  -l  filenames with a match\n-o  only matching part       -q  quiet (errors only)\n-s  silent (no error msg)\n\noutput prefix (default: filename if checking more than 1 file)\n-H  force filename           -b  byte offset of match\n-h  hide filename            -n  line number of match"
+#define HELP_grep "usage: grep [-EFrivwcloqsHbhn] [-ABC NUM] [-m MAX] [-e REGEX]... [-MS PATTERN]... [-f REGFILE] [FILE]...\n\nShow lines matching regular expressions. If no -e, first argument is\nregular expression to match. With no files (or \"-\" filename) read stdin.\nReturns 0 if matched, 1 if no match found, 2 for command errors.\n\n-e  Regex to match. (May be repeated.)\n-f  File listing regular expressions to match.\n\nfile search:\n-r  Recurse into subdirectories (defaults FILE to \".\")\n-R  Recurse into subdirectories and symlinks to directories\n-M  Match filename pattern (--include)\n-S  Skip filename pattern (--exclude)\n--exclude-dir=PATTERN  Skip directory pattern\n-I  Ignore binary files\n\nmatch type:\n-A  Show NUM lines after     -B  Show NUM lines before match\n-C  NUM lines context (A+B)  -E  extended regex syntax\n-F  fixed (literal match)    -a  always text (not binary)\n-i  case insensitive         -m  match MAX many lines\n-v  invert match             -w  whole word (implies -E)\n-x  whole line               -z  input NUL terminated\n\ndisplay modes: (default: matched line)\n-c  count of matching lines  -l  show only matching filenames\n-o  only matching part       -q  quiet (errors only)\n-s  silent (no error msg)    -Z  output NUL terminated\n\noutput prefix (default: filename if checking more than 1 file)\n-H  force filename           -b  byte offset of match\n-h  hide filename            -n  line number of match"
 
 #define HELP_getconf "usage: getconf -a [PATH] | -l | NAME [PATH]\n\nGet system configuration values. Values from pathconf(3) require a path.\n\n-a	Show all (defaults to \"/\" if no path given)\n-l	List available value names (grouped by source)"
 
-#define HELP_find "usage: find [-HL] [DIR...] [<options>]\n\nSearch directories for matching files.\nDefault: search \".\", match all, -print matches.\n\n-H  Follow command line symlinks         -L  Follow all symlinks\n\nMatch filters:\n-name  PATTERN   filename with wildcards   -iname      ignore case -name\n-path  PATTERN   path name with wildcards  -ipath      ignore case -path\n-user  UNAME     belongs to user UNAME     -nouser     user ID not known\n-group GROUP     belongs to group GROUP    -nogroup    group ID not known\n-perm  [-/]MODE  permissions (-=min /=any) -prune      ignore dir contents\n-size  N[c]      512 byte blocks (c=bytes) -xdev       only this filesystem\n-links N         hardlink count            -atime N[u] accessed N units ago\n-ctime N[u]      created N units ago       -mtime N[u] modified N units ago\n-inum N          inode number N            -empty      empty files and dirs\n-true            always true               -false      always false\n-context PATTERN security context          -executable access(X_OK) perm+ACL\n-samefile FILE   hardlink to FILE          -quit       exit immediately\n-depth           ignore contents of dir    -maxdepth N at most N dirs down\n-newer FILE      newer mtime than FILE     -mindepth N at least N dirs down\n-newerXY FILE    X=acm time > FILE's Y=acm time (Y=t: FILE is literal time)\n-type [bcdflps]  type is (block, char, dir, file, symlink, pipe, socket)\n\nNumbers N may be prefixed by a - (less than) or + (greater than). Units for\n-Xtime are d (days, default), h (hours), m (minutes), or s (seconds).\n\nCombine matches with:\n!, -a, -o, ( )    not, and, or, group expressions\n\nActions:\n-print  Print match with newline  -print0        Print match with null\n-exec   Run command with path     -execdir       Run command in file's dir\n-ok     Ask before exec           -okdir         Ask before execdir\n-delete Remove matching file/dir  -printf FORMAT Print using format string\n\nCommands substitute \"{}\" with matched file. End with \";\" to run each file,\nor \"+\" (next argument after \"{}\") to collect and run with multiple files.\n\n-printf FORMAT characters are \\ escapes and:\n%b  512 byte blocks used\n%f  basename            %g  textual gid          %G  numeric gid\n%i  decimal inode       %l  target of symlink    %m  octal mode\n%M  ls format type/mode %p  path to file         %P  path to file minus DIR\n%s  size in bytes       %T@ mod time as unixtime\n%u  username            %U  numeric uid          %Z  security context"
+#define HELP_find "usage: find [-HL] [DIR...] [<options>]\n\nSearch directories for matching files.\nDefault: search \".\", match all, -print matches.\n\n-H  Follow command line symlinks         -L  Follow all symlinks\n\nMatch filters:\n-name  PATTERN   filename with wildcards  (-iname case insensitive)\n-path  PATTERN   path name with wildcards (-ipath case insensitive)\n-user  UNAME     belongs to user UNAME     -nouser     user ID not known\n-group GROUP     belongs to group GROUP    -nogroup    group ID not known\n-perm  [-/]MODE  permissions (-=min /=any) -prune      ignore dir contents\n-size  N[c]      512 byte blocks (c=bytes) -xdev       only this filesystem\n-links N         hardlink count            -atime N[u] accessed N units ago\n-ctime N[u]      created N units ago       -mtime N[u] modified N units ago\n-newer FILE      newer mtime than FILE     -mindepth N at least N dirs down\n-depth           ignore contents of dir    -maxdepth N at most N dirs down\n-inum N          inode number N            -empty      empty files and dirs\n-type [bcdflps]  type is (block, char, dir, file, symlink, pipe, socket)\n-true            always true               -false      always false\n-context PATTERN security context          -executable access(X_OK) perm+ACL\n-newerXY FILE    X=acm time > FILE's Y=acm time (Y=t: FILE is literal time)\n\nNumbers N may be prefixed by a - (less than) or + (greater than). Units for\n-Xtime are d (days, default), h (hours), m (minutes), or s (seconds).\n\nCombine matches with:\n!, -a, -o, ( )    not, and, or, group expressions\n\nActions:\n-print  Print match with newline  -print0        Print match with null\n-exec   Run command with path     -execdir       Run command in file's dir\n-ok     Ask before exec           -okdir         Ask before execdir\n-delete Remove matching file/dir  -printf FORMAT Print using format string\n\nCommands substitute \"{}\" with matched file. End with \";\" to run each file,\nor \"+\" (next argument after \"{}\") to collect and run with multiple files.\n\n-printf FORMAT characters are \\ escapes and:\n%b  512 byte blocks used\n%f  basename            %g  textual gid          %G  numeric gid\n%i  decimal inode       %l  target of symlink    %m  octal mode\n%M  ls format type/mode %p  path to file         %P  path to file minus DIR\n%s  size in bytes       %T@ mod time as unixtime\n%u  username            %U  numeric uid          %Z  security context"
 
 #define HELP_file "usage: file [-bhLs] [FILE...]\n\nExamine the given files and describe their content types.\n\n-b	Brief (no filename)\n-h	Don't follow symlinks (default)\n-L	Follow symlinks\n-s	Show block/char device contents"
 
@@ -624,7 +602,7 @@
 
 #define HELP_env "usage: env [-i] [-u NAME] [NAME=VALUE...] [COMMAND...]\n\nSet the environment for command invocation, or list environment variables.\n\n-i	Clear existing environment\n-u NAME	Remove NAME from the environment\n-0	Use null instead of newline in output"
 
-#define HELP_echo "usage: echo [-neE] [ARG...]\n\nWrite each argument to stdout, one space between each, followed by a newline.\n\n-n	No trailing newline\n-E	Print escape sequences literally (default)\n-e	Process the following escape sequences:\n	\\\\  Backslash		\\0NNN Octal (1-3 digit)	\\xHH Hex (1-2 digit)\n	\\a  Alert (beep/flash)	\\b  Backspace		\\c  Stop here (no \\n)\n	\\f  Form feed		\\n  Newline		\\r  Carriage return\n	\\t  Horizontal tab	\\v  Vertical tab"
+#define HELP_echo "usage: echo [-neE] [ARG...]\n\nWrite each argument to stdout, with one space between each, followed\nby a newline.\n\n-n	No trailing newline\n-E	Print escape sequences literally (default)\n-e	Process the following escape sequences:\n	\\\\	Backslash\n	\\0NNN	Octal values (1 to 3 digits)\n	\\a	Alert (beep/flash)\n	\\b	Backspace\n	\\c	Stop output here (avoids trailing newline)\n	\\f	Form feed\n	\\n	Newline\n	\\r	Carriage return\n	\\t	Horizontal tab\n	\\v	Vertical tab\n	\\xHH	Hexadecimal values (1 to 2 digits)"
 
 #define HELP_du "usage: du [-d N] [-askxHLlmc] [FILE...]\n\nShow disk usage, space consumed by files and directories.\n\nSize in:\n-b	Apparent bytes (directory listing size, not space used)\n-k	1024 byte blocks (default)\n-K	512 byte blocks (posix)\n-m	Megabytes\n-h	Human readable (e.g., 1K 243M 2G)\n\nWhat to show:\n-a	All files, not just directories\n-H	Follow symlinks on cmdline\n-L	Follow all symlinks\n-s	Only total size of each argument\n-x	Don't leave this filesystem\n-c	Cumulative total\n-d N	Only depth < N\n-l	Disable hardlink filter"
 
@@ -632,9 +610,9 @@
 
 #define HELP_df "usage: df [-HPkhi] [-t type] [FILE...]\n\nThe \"disk free\" command shows total/used/available disk space for\neach filesystem listed on the command line, or all currently mounted\nfilesystems.\n\n-a	Show all (including /proc and friends)\n-P	The SUSv3 \"Pedantic\" option\n-k	Sets units back to 1024 bytes (the default without -P)\n-h	Human readable (K=1024)\n-H	Human readable (k=1000)\n-i	Show inodes instead of blocks\n-t type	Display only filesystems of this type\n\nPedantic provides a slightly less useful output format dictated by POSIX,\nand sets the units to 512 bytes instead of the default 1024 bytes."
 
-#define HELP_date "usage: date [-u] [-I RES] [-r FILE] [-d DATE] [+DISPLAY_FORMAT] [-D SET_FORMAT] [SET]\n\nSet/get the current date/time. With no SET shows the current date.\n\n-d	Show DATE instead of current time (convert date format)\n-D	+FORMAT for SET or -d (instead of MMDDhhmm[[CC]YY][.ss])\n-I RES	ISO 8601 with RESolution d=date/h=hours/m=minutes/s=seconds/n=ns\n-r	Use modification time of FILE instead of current date\n-s DATE	Set the system clock to DATE.\n-u	Use UTC instead of current timezone\n\nSupported input formats:\n\nMMDDhhmm[[CC]YY][.ss]     POSIX\n@UNIXTIME[.FRACTION]      seconds since midnight 1970-01-01\nYYYY-MM-DD [hh:mm[:ss]]   ISO 8601\nhh:mm[:ss]                24-hour time today\n\nAll input formats can be followed by fractional seconds, and/or a UTC\noffset such as -0800.\n\nAll input formats can be preceded by TZ=\"id\" to set the input time zone\nseparately from the output time zone. Otherwise $TZ sets both.\n\n+FORMAT specifies display format string using strftime(3) syntax:\n\n%% literal %             %n newline              %t tab\n%S seconds (00-60)       %M minute (00-59)       %m month (01-12)\n%H hour (0-23)           %I hour (01-12)         %p AM/PM\n%y short year (00-99)    %Y year                 %C century\n%a short weekday name    %A weekday name         %u day of week (1-7, 1=mon)\n%b short month name      %B month name           %Z timezone name\n%j day of year (001-366) %d day of month (01-31) %e day of month ( 1-31)\n%N nanosec (output only)\n\n%U Week of year (0-53 start Sunday)   %W Week of year (0-53 start Monday)\n%V Week of year (1-53 start Monday, week < 4 days not part of this year)\n\n%F \"%Y-%m-%d\"   %R \"%H:%M\"        %T \"%H:%M:%S\"        %z  timezone (-0800)\n%D \"%m/%d/%y\"   %r \"%I:%M:%S %p\"  %h \"%b\"              %:z timezone (-08:00)\n%x locale date  %X locale time    %c locale date/time  %s  unix epoch time"
+#define HELP_date "usage: date [-u] [-I RES] [-r FILE] [-d DATE] [+DISPLAY_FORMAT] [-D SET_FORMAT] [SET]\n\nSet/get the current date/time. With no SET shows the current date.\n\n-d	Show DATE instead of current time (convert date format)\n-D	+FORMAT for SET or -d (instead of MMDDhhmm[[CC]YY][.ss])\n-I RES	ISO 8601 with RESolution d=date/h=hours/m=minutes/s=seconds/n=ns\n-r	Use modification time of FILE instead of current date\n-u	Use UTC instead of current timezone\n\nSupported input formats:\n\nMMDDhhmm[[CC]YY][.ss]     POSIX\n@UNIXTIME[.FRACTION]      seconds since midnight 1970-01-01\nYYYY-MM-DD [hh:mm[:ss]]   ISO 8601\nhh:mm[:ss]                24-hour time today\n\nAll input formats can be followed by fractional seconds, and/or a UTC\noffset such as -0800.\n\nAll input formats can be preceded by TZ=\"id\" to set the input time zone\nseparately from the output time zone. Otherwise $TZ sets both.\n\n+FORMAT specifies display format string using strftime(3) syntax:\n\n%% literal %             %n newline              %t tab\n%S seconds (00-60)       %M minute (00-59)       %m month (01-12)\n%H hour (0-23)           %I hour (01-12)         %p AM/PM\n%y short year (00-99)    %Y year                 %C century\n%a short weekday name    %A weekday name         %u day of week (1-7, 1=mon)\n%b short month name      %B month name           %Z timezone name\n%j day of year (001-366) %d day of month (01-31) %e day of month ( 1-31)\n%N nanosec (output only)\n\n%U Week of year (0-53 start Sunday)   %W Week of year (0-53 start Monday)\n%V Week of year (1-53 start Monday, week < 4 days not part of this year)\n\n%F \"%Y-%m-%d\"   %R \"%H:%M\"        %T \"%H:%M:%S\"        %z  timezone (-0800)\n%D \"%m/%d/%y\"   %r \"%I:%M:%S %p\"  %h \"%b\"              %:z timezone (-08:00)\n%x locale date  %X locale time    %c locale date/time  %s  unix epoch time"
 
-#define HELP_cut "usage: cut [-Ds] [-bcCfF LIST] [-dO DELIM] [FILE...]\n\nPrint selected parts of lines from each FILE to standard output.\n\nEach selection LIST is comma separated, either numbers (counting from 1)\nor dash separated ranges (inclusive, with X- meaning to end of line and -X\nfrom start). By default selection ranges are sorted and collated, use -D\nto prevent that.\n\n-b	Select bytes\n-c	Select UTF-8 characters\n-C	Select unicode columns\n-d	Use DELIM (default is TAB for -f, run of whitespace for -F)\n-D	Don't sort/collate selections or match -fF lines without delimiter\n-f	Select fields (words) separated by single DELIM character\n-F	Select fields separated by DELIM regex\n-O	Output delimiter (default one space for -F, input delim for -f)\n-s	Skip lines without delimiters"
+#define HELP_cut "usage: cut [-Ds] [-bcfF LIST] [-dO DELIM] [FILE...]\n\nPrint selected parts of lines from each FILE to standard output.\n\nEach selection LIST is comma separated, either numbers (counting from 1)\nor dash separated ranges (inclusive, with X- meaning to end of line and -X\nfrom start). By default selection ranges are sorted and collated, use -D\nto prevent that.\n\n-b	Select bytes\n-c	Select UTF-8 characters\n-C	Select unicode columns\n-d	Use DELIM (default is TAB for -f, run of whitespace for -F)\n-D	Don't sort/collate selections or match -fF lines without delimiter\n-f	Select fields (words) separated by single DELIM character\n-F	Select fields separated by DELIM regex\n-O	Output delimiter (default one space for -F, input delim for -f)\n-s	Skip lines without delimiters"
 
 #define HELP_cpio "usage: cpio -{o|t|i|p DEST} [-v] [--verbose] [-F FILE] [--no-preserve-owner]\n       [ignored: -m -H newc]\n\nCopy files into and out of a \"newc\" format cpio archive.\n\n-F FILE	Use archive FILE instead of stdin/stdout\n-p DEST	Copy-pass mode, copy stdin file list to directory DEST\n-i	Extract from archive into file system (stdin=archive)\n-o	Create archive (stdin=list of files, stdout=archive)\n-t	Test files (list only, stdin=archive, stdout=list of files)\n-d	Create directories if needed\n-u	unlink existing files when extracting\n-v	Verbose\n--no-preserve-owner (don't set ownership during extract)"
 
@@ -646,7 +624,7 @@
 
 #define HELP_comm "usage: comm [-123] FILE1 FILE2\n\nRead FILE1 and FILE2, which should be ordered, and produce three text\ncolumns as output: lines only in FILE1; lines only in FILE2; and lines\nin both files. Filename \"-\" is a synonym for stdin.\n\n-1	Suppress the output column of lines unique to FILE1\n-2	Suppress the output column of lines unique to FILE2\n-3	Suppress the output column of lines duplicated in FILE1 and FILE2"
 
-#define HELP_cmp "usage: cmp [-ls] [-n LEN] FILE1 [FILE2 [SKIP1 [SKIP2]]]\n\nCompare the contents of files (vs stdin if only one given), optionally\nskipping bytes at start.\n\n-l	Show all differing bytes\n-n LEN	Compare at most LEN bytes\n-s	Silent"
+#define HELP_cmp "usage: cmp [-l] [-s] FILE1 [FILE2 [SKIP1 [SKIP2]]]\n\nCompare the contents of two files. (Or stdin and file if only one given.)\n\n-l	Show all differing bytes\n-s	Silent"
 
 #define HELP_crc32 "usage: crc32 [file...]\n\nOutput crc32 checksum for each file."
 
@@ -662,7 +640,7 @@
 
 #define HELP_cat "usage: cat [-etuv] [FILE...]\n\nCopy (concatenate) files to stdout.  If no files listed, copy from stdin.\nFilename \"-\" is a synonym for stdin.\n\n-e	Mark each newline with $\n-t	Show tabs as ^I\n-u	Copy one byte at a time (slow)\n-v	Display nonprinting characters as escape sequences with M-x for\n	high ascii characters (>127), and ^x for other nonprinting chars"
 
-#define HELP_cal "usage: cal [[[DAY] MONTH] YEAR]\n\nPrint a calendar.\n\nWith one argument, prints all months of the specified year.\nWith two arguments, prints calendar for month and year.\nWith three arguments, highlights day within month and year.\n\n-h	Don't highlight today"
+#define HELP_cal "usage: cal [[MONTH] YEAR]\n\nPrint a calendar.\n\nWith one argument, prints all months of the specified year.\nWith two arguments, prints calendar for month and year.\n\n-h	Don't highlight today"
 
 #define HELP_basename "usage: basename [-a] [-s SUFFIX] NAME... | NAME [SUFFIX]\n\nReturn non-directory portion of a pathname removing suffix.\n\n-a		All arguments are names\n-s SUFFIX	Remove suffix (implies -a)"
 
diff --git a/android/mac/generated/newtoys.h b/android/mac/generated/newtoys.h
index ade8831..40ac3d4 100644
--- a/android/mac/generated/newtoys.h
+++ b/android/mac/generated/newtoys.h
@@ -1,4 +1,4 @@
-USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT|TOYFLAG_NOHELP))
+USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT))
 USE_SH(OLDTOY(-bash, sh, 0))
 USE_SH(OLDTOY(-sh, sh, 0))
 USE_SH(OLDTOY(-toysh, sh, 0))
@@ -11,7 +11,7 @@
 USE_ARCH(NEWTOY(arch, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_ARP(NEWTOY(arp, "vi:nDsdap:A:H:[+Ap][!sd]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_ARPING(NEWTOY(arping, "<1>1s:I:w#<0c#<0AUDbqf[+AU][+Df]", TOYFLAG_USR|TOYFLAG_SBIN))
-USE_ASCII(NEWTOY(ascii, 0, TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LINEBUF))
+USE_ASCII(NEWTOY(ascii, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_BASE32(NEWTOY(base32, "diw#<0=76[!dw]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_BASE64(NEWTOY(base64, "diw#<0=76[!dw]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_BASENAME(NEWTOY(basename, "^<1as:", TOYFLAG_USR|TOYFLAG_BIN))
@@ -24,7 +24,7 @@
 USE_BRCTL(NEWTOY(brctl, "<1", TOYFLAG_USR|TOYFLAG_SBIN))
 USE_BUNZIP2(NEWTOY(bunzip2, "cftkv", TOYFLAG_USR|TOYFLAG_BIN))
 USE_BZCAT(NEWTOY(bzcat, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_CAL(NEWTOY(cal, ">3h", TOYFLAG_USR|TOYFLAG_BIN))
+USE_CAL(NEWTOY(cal, ">2h", TOYFLAG_USR|TOYFLAG_BIN))
 USE_CAT(NEWTOY(cat, "u"USE_CAT_V("vte"), TOYFLAG_BIN))
 USE_CATV(NEWTOY(catv, USE_CATV("vte"), TOYFLAG_USR|TOYFLAG_BIN))
 USE_SH(NEWTOY(cd, ">1LP[-LP]", TOYFLAG_NOFORK))
@@ -39,19 +39,18 @@
 USE_CHVT(NEWTOY(chvt, "<1", TOYFLAG_USR|TOYFLAG_BIN))
 USE_CKSUM(NEWTOY(cksum, "HIPLN", TOYFLAG_BIN))
 USE_CLEAR(NEWTOY(clear, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_CMP(NEWTOY(cmp, "<1>4ls(silent)(quiet)n#<1[!ls]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
+USE_CMP(NEWTOY(cmp, "<1>2ls(silent)(quiet)[!ls]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
 USE_COMM(NEWTOY(comm, "<2>2321", TOYFLAG_USR|TOYFLAG_BIN))
 USE_COUNT(NEWTOY(count, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]", TOYFLAG_BIN))
-USE_CPIO(NEWTOY(cpio, "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
+USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]", TOYFLAG_BIN))
+USE_CPIO(NEWTOY(cpio, "(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
 USE_CRC32(NEWTOY(crc32, 0, TOYFLAG_BIN))
 USE_CROND(NEWTOY(crond, "fbSl#<0=8d#<0L:c:[-bf][-LS][-ld]", TOYFLAG_USR|TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_CRONTAB(NEWTOY(crontab, "c:u:elr[!elr]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
-USE_CUT(NEWTOY(cut, "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_DATE(NEWTOY(date, "d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr]", TOYFLAG_BIN))
+USE_CUT(NEWTOY(cut, "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_DATE(NEWTOY(date, "d:D:I(iso)(iso-8601):;r:u(utc)[!dr]", TOYFLAG_BIN))
 USE_DD(NEWTOY(dd, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_DEALLOCVT(NEWTOY(deallocvt, ">1", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NEEDROOT))
-USE_SH(NEWTOY(declare, "pAailunxr", TOYFLAG_NOFORK))
 USE_GROUPDEL(OLDTOY(delgroup, groupdel, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_USERDEL(OLDTOY(deluser, userdel, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_DEMO_MANY_OPTIONS(NEWTOY(demo_many_options, "ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba", TOYFLAG_BIN))
@@ -90,7 +89,7 @@
 USE_FLOCK(NEWTOY(flock, "<1>1nsux[-sux]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_FMT(NEWTOY(fmt, "w#<0=75", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_FOLD(NEWTOY(fold, "bsuw#<1", TOYFLAG_USR|TOYFLAG_BIN))
-USE_FREE(NEWTOY(free, "hgmkb[!hgmkb]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_FREE(NEWTOY(free, "htgmkb[!htgmkb]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_FREERAMDISK(NEWTOY(freeramdisk, "<1>1", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_FSCK(NEWTOY(fsck, "?t:ANPRTVsC#", TOYFLAG_USR|TOYFLAG_BIN))
 USE_FSFREEZE(NEWTOY(fsfreeze, "<1>1f|u|[!fu]", TOYFLAG_USR|TOYFLAG_SBIN))
@@ -103,29 +102,22 @@
 USE_GETFATTR(NEWTOY(getfattr, "(only-values)dhn:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_GETOPT(NEWTOY(getopt, "^a(alternative)n:(name)o:(options)l*(long)(longoptions)Tu", TOYFLAG_USR|TOYFLAG_BIN))
 USE_GETTY(NEWTOY(getty, "<2t#<0H:I:l:f:iwnmLh", TOYFLAG_SBIN))
-USE_GPIODETECT(NEWTOY(gpiodetect, ">0", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOINFO(NEWTOY(gpiofind, "<1>1", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOGET(NEWTOY(gpioget, "<2l", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOFIND(NEWTOY(gpioinfo, 0, TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOSET(NEWTOY(gpioset, "<2l", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GREP(NEWTOY(grep, "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF]", TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)|TOYFLAG_LINEBUF))
+USE_GREP(NEWTOY(grep, "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw]", TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)|TOYFLAG_LINEBUF))
 USE_GROUPADD(NEWTOY(groupadd, "<1>2g#<0S", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_GROUPDEL(NEWTOY(groupdel, "<1>2", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
 USE_GROUPS(NEWTOY(groups, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 USE_GUNZIP(NEWTOY(gunzip, "cdfk123456789[-123456789]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_GZIP(NEWTOY(gzip,    "ncdfk123456789[-123456789]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_REBOOT(OLDTOY(halt, reboot, TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
-USE_HD(OLDTOY(hd, hexdump, TOYFLAG_USR|TOYFLAG_BIN))
 USE_HEAD(NEWTOY(head, "?n(lines)#<0=10c(bytes)#<0qv[-nc]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HELLO(NEWTOY(hello, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_HELP(NEWTOY(help, "ahu", TOYFLAG_BIN|TOYFLAG_MAYFORK))
-USE_HEXDUMP(NEWTOY(hexdump, "bcCdn#<0os#<0vx[!bcCdox]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HEXEDIT(NEWTOY(hexedit, "<1>1r", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_HOST(NEWTOY(host, "<1>2avt:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HOSTID(NEWTOY(hostid, ">0", TOYFLAG_USR|TOYFLAG_BIN))
 USE_HOSTNAME(NEWTOY(hostname, ">1bdsfF:[!bdsf]", TOYFLAG_BIN))
 USE_HWCLOCK(NEWTOY(hwclock, ">0(fast)f(rtc):u(utc)l(localtime)t(systz)s(hctosys)r(show)w(systohc)[-ul][!rtsw]", TOYFLAG_SBIN))
-USE_I2CDETECT(NEWTOY(i2cdetect, ">3aFlqry[!qr]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_I2CDETECT(NEWTOY(i2cdetect, ">3aFly", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CDUMP(NEWTOY(i2cdump, "<2>2fy", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CGET(NEWTOY(i2cget, "<3>3fy", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CSET(NEWTOY(i2cset, "<4fy", TOYFLAG_USR|TOYFLAG_BIN))
@@ -137,7 +129,7 @@
 USE_INSMOD(NEWTOY(insmod, "<1", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_INSTALL(NEWTOY(install, "<1cdDpsvt:m:o:g:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_IONICE(NEWTOY(ionice, "^tc#<0>3=2n#<0>7=5p#", TOYFLAG_USR|TOYFLAG_BIN))
-USE_IORENICE(NEWTOY(iorenice, "<1>3", TOYFLAG_USR|TOYFLAG_BIN))
+USE_IORENICE(NEWTOY(iorenice, "?<1>3", TOYFLAG_USR|TOYFLAG_BIN))
 USE_IOTOP(NEWTOY(iotop, ">0AaKO" "Hk*o*p*u*s#<1=7d%<100=3000m#n#<1bq", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT|TOYFLAG_LOCALE))
 USE_IP(NEWTOY(ip, NULL, TOYFLAG_SBIN))
 USE_IP(OLDTOY(ipaddr, ip, TOYFLAG_SBIN))
@@ -154,21 +146,20 @@
 USE_KLOGD(NEWTOY(klogd, "c#<1>8n", TOYFLAG_SBIN))
 USE_LAST(NEWTOY(last, "f:W", TOYFLAG_BIN))
 USE_LINK(NEWTOY(link, "<2>2", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LINUX32(NEWTOY(linux32, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_LN(NEWTOY(ln, "<1rt:Tvnfs", TOYFLAG_BIN))
 USE_LOAD_POLICY(NEWTOY(load_policy, "<1>1", TOYFLAG_USR|TOYFLAG_SBIN))
-USE_LOG(NEWTOY(log, "p:t:", TOYFLAG_USR|TOYFLAG_SBIN))
+USE_LOG(NEWTOY(log, "<1p:t:", TOYFLAG_USR|TOYFLAG_SBIN))
 USE_LOGGER(NEWTOY(logger, "t:p:s", TOYFLAG_USR|TOYFLAG_BIN))
 USE_LOGIN(NEWTOY(login, ">1f:ph:", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
 USE_LOGNAME(NEWTOY(logname, ">0", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LOGPATH(NEWTOY(logpath, 0, TOYFLAG_NOHELP|TOYFLAG_USR|TOYFLAG_BIN))
+USE_LOGWRAPPER(NEWTOY(logwrapper, 0, TOYFLAG_NOHELP|TOYFLAG_USR|TOYFLAG_BIN))
 USE_LOSETUP(NEWTOY(losetup, ">2S(sizelimit)#s(show)ro#j:fdcaD[!afj]", TOYFLAG_SBIN))
 USE_LS(NEWTOY(ls, "(color):;(full-time)(show-control-chars)ZgoACFHLRSabcdfhikl@mnpqrstuw#=80<0x1[-Cxm1][-Cxml][-Cxmo][-Cxmg][-cu][-ftS][-HL][!qb]", TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_LSATTR(NEWTOY(lsattr, "ldapvR", TOYFLAG_BIN))
 USE_LSMOD(NEWTOY(lsmod, NULL, TOYFLAG_SBIN))
 USE_LSOF(NEWTOY(lsof, "lp*t", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LSPCI(NEWTOY(lspci, "emkn@i:", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LSUSB(NEWTOY(lsusb, "i:", TOYFLAG_USR|TOYFLAG_BIN))
+USE_LSPCI(NEWTOY(lspci, "emkn"USE_LSPCI_TEXT("@i:"), TOYFLAG_USR|TOYFLAG_BIN))
+USE_LSUSB(NEWTOY(lsusb, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 USE_MAKEDEVS(NEWTOY(makedevs, "<1>1d:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_MAN(NEWTOY(man, "k:M:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_MCOOKIE(NEWTOY(mcookie, "v(verbose)V(version)", TOYFLAG_USR|TOYFLAG_BIN))
@@ -195,24 +186,24 @@
 USE_NETCAT(NEWTOY(netcat, USE_NETCAT_LISTEN("^tElL")"w#<1W#<1p#<1>65535q#<1s:f:46uU"USE_NETCAT_LISTEN("[!tlL][!Lw]")"[!46U]", TOYFLAG_BIN))
 USE_NETSTAT(NEWTOY(netstat, "pWrxwutneal", TOYFLAG_BIN))
 USE_NICE(NEWTOY(nice, "^<1n#", TOYFLAG_BIN))
-USE_NL(NEWTOY(nl, "v#=1l#w#<0=6b:n:s:E", TOYFLAG_USR|TOYFLAG_BIN))
+USE_NL(NEWTOY(nl, "v#=1l#w#<0=6Eb:n:s:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_NOHUP(NEWTOY(nohup, "<1^", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
 USE_NPROC(NEWTOY(nproc, "(all)", TOYFLAG_USR|TOYFLAG_BIN))
 USE_NSENTER(NEWTOY(nsenter, "<1F(no-fork)t#<1(target)i:(ipc);m:(mount);n:(net);p:(pid);u:(uts);U:(user);", TOYFLAG_USR|TOYFLAG_BIN))
 USE_OD(NEWTOY(od, "j#vw#<1=16N#xsodcbA:t*", TOYFLAG_USR|TOYFLAG_BIN))
 USE_ONEIT(NEWTOY(oneit, "^<1nc:p3[!pn]", TOYFLAG_SBIN))
-USE_OPENVT(NEWTOY(openvt, "^<1c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
+USE_OPENVT(NEWTOY(openvt, "c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
 USE_PARTPROBE(NEWTOY(partprobe, "<1", TOYFLAG_SBIN))
 USE_PASSWD(NEWTOY(passwd, ">1a:dlu", TOYFLAG_STAYROOT|TOYFLAG_USR|TOYFLAG_BIN))
 USE_PASTE(NEWTOY(paste, "d:s", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_PATCH(NEWTOY(patch, ">2(no-backup-if-mismatch)(dry-run)"USE_TOYBOX_DEBUG("x")"F#g#fulp#d:i:Rs(quiet)", TOYFLAG_USR|TOYFLAG_BIN))
 USE_PGREP(NEWTOY(pgrep, "?cld:u*U*t*s*P*g*G*fnovxL:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_PIDOF(NEWTOY(pidof, "so:x", TOYFLAG_BIN))
+USE_PIDOF(NEWTOY(pidof, "<1so:x", TOYFLAG_BIN))
 USE_PING(NEWTOY(ping, "<1>1m#t#<0>255=64c#<0=3s#<0>4064=56i%W#<0=3w#<0qf46I:[-46]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_PING(OLDTOY(ping6, ping, TOYFLAG_USR|TOYFLAG_BIN))
 USE_PIVOT_ROOT(NEWTOY(pivot_root, "<2>2", TOYFLAG_SBIN))
 USE_PKILL(NEWTOY(pkill,    "?Vu*U*t*s*P*g*G*fnovxl:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_PMAP(NEWTOY(pmap, "<1pqx", TOYFLAG_USR|TOYFLAG_BIN))
+USE_PMAP(NEWTOY(pmap, "<1xq", TOYFLAG_USR|TOYFLAG_BIN))
 USE_REBOOT(OLDTOY(poweroff, reboot, TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_PRINTENV(NEWTOY(printenv, "(null)0", TOYFLAG_BIN))
 USE_PRINTF(NEWTOY(printf, "<1?^", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
@@ -224,8 +215,8 @@
 USE_READAHEAD(NEWTOY(readahead, NULL, TOYFLAG_BIN))
 USE_READELF(NEWTOY(readelf, "<1(dyn-syms)adehlnp:SsWx:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_READLINK(NEWTOY(readlink, "<1nqmef(canonicalize)[-mef]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_REALPATH(OLDTOY(realpath, readlink, TOYFLAG_USR|TOYFLAG_BIN))
-USE_REBOOT(NEWTOY(reboot, "d:fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
+USE_REALPATH(NEWTOY(realpath, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+USE_REBOOT(NEWTOY(reboot, "fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_RENICE(NEWTOY(renice, "<1gpun#|", TOYFLAG_USR|TOYFLAG_BIN))
 USE_RESET(NEWTOY(reset, 0, TOYFLAG_USR|TOYFLAG_BIN))
 USE_RESTORECON(NEWTOY(restorecon, "<1DFnRrv", TOYFLAG_USR|TOYFLAG_SBIN))
@@ -245,12 +236,12 @@
 USE_SETFATTR(NEWTOY(setfattr, "hn:|v:x:|[!xv]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SETSID(NEWTOY(setsid, "^<1wcd[!dc]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SH(NEWTOY(sh, "0(noediting)(noprofile)(norc)sc:i", TOYFLAG_BIN))
-USE_SHA1SUM(OLDTOY(sha1sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA224SUM(OLDTOY(sha224sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA256SUM(OLDTOY(sha256sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA384SUM(OLDTOY(sha384sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_SHA1SUM(NEWTOY(sha1sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TOYBOX_LIBCRYPTO(USE_SHA224SUM(OLDTOY(sha224sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
+USE_TOYBOX_LIBCRYPTO(USE_SHA256SUM(OLDTOY(sha256sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
+USE_TOYBOX_LIBCRYPTO(USE_SHA384SUM(OLDTOY(sha384sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
 USE_SHA3SUM(NEWTOY(sha3sum, "bSa#<128>512=224", TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA512SUM(OLDTOY(sha512sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_TOYBOX_LIBCRYPTO(USE_SHA512SUM(OLDTOY(sha512sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
 USE_SH(NEWTOY(shift, ">1", TOYFLAG_NOFORK))
 USE_SHRED(NEWTOY(shred, "<1zxus#<1n#<1o#<0f", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SKELETON(NEWTOY(skeleton, "(walrus)(blubber):;(also):e@d*c#b:a", TOYFLAG_USR|TOYFLAG_BIN))
@@ -259,9 +250,8 @@
 USE_SNTP(NEWTOY(sntp, ">1M :m :Sp:t#<0=1>16asdDqr#<4>17=10[!as]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_SORT(NEWTOY(sort, USE_SORT_FLOAT("g")"S:T:m" "o:k*t:" "xVbMcszdfirun", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
 USE_SH(NEWTOY(source, "<1", TOYFLAG_NOFORK))
-USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1[!bl]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_STAT(NEWTOY(stat, "<1c:(format)fLt", TOYFLAG_BIN))
-USE_STRACE(NEWTOY(strace, "^p#s#v", TOYFLAG_USR|TOYFLAG_SBIN))
 USE_STRINGS(NEWTOY(strings, "t:an#=4<1fo", TOYFLAG_USR|TOYFLAG_BIN))
 USE_STTY(NEWTOY(stty, "?aF:g[!ag]", TOYFLAG_BIN))
 USE_SU(NEWTOY(su, "^lmpu:g:c:s:[!lmp]", TOYFLAG_BIN|TOYFLAG_ROOTONLY))
@@ -273,8 +263,8 @@
 USE_SYSCTL(NEWTOY(sysctl, "^neNqwpaA[!ap][!aq][!aw][+aA]", TOYFLAG_SBIN))
 USE_SYSLOGD(NEWTOY(syslogd,">0l#<1>8=8R:b#<0>99=1s#<0=200m#<0>71582787=20O:p:f:a:nSKLD", TOYFLAG_SBIN|TOYFLAG_STAYROOT))
 USE_TAC(NEWTOY(tac, NULL, TOYFLAG_USR|TOYFLAG_BIN))
-USE_TAIL(NEWTOY(tail, "?fFs:c(bytes)-n(lines)-[-cn][-fF]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_TAR(NEWTOY(tar, "&(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TAIL(NEWTOY(tail, "?fc-n-[-cn]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TAR(NEWTOY(tar, "&(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TASKSET(NEWTOY(taskset, "<1^pa", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
 USE_TCPSVD(NEWTOY(tcpsvd, "^<3c#=30<1C:b#=20<0u:l:hEv", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TEE(NEWTOY(tee, "ia", TOYFLAG_USR|TOYFLAG_BIN))
@@ -283,9 +273,9 @@
 USE_TEST(NEWTOY(test, 0, TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NOHELP|TOYFLAG_MAYFORK))
 USE_TFTP(NEWTOY(tftp, "<1b#<8>65464r:l:g|p|[!gp]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TFTPD(NEWTOY(tftpd, "rcu:l", TOYFLAG_BIN))
-USE_TIME(NEWTOY(time, "<1^pv[-pv]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
+USE_TIME(NEWTOY(time, "<1^pv", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
 USE_TIMEOUT(NEWTOY(timeout, "<2^(foreground)(preserve-status)vk:s(signal):", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
-USE_TOP(NEWTOY(top, ">0O*h" "Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
+USE_TOP(NEWTOY(top, ">0O*" "Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_TOUCH(NEWTOY(touch, "<1acd:fmr:t:h[!dtr]", TOYFLAG_BIN))
 USE_SH(OLDTOY(toysh, sh, TOYFLAG_BIN))
 USE_TR(NEWTOY(tr, "^>2<1Ccsd[+cC]", TOYFLAG_USR|TOYFLAG_BIN))
@@ -295,11 +285,10 @@
 USE_TRUNCATE(NEWTOY(truncate, "<1s:|c", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TTY(NEWTOY(tty, "s", TOYFLAG_USR|TOYFLAG_BIN))
 USE_TUNCTL(NEWTOY(tunctl, "<1>1t|d|u:T[!td]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_UCLAMPSET(NEWTOY(uclampset, "p#am#<-1>1024M#<-1>1024R", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
 USE_TCPSVD(OLDTOY(udpsvd, tcpsvd, TOYFLAG_USR|TOYFLAG_BIN))
 USE_ULIMIT(NEWTOY(ulimit, ">1P#<1SHavutsrRqpnmlifedc[-SH][!apvutsrRqnmlifedc]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_UMOUNT(NEWTOY(umount, "cndDflrat*v[!na]", TOYFLAG_BIN|TOYFLAG_STAYROOT))
-USE_UNAME(NEWTOY(uname, "aomvrns", TOYFLAG_BIN))
+USE_UNAME(NEWTOY(uname, "oamvrns[+os]", TOYFLAG_BIN))
 USE_UNICODE(NEWTOY(unicode, "<1", TOYFLAG_USR|TOYFLAG_BIN))
 USE_UNIQ(NEWTOY(uniq, "f#s#w#zicdu", TOYFLAG_USR|TOYFLAG_BIN))
 USE_UNIX2DOS(NEWTOY(unix2dos, 0, TOYFLAG_BIN))
@@ -321,12 +310,12 @@
 USE_WATCH(NEWTOY(watch, "^<1n%<100=2000tebx", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_WATCHDOG(NEWTOY(watchdog, "<1>1Ft#=4<1T#=60<1", TOYFLAG_NEEDROOT|TOYFLAG_BIN))
 USE_WC(NEWTOY(wc, "mcwl", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
-USE_WGET(NEWTOY(wget, "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):", TOYFLAG_USR|TOYFLAG_BIN))
+USE_WGET(NEWTOY(wget, "(no-check-certificate)O:", TOYFLAG_USR|TOYFLAG_BIN))
 USE_WHICH(NEWTOY(which, "<1a", TOYFLAG_USR|TOYFLAG_BIN))
 USE_WHO(NEWTOY(who, "a", TOYFLAG_USR|TOYFLAG_BIN))
 USE_WHOAMI(OLDTOY(whoami, logname, TOYFLAG_USR|TOYFLAG_BIN))
 USE_XARGS(NEWTOY(xargs, "^E:P#<0=1optrn#<1(max-args)s#0[!0E]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_XXD(NEWTOY(xxd, ">1c#<0>256l#o#g#<1=2iprs#[!rs]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_XXD(NEWTOY(xxd, ">1c#l#o#g#<1=2iprs#[!rs]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_XZCAT(NEWTOY(xzcat, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 USE_YES(NEWTOY(yes, NULL, TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LINEBUF))
 USE_ZCAT(NEWTOY(zcat,     "cdfk123456789[-123456789]", TOYFLAG_USR|TOYFLAG_BIN))
diff --git a/configure b/configure
index c718e83..0b6501f 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #!/bin/bash
 
-# set environment variables used by scripts/make.sh
+# This sets environment variables used by scripts/make.sh
 
 # People run ./configure out of habit, so do "defconfig" for them.
 
@@ -11,12 +11,30 @@
   exit $?
 fi
 
-# Warn about stuff, disable stupid warnings, be 8-bit clean for utf8.
-CFLAGS="$CFLAGS -Wall -Wundef -Wno-char-subscripts -Werror=implicit-function-declaration -Wno-char-subscripts -Wno-pointer-sign -Wno-string-plus-int -funsigned-char"
-
-# Set default values if variable not already set
-: ${CC:=cc} ${HOSTCC:=cc} ${GENDIR:=generated} ${KCONFIG_CONFIG:=.config}
-: ${UNSTRIPPED:=$GENDIR/unstripped} ${OUTNAME:=toybox${TARGET:+-$TARGET}}
-: ${OPTIMIZE:=-Os -ffunction-sections -fdata-sections -fno-asynchronous-unwind-tables -fno-strict-aliasing}
+# CFLAGS and OPTIMIZE are different so you can add extra CFLAGS without
+# disabling default optimizations
+[ -z "$CFLAGS" ] && CFLAGS="-Wall -Wundef -Wno-char-subscripts -Werror=implicit-function-declaration"
+# Required for our expected ABI. we're 8-bit clean thus "char" must be unsigned.
+CFLAGS="$CFLAGS -funsigned-char"
+[ -z "$OPTIMIZE" ] && OPTIMIZE="-Os -ffunction-sections -fdata-sections -fno-asynchronous-unwind-tables -fno-strict-aliasing"
+# set ASAN=1 to enable "address sanitizer" and debuggable backtraces
+[ -z "$ASAN" ] || { CFLAGS="$CFLAGS -O1 -g -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize=address"; NOSTRIP=1; }
 
 # We accept LDFLAGS, but by default don't have anything in it
+if [ "$(uname)" != "Darwin" ]
+then
+  [ -z "$LDOPTIMIZE" ] && LDOPTIMIZE="-Wl,--gc-sections"
+  LDASNEEDED="-Wl,--as-needed"
+fi
+
+# The makefile provides defaults for these, so this only gets used if
+# you call scripts/make.sh and friends directly.
+
+[ -z "$CC" ] && CC=cc
+[ -z "$STRIP" ] && STRIP=strip
+
+# If HOSTCC needs CFLAGS or LDFLAGS, just add them to the variable
+# ala HOSTCC="blah-cc --static"
+[ -z "$HOSTCC" ] && HOSTCC=cc
+
+[ -z "$GENERATED" ] && GENERATED=generated
diff --git a/kconfig/kconfig-language.txt b/kconfig/kconfig-language.txt
deleted file mode 100644
index d821369..0000000
--- a/kconfig/kconfig-language.txt
+++ /dev/null
@@ -1,284 +0,0 @@
-Linux 2.6.12 Documentation/kbuild/kconfig-language.txt
-
-Introduction
-------------
-
-The configuration database is collection of configuration options
-organized in a tree structure:
-
-	+- Code maturity level options
-	|  +- Prompt for development and/or incomplete code/drivers
-	+- General setup
-	|  +- Networking support
-	|  +- System V IPC
-	|  +- BSD Process Accounting
-	|  +- Sysctl support
-	+- Loadable module support
-	|  +- Enable loadable module support
-	|     +- Set version information on all module symbols
-	|     +- Kernel module loader
-	+- ...
-
-Every entry has its own dependencies. These dependencies are used
-to determine the visibility of an entry. Any child entry is only
-visible if its parent entry is also visible.
-
-Menu entries
-------------
-
-Most entries define a config option, all other entries help to organize
-them. A single configuration option is defined like this:
-
-config MODVERSIONS
-	bool "Set version information on all module symbols"
-	depends MODULES
-	help
-	  Usually, modules have to be recompiled whenever you switch to a new
-	  kernel.  ...
-
-Every line starts with a key word and can be followed by multiple
-arguments.  "config" starts a new config entry. The following lines
-define attributes for this config option. Attributes can be the type of
-the config option, input prompt, dependencies, help text and default
-values. A config option can be defined multiple times with the same
-name, but every definition can have only a single input prompt and the
-type must not conflict.
-
-Menu attributes
----------------
-
-A menu entry can have a number of attributes. Not all of them are
-applicable everywhere (see syntax).
-
-- type definition: "bool"/"tristate"/"string"/"hex"/"int"
-  Every config option must have a type. There are only two basic types:
-  tristate and string, the other types are based on these two. The type
-  definition optionally accepts an input prompt, so these two examples
-  are equivalent:
-
-	bool "Networking support"
-  and
-	bool
-	prompt "Networking support"
-
-- input prompt: "prompt" <prompt> ["if" <expr>]
-  Every menu entry can have at most one prompt, which is used to display
-  to the user. Optionally dependencies only for this prompt can be added
-  with "if".
-
-- default value: "default" <expr> ["if" <expr>]
-  A config option can have any number of default values. If multiple
-  default values are visible, only the first defined one is active.
-  Default values are not limited to the menu entry, where they are
-  defined, this means the default can be defined somewhere else or be
-  overridden by an earlier definition.
-  The default value is only assigned to the config symbol if no other
-  value was set by the user (via the input prompt above). If an input
-  prompt is visible the default value is presented to the user and can
-  be overridden by him.
-  Optionally dependencies only for this default value can be added with
-  "if".
-
-- dependencies: "depends on"/"requires" <expr>
-  This defines a dependency for this menu entry. If multiple
-  dependencies are defined they are connected with '&&'. Dependencies
-  are applied to all other options within this menu entry (which also
-  accept an "if" expression), so these two examples are equivalent:
-
-	bool "foo" if BAR
-	default y if BAR
-  and
-	depends on BAR
-	bool "foo"
-	default y
-
-- reverse dependencies: "select" <symbol> ["if" <expr>]
-  While normal dependencies reduce the upper limit of a symbol (see
-  below), reverse dependencies can be used to force a lower limit of
-  another symbol. The value of the current menu symbol is used as the
-  minimal value <symbol> can be set to. If <symbol> is selected multiple
-  times, the limit is set to the largest selection.
-  Reverse dependencies can only be used with boolean or tristate
-  symbols.
-
-- numerical ranges: "range" <symbol> <symbol> ["if" <expr>]
-  This allows to limit the range of possible input values for int
-  and hex symbols. The user can only input a value which is larger than
-  or equal to the first symbol and smaller than or equal to the second
-  symbol.
-
-- help text: "help" or "---help---"
-  This defines a help text. The end of the help text is determined by
-  the indentation level, this means it ends at the first line which has
-  a smaller indentation than the first line of the help text.
-  "---help---" and "help" do not differ in behaviour, "---help---" is
-  used to help visually seperate configuration logic from help within
-  the file as an aid to developers.
-
-
-Menu dependencies
------------------
-
-Dependencies define the visibility of a menu entry and can also reduce
-the input range of tristate symbols. The tristate logic used in the
-expressions uses one more state than normal boolean logic to express the
-module state. Dependency expressions have the following syntax:
-
-<expr> ::= <symbol>                             (1)
-           <symbol> '=' <symbol>                (2)
-           <symbol> '!=' <symbol>               (3)
-           '(' <expr> ')'                       (4)
-           '!' <expr>                           (5)
-           <expr> '&&' <expr>                   (6)
-           <expr> '||' <expr>                   (7)
-
-Expressions are listed in decreasing order of precedence. 
-
-(1) Convert the symbol into an expression. Boolean and tristate symbols
-    are simply converted into the respective expression values. All
-    other symbol types result in 'n'.
-(2) If the values of both symbols are equal, it returns 'y',
-    otherwise 'n'.
-(3) If the values of both symbols are equal, it returns 'n',
-    otherwise 'y'.
-(4) Returns the value of the expression. Used to override precedence.
-(5) Returns the result of (2-/expr/).
-(6) Returns the result of min(/expr/, /expr/).
-(7) Returns the result of max(/expr/, /expr/).
-
-An expression can have a value of 'n', 'm' or 'y' (or 0, 1, 2
-respectively for calculations). A menu entry becomes visible when it's
-expression evaluates to 'm' or 'y'.
-
-There are two types of symbols: constant and nonconstant symbols.
-Nonconstant symbols are the most common ones and are defined with the
-'config' statement. Nonconstant symbols consist entirely of alphanumeric
-characters or underscores.
-Constant symbols are only part of expressions. Constant symbols are
-always surrounded by single or double quotes. Within the quote any
-other character is allowed and the quotes can be escaped using '\'.
-
-Menu structure
---------------
-
-The position of a menu entry in the tree is determined in two ways. First
-it can be specified explicitly:
-
-menu "Network device support"
-	depends NET
-
-config NETDEVICES
-	...
-
-endmenu
-
-All entries within the "menu" ... "endmenu" block become a submenu of
-"Network device support". All subentries inherit the dependencies from
-the menu entry, e.g. this means the dependency "NET" is added to the
-dependency list of the config option NETDEVICES.
-
-The other way to generate the menu structure is done by analyzing the
-dependencies. If a menu entry somehow depends on the previous entry, it
-can be made a submenu of it. First, the previous (parent) symbol must
-be part of the dependency list and then one of these two conditions
-must be true:
-- the child entry must become invisible, if the parent is set to 'n'
-- the child entry must only be visible, if the parent is visible
-
-config MODULES
-	bool "Enable loadable module support"
-
-config MODVERSIONS
-	bool "Set version information on all module symbols"
-	depends MODULES
-
-comment "module support disabled"
-	depends !MODULES
-
-MODVERSIONS directly depends on MODULES, this means it's only visible if
-MODULES is different from 'n'. The comment on the other hand is always
-visible when MODULES is visible (the (empty) dependency of MODULES is
-also part of the comment dependencies).
-
-
-Kconfig syntax
---------------
-
-The configuration file describes a series of menu entries, where every
-line starts with a keyword (except help texts). The following keywords
-end a menu entry:
-- config
-- menuconfig
-- choice/endchoice
-- comment
-- menu/endmenu
-- if/endif
-- source
-The first five also start the definition of a menu entry.
-
-config:
-
-	"config" <symbol>
-	<config options>
-
-This defines a config symbol <symbol> and accepts any of above
-attributes as options.
-
-menuconfig:
-	"menuconfig" <symbol>
-	<config options>
-
-This is similiar to the simple config entry above, but it also gives a
-hint to front ends, that all suboptions should be displayed as a
-separate list of options.
-
-choices:
-
-	"choice"
-	<choice options>
-	<choice block>
-	"endchoice"
-
-This defines a choice group and accepts any of above attributes as
-options. A choice can only be of type bool or tristate, while a boolean
-choice only allows a single config entry to be selected, a tristate
-choice also allows any number of config entries to be set to 'm'. This
-can be used if multiple drivers for a single hardware exists and only a
-single driver can be compiled/loaded into the kernel, but all drivers
-can be compiled as modules.
-A choice accepts another option "optional", which allows to set the
-choice to 'n' and no entry needs to be selected.
-
-comment:
-
-	"comment" <prompt>
-	<comment options>
-
-This defines a comment which is displayed to the user during the
-configuration process and is also echoed to the output files. The only
-possible options are dependencies.
-
-menu:
-
-	"menu" <prompt>
-	<menu options>
-	<menu block>
-	"endmenu"
-
-This defines a menu block, see "Menu structure" above for more
-information. The only possible options are dependencies.
-
-if:
-
-	"if" <expr>
-	<if block>
-	"endif"
-
-This defines an if block. The dependency expression <expr> is appended
-to all enclosed menu entries.
-
-source:
-
-	"source" <prompt>
-
-This reads the specified configuration file. This file is always parsed.
diff --git a/lib/args.c b/lib/args.c
index 2b8da7c..ef23cc0 100644
--- a/lib/args.c
+++ b/lib/args.c
@@ -77,7 +77,6 @@
 //     ? Allow unknown arguments (pass them through to command).
 //     & first arg has imaginary dash (ala tar/ps/ar) which sets FLAGS_NODASH
 //     0 Include argv[0] in optargs
-//     note: ^ and ? implied when no options
 //
 //   At the end: [groups] of previously seen options
 //     - Only one in group (switch off)    [-abc] means -ab=-b, -ba=-a, -abc=-c
@@ -255,7 +254,7 @@
 
   // Parse option string into a linked list of options with attributes.
 
-  if (!*options) gof->stopearly++, gof->noerror++;
+  if (!*options) gof->stopearly++;
   while (*options) {
     char *temp;
 
@@ -343,7 +342,7 @@
 
   // Parse trailing group indicators
   while (*options) {
-    unsigned long long bits = 0;
+    unsigned bits = 0;
 
     if (CFG_TOYBOX_DEBUG && *options != '[') error_exit("trailing %s", options);
 
@@ -355,20 +354,20 @@
     // Don't advance past ] but do process it once in loop.
     while (*options++ != ']') {
       struct opts *opt;
-      long long ll;
+      int i;
 
       if (CFG_TOYBOX_DEBUG && !*options) error_exit("[ without ]");
       // Find this option flag (in previously parsed struct opt)
-      for (ll = 1, opt = gof->opts; ; ll <<= 1, opt = opt->next) {
+      for (i=0, opt = gof->opts; ; i++, opt = opt->next) {
         if (*options == ']') {
           if (!opt) break;
-          if (bits&ll) opt->dex[idx] |= bits&~ll;
+          if (bits&(1<<i)) opt->dex[idx] |= bits&~(1<<i);
         } else {
           if (*options==1) break;
           if (CFG_TOYBOX_DEBUG && !opt)
             error_exit("[] unknown target %c", *options);
           if (opt->c == *options) {
-            bits |= ll;
+            bits |= 1<<i;
             break;
           }
         }
@@ -428,7 +427,6 @@
         }
 
         // do we match a known --longopt?
-        check_help(toys.argv+gof.argc);
         for (lo = gof.longopts; lo; lo = lo->next) {
           if (!strncmp(gof.arg, lo->str, lo->len)) {
             if (!gof.arg[lo->len]) gof.arg = 0;
diff --git a/lib/dirtree.c b/lib/dirtree.c
index 4023101..43ecbd8 100644
--- a/lib/dirtree.c
+++ b/lib/dirtree.c
@@ -162,6 +162,7 @@
   // according to the fddir() man page, the filehandle in the DIR * can still
   // be externally used by things that don't lseek() it.
 
+  // The extra parentheses are to shut the stupid compiler up.
   while ((entry = readdir(dir))) {
     if ((flags&DIRTREE_PROC) && !isdigit(*entry->d_name)) continue;
     if (!(new = dirtree_add_node(node, entry->d_name, flags))) continue;
diff --git a/lib/help.c b/lib/help.c
new file mode 100644
index 0000000..cd02302
--- /dev/null
+++ b/lib/help.c
@@ -0,0 +1,45 @@
+// Function to display help text
+
+#include "toys.h"
+
+#include "generated/help.h"
+
+#undef NEWTOY
+#undef OLDTOY
+#define NEWTOY(name,opt,flags) HELP_##name "\0"
+#if CFG_TOYBOX
+#define OLDTOY(name,oldname,flags) "\xff" #oldname "\0"
+#else
+#define OLDTOY(name, oldname, flags) HELP_##oldname "\0"
+#endif
+static char *help_data =
+#include "generated/newtoys.h"
+;
+
+void show_help(FILE *out, int full)
+{
+  int i = toys.which-toy_list;
+  char *s, *ss;
+
+  if (!(full&2))
+    fprintf(out, "Toybox %s" USE_TOYBOX(" multicall binary")
+                 ": https://landley.net/toybox"
+                 USE_TOYBOX(" (see toybox --help)") "\n\n", toybox_version);
+
+  if (CFG_TOYBOX_HELP) {
+    for (;;) {
+      s = help_data;
+      while (i--) s += strlen(s) + 1;
+      // If it's an alias, restart search for real name
+      if (*s != 255) break;
+      i = toy_find(++s)-toy_list;
+    }
+
+    if (full) fprintf(out, "%s\n", s);
+    else {
+      strstart(&s, "usage: ");
+      for (ss = s; *ss && *ss!='\n'; ss++);
+      fprintf(out, "%.*s\n", (int)(ss-s), s);
+    }
+  }
+}
diff --git a/lib/lib.c b/lib/lib.c
index cf0a958..87bda4f 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -178,8 +178,7 @@
   // test for. Might as well do it up front.
 
   if (!fstatat(atfd, dir, &buf, 0)) {
-    // Note that mkdir should return EEXIST for already existed directory/file.
-    if (!(flags&MKPATHAT_MAKE) || ((flags&MKPATHAT_MKLAST) && !S_ISDIR(buf.st_mode))) {
+    if ((flags&MKPATHAT_MKLAST) && !S_ISDIR(buf.st_mode)) {
       errno = EEXIST;
       return 1;
     } else return 0;
@@ -371,7 +370,7 @@
 
 // Convert utf8 sequence to a unicode wide character
 // returns bytes consumed, or -1 if err, or -2 if need more data.
-int utf8towc(unsigned *wc, char *str, unsigned len)
+int utf8towc(wchar_t *wc, char *str, unsigned len)
 {
   unsigned result, mask, first;
   char *s, c;
@@ -404,7 +403,7 @@
 {
   char *try, *new;
   int len, mlen = (strlen(s)|7)+9;
-  unsigned c;
+  wchar_t c;
 
   try = new = xmalloc(mlen);
 
@@ -449,16 +448,15 @@
 // Remove trailing \n
 char *chomp(char *s)
 {
-  char *p = s+strlen(s);
+  char *p = strrchr(s, '\n');
 
-  while (p>=s && (p[-1]=='\r' || p[-1]=='\n')) *--p = 0;
-
+  if (p && !p[1]) *p = 0;
   return s;
 }
 
 int unescape(char c)
 {
-  char *from = "\\abefnrtv", *to = "\\\a\b\e\f\n\r\t\v";
+  char *from = "\\abefnrtv", *to = "\\\a\b\033\f\n\r\t\v";
   int idx = stridx(from, c);
 
   return (idx == -1) ? 0 : to[idx];
@@ -484,7 +482,7 @@
   if (-1 == (idx = stridx("\\abeEfnrtv'\"?0", **c))) return '\\';
   ++*c;
 
-  return "\\\a\b\e\e\f\n\r\t\v'\"?"[idx];
+  return "\\\a\b\033\033\f\n\r\t\v'\"?"[idx];
 }
 
 // If string ends with suffix return pointer to start of suffix in string,
@@ -715,9 +713,9 @@
 void loopfiles_rw(char **argv, int flags, int permissions,
   void (*function)(int fd, char *name))
 {
-  int fd, failok = !(flags&WARN_ONLY), anyway = flags & LOOPFILES_ANYWAY;
+  int fd, failok = !(flags&WARN_ONLY);
 
-  flags &= ~(WARN_ONLY|LOOPFILES_ANYWAY);
+  flags &= ~WARN_ONLY;
 
   // If no arguments, read from stdin.
   if (!*argv) function((flags & O_ACCMODE) != O_RDONLY ? 1 : 0, "-");
@@ -728,10 +726,10 @@
     if (!strcmp(*argv, "-")) fd = 0;
     else if (0>(fd = notstdio(open(*argv, flags, permissions))) && !failok) {
       perror_msg_raw(*argv);
-      if (!anyway) continue;
+      continue;
     }
     function(fd, *argv);
-    if ((flags & O_CLOEXEC) && fd>0) close(fd);
+    if ((flags & O_CLOEXEC) && fd) close(fd);
   } while (*++argv);
 }
 
@@ -741,7 +739,7 @@
   loopfiles_rw(argv, O_RDONLY|O_CLOEXEC|WARN_ONLY, 0, function);
 }
 
-// glue to call do_lines() from loopfiles
+// glue to call dl_lines() from loopfiles
 static void (*do_lines_bridge)(char **pline, long len);
 static void loopfile_lines_bridge(int fd, char *name)
 {
@@ -755,6 +753,25 @@
   loopfiles_rw(argv, O_RDONLY|WARN_ONLY, 0, loopfile_lines_bridge);
 }
 
+// Slow, but small.
+char *get_line(int fd)
+{
+  char c, *buf = NULL;
+  long len = 0;
+
+  for (;;) {
+    if (1>read(fd, &c, 1)) break;
+    if (!(len & 63)) buf=xrealloc(buf, len+65);
+    if ((buf[len++]=c) == '\n') break;
+  }
+  if (buf) {
+    buf[len]=0;
+    if (buf[--len]=='\n') buf[len]=0;
+  }
+
+  return buf;
+}
+
 int wfchmodat(int fd, char *name, mode_t mode)
 {
   int rc = fchmodat(fd, name, mode, 0);
@@ -826,7 +843,7 @@
 
 // Create a 256 entry CRC32 lookup table.
 
-void crc_init(unsigned *crc_table, int little_endian)
+void crc_init(unsigned int *crc_table, int little_endian)
 {
   unsigned int i;
 
@@ -914,7 +931,7 @@
 // Output a nicely formatted table of all the signals.
 void list_signals(void)
 {
-  int i = 1, count = 0;
+  int i = 0, count = 0;
   unsigned cols = 80;
   char *name;
 
@@ -1051,7 +1068,7 @@
 // Return pointer to xabspath(file) if file is under dir, else 0
 char *fileunderdir(char *file, char *dir)
 {
-  char *s1 = xabspath(dir, ABS_FILE), *s2 = xabspath(file, 0), *ss = s2;
+  char *s1 = xabspath(dir, 1), *s2 = xabspath(file, -1), *ss = s2;
   int rc = s1 && s2 && strstart(&ss, s1) && (!s1[1] || s2[strlen(s1)] == '/');
 
   free(s1);
@@ -1066,8 +1083,8 @@
   char *s, *ret = 0;
   int i, j, k;
 
-  if (!(from = xabspath(from, 0))) return 0;
-  if (!(to = xabspath(to, 0))) goto error;
+  if (!(from = xabspath(from, -1))) return 0;
+  if (!(to = xabspath(to, -1))) goto error;
 
   // skip common directories from root
   for (i = j = 0; from[i] && from[i] == to[i]; i++) if (to[i] == '/') j = i+1;
@@ -1147,10 +1164,9 @@
       if (scripts && !strcmp(bb, getbasename(cmd+strlen(cmd)+1))) goto match;
       continue;
 match:
-      if (callback(u, *cur)) goto done;
+      if (callback(u, *cur)) break;
     }
   }
-done:
   closedir(dp);
 }
 
@@ -1252,7 +1268,7 @@
 }
 
 // Return cached passwd entries.
-struct passwd *bufgetpwnamuid(char *name, uid_t uid)
+struct passwd *bufgetpwuid(uid_t uid)
 {
   struct pwuidbuf_list {
     struct pwuidbuf_list *next;
@@ -1264,14 +1280,11 @@
 
   // If we already have this one, return it.
   for (list = pwuidbuf; list; list = list->next)
-    if (name ? !strcmp(name, list->pw.pw_name) : list->pw.pw_uid==uid)
-      return &(list->pw);
+    if (list->pw.pw_uid == uid) return &(list->pw);
 
   for (;;) {
     list = xrealloc(list, size *= 2);
-    if (name) errno = getpwnam_r(name, &list->pw, sizeof(*list)+(char *)list,
-      size-sizeof(*list), &temp);
-    else errno = getpwuid_r(uid, &list->pw, sizeof(*list)+(char *)list,
+    errno = getpwuid_r(uid, &list->pw, sizeof(*list)+(char *)list,
       size-sizeof(*list), &temp);
     if (errno != ERANGE) break;
   }
@@ -1287,13 +1300,8 @@
   return &list->pw;
 }
 
-struct passwd *bufgetpwuid(uid_t uid)
-{
-  return bufgetpwnamuid(0, uid);
-}
-
 // Return cached group entries.
-struct group *bufgetgrnamgid(char *name, gid_t gid)
+struct group *bufgetgrgid(gid_t gid)
 {
   struct grgidbuf_list {
     struct grgidbuf_list *next;
@@ -1304,14 +1312,11 @@
   unsigned size = 256;
 
   for (list = grgidbuf; list; list = list->next)
-    if (name ? !strcmp(name, list->gr.gr_name) : list->gr.gr_gid==gid)
-      return &(list->gr);
+    if (list->gr.gr_gid == gid) return &(list->gr);
 
   for (;;) {
     list = xrealloc(list, size *= 2);
-    if (name) errno = getgrnam_r(name, &list->gr, sizeof(*list)+(char *)list,
-      size-sizeof(*list), &temp);
-    else errno = getgrgid_r(gid, &list->gr, sizeof(*list)+(char *)list,
+    errno = getgrgid_r(gid, &list->gr, sizeof(*list)+(char *)list,
       size-sizeof(*list), &temp);
     if (errno != ERANGE) break;
   }
@@ -1326,12 +1331,6 @@
   return &list->gr;
 }
 
-struct group *bufgetgrgid(gid_t gid)
-{
-  return bufgetgrnamgid(0, gid);
-}
-
-
 // Always null terminates, returns 0 for failure, len for success
 int readlinkat0(int dirfd, char *path, char *buf, int len)
 {
diff --git a/lib/lib.h b/lib/lib.h
index 70e5bed..f9c0428 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -8,6 +8,11 @@
   long len;
 };
 
+struct str_len {
+  char *str;
+  long len;
+};
+
 // llist.c
 
 // All these list types can be handled by the same code because first element
@@ -16,7 +21,7 @@
 
 struct string_list {
   struct string_list *next;
-  char str[];
+  char str[0];
 };
 
 struct arg_list {
@@ -85,7 +90,8 @@
   char *symlink;
   int dirfd;
   struct stat st;
-  char again, name[];
+  char again;
+  char name[];
 };
 
 int isdotdot(char *name);
@@ -99,23 +105,20 @@
   int (*callback)(struct dirtree *node));
 struct dirtree *dirtree_read(char *path, int (*callback)(struct dirtree *node));
 
+// help.c
+
+void show_help(FILE *out, int full);
+
 // Tell xopen and friends to print warnings but return -1 as necessary
 // The largest O_BLAH flag so far is arch/alpha's O_PATH at 0x800000 so
 // plenty of headroom.
-#define WARN_ONLY        (1<<31) // don't exit, just warn
-#define LOOPFILES_ANYWAY (1<<30) // call function with fd -1
-
-// xabspath flags
-#define ABS_PATH 1 // all but last path component must exist
-#define ABS_FILE 2 // last path component must exist
-#define ABS_KEEP 4 // don't resolve symlinks in path to last component
-#define ABS_LAST 8 // don't resolve symlink in last path component
+#define WARN_ONLY (1<<31)
 
 // xwrap.c
 void xstrncpy(char *dest, char *src, size_t size);
 void xstrncat(char *dest, char *src, size_t size);
-_Noreturn void _xexit(void);
-_Noreturn void xexit(void);
+void _xexit(void) __attribute__((__noreturn__));
+void xexit(void) __attribute__((__noreturn__));
 void *xmmap(void *addr, size_t length, int prot, int flags, int fd, off_t off);
 void *xmalloc(size_t size);
 void *xzalloc(size_t size);
@@ -174,11 +177,9 @@
 unsigned xgetuid(char *name);
 unsigned xgetgid(char *name);
 void xsetuser(struct passwd *pwd);
-char *xreadlinkat(int dir, char *name);
 char *xreadlink(char *name);
 double xstrtod(char *s);
 long xparsetime(char *arg, long units, long *fraction);
-void xparsetimespec(char *arg, struct timespec *ts);
 long long xparsemillitime(char *arg);
 void xpidfile(char *name);
 void xregcomp(regex_t *preg, char *rexec, int cflags);
@@ -194,13 +195,13 @@
 void verror_msg(char *msg, int err, va_list va);
 void error_msg(char *msg, ...) printf_format;
 void perror_msg(char *msg, ...) printf_format;
-_Noreturn void error_exit(char *msg, ...) printf_format;
-_Noreturn void perror_exit(char *msg, ...) printf_format;
-_Noreturn void help_exit(char *msg, ...) printf_format;
+void error_exit(char *msg, ...) printf_format __attribute__((__noreturn__));
+void perror_exit(char *msg, ...) printf_format __attribute__((__noreturn__));
+void help_exit(char *msg, ...) printf_format __attribute__((__noreturn__));
 void error_msg_raw(char *msg);
 void perror_msg_raw(char *msg);
-_Noreturn void error_exit_raw(char *msg);
-_Noreturn void perror_exit_raw(char *msg);
+void error_exit_raw(char *msg);
+void perror_exit_raw(char *msg);
 ssize_t readall(int fd, void *buf, size_t len);
 ssize_t writeall(int fd, void *buf, size_t len);
 off_t lskip(int fd, off_t offset);
@@ -230,7 +231,7 @@
 long long atolx_range(char *numstr, long long low, long long high);
 int stridx(char *haystack, char needle);
 int wctoutf8(char *s, unsigned wc);
-int utf8towc(unsigned *wc, char *str, unsigned len);
+int utf8towc(wchar_t *wc, char *str, unsigned len);
 char *strlower(char *s);
 char *strafter(char *haystack, char *needle);
 char *chomp(char *s);
@@ -252,7 +253,7 @@
 int copy_tempfile(int fdin, char *name, char **tempname);
 void delete_tempfile(int fdin, int fdout, char **tempname);
 void replace_tempfile(int fdin, int fdout, char **tempname);
-void crc_init(unsigned *crc_table, int little_endian);
+void crc_init(unsigned int *crc_table, int little_endian);
 void base64_init(char *p);
 int yesno(int def);
 int fyesno(FILE *fp, int def);
@@ -260,9 +261,7 @@
 void create_uuid(char *uuid);
 char *show_uuid(char *uuid);
 char *next_printf(char *s, char **start);
-struct passwd *bufgetpwnamuid(char *name, uid_t uid);
 struct passwd *bufgetpwuid(uid_t uid);
-struct group *bufgetgrnamgid(char *name, gid_t gid);
 struct group *bufgetgrgid(gid_t gid);
 int readlinkat0(int dirfd, char *path, char *buf, int len);
 int readlink0(char *path, char *buf, int len);
@@ -295,8 +294,18 @@
 void xclearenv(void);
 void reset_env(struct passwd *p, int clear);
 
-// utf8.c
+// linestack.c
 
+struct linestack {
+  long len, max;
+  struct ptr_len idx[];
+};
+
+void linestack_addstack(struct linestack **lls, struct linestack *throw,
+  long pos);
+void linestack_insert(struct linestack **lls, long pos, char *line, long len);
+void linestack_append(struct linestack **lls, char *line);
+struct linestack *linestack_load(char *name);
 int crunch_escape(FILE *out, int cols, int wc);
 int crunch_rev_escape(FILE *out, int cols, int wc);
 int crunch_str(char **str, int width, FILE *out, char *escmore,
@@ -331,6 +340,8 @@
 void xsetspeed(struct termios *tio, int speed);
 int set_terminal(int fd, int raw, int speed, struct termios *old);
 void xset_terminal(int fd, int raw, int speed, struct termios *old);
+void tty_esc(char *s);
+void tty_jump(int x, int y);
 void tty_reset(void);
 void tty_sigreset(int i);
 void start_redraw(unsigned *width, unsigned *height);
diff --git a/lib/linestack.c b/lib/linestack.c
new file mode 100644
index 0000000..0fc83e6
--- /dev/null
+++ b/lib/linestack.c
@@ -0,0 +1,198 @@
+#include "toys.h"
+
+// The design idea here is indexing a big blob of (potentially mmaped) data
+// instead of copying the data into a zillion seperate malloc()s.
+
+// A linestack is an array of struct ptr_len, with a currently used len
+// and max tracking the memory allocation. This indexes existing string data,
+// the lifetime of which is tracked externally.
+
+// Insert one stack into another before position in old stack.
+// (Does not copy contents of strings, just shuffles index array contents.)
+void linestack_addstack(struct linestack **lls, struct linestack *throw,
+  long pos)
+{
+  struct linestack *catch = *lls;
+
+  if (CFG_TOYBOX_DEBUG)
+    if (pos > catch->len) error_exit("linestack_addstack past end.");
+
+  // Make a hole, allocating more space if necessary.
+  if (catch->len+throw->len >= catch->max) {
+    // New size rounded up to next multiple of 64, allocate and copy start.
+    catch->max = ((catch->len+throw->len)|63)+1;
+    *lls = xmalloc(sizeof(struct linestack)+catch->max*sizeof(struct ptr_len));
+    memcpy(*lls, catch, sizeof(struct linestack)+pos*sizeof(struct ptr_len));
+  }
+
+  // Copy end (into new allocation if necessary)
+  if (pos != catch->len)
+    memmove((*lls)->idx+pos+throw->len, catch->idx+pos,
+      (catch->len-pos)*sizeof(struct ptr_len));
+
+  // Cleanup if we had to realloc.
+  if (catch != *lls) {
+    free(catch);
+    catch = *lls;
+  }
+
+  // Copy new chunk we made space for
+  memcpy(catch->idx+pos, throw->idx, throw->len*sizeof(struct ptr_len));
+  catch->len += throw->len;
+}
+
+// Insert one line/len into a linestack at pos
+void linestack_insert(struct linestack **lls, long pos, char *line, long len)
+{
+  // alloca() was in 32V and Turbo C for DOS, but isn't in posix or c99.
+  // This allocates enough memory for the linestack to have one ptr_len.
+  // (Even if a compiler adds gratuitous padidng that just makes it bigger.)
+  struct {
+    struct ptr_len pl;
+    struct linestack ls;
+  } ls;
+
+  ls.ls.len = ls.ls.max = 1;
+  ls.ls.idx[0].ptr = line;
+  ls.ls.idx[0].len = len;
+  linestack_addstack(lls, &ls.ls, pos);
+}
+
+void linestack_append(struct linestack **lls, char *line)
+{
+  linestack_insert(lls, (*lls)->len, line, strlen(line));
+}
+
+struct linestack *linestack_load(char *name)
+{
+  FILE *fp = fopen(name, "r");
+  struct linestack *ls;
+
+  if (!fp) return 0;
+
+  ls = xzalloc(sizeof(struct linestack));
+
+  for (;;) {
+    char *line = 0;
+    ssize_t len;
+
+    if ((len = getline(&line, (void *)&len, fp))<1) break;
+    if (line[len-1]=='\n') len--;
+    linestack_insert(&ls, ls->len, line, len);
+  }
+  fclose(fp);
+
+  return ls;
+}
+
+// Show width many columns, negative means from right edge, out=0 just measure
+// if escout, send it unprintable chars, otherwise pass through raw data.
+// Returns width in columns, moves *str to end of data consumed.
+int crunch_str(char **str, int width, FILE *out, char *escmore,
+  int (*escout)(FILE *out, int cols, int wc))
+{
+  int columns = 0, col, bytes;
+  char *start, *end;
+
+  for (end = start = *str; *end; columns += col, end += bytes) {
+    wchar_t wc;
+
+    if ((bytes = utf8towc(&wc, end, 4))>0 && (col = wcwidth(wc))>=0) {
+      if (!escmore || wc>255 || !strchr(escmore, wc)) {
+        if (width-columns<col) break;
+        if (out) fwrite(end, bytes, 1, out);
+
+        continue;
+      }
+    }
+
+    if (bytes<1) {
+      bytes = 1;
+      wc = *end;
+    }
+    col = width-columns;
+    if (col<1) break;
+    if (escout) {
+      if ((col = escout(out, col, wc))<0) break;
+    } else if (out) fwrite(end, 1, bytes, out);
+  }
+  *str = end;
+
+  return columns;
+}
+
+
+// standard escapes: ^X if <32, <XX> if invalid UTF8, U+XXXX if UTF8 !iswprint()
+int crunch_escape(FILE *out, int cols, int wc)
+{
+  char buf[11];
+  int rc;
+
+  if (wc<' ') rc = sprintf(buf, "^%c", '@'+wc);
+  else if (wc<256) rc = sprintf(buf, "<%02X>", wc);
+  else rc = sprintf(buf, "U+%04X", wc);
+
+  if (rc > cols) buf[rc = cols] = 0;
+  if (out) fputs(buf, out);
+
+  return rc;
+}
+
+// Display "standard" escapes in reverse video.
+int crunch_rev_escape(FILE *out, int cols, int wc)
+{
+  int rc;
+
+  tty_esc("7m");
+  rc = crunch_escape(out, cols, wc);
+  tty_esc("27m");
+
+  return rc;
+}
+
+// Write width chars at start of string to strdout with standard escapes
+// Returns length in columns so caller can pad it out with spaces.
+int draw_str(char *start, int width)
+{
+  return crunch_str(&start, width, stdout, 0, crunch_rev_escape);
+}
+
+// Return utf8 columns
+int utf8len(char *str)
+{
+  return crunch_str(&str, INT_MAX, 0, 0, crunch_rev_escape);
+}
+
+// Return bytes used by (up to) this many columns
+int utf8skip(char *str, int width)
+{
+  char *s = str;
+
+  crunch_str(&s, width, 0, 0, crunch_rev_escape);
+
+  return s-str;
+}
+
+// Print utf8 to stdout with standard escapes, trimmed to width and padded
+// out to padto. If padto<0 left justify. Returns columns printed
+int draw_trim_esc(char *str, int padto, int width, char *escmore,
+  int (*escout)(FILE *out, int cols, int wc))
+{
+  int apad = abs(padto), len = utf8len(str);
+
+  if (padto>=0 && len>width) str += utf8skip(str, len-width);
+  if (len>width) len = width;
+
+  // Left pad if right justified 
+  if (padto>0 && apad>len) printf("%*s", apad-len, "");
+  crunch_str(&str, len, stdout, 0, crunch_rev_escape);
+  if (padto<0 && apad>len) printf("%*s", apad-len, "");
+
+  return (apad > len) ? apad : len;
+}
+
+// draw_trim_esc() with default escape
+int draw_trim(char *str, int padto, int width)
+{
+  return draw_trim_esc(str, padto, width, 0, 0);
+}
diff --git a/lib/llist.c b/lib/llist.c
index 6ceb1ce..45fe014 100644
--- a/lib/llist.c
+++ b/lib/llist.c
@@ -41,13 +41,14 @@
 // as &list)
 void *llist_pop(void *list)
 {
-  void **llist = list, **next;
-
-  if (!list || !*llist) return 0;
-  next = (void **)*llist;
+  // I'd use a void ** for the argument, and even accept the typecast in all
+  // callers as documentation you need the &, except the stupid compiler
+  // would then scream about type-punned pointers.  Screw it.
+  void **llist = (void **)list;
+  void **next = (void **)*llist;
   *llist = *next;
 
-  return next;
+  return (void *)next;
 }
 
 // Remove first item from &list and return it
@@ -81,7 +82,6 @@
   return v;
 }
 
-// Append to list in-order (*list unchanged unless empty, ->prev is new node)
 void dlist_add_nomalloc(struct double_list **list, struct double_list *new)
 {
   if (*list) {
@@ -92,6 +92,7 @@
   } else *list = new->next = new->prev = new;
 }
 
+
 // Add an entry to the end of a doubly linked list
 struct double_list *dlist_add(struct double_list **list, char *data)
 {
diff --git a/lib/password.c b/lib/password.c
index 3497176..3a39d9e 100644
--- a/lib/password.c
+++ b/lib/password.c
@@ -6,6 +6,7 @@
  */
 
 #include "toys.h"
+#include <time.h>
 
 // generate ID prefix and random salt for given encryption algorithm.
 int get_salt(char *salt, char *algo)
@@ -26,7 +27,7 @@
       xgetrandom(libbuf, ((len*6)+7)/8, 0);
 
       // Grab 6 bit chunks and convert to characters in ./0-9a-zA-Z
-      for (i = 0; i<len; i++) {
+      for (i=0; i<len; i++) {
         int bitpos = i*6, bits = bitpos/8;
 
         bits = ((libbuf[i]+(libbuf[i+1]<<8)) >> (bitpos&7)) & 0x3f;
@@ -49,109 +50,150 @@
 int read_password(char *buf, int buflen, char *mesg)
 {
   struct termios oldtermio;
-  struct sigaction sa = {.sa_handler = generic_signal}, oldsa;
+  struct sigaction sa, oldsa;
   int i, tty = tty_fd(), ret = 1;
 
-  // Set NOP signal handler to return from the read.
+  // NOP signal handler to return from the read. Use sigaction() instead
+  // of xsignal() because we want to restore the old handler afterwards.
+  memset(&sa, 0, sizeof(sa));
+  sa.sa_handler = generic_signal;
   sigaction(SIGINT, &sa, &oldsa);
+
   tcflush(tty, TCIFLUSH);
   xset_terminal(tty, 1, 0, &oldtermio);
   dprintf(tty, "%s", mesg);
 
-  // Loop assembling password. (Too long = fail)
   for (i = 0; i<buflen-1; i++) {
-    // tty closed, or EOF or ctrl-D at start, or ctrl-C anywhere: fail.
-    if ((ret = read(tty, buf+i, 1))<0 || (!ret&&!i) || *buf==4 || buf[i]==3)
+    if ((ret = read(tty, buf+i, 1))<0 || (!ret&&!i) || *buf==4 || buf[i]==3) {
+      i = 0;
+      ret = 1;
+
       break;
-    // EOF or newline: return success
-    else if (!ret || buf[i]=='\n' || buf[i]=='\r') {
+    } else if (!ret || buf[i] == '\n' || buf[i] == '\r') {
       ret = 0;
+
       break;
     } else if (buf[i] == 8 || buf[i] == 127) i -= 2-!i;
   }
 
   // Restore terminal/signal state, terminate string
-  tcsetattr(0, TCSANOW, &oldtermio);
   sigaction(SIGINT, &oldsa, 0);
+  tcsetattr(0, TCSANOW, &oldtermio);
+  buf[i] = 0;
   xputc('\n');
-  buf[i*!ret] = 0;
 
   return ret;
 }
 
-/* update colon-separated text files ala /etc/{passwd,shadow,group,gshadow}
- * username = string match for first entry in line
- * entry = new entry (NULL deletes matching line from file)
- * pos = which entry to replace with "entry" (0 is first)
- */
-// filename+ = new copy being written, filename- = backup of old version
-// returns 1 for success, 0 for failure
-int update_password(char *filename, char *username, char *entry, int pos)
+static char *get_nextcolon(char *line, int cnt)
 {
-  char *filenamesfx = xmprintf("%s-", filename), *line = 0, *start, *end;
-  FILE *ofp, *nfp;
-  int ret = 0, found = 0, len = strlen(username)*!strchr(username, ':'), ii;
-  struct flock lock = {.l_type = F_WRLCK};
-  long long ll = 0;
+  while (cnt--) {
+    if (!(line = strchr(line, ':'))) error_exit("Invalid Entry\n");
+    line++; //jump past the colon
+  }
+  return line;
+}
 
-  // Open old filename ("r" won't let us lock), get blocking lock
-  if (!(ofp = fopen(filename, "w+")) || 0>fcntl(fileno(ofp), F_SETLK, &lock)) {
-    perror_msg("%s", filename);
+/*update_password is used by multiple utilities to update /etc/passwd,
+ * /etc/shadow, /etc/group and /etc/gshadow files,
+ * which are used as user, group databeses
+ * entry can be
+ * 1. encrypted password, when updating user password.
+ * 2. complete entry for user details, when creating new user
+ * 3. group members comma',' separated list, when adding user to group
+ * 4. complete entry for group details, when creating new group
+ * 5. entry = NULL, delete the named entry user/group
+ */
+int update_password(char *filename, char* username, char* entry)
+{
+  char *filenamesfx = NULL, *namesfx = NULL, *shadow = NULL,
+       *sfx = NULL, *line = NULL;
+  FILE *exfp, *newfp;
+  int ret = -1, found = 0, n;
+  struct flock lock;
+  size_t allocated_length;
+
+  shadow = strstr(filename, "shadow");
+  filenamesfx = xmprintf("%s+", filename);
+  sfx = strchr(filenamesfx, '+');
+
+  exfp = fopen(filename, "r+");
+  if (!exfp) {
+    perror_msg("Couldn't open file %s",filename);
     goto free_storage;
   }
 
-  // Delete old backup, link new backup. (Failure here isn't fatal.)
+  *sfx = '-';
   unlink(filenamesfx);
-  if (0>link(filename, filenamesfx)) perror_msg("%s", filenamesfx);
+  ret = link(filename, filenamesfx);
+  if (ret < 0) error_msg("can't create backup file");
 
-  // Open new file to copy entries to
-  filenamesfx[strlen(filenamesfx)-1] = '+';
-  if (!(nfp = fopen(filenamesfx, "w+"))) {
-    perror_msg("%s", filenamesfx);
+  *sfx = '+';
+  lock.l_type = F_WRLCK;
+  lock.l_whence = SEEK_SET;
+  lock.l_start = 0;
+  lock.l_len = 0;
+
+  ret = fcntl(fileno(exfp), F_SETLK, &lock);
+  if (ret < 0) perror_msg("Couldn't lock file %s",filename);
+
+  lock.l_type = F_UNLCK; //unlocking at a later stage
+
+  newfp = fopen(filenamesfx, "w+");
+  if (!newfp) {
+    error_msg("couldn't open file for writing");
+    ret = -1;
+    fclose(exfp);
     goto free_storage;
   }
 
-  // Loop through lines
-  while (getline(&line, (void *)&ll, ofp)) {
-    // find matching line
-    start = end = line;
-    if (strncmp(chomp(line), username, len) || line[len]!=':') {
-      found++;
-      if (!entry) continue;
+  ret = 0;
+  namesfx = xmprintf("%s:",username);
+  while ((n = getline(&line, &allocated_length, exfp)) > 0) {
+    line[n-1] = 0;
+    if (strncmp(line, namesfx, strlen(namesfx)))
+      fprintf(newfp, "%s\n", line);
+    else if (entry) {
+      char *current_ptr = NULL;
 
-      // Find start and end of span to replace
-      for (ii = pos;;) {
-        while (*end != ':') {
-          if (!*end) break;
-          end++;
-        }
-        if (ii) {
-          start = ++end;
-          ii--;
-        } else break;
+      found = 1;
+      if (!strcmp(toys.which->name, "passwd")) {
+        fprintf(newfp, "%s%s:",namesfx, entry);
+        current_ptr = get_nextcolon(line, 2); //past passwd
+        if (shadow) {
+          fprintf(newfp, "%u:",(unsigned)(time(NULL))/(24*60*60));
+          current_ptr = get_nextcolon(current_ptr, 1);
+          fprintf(newfp, "%s\n",current_ptr);
+        } else fprintf(newfp, "%s\n",current_ptr);
+      } else if (!strcmp(toys.which->name, "groupadd") ||
+          !strcmp(toys.which->name, "addgroup") ||
+          !strcmp(toys.which->name, "delgroup") ||
+          !strcmp(toys.which->name, "groupdel")){
+        current_ptr = get_nextcolon(line, 3); //past gid/admin list
+        *current_ptr = '\0';
+        fprintf(newfp, "%s", line);
+        fprintf(newfp, "%s\n", entry);
       }
-      if (ii) start = end = line;
     }
-
-    // Write with replacement (if any)
-    fprintf(nfp, "%*s%s%s\n", (int)(start-line), line,
-            (start==line) ? "" : entry, end);
-    memset(line, 0, strlen(line));
   }
   free(line);
-  fflush(nfp);
-  fsync(fileno(nfp));
-  fclose(nfp);  // automatically unlocks
+  free(namesfx);
+  if (!found && entry) fprintf(newfp, "%s\n", entry);
+  fcntl(fileno(exfp), F_SETLK, &lock);
+  fclose(exfp);
 
-  if (!found || rename(filenamesfx, filename)) {
-    if (found) perror_msg("%s -> %s", filenamesfx, filename);
-    else if (entry) fprintf(nfp, "%s\n", entry);
+  errno = 0;
+  fflush(newfp);
+  fsync(fileno(newfp));
+  fclose(newfp);
+  rename(filenamesfx, filename);
+  if (errno) {
+    perror_msg("File Writing/Saving failed: ");
     unlink(filenamesfx);
-  } else ret = 1;
+    ret = -1;
+  }
 
 free_storage:
-  if (ofp) fclose(ofp);
   free(filenamesfx);
-
   return ret;
 }
diff --git a/lib/pending.h b/lib/pending.h
index ccbd102..3c56394 100644
--- a/lib/pending.h
+++ b/lib/pending.h
@@ -2,5 +2,12 @@
 
 // password.c
 #define MAX_SALT_LEN  20 //3 for id, 16 for key, 1 for '\0'
-int read_password(char *buff, int buflen, char *mesg);
-int update_password(char *filename, char *username, char *encrypted, int pos);
+int read_password(char * buff, int buflen, char* mesg);
+int update_password(char *filename, char* username, char* encrypted);
+
+// lib.c
+// This should be switched to posix-2008 getline()
+char *get_line(int fd);
+
+
+// TODO this goes away when lib/password.c cleaned up
diff --git a/lib/portability.c b/lib/portability.c
index 89744dd..6118d0f 100644
--- a/lib/portability.c
+++ b/lib/portability.c
@@ -211,7 +211,7 @@
   if (not->count == not->max) error_exit("xnotify_add overflow");
   EV_SET(&event, fd, EVFILT_VNODE, EV_ADD|EV_CLEAR, NOTE_WRITE, 0, NULL);
   if (kevent(not->kq, &event, 1, NULL, 0, NULL) == -1 || event.flags & EV_ERROR)
-    error_exit("xnotify_add failed on %s", path);
+    return -1;
   not->paths[not->count] = path;
   not->fds[not->count++] = fd;
 
@@ -257,7 +257,7 @@
 
   if (not->max == not->count) error_exit("xnotify_add overflow");
   if ((not->fds[i] = inotify_add_watch(not->kq, path, IN_MODIFY))==-1)
-    perror_exit("xnotify_add failed on %s", path);
+    return -1;
   not->fds[i+1] = fd;
   not->paths[not->count++] = path;
 
@@ -422,7 +422,6 @@
 #define SIGNIFY(x) {SIG##x, #x}
 
 static const struct signame signames[] = {
-  {0, "0"},
   // POSIX
   SIGNIFY(ABRT), SIGNIFY(ALRM), SIGNIFY(BUS),
   SIGNIFY(FPE), SIGNIFY(HUP), SIGNIFY(ILL), SIGNIFY(INT), SIGNIFY(KILL),
@@ -457,6 +456,7 @@
   // Non-POSIX signals that don't cause termination
   SIGNIFY(WINCH),
 };
+int signames_len = ARRAY_LEN(signames);
 
 #undef SIGNIFY
 
@@ -464,7 +464,8 @@
 {
   int i;
 
-  for (i = 1; signames[i].num != SIGCHLD; i++)
+  if (!handler) handler = SIG_DFL;
+  for (i = 0; signames[i].num != SIGCHLD; i++)
     if (signames[i].num != SIGKILL) xsignal(signames[i].num, handler);
 }
 
@@ -475,8 +476,8 @@
   char *s;
 
   // Numeric?
-  offset = estrtol(sigstr, &s, 10);
-  if (!errno && !*s) return offset;
+  i = estrtol(sigstr, &s, 10);
+  if (!errno && !*s) return i;
 
   // Skip leading "SIG".
   strcasestart(&sigstr, "sig");
@@ -510,7 +511,7 @@
   int i;
 
   // A named signal?
-  for (i=0; i<ARRAY_LEN(signames); i++)
+  for (i=0; i<signames_len; i++)
     if (signames[i].num == sig) return signames[i].name;
 
   // A real-time signal?
@@ -623,45 +624,26 @@
 }
 #endif
 
-static ssize_t copy_file_range_wrap(int infd, off_t *inoff, int outfd,
-    off_t *outoff, size_t len, unsigned flags)
-{
-  // glibc added this constant in git at the end of 2017, shipped in 2018-02.
-#if defined(__NR_copy_file_range)
-  return syscall(__NR_copy_file_range, infd, inoff, outfd, outoff, len, flags);
-#else
-  errno = EINVAL;
-  return -1;
-#endif
-}
-
+// TODO copy_file_range
 // Return bytes copied from in to out. If bytes <0 copy all of in to out.
-// If consumed isn't null, amount read saved there (return is written or error)
+// If consuemd isn't null, amount read saved there (return is written or error)
 long long sendfile_len(int in, int out, long long bytes, long long *consumed)
 {
   long long total = 0, len, ww;
-  int copy_file_range = CFG_TOYBOX_COPYFILERANGE;
 
   if (consumed) *consumed = 0;
   if (in<0) return 0;
   while (bytes != total) {
     ww = 0;
     len = bytes-total;
+    if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf);
 
     errno = 0;
-    if (copy_file_range) {
-      if (bytes<0 || bytes>(1<<30)) len = (1<<30);
-      len = copy_file_range_wrap(in, 0, out, 0, len, 0);
-      if (len < 0 && errno == EINVAL) {
-        copy_file_range = 0;
-
-        continue;
-      }
-    }
-    if (!copy_file_range) {
-      if (bytes<0 || len>sizeof(libbuf)) len = sizeof(libbuf);
-      ww = len = read(in, libbuf, len);
-    }
+#if CFG_TOYBOX_COPYFILERANGE
+    len = copy_file_range(in, 0, out, 0, bytes, 0);
+#else
+    ww = len = read(in, libbuf, len);
+#endif
     if (len<1 && errno==EAGAIN) continue;
     if (len<1) break;
     if (consumed) *consumed += len;
@@ -672,50 +654,3 @@
   return total;
 }
 
-#ifdef __APPLE__
-// The absolute minimum POSIX timer implementation to build timeout(1).
-// Note that although timeout(1) uses POSIX timers to get the monotonic clock,
-// that doesn't seem to be an option on macOS (without using other libraries),
-// so we just mangle that back into a regular setitimer(ITIMER_REAL) call.
-int timer_create(clock_t c, struct sigevent *se, timer_t *t)
-{
-  if (se->sigev_notify != SIGEV_SIGNAL || se->sigev_signo != SIGALRM)
-    error_exit("unimplemented");
-  *t = 1;
-  return 0;
-}
-
-int timer_settime(timer_t t, int flags, struct itimerspec *new, void *old)
-{
-  struct itimerval mangled;
-
-  if (flags != 0 || old != 0) error_exit("unimplemented");
-  memset(&mangled, 0, sizeof(mangled));
-  mangled.it_value.tv_sec = new->it_value.tv_sec;
-  mangled.it_value.tv_usec = new->it_value.tv_nsec / 1000;
-  return setitimer(ITIMER_REAL, &mangled, NULL);
-}
-// glibc requires -lrt for linux syscalls, which pulls in libgcc_eh.a for
-// static linking, and gcc 9.3 leaks pthread calls from that breaking the build
-// These are both just linux syscalls: wrap them ourselves
-#elif !CFG_TOYBOX_HASTIMERS
-int timer_create_wrap(clockid_t c, struct sigevent *se, timer_t *t)
-{
-  // convert overengineered structure to what kernel actually uses
-  struct ksigevent { void *sv; int signo, notify, tid; } kk = {
-    0, se->sigev_signo, se->sigev_notify, 0
-  };
-  int timer;
-
-  if (syscall(SYS_timer_create, c, &kk, &timer)<0) return -1;
-  *t = (timer_t)(long)timer;
-
-  return 0;
-}
-
-int timer_settime_wrap(timer_t t, int flags, struct itimerspec *val,
-  struct itimerspec *old)
-{
-  return syscall(SYS_timer_settime, t, flags, val, old);
-}
-#endif
diff --git a/lib/portability.h b/lib/portability.h
index 77b6a2a..bb792f1 100644
--- a/lib/portability.h
+++ b/lib/portability.h
@@ -29,11 +29,6 @@
 // Test for gcc (using compiler builtin #define)
 
 #ifdef __GNUC__
-#ifndef __clang__
-#define QUIET = 0 // shut up false positive "may be used uninitialized" warning
-#else
-#define QUIET
-#endif
 #define printf_format	__attribute__((format(printf, 1, 2)))
 #else
 #define printf_format
@@ -198,13 +193,6 @@
 #endif
 #endif
 
-#ifdef __linux__
-#include <sys/personality.h>
-#else
-#define PER_LINUX32 0
-int personality(int);
-#endif
-
 #if defined(__APPLE__) || defined(__linux__)
 // Linux and macOS has both have getxattr and friends in <sys/xattr.h>, but
 // they aren't compatible.
@@ -311,17 +299,10 @@
   ANDROID_LOG_FATAL,
   ANDROID_LOG_SILENT,
 } android_LogPriority;
-#endif
-#if !defined(__BIONIC__) || defined(__ANDROID_NDK__)
-// Android NDKv18 has liblog.so but not liblog.a for static builds.
-static inline int stub_out_log_write(int pri, const char *tag, const char *msg)
+static inline int __android_log_write(int pri, const char *tag, const char *msg)
 {
   return -1;
 }
-#ifdef __ANDROID_NDK__
-#define __android_log_write(a, b, c) stub_out_log_write(a, b, c)
-#endif
-
 #endif
 
 // libprocessgroup is an Android platform library not included in the NDK.
@@ -338,6 +319,12 @@
 static inline char *get_sched_policy_name(int policy) {return "unknown";}
 #endif
 
+// Android NDKv18 has liblog.so but not liblog.c for static builds,
+// stub it out for now.
+#ifdef __ANDROID_NDK__
+#define __android_log_write(a, b, c) (0)
+#endif
+
 #ifndef SYSLOG_NAMES
 typedef struct {char *c_name; int c_val;} CODE;
 extern CODE prioritynames[], facilitynames[];
@@ -384,22 +371,3 @@
 char *fs_type_name(struct statfs *statfs);
 
 int get_block_device_size(int fd, unsigned long long *size);
-
-#ifdef __APPLE__
-// Apple doesn't have POSIX timers; this is "just enough" for timeout(1).
-typedef int timer_t;
-struct itimerspec {
-  struct timespec it_value;
-};
-int timer_create(clock_t c, struct sigevent *se, timer_t *t);
-int timer_settime(timer_t t, int flags, struct itimerspec *new, void *old);
-#elif !CFG_TOYBOX_HASTIMERS
-#include <syscall.h>
-#include <signal.h>
-#include <time.h>
-int timer_create_wrap(clockid_t c, struct sigevent *se, timer_t *t);
-#define timer_create(...) timer_create_wrap(__VA_ARGS__)
-int timer_settime_wrap(timer_t t, int flags, struct itimerspec *val,
-  struct itimerspec *old);
-#define timer_settime(...) timer_settime_wrap(__VA_ARGS__)
-#endif
diff --git a/lib/toyflags.h b/lib/toyflags.h
index 0c65735..c883087 100644
--- a/lib/toyflags.h
+++ b/lib/toyflags.h
@@ -37,3 +37,9 @@
 
 // Error code to return if argument parsing fails (default 1)
 #define TOYFLAG_ARGFAIL(x) (x<<24)
+
+#if CFG_TOYBOX_PEDANTIC_ARGS
+#define NO_ARGS ">0"
+#else
+#define NO_ARGS 0
+#endif
diff --git a/lib/tty.c b/lib/tty.c
index c09413b..d7e0f47 100644
--- a/lib/tty.c
+++ b/lib/tty.c
@@ -1,11 +1,6 @@
-/* tty.c - cursor control
+/* interestingtimes.c - cursor control
  *
  * Copyright 2015 Rob Landley <rob@landley.net>
- *
- * Common ANSI (See https://man7.org/linux/man-pages/man4/console_codes.4.html)
- * \e[#m   - color change           \e[y;xH - jump to x/y pos (1;1 is top left)
- * \e[K    - delete to EOL          \e[25l  - disable cursor (h to enable)
- * \e[1L   - Insert 1 (blank) line  \e[1M   - Delete 1 line (scrolling rest up)
  */
 
 #include "toys.h"
@@ -19,7 +14,7 @@
   return notstdio(open("/dev/tty", O_RDWR));
 }
 
-// Query size of terminal (without ANSI probe fallback).
+// Quick and dirty query size of terminal, doesn't do ANSI probe fallback.
 // set x=80 y=25 before calling to provide defaults. Returns 0 if couldn't
 // determine size.
 
@@ -29,8 +24,8 @@
   unsigned i, x = 0, y = 0;
   char *s;
 
-  // Check stdin, stdout, stderr
-  for (i = 0; i<3; i++) {
+  // stdin, stdout, stderr
+  for (i=0; i<3; i++) {
     memset(&ws, 0, sizeof(ws));
     if (isatty(i) && !ioctl(i, TIOCGWINSZ, &ws)) {
       if (ws.ws_col) x = ws.ws_col;
@@ -61,7 +56,7 @@
 
   // Send probe: bookmark cursor position, jump to bottom right,
   // query position, return cursor to bookmarked position.
-  xprintf("\e[s\e[999C\e[999B\e[6n\e[u");
+  xprintf("\033[s\033[999C\033[999B\033[6n\033[u");
 
   return 0;
 }
@@ -141,39 +136,39 @@
   int key;
   char *seq;
 } static const scan_key_list[] = {
-  {KEY_UP, "\e[A"}, {KEY_DOWN, "\e[B"},
-  {KEY_RIGHT, "\e[C"}, {KEY_LEFT, "\e[D"},
+  {KEY_UP, "\033[A"}, {KEY_DOWN, "\033[B"},
+  {KEY_RIGHT, "\033[C"}, {KEY_LEFT, "\033[D"},
 
-  {KEY_UP|KEY_SHIFT, "\e[1;2A"}, {KEY_DOWN|KEY_SHIFT, "\e[1;2B"},
-  {KEY_RIGHT|KEY_SHIFT, "\e[1;2C"}, {KEY_LEFT|KEY_SHIFT, "\e[1;2D"},
+  {KEY_UP|KEY_SHIFT, "\033[1;2A"}, {KEY_DOWN|KEY_SHIFT, "\033[1;2B"},
+  {KEY_RIGHT|KEY_SHIFT, "\033[1;2C"}, {KEY_LEFT|KEY_SHIFT, "\033[1;2D"},
 
-  {KEY_UP|KEY_ALT, "\e[1;3A"}, {KEY_DOWN|KEY_ALT, "\e[1;3B"},
-  {KEY_RIGHT|KEY_ALT, "\e[1;3C"}, {KEY_LEFT|KEY_ALT, "\e[1;3D"},
+  {KEY_UP|KEY_ALT, "\033[1;3A"}, {KEY_DOWN|KEY_ALT, "\033[1;3B"},
+  {KEY_RIGHT|KEY_ALT, "\033[1;3C"}, {KEY_LEFT|KEY_ALT, "\033[1;3D"},
 
-  {KEY_UP|KEY_CTRL, "\e[1;5A"}, {KEY_DOWN|KEY_CTRL, "\e[1;5B"},
-  {KEY_RIGHT|KEY_CTRL, "\e[1;5C"}, {KEY_LEFT|KEY_CTRL, "\e[1;5D"},
+  {KEY_UP|KEY_CTRL, "\033[1;5A"}, {KEY_DOWN|KEY_CTRL, "\033[1;5B"},
+  {KEY_RIGHT|KEY_CTRL, "\033[1;5C"}, {KEY_LEFT|KEY_CTRL, "\033[1;5D"},
 
   // VT102/VT220 escapes.
-  {KEY_HOME, "\e[1~"},
-  {KEY_HOME|KEY_CTRL, "\e[1;5~"},
-  {KEY_INSERT, "\e[2~"},
-  {KEY_DELETE, "\e[3~"},
-  {KEY_END, "\e[4~"},
-  {KEY_END|KEY_CTRL, "\e[4;5~"},
-  {KEY_PGUP, "\e[5~"},
-  {KEY_PGDN, "\e[6~"},
+  {KEY_HOME, "\033[1~"},
+  {KEY_HOME|KEY_CTRL, "\033[1;5~"},
+  {KEY_INSERT, "\033[2~"},
+  {KEY_DELETE, "\033[3~"},
+  {KEY_END, "\033[4~"},
+  {KEY_END|KEY_CTRL, "\033[4;5~"},
+  {KEY_PGUP, "\033[5~"},
+  {KEY_PGDN, "\033[6~"},
   // "Normal" "PC" escapes (xterm).
-  {KEY_HOME, "\eOH"},
-  {KEY_END, "\eOF"},
+  {KEY_HOME, "\033OH"},
+  {KEY_END, "\033OF"},
   // "Application" "PC" escapes (gnome-terminal).
-  {KEY_HOME, "\e[H"},
-  {KEY_END, "\e[F"},
-  {KEY_HOME|KEY_CTRL, "\e[1;5H"},
-  {KEY_END|KEY_CTRL, "\e[1;5F"},
+  {KEY_HOME, "\033[H"},
+  {KEY_END, "\033[F"},
+  {KEY_HOME|KEY_CTRL, "\033[1;5H"},
+  {KEY_END|KEY_CTRL, "\033[1;5F"},
 
-  {KEY_FN+1, "\eOP"}, {KEY_FN+2, "\eOQ"}, {KEY_FN+3, "\eOR"},
-  {KEY_FN+4, "\eOS"}, {KEY_FN+5, "\e[15~"}, {KEY_FN+6, "\e[17~"},
-  {KEY_FN+7, "\e[18~"}, {KEY_FN+8, "\e[19~"}, {KEY_FN+9, "\e[20~"},
+  {KEY_FN+1, "\033OP"}, {KEY_FN+2, "\033OQ"}, {KEY_FN+3, "\033OR"},
+  {KEY_FN+4, "\033OS"}, {KEY_FN+5, "\033[15~"}, {KEY_FN+6, "\033[17~"},
+  {KEY_FN+7, "\033[18~"}, {KEY_FN+8, "\033[19~"}, {KEY_FN+9, "\033[20~"},
 };
 
 // Scan stdin for a keypress, parsing known escape sequences, including
@@ -201,7 +196,7 @@
       // Check for return from terminal size probe
       memset(pos, 0, 6*sizeof(int));
       scratch[(1+*scratch)&15] = 0;
-      sscanf(scratch+1, "\e%n[%n%3u%n;%n%3u%nR%n", pos, pos+1, &y,
+      sscanf(scratch+1, "\033%n[%n%3u%n;%n%3u%nR%n", pos, pos+1, &y,
              pos+2, pos+3, &x, pos+4, pos+5);
       if (pos[5]) {
         // Recognized X/Y position, consume and return
@@ -257,10 +252,27 @@
   return scan_key_getsize(scratch, timeout_ms, NULL, NULL);
 }
 
+void tty_esc(char *s)
+{
+  printf("\033[%s", s);
+}
+
+void tty_jump(int x, int y)
+{
+  char s[32];
+
+  sprintf(s, "%d;%dH", y+1, x+1);
+  tty_esc(s);
+}
+
 void tty_reset(void)
 {
   set_terminal(0, 0, 0, 0);
-  xputsn("\e[?25h\e[0m\e[999H\e[K");
+  tty_esc("?25h");
+  tty_esc("0m");
+  tty_jump(0, 999);
+  tty_esc("K");
+  fflush(0);
 }
 
 // If you call set_terminal(), use sigatexit(tty_sigreset);
@@ -284,5 +296,5 @@
     toys.signal = -1;
     terminal_probesize(width, height);
   }
-  xputsn("\e[H\e[J");
+  xprintf("\033[H\033[J");
 }
diff --git a/lib/utf8.c b/lib/utf8.c
deleted file mode 100644
index 1608c2f..0000000
--- a/lib/utf8.c
+++ /dev/null
@@ -1,112 +0,0 @@
-#include "toys.h"
-
-// Show width many columns, negative means from right edge, out=0 just measure
-// if escout, send it unprintable chars, otherwise pass through raw data.
-// Returns width in columns, moves *str to end of data consumed.
-int crunch_str(char **str, int width, FILE *out, char *escmore,
-  int (*escout)(FILE *out, int cols, int wc))
-{
-  int columns = 0, col, bytes;
-  char *start, *end;
-  unsigned wc;
-
-  for (end = start = *str; *end; columns += col, end += bytes) {
-    if ((bytes = utf8towc(&wc, end, 4))>0 && (col = wcwidth(wc))>=0) {
-      if (!escmore || wc>255 || !strchr(escmore, wc)) {
-        if (width-columns<col) break;
-        if (out) fwrite(end, bytes, 1, out);
-
-        continue;
-      }
-    }
-
-    if (bytes<1) {
-      bytes = 1;
-      wc = *end;
-    }
-    col = width-columns;
-    if (col<1) break;
-    if (escout) {
-      if ((col = escout(out, col, wc))<0) break;
-    } else if (out) fwrite(end, 1, bytes, out);
-  }
-  *str = end;
-
-  return columns;
-}
-
-
-// standard escapes: ^X if <32, <XX> if invalid UTF8, U+XXXX if UTF8 !iswprint()
-int crunch_escape(FILE *out, int cols, int wc)
-{
-  char buf[11];
-  int rc;
-
-  if (wc<' ') rc = sprintf(buf, "^%c", '@'+wc);
-  else if (wc<256) rc = sprintf(buf, "<%02X>", wc);
-  else rc = sprintf(buf, "U+%04X", wc);
-
-  if (rc > cols) buf[rc = cols] = 0;
-  if (out) fputs(buf, out);
-
-  return rc;
-}
-
-// Display "standard" escapes in reverse video.
-int crunch_rev_escape(FILE *out, int cols, int wc)
-{
-  int rc;
-
-  xputsn("\e[7m");
-  rc = crunch_escape(out, cols, wc);
-  xputsn("\e[27m");
-
-  return rc;
-}
-
-// Write width chars at start of string to strdout with standard escapes
-// Returns length in columns so caller can pad it out with spaces.
-int draw_str(char *start, int width)
-{
-  return crunch_str(&start, width, stdout, 0, crunch_rev_escape);
-}
-
-// Return utf8 columns
-int utf8len(char *str)
-{
-  return crunch_str(&str, INT_MAX, 0, 0, crunch_rev_escape);
-}
-
-// Return bytes used by (up to) this many columns
-int utf8skip(char *str, int width)
-{
-  char *s = str;
-
-  crunch_str(&s, width, 0, 0, crunch_rev_escape);
-
-  return s-str;
-}
-
-// Print utf8 to stdout with standard escapes, trimmed to width and padded
-// out to padto. If padto<0 left justify. Returns columns printed
-int draw_trim_esc(char *str, int padto, int width, char *escmore,
-  int (*escout)(FILE *out, int cols, int wc))
-{
-  int apad = abs(padto), len = utf8len(str);
-
-  if (padto>=0 && len>width) str += utf8skip(str, len-width);
-  if (len>width) len = width;
-
-  // Left pad if right justified 
-  if (padto>0 && apad>len) printf("%*s", apad-len, "");
-  crunch_str(&str, len, stdout, 0, crunch_rev_escape);
-  if (padto<0 && apad>len) printf("%*s", apad-len, "");
-
-  return (apad > len) ? apad : len;
-}
-
-// draw_trim_esc() with default escape
-int draw_trim(char *str, int padto, int width)
-{
-  return draw_trim_esc(str, padto, width, 0, 0);
-}
diff --git a/lib/xwrap.c b/lib/xwrap.c
index 65e9f4f..64137da 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -1,8 +1,8 @@
-/* xwrap.c - library function wrappers that exit instead of returning error
+/* xwrap.c - wrappers around existing library functions.
  *
- * Functions with the x prefix either succeed or kill the program with an
- * error message, so the caller doesn't have to check for failure. They
- * usually have the same arguments and return value as the function they wrap.
+ * Functions with the x prefix are wrappers that either succeed or kill the
+ * program with an error message, but never return failure. They usually have
+ * the same arguments and return value as the function they wrap.
  *
  * Copyright 2006 Rob Landley <rob@landley.net>
  */
@@ -104,12 +104,7 @@
 // Die unless we can allocate a copy of this string.
 char *xstrdup(char *s)
 {
-  long len = strlen(s);
-  char *c = xmalloc(++len);
-
-  memcpy(c, s, len);
-
-  return c;
+  return xstrndup(s, strlen(s));
 }
 
 void *xmemdup(void *s, long len)
@@ -343,7 +338,7 @@
 {
   int status;
 
-  while (-1 == waitpid(pid, &status, 0) && errno == EINTR) errno = 0;
+  while (-1 == waitpid(pid, &status, 0) && errno == EINTR);
 
   return WIFEXITED(status) ? WEXITSTATUS(status) : WTERMSIG(status)+128;
 }
@@ -553,73 +548,74 @@
 }
 
 // Canonicalize path, even to file with one or more missing components at end.
-// Returns allocated string for pathname or NULL if doesn't exist. Flags are:
-// ABS_PATH:path to last component must exist ABS_FILE: whole path must exist
-// ABS_KEEP:keep symlinks in path ABS_LAST: keep symlink at end of path
-char *xabspath(char *path, int flags)
+// Returns allocated string for pathname or NULL if doesn't exist
+// exact = 1 file must exist, 0 dir must exist, -1 show theoretical location,
+// -2 don't resolve last file
+char *xabspath(char *path, int exact)
 {
-  struct string_list *todo, *done = 0, *new, **tail;
-  int fd, track, len, try = 9999, dirfd = -1, missing = 0;
-  char *str;
+  struct string_list *todo, *done = 0;
+  int try = 9999, dirfd = open("/", O_PATH), missing = 0;
+  char *ret;
 
-  // If the last file must exist, path to it must exist.
-  if (flags&ABS_FILE) flags |= ABS_PATH;
-  // If we don't resolve path's symlinks, don't resolve last symlink.
-  if (flags&ABS_KEEP) flags |= ABS_LAST;
-
-  // If this isn't an absolute path, start with cwd or $PWD.
+  // If this isn't an absolute path, start with cwd.
   if (*path != '/') {
-    if ((flags & ABS_KEEP) && (str = getenv("PWD")))
-      splitpath(path, splitpath(str, &todo));
-    else {
-      splitpath(path, splitpath(str = xgetcwd(), &todo));
-      free(str);
-    }
+    char *temp = xgetcwd();
+
+    splitpath(path, splitpath(temp, &todo));
+    free(temp);
   } else splitpath(path, &todo);
 
   // Iterate through path components in todo, prepend processed ones to done.
   while (todo) {
-    // break out of endless symlink loops
+    struct string_list *new = llist_pop(&todo), **tail;
+    ssize_t len;
+
+    // Eventually break out of endless loops
     if (!try--) {
       errno = ELOOP;
       goto error;
     }
 
-    // Remove . or .. component, tracking dirfd back up tree as necessary
-    str = (new = llist_pop(&todo))->str;
-    // track dirfd if this component must exist or we're resolving symlinks
-    track = ((flags>>!todo) & (ABS_PATH|ABS_KEEP)) ^ ABS_KEEP;
-    if (!done && track) dirfd = open("/", O_PATH);
-    if (*str=='.' && !str[1+((fd = str[1])=='.')]) {
+    // Removable path componenents.
+    if (!strcmp(new->str, ".") || !strcmp(new->str, "..")) {
+      int x = new->str[1];
+
       free(new);
-      if (fd) {
-        if (done) free(llist_pop(&done));
-        if (missing) missing--;
-        else if (track) {
-          if (-1 == (fd = openat(dirfd, "..", O_PATH))) goto error;
-          close(dirfd);
-          dirfd = fd;
-        }
+      if (!x) continue;
+      if (done) free(llist_pop(&done));
+      len = 0;
+
+      if (missing) missing--;
+      else {
+        if (-1 == (x = openat(dirfd, "..", O_PATH))) goto error;
+        close(dirfd);
+        dirfd = x;
       }
       continue;
     }
 
     // Is this a symlink?
-    if (flags & (ABS_KEEP<<!todo)) errno = len = 0;
+    if (exact == -2 && !todo) len = 0;
     else len = readlinkat(dirfd, new->str, libbuf, sizeof(libbuf));
     if (len>4095) goto error;
 
     // Not a symlink: add to linked list, move dirfd, fail if error
     if (len<1) {
+      int fd;
+
       new->next = done;
       done = new;
-      if (errno == ENOENT && !(flags & (ABS_PATH<<!todo))) missing++;
-      else if (errno != EINVAL && (flags & (ABS_PATH<<!todo))) goto error;
-      else if (track) {
-        if (-1 == (fd = openat(dirfd, new->str, O_PATH))) goto error;
-        close(dirfd);
-        dirfd = fd;
+      if (errno == EINVAL && !todo) break;
+      if (errno == ENOENT && exact<0) {
+        missing++;
+        continue;
       }
+      if (errno != EINVAL && (exact || todo)) goto error;
+
+      fd = openat(dirfd, new->str, O_PATH);
+      if (fd == -1 && (exact || todo || errno != ENOENT)) goto error;
+      close(dirfd);
+      dirfd = fd;
       continue;
     }
 
@@ -627,13 +623,13 @@
     libbuf[len] = 0;
     if (*libbuf == '/') {
       llist_traverse(done, free);
-      done = 0;
+      done=0;
       close(dirfd);
-      dirfd = -1;
+      dirfd = open("/", O_PATH);
     }
     free(new);
 
-    // prepend components of new path. Note symlink to "/" will leave new = NULL
+    // prepend components of new path. Note symlink to "/" will leave new NULL
     tail = splitpath(libbuf, &new);
 
     // symlink to "/" will return null and leave tail alone
@@ -642,10 +638,11 @@
       todo = new;
     }
   }
-  xclose(dirfd);
+  close(dirfd);
 
-  // At this point done has the path, in reverse order. Reverse list
-  // (into todo) while calculating buffer length.
+  // At this point done has the path, in reverse order. Reverse list while
+  // calculating buffer length.
+
   try = 2;
   while (done) {
     struct string_list *temp = llist_pop(&done);
@@ -657,18 +654,20 @@
   }
 
   // Assemble return buffer
-  *(str = xmalloc(try)) = '/';
-  str[try = 1] = 0;
+
+  ret = xmalloc(try);
+  *ret = '/';
+  ret [try = 1] = 0;
   while (todo) {
-    if (try>1) str[try++] = '/';
-    try = stpcpy(str+try, todo->str) - str;
+    if (try>1) ret[try++] = '/';
+    try = stpcpy(ret+try, todo->str) - ret;
     free(llist_pop(&todo));
   }
 
-  return str;
+  return ret;
 
 error:
-  xclose(dirfd);
+  close(dirfd);
   llist_traverse(todo, free);
   llist_traverse(done, free);
 
@@ -756,7 +755,7 @@
 
 // This can return null (meaning file not found).  It just won't return null
 // for memory allocation reasons.
-char *xreadlinkat(int dir, char *name)
+char *xreadlink(char *name)
 {
   int len, size = 0;
   char *buf = 0;
@@ -765,7 +764,7 @@
   for(;;) {
     size +=64;
     buf = xrealloc(buf, size);
-    len = readlinkat(dir, name, buf, size);
+    len = readlink(name, buf, size);
 
     if (len<0) {
       free(buf);
@@ -778,12 +777,6 @@
   }
 }
 
-char *xreadlink(char *name)
-{
-  return xreadlinkat(AT_FDCWD, name);
-}
-
-
 char *xreadfile(char *name, char *buf, off_t len)
 {
   if (!(buf = readfile(name, buf, len))) perror_exit("Bad '%s'", name);
@@ -927,10 +920,6 @@
   return (l*1000LL)+ll;
 }
 
-void xparsetimespec(char *arg, struct timespec *ts)
-{
-  ts->tv_sec = xparsetime(arg, 9, &ts->tv_nsec);
-}
 
 
 // Compile a regular expression into a regex_t
@@ -997,7 +986,6 @@
   struct tm tm;
   time_t now = *t;
   int len = 0, i = 0;
-  long long ll;
   // Formats with seconds come first. Posix can't agree on whether 12 digits
   // has year before (touch -t) or year after (date), so support both.
   char *s = str, *p, *oldtz = 0, *formats[] = {"%Y-%m-%d %T", "%Y-%m-%dT%T",
@@ -1009,14 +997,21 @@
   *nano = 0;
 
   // Parse @UNIXTIME[.FRACTION]
-  if (1 == sscanf(s, "@%lld%n", &ll, &len)) {
-    if (*(s+=len)=='.') for (len = 0, s++; len<9; len++) {
-      *nano *= 10;
-      if (isdigit(*s)) *nano += *s++-'0';
+  if (*str == '@') {
+    long long ll;
+
+    // Collect seconds and nanoseconds.
+    // &ll is not just t because we can't guarantee time_t is 64 bit (yet).
+    sscanf(s, "@%lld%n", &ll, &len);
+    if (s[len]=='.') {
+      s += len+1;
+      for (len = 0; len<9; len++) {
+        *nano *= 10;
+        if (isdigit(*s)) *nano += *s++-'0';
+      }
     }
-    // Can't be sure t is 64 bit (yet) for %lld above
     *t = ll;
-    if (!*s) return;
+    if (!s[len]) return;
     xvali_date(0, str);
   }
 
@@ -1044,33 +1039,25 @@
       }
 
       // Handle optional Z or +HH[[:]MM] timezone
-      while (isspace(*p)) p++;
       if (*p && strchr("Z+-", *p)) {
-        unsigned uu[3] = {0}, n = 0, nn = 0;
-        char *tz = 0, sign = *p++;
+        unsigned hh, mm = 0, len;
+        char *tz, sign = *p++;
 
         if (sign == 'Z') tz = "UTC0";
-        else if (0<sscanf(p, " %u%n : %u%n : %u%n", uu,&n,uu+1,&nn,uu+2,&nn)) {
-          if (n>2) {
-            uu[1] += uu[0]%100;
-            uu[0] /= 100;
-          }
-          if (n>nn) nn = n;
-          if (!nn) continue;
-
+        else if (sscanf(p, "%2u%2u%n",  &hh, &mm, &len) == 2
+              || sscanf(p, "%2u%n:%2u%n", &hh, &len, &mm, &len) > 0)
+        {
           // flip sign because POSIX UTC offsets are backwards
-          sprintf(tz = libbuf, "UTC%c%02u:%02u:%02u", "+-"[sign=='+'],
-            uu[0], uu[1], uu[2]);
-          p += nn;
-        }
+          sprintf(tz = libbuf, "UTC%c%02d:%02d", "+-"[sign=='+'], hh, mm);
+          p += len;
+        } else continue;
 
         if (!oldtz) {
           oldtz = getenv("TZ");
           if (oldtz) oldtz = xstrdup(oldtz);
         }
-        if (tz) setenv("TZ", tz, 1);
+        setenv("TZ", tz, 1);
       }
-      while (isspace(*p)) p++;
 
       if (!*p) break;
     }
diff --git a/main.c b/main.c
index 9d9d706..d5abe6e 100644
--- a/main.c
+++ b/main.c
@@ -30,7 +30,7 @@
   if (!CFG_TOYBOX || strchr(name, '/')) return 0;
 
   // Multiplexer name works as prefix, else skip first entry (it's out of order)
-  if (!toys.which && strstart(&name, toy_list->name)) return toy_list;
+  if (!toys.which && strstart(&name, "toybox")) return toy_list;
   bottom = 1;
 
   // Binary search to find this command.
@@ -60,50 +60,6 @@
 #include "generated/newtoys.h"
 0;  // Ends the opts || opts || opts...
 
-// Populate help text array
-
-#undef NEWTOY
-#undef OLDTOY
-#define NEWTOY(name,opt,flags) HELP_##name "\0"
-#if CFG_TOYBOX
-#define OLDTOY(name,oldname,flags) "\xff" #oldname "\0"
-#else
-#define OLDTOY(name, oldname, flags) HELP_##oldname "\0"
-#endif
-
-#include "generated/help.h"
-static char *help_data =
-#include "generated/newtoys.h"
-;
-
-void show_help(FILE *out, int full)
-{
-  int i = toys.which-toy_list;
-  char *s, *ss;
-
-  if (!(full&2))
-    fprintf(out, "Toybox %s"USE_TOYBOX(" multicall binary")"%s\n\n",
-      toybox_version, (CFG_TOYBOX && i) ? " (see toybox --help)"
-      : " (see https://landley.net/toybox)");
-
-  if (CFG_TOYBOX_HELP) {
-    for (;;) {
-      s = help_data;
-      while (i--) s += strlen(s) + 1;
-      // If it's an alias, restart search for real name
-      if (*s != 255) break;
-      i = toy_find(++s)-toy_list;
-    }
-
-    if (full) fprintf(out, "%s\n", s);
-    else {
-      strstart(&s, "usage: ");
-      for (ss = s; *ss && *ss!='\n'; ss++);
-      fprintf(out, "%.*s\n", (int)(ss-s), s);
-    }
-  }
-}
-
 static void unknown(char *name)
 {
   toys.exitval = 127;
@@ -111,26 +67,6 @@
   help_exit("Unknown command %s", name);
 }
 
-// Parse --help and --version for (almost) all commands
-void check_help(char **arg)
-{
-  if (!CFG_TOYBOX_HELP_DASHDASH || !*arg) return;
-  if (!CFG_TOYBOX || toys.which != toy_list)
-    if (toys.which->flags&TOYFLAG_NOHELP) return;
-
-  if (!strcmp(*arg, "--help")) {
-    if (CFG_TOYBOX && toys.which == toy_list && arg[1])
-      if (!(toys.which = toy_find(arg[1]))) unknown(arg[1]);
-    show_help(stdout, 1);
-    xexit();
-  }
-
-  if (!strcmp(*arg, "--version")) {
-    xprintf("toybox %s\n", toybox_version);
-    xexit();
-  }
-}
-
 // Setup toybox global state for this command.
 void toy_singleinit(struct toy_list *which, char *argv[])
 {
@@ -138,9 +74,24 @@
   toys.argv = argv;
   toys.toycount = ARRAY_LEN(toy_list);
 
+  // Parse --help and --version for (almost) all commands
+  if (CFG_TOYBOX_HELP_DASHDASH && !(which->flags & TOYFLAG_NOHELP) && argv[1]) {
+    if (!strcmp(argv[1], "--help")) {
+      if (CFG_TOYBOX && toys.which == toy_list && toys.argv[2])
+        if (!(toys.which = toy_find(toys.argv[2]))) unknown(toys.argv[2]);
+      show_help(stdout, 1);
+      xexit();
+    }
+
+    if (!strcmp(argv[1], "--version")) {
+      xprintf("toybox %s\n", toybox_version);
+      xexit();
+    }
+  }
+
   if (NEED_OPTIONS && which->options) get_optflags();
   else {
-    check_help(toys.optargs = argv+1);
+    toys.optargs = argv+1;
     for (toys.optc = 0; toys.optargs[toys.optc]; toys.optc++);
   }
 
@@ -165,6 +116,7 @@
   void *oldwhich = toys.which;
 
   // Drop permissions for non-suid commands.
+
   if (CFG_TOYBOX_SUID) {
     if (!toys.which) toys.which = toy_list;
 
@@ -179,11 +131,7 @@
     } else if (CFG_TOYBOX_DEBUG && uid && which != toy_list)
       error_msg("Not installed suid root");
 
-    if ((which->flags & TOYFLAG_NEEDROOT) && euid) {
-      toys.which = which;
-      check_help(argv+1);
-      help_exit("Not root");
-    }
+    if ((which->flags & TOYFLAG_NEEDROOT) && euid) help_exit("Not root");
   }
 
   // Free old toys contents (to be reentrant), but leave rebound if any
@@ -237,13 +185,12 @@
 
   // fast path: try to exec immediately.
   // (Leave toys.which null to disable suid return logic.)
-  // Try dereferencing symlinks until we hit a recognized name
+  // Try dereferencing one layer of symlink
   while (s) {
-    char *ss = basename(s);
-    struct toy_list *tl = toy_find(ss);
+    struct toy_list *tl = toy_find(basename(s));
 
-    if (tl==toy_list && s!=toys.argv[1]) unknown(ss);
-    toy_exec_which(tl, toys.argv+1);
+    if (tl==toy_list && s!=toys.argv[1]) unknown(basename(s));
+    toy_exec_which(toy_find(basename(s)), toys.argv+1);
     s = (0<readlink(s, libbuf, sizeof(libbuf))) ? libbuf : 0;
   }
 
diff --git a/post_update.sh b/regenerate.sh
similarity index 87%
rename from post_update.sh
rename to regenerate.sh
index 05c550c..689a482 100755
--- a/post_update.sh
+++ b/regenerate.sh
@@ -1,10 +1,5 @@
 #!/bin/bash
 
-# $1 Path to the new version.
-# $2 Path to the old version.
-
-cd $1
-
 set -e
 
 rm -rf .config generated/ android/
diff --git a/scripts/change.sh b/scripts/change.sh
index 74889aa..99dcfde 100755
--- a/scripts/change.sh
+++ b/scripts/change.sh
@@ -2,10 +2,8 @@
 
 # build each command as a standalone executable
 
-source scripts/portability.sh
-
 NOBUILD=1 scripts/make.sh > /dev/null &&
-${HOSTCC:-cc} -I . scripts/install.c -o "$UNSTRIPPED"/instlist &&
+${HOSTCC:-cc} -I . scripts/install.c -o generated/instlist &&
 export PREFIX=${PREFIX:-change/} &&
 mkdir -p "$PREFIX" || exit 1
 
@@ -14,7 +12,7 @@
 # sh - shell builtins like "cd" and "exit" need the multiplexer
 # help - needs to know what other commands are enabled (use command --help)
 
-for i in $("$UNSTRIPPED"/instlist | egrep -vw "sh|help")
+for i in $(generated/instlist | egrep -vw "sh|help")
 do
   echo -n " $i" &&
   scripts/single.sh $i > /dev/null 2>$PREFIX/${i}.bad &&
diff --git a/scripts/findglobals.sh b/scripts/findglobals.sh
index 2bb94d6..2c63164 100755
--- a/scripts/findglobals.sh
+++ b/scripts/findglobals.sh
@@ -3,4 +3,4 @@
 # Quick and dirty check to see if anybody's leaked global variables.
 # We should have this, toy_list, toybuf, and toys.
 
-nm --size-sort generated/unstripped/toybox | grep '[0-9A-Fa-f]* [BCDGRS]' #| cut -d ' ' -f 3
+nm toybox_unstripped | grep '[0-9A-Fa-f]* [BCDGRS]' | cut -d ' ' -f 3
diff --git a/scripts/genconfig.sh b/scripts/genconfig.sh
index 034aa37..955c82c 100755
--- a/scripts/genconfig.sh
+++ b/scripts/genconfig.sh
@@ -3,20 +3,20 @@
 # This has to be a separate file from scripts/make.sh so it can be called
 # before menuconfig.  (It's called again from scripts/make.sh just to be sure.)
 
-source scripts/portability.sh
+mkdir -p generated
 
-mkdir -p "$GENDIR"
+source scripts/portability.sh
 
 probecc()
 {
-  ${CROSS_COMPILE}${CC} $CFLAGS $LDFLAGS -xc -o /dev/null - "$@"
+  ${CROSS_COMPILE}${CC} $CFLAGS -xc -o /dev/null $1 -
 }
 
 # Probe for a single config symbol with a "compiles or not" test.
 # Symbol name is first argument, flags second, feed C file to stdin
 probesymbol()
 {
-  probecc "${@:2}" 2>/dev/null && DEFAULT=y || DEFAULT=n
+  probecc $2 2>/dev/null && DEFAULT=y || DEFAULT=n
   rm a.out 2>/dev/null
   echo -e "config $1\n\tbool" || exit 1
   echo -e "\tdefault $DEFAULT\n" || exit 1
@@ -24,6 +24,13 @@
 
 probeconfig()
 {
+  > generated/cflags
+  # llvm produces its own really stupid warnings about things that aren't wrong,
+  # and although you can turn the warning off, gcc reacts badly to command line
+  # arguments it doesn't understand. So probe.
+  [ -z "$(probecc -Wno-string-plus-int <<< \#warn warn 2>&1 | grep string-plus-int)" ] &&
+    echo -Wno-string-plus-int >> generated/cflags
+
   # Probe for container support on target
   probesymbol TOYBOX_CONTAINER << EOF
     #include <stdio.h>
@@ -101,17 +108,10 @@
     int main(void) { char buf[100]; getrandom(buf, 100, 0); }
 EOF
 
-  # glibc requires #define GNU to get the wrapper for this Linux system call,
-  # so just use syscall().
   probesymbol TOYBOX_COPYFILERANGE << EOF
     #include <sys/syscall.h>
     #include <unistd.h>
-    int main(void) { syscall(__NR_copy_file_range, 0, 0, 1, 0, 123, 0); }
-EOF
-  probesymbol TOYBOX_HASTIMERS << EOF
-    #include <signal.h>
-    #include <time.h>
-    int main(void) {void *x=0;timer_create(CLOCK_MONOTONIC,x,x);}
+    int main(void) { copyfilerange(0, 0, 1, 0, 123, 0); }
 EOF
 }
 
@@ -140,8 +140,8 @@
   done
 }
 
-probeconfig > "$GENDIR"/Config.probed || rm "$GENDIR"/Config.probed
-genconfig > "$GENDIR"/Config.in || rm "$GENDIR"/Config.in
+probeconfig > generated/Config.probed || rm generated/Config.probed
+genconfig > generated/Config.in || rm generated/Config.in
 
 # Find names of commands that can be built standalone in these C files
 toys()
diff --git a/scripts/help.txt b/scripts/help.txt
index d369e47..5bf0d61 100644
--- a/scripts/help.txt
+++ b/scripts/help.txt
@@ -7,8 +7,8 @@
   bloatcheck      - Report size differences between old and current versions
   test_COMMAND    - Run tests for COMMAND (test_ps, test_cat, etc.)
   tests           - Run test suite against all compiled commands.
-                    export TEST_HOST=1 to test host command, VERBOSE=all
-                    to show all failures.
+                    export TEST_HOST=1 to test host command, VERBOSE=1
+                    to show diff, VERBOSE=fail to stop after first failure.
   clean           - Delete temporary files.
   distclean       - Delete everything that isn't shipped.
   install_airlock - Install toybox and host toolchain into $PREFIX directory
diff --git a/scripts/install.sh b/scripts/install.sh
index 842ff9b..648a241 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -2,9 +2,9 @@
 
 # Grab default values for $CFLAGS and such.
 
-source scripts/portability.sh
+source ./configure
 
-[ -z "$PREFIX" ] && PREFIX="$PWD/install"
+[ -z "$PREFIX" ] && PREFIX="/usr/toybox"
 
 # Parse command line arguments.
 
@@ -32,8 +32,8 @@
 echo "Compile instlist..."
 
 NOBUILD=1 scripts/make.sh
-$DEBUG $HOSTCC -I . scripts/install.c -o "$UNSTRIPPED"/instlist || exit 1
-COMMANDS="$("$UNSTRIPPED"/instlist $LONG_PATH)"
+$DEBUG $HOSTCC -I . scripts/install.c -o generated/instlist || exit 1
+COMMANDS="$(generated/instlist $LONG_PATH)"
 
 echo "${UNINSTALL:-Install} commands..."
 
@@ -106,10 +106,9 @@
 # The following are commands toybox should provide, but doesn't yet.
 # For now symlink the host version. This list must go away by 1.0.
 
-PENDING="dd diff expr git tr vi wget bash sh xzcat bc ar gzip   ftpd less awk unxz bison flex make nm"
+PENDING="dd diff expr ftpd less tr vi wget awk sh sha512sum sha256sum unxz xzcat bc bison flex make nm ar gzip"
 
-# "gcc" can go away if the kernel guys merge my patch:
-# http://lkml.iu.edu/hypermail/linux/kernel/2202.0/01505.html
+# "gcc" should go away for llvm, but some things still hardwire it
 TOOLCHAIN="as cc ld gcc objdump"
 
 # Tools needed to build packages
diff --git a/scripts/make.sh b/scripts/make.sh
index b7bb693..5b2d5d8 100755
--- a/scripts/make.sh
+++ b/scripts/make.sh
@@ -2,11 +2,30 @@
 
 # Grab default values for $CFLAGS and such.
 
+if [ ! -z "$ASAN" ]; then
+  echo "Enabling ASan..."
+  # Turn ASan on. Everything except -fsanitize=address is optional, but
+  # but effectively required for useful backtraces.
+  asan_flags="-fsanitize=address \
+    -O1 -g -fno-omit-frame-pointer -fno-optimize-sibling-calls"
+  CFLAGS="$asan_flags $CFLAGS"
+  HOSTCC="$HOSTCC $asan_flags"
+  # Ignore leaks on exit.
+  export ASAN_OPTIONS="detect_leaks=0"
+fi
+
+export LANG=c
+export LC_ALL=C
 set -o pipefail
 source scripts/portability.sh
 
-# Default to running one more parallel cc instance than we have processors
-: ${CPUS:=$(($(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null)+1))}
+[ -z "$KCONFIG_CONFIG" ] && KCONFIG_CONFIG=.config
+[ -z "$OUTNAME" ] && OUTNAME=toybox"${TARGET:+-$TARGET}"
+UNSTRIPPED="generated/unstripped/$(basename "$OUTNAME")"
+
+# Try to keep one more cc invocation going than we have processors
+[ -z "$CPUS" ] && \
+  CPUS=$(($(nproc 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null)+1))
 
 # Respond to V= by echoing command lines as well as running them
 DOTPROG=
@@ -26,9 +45,9 @@
 
 echo "Generate headers from toys/*/*.c..."
 
-mkdir -p "$UNSTRIPPED"
+mkdir -p generated/unstripped
 
-if isnewer "$GENDIR"/Config.in toys || isnewer "$GENDIR"/Config.in Config.in
+if isnewer generated/Config.in toys || isnewer generated/Config.in Config.in
 then
   echo "Extract configuration information from toys/*.c files..."
   scripts/genconfig.sh
@@ -39,15 +58,14 @@
 # first element of the array). The rest must be sorted in alphabetical order
 # for fast binary search.
 
-if isnewer "$GENDIR"/newtoys.h toys
+if isnewer generated/newtoys.h toys
 then
-  echo -n "$GENDIR/newtoys.h "
+  echo -n "generated/newtoys.h "
 
-  echo "USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT|TOYFLAG_NOHELP))" \
-    > "$GENDIR"/newtoys.h
+  echo "USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT))" > generated/newtoys.h
   $SED -n -e 's/^USE_[A-Z0-9_]*(/&/p' toys/*/*.c \
 	| $SED 's/\(.*TOY(\)\([^,]*\),\(.*\)/\2 \1\2,\3/' | sort -s -k 1,1 \
-	| $SED 's/[^ ]* //'  >> "$GENDIR"/newtoys.h
+	| $SED 's/[^ ]* //'  >> generated/newtoys.h
   [ $? -ne 0 ] && exit 1
 fi
 
@@ -56,11 +74,14 @@
 # Extract a list of toys/*/*.c files to compile from the data in $KCONFIG_CONFIG
 # (First command names, then filenames with relevant {NEW,OLD}TOY() macro.)
 
-[ -d ".git" ] && [ ! -z "$(which git 2>/dev/null)" ] &&
-   GITHASH="-DTOYBOX_VERSION=\"$(git describe --tags --abbrev=12 2>/dev/null)\""
+[ -d ".git" ] && GITHASH="$(git describe --tags --abbrev=12 2>/dev/null)"
+[ ! -z "$GITHASH" ] && GITHASH="-DTOYBOX_VERSION=\"$GITHASH\""
 TOYFILES="$($SED -n 's/^CONFIG_\([^=]*\)=.*/\1/p' "$KCONFIG_CONFIG" | xargs | tr ' [A-Z]' '|[a-z]')"
-TOYFILES="main.c $(egrep -l "TOY[(]($TOYFILES)[ ,]" toys/*/*.c | xargs)"
+TOYFILES="$(egrep -l "TOY[(]($TOYFILES)[ ,]" toys/*/*.c)"
+CFLAGS="$CFLAGS $(cat generated/cflags)"
 BUILD="$(echo ${CROSS_COMPILE}${CC} $CFLAGS -I . $OPTIMIZE $GITHASH)"
+LIBFILES="$(ls lib/*.c | grep -v lib/help.c)"
+TOYFILES="lib/help.c main.c $TOYFILES"
 
 if [ "${TOYFILES/pending//}" != "$TOYFILES" ]
 then
@@ -71,38 +92,51 @@
 {
   # Write a canned build line for use on crippled build machines.
 
-  LLINK="$(echo $LDOPTIMIZE $LDFLAGS $(cat "$GENDIR"/optlibs.dat))"
-  echo -e "#!/bin/sh\n\nPATH='$PATH'\nBUILD='$BUILD'\nLINK='$LLINK'\n"
-  echo -e "\$BUILD lib/*.c $TOYFILES \$LINK -o $OUTNAME"
+  echo "#!/bin/sh"
+  echo
+  echo "PATH='$PATH'"
+  echo
+  echo "BUILD='$BUILD'"
+  echo
+  echo "LINK='$LINK'"
+  echo
+  echo "FILES='$LIBFILES $TOYFILES'"
+  echo
+  echo
+  echo '$BUILD $FILES $LINK'
 }
 
-if ! cmp -s <(genbuildsh 2>/dev/null | head -n 5) \
-            <(head -n 5 "$GENDIR"/build.sh 2>/dev/null | $SED '5s/ -o .*//')
+if ! cmp -s <(genbuildsh 2>/dev/null | head -n 6 ; echo LINK="'"$LDOPTIMIZE $LDFLAGS) \
+          <(head -n 7 generated/build.sh 2>/dev/null | $SED '7s/ -o .*//')
 then
   echo -n "Library probe"
 
-  # --as-needed removes libraries we don't use any symbols out of, but the
-  # compiler has no way to ignore a library that doesn't exist, so detect
-  # and skip nonexistent libraries for it.
+  # We trust --as-needed to remove each library if we don't use any symbols
+  # out of it, this loop is because the compiler has no way to ignore a library
+  # that doesn't exist, so we have to detect and skip nonexistent libraries
+  # for it.
 
-  > "$GENDIR"/optlibs.dat
-  for i in util crypt m resolv selinux smack attr crypto z log iconv tls ssl
+  > generated/optlibs.dat
+  for i in util crypt m resolv selinux smack attr crypto z log iconv
   do
     echo "int main(int argc, char *argv[]) {return 0;}" | \
-    ${CROSS_COMPILE}${CC} $CFLAGS $LDFLAGS -xc - -o "$GENDIR"/libprobe -l$i > /dev/null 2>/dev/null &&
-    echo -l$i >> "$GENDIR"/optlibs.dat
+    ${CROSS_COMPILE}${CC} $CFLAGS $LDFLAGS -xc - -o generated/libprobe $LDASNEEDED -l$i > /dev/null 2>/dev/null &&
+    echo -l$i >> generated/optlibs.dat
     echo -n .
   done
-  rm -f "$GENDIR"/libprobe
+  rm -f generated/libprobe
   echo
 fi
 
-genbuildsh > "$GENDIR"/build.sh && chmod +x "$GENDIR"/build.sh || exit 1
+# LINK needs optlibs.dat, above
+
+LINK="$(echo $LDOPTIMIZE $LDFLAGS -o "$UNSTRIPPED" $LDASNEEDED $(cat generated/optlibs.dat))"
+genbuildsh > generated/build.sh && chmod +x generated/build.sh || exit 1
 
 #TODO: "make $SED && make" doesn't regenerate config.h because diff .config
-if true #isnewer "$GENDIR"/config.h "$KCONFIG_CONFIG"
+if true #isnewer generated/config.h "$KCONFIG_CONFIG"
 then
-  echo "Make $GENDIR/config.h from $KCONFIG_CONFIG."
+  echo "Make generated/config.h from $KCONFIG_CONFIG."
 
   # This long and roundabout sed invocation is to make old versions of sed
   # happy. New ones have '\n' so can replace one line with two without all
@@ -127,12 +161,12 @@
     -e 's/.*/#define CFG_& 1/p' \
     -e 'g' \
     -e 's/.*/#define USE_&(...) __VA_ARGS__/p' \
-    $KCONFIG_CONFIG > "$GENDIR"/config.h || exit 1
+    $KCONFIG_CONFIG > generated/config.h || exit 1
 fi
 
-if [ ! -f "$GENDIR"/mkflags ] || [ "$GENDIR"/mkflags -ot scripts/mkflags.c ]
+if [ ! -f generated/mkflags ] || [ generated/mkflags -ot scripts/mkflags.c ]
 then
-  do_loudly $HOSTCC scripts/mkflags.c -o "$UNSTRIPPED"/mkflags || exit 1
+  do_loudly $HOSTCC scripts/mkflags.c -o generated/mkflags || exit 1
 fi
 
 # Process config.h and newtoys.h to generate FLAG_x macros. Note we must
@@ -140,10 +174,8 @@
 # allow multiple NEWTOY() in the same C file. (When disabled the FLAG is 0,
 # so flags&0 becomes a constant 0 allowing dead code elimination.)
 
-if isnewer "$GENDIR"/flags.h toys "$KCONFIG_CONFIG"
-then
-  echo -n "$GENDIR/flags.h "
-
+make_flagsh()
+{
   # Parse files through C preprocessor twice, once to get flags for current
   # .config and once to get flags for allyesconfig
   for I in A B
@@ -155,12 +187,12 @@
     echo '#define OLDTOY(...)'
     if [ "$I" == A ]
     then
-      cat "$GENDIR"/config.h
+      cat generated/config.h
     else
-      $SED '/USE_.*([^)]*)$/s/$/ __VA_ARGS__/' "$GENDIR"/config.h
+      $SED '/USE_.*([^)]*)$/s/$/ __VA_ARGS__/' generated/config.h
     fi
     echo '#include "lib/toyflags.h"'
-    cat "$GENDIR"/newtoys.h
+    cat generated/newtoys.h
 
     # Run result through preprocessor, glue together " " gaps leftover from USE
     # macros, delete comment lines, print any line with a quoted optstring,
@@ -178,7 +210,13 @@
 
   done | sort -s | $SED -n -e 's/ A / /;t pair;h;s/\([^ ]*\).*/\1 " "/;x' \
     -e 'b single;:pair;h;n;:single;s/[^ ]* B //;H;g;s/\n/ /;p' | \
-    tee "$GENDIR"/flags.raw | "$UNSTRIPPED"/mkflags > "$GENDIR"/flags.h || exit 1
+    tee generated/flags.raw | generated/mkflags > generated/flags.h || exit 1
+}
+
+if isnewer generated/flags.h toys "$KCONFIG_CONFIG"
+then
+  echo -n "generated/flags.h "
+  make_flagsh
 fi
 
 # Extract global structure definitions and flag definitions from toys/*/*.c
@@ -187,18 +225,18 @@
 {
   for i in toys/*/*.c
   do
-    # alas basename -s isn't in posix yet.
     NAME="$(echo $i | $SED 's@.*/\(.*\)\.c@\1@')"
     DATA="$($SED -n -e '/^GLOBALS(/,/^)/b got;b;:got' \
-            -e 's/^GLOBALS(/_data {/' \
+            -e 's/^GLOBALS(/struct '"$NAME"'_data {/' \
             -e 's/^)/};/' -e 'p' $i)"
-    [ ! -z "$DATA" ] && echo -e "// $i\n\nstruct $NAME$DATA\n"
+
+    [ ! -z "$DATA" ] && echo -e "// $i\n\n$DATA\n"
   done
 }
 
-if isnewer "$GENDIR"/globals.h toys
+if isnewer generated/globals.h toys
 then
-  echo -n "$GENDIR/globals.h "
+  echo -n "generated/globals.h "
   GLOBSTRUCT="$(getglobals)"
   (
     echo "$GLOBSTRUCT"
@@ -207,30 +245,30 @@
     echo "$GLOBSTRUCT" | \
       $SED -n 's/struct \(.*\)_data {/	struct \1_data \1;/p'
     echo "} this;"
-  ) > "$GENDIR"/globals.h
+  ) > generated/globals.h
 fi
 
-if [ ! -f "$UNSTRIPPED"/mktags ] || [ "$UNSTRIPPED"/mktags -ot scripts/mktags.c ]
+if [ ! -f generated/mktags ] || [ generated/mktags -ot scripts/mktags.c ]
 then
-  do_loudly $HOSTCC scripts/mktags.c -o "$UNSTRIPPED"/mktags || exit 1
+  do_loudly $HOSTCC scripts/mktags.c -o generated/mktags || exit 1
 fi
 
-if isnewer "$GENDIR"/tags.h toys
+if isnewer generated/tags.h toys
 then
-  echo -n "$GENDIR/tags.h "
+  echo -n "generated/tags.h "
 
   $SED -n '/TAGGED_ARRAY(/,/^)/{s/.*TAGGED_ARRAY[(]\([^,]*\),/\1/;p}' \
-    toys/*/*.c lib/*.c | "$UNSTRIPPED"/mktags > "$GENDIR"/tags.h
+    toys/*/*.c lib/*.c | generated/mktags > generated/tags.h
 fi
 
-if [ ! -f "$UNSTRIPPED"/config2help ] || [ "$UNSTRIPPED"/config2help -ot scripts/config2help.c ]
+if [ ! -f generated/config2help ] || [ generated/config2help -ot scripts/config2help.c ]
 then
-  do_loudly $HOSTCC scripts/config2help.c -o "$UNSTRIPPED"/config2help || exit 1
+  do_loudly $HOSTCC scripts/config2help.c -o generated/config2help || exit 1
 fi
-if isnewer "$GENDIR"/help.h "$GENDIR"/Config.in
+if isnewer generated/help.h generated/Config.in
 then
-  echo "$GENDIR/help.h"
-  "$UNSTRIPPED"/config2help Config.in $KCONFIG_CONFIG > "$GENDIR"/help.h || exit 1
+  echo "generated/help.h"
+  generated/config2help Config.in $KCONFIG_CONFIG > generated/help.h || exit 1
 fi
 
 [ ! -z "$NOBUILD" ] && exit 0
@@ -239,62 +277,77 @@
 [ ! -z "$V" ] && echo
 DOTPROG=.
 
-# This is a parallel version of: do_loudly $BUILD $FILES $LLINK || exit 1
+# This is a parallel version of: do_loudly $BUILD $FILES $LINK || exit 1
 
 # Any headers newer than the oldest generated/obj file?
-X="$(ls -1t "$GENDIR"/obj/* 2>/dev/null | tail -n 1)"
+X="$(ls -1t generated/obj/* 2>/dev/null | tail -n 1)"
 # TODO: redo this
 if [ ! -e "$X" ] || [ ! -z "$(find toys -name "*.h" -newer "$X")" ]
 then
-  rm -rf "$GENDIR"/obj && mkdir -p "$GENDIR"/obj || exit 1
+  rm -rf generated/obj && mkdir -p generated/obj || exit 1
 else
-  rm -f "$GENDIR"/obj/main.o || exit 1
+  rm -f generated/obj/{main,lib_help}.o || exit 1
 fi
 
 # build each generated/obj/*.o file in parallel
 
-unset PENDING LNKFILES CLICK
+PENDING=
+LNKFILES=
 DONE=0
 COUNT=0
+CLICK=
 
-for i in lib/*.c click $TOYFILES
+for i in $LIBFILES click $TOYFILES
 do
   [ "$i" == click ] && CLICK=1 && continue
 
   X=${i/lib\//lib_}
   X=${X##*/}
-  OUT="$GENDIR/obj/${X%%.c}.o"
+  OUT="generated/obj/${X%%.c}.o"
   LNKFILES="$LNKFILES $OUT"
 
-  # Library files don't need to be rebuilt if older than .config.
+  # $LIBFILES doesn't need to be rebuilt if older than .config, $TOYFILES does
   # ($TOYFILES contents can depend on CONFIG symbols, lib/*.c never should.)
 
   [ "$OUT" -nt "$i" ] && [ -z "$CLICK" -o "$OUT" -nt "$KCONFIG_CONFIG" ] &&
     continue
 
   do_loudly $BUILD -c $i -o $OUT &
+  PENDING="$PENDING $!"
+  COUNT=$(($COUNT+1))
 
   # ratelimit to $CPUS many parallel jobs, detecting errors
-  [ $((++COUNT)) -ge $CPUS ] && { wait $DASHN; DONE=$?; : $((--COUNT)); }
+
+  for j in $PENDING
+  do
+    [ "$COUNT" -lt "$CPUS" ] && break;
+
+    wait $j
+    DONE=$(($DONE+$?))
+    COUNT=$(($COUNT-1))
+    PENDING="${PENDING## $j}"
+  done
   [ $DONE -ne 0 ] && break
 done
+
 # wait for all background jobs, detecting errors
 
-while [ $((COUNT--)) -gt 0 ]
+for i in $PENDING
 do
-  wait $DASHN;
-  DONE=$((DONE+$?))
+  wait $i
+  DONE=$(($DONE+$?))
 done
+
 [ $DONE -ne 0 ] && exit 1
 
-UNSTRIPPED="$UNSTRIPPED/${OUTNAME/*\//}"
-do_loudly $BUILD $LNKFILES $LLINK -o "$UNSTRIPPED" || exit 1
+do_loudly $BUILD $LNKFILES $LINK || exit 1
 if [ ! -z "$NOSTRIP" ] ||
   ! do_loudly ${CROSS_COMPILE}${STRIP} "$UNSTRIPPED" -o "$OUTNAME"
 then
   [ -z "$NOSTRIP" ] && echo "strip failed, using unstripped"
   rm -f "$OUTNAME" &&
-  cp "$UNSTRIPPED" "$OUTNAME" || exit 1
+  cp "$UNSTRIPPED" "$OUTNAME" ||
+    exit 1
 fi
 
 # gcc 4.4's strip command is buggy, and doesn't set the executable bit on
diff --git a/scripts/mkflags.c b/scripts/mkflags.c
index 6560db5..7ea8770 100644
--- a/scripts/mkflags.c
+++ b/scripts/mkflags.c
@@ -166,7 +166,7 @@
 
   printf("#undef FORCED_FLAG\n#undef FORCED_FLAGLL\n"
     "#ifdef FORCE_FLAGS\n#define FORCED_FLAG 1\n#define FORCED_FLAGLL 1ULL\n"
-    "#else\n#define FORCED_FLAG 0\n#define FORCED_FLAGLL 0LL\n#endif\n\n");
+    "#else\n#define FORCED_FLAG 0\n#define FORCED_FLAGLL 0\n#endif\n\n");
 
   for (;;) {
     struct flag *flist, *aflist, *offlist;
@@ -218,8 +218,8 @@
     }
     printf("#endif\n\n");
 
-    sprintf(out, "#ifdef FOR_%s\n#define CLEANUP_%s\n#ifndef TT\n#define TT this.%s\n#endif\n",
-            command, command, command);
+    sprintf(out, "#ifdef FOR_%s\n#ifndef TT\n#define TT this.%s\n#endif\n",
+            command, command);
     out += strlen(out);
 
     while (aflist) {
diff --git a/scripts/mkroot.sh b/scripts/mkroot.sh
index c099bec..0953f41 100755
--- a/scripts/mkroot.sh
+++ b/scripts/mkroot.sh
@@ -1,98 +1,72 @@
 #!/bin/bash
 
-# ------------------------------ Part 1: Setup -------------------------------
-
 # Clear environment variables by restarting script w/bare minimum passed through
 [ -z "$NOCLEAR" ] && exec env -i NOCLEAR=1 HOME="$HOME" PATH="$PATH" \
-    LINUX="$LINUX" CROSS="$CROSS" CROSS_COMPILE="$CROSS_COMPILE" "$0" "$@"
+    "LINUX=$LINUX" "CROSS=$CROSS" CROSS_COMPILE="$CROSS_COMPILE" "$0" "$@"
 
-# assign command line NAME=VALUE args to env vars, the rest are packages
-for i in "$@"; do
-  [ "${i/=/}" != "$i" ] && export "$i" || { [ "$i" != -- ] && PKG="$PKG $i"; }
+# assign command line NAME=VALUE args to env vars, keeping rest as packages
+while [ $# -ne 0 ]; do
+  [ "${1/=/}" != "$1" ] && eval "export ${1/=*/}=\"\${1#*=}\"" ||
+    { [ "$1" != '--' ] && PKG="${PKG:-plumbing} $1"; }
+  shift
 done
 
-# Set default directory locations (overrideable from command line)
-: ${LOG:=${BUILD:=${TOP:=$PWD/root}/build}/log} ${AIRLOCK:=$BUILD/airlock}
-: ${CCC:=$PWD/ccc} ${PKGDIR:=$PWD/scripts/root}
-
-# useful functions
-announce() { echo -e "\033]2;$CROSS $*\007\n=== $*"; }
 die() { echo "$@" >&2; exit 1; }
+announce() { echo -e "\033]2;$CROSS $*\007\n=== $*"; }
 
-# ----- Are we cross compiling (via CROSS_COMPILE= or CROSS=)
+# Create target-independent working directories (cmdline can change locations)
+TOP="$PWD/root"
+mkdir -p ${BUILD:=$TOP/build} ${AIRLOCK:=$TOP/airlock} ${LOG:=$TOP/log} ||exit 1
 
-if [ -n "$CROSS_COMPILE" ]; then
-  CROSS_COMPILE="$(realpath -s "$CROSS_COMPILE")" # airlock needs absolute path
-  [ -z "$CROSS" ] && CROSS=${CROSS_COMPILE/*\//} CROSS=${CROSS/-*/}
-
-elif [ -n "$CROSS" ]; then # CROSS=all/allnonstop/$ARCH else list known $ARCHes
-  [ ! -d "$CCC" ] && die "No ccc symlink to compiler directory."
-  TARGETS="$(ls "$CCC" | sed -n 's/-.*//p' | sort -u)"
-
-  if [ "${CROSS::3}" == all ]; then # loop calling ourselves for each target
-    for i in $TARGETS; do
-      "$0" "$@" CROSS=$i || [ "$CROSS" == allnonstop ] || exit 1
-    done; exit
-
-  else # Find matching cross compiler under ccc/ else list available targets
-    CROSS_COMPILE="$(echo "$CCC/$CROSS"-*cross/bin/"$CROSS"*-cc)" # wildcard
-    [ ! -e "$CROSS_COMPILE" ] && echo $TARGETS && exit # list available targets
-    CROSS_COMPILE="${CROSS_COMPILE%cc}" # trim to prefix for cc/ld/as/nm/strip
+# set CROSS_COMPILE from $CROSS using ccc. Handle "all" w/log, list, and err chk
+if [ ! -z "$CROSS" ]; then
+  [ ! -d "${CCC:=$PWD/ccc}" ] && die "No ccc symlink to compiler directory."
+  CROSS_COMPILE="$(echo "$CCC/$CROSS"-*cross/bin/"$CROSS"*-cc | sed 's/cc$//')"
+  if [ "${CROSS::3}" == all ]; then
+    for i in $(ls "$CCC" | sed -n 's/-.*//p' | sort -u | xargs); do
+      { rm -f "$LOG/$i-log".{failed,success}
+        "$0" "$@" CROSS=$i ; [ $? -eq 0 ] && mv "$LOG/$i".{txt,success}
+      } |& tee "$LOG/$i.txt"
+      [ ! -e "$LOG/$i.success" ] &&
+        { mv "$LOG/$i".{txt,failed};[ "$CROSS" != allnonstop ] && exit 1; }
+    done
+    exit
+  elif [ ! -e "${CROSS_COMPILE}cc" ]; then
+    ls "$CCC" | sed -n 's/-.*//p' | sort -u | xargs
+    exit
   fi
 fi
 
-# Verify selected compiler works
 ${CROSS_COMPILE}cc --static -xc - -o /dev/null <<< "int main(void){return 0;}"||
   die "${CROSS_COMPILE}cc can't create static binaries"
 
-# When not cross compiling set CROSS=host. Create per-target output directory
-: ${CROSS:=host} ${OUTPUT:=$TOP/$CROSS}
+# Parse and sanity check $CROSS_COMPILE (if any)
+if [ ! -z "$CROSS_COMPILE" ]; then
+  CROSS_PATH="$(dirname "$(which "${CROSS_COMPILE}cc")")"
+  [ -z "$CROSS_PATH" ] && die "no ${CROSS_COMPILE}cc in path"
+  : ${CROSS_BASE:=$(basename "$CROSS_COMPILE")} ${CROSS:=${CROSS_BASE/-*/}}
+fi
+echo "Building for ${CROSS:=host}"
 
-# ----- Create hermetic build environment
+# Create target-specific work/output directories
+: ${OUTPUT:=$TOP/$CROSS} ${PKGDIR:=$PWD/scripts/root}
+MYBUILD="$BUILD/${CROSS_BASE:-host-}tmp"
+rm -rf "$MYBUILD" && mkdir -p "$MYBUILD" || exit 1
+[ -z "$ROOT" ] && ROOT="$OUTPUT/fs" && rm -rf "$ROOT" # only blank if NOT set
 
-if [ -z "$NOAIRLOCK"] && [ -n "$CROSS_COMPILE" ]; then
-  # When cross compiling set host $PATH to binaries with known behavior by
-  # - building a host toybox later builds use as their command line
-  # - cherry-picking specific commands from old path via symlink
+# When cross compiling build everything under a host toybox with known behavior
+if [ ! -z "$CROSS_COMPILE" ]; then
   if [ ! -e "$AIRLOCK/toybox" ]; then
-    announce "airlock" &&
-    PREFIX="$AIRLOCK" KCONFIG_CONFIG=.singleconfig_airlock CROSS_COMPILE= \
-      make clean defconfig toybox install_airlock && # see scripts/install.sh
-    rm .singleconfig_airlock || exit 1
+    announce "airlock"
+    PREFIX="$AIRLOCK" KCONFIG_CONFIG="$TOP"/.airlock CROSS_COMPILE= \
+      make clean defconfig toybox install_airlock && rm "$TOP"/.airlock ||exit 1
   fi
-  export PATH="$AIRLOCK"
+  export PATH="$CROSS_PATH:$AIRLOCK"
 fi
 
-# Create per-target work directories
-MYBUILD="$BUILD/${CROSS}-tmp" && rm -rf "$MYBUILD" &&
-mkdir -p "$MYBUILD" "$OUTPUT" "$LOG" || exit 1
-[ -z "$ROOT" ] && ROOT="$OUTPUT/fs" && rm -rf "$ROOT"
-
-# ----- log build output
-
-# Install command line recording wrapper, logs all commands run from $PATH
-if [ -z "$NOLOGPATH" ]; then
-  # Move cross compiler into $PATH so calls to it get logged
-  [ -n "$CROSS_COMPILE" ] && PATH="${CROSS_COMPILE%/*}:$PATH" &&
-    CROSS_COMPILE=${CROSS_COMPILE##*/}
-  export WRAPDIR="$BUILD/record-commands" LOGPATH="$LOG/$CROSS-commands.txt"
-  rm -rf "$WRAPDIR" "$LOGPATH" generated/obj &&
-  WRAPDIR="$WRAPDIR" CROSS_COMPILE= NOSTRIP=1 source scripts/record-commands ||
-    exit 1
-fi
-
-# Start logging stdout/stderr
-rm -f "$LOG/$CROSS".{n,y} || exit 1
-[ -z "$NOLOG" ] && exec > >(tee "$LOG/$CROSS.n") 2>&1
-echo "Building for $CROSS"
-
-# ---------------------- Part 2: Create root filesystem -----------------------
-
-# ----- Create new root filesystem's directory layout.
-
-# FHS wants boot media opt srv usr/{local,share}, stuff under /var...
-mkdir -p "$ROOT"/{dev,etc/rc,home,mnt,proc,root,sys,tmp/run,usr/{bin,sbin,lib},var} &&
-chmod a+rwxt "$ROOT"/tmp && ln -s usr/{bin,sbin,lib} tmp/run "$ROOT" || exit 1
+# Create new root filesystem's directory layout
+mkdir -p "$ROOT"/{etc,tmp,proc,sys,dev,home,mnt,root,usr/{bin,sbin,lib},var} &&
+chmod a+rwxt "$ROOT"/tmp && ln -s usr/{bin,sbin,lib} "$ROOT" || exit 1
 
 # Write init script. Runs as pid 1 from initramfs to set up and hand off system.
 cat > "$ROOT"/init << 'EOF' &&
@@ -101,17 +75,16 @@
 export HOME=/home PATH=/bin:/sbin
 
 if ! mountpoint -q dev; then
-  mount -t devtmpfs dev dev
-  [ $$ -eq 1 ] && exec 0<>/dev/console 1>&0 2>&1
+  mount -t devtmpfs dev dev || mdev -s
+  [ $$ -eq 1 ] && exec >/dev/console 2>&1
   for i in ,fd /0,stdin /1,stdout /2,stderr
   do ln -sf /proc/self/fd${i/,*/} dev/${i/*,/}; done
-  mkdir dev/shm
+  mkdir -p dev/{shm,pts}
+  mountpoint -q dev/pts || mount -t devpts dev/pts dev/pts
   chmod +t /dev/shm
 fi
-mountpoint -q dev/pts || { mkdir dev/pts && mount -t devpts dev/pts dev/pts; }
 mountpoint -q proc || mount -t proc proc proc
 mountpoint -q sys || mount -t sysfs sys sys
-echo 0 99999 > /proc/sys/net/ipv4/ping_group_range
 
 if [ $$ -eq 1 ]; then # Setup networking for QEMU (needs /proc)
   ifconfig lo 127.0.0.1
@@ -121,10 +94,10 @@
   [ "$(date +%s)" -lt 10000000 ] && sntp -sq time.google.com
 
   # Run package scripts (if any)
-  for i in $(ls -1 /etc/rc 2>/dev/null | sort); do . /etc/rc/"$i"; done
+  [ -e /etc/rc ] && for i in $(echo /etc/rc/* | sort); do . $i; done
 
   [ -z "$CONSOLE" ] && CONSOLE="$(</sys/class/tty/console/active)"
-  [ -z "$HANDOFF" ] && HANDOFF=/bin/sh && echo -e '\e[?7hType exit when done.'
+  [ -z "$HANDOFF" ] && HANDOFF=/bin/sh && echo Type exit when done.
   echo 3 > /proc/sys/kernel/printk
   exec oneit -c /dev/"${CONSOLE:-console}" $HANDOFF
 else # for chroot
@@ -145,28 +118,23 @@
 
 # Build static toybox with existing .config if there is one, else defconfig+sh
 announce toybox
-[ ! -z "$PENDING" ] && rm -f .config
-[ -e .config ] && CONF=silentoldconfig || unset CONF
-for i in $PENDING sh route wget; do XX="$XX"$'\n'CONFIG_${i^^?}=y; done
-LDFLAGS=--static PREFIX="$ROOT" make clean \
-  ${CONF:-defconfig KCONFIG_ALLCONFIG=<(echo "$XX")} toybox install || exit 1
+[ -e .config ] && [ -z "$PENDING" ] && CONF=silentoldconfig || unset CONF
+for i in $PENDING sh route; do XX="$XX"$'\n'CONFIG_${i^^?}=y; done
+make clean ${CONF:-defconfig KCONFIG_ALLCONFIG=<(echo "$XX")} &&
+LDFLAGS=--static PREFIX="$ROOT" make toybox install || exit 1
 
 # Build any packages listed on command line
-for i in ${PKG:+plumbing $PKG}; do
-  announce "$i"; PATH="$PKGDIR:$PATH" source $i || die $i
+for i in $PKG; do
+  announce "$i"; PATH="$PKGDIR:$PATH" source $i; [ $? -ne 0 ] && die $i
 done
 
-# ------------------ Part 3: Build + package bootable system ------------------
-
-# ----- Build kernel for target
-
 if [ -z "$LINUX" ] || [ ! -d "$LINUX/kernel" ]; then
   echo 'No $LINUX directory, kernel build skipped.'
 else
   # Which architecture are we building a kernel for?
   LINUX="$(realpath "$LINUX")"
-  [ -z "$TARGET" ] &&
-    { [ "$CROSS" == host ] && TARGET="$(uname -m)" || TARGET="$CROSS"; }
+  [ -z "$TARGET" ] && TARGET="${CROSS_BASE/-*/}"
+  [ -z "$TARGET" ] && TARGET="$(uname -m)"
 
   # Target-specific info in an (alphabetical order) if/else staircase
   # Each target needs board config, serial console, RTC, ethernet, block device.
@@ -187,10 +155,7 @@
       QEMU="arm -M virt" KARCH=arm VMLINUX=arch/arm/boot/zImage
     fi
     KARGS=ttyAMA0
-    KCONF=MMU,ARCH_MULTI_V7,ARCH_VIRT,SOC_DRA7XX,ARCH_OMAP2PLUS_TYPICAL,ARCH_ALPINE,ARM_THUMB,VDSO,CPU_IDLE,ARM_CPUIDLE,KERNEL_MODE_NEON,SERIAL_AMBA_PL011,SERIAL_AMBA_PL011_CONSOLE,RTC_CLASS,RTC_HCTOSYS,RTC_DRV_PL031,NET_CORE,VIRTIO_MENU,VIRTIO_NET,PCI,PCI_HOST_GENERIC,VIRTIO_BLK,VIRTIO_PCI,VIRTIO_MMIO,ATA,ATA_SFF,ATA_BMDMA,ATA_PIIX,PATA_PLATFORM,PATA_OF_PLATFORM,ATA_GENERIC,CONFIG_ARM_LPAE
-  elif [ "$TARGET" == hexagon ]; then
-    QEMU="hexagon -M comet" KARGS=ttyS0 VMLINUX=vmlinux
-    KARCH="hexagon LLVM_IAS=1" KCONF=SPI,SPI_BITBANG,IOMMU_SUPPORT
+    KCONF=MMU,ARCH_MULTI_V7,ARCH_VIRT,SOC_DRA7XX,ARCH_OMAP2PLUS_TYPICAL,ARCH_ALPINE,ARM_THUMB,VDSO,CPU_IDLE,ARM_CPUIDLE,KERNEL_MODE_NEON,SERIAL_AMBA_PL011,SERIAL_AMBA_PL011_CONSOLE,RTC_CLASS,RTC_HCTOSYS,RTC_DRV_PL031,NET_CORE,VIRTIO_MENU,VIRTIO_NET,PCI,PCI_HOST_GENERIC,VIRTIO_BLK,VIRTIO_PCI,VIRTIO_MMIO,ATA,ATA_SFF,ATA_BMDMA,ATA_PIIX,PATA_PLATFORM,PATA_OF_PLATFORM,ATA_GENERIC
   elif [ "$TARGET" == i486 ] || [ "$TARGET" == i686 ] ||
        [ "$TARGET" == x86_64 ] || [ "$TARGET" == x32 ]; then
     if [ "$TARGET" == i486 ]; then
@@ -205,7 +170,7 @@
     KCONF=$KCONF,UNWINDER_FRAME_POINTER,PCI,BLK_DEV_SD,ATA,ATA_SFF,ATA_BMDMA,ATA_PIIX,NET_VENDOR_INTEL,E1000,SERIAL_8250,SERIAL_8250_CONSOLE,RTC_CLASS
   elif [ "$TARGET" == m68k ]; then
     QEMU="m68k -M q800" KARCH=m68k KARGS=ttyS0 VMLINUX=vmlinux
-    KCONF=MMU,M68040,M68KFPU_EMU,MAC,SCSI_MAC_ESP,MACINTOSH_DRIVERS,ADB,ADB_MACII,NET_CORE,NET_VENDOR_NATSEMI,MACSONIC,SERIAL_PMACZILOG,SERIAL_PMACZILOG_TTYS,SERIAL_PMACZILOG_CONSOLE
+    KCONF=MMU,M68040,M68KFPU_EMU,MAC,SCSI_MAC_ESP,MACINTOSH_DRIVERS,ADB,ADB_MACII,NET_CORE,MACSONIC,SERIAL_PMACZILOG,SERIAL_PMACZILOG_TTYS,SERIAL_PMACZILOG_CONSOLE
   elif [ "$TARGET" == mips ] || [ "$TARGET" == mipsel ]; then
     QEMU="mips -M malta" KARCH=mips KARGS=ttyS0 VMLINUX=vmlinux
     KCONF=MIPS_MALTA,CPU_MIPS32_R2,SERIAL_8250,SERIAL_8250_CONSOLE,PCI,BLK_DEV_SD,ATA,ATA_SFF,ATA_BMDMA,ATA_PIIX,NET_VENDOR_AMD,PCNET32,POWER_RESET,POWER_RESET_SYSCON
@@ -215,15 +180,15 @@
     KARCH=powerpc QEMU="ppc -M g3beige" KARGS=ttyS0 VMLINUX=vmlinux
     KCONF=ALTIVEC,PPC_PMAC,PPC_OF_BOOT_TRAMPOLINE,IDE,IDE_GD,IDE_GD_ATA,BLK_DEV_IDE_PMAC,BLK_DEV_IDE_PMAC_ATA100FIRST,MACINTOSH_DRIVERS,ADB,ADB_CUDA,NET_VENDOR_NATSEMI,NET_VENDOR_8390,NE2K_PCI,SERIO,SERIAL_PMACZILOG,SERIAL_PMACZILOG_TTYS,SERIAL_PMACZILOG_CONSOLE,BOOTX_TEXT
   elif [ "$TARGET" == powerpc64le ]; then
-    KARCH=powerpc QEMU="ppc64 -M pseries -vga none" KARGS=hvc0
+    KARCH=powerpc QEMU="ppc64 -M pseries -vga none" KARGS=/dev/hvc0
     VMLINUX=vmlinux
     KCONF=PPC64,PPC_PSERIES,CPU_LITTLE_ENDIAN,PPC_OF_BOOT_TRAMPOLINE,BLK_DEV_SD,SCSI_LOWLEVEL,SCSI_IBMVSCSI,ATA,NET_VENDOR_IBM,IBMVETH,HVC_CONSOLE,PPC_TRANSACTIONAL_MEM,PPC_DISABLE_WERROR,SECTION_MISMATCH_WARN_ONLY
   elif [ "$TARGET" = s390x ]; then
     QEMU="s390x" KARCH=s390 VMLINUX=arch/s390/boot/bzImage
     KCONF=MARCH_Z900,PACK_STACK,NET_CORE,VIRTIO_NET,VIRTIO_BLK,SCLP_TTY,SCLP_CONSOLE,SCLP_VT220_TTY,SCLP_VT220_CONSOLE,S390_GUEST
   elif [ "$TARGET" == sh2eb ]; then
-    BUILTIN=1 KARCH=sh VMLINUX=vmlinux
-    KERNEL_CONFIG=$'CONFIG_MEMORY_START=0x10000000\nCONFIG_CMDLINE="console=ttyUL0 earlycon"'
+    KARCH=sh VMLINUX=vmlinux KERNEL_CONFIG='CONFIG_MEMORY_START=0x10000000
+CONFIG_CMDLINE="console=ttyUL0 earlycon"' BUILTIN=1
     KCONF=CPU_SUBTYPE_J2,CPU_BIG_ENDIAN,SH_JCORE_SOC,SMP,BINFMT_ELF_FDPIC,JCORE_EMAC,SERIAL_UARTLITE,SERIAL_UARTLITE_CONSOLE,HZ_100,CMDLINE_OVERWRITE,SPI,SPI_JCORE,MMC,PWRSEQ_SIMPLE,MMC_BLOCK,MMC_SPI
   elif [ "$TARGET" == sh4 ]; then
     QEMU="sh4 -M r2d -serial null -serial mon:stdio" KARCH=sh
@@ -235,21 +200,19 @@
   fi
 
   # Write the qemu launch script
-  if [ -n "$QEMU" ]; then
-    [ -z "$BUILTIN" ] && INITRD="-initrd ${CROSS}root.cpio.gz"
-    { echo qemu-system-"$QEMU" '"$@"' $QEMU_MORE -nographic -no-reboot -m 256 \
-        -kernel $(basename $VMLINUX) $INITRD ${DTB:+-dtb "$(basename "$DTB")"} \
-        "-append \"panic=1 HOST=$TARGET console=$KARGS \$KARGS\"" &&
-      echo "echo -e '\\e[?7h'"
-    } > "$OUTPUT/qemu-$TARGET.sh" &&
+  if [ ! -z "$QEMU" ]; then
+    [ -z "$BUILTIN" ] && INITRD="-initrd ${CROSS_BASE}root.cpio.gz"
+    echo qemu-system-"$QEMU" '"$@"' $QEMU_MORE -nographic -no-reboot -m 256 \
+         -kernel $(basename $VMLINUX) $INITRD \
+         "-append \"panic=1 HOST=$TARGET console=$KARGS \$KARGS\"" \
+         ${DTB:+-dtb "$(basename "$DTB")"} ";echo -e '\e[?7h'" \
+         > "$OUTPUT/qemu-$TARGET.sh" &&
     chmod +x "$OUTPUT/qemu-$TARGET.sh" || exit 1
   fi
 
   announce "linux-$KARCH"
   pushd "$LINUX" && make distclean && popd &&
   cp -sfR "$LINUX" "$MYBUILD/linux" && pushd "$MYBUILD/linux" &&
-  sed -is '/select HAVE_STACK_VALIDATION/d' arch/x86/Kconfig && # Fix x86-64
-  sed -is 's/depends on !SMP/& || !MMU/' mm/Kconfig &&          # Fix sh2eb
 
   # Write miniconfig
   { echo "# make ARCH=$KARCH allnoconfig KCONFIG_ALLCONFIG=$TARGET.miniconf"
@@ -257,12 +220,12 @@
     echo "# CONFIG_EMBEDDED is not set"
 
     # Expand list of =y symbols, first generic then architecture-specific
-    for i in BINFMT_ELF,BINFMT_SCRIPT,NO_HZ,HIGH_RES_TIMERS,BLK_DEV,BLK_DEV_INITRD,RD_GZIP,BLK_DEV_LOOP,EXT4_FS,EXT4_USE_FOR_EXT2,VFAT_FS,FAT_DEFAULT_UTF8,MISC_FILESYSTEMS,SQUASHFS,SQUASHFS_XATTR,SQUASHFS_ZLIB,DEVTMPFS,DEVTMPFS_MOUNT,TMPFS,TMPFS_POSIX_ACL,NET,PACKET,UNIX,INET,IPV6,NETDEVICES,NET_CORE,NETCONSOLE,ETHERNET,COMPAT_32BIT_TIME,EARLY_PRINTK,IKCONFIG,IKCONFIG_PROC $KCONF $KEXTRA ; do
+    for i in BINFMT_ELF,BINFMT_SCRIPT,NO_HZ,HIGH_RES_TIMERS,BLK_DEV,BLK_DEV_INITRD,RD_GZIP,BLK_DEV_LOOP,EXT4_FS,EXT4_USE_FOR_EXT2,VFAT_FS,FAT_DEFAULT_UTF8,MISC_FILESYSTEMS,SQUASHFS,SQUASHFS_XATTR,SQUASHFS_ZLIB,DEVTMPFS,DEVTMPFS_MOUNT,TMPFS,TMPFS_POSIX_ACL,NET,PACKET,UNIX,INET,IPV6,NETDEVICES,NET_CORE,NETCONSOLE,ETHERNET,COMPAT_32BIT_TIME,EARLY_PRINTK,IKCONFIG,IKCONFIG_PROC $KCONF ; do
       echo "# architecture ${X:-independent}"
       sed -E '/^$/d;s/([^,]*)($|,)/CONFIG_\1=y\n/g' <<< "$i"
       X=specific
     done
-    [ -n "$BUILTIN" ] && echo -e CONFIG_INITRAMFS_SOURCE="\"$OUTPUT/fs\""
+    [ ! -z "$BUILTIN" ] && echo -e CONFIG_INITRAMFS_SOURCE="\"$OUTPUT/fs\""
     echo "$KERNEL_CONFIG"
   } > "$OUTPUT/miniconfig-$TARGET" &&
   make ARCH=$KARCH allnoconfig KCONFIG_ALLCONFIG="$OUTPUT/miniconfig-$TARGET" &&
@@ -277,16 +240,12 @@
   # Build kernel. Copy config, device tree binary, and kernel binary to output
   make ARCH=$KARCH CROSS_COMPILE="$CROSS_COMPILE" -j $(nproc) &&
   cp .config "$OUTPUT/linux-fullconfig" || exit 1
-  [ -n "$DTB" ] && { cp "$DTB" "$OUTPUT" || exit 1 ;}
+  [ ! -z "$DTB" ] && { cp "$DTB" "$OUTPUT" || exit 1 ;}
   cp "$VMLINUX" "$OUTPUT" && cd .. && rm -rf linux && popd || exit 1
 fi
 
 # clean up and package root filesystem for initramfs.
-if [ -z "$BUILTIN" ]; then
-  announce "${CROSS}root.cpio.gz"
-  (cd "$ROOT" && find . | cpio -o -H newc ${CROSS_COMPILE:+--no-preserve-owner}\
-    | gzip) > "$OUTPUT/$CROSS"root.cpio.gz || exit 1
-fi
-
-mv "$LOG/$CROSS".{n,y}
-rmdir "$MYBUILD" "$BUILD" 2>/dev/null || exit 0 # remove if empty, not an error
+[ -z "$BUILTIN" ] && announce "${CROSS_BASE}root.cpio.gz" &&
+  (cd "$ROOT" && find . | cpio -o -H newc ${CROSS_COMPILE:+--no-preserve-owner} | gzip) \
+    > "$OUTPUT/$CROSS_BASE"root.cpio.gz
+rmdir "$MYBUILD" "$BUILD" 2>/dev/null # remove if empty
diff --git a/scripts/mkstatus.py b/scripts/mkstatus.py
index ed6dd54..c1b325e 100755
--- a/scripts/mkstatus.py
+++ b/scripts/mkstatus.py
@@ -21,15 +21,15 @@
 
 print "Collecting data..."
 
-stuff,blah=readit(["sed","-n", 's/<span id=\\([a-z_]*\\)>/\\1 /;t good;d;:good;h;:loop;n;s@</span>@@;t out;H;b loop;:out;g;s/\\n/ /g;p', "www/roadmap.html"])
+stuff,blah=readit(["sed","-n", 's/<span id=\\([a-z_]*\\)>/\\1 /;t good;d;:good;h;:loop;n;s@</span>@@;t out;H;b loop;:out;g;s/\\n/ /g;p', "www/roadmap.html", "www/status.html"])
 blah,toystuff=readit(["./toybox"])
-blah,stuff["shell"]=readit(["sed", "-n", "s/.*NEWTOY[(]\\([^,]*\\).*TOYFLAG_NOFORK.*/\\1/p", "toys/pending/sh.c"])
-blah,pending=readit(["/bin/bash", "-c", "sed -n 's/[^ \\t].*TOY(\\([^,]*\\),.*/\\1/p' toys/pending/*.c"])
-version=readit(["./toybox","--version"])[-1][-1]
+blah,pending=readit(["sed -n 's/[^ \\t].*TOY(\\([^,]*\\),.*/\\1/p' toys/pending/*.c"], 1)
+blah,version=readit(["git","describe","--tags"])
 
 print "Analyzing..."
 
 # Create reverse mappings: reverse["command"] gives list of categories it's in
+
 reverse={}
 for i in stuff:
   for j in stuff[i]:
@@ -50,13 +50,13 @@
 
 conv = [("posix", '<a href="http://pubs.opengroup.org/onlinepubs/9699919799/utilities/%s.html">%%s</a>', "[%s]"),
         ("lsb", '<a href="http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/%s.html">%%s</a>', '&lt;%s&gt;'),
-        ("development", '<a href="https://man7.org/linux/man-pages/man1/%s.1.html">%%s</a>', '(%s)'),
+        ("development", '<a href="http://linux.die.net/man/1/%s">%%s</a>', '(%s)'),
         ("toolbox", "", '{%s}'), ("klibc_cmd", "", '=%s='),
         ("sash_cmd", "", '#%s#'), ("sbase_cmd", "", '@%s@'),
-        ("beastiebox_cmd", "", '*%s*'), ("tizen_cmd", "", '$%s$'),
-        ("fhs_cmd", "", '-%s-'), ("yocto_cmd", "", ".%s."),
+        ("beastiebox_cmd", "", '*%s*'), ("tizen", "", '$%s$'),
         ("shell", "", "%%%s%%"),
-        ("request", '<a href="https://man7.org/linux/man-pages/man1/%s.1.html">%%s</a>', '+%s+')]
+        ("request", '<a href="http://linux.die.net/man/1/%s">%%s</a>', '+%s+')]
+
 
 def categorize(reverse, i, skippy=""):
   linky = "%s"
@@ -96,25 +96,22 @@
 
 # Write data to output file
 
-outfile=open("www/status.html", "w")
-outfile.write("""<html><head><title>toybox current status</title>
-<!--#include file="header.html" -->
-<title>Toybox Status</title>
-""");
-outfile.write("<h1>Status of toybox %s</h1>\n" % version);
-outfile.write("<h3>Legend: %s <strike>pending</strike></h3>\n"%" ".join(map(lambda i: i[2]%(i[0].split("_")[0]), conv)))
+outfile=open("www/status.gen", "w")
+outfile.write("<h1>Status of toybox %s</h1>\n" % version[0]);
+outfile.write("<h3>Legend: [posix] &lt;lsb&gt; (development) {android}\n")
+outfile.write("=klibc= #sash# @sbase@ *beastiebox* $tizen$ %shell% +request+ other\n")
+outfile.write("<strike>pending</strike></h3>\n");
 
 outfile.write("<a name=done><h2><a href=#done>Completed</a></h2><blockquote><p>%s</p></blockquote>\n" % "\n".join(done))
-outfile.write("<a name=part><h2><a href=#part>Partially implemented (in toys/pending)</a></h2><blockquote><p>%s</p></blockquote>\n" % "\n".join(pend))
+outfile.write("<a name=part><h2><a href=#part>Partially implemented</a></h2><blockquote><p>%s</p></blockquote>\n" % "\n".join(pend))
 outfile.write("<a name=todo><h2><a href=#todo>Not started yet</a></h2><blockquote><p>%s</p></blockquote>\n" % "\n".join(todo))
 
 # Output unfinished commands by category
 
 outfile.write("<hr><h2>Categories of remaining todo items</h2>")
 
-for i in conv:
+for i in stuff:
   todo = []
-  i=i[0]
 
   for j in stuff[i]:
     if j in toystuff: continue
@@ -125,15 +122,10 @@
     k = i
     for j in conv:
       if j[0] == i:
-        k = j[2] % i.split("_")[0]
+        k = j[2] % i
 
     outfile.write("<a name=%s><h2><a href=#%s>%s<a></h2><blockquote><p>" % (i,i,k))
     outfile.write(" ".join(todo))
     outfile.write("</p></blockquote>\n")
 
 outfile.write("<hr><a name=all><h2><a href=#all>All commands together in one big list</a></h2><blockquote><p>%s</p></blockquote>\n" % "\n".join(allcmd))
-
-outfile.write("""
-<p>See the <a href=roadmap.html>Roadmap page</a> for more information.</p>
-
-<!-- #include "footer.html" -->""")
diff --git a/scripts/portability.sh b/scripts/portability.sh
index 3af2be5..618022c 100644
--- a/scripts/portability.sh
+++ b/scripts/portability.sh
@@ -1,6 +1,6 @@
 # sourced to find alternate names for things
 
-source ./configure
+source configure
 
 if [ -z "$(command -v "${CROSS_COMPILE}${CC}")" ]
 then
@@ -12,31 +12,3 @@
 then
   [ ! -z "$(command -v gsed 2>/dev/null)" ] && SED=gsed || SED=sed
 fi
-
-# Tell linker to do dead code elimination at function level
-if [ "$(uname)" == "Darwin" ]
-then
-  : ${LDOPTIMIZE:=-Wl,-dead_strip} ${STRIP:=strip}
-else
-  : ${LDOPTIMIZE:=-Wl,--gc-sections -Wl,--as-needed} ${STRIP:=strip -s -R .note* -R .comment}
-fi
-
-# Address Sanitizer
-if [ ! -z "$ASAN" ]; then
-  # Turn ASan on and disable most optimization to get more readable backtraces.
-  # (Technically ASAN is just "-fsanitize=address" and the rest is optional.)
-  ASAN_FLAGS="-fsanitize=address -O1 -g -fno-omit-frame-pointer -fno-optimize-sibling-calls"
-  CFLAGS="$CFLAGS $ASAN_FLAGS"
-  HOSTCC="$HOSTCC $ASAN_FLAGS"
-  NOSTRIP=1
-  # Ignore leaks on exit. TODO
-  export ASAN_OPTIONS="detect_leaks=0"
-  unset ASAN
-fi
-
-# Centos 7 bug workaround, EOL June 30 2024. TODO
-DASHN=-n; wait -n 2>/dev/null; [ $? -eq 2 ] && unset DASHN
-
-# If the build is using gnu tools, make them behave less randomly.
-export LANG=c
-export LC_ALL=C
diff --git a/scripts/record-commands b/scripts/record-commands
index d2b779f..8410966 100755
--- a/scripts/record-commands
+++ b/scripts/record-commands
@@ -3,40 +3,38 @@
 # Set up command recording wrapper
 
 [ -z "$WRAPDIR" ] && WRAPDIR="$PWD"/record-commands && RM=$(which rm)
-[ -z "$LOGPATH" ] && export LOGPATH="$PWD"/log.txt
+[ -z "$WRAPLOG" ] && export WRAPLOG="$PWD"/log.txt
 
-if [ ${#BASH_SOURCE[@]} -lt 2 ] && [ $# -eq 0 ]
+if [ $# -eq 0 ]
 then
-  echo "usage: WRAPDIR=dir LOGPATH=log.txt record-commands COMMAND..."
+  echo "usage: WRAPDIR=dir WRAPLOG=log.txt record-commands COMMAND..."
   echo 'Then examine log.txt. "record-commands echo" to just setup $WRAPDIR'
   exit 1
 fi
 
-if [ ! -x "$WRAPDIR/logpath" ]
+if [ ! -x "$WRAPDIR/logwrapper" ]
 then
-  mkdir -p "$WRAPDIR" && PREFIX="$WRAPDIR/" scripts/single.sh logpath || exit 1
+  make logwrapper
+  mkdir -p "$WRAPDIR" && mv logwrapper "$WRAPDIR" || exit 1
+
   echo "$PATH" | tr : '\n' | while read DIR
   do
-    find "$DIR/" -type f,l -maxdepth 1 -executable -exec basename {} \; | \
-    while read FILE
+    ls "$DIR/" | while read FILE
     do
-      ln -s logpath "$WRAPDIR/$FILE" 2>/dev/null
+      ln -s logwrapper "$WRAPDIR/$FILE" 2>/dev/null
     done
   done
 fi
 
 # Delete old log (if any)
-rm -f "$LOGPATH"
+rm -f "$WRAPLOG"
 
-# When sourced, set up wrapper for current context.
-export PATH="$WRAPDIR:$PATH"
-if [ ${#BASH_SOURCE[@]} -lt 2 ]
+X=0
+if [ ! -z "$1" ]
 then
-  "$@"
-  X=$?
-
-  [ ! -z "$RM" ] && "$RM" -rf "$WRAPDIR"
-
-  exit $X
+  PATH="$WRAPDIR:$PATH" "$@"
 fi
+X=$?
+[ ! -z "$RM" ] && "$RM" -rf "$WRAPDIR"
 
+exit $X
diff --git a/scripts/root/dropbear b/scripts/root/dropbear
index 75839c3..a2a49dd 100755
--- a/scripts/root/dropbear
+++ b/scripts/root/dropbear
@@ -4,11 +4,11 @@
 
 echo === download source
 
-download e6d119755acdf9104d7ba236b1242696940ed6dd \
-  http://downloads.sf.net/libpng/zlib-1.2.11.tar.gz
+download a4d316c404ff54ca545ea71a27af7dbc29817088 \
+  http://downloads.sf.net/libpng/zlib-1.2.8.tar.gz
 
-download c3d4fe27fa17ec8217dbedbd33dd73a1ca6cda2c \
-  https://matt.ucc.asn.au/dropbear/releases/dropbear-2020.81.tar.bz2
+download 820ec2b8c869edbcf5ad1138777fc0f54349505c \
+  https://matt.ucc.asn.au/dropbear/releases/dropbear-2019.78.tar.bz2
 
 echo === Native build static zlib
 
@@ -28,7 +28,7 @@
 echo 'echo "$@"' > config.sub &&
 ZLIB="$(echo ../zlib*)" &&
 CFLAGS="-I $ZLIB -O2" LDFLAGS="-L $ZLIB" ./configure --enable-static \
-  --disable-wtmp --host="$(basename "$CROSS_COMPILE" | sed 's/-$//')" &&
+  --disable-wtmp --host=${CROSS_BASE%-} &&
 sed -i 's@/usr/bin/dbclient@ssh@' options.h &&
 sed -i 's@\(#define NON_INETD_MODE\) 1@\1 0@' default_options.h &&
 make -j $(nproc) PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" MULTI=1 SCPPROGRESS=1 &&
diff --git a/scripts/runtest.sh b/scripts/runtest.sh
index 5a64767..158ed7f 100644
--- a/scripts/runtest.sh
+++ b/scripts/runtest.sh
@@ -8,11 +8,9 @@
 
 # The following environment variables enable optional behavior in "testing":
 #    DEBUG - Show every command run by test script.
-#    VERBOSE - "all"    continue after failed test
-#              "fail"   show diff and stop at first failed test
+#    VERBOSE - "all" continue after failed test
+#              "quiet" like all but just print FAIL (no diff -u).
 #              "nopass" don't show successful tests
-#              "quiet"  don't show diff -u for failures
-#              "spam"   show passing test command lines
 #
 # The "testcmd" function takes five arguments:
 #	$1) Description to display when running command
@@ -69,14 +67,9 @@
   SKIP=1
 }
 
-verbose_has()
-{
-  [ "${VERBOSE/$1/}" != "$VERBOSE" ]
-}
-
 skipnot()
 {
-  if verbose_has quiet
+  if [ "$VERBOSE" == quiet ]
   then
     eval "$@" 2>/dev/null
   else
@@ -111,7 +104,7 @@
 # Announce success
 do_pass()
 {
-  ! verbose_has nopass && printf "%s\n" "$SHOWPASS: $NAME"
+  [ "$VERBOSE" != "nopass" ] && printf "%s\n" "$SHOWPASS: $NAME"
 }
 
 # The testing function
@@ -127,7 +120,7 @@
 
   if [ -n "$SKIP" -o -n "$SKIP_HOST" -a -n "$TEST_HOST" -o -n "$SKIPNEXT" ]
   then
-    verbose_has quiet && printf "%s\n" "$SHOWSKIP: $NAME"
+    [ "$VERBOSE" != quiet ] && printf "%s\n" "$SHOWSKIP: $NAME"
     unset SKIPNEXT
     return 0
   fi
@@ -141,21 +134,20 @@
   [ $RETVAL -gt 128 ] && [ $RETVAL -lt 255 ] &&
     echo "exited with signal (or returned $RETVAL)" >> actual
   DIFF="$(diff -au${NOSPACE:+w} expected actual)"
-  if [ -n "$DIFF" ]
+  if [ ! -z "$DIFF" ]
   then
     FAILCOUNT=$(($FAILCOUNT+1))
     printf "%s\n" "$SHOWFAIL: $NAME"
+    if [ "$VERBOSE" != quiet ]
+    then
+      [ ! -z "$4" ] && printf "%s\n" "echo -ne \"$4\" > input"
+      printf "%s\n" "echo -ne '$5' |$EVAL $2"
+      printf "%s\n" "$DIFF"
+      [ "$VERBOSE" != all ] && exit 1
+    fi
   else
-    ! verbose_has nopass && printf "%s\n" "$SHOWPASS: $NAME"
+    [ "$VERBOSE" != "nopass" ] && printf "%s\n" "$SHOWPASS: $NAME"
   fi
-  if ! verbose_has quiet && { [ -n "$DIFF" ] || verbose_has spam; }
-  then
-    [ ! -z "$4" ] && printf "%s\n" "echo -ne \"$4\" > input"
-    printf "%s\n" "echo -ne '$5' |$EVAL $2"
-    [ -n "$DIFF" ] && printf "%s\n" "$DIFF"
-  fi
-
-  [ -n "$DIFF" ] && ! verbose_has all && exit 1
   rm -f input expected actual
 
   [ -n "$DEBUG" ] && set +x
@@ -182,7 +174,7 @@
     echo "Expected '$CASE'"
     echo "Got '$A'"
   fi
-  ! verbose_has all && exit 1
+  [ "$VERBOSE" != all ] && [ "$VERBOSE" != quiet ] && exit 1
 }
 
 # txpect NAME COMMAND [I/O/E/Xstring]...
@@ -191,7 +183,7 @@
 # X means close stdin/stdout/stderr and match return code (blank means nonzero)
 txpect()
 {
-  local NAME CASE VERBOSITY LEN A B X O
+  local NAME CASE VERBOSITY LEN A B
 
   # Run command with redirection through fifos
   NAME="$CMDNAME $1"
@@ -212,9 +204,11 @@
   # Loop through challenge/response pairs, with 2 second timeout
   while [ $# -gt 0 ]
   do
-    VERBOSITY="$VERBOSITY"$'\n'"$1"  LEN=$((${#1}-1))  CASE="$1"  A=  B=
-
-    verbose_has spam && echo "txpect $CASE"
+    VERBOSITY="$VERBOSITY"$'\n'"$1"
+    LEN=$((${#1}-1))
+    CASE="$1"
+    A=
+    B=
     case ${1::1} in
 
       # send input to child
@@ -224,15 +218,14 @@
       # check output from child
       [OE])
         [ $LEN == 0 ] && LARG="" || LARG="-rN $LEN"
-        O=$OUT  A=
+        O=$OUT
         [ "${1:$B:1}" == 'E' ] && O=$ERR
+        A=
         read -t2 $LARG A <&$O
-        X=$?
-        verbose_has spam && echo "txgot $X '$A'"
         VERBOSITY="$VERBOSITY"$'\n'"$A"
         if [ $LEN -eq 0 ]
         then
-          [ -z "$A" -o "$X" -ne 0 ] && { do_fail;break;}
+          [ -z "$A" ] && { do_fail;break;}
         else
           if [ ${1::1} == 'R' ] && [[ "$A" =~ "${1:2}" ]]; then true
           elif [ ${1::1} != 'R' ] && [ "$A" == "${1:1}" ]; then true
@@ -269,7 +262,7 @@
   then
     do_pass
   else
-    ! verbose_has quiet && echo "$VERBOSITY" >&2
+    [ "$VERBOSE" != quiet ] && echo "$VERBOSITY" >&2
   fi
 }
 
diff --git a/scripts/single.sh b/scripts/single.sh
index 023ccea..c40c6bc 100755
--- a/scripts/single.sh
+++ b/scripts/single.sh
@@ -2,24 +2,26 @@
 
 # Build a standalone toybox command
 
-[ -z "$1" ] && { echo "usage: single.sh command..." >&2; exit 1; }
+if [ -z "$1" ]
+then
+  echo "usage: single.sh command..." >&2
+  exit 1
+fi
 
 # Add trailing / to PREFIX when it's set but hasn't got one
 [ "$PREFIX" == "${PREFIX%/}" ] && PREFIX="${PREFIX:+$PREFIX/}"
 
-# Harvest TOYBOX_* symbols from .config, or fresh defconfig if none
-export KCONFIG_CONFIG
-if [ ! -e ${KCONFIG_CONFIG:=.config} ]
+# Harvest TOYBOX_* symbols from .config
+if [ ! -e .config ]
 then
-  KCONFIG_CONFIG=.singleconfig
-  make defconfig
-else
-  # Force dependencies to rebuild headers if we build multiplexer after this.
-  touch "$KCONFIG_CONFIG"
+  echo "Need .config for toybox global settings. Run defconfig/menuconfig." >&2
+  exit 1
 fi
-GLOBDEP="$(sed -n 's/CONFIG_\(TOYBOX_[^=]*\)=y/\1/p' "$KCONFIG_CONFIG")"
-KCONFIG_CONFIG=.singleconfig
 
+# Force dependencies to rebuild headers if we build multiplexer after this.
+touch -c .config
+
+export KCONFIG_CONFIG=.singleconfig
 for i in "$@"
 do
   echo -n "$i:"
@@ -33,7 +35,8 @@
 
   make allnoconfig > /dev/null || exit 1
 
-  unset DEPENDS MPDEL
+  DEPENDS=
+  MPDEL=
   if [ "$i" == sh ]
   then
     DEPENDS="$(sed -n 's/USE_\([^(]*\)(NEWTOY([^,]*,.*TOYFLAG_MAYFORK.*/\1/p' toys/*/*.c)"
@@ -42,11 +45,11 @@
   fi
 
   # Enable stuff this command depends on
-  DEPENDS="$({ echo $DEPENDS $GLOBDEP; sed -n "/^config *$i"'$/,/^$/{s/^[ \t]*depends on //;T;s/[!][A-Z0-9_]*//g;s/ *&& */|/g;p}' $TOYFILE;}| xargs | tr ' ' '|')"
+  DEPENDS="$({ echo $DEPENDS; sed -n "/^config *$i"'$/,/^$/{s/^[ \t]*depends on //;T;s/[!][A-Z0-9_]*//g;s/ *&& */|/g;p}' $TOYFILE; sed -n 's/CONFIG_\(TOYBOX_[^=]*\)=y/\1/p' .config;}| xargs | tr ' ' '|')"
   NAME=$(echo $i | tr a-z- A-Z_)
   sed -ri -e "$MPDEL" \
     -e "s/# (CONFIG_($NAME|${NAME}_.*${DEPENDS:+|$DEPENDS})) is not set/\1=y/" \
-    "$KCONFIG_CONFIG" || exit 1
+    "$KCONFIG_CONFIG" || exit 1 #&& grep "CONFIG_TOYBOX_" .config >> "$KCONFIG_CONFIG" || exit 1
 
   export OUTNAME="$PREFIX$i"
   rm -f "$OUTNAME" &&
diff --git a/scripts/test.sh b/scripts/test.sh
index da22f66..cdfe3bd 100755
--- a/scripts/test.sh
+++ b/scripts/test.sh
@@ -31,23 +31,20 @@
 
 do_test()
 {
-  cd "$TESTDIR" && rm -rf testdir continue && mkdir testdir && cd testdir ||
-    exit 1
+  cd "$TESTDIR" && rm -rf testdir && mkdir testdir && cd testdir || exit 1
   CMDNAME="${1##*/}"
   CMDNAME="${CMDNAME%.test}"
   if [ -z "$TEST_HOST" ]
   then
     C="$TESTDIR/$CMDNAME"
     [ ! -e "$C" ] && echo "$CMDNAME disabled" && return
-    C="$(dirname $(realpath "$C"))/$CMDNAME"
   else
     C="$(which $CMDNAME 2>/dev/null)"
     [ -z "$C" ] && printf '%s\n' "$SHOWSKIP: no $CMDNAME" && return
   fi
+  C="$(dirname $(realpath "$C"))/$CMDNAME"
 
-  (. "$1"; cd "$TESTDIR"; touch continue)
-  cd "$TESTDIR"
-  [ -e continue ] || exit 1
+  . "$1"
 }
 
 if [ $# -ne 0 ]
diff --git a/tests/cmp.test b/tests/cmp.test
index ce776e8..d1a8033 100755
--- a/tests/cmp.test
+++ b/tests/cmp.test
@@ -3,13 +3,13 @@
 [ -f testing.sh ] && . testing.sh
 
 # TODO: coreutils cmp uses stdin if only one file is given
-testcmd "one argument match" 'input && echo yes' "yes\n" \
+testing "one argument match" 'cmp input && echo yes' "yes\n" \
   "one\ntwo\nthree" "one\ntwo\nthree"
 # posix says ""%s %s differ: char %d, line %d\n" but diffutils says "byte"
-testcmd "one argument diff" 'input | sed s/byte/char/' \
+testing "one argument diff" 'cmp input | sed s/byte/char/' \
   "input - differ: char 5, line 2\n" "one\ntwo\nthree" "one\nboing\nthree"
 
-testcmd "missing file1 [fail]" 'file1 input 2>/dev/null || echo $?' "2\n" "foo" ""
+testing "missing file1 [fail]" 'cmp file1 input 2>/dev/null || echo $?' "2\n" "foo" ""
 
 #mkdir dir
 #testing "directory [fail]" "cmp dir dir 2>/dev/null || echo yes" \
@@ -19,27 +19,27 @@
 echo "ab
 c" > input2
 
-testcmd "identical files, stdout" "input input2" "" "ab\nc\n" ""
-testcmd "identical files, return code" "input input2 && echo yes" "yes\n" "ab\nc\n" ""
+testing "identical files, stdout" "cmp input input2" "" "ab\nc\n" ""
+testing "identical files, return code" "cmp input input2 && echo yes" "yes\n" "ab\nc\n" ""
 
-testcmd "EOF, stderr" "input input2 2>&1" "cmp: EOF on input2\n" "ab\nc\nx" ""
-testcmd "EOF, return code" "input input2 2>/dev/null || echo yes" "yes\n" "ab\nc\nx" ""
+testing "EOF, stderr" "cmp input input2 2>&1" "cmp: EOF on input2\n" "ab\nc\nx" ""
+testing "EOF, return code" "cmp input input2 2>/dev/null || echo yes" "yes\n" "ab\nc\nx" ""
 # The gnu/dammit version fails this because posix says "char" and they don't.
-testcmd "diff, stdout" "input input2 | sed s/byte/char/" \
+testing "diff, stdout" "cmp input input2 | sed s/byte/char/" \
   "input input2 differ: char 4, line 2\n" "ab\nx\nx" ""
-testcmd "diff, return code" "input input2 > /dev/null || echo yes" "yes\n" "ab\nx\nx" ""
+testing "diff, return code" "cmp input input2 > /dev/null || echo yes" "yes\n" "ab\nx\nx" ""
 
-testcmd "-s EOF, return code" "-s input input2 2>&1 || echo yes"  "yes\n" "ab\nc\nx" ""
-testcmd "-s diff, return code" "-s input input2 2>&1 || echo yes" "yes\n" "ab\nx\nx" ""
+testing "-s EOF, return code" "cmp -s input input2 2>&1 || echo yes"  "yes\n" "ab\nc\nx" ""
+testing "-s diff, return code" "cmp -s input input2 2>&1 || echo yes" "yes\n" "ab\nx\nx" ""
 
-testcmd "-l EOF, stderr" "-l input input2 2>&1" "cmp: EOF on input2\n" "ab\nc\nx" ""
-testcmd "-l diff and EOF, stdout and stderr" "-l input input2 2>&1 | sort" "4 170 143\ncmp: EOF on input2\n" "ab\nx\nx" ""
+testing "-l EOF, stderr" "cmp -l input input2 2>&1" "cmp: EOF on input2\n" "ab\nc\nx" ""
+testing "-l diff and EOF, stdout and stderr" "cmp -l input input2 2>&1 | sort" "4 170 143\ncmp: EOF on input2\n" "ab\nx\nx" ""
 
-testcmd "-s not exist" "-s input doesnotexist 2>&1 || echo yes" "yes\n" "x" ""
+testing "-s not exist" "cmp -s input doesnotexist 2>&1 || echo yes" "yes\n" "x" ""
 
 rm input2
 
-testcmd "stdin and file" "input - | sed s/byte/char/" \
+testing "stdin and file" "cmp input - | sed s/byte/char/" \
   "input - differ: char 4, line 2\n" "ab\nc\n" "ab\nx\n"
-testcmd "-n skip1 skip2" "-n 3 input - 3 5 && echo yes" "yes\n" "abcdef123" "vwxyzdef987"
+#testing "stdin and stdin" "cmp input -" "" "" "ab\nc\n"
 
diff --git a/tests/comm.test b/tests/comm.test
deleted file mode 100755
index 63d9c84..0000000
--- a/tests/comm.test
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/bin/bash
-
-[ -f testing.sh ] && . testing.sh
-
-#testing "name" "command" "result" "infile" "stdin"
-
-for i in a b c ; do echo $i >> lhs ; done
-for i in c d e ; do echo $i >> rhs ; done
-testing "comm" "comm lhs rhs" "a\nb\n\t\tc\n\td\n\te\n" "" ""
diff --git a/tests/cp.test b/tests/cp.test
index 3e25f6c..b0d5d3a 100755
--- a/tests/cp.test
+++ b/tests/cp.test
@@ -140,14 +140,6 @@
   'two\n' '' ''
 testing '-u2' 'echo two>two; sleep .1; echo one>one; cp -u one two; cat two' \
   'one\n' '' ''
-mkdir a b
-
-echo potato > a/one
-echo potato > a/two
-touch b/one b/two
-testing '-i' 'cp -ri a/. b/. 2>/dev/null; cmp -s a/one b/one || cmp -s a/one b/two && echo yes' \
-  'yes\n' '' 'n\ny\n'
-rm -rf one two a b
 
 # cp -r ../source destdir
 # cp -r one/two/three missing
diff --git a/tests/cut.test b/tests/cut.test
index 889fc18..8d8c4ba 100755
--- a/tests/cut.test
+++ b/tests/cut.test
@@ -13,27 +13,29 @@
 alpha:beta:gamma:delta:epsilon:zeta:eta:theta:iota:kappa:lambda:mu
 the quick brown fox jumps over the lazy dog" >abc.txt
 
-testcmd "-b a,a,a" "-b 3,3,3 abc.txt" "e\np\ne\n" "" ""
-testcmd "-b overlaps" "-b 1-3,2-5,7-9,9-10 abc.txt" \
+testing "-b a,a,a" "cut -b 3,3,3 abc.txt" "e\np\ne\n" "" ""
+testing "-b overlaps" "cut -b 1-3,2-5,7-9,9-10 abc.txt" \
   "one:to:th\nalphabeta\nthe qick \n" "" ""
-testcmd "-b encapsulated" "-b 3-8,4-6 abc.txt" "e:two:\npha:be\ne quic\n" \
+testing "-b encapsulated" "cut -b 3-8,4-6 abc.txt" "e:two:\npha:be\ne quic\n" \
   "" ""
-testcmd "-bO overlaps" "--output-delimiter ' ' -b 1-3,2-5,7-9,9-10 abc.txt" \
+testing "-bO overlaps" \
+  "cut --output-delimiter ' ' -b 1-3,2-5,7-9,9-10 abc.txt" \
   "one:t o:th\nalpha beta\nthe q ick \n" "" ""
-testcmd "high-low error" "-b 8-3 abc.txt 2>/dev/null || echo err" "err\n" \
+testing "high-low error" "cut -b 8-3 abc.txt 2>/dev/null || echo err" "err\n" \
   "" ""
 
-testcmd "-c a-b" "-c 4-10 abc.txt" ":two:th\nha:beta\n quick \n" "" ""
-testcmd "-c a-" "-c 41- abc.txt" "\ntheta:iota:kappa:lambda:mu\ndog\n" "" ""
-testcmd "-c -b" "-c -39 abc.txt" \
+testing "-c a-b" "cut -c 4-10 abc.txt" ":two:th\nha:beta\n quick \n" "" ""
+testing "-c a-" "cut -c 41- abc.txt" "\ntheta:iota:kappa:lambda:mu\ndog\n" "" ""
+testing "-c -b" "cut -c -39 abc.txt" \
   "one:two:three:four:five:six:seven\nalpha:beta:gamma:delta:epsilon:zeta:eta\nthe quick brown fox jumps over the lazy\n" \
   "" ""
-testcmd "-c a" "-c 40 abc.txt" "\n:\n \n" "" ""
-testcmd "-c a,b-c,d" "-c 3,5-7,10 abc.txt" "etwoh\npa:ba\nequi \n" "" ""
-toyonly testcmd "-c japan.txt" '-c 3-6,9-12 "$FILES/utf8/japan.txt"' \
+testing "-c a" "cut -c 40 abc.txt" "\n:\n \n" "" ""
+testing "-c a,b-c,d" "cut -c 3,5-7,10 abc.txt" "etwoh\npa:ba\nequi \n" "" ""
+toyonly testing "-c japan.txt" 'cut -c 3-6,9-12 "$FILES/utf8/japan.txt"' \
   "ガラスをられます\n" "" ""
 
-toyonly testcmd "-C test1.txt" '-C -1 "$FILES/utf8/test1.txt"' "l̴̗̞̠\n" "" ""
+toyonly testing "-C test1.txt" 'cut -C -1 "$FILES/utf8/test1.txt"' \
+  "l̴̗̞̠\n" "" ""
 
 # substitute for awk
 toyonly testcmd "-DF" "-DF 2,7,5" \
@@ -45,26 +47,24 @@
 Apple: you can buy better, but you can't pay more.
 Subcalifragilisticexpialidocious.
 Auntie Em: Hate you, hate Kansas. Took the dog. Dorothy."
-toyonly testcmd "-DF 2" "-DF 7,1,3-6,2-5" \
-  "seven one three four five six two three four five\n" "" \
-  "one two three four five six seven eight nine\n"
 
 testcmd "empty field" "-d ':' -f 1-3" "a::b\n" "" "a::b\n"
 testcmd "empty field 2" "-d ':' -f 3-5" "b::c\n" "" "a::b::c:d\n"
 
-testcmd "-f a-" "-d ':' -f 5- abc.txt" "five:six:seven\nepsilon:zeta:eta:theta:iota:kappa:lambda:mu\nthe quick brown fox jumps over the lazy dog\n" "" ""
+testing "-f a-" "cut -d ':' -f 5- abc.txt" "five:six:seven\nepsilon:zeta:eta:theta:iota:kappa:lambda:mu\nthe quick brown fox jumps over the lazy dog\n" "" ""
 
-testcmd "show whole line with no delim" "-d ' ' -f 3 abc.txt" \
+testing "show whole line with no delim" "cut -d ' ' -f 3 abc.txt" \
 	"one:two:three:four:five:six:seven\nalpha:beta:gamma:delta:epsilon:zeta:eta:theta:iota:kappa:lambda:mu\nbrown\n" "" ""
 
-testcmd "-c (a-b)" "-c 1-15 " "ref_categorie=t\n" "" "ref_categorie=test\n"
-testcmd "-c (a)" "-c 14" "=\n" "" "ref_categorie=test\n"
+testing "with echo, -c (a-b)" "echo 'ref_categorie=test' | cut -c 1-15 " "ref_categorie=t\n" "" ""
+testing "with echo, -c (a)" "echo 'ref_categorie=test' | cut -c 14" "=\n" "" ""
 
 # Modifying abc.txt data as per new testcase
 echo "abcdefghijklmnopqrstuvwxyz" >abc.txt
 
-testcmd "-c (a,b,c)" "-c 4,5,20 abc.txt" "det\n" "" ""
-testcmd "-b (a,b,c)" "-b 4,5,20 abc.txt" "det\n" "" ""
+testing "with -c (a,b,c)" "cut -c 4,5,20 abc.txt" "det\n" "" ""
+
+testing "with -b (a,b,c)" "cut -b 4,5,20 abc.txt" "det\n" "" ""
 
 # Modifying abc.txt data as per testcase
 echo "406378:Sales:Itorre:Jan
@@ -72,17 +72,13 @@
 636496:Research:Ancholie:Mel
 396082:Sales:Jucacion:Ed" >abc.txt
 
-testcmd "-d -f(:) -s" "-d: -f3 -s abc.txt" "Itorre\nNasium\nAncholie\nJucacion\n" "" ""
-testcmd "-d -f( ) -s" "-d' ' -f3 -s abc.txt && echo yes" "yes\n" "" ""
-testcmd "-d -f(a) -s" "-da -f3 -s abc.txt" "n\nsium:Jim\n\ncion:Ed\n" "" ""
-testcmd "-d -f(a) -s -n" "-da -f3 -s -n abc.txt" "n\nsium:Jim\n\ncion:Ed\n" "" ""
+testing "with -d -f(:) -s" "cut -d: -f3 -s abc.txt" "Itorre\nNasium\nAncholie\nJucacion\n" "" ""
 
-# Feature posix documents but nobody bothers to implement
-toyonly testcmd "-nb" '-nb 8-17 "$FILES/utf8/japan.txt"' "ガラス\n" "" ""
+testing "with -d -f( ) -s" "cut -d' ' -f3 -s abc.txt && echo yes" "yes\n" "" ""
 
-# Feature that is, as far as I can tell, totally undocumented?
-testcmd "-d newline" "-d \$'\n' -f 2-3,5" "two\nthree\nfive\n" "" \
-  'one\ntwo\nthree\nfour\nfive\nsix\seven\n'
+testing "with -d -f(a) -s" "cut -da -f3 -s abc.txt" "n\nsium:Jim\n\ncion:Ed\n" "" ""
+
+testing "with -d -f(a) -s -n" "cut -da -f3 -s -n abc.txt" "n\nsium:Jim\n\ncion:Ed\n" "" ""
 
 # Removing abc.txt file for cleanup purpose
 rm abc.txt
diff --git a/tests/date.test b/tests/date.test
index dfcefb2..6aaf937 100644
--- a/tests/date.test
+++ b/tests/date.test
@@ -76,8 +76,6 @@
 # Test all supported UTC offset variants.
 testing "tz Z" \
   "date -u -d 2020-08-01T12:34:56Z" "Sat Aug  1 12:34:56 UTC 2020\n" "" ""
-testing "tz ' Z '" \
-  "date -u -d '2020-08-01T12:34:56 Z '" "Sat Aug  1 12:34:56 UTC 2020\n" "" ""
 testing "tz -0800" \
   "date -u -d 2020-08-01T12:34:56-0800" "Sat Aug  1 20:34:56 UTC 2020\n" "" ""
 testing "tz +0800" \
@@ -90,9 +88,6 @@
   "date -u -d 2020-08-01T12:34:56+08" "Sat Aug  1 04:34:56 UTC 2020\n" "" ""
 testing "tz +008" \
   "date -u -d 2020-08-01T12:34:56+008" "Sat Aug  1 12:26:56 UTC 2020\n" "" ""
-testing "tz + 8 : 8 " \
-  "date -u -d '2020-08-01T12:34:56 + 8 : 8 '" "Sat Aug  1 04:26:56 UTC 2020\n"\
-  "" ""
 
 # Can we parse date's own output format?
 testing "round trip" 'TZ=$tz date -d "$(TZ=$tz date -d @1598476818)"' \
diff --git a/tests/env.test b/tests/env.test
index 06ba680..6d8928d 100755
--- a/tests/env.test
+++ b/tests/env.test
@@ -11,8 +11,7 @@
 testcmd "read" "$FILTER" "BANANA=hello\nLETTERS=\nWALRUS=42\n" "" ""
 testcmd "-u" "-u BANANA $FILTER" "LETTERS=\nWALRUS=42\n" "" ""
 testcmd "-uu" "-u LETTERS -u WALRUS $FILTER" "BANANA=hello\n" "" ""
-testcmd "-i uses old \$PATH" "-i echo hello" "hello\n" "" ""
-testcmd "-i env" "-i env" "" "" ""
+testcmd "-i" "-i env" "" "" ""
 testcmd "-i =" "-i one=two three=four $C | sort" \
   "one=two\nthree=four\n" "" ""
 testcmd "-0" "-i five=six seven=eight $C -0 | sort -z" "five=six\0seven=eight\0" "" ""
diff --git a/tests/file.test b/tests/file.test
index bd023ac..2e97099 100755
--- a/tests/file.test
+++ b/tests/file.test
@@ -4,72 +4,57 @@
 
 #testing "name" "command" "result" "infile" "stdin"
 
-test_line() {
-  ONE="$1"; shift; TWO="\"$FILES\"/$1 | sed 's/^.*: //'"; shift
-  testcmd "$ONE" "$TWO" "$@"
-}
-
-ln -s "$FILES"/java.class symlink
+touch empty
+echo "#!/bin/bash" > bash.script
+echo "#!  /bin/bash" > bash.script2
+echo "#!  /usr/bin/env python" > test.py
+echo "Hello, world!" > ascii
+echo "6465780a3033350038ca8f6ce910f94e" | xxd -r -p > android.dex
+ln -s $FILES/java.class symlink
 LINK=$(readlink symlink)
-ln -s "$FILES"/java.klass dangler
+ln -s $FILES/java.klass dangler
 BROKEN=$(readlink dangler)
 
-mkdir directory
 testing "directory" "file ." ".: directory\n" "" ""
-rmdir directory
-touch empty
 testing "empty" "file empty" "empty: empty\n" "" ""
-rm -f empty
-
-testing "script" "file input | grep -o ' script'" " script\n" "#!/bin/bash\n" ""
-testing "script with spaces" "file input | grep -o ' script'" " script\n" \
-  "#!  /bin/bash\n" ""
-testing "env script" "file input | egrep -o '(python|script)' | sort" \
-  "python\nscript\n" "#! /usr/bin/env python\n" ""
-testing "ascii" "file input" "input: ASCII text\n" "Hello, world!\n" ""
+testing "bash.script" "file bash.script | grep -o ' script'" " script\n" "" ""
+testing "bash.script with spaces" "file bash.script2 | grep -o ' script'" " script\n" "" ""
+testing "env python script" "file test.py | egrep -o '(python|script)' | sort" \
+  "python\nscript\n" "" ""
+testing "ascii" "file ascii" "ascii: ASCII text\n" "" ""
 testing "utf-8" \
-  "file \"$FILES\"/utf8/japan.txt | egrep -o '(UTF-8|text)' | LANG=c sort" \
+  "file $FILES/utf8/japan.txt | egrep -o '(UTF-8|text)' | LANG=c sort" \
   "UTF-8\ntext\n" "" ""
-
-# TODO each of these has multiple options we could test
 testing "java class" \
-  "file \"$FILES\"/java.class | egrep -o '(Java class|version 53.0)'"\
+  "file $FILES/java.class | egrep -o '(Java class|version 53.0)'"\
   "Java class\nversion 53.0\n" "" ""
-
-echo "cafebabe000000020100000700000003000040000000d9300000000e0100000c8000000200014000000098500000000e" | xxd -r -p > universal
-testcmd "mach-o universal" "universal" \
-  "universal: Mach-O universal binary with 2 architectures: [x86_64] [arm64]\n" "" ""
-rm universal
-
-test_line "tar file" "tar/tar.tar" "POSIX tar archive (GNU)\n" "" ""
-testing "gzip data" "file \"$FILES\"/tar/tar.tgz | grep -o 'gzip compressed data'" \
+testing "tar file" "file $FILES/tar/tar.tar | sed 's|$FILES/||'" \
+    "tar/tar.tar: POSIX tar archive (GNU)\n" "" ""
+testing "gzip data" "file $FILES/tar/tar.tgz | grep -o 'gzip compressed data'" \
     "gzip compressed data\n" "" ""
-test_line "bzip2 data" "tar/tar.tbz2" \
-  "bzip2 compressed data, block size = 900k\n" "" ""
-test_line "7z file" "tar/tar.7z" "7-zip archive data, version 0.4\n" "" ""
+testing "bzip2 data" "file $FILES/tar/tar.tbz2 | sed 's|$FILES/||'" \
+    "tar/tar.tbz2: bzip2 compressed data, block size = 900k\n" "" ""
+testing "7z file" "file $FILES/tar/tar.7z | sed 's|$FILES/||'" \
+    "tar/tar.7z: 7-zip archive data, version 0.4\n" "" ""
 testing "zip file" \
   "file $FILES/zip/example.zip | egrep -o '(Zip archive data|at least v1.0 to extract)'" \
     "Zip archive data\nat least v1.0 to extract\n" "" ""
-
 echo R0lGODlhIAAgAMZHAAAAABYWFiYmJioqKi4uLjIy | base64 -d > gif
 testing "gif file" "file gif" "gif: GIF image data, version 89a, 32 x 32\n" "" ""
 rm -f gif
 
 # TODO: check in a genuine minimal .dex
-
-echo "6465780a3033350038ca8f6ce910f94e" | xxd -r -p > android.dex
 testing "Android .dex" "file android.dex | egrep -o '(dex file|version 035)'" \
   "dex file\nversion 035\n" "" ""
-rm -f android.dex
 
 # These actually test a lot of the ELF code: 32-/64-bit, arm/arm64, PT_INTERP,
 # the two kinds of NDK ELF note, BuildID, and stripped/not stripped.
-toyonly test_line "Android NDK full ELF note" "elf/ndk-elf-note-full" \
+toyonly testing "Android NDK full ELF note" \
+    "file $FILES/elf/ndk-elf-note-full | sed 's/^.*: //'" \
     "ELF shared object, 64-bit LSB arm64, dynamic (/system/bin/linker64), for Android 24, built by NDK r19b (5304403), BuildID=0c712b8af424d57041b85326f0000fadad38ee0a, not stripped\n" "" ""
-toyonly test_line "Android NDK short ELF note" "elf/ndk-elf-note-short" \
+toyonly testing "Android NDK short ELF note" \
+    "file $FILES/elf/ndk-elf-note-short | sed 's/^.*: //'" \
     "ELF shared object, 32-bit LSB arm, dynamic (/system/bin/linker), for Android 28, BuildID=da6a5f4ca8da163b9339326e626d8a3c, stripped\n" "" ""
-toyonly test_line "ELF static fdpic" "elf/fdstatic" \
-    "ELF executable (fdpic), 32-bit MSB sh, static, stripped\n" "" ""
 
 testing "broken symlink" "file dangler" "dangler: broken symbolic link to $BROKEN\n" "" ""
 testing "symlink" "file symlink" "symlink: symbolic link to $LINK\n" "" ""
@@ -90,32 +75,4 @@
 testing "/dev/zero" "file /dev/zero" "/dev/zero: character special ($zero_dev)\n" "" ""
 testing "- </dev/zero" "file - </dev/zero | grep -ow data" "data\n" "" ""
 
-testcmd 'ar' 'input | grep -o " ar archive"' ' ar archive\n' \
-  "$(echo -e '!<arch>\nhello/          0           0     0     644     6         `\nworld')\n" ""
-testcmd 'cpio' 'input' 'input: ASCII cpio archive (SVR4 with no CRC)\n' \
-  '07070103344745000081A4000003E800' ''
-
-#TODO block fifo socket
-#can't stat (unopenable)
-#file
-#  readerror
-#  elf
-#  png (grayscale, color RGB, indexed color, grayscale with alpha, color RGBA
-#    X x X x-bit/{non-}interlaced
-#  gif87
-#  jpeg
-#  xz
-#  Ogg (buncha types)
-#  wav audio (buncha types)
-#  truetype font/collection
-#  Opentype font
-#  LLVM IR bitcode
-#  PEM certificate
-#  pe32
-#  BMP
-#  Linux perf
-#  Android sparse image file
-#  Android boot image
-#  Android DTB/DTBO
-#  Android Binary XML
-#  #! shell script
+rm empty bash.script bash.script2 test.py ascii android.dex
diff --git a/tests/files/elf/fdstatic b/tests/files/elf/fdstatic
deleted file mode 100755
index f8d01ec..0000000
--- a/tests/files/elf/fdstatic
+++ /dev/null
Binary files differ
diff --git a/tests/find.test b/tests/find.test
index d57d191..f427737 100755
--- a/tests/find.test
+++ b/tests/find.test
@@ -10,7 +10,7 @@
 sleep .1
 ln -s fifo link
 cd ..
-touch irrelevant
+touch b
 
 mkdir perm
 touch perm/all-read-only
@@ -85,16 +85,14 @@
 testing "-name file" "find dir -name file" "dir/file\n" "" ""
 testing "-name FILE" "find dir -name FILE" "" "" ""
 
-ln -s ../broken dir/link2
 testing "-iname file" "find dir -iname FILE" "dir/file\n" "" ""
 testing "-iname FILE" "find dir -iname FILE" "dir/file\n" "" ""
 
+
 testing "-name (no arguments)" \
   "find dir -name 2>&1 | grep -o '[-]name'" "-name\n" "" ""
 testing "-iname (no arguments)" \
   "find dir -iname 2>&1 | grep -o '[-]iname'" "-iname\n" "" ""
-testing "-lname" "find dir -lname '?./brok*'" "dir/link2\n" "" ""
-testing "-ilname" "find dir -ilname '*ROK*'" "dir/link2\n" "" ""
 
 testing "" "find dir \( -iname file -o -iname missing \) -exec echo {} \;" \
   "dir/file\n" "" ""
@@ -125,6 +123,7 @@
 testing "-L symlink loop noisy" \
   "LANG=C find -L dir -name file 2>err ; grep -q dir/looper err || echo missing error" \
   "dir/file\n" "" ""
+rm -f dir/looper err
 
 testing "-false" "find dir -false" "" "" ""
 testing "-true" "find dir/file -true" "dir/file\n" "" ""
@@ -132,7 +131,6 @@
 testing "missing root error" \
   "LANG=C find -L dir/missing-root 2>err ; grep -q dir/missing-root err || echo missing error" \
   "" "" ""
-rm -f dir/looper err
 
 testing "-path match root" "find dir/f* -path dir/file" "dir/file\n" "" ""
 testing "-name match root" "find dir/f* -name file" "dir/file\n" "" ""
@@ -145,15 +143,5 @@
 testing "one slash" 'find /etc/ -maxdepth 1 | grep /passwd\$' '/etc/passwd\n' \
   '' ''
 testing 'empty arg' 'find "" dir -name file 2>/dev/null' 'dir/file\n' '' ''
-testing 'quit' 'find dir perm -print -quit' 'dir\n' '' ''
-ln dir/file perm/hardlink
-testing 'samefile' 'find . -samefile dir/file | sort' \
-  './dir/file\n./perm/hardlink\n' '' ''
-rm -rf dir broken perm irrelevant
 
-mkdir dir
-touch -d @12345 dir/one
-touch -d @12346 dir/two
-testing 'newerat' 'find dir -type f -newerat @12345' 'dir/two\n' '' ''
-testing 'newer nano' 'find dir -type f -newerat @12345.67890' 'dir/two\n' '' ''
 rm -rf dir
diff --git a/tests/fmt.test b/tests/fmt.test
index 7be2e4e..201952e 100755
--- a/tests/fmt.test
+++ b/tests/fmt.test
@@ -26,8 +26,7 @@
 testing "" "fmt -w 12" "1 2 3 4 5 6\n7 8 9 0\n" "" "1 2 3 4 5 6 7 8 9 0\n"
 
 testing "matched tab indent" "fmt" "\thello world\n" "" "\thello\n\tworld"
-# Version skew: debian is now emitting \t instead of "first line's indent"
-toyonly testing "matched tab/space" "fmt" '        hello world\n' "" \
+testing "matched tab/space" "fmt" '        hello world\n' "" \
   "        hello\n\tworld"
 testing "matched space/tab" "fmt" "\thello world\n" ""  "\thello\n        world"
 
diff --git a/tests/grep.test b/tests/grep.test
index dbab4cc..215491c 100755
--- a/tests/grep.test
+++ b/tests/grep.test
@@ -13,7 +13,6 @@
 echo -e "this is test2" > foo2
 echo -e "this is foo3" > foo3
 testing "-l" "grep -l test foo foo2 foo3" "foo\nfoo2\n" "" ""
-testing "-L" "grep -L test foo foo2 foo3" "foo3\n" "" ""
 rm foo foo2 foo3
 
 testing "-q" "grep -q test input && echo yes" "yes\n" "this is a test\n" ""
@@ -203,7 +202,3 @@
 
 testing "print zero length match" "grep '[0-9]*'" "abc\n" "" "abc\n"
 testing "-o skip zero length match" "grep -o '[0-9]*'" "1234\n" "" "a1234b"
-# Bit of a hack, but other greps insert gratuitous \e[K clear-to-EOL
-testing "--color highlights all matches" \
-  "grep --color=always def | grep -o '[[][0-9;]*[Km]def.[[]m' | wc -l" \
-  "2\n" "" "abcdefghidefjkl\n"
diff --git a/tests/hexdump.test b/tests/hexdump.test
deleted file mode 100755
index e319957..0000000
--- a/tests/hexdump.test
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/bin/bash
-
-[ -f testing.sh ] && . testing.sh
-
-testcmd "simple file" "input" "0000000 6973 706d 656c 000a\n0000007\n" "simple\\n" ""
-testcmd "simple file -b" "-b input" "0000000 163 151 155 160 154 145 012\n0000007\n" "simple\\n" ""
-testcmd "simple file -c" "-c input" "0000000   s   i   m   p   l   e  \\\\n\n0000007\n" "simple\\n" ""
-testcmd "simple file -d" "-d input" "0000000 26995 28781 25964 00010\n0000007\n" "simple\\n" ""
-testcmd "simple file -o" "-o input" "0000000 064563 070155 062554 000012\n0000007\n" "simple\\n" ""
-testcmd "simple file -x" "-x input" "0000000 6973 706d 656c 000a\n0000007\n" "simple\\n" ""
-
-testcmd \
-  "simple file canonical output -C" \
-  "-C input" \
-  "\
-00000000  73 69 6d 70 6c 65 0a                              |simple.|\n\
-00000007\n" \
-  "simple\n" \
-  ""
-testcmd \
-  "simple file canonical output -C multiline" \
-  "-C input" \
-  "\
-00000000  73 69 6d 70 6c 65 0a 62  61 72 66 6f 6f 62 61 72  |simple.barfoobar|\n\
-00000010  66 6f 6f 62 61 72 0a                              |foobar.|\n\
-00000017\n" \
-  "\
-simple\n\
-barfoobarfoobar\n" \
-  ""
-
-testcmd \
-  "head of file -n 10" \
-  "-n 10 input" \
-  "\
-0000000 6973 706d 656c 730a 6d69\n\
-000000a\n" \
-  "simple\nsimple\n" \
-  ""
-testcmd \
-  "skip head of file -s 10" \
-  "-s 10 input" \
-  "\
-000000a 6c70 0a65\n\
-000000e\n" \
-  "simple\nsimple\n" \
-  ""
-
-testcmd \
-  "squeeze repeating lines" \
-  "input" \
-  "\
-0000000 6161 6161 6161 6161 6161 6161 6161 0a61\n\
-*\n\
-0000070 6f66 006f\n\
-0000073\n" \
-  "\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-foo" \
-  ""
-testcmd \
-  "squeeze repeating lines" \
-  "input" \
-  "\
-0000000 6161 6161 6161 6161 6161 6161 6161 0a61\n\
-*\n\
-0000030 6262 6262 6262 6262 6262 6262 6262 0a62\n\
-0000040 6161 6161 6161 6161 6161 6161 6161 0a61\n\
-*\n\
-0000070 6262 6262 6262 6262 6262 6262 6262 0a62\n\
-0000080\n" \
-  "\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-bbbbbbbbbbbbbbb\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-bbbbbbbbbbbbbbb\n" \
-  ""
-testcmd \
-  "don't squeeze repeating lines" \
-  "-v input" \
-  "\
-0000000 6161 6161 6161 6161 6161 6161 6161 0a61\n\
-0000010 6161 6161 6161 6161 6161 6161 6161 0a61\n\
-0000020 6161 6161 6161 6161 6161 6161 6161 0a61\n\
-0000030 6161 6161 6161 6161 6161 6161 6161 0a61\n\
-0000040 6161 6161 6161 6161 6161 6161 6161 0a61\n\
-0000050 6161 6161 6161 6161 6161 6161 6161 0a61\n\
-0000060 6161 6161 6161 6161 6161 6161 6161 0a61\n\
-0000070 6f66 006f\n\
-0000073\n" \
-  "\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-aaaaaaaaaaaaaaa\n\
-foo" \
-  ""
-
-for _ in {1..25}; do echo "foobar" >> file1; done
-for _ in {1..25}; do echo "buzzbar" >> file2; done
-
-testcmd \
-  "accumulate offset accross files" \
-  "file1 file2" \
-  "0000000 6f66 626f 7261 660a 6f6f 6162 0a72 6f66\n\
-0000010 626f 7261 660a 6f6f 6162 0a72 6f66 626f\n\
-0000020 7261 660a 6f6f 6162 0a72 6f66 626f 7261\n\
-0000030 660a 6f6f 6162 0a72 6f66 626f 7261 660a\n\
-0000040 6f6f 6162 0a72 6f66 626f 7261 660a 6f6f\n\
-0000050 6162 0a72 6f66 626f 7261 660a 6f6f 6162\n\
-0000060 0a72 6f66 626f 7261 660a 6f6f 6162 0a72\n\
-0000070 6f66 626f 7261 660a 6f6f 6162 0a72 6f66\n\
-0000080 626f 7261 660a 6f6f 6162 0a72 6f66 626f\n\
-0000090 7261 660a 6f6f 6162 0a72 6f66 626f 7261\n\
-00000a0 660a 6f6f 6162 0a72 6f66 626f 7261 620a\n\
-00000b0 7a75 627a 7261 620a 7a75 627a 7261 620a\n\
-*\n\
-0000170 7a75 627a 7261 000a\n\
-0000177\n" \
-  "" \
-  ""
-rm file1 file2
diff --git a/tests/kill.test b/tests/kill.test
index c15c25e..ce42341 100644
--- a/tests/kill.test
+++ b/tests/kill.test
@@ -6,4 +6,3 @@
 
 testcmd "-l HUP" "-l HUP" "1\n" "" ""
 testcmd "-l 1" "-l 1" "HUP\n" "" ""
-testcmd "-0 self" "-0 $$ && echo yes" "yes\n" "" ""
diff --git a/tests/mkdir.test b/tests/mkdir.test
index dfee03c..e1bdb88 100755
--- a/tests/mkdir.test
+++ b/tests/mkdir.test
@@ -8,15 +8,10 @@
 rmdir one
 
 touch existing
-testing "existing file" \
+testing "existing" \
 	"mkdir existing 2> /dev/null || [ -f existing ] && echo yes" "yes\n" "" ""
 rm existing
 
-mkdir existing
-testing "existing dir" \
-	"mkdir existing 2> /dev/null || echo yes" "yes\n" "" ""
-rmdir existing
-
 testing "one two" \
 	"mkdir one two && [ -d one ] && [ -d two ] && echo yes" "yes\n" "" ""
 rmdir one two
diff --git a/tests/nl.test b/tests/nl.test
index 4bf8e39..046773f 100755
--- a/tests/nl.test
+++ b/tests/nl.test
@@ -52,5 +52,4 @@
 testing "no space" "nl -w 1 -v 42" "42\tline\n" "" "line\n"
 
 # Should test for -E but no other implementation seems to have it?
-toyonly testing "-E" "nl -w2 -sx -Ebp'(one|two)'" " 1xone\n   and\n 2xtwo\n" \
-  "" "one\nand\ntwo\n"
+#testing "-E" "nl -w2 -sx -Ebp'(one|two)'" " 1x" "one\nand\ntwo\n"
diff --git a/tests/realpath.test b/tests/realpath.test
deleted file mode 100755
index c42fd43..0000000
--- a/tests/realpath.test
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/bash
-
-[ -f testing.sh ] && . testing.sh
-
-#testing "name" "command" "result" "infile" "stdin"
-
-TOP="$(readlink -f .)"
-
-testcmd '' '.' "$TOP\n" '' ''
-#testcmd '-z' '-z . | tr "\0" X' "${TOP}X" '' ''
-touch file
-testcmd 'file' 'file' "$TOP/file\n" '' ''
-mkdir -p one/two/three
-testcmd 'dir' 'one/two/three' "$TOP/one/two/three\n" '' ''
-#testcmd '--relative-to' '. --relative-to=one/two/three' '../../..\n' '' ''
-#testcmd '--relative-base' 'one one/two one/two/three --relative-base=one/two' \
-#  "$TOP/one\n.\nthree\n" '' ''
-#testcmd '--relative-base stomps --relative-to' \
-#  '--relative-to=.. --relative-base=one/two one' "$TOP/one\n" '' ''
-testcmd 'missing defaults to -m' 'missing' "$TOP/missing\n" '' ''
-testcmd 'missing -e' '-e missing 2>/dev/null || echo ok' 'ok\n' '' ''
-
-# The -s tests use $PWD instead of $TOP because symlinks in path _to_ here
-# should not be resolved either. The shell exports $PWD: use it.
-ln -s ./one uno
-#testcmd '-s' '-s uno/two' "$PWD/uno/two\n" '' ''
-ln -s one/two dos
-#testcmd '-s link/..' '-es dos/three' "$PWD/dos/three\n" '' ''
-#testcmd '-s .. eats symlink' '-s dos/..' "$PWD\n" '' ''
-# In toybox this test is consistent with the previous one
-#toyonly testing '-s .. eats symlink in $PWD' \
-#  'cd dos && realpath -s ..' "$PWD\n" '' ''
-# Logically -es means the _symlink_ should exist, but match behavior...
-ln -s missing dangling
-#testcmd '-es dangling symlink' '-es dangling 2>/dev/null || echo ok' \
-#  'ok\n' '' ''
-#testcmd '-ms' '-ms dangling/../dos/../one/two' "$PWD/one/two\n" '' ''
-ln -s ../two/.. one/two/ichi
-#testcmd '-es' '-es one/two/ichi/two/ichi/two' "$PWD/one/two/ichi/two/ichi/two\n" '' ''
diff --git a/tests/sed.test b/tests/sed.test
index 5035478..fd3b205 100755
--- a/tests/sed.test
+++ b/tests/sed.test
@@ -195,9 +195,6 @@
   '138c1fa7c3f64186203b0192fb4abdb33cb4e98a  -\n' '' "$X\n"
 unset X Y
 
-testing "w doesn't blank" "sed -e 'w one' -e 'w one' -e d; cat one" \
-  'hello\nhello\n' '' 'hello\n'
-
 testing 's i and I' 'sed s/o/0/ig' "f00l F00L" "" "fool FOOL"
 
 # -i with $ last line test
diff --git a/tests/sh.test b/tests/sh.test
index 9cfa9fd..947e3ae 100644
--- a/tests/sh.test
+++ b/tests/sh.test
@@ -84,8 +84,6 @@
 ln -s $(which $SH) bash
 testing 'non-absolute $_' "./bash -c 'echo \$_'" './bash\n' '' ''
 rm bash
-testing '$_ with functions' 'true; x(){ echo $_;}; x abc; echo $_' \
-  'true\nabc\n' '' ''
 
 shxpect '$_ preserved on assignment error' I$'true hello; a=1 b=2 c=${}\n' \
   E E"$P" I$'echo $_\n' O$'hello\n'
@@ -122,9 +120,8 @@
 testing "script file" "chmod +x input; ./input" "hello\n" "#!$C\necho hello" ""
 testing 'IFS $*' "$SH -c 'IFS=xy; echo \"\$*\"' one two tyree" "twoxtyree\n" \
   "" ""
-# Without the \n\n bash 5 emits SHLVL=0
 testing 'default exports' \
-  "env -i \"$(which $SH)\" --noprofile --norc -c \$'env\n\n' | sort" \
+  "env -i \"$(which $SH)\" --noprofile --norc -c env | sort" \
   "PWD=$(pwd)\nSHLVL=1\n_=$(which env)\n" "" ""
 # toysh order of operations not matching bash
 #testing "leading assignment fail" \
@@ -137,17 +134,8 @@
 # Change EVAL to call sh -c for us, using "bash" explicitly for the host.
 export EVAL="$SH -c"
 
-
-mkdir -p one/two/three
-testing 'cd in renamed dir' \
-  'cd one/two/three && mv ../../../{one,four} && cd .. && echo ${PWD: -9:9}' \
-  '/four/two\n' '' ''
-rm -rf one
-
 testing "smoketest" "echo hello" "hello\n" "" ""
 testing "line break" $'ec\\\nho hello' 'hello\n' '' ''
-testing "assignment" 'x=y; echo $x' 'y\n' '' ''
-testing "+= assignment" 'x+=abc; y=def; y+=$x; echo $y' 'defabc\n' '' ''
 testing "eval" "eval echo hello" "hello\n" "" ""
 testing "eval2" "eval 'echo hello'; echo $?" "hello\n0\n" "" ""
 testing "eval3" 'X="echo hello"; eval "$X"' "hello\n" "" ""
@@ -223,19 +211,13 @@
 testing 'wildcards' 'echo w[v-x]w w[x-v]w abc/*/ghi' \
   'www w[x-v]w abc/def/ghi\n' '' ''
 
-testing "backtick1" 'x=fred; echo `echo $x`' 'fred\n' "" ""
-testing "backtick2" 'x=fred; echo `x=y; echo $x`; echo $x' 'y\nfred\n' "" ""
+#testing "backtick1" 'X=fred; echo `echo $x`' 'fred\n' "" ""
+#testing "backtick2" 'X=fred; echo `x=y; echo $x`' 'y\n' "" ""
 testing '$(( ) )' 'echo ab$((echo hello) | tr e x)cd' "abhxllocd\n" "" ""
-SKIPNEXT=1 testing '$((x=y)) lifetime' 'a=boing; echo $a $a$((a=4))$a $a' 'boing boing44 4\n' '' ''
+testing '$((x=y)) lifetime' 'a=boing; echo $a $a$((a=4))$a $a' 'boing boing44 4\n' '' ''
 
 testing 'quote' "echo \"'\"" "'\n" "" ""
 
-testing "math" 'echo $((1+2))' '3\n' '' ''
-testing "[math]" 'echo $[1+2]' '3\n' '' ''
-testing "math prio" 'echo $((1+2*3**4))' '163\n' '' ''
-testing "math paren" 'echo $(((1+2)*3))' '9\n' '' ''
-testing "math spaces" 'echo $(( ( 1 + 2 ) * 7 - 5 ** 2 ))' '-4\n' '' ''
-
 # Loops and flow control
 testing "case" 'for i in A C J B; do case "$i" in A) echo got A ;; B) echo and B ;; C) echo then C ;; *) echo default ;; esac; done' \
   "got A\nthen C\ndefault\nand B\n" "" ""
@@ -285,14 +267,12 @@
 
 mkfifo POIT
 testing 'background curly block' \
-  '{ sed s/ll/xx/ POIT; }& echo hello > POIT; wait && echo yes' \
-  'hexxo\nyes\n' '' ''
+  '{ sed s/ll/xx/ POIT; }& echo hello > POIT; wait' 'hexxo\n' '' ''
 rm -f POIT
 
 testing 'background pipe block' \
   'if true; then { sleep .25;bzcat "$FILES"/blkid/ntfs.bz2; }& fi | wc -c' \
   '8388608\n' '' ''
-testing 'background variable assignment' 'X=x; X=y & echo $X' 'x\n' '' ''
 
 #$ IFS=x X=xyxz; for i in abc${X}def; do echo =$i=; done
 #=abc=
@@ -366,8 +346,7 @@
 testing "case quoting" 'case a in "a") echo hello;; esac' 'hello\n' "" ""
 
 testing "subshell splitting" 'for i in $(true); do echo =$i=; done' "" "" ""
-testing "subshell split 2" 'for i in $(echo "one two thr"); do echo =$i=; done'\
-  "=one=\n=two=\n=thr=\n" "" ""
+#testing "subshell split 2"
 
 # variable assignment argument splitting only performed for "$@"
 testing "assignment nosplit" 'X="one two"; Y=$X; echo $Y' "one two\n" "" ""
@@ -446,8 +425,7 @@
   'abc\nabcdef\nabcq\n' '' ''
 testing '${!x*} none' 'echo "${!abc*}"' '\n' '' ''
 testing '${!x*} err' '{ echo "${!abc*x}"; echo boing;} 2>/dev/null' '' '' ''
-# TODO bash 5.x broke this
-#testing '${!none@Q}' 'echo ${X@Q} ${!X@Q}; X=ABC; echo ${!X@Q}' '\n\n' '' ''
+testing '${!none@Q}' 'echo ${X@Q} ${!X@Q}; X=ABC; echo ${!X@Q}' '\n\n' '' ''
 testing '${!x@Q}' 'ABC=123 X=ABC; echo ${!X@Q}' "'123'\n" '' ''
 testing '${#@Q}' 'echo ${#@Q}' "'0'\n" '' ''
 testing '${!*}' 'xx() { echo ${!*};}; fruit=123; xx fruit' '123\n' '' ''
@@ -455,8 +433,7 @@
   "'one' 'two' 'three'\n" '' ''
 testing '${!x@ } match' \
   '{ ABC=def; def=ghi; echo ${!ABC@ }; } 2>&1 | grep -o bad' 'bad\n' '' ''
-# Bash added an error for this between 4.4 and 5.x.
-#testing '${!x@ } no match no err' 'echo ${!ABC@ }def' 'def\n' '' ''
+testing '${!x@ } no match no err' 'echo ${!ABC@ }def' 'def\n' '' ''
 testing '${!x@ } no match no err2' 'ABC=def; echo ${!ABC@ }ghi' 'ghi\n' '' ''
 toyonly testing '${#x::}' 'ABC=abcdefghijklmno; echo ${#ABC:1:2}' '5\n' '' ''
 # TODO: ${!abc@x} does _not_ error? And ${PWD@q}
@@ -469,9 +446,8 @@
 testing '${a :}' 'ABC=def; { echo ${ABC :1};} 2>&1 | grep -o bad' 'bad\n' '' ''
 testing '${::}' 'ABC=defghi; echo ${ABC:1:2}' 'ef\n' '' ''
 testing '${: : }' 'ABC=defghi; echo ${ABC: 1 : 2 }' 'ef\n' '' ''
-testing '${::} indirect' \
-  'ABC=defghi:1:2; ( echo ${!ABC};) 2>input; [ -s input ] && echo yes' \
-  'yes\n' '' ''
+testing '${::} indirect' 'ABC=defghi:1:2; { echo ${!ABC};} 2>&1 | grep -o bad' \
+  'bad\n' '' ''
 testing '${::-}' 'ABC=defghi; echo ${ABC:1:-2}' 'efg\n' '' ''
 testing '${:-:-}' 'ABC=defghi; echo ${ABC:-3:2}' 'defghi\n' '' ''
 testing '${:-:-}2' 'echo ${ABC:-3:2}' '3:2\n' '' ''
@@ -570,45 +546,13 @@
 testing 'function() just wants any block span' \
   'func() if true; then echo hello; fi; echo one; func; echo two' \
   'one\nhello\ntwo\n' '' ''
-testing 'function alternate syntax' \
-  'function func if true; then echo hello; fi; echo one; func; echo two' \
-  'one\nhello\ntwo\n' '' ''
-testing 'function syntax 3' \
-  'function func ( ) if true; then echo hello; fi; echo one; func; echo two' \
-  'one\nhello\ntwo\n' '' ''
-testing 'function nested parentheses' \
-  '( potato() { echo aaa; }; potato )' 'aaa\n' '' ''
 shxpect 'local creates a whiteout' \
   I$'func() { local potato; echo ${potato?bang}; }; potato=123; func\n' \
   E E"$P" I$'echo $?\n' O$'1\n'
-testing 'local replaces/preserves magic type' \
-  'x() { local RANDOM=potato; echo $RANDOM;};x;echo -e "$RANDOM\n$RANDOM"|wc -l'\
-  'potato\n2\n' '' ''
-
-testing '$$ is parent shell' \
-  '{ echo $$; (echo $$) } | sort -u | wc -l' "1\n" "" ""
-testing '$PPID is parent shell' \
-  '{ echo $PPID; (echo $PPID) } | sort -u | wc -l' "1\n" "" ""
-testing '$BASHPID is current PID' \
-  '{ echo $BASHPID; (echo $BASHPID) } | sort -u | wc -l' "2\n" "" ""
-
-testing 'unexport supports +=' 'export -n ABC+=DEF; declare -p ABC' \
-  'declare -- ABC="DEF"\n' '' ''
-testing 'unexport existing +=' \
-  'export ABC=XYZ; export -n ABC+=DEF; declare -p ABC' \
-  'declare -- ABC="XYZDEF"\n' '' ''
-
-testing '$!' '{ echo $BASHPID & echo $!; echo ${!};} | sort -u | wc -l' '1\n' \
-  '' ''
-
-shxpect 'blank line preserves $?' \
-  I$'false\n' E"$P" I$'\n' E"$P" I$'echo $?\n' O$'1\n'
-testing 'NOP line clears $?' 'false;$NOTHING;echo $?' '0\n' '' ''
-testing 'run "$@"' 'false;"$@";echo $?' '0\n' '' ''
 
 # TODO finish variable list from shell init
 
-# $# $? $- $! $0  # $$
+# $# $? $- $$ $! $0
 # always exported: PWD SHLVL _
 #  ./bash -c 'echo $_' prints $BASH, but PATH search shows path? Hmmm...
 # ro: UID PPID EUID $
@@ -623,6 +567,7 @@
 
 # maybe not: EXECIGNORE, FIGNORE, GLOBIGNORE
 
+#BASHPID - synonym for $$ HERE
 #BASH_SUBSHELL - SHLVL synonym
 #BASH_EXECUTION_STRING - -c argument
 #
diff --git a/tests/sha1sum.test b/tests/sha1sum.test
index fa4298d..b4d4b75 100755
--- a/tests/sha1sum.test
+++ b/tests/sha1sum.test
@@ -6,55 +6,52 @@
 
 # These tests are based on RFC3174 which were based on FIPS PUB 180-1
 
-if [ "$CMDNAME" == sha1sum ]; then
-  ABC=a9993e364706816aba3e25717850c26c9cd0d89d
-  ABCLONG=84983e441c3bd26ebaae4aa1f95129e5e54670f1
-  MILNUL=34aa973cd4c4daa4f61eeb2bdbad27316534016f
-  DIGITS=dea356a2cddd90c7a7ecedc5ebb563934f460452
-  DEF=589c22335a381f122d129225f5c0ba3056ed5811
-  SEQ=f70b7b8768a1183d6d1cd79d3b076d9eb5156350
-elif [ "$CMDNAME" == sha224sum ]; then
-  ABC=23097d223405d8228642a477bda255b32aadbce4bda0b3f7e36c9da7
-  ABCLONG=75388b16512776cc5dba5da1fd890150b0c6455cb4f58b1952522525
-  MILNUL=20794655980c91d8bbb4c1ea97618a4bf03f42581948b2ee4ee7ad67
-  DIGITS=567f69f168cd7844e65259ce658fe7aadfa25216e68eca0eb7ab8262
-  DEF=b6773126557f37fbc9b24e7b6adedc05d3eb3923fe3feeb369812d16
-  SEQ=d8b406f661bc690a1f58241f37c94e04d0a1af74af867b877778f18e
-elif [ "$CMDNAME" == sha256sum ]; then
-  ABC=ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad
-  ABCLONG=248d6a61d20638b8e5c026930c3e6039a33ce45964ff2167f6ecedd419db06c1
-  MILNUL=cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0
-  DIGITS=594847328451bdfa85056225462cc1d867d877fb388df0ce35f25ab5562bfbb5
-  DEF=cb8379ac2098aa165029e3938a51da0bcecfc008fd6795f401178647f96c5b34
-  SEQ=8060aa0ac20a3e5db2b67325c98a0122f2d09a612574458225dcb9a086f87cc3
-elif [ "$CMDNAME" == sha384sum ]; then
-  ABC=cb00753f45a35e8bb5a03d699ac65007272c32ab0eded1631a8b605a43ff5bed8086072ba1e7cc2358baeca134c825a7
-  ABCLONG=3391fdddfc8dc7393707a65b1b4709397cf8b1d162af05abfe8f450de5f36bc6b0455a8520bc4e6f5fe95b1fe3c8452b
-  MILNUL=9d0e1809716474cb086e834e310a4a1ced149e9c00f248527972cec5704c2a5b07b8b3dc38ecc4ebae97ddd87f3d8985
-  DIGITS=2fc64a4f500ddb6828f6a3430b8dd72a368eb7f3a8322a70bc84275b9c0b3ab00d27a5cc3c2d224aa6b61a0d79fb4596
-  DEF=180c325cccb299e76ec6c03a5b5a7755af8ef499906dbf531f18d0ca509e4871b0805cac0f122b962d54badc6119f3cf
-  SEQ=7d2a49098f0df0f3c152ca9916a3864542258b2bd487e00ea33cb68e7d27c5c0f25b540d29f62fb33720846073c51b66
-elif [ "$CMDNAME" == sha512sum ]; then
-  ABC=ddaf35a193617abacc417349ae20413112e6fa4e89a97ea20a9eeee64b55d39a2192992a274fc1a836ba3c23a3feebbd454d4423643ce80e2a9ac94fa54ca49f
-  ABCLONG=204a8fc6dda82f0a0ced7beb8e08a41657c16ef468b228a8279be331a703c33596fd15c13b1b07f9aa1d3bea57789ca031ad85c7a71dd70354ec631238ca3445
-  MILNUL=e718483d0ce769644e2e42c7bc15b4638e1f98b13b2044285632a803afa973ebde0ff244877ea60a4cb0432ce577c31beb009c5c2c49aa2e4eadb217ad8cc09b
-  DIGITS=89d05ba632c699c31231ded4ffc127d5a894dad412c0e024db872d1abd2ba8141a0f85072a9be1e2aa04cf33c765cb510813a39cd5a84c4acaa64d3f3fb7bae9
-  DEF=40a855bf0a93c1019d75dd5b59cd8157608811dd75c5977e07f3bc4be0cad98b22dde4db9ddb429fc2ad3cf9ca379fedf6c1dc4d4bb8829f10c2f0ee04a66663
-  SEQ=3000c8961bb83de289fa8b407d0ea23f53a57ea11ddb0f782a4ccc0f586780822946053132794b177823c2974873d5dfb2ab1b6c45ae3328e2e703ca907f54d7
-fi
-testcmd "abc" "" "$ABC  -\n" "" "abc"
-testcmd "longer str" "" "$ABCLONG  -\n"\
-        "" "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
-testing "a million nulls" \
-        'dd if=/dev/zero bs=1000 count=1000 2>/dev/null|tr \\0 a|$CMDNAME' \
-        "$MILNUL  -\n" "" ""
-testing "digits" 'for i in `seq 80`; do echo -n 01234567 ; done | $CMDNAME' \
-        "$DIGITS  -\n" "" ""
-testing "seq 10000" "seq 10000 | $CMDNAME" "$SEQ  -\n" "" ""
+testing "TEST1" \
+        "sha1sum" \
+        "a9993e364706816aba3e25717850c26c9cd0d89d  -\n" \
+        "" "abc"
 
+testing "TEST2" \
+        "sha1sum" \
+        "84983e441c3bd26ebaae4aa1f95129e5e54670f1  -\n" \
+        "" "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+
+testing "TEST3" \
+        'dd if=/dev/zero bs=1000 count=1000 2>/dev/null | tr \\0 a | sha1sum' \
+        "34aa973cd4c4daa4f61eeb2bdbad27316534016f  -\n" \
+        "" ""
+
+testing "TEST4" \
+        'for i in `seq 1 10`; do echo -n 0123456701234567012345670123456701234567012345670123456701234567 ; done | sha1sum' \
+        "dea356a2cddd90c7a7ecedc5ebb563934f460452  -\n" \
+        "" ""
+
+echo -n "abc" > file1
 echo -n "def" > file2
-testcmd "file" "input" "$ABC  input\n" "abc" ""
-testcmd "file1 file2" "input file2" "$ABC  input\n$DEF  file2\n" "abc" ""
-testcmd "file1 file2 -" "input file2 -" "$ABC  input\n$DEF  file2\n$ABC  -\n" \
-        "abc" "abc"
-rm -f file2
+testing "sha1sum" \
+        "sha1sum" \
+        "a9993e364706816aba3e25717850c26c9cd0d89d  -\n" \
+        "" "abc"
+
+testing "-" \
+        "sha1sum -" \
+        "a9993e364706816aba3e25717850c26c9cd0d89d  -\n" \
+        "" "abc"
+
+testing "file" \
+        "sha1sum file1" \
+        "a9993e364706816aba3e25717850c26c9cd0d89d  file1\n" \
+        "" ""
+
+testing "file1 file2" \
+        "sha1sum file1 file2" \
+        "a9993e364706816aba3e25717850c26c9cd0d89d  file1\n589c22335a381f122d129225f5c0ba3056ed5811  file2\n" \
+        "" ""
+
+testing "file1 file2 -" \
+        "sha1sum file1 file2 -" \
+        "a9993e364706816aba3e25717850c26c9cd0d89d  file1\n589c22335a381f122d129225f5c0ba3056ed5811  file2\na9993e364706816aba3e25717850c26c9cd0d89d  -\n" \
+        "" "abc"
+
+rm -f file1 file2
+
diff --git a/tests/sha224sum.test b/tests/sha224sum.test
deleted file mode 120000
index bc02ebe..0000000
--- a/tests/sha224sum.test
+++ /dev/null
@@ -1 +0,0 @@
-sha1sum.test
\ No newline at end of file
diff --git a/tests/sha256sum.test b/tests/sha256sum.test
deleted file mode 120000
index bc02ebe..0000000
--- a/tests/sha256sum.test
+++ /dev/null
@@ -1 +0,0 @@
-sha1sum.test
\ No newline at end of file
diff --git a/tests/sha384sum.test b/tests/sha384sum.test
deleted file mode 120000
index bc02ebe..0000000
--- a/tests/sha384sum.test
+++ /dev/null
@@ -1 +0,0 @@
-sha1sum.test
\ No newline at end of file
diff --git a/tests/sha512sum.test b/tests/sha512sum.test
deleted file mode 120000
index bc02ebe..0000000
--- a/tests/sha512sum.test
+++ /dev/null
@@ -1 +0,0 @@
-sha1sum.test
\ No newline at end of file
diff --git a/tests/sort.test b/tests/sort.test
index 5fe925e..dd2b826 100755
--- a/tests/sort.test
+++ b/tests/sort.test
@@ -88,7 +88,7 @@
 /usr/lib/prebaseconfig.d/6
 "
 
-toyonly testing "-x" "sort -x" "010\na0\n 0c0\n" "" "a0\n010\n 0c0\n"
+testing "-x" "sort -x" "010\na0\n 0c0\n" "" "a0\n010\n 0c0\n"
 
 # Test that -f applies to key or fallback independently
 
@@ -97,12 +97,10 @@
 testing "" "sort -f -k2,2" "A b b\na B C\na B a\n" "" "a B a\nA b b\na B C\n" 
 testing "" "sort -t, -k3n" "3,4,1,2\n4,1,2,3\n1,2,3,4\n2,3,4,1\n" "" \
   "1,2,3,4\n2,3,4,1\n4,1,2,3\n3,4,1,2\n"
-toyonly testing "-kx" "sort -k1,1x" "3\na\n0c\n" "" "0c\na\n3\n"
+testing "-kx" "sort -k1,1x" "3\na\n0c\n" "" "0c\na\n3\n"
 
-# This has irredeemable version skew on the host and no standard defining it.
-# testing "-V" "LANG=c sort -V" \
-#  "toy-2.37.tar.gz\ntoy-3.4.tar.gz\ntoy-3.12.tar.gz\ntoy-4.16-rc2.tar.gz\ntoy-4.16.tar.gz\n" "" \
-#  "toy-3.12.tar.gz\ntoy-2.37.tar.gz\ntoy-3.4.tar.gz\ntoy-4.16-rc2.tar.gz\ntoy-4.16.tar.gz"
+testing "" "sort -V" "toy-2.37.tar.gz\ntoy-3.4.tar.gz\ntoy-3.12.tar.gz\ntoy-4.16-rc2.tar.gz\ntoy-4.16.tar.gz\n" "" \
+  "toy-3.12.tar.gz\ntoy-2.37.tar.gz\ntoy-3.4.tar.gz\ntoy-4.16-rc2.tar.gz\ntoy-4.16.tar.gz"
 
 optional SORT_FLOAT
 
@@ -110,10 +108,3 @@
 testing "-g" "sort -g" \
   "bork\nNaN\n-inf\n0.4\n1.222\n01.37\n2.1\n+infinity\n" "" \
   "01.37\n1.222\n2.1\n0.4\nNaN\nbork\n-inf\n+infinity\n"
-
-# -n without number sorts as leading zero, but fallback is whole string
-testcmd '-n without number sorts as leading zero' '-n' \
-  '-1\n0A\n0D\nC\n1z\n3b\n' '' '1z\n0D\n3b\nC\n-1\n0A\n'
-
-testcmd '-u implies -s' '-uk2,2n' 'zero 1\nthree 2\nfour 3\n' '' \
-   'zero 1\none 1\nfour 3\ntwo 1\nthree 2\nalso 1'
diff --git a/tests/split.test b/tests/split.test
index 57270ff..4a52243 100755
--- a/tests/split.test
+++ b/tests/split.test
@@ -5,21 +5,21 @@
 #testing "name" "command" "result" "infile" "stdin"
 
 testing "split" "seq 1 12345 | split && ls xa[a-z] | wc -l" "13\n" "" ""
-rm -f xa[a-z]
+rm xa[a-z]
 
 testing "-" "seq 1 12345 | split - && ls xa[a-z] | wc -l" "13\n" "" ""
-rm -f xa[a-z]
+rm xa[a-z]
 
 seq 1 12345 > file
 testing "file" "split file && ls xa[a-z] | wc -l" "13\n" "" ""
-rm -f xa[a-z]
+rm xa[a-z]
 
-toyonly testing "-l" "split file -l 10k && wc -l xab" "2105 xab\n" "" ""
-rm -f xa[ab]
+testing "-l" "split file -l 10k && wc -l xab" "2105 xab\n" "" ""
+rm xa[ab]
 
 testing "suffix exhaustion" \
   "split file -l 10 -a 1 walrus 2>/dev/null || ls walrus* | wc -l" "26\n" "" ""
-rm -f walrus*
+rm walrus*
 
 testing "bytes" \
   "seq 1 20000 | split -b 100 -a 3 - whang && ls whang* | wc -l && wc -c whangbpw" "1089\n94 whangbpw\n" "" ""
@@ -27,9 +27,5 @@
 testing "reassembly" \
   'ls whang* | sort | xargs cat > reassembled && seq 1 20000 | diff -u reassembled - && echo yes' \
   "yes\n" "" ""
-rm -f file whang* reassembled
 
-testing "-n" "split -n 3 input; md5sum xaa xab xac" \
-  "494bb8fb423bfa1a5fd66dd0b98f866d  xaa\n449acfdbc692780de30a2df05c5d32aa  xab\n15ab4be57aebe9a1e445195d5094036c  xac\n" \
-  "$(seq 1 10000)" ""
-
+rm file whang* reassembled
diff --git a/tests/tail.test b/tests/tail.test
index 94644c8..036f433 100755
--- a/tests/tail.test
+++ b/tests/tail.test
@@ -73,9 +73,3 @@
   'tail -f one two three & sleep .25 ; echo more >> three ; echo also >> one; sleep .25; kill $! >/dev/null' \
   "==> one <==\nuno\n\n==> two <==\ndos\n\n==> three <==\ntres\nmore\n\n==> one <==\nalso\n" "" ""
 rm one two three
-
-testing "-F" "tail -s .1 -F walrus 2>/dev/null & sleep .2; echo hello > walrus;
-sleep .2; truncate -s 0 walrus; sleep .2; echo potato >> walrus; sleep .2;
-echo hello >> walrus; sleep .2; rm walrus; sleep .2; echo done > walrus;
-  sleep .5; kill %1" "hello\npotato\nhello\ndone\n" "" ""
-rm -f walrus
diff --git a/tests/tar.test b/tests/tar.test
index 034a3bf..70668c9 100644
--- a/tests/tar.test
+++ b/tests/tar.test
@@ -19,11 +19,21 @@
 # Reproducible tarballs: override ownership and timestamp.
 TAR='tar c --owner root --group root --mtime @1234567890'
 
-# Different tars add variable trailing NUL padding (1024 bytes is just minimum)
-# so look at first N 512-byte frames when analyzing header content.
+# Also amount of trailing NUL padding varies (1024 bytes is minimum,
+# gnu/dammit does more) so look at first N 512-byte frames when
+# analyzing header content.
 function SUM()
 {
-  tee save.dat | head -c $(($1*512)) | sha1sum | sed "s/ .*//"
+  if [ -n "$TARHD" ]; then
+    # (Android's shell doesn't support process substitution.)
+    mkfifo xxd-pipe
+    xxd <xxd-pipe & pid=$!
+    tee xxd-pipe | head -c $(($1*512)) | sha1sum | sed "s/ .*//"
+    rm xxd-pipe
+    wait $pid
+  else
+    head -c $(($1*512)) | sha1sum | sed "s/ .*//"
+  fi
 }
 
 function LST()
@@ -41,12 +51,12 @@
 # The kernel has two hardwired meaningful UIDs: 0 (root) and 65534 (nobody).
 # (Technically changeable via /proc/sys/*/overflowuid but nobody ever does)
 skipnot id nobody >/dev/null
-testing "pass user" "tar -c --owner nobody:65534 --group root --mtime @0 file | LST" \
+testing "pass user" "tar -c --owner nobody --group root --mtime @0 file | LST" \
   "-rw-rw-r-- nobody/root 0 1970-01-01 00:00 file\n" "" ""
 # (We assume that if we have the nobody user, we also have the group, in the
 # absence of a good portable way to test for the existence of a named group.)
 skipnot id nobody >/dev/null
-testing "pass group" "tar c --owner root --group nobody:65534 --mtime @0 file | LST" \
+testing "pass group" "tar c --owner root --group nobody --mtime @0 file | LST" \
   "-rw-rw-r-- root/nobody 0 1970-01-01 00:00 file\n" "" ""
 
 # Historically we output a "base 256" format that _we_ could decode but that
@@ -210,12 +220,11 @@
   "dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \
   "" ""
 
-yes | head -n $((1<<18)) > bang
-{ dd bs=$((1<<16)) count=1 status=none; dd bs=8192 seek=14 count=1 status=none; dd bs=4096 seek=64 count=5 status=none; } < bang > fweep
+yes | (dd bs=$((1<<16)) count=1; dd bs=8192 seek=14 count=1; dd bs=4096 seek=64 count=5) 2>/dev/null > fweep
 testing "sparse without overflow" "$TAR --sparse fweep | SUM 3" \
   "e1560110293247934493626d564c8f03c357cec5\n" "" ""
-rm bang fweep
 
+rm fweep
 for i in 1 3 5 7 9 14 27 36 128 256 300 304
 do
   dd if=/dev/zero of=fweep bs=65536 seek=$i count=1 2>/dev/null
@@ -276,14 +285,6 @@
   'hello\n' '' ''
 rm -rf one test.tar
 
-mkdir ..dotsdir
-testing "create ..dotsdir" "$TAR ..dotsdir | SUM 3" \
-  "de99091a91c74ef6b90093e9165b413670730572\n" "" ""
-
-testing "pass ..dotsdir" "$TAR ..dotsdir | LST" \
-  "drwxrwxr-x root/root 0 2009-02-13 23:31 ..dotsdir/\n" "" ""
-rmdir ..dotsdir
-
 if false
 then
 
@@ -326,4 +327,3 @@
 umask $OLDUMASK
 unset LONG TAR SUM OLDUMASK OLDTZ
 unset -f LST
-rm save.dat
diff --git a/toys.h b/toys.h
index 81c4955..ead39b5 100644
--- a/toys.h
+++ b/toys.h
@@ -56,16 +56,15 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
-// Internationalization support (also in POSIX)
+// Internationalization support (also in POSIX and LSB)
 
 #include <langinfo.h>
 #include <locale.h>
 #include <wchar.h>
 #include <wctype.h>
 
-// Non-posix headers
+// LSB 4.1 headers
 #include <sys/ioctl.h>
-#include <sys/syscall.h>
 
 #include "lib/lib.h"
 #include "lib/lsm.h"
@@ -83,10 +82,8 @@
 // These live in main.c
 
 struct toy_list *toy_find(char *name);
-void show_help(FILE *out, int full);
-void check_help(char **arg);
-void toy_singleinit(struct toy_list *which, char *argv[]);
 void toy_init(struct toy_list *which, char *argv[]);
+void toy_singleinit(struct toy_list *which, char *argv[]);
 void toy_exec(char *argv[]);
 
 // Array of available commands
@@ -122,7 +119,9 @@
 
 // Two big temporary buffers: one for use by commands, one for library functions
 
-extern char **environ, *toybox_version, toybuf[4096], libbuf[4096];
+extern char *toybox_version, toybuf[4096], libbuf[4096];
+
+extern char **environ;
 
 #define FLAG(x) (toys.optflags&FLAG_##x)
 
@@ -134,5 +133,5 @@
 #ifndef TOYBOX_VENDOR
 #define TOYBOX_VENDOR ""
 #endif
-#define TOYBOX_VERSION "0.8.6"TOYBOX_VENDOR
+#define TOYBOX_VERSION "0.8.4"TOYBOX_VENDOR
 #endif
diff --git a/toys/android/README b/toys/android/README
index b1b627c..d471a20 100644
--- a/toys/android/README
+++ b/toys/android/README
@@ -1,6 +1,5 @@
-Android commands
+Android
 
-Commands primarily used by Android, not present in vanilla Linux.
-(Mostly SELinux stuff.)
+Commands primarily used by Android, not vanilla Linux. (Also SELinux stuff.)
 
 Bug Elliott Hughes <enh@google.com> about this.
diff --git a/toys/android/log.c b/toys/android/log.c
index 0f7b387..3fbc95a 100644
--- a/toys/android/log.c
+++ b/toys/android/log.c
@@ -2,16 +2,16 @@
  *
  * Copyright 2016 The Android Open Source Project
 
-USE_LOG(NEWTOY(log, "p:t:", TOYFLAG_USR|TOYFLAG_SBIN))
+USE_LOG(NEWTOY(log, "<1p:t:", TOYFLAG_USR|TOYFLAG_SBIN))
 
 config LOG
   bool "log"
   depends on TOYBOX_ON_ANDROID
   default y
   help
-    usage: log [-p PRI] [-t TAG] [MESSAGE...]
+    usage: log [-p PRI] [-t TAG] MESSAGE...
 
-    Logs message (or stdin) to logcat.
+    Logs message to logcat.
 
     -p	Use the given priority instead of INFO:
     	d: DEBUG  e: ERROR  f: FATAL  i: INFO  v: VERBOSE  w: WARN  s: SILENT
@@ -40,18 +40,17 @@
   }
   if (!TT.t) TT.t = "log";
 
-  if (toys.optc) {
-    for (i = 0; toys.optargs[i]; i++) {
-      if (i) *s++ = ' ';
-      if ((s-toybuf)+strlen(toys.optargs[i])>=1024) {
-        memcpy(s, toys.optargs[i], 1024-(s-toybuf));
-        toybuf[1024] = 0;
-        error_msg("log cut at 1024 bytes");
-        break;
-      }
-      s = stpcpy(s, toys.optargs[i]);
+  for (i = 0; toys.optargs[i]; i++) {
+    if (i) *s++ = ' ';
+    if ((s-toybuf)+strlen(toys.optargs[i])>=1024) {
+      memcpy(s, toys.optargs[i], 1024-(s-toybuf));
+      toybuf[1024] = 0;
+      error_msg("log cut at 1024 bytes");
+
+      break;
     }
-  } else toybuf[readall(0, toybuf, 1024-1)] = 0;
+    s = stpcpy(s, toys.optargs[i]);
+  }
 
   __android_log_write(pri, TT.t, toybuf);
 }
diff --git a/toys/example/README b/toys/example/README
index 6e73fa1..0ebc202 100644
--- a/toys/example/README
+++ b/toys/example/README
@@ -2,22 +2,13 @@
 
 You probably don't want to deploy any of this.
 
-The hello.c and skeleton.c commands provide templates for new commands. When
-writing a new command, copying hello.c or skeleton.c to the new name may provide
-a good starting point. (The minimal staring point is toys/posix/false.c)
+The hello.c and skeleton.c commands provide templates for new commands:
+hello.c is clean and simple, skeleton.c demonstrates the option parsing
+infrastructure and having multiple commands per file. When writing a new
+command, copying hello.c or skeleton.c to the new name may provide a good
+starting point. (The minimal staring point is toys/posix/false.c)
 
-  - hello.c is clean and simple, and an easy way to check the behavior of
-    toybox library functions running in command context.
+The demo_* commands demonstrate infrastructure, and do regression testing.
 
-  - skeleton.c demonstrates the option parsing infrastructure and having
-    multiple commands per file.
-
-Some of the commands in here are test infrastructure:
-
-  - logpath.c is optionally used by mkroot.sh and scripts/record-commands
-
-  - demo_* demonstrates infrastructure, allowing tests/demo_*.test to
-    regression test library functions directly.
-
-hostid.c is an obsolete command still in posix and present on some recent
-Linux systems, but not really useful on modern systems.
+Other commands in here are obsolete versions still in some recent Linux systems
+(and often still in posix), but not really useful on modern systems.
diff --git a/toys/example/demo_scankey.c b/toys/example/demo_scankey.c
index 05ffc41..cc62509 100644
--- a/toys/example/demo_scankey.c
+++ b/toys/example/demo_scankey.c
@@ -30,17 +30,20 @@
   y = 1;
 
   sigatexit(tty_sigreset);  // Make ctrl-c restore tty
-  // hide cursor, reset color to default, clear screen
-  xputsn("\e[?25l\e0m\e[2J");
+  tty_esc("?25l");          // hide cursor
+  tty_esc("0m");            // reset color to default
+  tty_esc("2J");            // Clear screen
   xset_terminal(1, 1, 0, 0); // Raw mode
 
   for (;;) {
-    printf("\e[%u;%uH%c", y+1, x+1, c);
+    tty_jump(x, y);
+    xputc(c);
     t[1&++tick] = time(0);
     if (t[0] != t[1]) terminal_probesize(&width, &height);
     // Don't block first time through, to force header print
     key = scan_key_getsize(scratch, -1*!!t[0], &width, &height);
-    printf("\e[HESC to exit: ");
+    tty_jump(0, 0);
+    printf("ESC to exit: ");
     // Print unknown escape sequence
     if (*scratch) {
       printf("key=[ESC");
@@ -49,13 +52,14 @@
         printf("%c", key);
       printf("] ");
     } else printf("key=%d ", key);
-    printf("x=%d y=%d width=%d height=%d\e[K", x, y, width, height);
+    printf("x=%d y=%d width=%d height=%d\033[K", x, y, width, height);
     fflush(0);
 
     if (key == -2) continue;
     if (key <= ' ') break;
     if (key>=256) {
-      printf("\e[%u;%uH ", y+1, x+1);
+      tty_jump(x, y);
+      xputc(' ');
 
       key -= 256;
       if (key==KEY_UP) y--;
diff --git a/toys/example/demo_utf8towc.c b/toys/example/demo_utf8towc.c
index 2c6050b..c052254 100644
--- a/toys/example/demo_utf8towc.c
+++ b/toys/example/demo_utf8towc.c
@@ -19,11 +19,11 @@
 {
   mbstate_t mb;
   int len1, len2;
-  unsigned u, h, wc2;
-  wchar_t wc1;
+  unsigned u, h;
+  wchar_t wc1, wc2;
 
   memset(&mb, 0, sizeof(mb));
-  for (u = 1; u<=0x10ffff; u++) {
+  for (u=1; u; u++) {
     char *str = (void *)&h;
 
     wc1 = wc2 = 0;
diff --git a/toys/example/hello.c b/toys/example/hello.c
index ad74eba..3e68f21 100644
--- a/toys/example/hello.c
+++ b/toys/example/hello.c
@@ -5,8 +5,7 @@
  * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/
  * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cmdbehav.html
  * See https://www.ietf.org/rfc/rfc3.txt
- * See https://man7.org/linux/man-pages/man1/intro.1.html
- * No standard.
+ * See http://man7.org/linux/man-pages/dir_section_1.html
 
 USE_HELLO(NEWTOY(hello, 0, TOYFLAG_USR|TOYFLAG_BIN))
 
@@ -34,5 +33,5 @@
   xprintf("Hello world\n");
 
   // Avoid kernel panic if run as init.
-  if (getpid() == 1) getchar();
+  if (getpid() == 1) wait(&TT.unused);
 }
diff --git a/toys/example/logpath.c b/toys/example/logwrapper.c
similarity index 61%
rename from toys/example/logpath.c
rename to toys/example/logwrapper.c
index 84fb712..036fcd3 100644
--- a/toys/example/logpath.c
+++ b/toys/example/logwrapper.c
@@ -1,36 +1,33 @@
-/* logpath.c - Record commands called out of $PATH to a log
+/* logwrapper.c - Record commands called out of $PATH to a log
  *
  * Copyright 2019 Rob Landley <rob@landley.net>
  *
  * I made it up. Must be built standalone to work. (Is its own multiplexer.)
 
-USE_LOGPATH(NEWTOY(logpath, 0, TOYFLAG_NOHELP|TOYFLAG_USR|TOYFLAG_BIN))
+USE_LOGWRAPPER(NEWTOY(logwrapper, 0, TOYFLAG_NOHELP|TOYFLAG_USR|TOYFLAG_BIN))
 
-config LOGPATH
-  bool "logpath"
+config LOGWRAPPER
+  bool "logwrapper"
   default n
   help
-    usage: logpath ...
+    usage: logwrapper ...
 
-    Append command line to $LOGPATH, then call second instance
+    Append command line to $WRAPLOG, then call second instance
     of command in $PATH.
 */
 
-#define FOR_logpath
+#define FOR_logwrapper
 #include "toys.h"
 
-#if CFG_TOYBOX
-#warning Must be built standalone to work.
-#endif
-
-void logpath_main(void)
+void logwrapper_main(void)
 {
-  char *log = getenv("LOGPATH"), *omnom = basename(*toys.argv), *s, *ss, *sss;
+  char *log = getenv("WRAPLOG"), *omnom = basename(*toys.argv),
+       *s, *ss, *sss;
   struct string_list *list;
   int i, len;
 
   // Log the command line
-  if (!log) error_exit("no $LOGPATH");
+  if (!log) error_exit("no $WRAPLOG");
   len = strlen(omnom)+2;
   for (i = 0; i<toys.optc; i++) len += 2*strlen(toys.optargs[i])+3;
   ss = stpcpy(s = xmalloc(len), omnom);
@@ -51,7 +48,7 @@
   *(ss++) = '\n';
 
   // Atomically append to log and free buffer
-  i = xcreate(log, O_WRONLY|O_CREAT|O_APPEND, 0644);
+  i = xcreate(log, O_RDWR|O_CREAT|O_APPEND, 0644);
   xwrite(i, s, ss-s);
   close(i);
   free(s);
@@ -66,12 +63,13 @@
     }
   }
 
-  // Skip first instance and try to run next one, continuing until one works
-  for (;list; free(llist_pop(&list))) {
-    free(llist_pop(&list));
+  // Skip first instance and try to run next one, until out of instances.
+  for (;;) {
+    if (list) free(llist_pop(&list));
+    if (!list)
+      error_exit("no %s after %s in $PATH=%s", omnom,
+        **toys.argv == '/' ? *toys.argv : "logwrapper", getenv("PATH"));
     *toys.argv = list->str;
     execve(list->str, toys.argv, environ);
   }
-  error_exit("no %s after %s in $PATH=%s", omnom,
-    **toys.argv == '/' ? *toys.argv : "logpath", getenv("PATH"));
 }
diff --git a/toys/example/skeleton.c b/toys/example/skeleton.c
index 5408068..a22bc90 100644
--- a/toys/example/skeleton.c
+++ b/toys/example/skeleton.c
@@ -6,8 +6,7 @@
  * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/
  * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cmdbehav.html
  * See https://www.ietf.org/rfc/rfc3.txt
- * See https://man7.org/linux/man-pages/man1/intro.1.html
- * No standard.
+ * See http://man7.org/linux/man-pages/dir_section_1.html
 
 // Accept many different kinds of command line argument (see top of lib/args.c)
 // Demonstrate two commands in the same file (see www/documentation.html)
@@ -36,7 +35,7 @@
     usage: skeleton_alias [-dq] [-b NUMBER]
 
     Example of a second command with different arguments in the same source
-    file as the first. This allows shared infrastructure outside of lib/.
+    file as the first. This allows shared infrastructure not added to lib/.
 */
 
 #define FOR_skeleton
@@ -91,6 +90,7 @@
 }
 
 // Switch gears from skeleton to skeleton_alias (swap FLAG macros).
+#define CLEANUP_skeleton
 #define FOR_skeleton_alias
 #include "generated/flags.h"
 
diff --git a/toys/lsb/dmesg.c b/toys/lsb/dmesg.c
index 384d6fc..829fcd5 100644
--- a/toys/lsb/dmesg.c
+++ b/toys/lsb/dmesg.c
@@ -42,7 +42,7 @@
 
 static void color(int c)
 {
-  if (TT.use_color) printf("\e[%dm", c);
+  if (TT.use_color) printf("\033[%dm", c);
 }
 
 static void format_message(char *msg, int new)
@@ -141,7 +141,7 @@
     for (;;) {
       // why does /dev/kmesg return EPIPE instead of EAGAIN if oldest message
       // expires as we read it?
-      if (-1==(len = read(fd, msg, sizeof(msg)-1)) && errno==EPIPE) continue;
+      if (-1==(len = read(fd, msg, sizeof(msg))) && errno==EPIPE) continue;
       // read() from kmsg always fails on a pre-3.5 kernel.
       if (len==-1 && errno==EINVAL) goto klogctl_mode;
       if (len<1) break;
diff --git a/toys/lsb/md5sum.c b/toys/lsb/md5sum.c
index feb403f..da9b14b 100644
--- a/toys/lsb/md5sum.c
+++ b/toys/lsb/md5sum.c
@@ -1,13 +1,12 @@
-/* md5sum.c - Calculate hashes md5, sha1, sha224, sha256, sha384, sha512.
+/* md5sum.c - Calculate RFC 1321 md5 hash and sha1 hash.
  *
- * Copyright 2012, 2021 Rob Landley <rob@landley.net>
+ * Copyright 2012 Rob Landley <rob@landley.net>
  *
  * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/md5sum.html
  * and http://www.ietf.org/rfc/rfc1321.txt
- * and http://www.ietf.org/rfc/rfc4634.txt
  *
  * They're combined this way to share infrastructure, and because md5sum is
- * a LSB standard command (but sha1sum and newer hashes are a good idea,
+ * and LSB standard command (but sha1sum and newer hashes are a good idea,
  * see http://valerieaurora.org/hash.html).
  *
  * We optionally use openssl (or equivalent) to access assembly optimized
@@ -17,21 +16,20 @@
  * coreutils supports --status but not -s, busybox supports -s but not --status
 
 USE_MD5SUM(NEWTOY(md5sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA1SUM(OLDTOY(sha1sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA224SUM(OLDTOY(sha224sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA256SUM(OLDTOY(sha256sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA384SUM(OLDTOY(sha384sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
-USE_SHA512SUM(OLDTOY(sha512sum, md5sum, TOYFLAG_USR|TOYFLAG_BIN))
+USE_SHA1SUM(NEWTOY(sha1sum, "bc(check)s(status)[!bc]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TOYBOX_LIBCRYPTO(USE_SHA224SUM(OLDTOY(sha224sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
+USE_TOYBOX_LIBCRYPTO(USE_SHA256SUM(OLDTOY(sha256sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
+USE_TOYBOX_LIBCRYPTO(USE_SHA384SUM(OLDTOY(sha384sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
+USE_TOYBOX_LIBCRYPTO(USE_SHA512SUM(OLDTOY(sha512sum, sha1sum, TOYFLAG_USR|TOYFLAG_BIN)))
 
 config MD5SUM
   bool "md5sum"
   default y
   help
-    usage: ???sum [-bcs] [FILE]...
+    usage: md5sum [-bcs] [FILE]...
 
-    Calculate hash for each input file, reading from stdin if none, writing
-    hexadecimal digits to stdout for each input file (md5=32 hex digits,
-    sha1=40, sha224=56, sha256=64, sha384=96, sha512=128) followed by filename.
+    Calculate md5 hash for each input file, reading from stdin if none.
+    Output one hash (32 hex digits) for each input file, followed by filename.
 
     -b	Brief (hash only, no filename)
     -c	Check each line of each FILE is the same hash+filename we'd output
@@ -41,31 +39,43 @@
   bool "sha1sum"
   default y
   help
-    See md5sum
+    usage: sha?sum [-bcs] [FILE]...
+
+    Calculate sha hash for each input file, reading from stdin if none. Output
+    one hash (40 hex digits for sha1, 56 for sha224, 64 for sha256, 96 for sha384,
+    and 128 for sha512) for each input file, followed by filename.
+
+    -b	Brief (hash only, no filename)
+    -c	Check each line of each FILE is the same hash+filename we'd output
+    -s	No output, exit status 0 if all hashes match, 1 otherwise
 
 config SHA224SUM
   bool "sha224sum"
   default y
+  depends on TOYBOX_LIBCRYPTO
   help
-    See md5sum
+    See sha1sum
 
 config SHA256SUM
   bool "sha256sum"
   default y
+  depends on TOYBOX_LIBCRYPTO
   help
-    See md5sum
+    See sha1sum
 
 config SHA384SUM
   bool "sha384sum"
   default y
+  depends on TOYBOX_LIBCRYPTO
   help
-    See md5sum
+    See sha1sum
 
 config SHA512SUM
   bool "sha512sum"
   default y
+  depends on TOYBOX_LIBCRYPTO
   help
-    See md5sum
+    See sha1sum
 */
 
 #define FORCE_FLAGS
@@ -81,21 +91,20 @@
 
 GLOBALS(
   int sawline;
-  unsigned *rconsttable32;
-  unsigned long long *rconsttable64; // for sha384,sha512
 
+  unsigned *md5table;
   // Crypto variables blanked after summing
-  unsigned long long count, overflow;
+  unsigned state[5], oldstate[5];
+  unsigned long long count;
   union {
-    char c[128]; // bytes, 1024 bits
-    unsigned i32[16]; // 512 bits for md5,sha1,sha224,sha256
-    unsigned long long i64[16]; // 1024 bits for sha384,sha512
-  } state, buffer;
+    char c[64];
+    unsigned i[16];
+  } buffer;
 )
 
-// Round constants. Static table for when we haven't got floating point support
+// Static table for when we haven't got floating point support
 #if ! CFG_TOYBOX_FLOAT
-static const unsigned md5nofloat[64] = {
+static unsigned md5nofloat[64] = {
   0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a,
   0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
   0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340,
@@ -111,59 +120,18 @@
 #else
 #define md5nofloat 0
 #endif
-static unsigned long long sha512nofloat[80] = {
-  // we cannot calculate these 64-bit values using the readily
-  // available floating point data types and math functions,
-  // so we always use this lookup table (80 * 8 bytes)
-  0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f,
-  0xe9b5dba58189dbbc, 0x3956c25bf348b538, 0x59f111f1b605d019,
-  0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242,
-  0x12835b0145706fbe, 0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2,
-  0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
-  0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3,
-  0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65, 0x2de92c6f592b0275,
-  0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5,
-  0x983e5152ee66dfab, 0xa831c66d2db43210, 0xb00327c898fb213f,
-  0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
-  0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc,
-  0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed, 0x53380d139d95b3df,
-  0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6,
-  0x92722c851482353b, 0xa2bfe8a14cf10364, 0xa81a664bbc423001,
-  0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
-  0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8,
-  0x19a4c116b8d2d0c8, 0x1e376c085141ab53, 0x2748774cdf8eeb99,
-  0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb,
-  0x5b9cca4f7763e373, 0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc,
-  0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
-  0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915,
-  0xc67178f2e372532b, 0xca273eceea26619c, 0xd186b8c721c0c207,
-  0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba,
-  0x0a637dc5a2c898a6, 0x113f9804bef90dae, 0x1b710b35131c471b,
-  0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
-  0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a,
-  0x5fcb6fab3ad6faec, 0x6c44198c4a475817
-};
-// sha1 needs only 4 round constant values, so prefer precomputed
-static const unsigned sha1rconsts[] = {
-  0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
-};
-
-// bit rotations
-#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
-#define ror(value, bits) (((value) >> (bits)) | ((value) << (32 - (bits))))
-#define ror64(value, bits) (((value) >> (bits)) | ((value) << (64 - (bits))))
 
 // Mix next 64 bytes of data into md5 hash
 
 static void md5_transform(void)
 {
-  unsigned x[4], *b = TT.buffer.i32;
+  unsigned x[4], *b = (unsigned *)TT.buffer.c;
   int i;
 
-  memcpy(x, TT.state.i32, sizeof(x));
+  memcpy(x, TT.state, sizeof(x));
 
-  for (i = 0; i<64; i++) {
-    unsigned in, a, rot, temp;
+  for (i=0; i<64; i++) {
+    unsigned int in, a, rot, temp;
 
     a = (-i)&3;
     if (i<16) {
@@ -189,27 +157,33 @@
       rot = (5*rot)+(((rot+2)&2)>>1);
       temp = x[(a+2)&3] ^ (x[(a+1)&3] | ~x[(a+3)&3]);
     }
-    temp += x[a] + b[in] + TT.rconsttable32[i];
+    temp += x[a] + b[in] + TT.md5table[i];
     x[a] = x[(a+1)&3] + ((temp<<rot) | (temp>>(32-rot)));
   }
-  for (i = 0; i<4; i++) TT.state.i32[i] += x[i];
+  for (i=0; i<4; i++) TT.state[i] += x[i];
 }
 
 // Mix next 64 bytes of data into sha1 hash.
 
+static const unsigned rconsts[]={0x5A827999,0x6ED9EBA1,0x8F1BBCDC,0xCA62C1D6};
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
 static void sha1_transform(void)
 {
   int i, j, k, count;
-  unsigned *block = TT.buffer.i32, oldstate[5], *rot[5], *temp, work;
+  unsigned *block = TT.buffer.i;
+  unsigned *rot[5], *temp;
 
-  // Copy context->state.i32[] to working vars
-  for (i = 0; i<5; i++) {
-    oldstate[i] = TT.state.i32[i];
-    rot[i] = TT.state.i32 + i;
+  // Copy context->state[] to working vars
+  for (i=0; i<5; i++) {
+    TT.oldstate[i] = TT.state[i];
+    rot[i] = TT.state + i;
   }
   // 4 rounds of 20 operations each.
-  for (i = count = 0; i<4; i++) {
-    for (j = 0; j<20; j++) {
+  for (i=count=0; i<4; i++) {
+    for (j=0; j<20; j++) {
+      unsigned work;
+
       work = *rot[2] ^ *rot[3];
       if (!i) work = (work & *rot[1]) ^ *rot[3];
       else {
@@ -218,108 +192,44 @@
       }
 
       if (!i && j<16)
-        work += block[count] = (ror(block[count],8)&0xFF00FF00)
+        work += block[count] = (rol(block[count],24)&0xFF00FF00)
                              | (rol(block[count],8)&0x00FF00FF);
       else
         work += block[count&15] = rol(block[(count+13)&15]
               ^ block[(count+8)&15] ^ block[(count+2)&15] ^ block[count&15], 1);
-      *rot[4] += work + rol(*rot[0],5) + sha1rconsts[i];
+      *rot[4] += work + rol(*rot[0],5) + rconsts[i];
       *rot[1] = rol(*rot[1],30);
 
       // Rotate by one for next time.
       temp = rot[4];
-      for (k = 4; k; k--) rot[k] = rot[k-1];
+      for (k=4; k; k--) rot[k] = rot[k-1];
       *rot = temp;
       count++;
     }
   }
-  // Add the previous values of state.i32[]
-  for (i = 0; i<5; i++) TT.state.i32[i] += oldstate[i];
+  // Add the previous values of state[]
+  for (i=0; i<5; i++) TT.state[i] += TT.oldstate[i];
 }
 
-static void sha2_32_transform(void)
-{
-  unsigned block[64], s0, s1, S0, S1, ch, maj, temp1, temp2, rot[8];
-  int i;
+// Fill the 64-byte working buffer and call transform() when full.
 
-  for (i = 0; i<16; i++) block[i] = SWAP_BE32(TT.buffer.i32[i]);
-
-  // Extend the message schedule array beyond first 16 words
-  for (i = 16; i<64; i++) {
-    s0 = ror(block[i-15], 7) ^ ror(block[i-15], 18) ^ (block[i-15] >> 3);
-    s1 = ror(block[i-2], 17) ^ ror(block[i-2], 19) ^ (block[i-2] >> 10);
-    block[i] = block[i-16] + s0 + block[i-7] + s1;
-  }
-  // Copy context->state.i32[] to working vars
-  for (i = 0; i<8; i++) rot[i] = TT.state.i32[i];
-  // 64 rounds
-  for (i = 0; i<64; i++) {
-    S1 = ror(rot[4],6) ^ ror(rot[4],11) ^ ror(rot[4], 25);
-    ch = (rot[4] & rot[5]) ^ ((~ rot[4]) & rot[6]);
-    temp1 = rot[7] + S1 + ch + TT.rconsttable32[i] + block[i];
-    S0 = ror(rot[0],2) ^ ror(rot[0],13) ^ ror(rot[0], 22);
-    maj = (rot[0] & rot[1]) ^ (rot[0] & rot[2]) ^ (rot[1] & rot[2]);
-    temp2 = S0 + maj;
-    memmove(rot+1, rot, 28);
-    rot[4] += temp1;
-    rot[0] = temp1 + temp2;
-  }
-
-  // Add the previous values of state.i32[]
-  for (i = 0; i<8; i++) TT.state.i32[i] += rot[i];
-}
-
-static void sha2_64_transform(void)
-{
-  unsigned long long block[80], s0, s1, S0, S1, ch, maj, temp1, temp2, rot[8];
-  int i;
-
-  for (i=0; i<16; i++) block[i] = SWAP_BE64(TT.buffer.i64[i]);
-
-  // Extend the message schedule array beyond first 16 words
-  for (i = 16; i<80; i++) {
-    s0 = ror64(block[i-15], 1) ^ ror64(block[i-15], 8) ^ (block[i-15] >> 7);
-    s1 = ror64(block[i-2], 19) ^ ror64(block[i-2], 61) ^ (block[i-2] >> 6);
-    block[i] = block[i-16] + s0 + block[i-7] + s1;
-  }
-  // Copy context->state.i64[] to working vars
-  for (i = 0; i<8; i++) rot[i] = TT.state.i64[i];
-  // 80 rounds
-  for (i = 0; i<80; i++) {
-    S1 = ror64(rot[4],14) ^ ror64(rot[4],18) ^ ror64(rot[4], 41);
-    ch = (rot[4] & rot[5]) ^ ((~ rot[4]) & rot[6]);
-    temp1 = rot[7] + S1 + ch + TT.rconsttable64[i] + block[i];
-    S0 = ror64(rot[0],28) ^ ror64(rot[0],34) ^ ror64(rot[0], 39);
-    maj = (rot[0] & rot[1]) ^ (rot[0] & rot[2]) ^ (rot[1] & rot[2]);
-    temp2 = S0 + maj;
-    memmove(rot+1, rot, 56);
-    rot[4] += temp1;
-    rot[0] = temp1 + temp2;
-  }
-
-  // Add the previous values of state.i64[]
-  for (i=0; i<8; i++) TT.state.i64[i] += rot[i];
-}
-
-// Fill the 64/128-byte (512/1024-bit) working buffer and call transform() when full.
-
-static void hash_update(char *data, unsigned int len, void (*transform)(void),
-  int chunksize)
+static void hash_update(char *data, unsigned int len, void (*transform)(void))
 {
   unsigned int i, j;
 
-  j = TT.count & (chunksize - 1);
-  if (TT.count+len<TT.count) TT.overflow++;
+  j = TT.count & 63;
   TT.count += len;
 
   for (;;) {
     // Grab next chunk of data, return if it's not enough to process a frame
-    i = chunksize - j;
+    i = 64 - j;
     if (i>len) i = len;
     memcpy(TT.buffer.c+j, data, i);
-    if (j+i != chunksize) break;
+    if (j+i != 64) break;
 
     // Process a frame
+    if (IS_BIG_ENDIAN)
+      for (j=0; j<16; j++) TT.buffer.i[j] = SWAP_LE32(TT.buffer.i[j]);
     transform();
     j=0;
     data += i;
@@ -373,93 +283,74 @@
     sprintf(toybuf+2*i, "%02x", toybuf[i+128]);
 }
 
+// Callback for loopfiles()
+
 static void do_builtin_hash(int fd, char *name)
 {
-  unsigned long long count[2];
-  int i, chunksize, digestlen, method;
-  volatile char *pp;
+  unsigned long long count;
+  int i, sha1 = toys.which->name[0]=='s';
+  char buf, *pp;
   void (*transform)(void);
-  char buf;
 
-  // md5sum, sha1sum, sha224sum, sha256sum, sha384sum, sha512sum
-  method = stridx("us2581", toys.which->name[4]);
-
-  // select hash type
-  transform = (void *[]){md5_transform, sha1_transform, sha2_32_transform,
-    sha2_32_transform, sha2_64_transform, sha2_64_transform}[method];
-  digestlen = (char []){16, 20, 28, 32, 48, 64}[method];
-  chunksize = 64<<(method>=4);
-  if (method<=1)
-    memcpy(TT.state.i32, (unsigned []){0x67452301, 0xEFCDAB89, 0x98BADCFE,
-      0x10325476, 0xC3D2E1F0}, 20);
-  else if (method==2)
-    memcpy(TT.state.i32, (unsigned []){0xc1059ed8, 0x367cd507, 0x3070dd17,
-      0xf70e5939, 0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4}, 32);
-  else if (method==3)
-    memcpy(TT.state.i32, (unsigned []){0x6a09e667, 0xbb67ae85, 0x3c6ef372,
-      0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}, 32);
-  else if (method==4)
-    memcpy(TT.state.i64, (unsigned long long []){0xcbbb9d5dc1059ed8,
-      0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
-      0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7,
-      0x47b5481dbefa4fa4}, 64);
-  else memcpy(TT.state.i64, (unsigned long long []){0x6a09e667f3bcc908,
-      0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
-      0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b,
-      0x5be0cd19137e2179}, 64);
-
+  /* SHA1 initialization constants  (md5sum uses first 4) */
+  TT.state[0] = 0x67452301;
+  TT.state[1] = 0xEFCDAB89;
+  TT.state[2] = 0x98BADCFE;
+  TT.state[3] = 0x10325476;
+  TT.state[4] = 0xC3D2E1F0;
   TT.count = 0;
+
+  transform = sha1 ? sha1_transform : md5_transform;
   for (;;) {
     i = read(fd, toybuf, sizeof(toybuf));
     if (i<1) break;
-    hash_update(toybuf, i, transform, chunksize);
+    hash_update(toybuf, i, transform);
   }
 
+  count = TT.count << 3;
+
   // End the message by appending a "1" bit to the data, ending with the
   // message size (in bits, big endian), and adding enough zero bits in
-  // between to pad to the end of the next frame.
+  // between to pad to the end of the next 64-byte frame.
   //
   // Since our input up to now has been in whole bytes, we can deal with
-  // bytes here too. sha384 and 512 use 128 bit counter, so track overflow.
-  buf = 0x80;
-  count[0] = (TT.overflow<<3)+(TT.count>>61);
-  count[1] = TT.count<<3; // convert to bits
-  for (i = 0; i<2; i++)
-    count[i] = !method ? SWAP_LE64(count[i]) : SWAP_BE64(count[i]);
-  i = 8<<(method>=4);
-  do {
-    hash_update(&buf, 1, transform, chunksize);
-    buf = 0;
-  } while ((TT.count&(chunksize-1)) != chunksize-i);
-  hash_update((void *)(count+(method<4)), i, transform, chunksize);
+  // bytes here too.
 
-  // write digest to toybuf
-  if (method>=4) for (i=0; i<digestlen/8; i++)
-    sprintf(toybuf+16*i, "%016llx", TT.state.i64[i]);
-  else for (i=0; i<digestlen/4; i++)
-    sprintf(toybuf+8*i, "%08x",
-            !method ? bswap_32(TT.state.i32[i]) : TT.state.i32[i]);
-  // Wipe variables. Cryptographer paranoia. Avoid "optimizing" out memset
-  // by looping on a volatile pointer.
-  i = sizeof(struct md5sum_data)-offsetof(struct md5sum_data, state.i64);
-  for (pp = (void *)TT.state.i64; i; i--) *pp++ = 0;
-  pp = toybuf+strlen(toybuf)+1;
-  for (i = sizeof(toybuf)-(pp-toybuf); i; i--) *pp++ = 0;
+  buf = 0x80;
+  do {
+    hash_update(&buf, 1, transform);
+    buf = 0;
+  } while ((TT.count & 63) != 56);
+  count = sha1 ? SWAP_BE64(count) : SWAP_LE64(count);
+  hash_update((void *)&count, 8, transform);
+
+  if (sha1)
+    for (i = 0; i < 20; i++)
+      sprintf(toybuf+2*i, "%02x", 255&(TT.state[i>>2] >> ((3-(i & 3)) * 8)));
+  else for (i=0; i<4; i++) sprintf(toybuf+8*i, "%08x", bswap_32(TT.state[i]));
+
+  // Wipe variables. Cryptographer paranoia.
+  // if we do this with memset(), gcc throws a broken warning, and the (long)
+  // typecasts stop gcc from breaking "undefined behavior" that isn't.
+  for (pp = (void *)TT.state; (unsigned long)pp-(unsigned long)TT.state<sizeof(TT)-((unsigned long)TT.state-(unsigned long)&TT); pp++)
+    *pp = 0;
+  i = strlen(toybuf)+1;
+  memset(toybuf+i, 0, sizeof(toybuf)-i);
 }
 
-// Callback for loopfiles()
 // Call builtin or lib hash function, then display output if necessary
 static void do_hash(int fd, char *name)
 {
   if (CFG_TOYBOX_LIBCRYPTO) do_lib_hash(fd, name);
   else do_builtin_hash(fd, name);
 
-  if (name) printf("%s  %s\n"+4*!!FLAG(b), toybuf, name);
+  if (name)
+    printf(FLAG(b) ? "%s\n" : "%s  %s\n", toybuf, name);
 }
 
-static void do_c_line(char *line)
+static int do_c_line(char *line)
 {
-  int space = 0, fail = 0, fd;
+  int space = 0, fail = 0;
   char *name;
 
   for (name = line; *name; name++) {
@@ -468,32 +359,42 @@
       *name = 0;
     } else if (space) break;
   }
-  if (!space || !*line || !*name) return error_msg("bad line %s", line);
 
-  fd = !strcmp(name, "-") ? 0 : open(name, O_RDONLY);
+  if (!space || !*line || !*name) error_msg("bad line %s", line);
+  else {
+    int fd = !strcmp(name, "-") ? 0 : open(name, O_RDONLY);
 
-  TT.sawline = 1;
-  if (fd==-1) {
-    perror_msg_raw(name);
-    *toybuf = 0;
-  } else do_hash(fd, 0);
-  if (strcasecmp(line, toybuf)) toys.exitval = fail = 1;
-  if (!FLAG(s)) printf("%s: %s\n", name, fail ? "FAILED" : "OK");
-  if (fd>0) close(fd);
+    TT.sawline = 1;
+    if (fd==-1) {
+      perror_msg_raw(name);
+      *toybuf = 0;
+    } else do_hash(fd, 0);
+    if (strcasecmp(line, toybuf)) toys.exitval = fail = 1;
+    if (!FLAG(s)) printf("%s: %s\n", name, fail ? "FAILED" : "OK");
+    if (fd>0) close(fd);
+  }
+
+  return 0;
 }
 
 // Used instead of loopfiles_line to report error on files containing no hashes.
 static void do_c_file(char *name)
 {
   FILE *fp = !strcmp(name, "-") ? stdin : fopen(name, "r");
-  char *line;
 
-  if (!fp) return perror_msg_raw(name);
+  if (!fp) {
+    perror_msg_raw(name);
+    return;
+  }
 
   TT.sawline = 0;
 
   for (;;) {
-    if (!(line = xgetline(fp))) break;
+    char *line = 0;
+    ssize_t len;
+
+    if ((len = getline(&line, (void *)&len, fp))<1) break;
+    if (line[len-1]=='\n') line[len-1] = 0;
     do_c_line(line);
     free(line);
   }
@@ -504,25 +405,26 @@
 
 void md5sum_main(void)
 {
+  char **arg;
   int i;
 
   // Calculate table if we have floating point. Static version should drop
   // out at compile time when we don't need it.
-  if (!CFG_TOYBOX_LIBCRYPTO) {
-    if (*toys.which->name == 'm') { // MD5
-      if (CFG_TOYBOX_FLOAT) {
-        TT.rconsttable32 = xmalloc(64*4);
-        for (i = 0; i<64; i++) TT.rconsttable32[i] = fabs(sin(i+1))*(1LL<<32);
-      } else TT.rconsttable32 = md5nofloat;
-    } else if (toys.which->name[3] == '2') { // sha224, sha256
-      TT.rconsttable32 = xmalloc(64*4);
-      for (i=0; i<64; i++) TT.rconsttable32[i] = sha512nofloat[i] >> 32;
-    } else TT.rconsttable64 = sha512nofloat; // sha384, sha512
+  if (!CFG_TOYBOX_LIBCRYPTO && toys.which->name[0]=='m') {
+    if (CFG_TOYBOX_FLOAT) {
+      TT.md5table = xmalloc(64*4);
+      for (i = 0; i<64; i++) TT.md5table[i] = fabs(sin(i+1))*(1LL<<32);
+    } else TT.md5table = md5nofloat;
   }
 
-  if (FLAG(c)) for (i = 0; toys.optargs[i]; i++) do_c_file(toys.optargs[i]);
+  if (FLAG(c)) for (arg = toys.optargs; *arg; arg++) do_c_file(*arg);
   else {
     if (FLAG(s)) error_exit("-s only with -c");
     loopfiles(toys.optargs, do_hash);
   }
 }
+
+void sha1sum_main(void)
+{
+  md5sum_main();
+}
diff --git a/toys/lsb/mount.c b/toys/lsb/mount.c
index 10e8e9e..8ff084c 100644
--- a/toys/lsb/mount.c
+++ b/toys/lsb/mount.c
@@ -215,7 +215,7 @@
     if (fp && !buf) {
       size_t i;
 
-      if (getline(&buf, &i, fp)<1) {
+      if (getline(&buf, &i, fp)<0) {
         error_msg("%s: need -t", dev);
         break;
       }
@@ -232,7 +232,8 @@
       i = strlen(type);
       if (i) type[i-1] = 0;
     }
-    if (FLAG(v)) printf("try '%s' type '%s' on '%s'\n", dev, type, dir);
+    if (FLAG(v))
+      printf("try '%s' type '%s' on '%s'\n", dev, type, dir);
     for (;;) {
       rc = mount(dev, dir, type, flags, opts);
       // Did we succeed, fail unrecoverably, or already try read-only?
@@ -353,7 +354,8 @@
           continue;
       } else {
         if (dir && strcmp(dir, mm->dir)) continue;
-        if (strcmp(dev, mm->device) && (dir || strcmp(dev, mm->dir))) continue;
+        if (dev && strcmp(dev, mm->device) && (dir || strcmp(dev, mm->dir)))
+          continue;
       }
 
       // Don't overmount the same dev on the same directory
diff --git a/toys/lsb/passwd.c b/toys/lsb/passwd.c
index 8c17dc6..8ff010e 100644
--- a/toys/lsb/passwd.c
+++ b/toys/lsb/passwd.c
@@ -58,6 +58,7 @@
   struct passwd *pw = 0;
   struct spwd *sp;
   char *pass, *name, *encrypted = 0, salt[MAX_SALT_LEN];
+  int ret = -1;
 
   // If we're root or not -lud, load specified user. Exit if not allowed.
   if (!(myuid = getuid()) || !(toys.optflags&(FLAG_l|FLAG_u|FLAG_d))) {
@@ -71,20 +72,19 @@
   name = pw->pw_name;
   if (*(pass = pw->pw_passwd)=='x' && (sp = getspnam(name))) pass = sp->sp_pwdp;
 
-  if (FLAG(l)) {
+  if (toys.optflags & FLAG_l) {
     if (*pass=='!') error_exit("already locked");
     printf("Locking '%s'\n", name);
     encrypted = xmprintf("!%s", pass);
-  } else if (FLAG(u)) {
+  } else if (toys.optflags & FLAG_u) {
     if (*pass!='!') error_exit("already unlocked");
     printf("Unlocking '%s'\n", name);
     encrypted = pass+1;
-  } else if (FLAG(d)) {
+  } else if (toys.optflags & FLAG_d) {
     printf("Deleting password for '%s'\n", name);
-    *(encrypted = toybuf) = 0;
+    encrypted = "";
   } else {
-    if (!TT.a) TT.a = "des";
-    if (get_salt(salt, TT.a)<0) error_exit("bad -a '%s'", TT.a);
+    if (get_salt(salt, TT.a ? TT.a : "des")<0) error_exit("bad -a '%s'", TT.a);
 
     printf("Changing password for %s\n", name);
     if (myuid) {
@@ -105,11 +105,11 @@
   }
 
   // Update the passwd
-  if (update_password(*pw->pw_passwd=='x' ? "/etc/shadow" : "/etc/passwd",
-    name, encrypted, 1)) error_msg("Failure");
+  ret = update_password(*pw->pw_passwd=='x' ? "/etc/shadow" : "/etc/passwd",
+    name, encrypted);
+
+  if (ret) error_msg("Failure");
   else fprintf(stderr, "Success\n");
 
-  memset(toybuf, 0, sizeof(toybuf));
-  memset(encrypted, 0, strlen(encrypted));
-  free(encrypted);
+  if (CFG_TOYBOX_FREE && (toys.optflags & FLAG_l)) free(encrypted);
 }
diff --git a/toys/lsb/pidof.c b/toys/lsb/pidof.c
index 791eed0..cd705a7 100644
--- a/toys/lsb/pidof.c
+++ b/toys/lsb/pidof.c
@@ -5,18 +5,18 @@
  *
  * http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/pidof.html
 
-USE_PIDOF(NEWTOY(pidof, "so:x", TOYFLAG_BIN))
+USE_PIDOF(NEWTOY(pidof, "<1so:x", TOYFLAG_BIN))
 
 config PIDOF
   bool "pidof"
   default y
   help
-    usage: pidof [-s] [-o omitpid[,omitpid...]] [NAME...]
+    usage: pidof [-s] [-o omitpid[,omitpid...]] [NAME]...
 
     Print the PIDs of all processes with the given names.
 
-    -o	Omit PID(s)
     -s	Single shot, only return one pid
+    -o	Omit PID(s)
     -x	Match shell scripts too
 */
 
@@ -24,17 +24,17 @@
 #include "toys.h"
 
 GLOBALS(
-  char *o;
+  char *omit;
 )
 
 static int print_pid(pid_t pid, char *name)
 {
   sprintf(toybuf, "%d", (int)pid);
-  if (comma_scan(TT.o, toybuf, 0)) return 0;
+  if (comma_scan(TT.omit, toybuf, 0)) return 0;
   xprintf(" %s"+!!toys.exitval, toybuf);
   toys.exitval = 0;
 
-  return FLAG(s);
+  return toys.optflags & FLAG_s;
 }
 
 void pidof_main(void)
diff --git a/toys/lsb/su.c b/toys/lsb/su.c
index 136e81e..8083630 100644
--- a/toys/lsb/su.c
+++ b/toys/lsb/su.c
@@ -56,7 +56,7 @@
   if (*toys.optargs) name = *(toys.optargs++);
   else name = "root";
 
-  loggit(LOG_NOTICE, "%s->%s", getusername(geteuid()), name);
+  loggit(LOG_NOTICE, "%s->%s", getusername(getuid()), name);
 
   if (!(shp = getspnam(name))) perror_exit("no '%s'", name);
   if (getuid()) {
diff --git a/toys/net/README b/toys/net/README
index 49259ca..8708e4b 100644
--- a/toys/net/README
+++ b/toys/net/README
@@ -1,6 +1 @@
-Networking commands
-
-The Internet Engineering Task Force publishes standards drafts at
-https://www.ietf.org/rfc/rfc-index.txt (ala https://www.ietf.org/rfc/rfc3.txt)
-and the commands tend to be documented in manual page section 8
-https://man7.org/linux/man-pages/dir_section_8.html
+Networking
diff --git a/toys/net/host.c b/toys/net/host.c
deleted file mode 100644
index 2033167..0000000
--- a/toys/net/host.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/* host.c - DNS lookup utility
- *
- * Copyright 2014 Rich Felker <dalias@aerifal.cx>
- *
- * No standard, but there's a version in bind9
- * See https://www.ietf.org/rfc/rfc1035.txt
- * See https://www.ietf.org/rfc/rfc3596.txt
-
-USE_HOST(NEWTOY(host, "<1>2avt:", TOYFLAG_USR|TOYFLAG_BIN))
-
-config HOST
-  bool "host"
-  default y
-  help
-    usage: host [-v] [-t TYPE] NAME [SERVER]
-
-    Look up DNS records for NAME, either domain name or IPv4/IPv6 address to
-    reverse lookup, from SERVER or default DNS server(s).
-
-    -a	All records
-    -t TYPE	Record TYPE (number or ANY A AAAA CNAME MX NS PTR SOA SRV TXT)
-    -v	Verbose
-*/
-
-#define FOR_host
-#include "toys.h"
-#include <resolv.h>
-
-GLOBALS(
-  char *t;
-
-  char **nsname;
-  unsigned nslen;
-)
-
-static const struct rrt {
-  char *name, *msg;
-  int type;
-} rrt[] = { { "A", "has address", 1 }, { "NS", "name server", 2 },
-  { "CNAME", "is a nickname for", 5 }, { "SOA", "start of authority", 6 },
-  { "PTR", "domain name pointer", 12 }, { "MX", "mail is handled", 15 },
-  { "TXT", "descriptive text", 16 }, { "AAAA", "has address", 28 },
-  { "SRV", "mail is handled", 33 }
-};
-
-int xdn_expand(char *packet, char *endpkt, char *comp, char *expand, int elen)
-{
-  int i = dn_expand(packet, endpkt, comp, expand, elen);
-
-  if (i<1) error_exit("bad dn_expand");
-
-  return i;
-}
-
-// Fetch "nameserve" lines from /etc/resolv.conf. Ignores 'options' lines
-static void get_nsname(char **pline, long len)
-{
-  char *line, *p;
-
-  if (!len) return;
-  line = *pline;
-  if (strstart(&line, "nameserver") && isspace(*line)) {
-    while (isspace(*line)) line++;
-    for (p = line; *p && !isspace(*p) && *p!='#'; p++);
-    if (p == line) return;
-    *p = 0;
-    if (!(TT.nslen&8))
-      TT.nsname = xrealloc(TT.nsname, (TT.nslen+8)*sizeof(void *));
-    TT.nsname[TT.nslen++] = xstrdup(line);
-  }
-}
-
-void host_main(void)
-{
-  int verbose = FLAG(a)||FLAG(v), type, abuf_len = 65536, //Largest TCP response
-      i, j, sec, rcode, qlen, alen QUIET, pllen = 0, t2len = 2048;
-  unsigned count, ttl;
-  char *abuf = xmalloc(abuf_len), *name = *toys.optargs, *p, *ss,
-       *t2 = toybuf+t2len;
-  struct addrinfo *ai;
-
-  // What kind of query are we doing?
-  if (!TT.t && FLAG(a)) TT.t = "255";
-  if (!getaddrinfo(name, 0,&(struct addrinfo){.ai_flags=AI_NUMERICHOST}, &ai)) {
-    name = toybuf;
-    if (ai->ai_family == AF_INET) {
-      p = (void *)&((struct sockaddr_in *)ai->ai_addr)->sin_addr;
-      sprintf(name, "%d.%d.%d.%d.in-addr.arpa", p[3], p[2], p[1], p[0]);
-    } else if (ai->ai_family == AF_INET6) {
-      p = (void *)&((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
-      for (j = 0, i = 15; i>=0; i--)
-        j += sprintf(name+j, "%x.%x.", p[i]&15, p[i]>>4);
-      strcpy(name+j, "ip6.arpa");
-    }
-    if (!TT.t) TT.t = "12";
-  } else if (!TT.t) TT.t = "1";
-
-  // Prepare query packet of appropriate type
-  if (TT.t[0]-'0'<10) type = atoi(TT.t); // TODO
-  else if (!strcasecmp(TT.t, "any") || strcmp(TT.t, "*")) type = 255;
-  else {
-    for (i = 0; i<ARRAY_LEN(rrt); i++) if (!strcasecmp(TT.t, rrt[i].name)) {
-      type = rrt[i].type;
-      break;
-    }
-    if (i == ARRAY_LEN(rrt)) error_exit("bad -t: %s", TT.t);
-  }
-  qlen = res_mkquery(0, name, 1, type, 0, 0, 0, t2, 280); //t2len);
-  if (qlen<0) error_exit("bad NAME: %s", name);
-
-  // Grab nameservers
-  if (toys.optargs[1]) TT.nsname = toys.optargs+1;
-  else do_lines(xopen("/etc/resolv.conf", O_RDONLY), '\n', get_nsname);
-  if (!TT.nsname) error_exit("No nameservers");
-
-  // Send one query packet to each server until we receive response
-  while (*TT.nsname) {
-    if (verbose) printf("Using domain server %s:\n", *TT.nsname);
-    ai = xgetaddrinfo(*TT.nsname, "53", 0, SOCK_DGRAM, 0, 0);
-    i = xsocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
-    xconnect(i, ai->ai_addr, ai->ai_addrlen);
-    setsockopt(i, SOL_SOCKET, SO_RCVTIMEO, &(struct timeval){ .tv_sec = 5 },
-      sizeof(struct timeval));
-    send(i, t2, qlen, 0);
-    if (16 < (alen = recv(i, abuf, abuf_len, 0))) break;
-    if (!*++TT.nsname) error_exit("Host not found.");
-    close(i);
-  }
-
-  // Did it error?
-  rcode = abuf[3]&7;
-  if (verbose) {
-    printf("rcode = %d, ancount = %d\n", rcode, (int)peek_be(abuf+6, 2));
-    if (!(abuf[2]&4)) puts("The following answer is not authoritative:");
-  }
-  if (rcode) error_exit("Host not found: %s",
-    (char *[]){ "Format error", "Server failure",
-    "Non-existant domain", "Not implemented", "Refused", ""}[rcode-1]);
-
-  // Print the result
-  p = abuf + 12;
-  for (sec = 0; sec<(2<<verbose); sec++) {
-    count = peek_be(abuf+4+2*sec, 2);
-    if (verbose && count>0 && sec>1) 
-      puts(sec==2 ? "For authoritative answers, see:"
-        : "Additional information:");
-
-    for (; count--; p += pllen) {
-      p += xdn_expand(abuf, abuf+alen, p, toybuf, 4096-t2len);
-      if (alen-(p-abuf)<10) error_exit("tilt");
-      type = peek_be(p, 2);
-      p += 4;
-      if (!sec) continue;
-      ttl = peek_be(p, 4);
-      p += 4;
-      pllen = peek_be(p, 2);
-      p += 2;
-      if ((p-abuf)+pllen>alen) error_exit("tilt");
-
-      if (type==1 || type == 28)
-        inet_ntop(type==1 ? AF_INET : AF_INET6, p, t2, t2len);
-      else if (type==2 || type==5) xdn_expand(abuf, abuf+alen, p, t2, t2len);
-      else if (type==16) sprintf(t2, "\"%.*s\"", minof(pllen, t2len), p);
-      else if (type==6) { 
-        ss = p+xdn_expand(abuf, abuf+alen, p, t2, t2len-1);
-        j = strlen(t2);
-        t2[j++] = ' ';
-        ss += xdn_expand(abuf, abuf+alen, ss, t2+j, t2len-j);
-        j += strlen(t2+j);
-        snprintf(t2+j, t2len-j, "(\n\t\t%u\t;serial (version)\n\t\t%u\t"
-          ";refresh period\n\t\t%u\t;retry interval\n\t\t%u\t;expire time\n"
-          "\t\t%u\t;default ttl\n\t\t)", (unsigned)peek_be(ss, 4),
-          (unsigned)peek_be(ss+4, 4), (unsigned)peek_be(ss+8, 4),
-          (unsigned)peek_be(ss+12, 4), (unsigned)peek_be(ss+16, 4));
-      } else if (type==15) {
-        j = peek_be(p, 2);
-        j = sprintf(t2, verbose ? "%d " : "(pri=%d) by ", j);
-        xdn_expand(abuf, abuf+alen, p+2, t2+j, t2len-j);
-      } else if (type==33) {
-        j = sprintf(t2, "%u %u %u ", (int)peek_be(p, 2), (int)peek_be(p+2, 2),
-          (int)peek_be(p+4, 2));
-        xdn_expand(abuf, abuf+alen, p+6, t2+j, t2len-j);
-      } else {
-        printf("%s unsupported RR type %u\n", toybuf, type);
-        continue;
-      }
-
-      for (i = 0; rrt[i].type != type; i++);
-      if (verbose) printf("%s\t%u\tIN %s\t%s\n", toybuf, ttl, rrt[i].name, t2);
-      else printf("%s %s %s\n", toybuf, rrt[type].msg, t2);
-    }
-  }
-
-  if (CFG_TOYBOX_FREE) free(abuf);
-  toys.exitval = rcode;
-}
diff --git a/toys/net/ifconfig.c b/toys/net/ifconfig.c
index e9671bb..f8f1277 100644
--- a/toys/net/ifconfig.c
+++ b/toys/net/ifconfig.c
@@ -42,7 +42,6 @@
     broadcast ADDR   - Set broadcast address
     pointopoint ADDR - PPP and PPPOE use this instead of "route add default gw"
     hw TYPE ADDR     - set hardware (mac) address (type = ether|infiniband)
-    rename NEWNAME   - rename interface
 
     Flags you can set on an interface (or -remove by prefixing with -):
 
@@ -249,7 +248,7 @@
 
     for (s = str; *s; s++) {
       if (flags & mask) xprintf("%s ", *s);
-      mask <<= 1;
+      mask = mask << 1;
     }
   } else xprintf("[NO FLAGS] ");
 
@@ -406,7 +405,6 @@
       {"netmask", 0, SIOCSIFNETMASK},
       {"dstaddr", 0, SIOCSIFDSTADDR},
       {"mtu", IFREQ_OFFSZ(ifr_mtu), SIOCSIFMTU},
-      {"rename", IFREQ_OFFSZ(ifr_newname), SIOCSIFNAME},
       {"keepalive", IFREQ_OFFSZ(ifr_data), SIOCDEVPRIVATE}, // SIOCSKEEPALIVE
       {"outfill", IFREQ_OFFSZ(ifr_data), SIOCDEVPRIVATE+2}, // SIOCSOUTFILL
       {"metric", IFREQ_OFFSZ(ifr_metric), SIOCSIFMETRIC},
@@ -495,7 +493,6 @@
       struct argh *t = try+i;
       int on = t->on, off = t->off;
 
-      // First entry in list assigns address to interface (no command name)
       if (!t->name) {
         if (isdigit(**argv) || !strcmp(*argv, "default")) argv--;
         else continue;
@@ -508,12 +505,11 @@
 
           // Assign value to ifre field and call ioctl? (via IFREQ_OFFSZ.)
           if (on < 0) {
-            void *dest = ((on = -on)>>16)+(char *)&ifre;
+            long l = strtoul(*argv, 0, 0);
 
-            // If we're about to set mem_start/io_addr/irq, get other 2 first
             if (off == SIOCSIFMAP) xioctl(TT.sockfd, SIOCGIFMAP, &ifre);
-            if (off == SIOCSIFNAME) xstrncpy(dest, *argv, on&0xffff);
-            else poke(dest, strtoul(*argv, 0, 0), on&15);
+            on = -on;
+            poke((on>>16) + (char *)&ifre, l, on&15);
             xioctl(TT.sockfd, off, &ifre);
             break;
           } else {
diff --git a/toys/net/netstat.c b/toys/net/netstat.c
index 7eed02d..24a2cee 100644
--- a/toys/net/netstat.c
+++ b/toys/net/netstat.c
@@ -182,8 +182,8 @@
     if (state==1 && flags && !(FLAG(a) || FLAG(l))) continue;
 
     if (type==10) type = 7; // move SOCK_PACKET into line
-    if (type>=ARRAY_LEN(types)) type = 0;
-    if (state>=ARRAY_LEN(states) || (state==1 && !flags)) state = 0;
+    if (type>ARRAY_LEN(types)) type = 0;
+    if (state>ARRAY_LEN(states) || (state==1 && !flags)) state = 0;
 
     if (state!=1 && FLAG(l)) continue;
 
diff --git a/toys/net/ping.c b/toys/net/ping.c
index e7b296d..018e887 100644
--- a/toys/net/ping.c
+++ b/toys/net/ping.c
@@ -123,7 +123,7 @@
 
   // Set nonstatic default values
   if (!FLAG(i)) TT.i = FLAG(f) ? 200 : 1000;
-  else if (TT.i<200 && geteuid()) error_exit("need root for -i <200");
+  else if (TT.i<200 && getuid()) error_exit("need root for -i <200");
   if (!FLAG(s)) TT.s = 56; // 64-PHDR_LEN
   if (FLAG(f) && !FLAG(c)) TT.c = 15;
 
@@ -301,7 +301,9 @@
     toys.exitval = 0;
   }
 
-  // summary(0) gets called for us atexit.
+  sigatexit(0);
+  summary(0);
+
   if (CFG_TOYBOX_FREE) {
     freeaddrinfo(ai2);
     if (ifa2) freeifaddrs(ifa2);
diff --git a/toys/net/sntp.c b/toys/net/sntp.c
index 1139b0e..161cab4 100644
--- a/toys/net/sntp.c
+++ b/toys/net/sntp.c
@@ -72,7 +72,7 @@
 void sntp_main(void)
 {
   struct timespec tv, tv2;
-  unsigned long long *pktime = (void *)toybuf, now, then, before QUIET;
+  unsigned long long *pktime = (void *)toybuf, now, then, before = before;
   long long diff = 0;
   struct addrinfo *ai;
   union socksaddr sa;
diff --git a/toys/other/ascii.c b/toys/other/ascii.c
index aa49872..42f7326 100644
--- a/toys/other/ascii.c
+++ b/toys/other/ascii.c
@@ -4,15 +4,8 @@
  *
  * Technically 7-bit ASCII is ANSI X3.4-1986, a standard available as
  * INCITS 4-1986[R2012] on ansi.org, but they charge for it.
- *
- * unicode.c - convert between Unicode and UTF-8
- *
- * Copyright 2020 The Android Open Source Project.
- *
- * Loosely based on the Plan9/Inferno unicode(1).
 
-USE_ASCII(NEWTOY(ascii, 0, TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LINEBUF))
-USE_UNICODE(NEWTOY(unicode, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+USE_ASCII(NEWTOY(ascii, 0, TOYFLAG_USR|TOYFLAG_BIN))
 
 config ASCII
   bool "ascii"
@@ -21,65 +14,27 @@
     usage: ascii
 
     Display ascii character set.
-
-config UNICODE
-  bool "unicode"
-  default y
-  help
-    usage: unicode CODE[-END]...
-
-    Convert between Unicode code points and UTF-8, in both directions.
-    CODE can be one or more characters (show U+XXXX), hex numbers
-    (show character), or dash separated range.
 */
 
-#define FOR_unicode
 #include "toys.h"
 
-static char *low="NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2"
-                 "DC3DC4NAKSYNETBCANEM SUBESCFS GS RS US ";
-
-static void codepoint(unsigned wc)
-{
-  char *s = toybuf + sprintf(toybuf, "U+%04X : ", wc), *ss;
-  unsigned n, i;
-
-  if (wc>31 && wc!=127) {
-    s += n = wctoutf8(ss = s, wc);
-    if (n>1) for (i = 0; i<n; i++) s += sprintf(s, " : %#02x"+2*!!i, *ss++);
-  } else s = memcpy(s, (wc==127) ? "DEL" : low+wc*3, 3)+3;
-  *s++ = '\n';
-  writeall(1, toybuf, s-toybuf);
-}
-
-void unicode_main(void)
-{
-  int from, to, n;
-  char next, **args, *s;
-  unsigned wc;
-
-  // Loop through args, handling range, hex code, or character(s)
-  for (args = toys.optargs; *args; args++) {
-    if (sscanf(*args, "%x-%x%c", &from, &to, &next) == 2)
-      while (from <= to) codepoint(from++);
-    else if (sscanf(*args, "%x%c", &from, &next) == 1) codepoint(from);
-    else for (s = *args; (n = utf8towc(&wc, s, 4)) > 0; s += n) codepoint(wc);
-  }
-}
-
 void ascii_main(void)
 {
-  char *s = toybuf;
-  int i, x, y;
+  char *low="NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4"
+            "NAKSYNETBCANEM SUBESCFS GS RS US ";
+  int x, y;
 
-  for (y = -1; y<16; y++) for (x = 0; x<8; x++) {
-    if (y>=0) {
-      i = (x<<4)+y;
-      s += sprintf(s, "% *d %02X ", 3+(x>5), i, i);
-      if (i<32 || i==127) s += sprintf(s, "%.3s", (i<32) ? low+3*i : "DEL");
-      else *s++ = i;
-    } else s += sprintf(s, "Dec Hex%*c", 1+2*(x<2)+(x>4), ' ');
-    *s++ = (x>6) ? '\n' : ' ';
+  for (x = 0; x<8; x++) printf("Dec Hex%*c", 2+2*(x<2)+(x>4), ' ');
+  xputc('\n');
+  for (y=0; y<=15; y++) {
+    for (x=0; x<8; x++) {
+      int i = x*16+y;
+
+      if (i>95 && i<100) putchar(' ');
+      printf("% 3d %02X ", i, i);
+      if (i<32 || i==127) printf("%.3s ", (i==127) ? "DEL" : low+3*i);
+      else printf("%c ", i);
+    }
+    xputc('\n');
   }
-  writeall(1, toybuf, s-toybuf);
 }
diff --git a/toys/other/blkid.c b/toys/other/blkid.c
index 01b5971..e3badca 100644
--- a/toys/other/blkid.c
+++ b/toys/other/blkid.c
@@ -197,11 +197,12 @@
   if (*toys.optargs && !FLAG(L) && !FLAG(U)) loopfiles(toys.optargs, do_blkid);
   else {
     unsigned int ma, mi, sz, fd;
-    char name[32], device[5+32];
+    char *name = toybuf, *buffer = toybuf+1024, device[32];
     FILE *fp = xfopen("/proc/partitions", "r");
 
-    while (fgets(toybuf, sizeof(toybuf), fp)) {
-      if (sscanf(toybuf, " %u %u %u %31s", &ma, &mi, &sz, name) != 4)
+    while (fgets(buffer, 1024, fp)) {
+      *name = 0;
+      if (sscanf(buffer, " %u %u %u %[^\n ]", &ma, &mi, &sz, name) != 4)
         continue;
 
       sprintf(device, "/dev/%.20s", name);
diff --git a/toys/other/chrt.c b/toys/other/chrt.c
index 1a8222f..6732a71 100644
--- a/toys/other/chrt.c
+++ b/toys/other/chrt.c
@@ -35,6 +35,7 @@
 // musl-libc intentionally broke sched_get_priority_min() and friends in
 // commit 1e21e78bf7a5 because its maintainer didn't like those Linux
 // system calls, so work around it here.
+#include <sys/syscall.h>
 #define sched_get_priority_min(policy) \
   (int)syscall(SYS_sched_get_priority_min, (int)policy)
 #define sched_get_priority_max(policy) \
@@ -47,7 +48,7 @@
   syscall(SYS_sched_setscheduler, (pid_t)pid, (int)scheduler, (void *)param)
 #endif
 
-static char *polnames[] = {
+char *polnames[] = {
   "SCHED_OTHER", "SCHED_FIFO", "SCHED_RR", "SCHED_BATCH", 0, "SCHED_IDLE",
   "SCHED_DEADLINE"
 };
diff --git a/toys/other/chvt.c b/toys/other/chvt.c
new file mode 100644
index 0000000..a93327f
--- /dev/null
+++ b/toys/other/chvt.c
@@ -0,0 +1,34 @@
+/* chvt.c - switch virtual terminals
+ *
+ * Copyright (C) 2008 David Anders <danders@amltd.com>
+
+USE_CHVT(NEWTOY(chvt, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+
+config CHVT
+  bool "chvt"
+  default y
+  help
+    usage: chvt N
+
+    Change to virtual terminal number N. (This only works in text mode.)
+
+    Virtual terminals are the Linux VGA text mode displays, ordinarily
+    switched between via alt-F1, alt-F2, etc. Use ctrl-alt-F1 to switch
+    from X to a virtual terminal, and alt-F6 (or F7, or F8) to get back.
+*/
+
+#include "toys.h"
+
+void chvt_main(void)
+{
+  int vtnum, fd = fd;
+  char *consoles[]={"/dev/console", "/dev/vc/0", "/dev/tty", NULL}, **cc;
+
+  vtnum=atoi(*toys.optargs);
+  for (cc = consoles; *cc; cc++)
+    if (-1 != (fd = open(*cc, O_RDWR))) break;
+
+  // These numbers are VT_ACTIVATE and VT_WAITACTIVE from linux/vt.h
+  if (!*cc || fd < 0 || ioctl(fd, 0x5606, vtnum) || ioctl(fd, 0x5607, vtnum))
+    perror_exit(0);
+}
diff --git a/toys/other/clear.c b/toys/other/clear.c
index 400fe7b..842579f 100644
--- a/toys/other/clear.c
+++ b/toys/other/clear.c
@@ -15,5 +15,5 @@
 
 void clear_main(void)
 {
-  printf("\e[2J\e[H");
+  printf("\033[2J\033[H");
 }
diff --git a/toys/other/eject.c b/toys/other/eject.c
index f275d3b..bd7af56 100644
--- a/toys/other/eject.c
+++ b/toys/other/eject.c
@@ -24,14 +24,13 @@
 #include "toys.h"
 #include <scsi/sg.h>
 #include <scsi/scsi.h>
-#include <linux/cdrom.h>
 
-// SCSI's overcomplicated way of requesting eject
+// The SCSI way of requesting eject
 static void remove_scsi(int fd)
 {
   unsigned i;
   sg_io_hdr_t *header = (sg_io_hdr_t *)(toybuf+64);
-  char sg_driver_cmd[][6] = {
+  char sg_driver_cmd[3][6] = {
     { ALLOW_MEDIUM_REMOVAL, 0, 0, 0, 0, 0 },
     { START_STOP, 0, 0, 0, 1, 0 }, //start the motor
     { START_STOP, 0, 0, 0, 2, 0 } //eject the media
@@ -45,22 +44,35 @@
   header->sbp = (void *)toybuf;
   header->timeout = 2000;
 
-  for (i = 0; i < ARRAY_LEN(sg_driver_cmd); i++) {
+  for (i = 0; i < 3; i++) {
     header->cmdp = (void *)sg_driver_cmd[i];
-    xioctl(fd, SG_IO, header);
+    xioctl(fd, SG_IO, (void *)header);
   }
 
   // force kernel to reread partition table when new disc is inserted
   ioctl(fd, BLKRRPART);
 }
 
+/*
+ * eject main function.
+ */
 void eject_main(void)
 {
-  int fd = xopen(*toys.optargs ? : "/dev/cdrom", O_RDONLY | O_NONBLOCK);
+  int fd, out = 0;
+  char *device_name = "/dev/cdrom";
 
-  if (FLAG(s)) remove_scsi(fd);
-  else if (FLAG(T) && CDS_TRAY_OPEN == ioctl(fd, CDROM_DRIVE_STATUS, toybuf))
-    xioctl(fd, CDROMCLOSETRAY, toybuf);
-  else xioctl(fd, CDROMEJECT, toybuf);
+  if (*toys.optargs) device_name = *toys.optargs;
+
+  fd = xopen(device_name, O_RDONLY | O_NONBLOCK);
+  if (!toys.optflags) xioctl(fd, 0x5309, &out);		// CDROM_EJECT
+  else if (toys.optflags & FLAG_s) remove_scsi(fd);
+  else {
+    if ((toys.optflags & FLAG_T) || (toys.optflags & FLAG_t)) {
+      int rc = ioctl(fd, 0x5326, &out);			// CDROM_DRIVE_STATUS
+      if ((toys.optflags & FLAG_t) || rc == 2)		// CDS_TRAY_OPEN
+        xioctl(fd, 0x5319, &out);			// CDROM_CLOSE_TRAY
+      else xioctl(fd, 0x5309, &out);			// CDROM_EJECT
+    }
+  }
   if (CFG_TOYBOX_FREE) xclose(fd);
 }
diff --git a/toys/other/factor.c b/toys/other/factor.c
index 47e1267..f0e69c5 100644
--- a/toys/other/factor.c
+++ b/toys/other/factor.c
@@ -2,7 +2,7 @@
  *
  * Copyright 2014 Rob Landley <rob@landley.net>
  *
- * See https://man7.org/linux/man-pages/man1/factor.1.html
+ * No standard, but it's in coreutils
 
 USE_FACTOR(NEWTOY(factor, 0, TOYFLAG_USR|TOYFLAG_BIN))
 
@@ -19,7 +19,7 @@
 
 static void factor(char *s)
 {
-  unsigned long long l, ll, lll;
+  unsigned long long l, ll;
 
   for (;;) {
     char *err = s;
@@ -55,8 +55,9 @@
     }
 
     // test odd numbers until square is > remainder or integer wrap.
-    for (ll = 3;; ll += 2) {
-      lll = ll*ll;
+    for (ll=3; ;ll += 2) {
+      long lll = ll*ll;
+
       if (lll>l || lll<ll) {
         if (l>1) printf(" %llu", l);
         break;
@@ -72,11 +73,14 @@
 
 void factor_main(void)
 {
-  char *s = 0, **ss;
-  size_t len = 0;
+  if (toys.optc) {
+    char **ss;
 
-  if (toys.optc) for (ss = toys.optargs; *ss; ss++) factor(*ss);
-  else for (;;) {
+    for (ss = toys.optargs; *ss; ss++) factor(*ss);
+  } else for (;;) {
+    char *s = 0;
+    size_t len = 0;
+
     if (-1 == getline(&s, &len, stdin)) break;
     factor(s);
   }
diff --git a/toys/other/free.c b/toys/other/free.c
index 6be1cdc..d76e050 100644
--- a/toys/other/free.c
+++ b/toys/other/free.c
@@ -2,8 +2,8 @@
  *
  * Copyright 2012 Elie De Brauwer <eliedebrauwer@gmail.com>
 
-// Flag order is signifcant: b-g are units in order, FLAG_h-1 is unit mask
-USE_FREE(NEWTOY(free, "hgmkb[!hgmkb]", TOYFLAG_USR|TOYFLAG_BIN))
+// Flag order is signifcant: b-t are units in order, FLAG_h-1 is unit mask
+USE_FREE(NEWTOY(free, "htgmkb[!htgmkb]", TOYFLAG_USR|TOYFLAG_BIN))
 
 config FREE
   bool "free"
@@ -13,7 +13,7 @@
 
     Display the total, free and used amount of physical memory and swap space.
 
-    -bkmg	Output units (default is bytes)
+    -bkmgt	Output units (default is bytes)
     -h	Human readable (K=1024)
 */
 
diff --git a/toys/other/freeramdisk.c b/toys/other/freeramdisk.c
index 9e6845a..cb0b7f8 100644
--- a/toys/other/freeramdisk.c
+++ b/toys/other/freeramdisk.c
@@ -19,5 +19,9 @@
 
 void freeramdisk_main(void)
 {
-  xioctl(xopen(*toys.optargs, O_RDWR), BLKFLSBUF, 0);
+  int fd;
+
+  fd = xopen(toys.optargs[0], O_RDWR);
+  xioctl(fd, BLKFLSBUF, toys.optargs[0]);
+  if (CFG_TOYBOX_FREE) xclose(fd);
 }
diff --git a/toys/other/fsync.c b/toys/other/fsync.c
index e155b60..d7812b9 100644
--- a/toys/other/fsync.c
+++ b/toys/other/fsync.c
@@ -12,9 +12,9 @@
   help
     usage: fsync [-d] [FILE...]
 
-    Flush disk cache for FILE(s), writing cached data to storage device.
+    Synchronize a file's in-core state with storage device.
 
-    -d	Skip directory info (sync file contents only).
+    -d	Avoid syncing metadata
 */
 
 #define FOR_fsync
@@ -22,7 +22,8 @@
 
 static void do_fsync(int fd, char *name)
 {
-  if (FLAG(d) ? fdatasync(fd) : fsync(fd)) perror_msg("can't sync '%s'", name);
+  if (((toys.optflags & FLAG_d) ? fdatasync(fd) : fsync(fd)))
+    perror_msg("can't sync '%s'", name);
 }
 
 void fsync_main(void)
diff --git a/toys/other/gpiod.c b/toys/other/gpiod.c
deleted file mode 100644
index cc3ce64..0000000
--- a/toys/other/gpiod.c
+++ /dev/null
@@ -1,254 +0,0 @@
-/* gpiod.c - gpio tools
- *
- * Copyright 2021 The Android Open Source Project
- *
- * TODO: gpiomon
-
-USE_GPIODETECT(NEWTOY(gpiodetect, ">0", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOFIND(NEWTOY(gpioinfo, 0, TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOGET(NEWTOY(gpioget, "<2l", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOINFO(NEWTOY(gpiofind, "<1>1", TOYFLAG_USR|TOYFLAG_BIN))
-USE_GPIOSET(NEWTOY(gpioset, "<2l", TOYFLAG_USR|TOYFLAG_BIN))
-
-config GPIODETECT
-  bool "gpiodetect"
-  default y
-  help
-    usage: gpiodetect
-
-    Show all gpio chips' names, labels, and number of lines.
-
-config GPIOFIND
-  bool "gpiofind"
-  default y
-  help
-    usage: gpiofind NAME
-
-    Show the chip and line number for the given line name.
-
-config GPIOINFO
-  bool "gpioinfo"
-  default y
-  help
-    usage: gpioinfo [CHIP...]
-
-    Show gpio chips' lines.
-
-config GPIOGET
-  bool "gpioget"
-  default y
-  help
-    usage: gpioget [-l] CHIP LINE...
-
-    Gets the values of the given lines on CHIP. Use gpiofind to convert line
-    names to numbers.
-
-    -l	Active low
-
-config GPIOSET
-  bool "gpioset"
-  default y
-  help
-    usage: gpioset [-l] CHIP LINE=VALUE...
-
-    Set the lines on CHIP to the given values. Use gpiofind to convert line
-    names to numbers.
-
-    -l	Active low
-*/
-
-#define FOR_gpiodetect
-#define TT this.gpiod
-#include "toys.h"
-
-GLOBALS(
-  struct double_list *chips;
-  int chip_count;
-)
-
-#include <linux/gpio.h>
-
-static int open_chip(char *chip)
-{
-  sprintf(toybuf, isdigit(*chip) ? "/dev/gpiochip%s" : "/dev/%s", chip);
-  return xopen(toybuf, O_RDWR);
-}
-
-static int collect_chips(struct dirtree *node)
-{
-  int n;
-
-  if (!node->parent) return DIRTREE_RECURSE; // Skip the directory itself.
-
-  if (sscanf(node->name, "gpiochip%d", &n)!=1) return 0;
-
-  dlist_add(&TT.chips, strdup(node->name));
-  TT.chip_count++;
-
-  return 0;
-}
-
-static int comparator(const void *a, const void *b)
-{
-  struct double_list *lhs = *(struct double_list **)a,
-    *rhs = *(struct double_list **)b;
-
-  return strcmp(lhs->data, rhs->data);
-}
-
-// call cb() in sorted order
-static void foreach_chip(void (*cb)(char *name))
-{
-  struct double_list **sorted;
-  int i = 0;
-
-  dirtree_flagread("/dev", DIRTREE_SHUTUP, collect_chips);
-  if (!TT.chips) return;
-
-  sorted = xmalloc(TT.chip_count*sizeof(void *));
-  for (i = 0; i<TT.chip_count; i++) sorted[i] = TT.chips = TT.chips->next;
-  qsort(sorted, TT.chip_count, sizeof(void *), comparator);
-
-  for (i = 0; i<TT.chip_count; i++) {
-    sprintf(toybuf, "/dev/%s", sorted[i]->data);
-    cb(toybuf);
-  }
-
-  free(sorted);
-  llist_traverse(&TT.chips, llist_free_arg);
-}
-
-static void gpiodetect(char *path)
-{
-  struct gpiochip_info chip;
-  int fd = xopen(path, O_RDWR);
-
-  xioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &chip);
-  close(fd);
-
-  // gpiochip0 [pinctrl-bcm2711] (58 line)
-  printf("%s [%s] (%u line%s)\n", chip.name, chip.label, chip.lines,
-         chip.lines==1?"":"s");
-}
-
-void gpiodetect_main(void)
-{
-  foreach_chip(gpiodetect);
-}
-
-#define FOR_gpiofind
-#include "generated/flags.h"
-
-static void gpiofind(char *path)
-{
-  struct gpiochip_info chip;
-  struct gpioline_info line;
-  int fd = xopen(path, O_RDWR);
-
-  xioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &chip);
-
-  for (line.line_offset=0; line.line_offset<chip.lines; line.line_offset++) {
-    xioctl(fd, GPIO_GET_LINEINFO_IOCTL, &line);
-    if (!strcmp(line.name, *toys.optargs)) {
-      printf("%s %d\n", chip.name, line.line_offset);
-      break;
-    }
-  }
-  close(fd);
-}
-
-void gpiofind_main(void)
-{
-  foreach_chip(gpiofind);
-}
-
-#define FOR_gpioinfo
-#include "generated/flags.h"
-
-static void gpioinfo_fd(int fd)
-{
-  struct gpiochip_info chip;
-  struct gpioline_info line;
-
-  xioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &chip);
-
-  // gpiochip1 - 8 lines:
-  printf("%s - %d line%s:\n", chip.name, chip.lines, chip.lines==1?"":"s");
-
-  //     line   4: "VDD_SD_IO_SEL" "vdd-sd-io" output active-high [used]
-  // We use slightly wider columns for the name and consumer; just wide enough
-  // to show all Raspberry Pi 400 pins without wrapping an 80-column terminal.
-  for (line.line_offset=0; line.line_offset<chip.lines; line.line_offset++) {
-    xioctl(fd, GPIO_GET_LINEINFO_IOCTL, &line);
-    if (*line.name) sprintf(toybuf, "\"%s\"", line.name);
-    else strcpy(toybuf, "unnamed");
-    if (*line.consumer) sprintf(toybuf+64, "\"%s\"", line.consumer);
-    else strcpy(toybuf+64, "unused");
-    printf("\tline %3d:%18s %18s", line.line_offset, toybuf, toybuf+64);
-    printf(" %sput", line.flags&GPIOLINE_FLAG_IS_OUT?"out":" in");
-    printf(" active-%s", line.flags&GPIOLINE_FLAG_ACTIVE_LOW?"low ":"high");
-    if (line.flags&GPIOLINE_FLAG_KERNEL) printf(" [used]");
-    printf("\n");
-  }
-
-  close(fd);
-}
-
-static void gpioinfo(char *path)
-{
-  gpioinfo_fd(xopen(path, O_RDWR));
-}
-
-void gpioinfo_main(void)
-{
-  int i;
-
-  if (!toys.optc) foreach_chip(gpioinfo);
-  else for (i = 0; toys.optargs[i];i++) gpioinfo_fd(open_chip(toys.optargs[i]));
-}
-
-#define FOR_gpioget
-#include "generated/flags.h"
-
-void gpioget_main(void)
-{
-  struct gpiohandle_request req = { .flags = GPIOHANDLE_REQUEST_INPUT };
-  struct gpiohandle_data data;
-  struct gpiochip_info chip;
-  char **args = toys.optargs;
-  int fd, line;
-
-  fd = open_chip(*args);
-  xioctl(fd, GPIO_GET_CHIPINFO_IOCTL, &chip);
-  if (FLAG(l)) req.flags |= GPIOHANDLE_REQUEST_ACTIVE_LOW;
-  for (args++; *args; args++, req.lines++) {
-    if (req.lines >= GPIOHANDLES_MAX) error_exit("too many requests!");
-    line = atolx_range(*args, 0, chip.lines);
-    req.lineoffsets[req.lines] = line;
-  }
-  xioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
-  xioctl(req.fd, GPIOHANDLE_GET_LINE_VALUES_IOCTL, &data);
-  for (line = 0; line<req.lines; line++)
-    printf("%s%d", " "+(line<1), data.values[line]);
-  xputc('\n');
-}
-
-#define FOR_gpioset
-#include "generated/flags.h"
-
-void gpioset_main(void)
-{
-  struct gpiohandle_request req = { .flags = GPIOHANDLE_REQUEST_OUTPUT };
-  char **args = toys.optargs;
-  int fd, value;
-
-  fd = open_chip(*args);
-  if (FLAG(l)) req.flags |= GPIOHANDLE_REQUEST_ACTIVE_LOW;
-  for (args++; *args; args++, req.lines++) {
-    if (req.lines == GPIOHANDLES_MAX) error_exit("too many requests!");
-    if (sscanf(*args, "%d=%d", req.lineoffsets+req.lines, &value) != 2)
-      perror_exit("not LINE=VALUE: %s", *args);
-    req.default_values[req.lines] = value;
-  }
-  xioctl(fd, GPIO_GET_LINEHANDLE_IOCTL, &req);
-}
diff --git a/toys/other/help.c b/toys/other/help.c
index 1cdbe7e..ab168c6 100644
--- a/toys/other/help.c
+++ b/toys/other/help.c
@@ -30,7 +30,7 @@
     xprintf("<a name=\"%s\"><h1>%s</h1><blockquote><pre>\n", t->name, t->name);
 
   toys.which = t;
-  show_help(stdout, !FLAG(u)+(!!toys.argv[1]<<1));
+  show_help(stdout, FLAG(h)+!FLAG(u));
 
   if (FLAG(h)) xprintf("</blockquote></pre>\n");
 }
diff --git a/toys/other/hexedit.c b/toys/other/hexedit.c
index d340205..398ec15 100644
--- a/toys/other/hexedit.c
+++ b/toys/other/hexedit.c
@@ -2,7 +2,7 @@
  *
  * Copyright 2015 Rob Landley <rob@landley.net>
  *
- * No standard.
+ * No standard
 
 USE_HEXEDIT(NEWTOY(hexedit, "<1>1r", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 
@@ -24,7 +24,6 @@
     ^J or :        Jump (+/- for relative offset, otherwise absolute address)
     ^F or /        Find string (^G/n: next, ^D/p: previous match)
     u              Undo
-    x              Toggle bw/color display
     q/^C/^Q/Esc    Quit
 */
 
@@ -32,17 +31,22 @@
 #include "toys.h"
 
 GLOBALS(
-  char *data, *search, keybuf[16], input[80];
-  long long len, base, pos;
-  int numlen, undo, undolen, mode;
+  char *data;
+  long long len, base;
+  int numlen, undo, undolen;
   unsigned rows, cols;
+  long long pos;
+  char keybuf[16];
+  char input[80];
+  char *search;
 )
 
 #define UNDO_LEN (sizeof(toybuf)/(sizeof(long long)+1))
 
 static void show_error(char *what)
 {
-  printf("\e[%dH\e[41m\e[37m\e[K\e[1m%s\e[0m", TT.rows+1, what);
+  tty_jump(0, TT.rows);
+  printf("\e[41m\e[37m\e[K\e[1m%s\e[0m", what);
   xflush(1);
   msleep(500);
 }
@@ -54,7 +58,10 @@
 
   strcpy(TT.input, initial_value);
   while (1) {
-    printf("\e[%dH\e[K\e[1m%s: \e[0m%s\e[?25h", TT.rows+1, prompt, TT.input);
+    tty_jump(0, TT.rows);
+    tty_esc("K");
+    printf("\e[1m%s: \e[0m%s", prompt, TT.input);
+    tty_esc("?25h");
     xflush(1);
 
     key = scan_key(TT.keybuf, -1);
@@ -64,36 +71,24 @@
       break;
     }
 
-    if (key == 0x7f && (len > 0)) TT.input[--len] = 0;
-    else if (key == 'U'-'@') while (len > 0) TT.input[--len] = 0;
-    else if (key >= ' ' && key < 0x7f && len < sizeof(TT.input))
+    if (key == 0x7f) {
+      if (len > 0) TT.input[--len] = 0;
+    } else if (key == 'U'-'@') {
+      while (len > 0) TT.input[--len] = 0;
+    } else if (key >= ' ' && key < 0x7f && len < sizeof(TT.input)) {
       TT.input[len++] = key;
+    }
   }
-  printf("\e[?25l");
 
+  tty_esc("?25l");
   return yes;
 }
 
 // Render all characters printable, using color to distinguish.
 static void draw_char(int ch)
 {
-  if (ch >= ' ' && ch < 0x7f) {
-    putchar(ch);
-    return;
-  }
-
-  if (TT.mode) {
-    if (ch>127) {
-      printf("\e[2m");
-      ch &= 127;
-    }
-    if (ch<32 || ch==127) {
-      printf("\e[7m");
-      if (ch==127) ch = 32;
-      else ch += 64;
-    }
-    xputc(ch);
-  } else {
+  if (ch >= ' ' && ch < 0x7f) putchar(ch);
+  else {
     if (ch < ' ') printf("\e[31m%c", ch + '@');
     else printf("\e[35m?");
   }
@@ -104,7 +99,8 @@
 {
   char line[80];
 
-  printf("\e[%dH\e[K", TT.rows+1);
+  tty_jump(0, TT.rows);
+  tty_esc("K");
 
   snprintf(line, sizeof(line), "\"%s\"%s, %#llx/%#llx", *toys.optargs,
     FLAG(r) ? " [readonly]" : "", TT.pos, TT.len);
@@ -125,7 +121,7 @@
   if (yy+xx>=TT.len) xx = TT.len-yy;
 
   if (yy<TT.len) {
-    printf("\r\e[%dm%0*llx\e[0m ", 33*!TT.mode, TT.numlen, yy);
+    printf("\r\e[33m%0*llx\e[0m ", TT.numlen, yy);
     for (x=0; x<xx; x++) {
       putchar(' ');
       draw_byte(TT.data[yy+x]);
@@ -134,15 +130,16 @@
     for (x=0; x<xx; x++) draw_char(TT.data[yy+x]);
     printf("%*s", 16-xx, "");
   }
-  printf("\e[K");
+  tty_esc("K");
 }
 
 static void draw_page(void)
 {
   int y;
 
+  tty_jump(0, 0);
   for (y = 0; y<TT.rows; y++) {
-    printf(y ? "\r\n" : "\e[H");
+    if (y) printf("\r\n");
     draw_line(y);
   }
   draw_status();
@@ -155,15 +152,18 @@
   int i;
 
   // Display cursor in hex area.
-  printf("\e[%u;%uH\e[%dm", yy+1, TT.numlen+3*(xx+1), 7*(side!=2));
+  tty_jump(2+TT.numlen+3*xx, yy);
+  tty_esc("0m");
+  if (side!=2) tty_esc("7m");
   if (side>1) draw_byte(cc);
   else for (i=0; i<2;) {
-    if (side==i) printf("\e[32m");
+    if (side==i) tty_esc("32m");
     printf("%x", (cc>>(4*(1&++i)))&15);
   }
+  tty_jump(TT.numlen+17*3+xx, yy);
 
   // Display cursor in text area.
-  printf("\e[7m\e[%u;%uH"+4*(side==2), yy+1, 1+TT.numlen+17*3+xx);
+  if (side!=2) tty_esc("7m");
   draw_char(cc);
 }
 
@@ -201,7 +201,9 @@
   if (TT.rows) TT.rows--;
   xsignal(SIGWINCH, generic_signal);
   sigatexit(tty_sigreset);
-  dprintf(1, "\e[0m\e[?25l");
+  tty_esc("0m");
+  tty_esc("?25l");
+  xflush(1);
   xset_terminal(1, 1, 0, 0);
 
   if (access(*toys.optargs, W_OK)) toys.optflags |= FLAG_r;
@@ -223,30 +225,29 @@
     x = TT.pos&15;
     y = TT.pos/16;
 
-    // scroll up
     while (y<TT.base) {
       if (TT.base-y>(TT.rows/2)) {
         TT.base = y;
         draw_page();
       } else {
         TT.base--;
-        printf("\e[H\e[1L");
+        tty_jump(0, 0);
+        tty_esc("1L");
         draw_line(0);
       }
     }
-
-    // scroll down
     while (y>=TT.base+TT.rows) {
       if (y-(TT.base+TT.rows)>(TT.rows/2)) {
         TT.base = y-TT.rows-1;
         draw_page();
       } else {
         TT.base++;
-        printf("\e[H\e[1M\e[%uH", TT.rows);
+        tty_jump(0, 0);
+        tty_esc("1M");
+        tty_jump(0, TT.rows-1);
         draw_line(TT.rows-1);
       }
     }
-
     draw_status();
     y -= TT.base;
 
@@ -266,13 +267,6 @@
       continue;
     }
 
-    if (key == 'x') {
-      TT.mode = !TT.mode;
-      printf("\e[0m");
-      draw_page();
-      continue;
-    }
-
     // Various popular ways to quit...
     if (key==-1||key==('C'-'@')||key==('Q'-'@')||key==27||key=='q') break;
     highlight(x, y, 2);
@@ -359,8 +353,8 @@
         if (TT.pos > TT.len-1) TT.pos = TT.len-1;
         TT.base = TT.pos/16;
         draw_page();
-      } else if (key==KEY_HOME) TT.pos &= ~0xf;
-      else if (key==KEY_END) TT.pos |= 0xf;
+      } else if (key==KEY_HOME) TT.pos = TT.pos & ~0xf;
+      else if (key==KEY_END) TT.pos = TT.pos | 0xf;
       else if (key==(KEY_CTRL|KEY_HOME)) TT.pos = 0;
       else if (key==(KEY_CTRL|KEY_END)) TT.pos = TT.len-1;
     }
diff --git a/toys/other/i2ctools.c b/toys/other/i2ctools.c
index bce160d..cd1b892 100644
--- a/toys/other/i2ctools.c
+++ b/toys/other/i2ctools.c
@@ -11,7 +11,7 @@
  * TODO: i2cget non-byte modes? default to current read address?
  * TODO: i2cset -r? -m MASK? c/s modes, p mode modifier?
 
-USE_I2CDETECT(NEWTOY(i2cdetect, ">3aFlqry[!qr]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_I2CDETECT(NEWTOY(i2cdetect, ">3aFly", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CDUMP(NEWTOY(i2cdump, "<2>2fy", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CGET(NEWTOY(i2cget, "<3>3fy", TOYFLAG_USR|TOYFLAG_BIN))
 USE_I2CSET(NEWTOY(i2cset, "<4fy", TOYFLAG_USR|TOYFLAG_BIN))
@@ -20,16 +20,15 @@
   bool "i2cdetect"
   default y
   help
-    usage: i2cdetect [-aqry] BUS [FIRST LAST]
+    usage: i2cdetect [-ary] BUS [FIRST LAST]
     usage: i2cdetect -F BUS
     usage: i2cdetect -l
 
     Detect i2c devices.
 
-    -a	All addresses (0x00-0x7f rather than 0x03-0x77 or FIRST-LAST)
+    -a	All addresses (0x00-0x7f rather than 0x03-0x77)
     -F	Show functionality
-    -l	List available buses
-    -q	Probe with SMBus Quick Write (default)
+    -l	List all buses
     -r	Probe with SMBus Read Byte
     -y	Answer "yes" to confirmation prompts (for script use)
 
@@ -68,7 +67,6 @@
 */
 
 #define FOR_i2cdetect
-#define TT this.i2ctools
 #include "toys.h"
 
 #include <linux/i2c.h>
@@ -78,7 +76,7 @@
 {
   va_list va;
 
-  if (FLAG(y)) return;
+  if (toys.optflags & FLAG_y) return;
 
   va_start(va, fmt);
   vfprintf(stderr, fmt, va);
@@ -108,26 +106,23 @@
 
 static int i2c_read_byte(int fd, int addr, int *byte)
 {
+  struct i2c_smbus_ioctl_data ioctl_data;
   union i2c_smbus_data data;
-  struct i2c_smbus_ioctl_data ioctl_data = { .read_write = I2C_SMBUS_READ,
-    .size = I2C_SMBUS_BYTE_DATA, .command = addr, .data = &data };
 
   memset(&data, 0, sizeof(data));
-  if (ioctl(fd, I2C_SMBUS, &ioctl_data)==-1) return -1;
+  ioctl_data.read_write = I2C_SMBUS_READ;
+  ioctl_data.size = I2C_SMBUS_BYTE_DATA;
+  ioctl_data.command = addr;
+  ioctl_data.data = &data;
+  if (ioctl(fd, I2C_SMBUS, &ioctl_data) == -1) return -1;
   *byte = data.byte;
   return 0;
 }
 
-static int i2c_quick_write(int fd, int addr)
-{
-  struct i2c_smbus_ioctl_data ioctl_data = { .read_write = I2C_SMBUS_QUICK,
-    .size = 0, .command = addr };
-
-  return ioctl(fd, I2C_SMBUS, &ioctl_data);
-}
-
 static void i2cdetect_dash_F(int bus)
 {
+  size_t i;
+
   struct { int mask; const char *name; } funcs[] = {
     {I2C_FUNC_I2C, "I2C"},
     {I2C_FUNC_SMBUS_QUICK, "SMBus Quick Command"},
@@ -145,12 +140,13 @@
     {I2C_FUNC_SMBUS_WRITE_I2C_BLOCK, "I2C Write Block"},
     {I2C_FUNC_SMBUS_READ_I2C_BLOCK, "I2C Read Block"},
   };
-  unsigned long sup = i2c_get_funcs(bus);
-  int i;
+  unsigned long supported = i2c_get_funcs(bus);
 
   printf("Functionalities implemented by %s:\n", toybuf);
-  for (i = 0; i < ARRAY_LEN(funcs); ++i)
-    printf("%-32s %s\n", funcs[i].name, (sup & funcs[i].mask) ? "yes" : "no");
+  for (i = 0; i < ARRAY_LEN(funcs); ++i) {
+    printf("%-32s %s\n", funcs[i].name,
+           (supported & funcs[i].mask) ? "yes" : "no");
+  }
 }
 
 static int i2cdetect_dash_l(struct dirtree *node)
@@ -162,7 +158,7 @@
 
   if (!node->parent) return DIRTREE_RECURSE; // Skip the directory itself.
 
-  if (sscanf(node->name, "i2c-%d", &bus)!=1) return 0;
+  if (sscanf(node->name, "i2c-%d", &bus) != 1) return 0;
   funcs = i2c_get_funcs(bus);
 
   fname = dirtree_path(node, &suffix_len);
@@ -171,9 +167,10 @@
   free(fname);
   if ((p = strchr(toybuf, '\n'))) *p = 0;
 
-  // "i2c-1	i2c	Synopsys DesignWare I2C adapter		I2C adapter"
+  // "i2c-1	i2c       	Synopsys DesignWare I2C adapter 	I2C adapter"
   printf("%s\t%-10s\t%-32s\t%s\n", node->name,
-         (funcs & I2C_FUNC_I2C) ? "i2c" : "?", toybuf,
+         (funcs & I2C_FUNC_I2C) ? "i2c" : "?",
+         toybuf,
          (funcs & I2C_FUNC_I2C) ? "I2C Adapter" : "?");
 
   return 0;
@@ -181,23 +178,23 @@
 
 void i2cdetect_main(void)
 {
-  if (FLAG(l)) {
+  if (toys.optflags & FLAG_l) {
     if (toys.optc) error_exit("-l doesn't take arguments");
-    dirtree_flagread("/sys/class/i2c-dev", DIRTREE_SHUTUP, i2cdetect_dash_l);
-  } else if (FLAG(F)) {
+    dirtree_read("/sys/class/i2c-dev", i2cdetect_dash_l);
+  } else if (toys.optflags & FLAG_F) {
     if (toys.optc != 1) error_exit("-F BUS");
     i2cdetect_dash_F(atolx_range(*toys.optargs, 0, INT_MAX));
   } else {
     int bus, first = 0x03, last = 0x77, fd, row, addr, byte;
 
-    if (FLAG(a)) {
+    if (toys.optflags & FLAG_a) {
       first = 0x00;
       last = 0x7f;
     }
 
-    if (toys.optc!=1 && toys.optc!=3) help_exit("Needs 1 or 3 arguments");
+    if (toys.optc != 1 && toys.optc != 3) error_exit("bad args");
     bus = atolx_range(*toys.optargs, 0, INT_MAX);
-    if (toys.optc==3) {
+    if (toys.optc == 3) {
       first = atolx_range(toys.optargs[1], 0, 0x7f);
       last = atolx_range(toys.optargs[2], 0, 0x7f);
       if (first > last) error_exit("first > last");
@@ -209,8 +206,8 @@
     printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f\n");
     for (row = 0; row <= 0x70; row += 16) {
       xprintf("%02x:", row & 0xf0);
-      for (addr = row; addr<row+16; ++addr) {
-        if (addr<first || addr>last) printf("   ");
+      for (addr = row; addr < row + 16; ++addr) {
+        if (addr < first || addr > last) printf("   ");
         else {
           if (ioctl(fd, I2C_SLAVE, addr) == -1) {
             if (errno == EBUSY) {
@@ -219,8 +216,7 @@
             }
             perror_exit("ioctl(I2C_SLAVE)");
           }
-          if ((FLAG(r) ? i2c_read_byte(fd, addr, &byte)
-                       : i2c_quick_write(fd, addr)) == -1) xprintf(" --");
+          if (i2c_read_byte(fd, addr, &byte) == -1) xprintf(" --");
           else xprintf(" %02x", addr);
         }
       }
@@ -230,6 +226,7 @@
   }
 }
 
+#define CLEANUP_i2cdetect
 #define FOR_i2cdump
 #include "generated/flags.h"
 
@@ -241,16 +238,13 @@
 
   confirm("Dump chip 0x%02x on bus %d?", chip, bus);
 
-  fd = i2c_open(bus, FLAG(f) ? I2C_SLAVE_FORCE : I2C_SLAVE, chip);
+  fd = i2c_open(bus, (toys.optflags&FLAG_f)?I2C_SLAVE_FORCE:I2C_SLAVE, chip);
   printf("     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f    0123456789abcdef\n");
-  for (row = 0; row<=0xf0; row += 16) {
+  for (row = 0; row <= 0xf0; row += 16) {
     xprintf("%02x:", row & 0xf0);
-    for (addr = row; addr<row+16; ++addr) {
-      if (!i2c_read_byte(fd, addr, &byte)) printf(" %02x", byte);
-      else {
-        printf(" XX");
-        byte = 'X';
-      }
+    for (addr = row; addr < row + 16; ++addr) {
+      if (i2c_read_byte(fd, addr, &byte) == -1) perror_exit("i2c_read_byte");
+      printf(" %02x", byte);
       toybuf[addr-row] = isprint(byte) ? byte : (byte ? '?' : '.');
     }
     printf("    %16.16s\n", toybuf);
@@ -258,6 +252,7 @@
   close(fd);
 }
 
+#define CLEANUP_i2cdump
 #define FOR_i2cget
 #include "generated/flags.h"
 
@@ -270,12 +265,13 @@
 
   confirm("Read register 0x%02x from chip 0x%02x on bus %d?", addr, chip, bus);
 
-  fd = i2c_open(bus, FLAG(f) ? I2C_SLAVE_FORCE : I2C_SLAVE, chip);
-  if (i2c_read_byte(fd, addr, &byte)==-1) perror_exit("i2c_read_byte");
+  fd = i2c_open(bus, (toys.optflags&FLAG_f)?I2C_SLAVE_FORCE:I2C_SLAVE, chip);
+  if (i2c_read_byte(fd, addr, &byte) == -1) perror_exit("i2c_read_byte");
   printf("0x%02x\n", byte);
   close(fd);
 }
 
+#define CLEANUP_i2cget
 #define FOR_i2cset
 #include "generated/flags.h"
 
@@ -290,24 +286,26 @@
   union i2c_smbus_data data;
 
   memset(&data, 0, sizeof(data));
-  if (strlen(mode)!=1) help_exit("mode too long");
-  if (*mode=='b' && toys.optc==5) {
+  if (strlen(mode) != 1) help_exit("mode too long");
+  if (*mode == 'b' && toys.optc == 5) {
     ioctl_data.size = I2C_SMBUS_BYTE_DATA;
     data.byte = atolx_range(toys.optargs[3], 0, 0xff);
-  } else if (*mode=='w' && toys.optc==5) {
+  } else if (*mode == 'w' && toys.optc == 5) {
     ioctl_data.size = I2C_SMBUS_WORD_DATA;
     data.word = atolx_range(toys.optargs[3], 0, 0xffff);
-  } else if (*mode=='i' && toys.optc>=5) {
-    if (toys.optc-4>I2C_SMBUS_BLOCK_MAX) error_exit("too much data");
+  } else if (*mode == 'i' && toys.optc >= 5) {
+    if (toys.optc - 4 > I2C_SMBUS_BLOCK_MAX) error_exit("too much data");
     ioctl_data.size = I2C_SMBUS_I2C_BLOCK_DATA;
-    for (i = 0; i<toys.optc-4; ++i)
+    for (i = 0; i < toys.optc - 4; ++i)
       data.block[i+1] = atolx_range(toys.optargs[3+i], 0, 0xff);
-    data.block[0] = toys.optc-4;
-  } else help_exit("syntax error");
+    data.block[0] = toys.optc - 4;
+  } else {
+    help_exit("syntax error");
+  }
 
   confirm("Write register 0x%02x from chip 0x%02x on bus %d?", addr, chip, bus);
 
-  fd = i2c_open(bus, FLAG(f) ? I2C_SLAVE_FORCE : I2C_SLAVE, chip);
+  fd = i2c_open(bus, (toys.optflags&FLAG_f)?I2C_SLAVE_FORCE:I2C_SLAVE, chip);
   ioctl_data.read_write = I2C_SMBUS_WRITE;
   ioctl_data.command = addr;
   ioctl_data.data = &data;
diff --git a/toys/other/insmod.c b/toys/other/insmod.c
index 176e5a6..9a3f595 100644
--- a/toys/other/insmod.c
+++ b/toys/other/insmod.c
@@ -8,13 +8,21 @@
   bool "insmod"
   default y
   help
-    usage: insmod MODULE [OPTION...]
+    usage: insmod MODULE [MODULE_OPTIONS]
 
     Load the module named MODULE passing options if given.
 */
 
 #include "toys.h"
 
+#include <sys/syscall.h>
+#ifdef SYS_finit_module
+#define finit_module(fd, opts, flags) syscall(SYS_finit_module, fd, opts, flags)
+#else
+#define finit_module(a, b, c) (errno = ENOSYS)
+#endif
+#define init_module(mod, len, opts) syscall(SYS_init_module, mod, len, opts)
+
 void insmod_main(void)
 {
   int fd = xopenro(*toys.optargs);
@@ -28,15 +36,15 @@
     strcat(toybuf, " ");
   }
 
-  // finit_module doesn't work on stdin, so we fall back to init_module...
-  rc = syscall(SYS_finit_module, fd, toybuf, 0);
+  // finit_module was new in Linux 3.8, and doesn't work on stdin,
+  // so we fall back to init_module if necessary.
+  rc = finit_module(fd, toybuf, 0);
   if (rc && (fd == 0 || errno == ENOSYS)) {
     off_t len = 0;
     char *path = !strcmp(*toys.optargs, "-") ? "/dev/stdin" : *toys.optargs;
     char *buf = readfileat(AT_FDCWD, path, NULL, &len);
 
-    if (!buf) perror_exit("couldn't read %s", path);
-    rc = syscall(SYS_init_module, buf, len, toybuf);
+    rc = init_module(buf, len, toybuf);
     if (CFG_TOYBOX_FREE) free(buf);
   }
 
diff --git a/toys/other/ionice.c b/toys/other/ionice.c
index db3a6f4..f356c5f 100644
--- a/toys/other/ionice.c
+++ b/toys/other/ionice.c
@@ -6,7 +6,7 @@
  * Documentation/block/ioprio.txt in the linux source.
 
 USE_IONICE(NEWTOY(ionice, "^tc#<0>3=2n#<0>7=5p#", TOYFLAG_USR|TOYFLAG_BIN))
-USE_IORENICE(NEWTOY(iorenice, "<1>3", TOYFLAG_USR|TOYFLAG_BIN))
+USE_IORENICE(NEWTOY(iorenice, "?<1>3", TOYFLAG_USR|TOYFLAG_BIN))
 
 config IONICE
   bool "ionice"
@@ -37,6 +37,7 @@
 
 #define FOR_ionice
 #include "toys.h"
+#include <sys/syscall.h>
 
 GLOBALS(
   long p, n, c;
@@ -59,12 +60,11 @@
   if (!TT.p && !toys.optc) error_exit("Need -p or COMMAND");
   if (toys.optflags == FLAG_p) {
     int p = ioprio_get();
-
     xprintf("%s: prio %d\n",
       (char *[]){"unknown", "Realtime", "Best-effort", "Idle"}[(p>>13)&3],
       p&7);
   } else {
-    if (-1 == ioprio_set() && !FLAG(t)) perror_exit("set");
+    if (-1 == ioprio_set() && !(toys.optflags&FLAG_t)) perror_exit("set");
     if (!TT.p) xexec(toys.optargs);
   }
 }
diff --git a/toys/other/losetup.c b/toys/other/losetup.c
index ce84c1e..7b8aed4 100644
--- a/toys/other/losetup.c
+++ b/toys/other/losetup.c
@@ -103,9 +103,9 @@
     }
   // Associate file with this device?
   } else if (file) {
-    char *f_path = xabspath(file, ABS_PATH);
+    char *f_path = xabspath(file, 1);
 
-    if (!f_path) perror_exit("%s", file); // already opened but if deleted since
+    if (!f_path) perror_exit("file"); // already opened, but if deleted since...
     if (ioctl(lfd, LOOP_SET_FD, ffd)) {
       free(f_path);
       if (racy && errno == EBUSY) return 1;
diff --git a/toys/other/lsattr.c b/toys/other/lsattr.c
index 31d7f43..547012e 100644
--- a/toys/other/lsattr.c
+++ b/toys/other/lsattr.c
@@ -63,40 +63,33 @@
 #include <linux/fs.h>
 
 GLOBALS(
-  long v, p;
+  long v;
+  long p;
 
-  unsigned add, rm, set;
+  long add, rm, set;
   // !add and !rm tell us whether they were used, but `chattr =` is meaningful.
   int have_set;
 )
 
-// Added more recently than the 7 year support horizon. TODO: remove
-#ifndef FS_INLINE_DATA_FL
-#define FS_INLINE_DATA_FL 0x10000000 // commit 68ce7bfcd995a 2016-01-08
-#endif
-#ifndef FS_PROJINHERIT_FL
-#define FS_PROJINHERIT_FL 0x20000000 // commit 8b4953e13f4c5 2015-10-17
-#endif
-#ifndef FS_CASEFOLD_FL
-#define FS_CASEFOLD_FL    0x40000000 // commit 71e90b4654a92 2019-07-23
-#endif
-#ifndef FS_VERITY_FL
-#define FS_VERITY_FL      0x00100000 // commit fe9918d3b228b 2019-07-22
-#endif
+#define FS_PROJINHERT_FL 0x20000000 // Linux 4.5
+#define FS_CASEFOLD_FL   0x40000000 // Linux 5.4
+#define FS_VERITY_FL     0x00100000 // Linux 5.4
 
-#ifndef FS_IOC_FSGETXATTR
-// commit 334e580a6f97e 2016-01-04
-struct fsxattr {
-  unsigned fsx_xflags, fsx_extsize, fsx_nextents, fsx_projid, fsx_cowextsize;
+// Linux 4.5
+struct fsxattr_4_5 {
+  unsigned fsx_xflags;
+  unsigned fsx_extsize;
+  unsigned fsx_nextents;
+  unsigned fsx_projid;
+  unsigned fsx_cowextsize;
   char fsx_pad[8];
 };
-#define FS_IOC_FSGETXATTR _IOR('X', 31, struct fsxattr)
-#define FS_IOC_FSSETXATTR _IOW('X', 32, struct fsxattr)
-#endif
+#define FS_IOC_FSGETXATTR_4_5 _IOR('X', 31, struct fsxattr_4_5)
+#define FS_IOC_FSSETXATTR_4_5 _IOW('X', 32, struct fsxattr_4_5)
 
 static struct ext2_attr {
   char *name;
-  unsigned flag;
+  unsigned long flag;
   char opt;
 } e2attrs[] = {
   // Do not sort! These are in the order that lsattr outputs them.
@@ -125,7 +118,7 @@
 };
 
 // Get file flags on a Linux second extended file system.
-static int ext2_getflag(int fd, struct stat *sb, unsigned *flag)
+static int ext2_getflag(int fd, struct stat *sb, unsigned long *flag)
 {
   if(!S_ISREG(sb->st_mode) && !S_ISDIR(sb->st_mode)) {
     errno = EOPNOTSUPP;
@@ -134,7 +127,7 @@
   return (ioctl(fd, FS_IOC_GETFLAGS, (void*)flag));
 }
 
-static char *attrstr(unsigned attrs, int full)
+static char *attrstr(unsigned long attrs, int full)
 {
   struct ext2_attr *a = e2attrs;
   char *s = toybuf;
@@ -142,32 +135,31 @@
   for (; a->name; a++)
     if (attrs & a->flag) *s++ = a->opt;
     else if (full) *s++ = '-';
-  *s = 0;
-
+  *s = '\0';
   return toybuf;
 }
 
 static void print_file_attr(char *path)
 {
-  unsigned flag = 0, version = 0;
-  int fd = -1;
+  unsigned long flag = 0, version = 0;
+  int fd;
   struct stat sb;
 
   if (!stat(path, &sb) && !S_ISREG(sb.st_mode) && !S_ISDIR(sb.st_mode)) {
     errno = EOPNOTSUPP;
-    goto error;
+    goto LABEL1;
   }
-  if (-1 == (fd=open(path, O_RDONLY | O_NONBLOCK))) goto error;
+  if (-1 == (fd=open(path, O_RDONLY | O_NONBLOCK))) goto LABEL1;
 
   if (FLAG(p)) {
-    struct fsxattr fsx;
+    struct fsxattr_4_5 fsx;
 
-    if (ioctl(fd, FS_IOC_FSGETXATTR, &fsx)) goto error;
+    if (ioctl(fd, FS_IOC_FSGETXATTR_4_5, &fsx)) goto LABEL2;
     xprintf("%5u ", fsx.fsx_projid);
   }
   if (FLAG(v)) {
-    if (ioctl(fd, FS_IOC_GETVERSION, (void*)&version) < 0) goto error;
-    xprintf("%-10u ", version);
+    if (ioctl(fd, FS_IOC_GETVERSION, (void*)&version) < 0) goto LABEL2;
+    xprintf("%-10lu ", version);
   }
 
   if (ext2_getflag(fd, &sb, &flag) < 0) perror_msg("reading flags '%s'", path);
@@ -189,10 +181,10 @@
       xputc('\n');
     } else xprintf("%s %s\n", attrstr(flag, 1), path);
   }
-  path = 0;
-error:
   xclose(fd);
-  if (path) perror_msg("reading '%s'", path);
+  return;
+LABEL2: xclose(fd);
+LABEL1: perror_msg("reading '%s'", path);
 }
 
 // Get directory information.
@@ -236,11 +228,12 @@
 }
 
 // Switch gears from lsattr to chattr.
+#define CLEANUP_lsattr
 #define FOR_chattr
 #include "generated/flags.h"
 
 // Set file flags on a Linux second extended file system.
-static inline int ext2_setflag(int fd, struct stat *sb, unsigned flag)
+static inline int ext2_setflag(int fd, struct stat *sb, unsigned long flag)
 {
   if (!S_ISREG(sb->st_mode) && !S_ISDIR(sb->st_mode)) {
     errno = EOPNOTSUPP;
@@ -249,11 +242,12 @@
   return (ioctl(fd, FS_IOC_SETFLAGS, (void*)&flag));
 }
 
-static unsigned get_flag_val(char ch)
+static unsigned long get_flag_val(char ch)
 {
   struct ext2_attr *ptr = e2attrs;
 
-  for (; ptr->name; ptr++) if (ptr->opt == ch) return ptr->flag;
+  for (; ptr->name; ptr++)
+    if (ptr->opt == ch) return ptr->flag;
   help_exit("bad '%c'", ch);
 }
 
@@ -287,7 +281,7 @@
 static int update_attr(struct dirtree *root)
 {
   char *fpath = NULL;
-  int vv = TT.v, fd;
+  int v = TT.v, fd;
 
   if (!dirtree_notdotdot(root)) return 0;
 
@@ -308,7 +302,7 @@
 
   // Any potential flag changes?
   if (TT.have_set | TT.add | TT.rm) {
-    unsigned orig, new;
+    unsigned long orig, new;
 
     // Read current flags.
     if (ext2_getflag(fd, &(root->st), &orig) < 0) {
@@ -332,15 +326,15 @@
 
   // (FS_IOC_SETVERSION works all the way back to 2.6, but FS_IOC_FSSETXATTR
   // isn't available until 4.5.)
-  if (FLAG(v) && (ioctl(fd, FS_IOC_SETVERSION, &vv)<0))
-    perror_msg("%s: setting version to %d failed", fpath, vv);
+  if (FLAG(v) && (ioctl(fd, FS_IOC_SETVERSION, &v)<0))
+    perror_msg("%s: setting version to %d failed", fpath, v);
 
   if (FLAG(p)) {
-    struct fsxattr fsx;
-    int fail = ioctl(fd, FS_IOC_FSGETXATTR, &fsx);
+    struct fsxattr_4_5 fsx;
+    int fail = ioctl(fd, FS_IOC_FSGETXATTR_4_5, &fsx);
 
     fsx.fsx_projid = TT.p;
-    if (fail || ioctl(fd, FS_IOC_FSSETXATTR, &fsx))
+    if (fail || ioctl(fd, FS_IOC_FSSETXATTR_4_5, &fsx))
       perror_msg("%s: setting projid to %u failed", fpath, fsx.fsx_projid);
   }
 
diff --git a/toys/other/lspci.c b/toys/other/lspci.c
new file mode 100644
index 0000000..4c115fd
--- /dev/null
+++ b/toys/other/lspci.c
@@ -0,0 +1,128 @@
+/*
+ * lspci - written by Isaac Dunham
+
+USE_LSPCI(NEWTOY(lspci, "emkn"USE_LSPCI_TEXT("@i:"), TOYFLAG_USR|TOYFLAG_BIN))
+
+config LSPCI
+  bool "lspci"
+  default y
+  help
+    usage: lspci [-ekm]
+
+    List PCI devices.
+
+    -e	Print all 6 digits in class
+    -k	Print kernel driver
+    -m	Machine readable format
+
+config LSPCI_TEXT
+  bool "lspci readable output"
+  depends on LSPCI
+  default y
+  help
+    usage: lspci [-n] [-i FILE ]
+
+    -n	Numeric output (repeat for readable and numeric)
+    -i	PCI ID database (default /usr/share/misc/pci.ids)
+
+*/
+
+#define FOR_lspci
+#include "toys.h"
+
+GLOBALS(
+  char *i;
+  long n;
+
+  FILE *db;
+)
+
+static int do_lspci(struct dirtree *new)
+{
+  char *p = toybuf, *vendor = toybuf+9, *device = toybuf+18,
+       driver[256], *vbig = 0, *dbig = 0, **fields;
+  int dirfd;
+
+  if (!new->parent) return DIRTREE_RECURSE;
+
+  // Parse data out of /proc
+
+  if (-1 == (dirfd = openat(dirtree_parentfd(new), new->name, O_RDONLY)))
+    return 0;
+
+  *driver = 0;
+  if (toys.optflags & FLAG_k)
+    readlinkat0(dirfd, "driver", driver, sizeof(driver));
+
+  for (fields = (char*[]){"class", "vendor", "device", 0}; *fields; fields++) {
+    int fd, size = 6 + 2*((toys.optflags & FLAG_e) && p == toybuf);
+    *p = 0;
+
+    if (-1 == (fd = openat(dirfd, *fields, O_RDONLY))) {
+      close(dirfd);
+      return 0;
+    }
+    xreadall(fd, p, size);
+    memmove(p, p+2, size -= 2);
+    p[size] = 0;
+    close(fd);
+    p += 9;
+  }
+
+  close(dirfd);
+
+  // Lookup/display data from pci.ids?
+
+  if (CFG_LSPCI_TEXT && TT.db) {
+    if (TT.n != 1) {
+      char *s;
+
+      fseek(TT.db, 0, SEEK_SET);
+      while (!vbig || !dbig) {
+        s = p;
+        if (!fgets(s, sizeof(toybuf)-(p-toybuf)-1, TT.db)) break;
+        while (isspace(*s)) s++;
+        if (*s == '#') continue;
+        if (vbig && s == p) break;
+        if (strstart(&s, vbig ? device : vendor)) {
+          if (vbig) dbig = s+2;
+          else vbig = s+2;
+          s += strlen(s);
+          s[-1] = 0; // trim ending newline
+          p = s + 1;
+        }
+      }
+    }
+
+    if (TT.n > 1) {
+      printf((toys.optflags & FLAG_m)
+        ? "%s, \"%s\" \"%s [%s]\" \"%s [%s]\""
+        : "%s Class %s: %s [%s] %s [%s]",
+        new->name+5, toybuf, vbig ? vbig : "", vendor,
+        dbig ? dbig : "", device);
+
+      goto driver;
+    }
+  }
+
+  printf((toys.optflags & FLAG_m) ? "%s \"%s\" \"%s\" \"%s\""
+    : "%s Class %s: %s:%s", new->name+5, toybuf, 
+    vbig ? vbig : vendor, dbig ? dbig : device);
+
+driver:
+  if (*driver)
+    printf((toys.optflags & FLAG_m) ? " \"%s\"" : " %s", basename(driver));
+  xputc('\n');
+
+  return 0;
+}
+
+void lspci_main(void)
+{
+  if (CFG_LSPCI_TEXT && TT.n != 1) {
+    if (!TT.i) TT.i = "/usr/share/misc/pci.ids";
+    if (!(TT.db = fopen(TT.i, "r"))) perror_msg("%s", TT.i);
+  }
+
+  dirtree_read("/sys/bus/pci/devices", do_lspci);
+}
diff --git a/toys/other/lsusb.c b/toys/other/lsusb.c
index 836c4f6..031dbd9 100644
--- a/toys/other/lsusb.c
+++ b/toys/other/lsusb.c
@@ -1,237 +1,49 @@
 /* lsusb.c - list available USB devices
  *
  * Copyright 2013 Andre Renaud <andre@bluewatersys.com>
- * Copyright 2013 Isaac Dunham <ibid.ag@gmail.com>
 
-USE_LSUSB(NEWTOY(lsusb, "i:", TOYFLAG_USR|TOYFLAG_BIN))
-USE_LSPCI(NEWTOY(lspci, "emkn@i:", TOYFLAG_USR|TOYFLAG_BIN))
-
-config LSPCI
-  bool "lspci"
-  default y
-  help
-    usage: lspci [-ekmn] [-i FILE]
-
-    List PCI devices.
-
-    -e  Extended (6 digit) class
-    -i  ID database (default /etc/pci.ids[.gz])
-    -k  Show kernel driver
-    -m  Machine readable
-    -n  Numeric output (-nn for both)
+USE_LSUSB(NEWTOY(lsusb, NULL, TOYFLAG_USR|TOYFLAG_BIN))
 
 config LSUSB
   bool "lsusb"
   default y
   help
-    usage: lsusb [-i]
+    usage: lsusb
 
     List USB hosts/devices.
-
-    -i	ID database (default /etc/usb.ids[.gz])
 */
 
-#define FOR_lsusb
 #include "toys.h"
 
-GLOBALS(
-  char *i;
-  long n;
-
-  void *ids, *class;
-  int count;
-)
-
-struct dev_ids {
-  struct dev_ids *next, *child;
-  int id;
-  char name[];
-};
-
-struct scanloop {
-  char *pattern;
-  void *d1, *d2;
-};
-
-// Common function to read uevent file under /proc for both pci and usb
-// note that %s is omitted (because pointer is into toybuf, avoiding copy).
-static int scan_uevent(struct dirtree *new, int len, struct scanloop *sl)
+static int list_device(struct dirtree *new)
 {
-  int ii, count = 0;
-  off_t flen = sizeof(toybuf);
-  char *ss, *yy;
-
-  // Read data
-  if (*new->name == '.') return 0;
-  sprintf(toybuf, "%s/uevent", new->name);
-  if (!readfileat(dirtree_parentfd(new), ss = toybuf, toybuf, &flen)) return 0;
-
-  // Loop over lines
-  while ((flen = strcspn(ss, "\n"))) {
-    if (ss[flen]) ss[flen++] = 0;
-    yy = ss+flen;
-
-    // Try each pattern
-    for (ii = 0; ii<len; ii++) {
-      if (strchr(sl[ii].pattern, '%')) {
-        if (2-!sl[ii].d2==sscanf(ss, sl[ii].pattern, sl[ii].d1, sl[ii].d2))
-          break;
-      } else if (strstart(&ss, sl[ii].pattern)) {
-        *(void **)sl[ii].d1 = ss;
-        break;
-      }
-    }
-    if (ii!=len) count++;
-    ss = yy;
-  }
-
-  return count;
-}
-
-static void get_names(struct dev_ids *ids, int id1, int id2,
-  char **name1, char **name2)
-{
-  // Look up matching dev_ids (if any)
-  *name1 = *name2 = "";
-  for (; ids; ids = ids->next) {
-    if (id1 != ids->id) continue;
-    *name1 = ids->name;
-    for (ids = ids->child; ids; ids = ids->next) {
-      if (id2 != ids->id) continue;
-      *name2 = ids->name;
-      return;
-    }
-    return;
-  }
-}
-
-// Search for pci.ids or usb.ids and return parsed structure or NULL
-struct dev_ids *parse_dev_ids(char *name, struct dev_ids **and)
-{
-  char *path = "/etc:/vendor:/usr/share/misc";
-  struct string_list *sl;
-  FILE *fp;
-  char *s, *ss, *sss;
-  struct dev_ids *ids = 0, *new;
-  int fd = -1, tick = 0;
-
-  // Open compressed or uncompressed file
-  sprintf(toybuf, "%s.gz", name);
-  if ((sl = find_in_path(path, toybuf))) {
-    signal(SIGCHLD, SIG_IGN);
-    xpopen((char *[]){"zcat", sl->str, 0}, &fd, 1);
-  } else if ((sl = find_in_path(path, name))) fd = xopen(sl->str,O_RDONLY);
-  llist_traverse(sl, free);
-  if (fd == -1) return 0;
-  
-  for (fp = fdopen(fd, "r"); (s = ss = xgetline(fp)); free(s)) {
-    // TODO parse and use third level instead of skipping it here
-    if (s[strspn(s, " \t")]=='#' || strstart(&ss, "\t\t")) continue;
-
-    // Switch to device class list?
-    if (strstart(&ss, "C ") && and) {
-      *and = ids;
-      and = 0;
-      tick++;
-    } 
-    fd = estrtol(sss = ss, &ss, 16);
-    if (ss>sss && *ss++==' ') {
-      while (isspace(*ss)) ss++;
-      new = xmalloc(sizeof(*new)+strlen(ss)+1);
-      new->child = 0;
-      new->id = fd;
-      strcpy(new->name, ss);
-      if (!ids || *s!='\t') {
-        new->next = ids;
-        ids = new;
-      } else {
-        new->next = ids->child;
-        ids->child = new;
-      }
-    }
-  }
-  fclose(fp);
-
-  return ids;
-}
-
-static int list_usb(struct dirtree *new)
-{
+  FILE *file;
+  char *name;
   int busnum = 0, devnum = 0, pid = 0, vid = 0;
-  char *n1, *n2;
 
   if (!new->parent) return DIRTREE_RECURSE;
-  if (3 == scan_uevent(new, 3, (struct scanloop[]){{"BUSNUM=%u", &busnum, 0},
-    {"DEVNUM=%u", &devnum, 0}, {"PRODUCT=%x/%x", &pid, &vid}}))
-  {
-    get_names(TT.ids, pid, vid, &n1, &n2);
-    printf("Bus %03d Device %03d: ID %04x:%04x %s %s\n",
-      busnum, devnum, pid, vid, n1, n2);
+  if (new->name[0] == '.') return 0;
+  name = dirtree_path(new, 0);
+  sprintf(toybuf, "%s/uevent", name);
+  file = fopen(toybuf, "r");
+  if (file) {
+    int count = 0;
+
+    while (fgets(toybuf, sizeof(toybuf), file))
+      if (sscanf(toybuf, "BUSNUM=%u\n", &busnum)
+          || sscanf(toybuf, "DEVNUM=%u\n", &devnum)
+          || sscanf(toybuf, "PRODUCT=%x/%x/", &pid, &vid)) count++;
+
+    if (count == 3)
+      printf("Bus %03d Device %03d: ID %04x:%04x\n", busnum, devnum, pid, vid);
+    fclose(file);
   }
+  free(name);
 
   return 0;
 }
 
 void lsusb_main(void)
 {
-  // Parse http://www.linux-usb.org/usb.ids file (if available)
-  TT.ids = parse_dev_ids("usb.ids", 0);
-  dirtree_read("/sys/bus/usb/devices/", list_usb);
-}
-
-#define FOR_lspci
-#include "generated/flags.h"
-
-// TODO: -v
-static int list_pci(struct dirtree *new)
-{
-  char *driver = 0, buf[16], *ss, *names[3];
-  int cvd[3] = {0}, ii, revision = 0;
-  off_t len = sizeof(toybuf);
-
-// Output formats: -n, -nn, -m, -nm, -nnm, -k
-
-  if (!new->parent) return DIRTREE_RECURSE;
-  if (strlen(new->name)<6) return 0;
-  TT.count = 0;
-
-  // Load revision
-  sprintf(toybuf, "%s/revision", new->name);
-  if (readfileat(dirtree_parentfd(new), ss = toybuf, toybuf, &len)) {
-    strstart(&ss, "0x");
-    sscanf(ss, "%x", &revision);
-  }
-
-  // Load uevent data, look up names in database
-  if (3 != scan_uevent(new, 3, (struct scanloop[]){{"DRIVER=", &driver, 0},
-    {"PCI_CLASS=%x", cvd, 0}, {"PCI_ID=%x:%x", cvd+1, cvd+2}})) return 0;
-  get_names(TT.class, 255&(cvd[0]>>16), 255&(cvd[0]>>8), names, names);
-  get_names(TT.ids, cvd[1], cvd[2], names+1, names+2);
-  if (!FLAG(e)) cvd[0] >>= 8;
-
-  // Output line according to flags
-  printf("%s", new->name+5);
-  for (ii = 0; ii<3; ii++) {
-    sprintf(buf, "%0*x", 6-2*(ii||!FLAG(e)), cvd[ii]);
-    if (!TT.n) printf(FLAG(m) ? " \"%s\"" : ": %s"+(ii!=1), names[ii] ? : buf);
-    else if (TT.n==1) printf(FLAG(m) ? " \"%s\"" : (ii==2) ? "%s " : " %s:", buf);
-    else if (!FLAG(m)) {
-      // This one permutes the order, so do it all first time and abort loop
-      printf(" %s [%s]: %s %s [%04x:%04x]", names[0], buf, names[1], names[2],
-        cvd[1], cvd[2]);
-      break;
-    } else printf(" \"%s [%s]\"", names[ii], buf);
-  }
-  printf(FLAG(m) ? " -r%02x" : " (rev %02x)", revision);
-  if (FLAG(k)) printf(FLAG(m) ? " \"%s\"" : " %s", driver);
-  xputc('\n');
-
-  return 0;
-}
-
-void lspci_main(void)
-{
-  // Parse https://pci-ids.ucw.cz/v2.2/pci.ids (if available)
-  if (TT.n != 1) TT.class = parse_dev_ids("pci.ids", (void *)&TT.ids);
-  dirtree_read("/sys/bus/pci/devices/", list_pci);
+  dirtree_read("/sys/bus/usb/devices/", list_device);
 }
diff --git a/toys/other/makedevs.c b/toys/other/makedevs.c
index 4edd073..a6998fc 100644
--- a/toys/other/makedevs.c
+++ b/toys/other/makedevs.c
@@ -39,24 +39,22 @@
   char *d;
 )
 
-void makedevs_main(void)
+void makedevs_main()
 {
-  FILE *fp = stdin;
+  int fd = 0, line_no, i;
   char *line = NULL;
-  size_t allocated_length = 0;
-  int line_no = 0, i;
 
   // Open file and chdir, verbosely
   xprintf("rootdir = %s\n", *toys.optargs);
-  if (FLAG(d) && strcmp(TT.d, "-")) {
-    fp = xfopen(TT.d, "r");
+  if ((toys.optflags & FLAG_d) && strcmp(TT.d, "-")) {
+    fd = xopenro(TT.d);
     xprintf("table = %s\n", TT.d);
   } else xprintf("table = <stdin>\n");
   xchdir(*toys.optargs);
 
-  while (getline(&line, &allocated_length, fp) > 0) {
+  for (line_no = 0; (line = get_line(fd)); free(line)) {
     char type=0, user[64], group[64], *node, *ptr = line;
-    unsigned int mode = 0755, major = 0, minor = 0, cnt = 0, incr = 0,
+    unsigned int mode = 0755, major = 0, minor = 0, cnt = 0, incr = 0, 
                  st_val = 0;
     uid_t uid;
     gid_t gid;
@@ -106,10 +104,9 @@
         continue;
       }
 
-      if (chown(ptr, uid, gid) || chmod(ptr, mode))
+      if (chown(ptr, uid, gid) || chmod(ptr, mode)) 
         perror_msg("line %d: can't chown/chmod '%s'", line_no, ptr);
     }
   }
-  free(line);
-  if (fp != stdin) fclose(fp);
+  xclose(fd);
 }
diff --git a/toys/other/nsenter.c b/toys/other/nsenter.c
index d0c75d0..dfcfbe8 100644
--- a/toys/other/nsenter.c
+++ b/toys/other/nsenter.c
@@ -64,6 +64,7 @@
 
 #define FOR_nsenter
 #include "toys.h"
+#include <sys/syscall.h>
 #include <linux/sched.h>
 
 #define unshare(flags) syscall(SYS_unshare, flags)
@@ -75,14 +76,15 @@
 )
 
 // Code that must run in unshare's flag context
+#define CLEANUP_nsenter
 #define FOR_unshare
 #include <generated/flags.h>
 
 static void write_ugid_map(char *map, unsigned eugid)
 {
-  int fd = xopen(map, O_WRONLY);
+  int bytes = sprintf(toybuf, "0 %u 1", eugid), fd = xopen(map, O_WRONLY);
 
-  dprintf(fd, "0 %u 1", eugid);
+  xwrite(fd, toybuf, bytes);
   xclose(fd);
 }
 
@@ -110,6 +112,7 @@
 }
 
 // Shift back to the context GLOBALS lives in (I.E. matching the filename).
+#define CLEANUP_unshare
 #define FOR_nsenter
 #include <generated/flags.h>
 
diff --git a/toys/other/openvt.c b/toys/other/openvt.c
deleted file mode 100644
index 8210587..0000000
--- a/toys/other/openvt.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* openvt.c - Run a program on a new VT
- *
- * Copyright 2008 David Anders <danders@amltd.com>
- * Copyright 2014 Vivek Kumar Bhagat <vivek.bhagat89@gmail.com>
- *
- * No Standard
-
-USE_OPENVT(NEWTOY(openvt, "^<1c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
-USE_CHVT(NEWTOY(chvt, "<1", TOYFLAG_USR|TOYFLAG_BIN))
-USE_DEALLOCVT(NEWTOY(deallocvt, ">1", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NEEDROOT))
-
-config OPENVT
-  bool "openvt"
-  default y
-  help
-    usage: openvt [-c NUM] [-sw] COMMAND...
-
-    Run COMMAND on a new virtual terminal.
-
-    -c NUM  Use VT NUM
-    -s    Switch to the new VT
-    -w    Wait for command to exit (with -s, deallocates VT on exit)
-
-config CHVT
-  bool "chvt"
-  default y
-  help
-    usage: chvt NUM
-
-    Change to virtual terminal number NUM. (This only works in text mode.)
-
-    Virtual terminals are the Linux VGA text mode (or framebuffer) displays,
-    switched between via alt-F1, alt-F2, etc. Use ctrl-alt-F1 to switch
-    from X11 to a virtual terminal, and alt-F6 (or F7, or F8) to get back.
-
-config DEALLOCVT
-  bool "deallocvt"
-  default y
-  help
-    usage: deallocvt [NUM]
-
-    Deallocate unused virtual terminals, either a specific /dev/ttyNUM, or all.
-*/
-
-#define FOR_openvt
-#include "toys.h"
-#include <linux/vt.h>
-#include <linux/kd.h>
-
-GLOBALS(
-  long c;
-)
-
-static int open_console(void)
-{
-  char arg = 0, *console_name[] = {"/dev/tty", "/dev/tty0", "/dev/console"};
-  int i, fd;
-
-  for (i = 0; i < ARRAY_LEN(console_name); i++) {
-    if (0>(fd = open(console_name[i], O_RDWR))) continue;
-    if (!ioctl(fd, KDGKBTYPE, &arg)) return fd;
-    close(fd);
-  }
-  for (fd = 0; fd < 3; fd++) if (!ioctl(fd, KDGKBTYPE, &arg)) return fd;
-  error_exit("can't open console");
-}
-
-static int activate(int fd, int cc)
-{
-  return ioctl(fd, VT_ACTIVATE, cc) || ioctl(fd, VT_WAITACTIVE, cc);
-}
-
-void openvt_main(void)
-{
-  struct vt_stat vstate;
-  int fd, cc = (int)TT.c;
-  pid_t pid;
-
-  // find current console
-  if (-1 == (ioctl(fd = open_console(), VT_GETSTATE, &vstate)) ||
-      (!cc && 0>=(cc = xioctl(fd, VT_OPENQRY, &fd))))
-    perror_exit("can't find open VT");
-
-  sprintf(toybuf, "/dev/tty%d", cc);
-  if (!(pid = XVFORK())) {
-    close(0);  //new vt becomes stdin
-    dup2(dup2(xopen_stdio(toybuf, O_RDWR), 1), 2);
-    if (FLAG(s)) activate(0, cc);
-    setsid();
-    ioctl(0, TIOCSCTTY, 0);
-    if (fd>2) close(fd);
-    xexec(toys.optargs);
-  }
-  if (FLAG(w)) {
-    while (-1 == waitpid(pid, NULL, 0) && errno == EINTR) errno = 0;
-    if (FLAG(s)) {
-      activate(fd, vstate.v_active);
-      dprintf(2, "%d\n", ioctl(fd, VT_DISALLOCATE, cc));
-    }
-  }
-}
-
-void chvt_main(void)
-{
-  if (activate(open_console(), atoi(*toys.optargs)))
-    perror_exit_raw(*toys.optargs);
-}
-
-void deallocvt_main(void)
-{
-  int fd = open_console(), vt_num = 0; // 0 = all
-
-  if (*toys.optargs) vt_num = atolx_range(*toys.optargs, 1, 63);
-  if (-1 == ioctl(fd, VT_DISALLOCATE, vt_num)) perror_exit("%d", vt_num);
-}
diff --git a/toys/other/pivot_root.c b/toys/other/pivot_root.c
index f9a8918..7748032 100644
--- a/toys/other/pivot_root.c
+++ b/toys/other/pivot_root.c
@@ -22,6 +22,9 @@
 #define FOR_pivot_root
 #include "toys.h"
 
+#include <sys/syscall.h>
+#include <unistd.h>
+
 void pivot_root_main(void)
 {
   if (syscall(__NR_pivot_root, toys.optargs[0], toys.optargs[1]))
diff --git a/toys/other/pmap.c b/toys/other/pmap.c
index d222f01..02260db 100644
--- a/toys/other/pmap.c
+++ b/toys/other/pmap.c
@@ -4,22 +4,19 @@
  * Copyright 2013 Kyungwan Han <asura321@gmail.com>
  *
  * No Standard.
- *
- * TODO: two passes so we can auto-size the columns?
 
-USE_PMAP(NEWTOY(pmap, "<1pqx", TOYFLAG_USR|TOYFLAG_BIN))
+USE_PMAP(NEWTOY(pmap, "<1xq", TOYFLAG_USR|TOYFLAG_BIN))
 
 config PMAP
   bool "pmap"
   default y
   help
-    usage: pmap [-pqx] PID...
+    usage: pmap [-xq] [pids...]
 
     Report the memory map of a process or processes.
 
-    -q	Show full paths
-    -q	Do not show header or footer
     -x	Show the extended format
+    -q	Do not display some header/footer lines
 */
 
 #define FOR_pmap
@@ -27,77 +24,90 @@
 
 void pmap_main(void)
 {
-  char **optargs, *line = 0;
-  size_t len = 0;
+  char **optargs;
 
   for (optargs = toys.optargs; *optargs; optargs++) {
-    long long start, end, pss, tpss=0, dirty, tdirty=0, swap, tswap=0, total=0;
-    char *name = 0, *k = FLAG(x) ? "" : "K", mode[5];
     pid_t pid = atolx(*optargs);
-    int extras = 0, off, count;
     FILE *fp;
+    char *line, *oldline = 0, *name = 0,
+         *k = (toys.optflags & FLAG_x) ? "" : "K";
+    size_t len;
+    long long start, end, pss, tpss = 0, dirty, tdirty = 0, swap, tswap = 0,
+              total = 0;
+    int xx = 0;
 
-    sprintf(toybuf, "/proc/%u/cmdline", pid);
-    if (!(name = readfile(toybuf, 0, 0))) {
-      error_msg("no %s", toybuf);
-      continue;
-    }
-    xprintf("%d: %s\n", pid, name);
-    free(name);
+    snprintf(toybuf, sizeof(toybuf), "/proc/%u/cmdline", pid);
+    line = readfile(toybuf, 0, 0);
+    if (!line) error_msg("No %lu", (long)pid);
+    xprintf("%u: %s\n", (int)pid, line);
+    free(line);
 
-    // Only bother scanning the more verbose smaps file in -x mode.
-    sprintf(toybuf, "/proc/%u/%smaps", pid, "s"+!FLAG(x));
+    // Header
+    // Only use the more verbose file in -x mode
+    sprintf(toybuf, "/proc/%u/%smaps", pid,
+      (toys.optflags & FLAG_x) ? "s" : "");
     if (!(fp = fopen(toybuf, "r"))) {
-      error_msg("no %s", toybuf);
-      continue;
+      error_msg("No %ld\n", (long)pid);
+      return;
     }
 
-    if (FLAG(x) && !FLAG(q))
-      xprintf("Address%*cKbytes     PSS   Dirty    Swap Mode  Mapping\n",
-          (int)(sizeof(long)*2)-5, ' ');
+    if ((toys.optflags & (FLAG_q|FLAG_x)) == FLAG_x)
+      xprintf("Address%*cKbytes     PSS   Dirty    Swap  Mode  Mapping\n",
+        (int)(sizeof(long)*2)-4, ' ');
 
-    while (getline(&line, &len, fp) > 0) {
-      count = sscanf(line, "%llx-%llx %4s %*s %*s %*s %n", &start, &end, mode,
-          &off);
+    // Loop through mappings
+    for (;;) {
+      int off, count;
+
+      line = 0;
+      if (0 >= getline(&line, &len, fp)) break;
+      count = sscanf(line, "%llx-%llx %s %*s %*s %*s %n",
+        &start, &end, toybuf, &off);
+
       if (count == 3) {
         name = line[off] ? line+off : "  [anon]\n";
-        if (mode[3] == 'p') mode[3] = '-';
+        if (toybuf[3] == 'p') toybuf[3] = '-';
         total += end = (end-start)/1024;
-        printf("%0*llx % *lld%s ", (int)(2*sizeof(long)), start, 6+!!FLAG(x),
-            end, k);
-        if (FLAG(x)) {
-          strcpy(toybuf, name);
-          name = toybuf;
+        printf("%0*llx % *lld%s ", (int)(2*sizeof(long)), start,
+          6+!!(toys.optflags & FLAG_x), end, k);
+        if (toys.optflags & FLAG_x) {
+          oldline = line;
           continue;
         }
       } else {
-        if (sscanf(line, "Pss: %lld", &pss) ||
-            sscanf(line, "Private_Dirty: %lld", &dirty) ||
-            sscanf(line, "Swap: %lld", &swap)) extras++;
-        if (extras==3) {
-          printf("% 7lld %7lld %7lld ", pss, dirty, swap);
-          tpss += pss;
-          tdirty += dirty;
-          tswap += swap;
-          extras = 0;
-        } else continue;
+        if (0<sscanf(line, "Pss: %lld", &pss)
+            || 0<sscanf(line, "Private_Dirty: %lld", &dirty)
+            || 0<sscanf(line, "Swap: %lld", &swap)) xx++;
+        free(line);
+        if (xx<3) continue;
+        line = oldline;
+        name = basename(name);
+        xx = 0;
+        printf("% 7lld %7lld %7lld ", pss, dirty, swap);
+        tpss += pss;
+        tdirty += dirty;
+        tswap += swap;
       }
 
-      xprintf("%s- %s%s", mode, *name == '[' ? "  " : "",
-              FLAG(p) ? name : basename(name));
+      xprintf("%s-  %s%s", toybuf, line[off]=='[' ? "  " : "", name);
+
+      free(line);
+      line = 0;
     }
 
-    if (!FLAG(q)) {
-      if (FLAG(x)) {
-        xprintf("----------------  ------  ------  ------  ------\n" +
-            ((sizeof(long)==4)?8:0));
+    // Trailer
+    if (!(toys.optflags & FLAG_q)) {
+      int x = !!(toys.optflags & FLAG_x);
+      if (x) {
+        memset(toybuf, '-', 16);
+        xprintf("%.*s  ------  ------  ------  ------\n", (int)(sizeof(long)*2),
+          toybuf);
       }
-      printf("total% *lld%s", 2*(int)(sizeof(long)+1)+!!FLAG(x), total, k);
-      if (FLAG(x)) printf("% 8lld% 8lld% 8lld", tpss, tdirty, tswap);
+      printf("total% *lld%s", 2*(int)(sizeof(long)+1)+x, total, k);
+      if (x) printf("% 8lld% 8lld% 8lld", tpss, tdirty, tswap);
       xputc('\n');
     }
-
+ 
     fclose(fp);
   }
-  free(line);
 }
diff --git a/toys/other/pwgen.c b/toys/other/pwgen.c
index c34daf5..c6621cc 100644
--- a/toys/other/pwgen.c
+++ b/toys/other/pwgen.c
@@ -61,7 +61,7 @@
         else c |= (0x80&randbuf[rand])>>2;
       }
       if (FLAG(0) && c>='0' && c<='9') continue;
-      if (FLAG(B) && strchr("0O1lI8B5S2ZD'`.,", c)) continue;
+      if (FLAG(B) && strchr("0O1lI'`.,", c)) continue;
       if (FLAG(v) && strchr("aeiou", tolower(c))) continue;
       if (!FLAG(y) || (0x80&randbuf[rand]))
         if (c<'0' || (c>'9' && c<'A') || (c>'Z' && c<'a') || c>'z') continue;
diff --git a/toys/other/readahead.c b/toys/other/readahead.c
index 3221227..4edd651 100644
--- a/toys/other/readahead.c
+++ b/toys/other/readahead.c
@@ -17,6 +17,8 @@
 
 #include "toys.h"
 
+#include <sys/syscall.h>
+
 static void do_readahead(int fd, char *name)
 {
   int rc;
diff --git a/toys/other/readlink.c b/toys/other/readlink.c
index 3155dcc..bae0953 100644
--- a/toys/other/readlink.c
+++ b/toys/other/readlink.c
@@ -2,9 +2,8 @@
  *
  * Copyright 2007 Rob Landley <rob@landley.net>
 
-// -ef positions match ABS_FILE ABS_PATH
 USE_READLINK(NEWTOY(readlink, "<1nqmef(canonicalize)[-mef]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_REALPATH(OLDTOY(realpath, readlink, TOYFLAG_USR|TOYFLAG_BIN))
+USE_REALPATH(NEWTOY(realpath, "<1", TOYFLAG_USR|TOYFLAG_BIN))
 
 config READLINK
   bool "readlink"
@@ -39,17 +38,22 @@
 {
   char **arg, *s;
 
-  if (toys.which->name[3]=='l') toys.optflags |= FLAG_f;
   for (arg = toys.optargs; *arg; arg++) {
     // Calculating full canonical path?
-    // Take advantage of flag positions: m = 0, f = ABS_PATH, e = ABS_FILE
+    // Take advantage of flag positions to calculate m = -1, f = 0, e = 1
     if (toys.optflags & (FLAG_f|FLAG_e|FLAG_m))
-      s = xabspath(*arg, toys.optflags&(FLAG_f|FLAG_e));
+      s = xabspath(*arg, (toys.optflags&(FLAG_f|FLAG_e))-1);
     else s = xreadlink(*arg);
 
     if (s) {
-      if (!FLAG(q)) xprintf("%s%s", s, (FLAG(n) && !arg[1]) ? "" : "\n");
-      free(s);
+      if (!FLAG(q)) xprintf(FLAG(n) ? "%s" : "%s\n", s);
+      if (CFG_TOYBOX_FREE) free(s);
     } else toys.exitval = 1;
   }
 }
+
+void realpath_main(void)
+{
+  toys.optflags = FLAG_f;
+  readlink_main();
+}
diff --git a/toys/other/reboot.c b/toys/other/reboot.c
index 4770d1f..c883e34 100644
--- a/toys/other/reboot.c
+++ b/toys/other/reboot.c
@@ -2,7 +2,7 @@
  *
  * Copyright 2013 Elie De Brauwer <eliedebrauwer@gmail.com>
 
-USE_REBOOT(NEWTOY(reboot, "d:fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
+USE_REBOOT(NEWTOY(reboot, "fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_REBOOT(OLDTOY(halt, reboot, TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 USE_REBOOT(OLDTOY(poweroff, reboot, TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
 
@@ -10,37 +10,26 @@
   bool "reboot"
   default y
   help
-    usage: reboot/halt/poweroff [-fn] [-d DELAY]
+    usage: reboot/halt/poweroff [-fn]
 
-    Restart, halt, or power off the system.
+    Restart, halt or powerdown the system.
 
-    -d	Wait DELAY before proceeding (in seconds or m/h/d suffix: -d 1.5m = 90s)
-    -f	Force reboot (don't signal init, reboot directly)
-    -n	Don't sync filesystems before reboot
+    -f	Don't signal init
+    -n	Don't sync before stopping the system
 */
 
 #define FOR_reboot
 #include "toys.h"
 #include <sys/reboot.h>
 
-GLOBALS(
-  char *d;
-)
-
 void reboot_main(void)
 {
-  struct timespec ts;
   int types[] = {RB_AUTOBOOT, RB_HALT_SYSTEM, RB_POWER_OFF},
       sigs[] = {SIGTERM, SIGUSR1, SIGUSR2}, idx;
 
-  if (TT.d) {
-    xparsetimespec(TT.d, &ts);
-    nanosleep(&ts, NULL);
-  }
-
-  if (!FLAG(n)) sync();
+  if (!(toys.optflags & FLAG_n)) sync();
 
   idx = stridx("hp", *toys.which->name)+1;
-  if (FLAG(f)) toys.exitval = reboot(types[idx]);
+  if (toys.optflags & FLAG_f) toys.exitval = reboot(types[idx]);
   else toys.exitval = kill(1, sigs[idx]);
 }
diff --git a/toys/other/reset.c b/toys/other/reset.c
index 8723760..4d16a4a 100644
--- a/toys/other/reset.c
+++ b/toys/other/reset.c
@@ -3,9 +3,6 @@
  * Copyright 2015 Rob Landley <rob@landley.net>
  *
  * No standard.
- *
- * In 1979 3BSD's tset had a sleep(1) to let mechanical printer-and-ink
- * terminals "settle down". We're not doing that.
 
 USE_RESET(NEWTOY(reset, 0, TOYFLAG_USR|TOYFLAG_BIN))
 
@@ -25,5 +22,5 @@
 
   // man 4 console_codes: reset terminal is ESC (no left bracket) c
   // DEC private mode set enable wraparound sequence.
-  xwrite(fd<0 ? 1 : fd, "\ec\e[?7h", 2);
+  xwrite(fd<0 ? 1 : fd, "\033c\033[?7h", 2);
 }
diff --git a/toys/other/rmmod.c b/toys/other/rmmod.c
index 0450c0b..d9f0a15 100644
--- a/toys/other/rmmod.c
+++ b/toys/other/rmmod.c
@@ -8,32 +8,36 @@
   bool "rmmod"
   default y
   help
-    usage: rmmod [-wf] MODULE...
+    usage: rmmod [-wf] [MODULE]
 
-    Unload the given kernel modules.
-
+    Unload the module named MODULE from the Linux kernel.
     -f	Force unload of a module
     -w	Wait until the module is no longer used
+
 */
 
 #define FOR_rmmod
 #include "toys.h"
 
+#include <sys/syscall.h>
 #define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags)
 
 void rmmod_main(void)
 {
-  char **args, *module, *s;
-  unsigned flags;
+  unsigned int flags = O_NONBLOCK|O_EXCL;
+  char * mod_name;
+  int len;
 
-  for (args = toys.optargs; *args; args++) {
-    module = basename(*args);
-    // Remove .ko if present
-    if ((s = strend(module, ".ko"))) *s = 0;
+  // Basename
+  mod_name = basename(*toys.optargs);
 
-    flags = O_NONBLOCK;
-    if (FLAG(f)) flags |= O_TRUNC;
-    if (FLAG(w)) flags &= ~O_NONBLOCK;
-    if (delete_module(module, flags)) perror_msg("failed to unload %s", module);
-  }
+  // Remove .ko if present
+  len = strlen(mod_name);
+  if (len > 3 && !strcmp(&mod_name[len-3], ".ko" )) mod_name[len-3] = 0;
+
+  if (toys.optflags & FLAG_f) flags |= O_TRUNC;
+  if (toys.optflags & FLAG_w) flags &= ~O_NONBLOCK;
+
+  if (delete_module(mod_name, flags))
+    perror_exit("failed to unload %s", mod_name);
 }
diff --git a/toys/other/shred.c b/toys/other/shred.c
index 1932f75..3911e24 100644
--- a/toys/other/shred.c
+++ b/toys/other/shred.c
@@ -10,7 +10,7 @@
   bool "shred"
   default y
   help
-    usage: shred [-fuxz] [-n COUNT] [-o OFFSET] [-s SIZE] FILE...
+    usage: shred [-fuz] [-n COUNT] [-s SIZE] FILE...
 
     Securely delete a file by overwriting its contents with random data.
 
diff --git a/toys/other/switch_root.c b/toys/other/switch_root.c
index 3df703d..eb1e2b0 100644
--- a/toys/other/switch_root.c
+++ b/toys/other/switch_root.c
@@ -46,7 +46,7 @@
   char *newroot = *toys.optargs, **cmdline = toys.optargs+1;
   struct stat st1, st2;
   struct statfs stfs;
-  int console QUIET;
+  int console = console; // gcc's "may be used" warnings are broken.
 
   if (getpid() != 1) error_exit("not pid 1");
 
diff --git a/toys/other/taskset.c b/toys/other/taskset.c
index 2a9ae02..6a9de77 100644
--- a/toys/other/taskset.c
+++ b/toys/other/taskset.c
@@ -34,6 +34,7 @@
 #define FOR_taskset
 #include "toys.h"
 
+#include <sys/syscall.h>
 #define sched_setaffinity(pid, size, cpuset) \
   syscall(__NR_sched_setaffinity, (pid_t)pid, (size_t)size, (void *)cpuset)
 #define sched_getaffinity(pid, size, cpuset) \
diff --git a/toys/other/timeout.c b/toys/other/timeout.c
index e93a806..1e12530 100644
--- a/toys/other/timeout.c
+++ b/toys/other/timeout.c
@@ -33,9 +33,8 @@
 
   int nextsig;
   pid_t pid;
-  struct timespec kts;
-  struct itimerspec its;
-  timer_t timer;
+  struct timeval ktv;
+  struct itimerval itv;
 )
 
 static void handler(int i)
@@ -49,19 +48,27 @@
     TT.k = 0;
     TT.nextsig = SIGKILL;
     xsignal(SIGALRM, handler);
-    TT.its.it_value = TT.kts;
-    if (timer_settime(TT.timer, 0, &TT.its, 0)) perror_exit("timer_settime");
+    TT.itv.it_value = TT.ktv;
+    setitimer(ITIMER_REAL, &TT.itv, (void *)toybuf);
   }
 }
 
+// timeval inexplicably makes up a new type for microseconds, despite timespec's
+// nanoseconds field (needing to store 1000* the range) using "long". Bravo.
+static void xparsetimeval(char *s, struct timeval *tv)
+{
+  long ll;
+
+  tv->tv_sec = xparsetime(s, 6, &ll);
+  tv->tv_usec = ll;
+}
+
 void timeout_main(void)
 {
-  struct sigevent se = { .sigev_notify = SIGEV_SIGNAL, .sigev_signo = SIGALRM };
-
   // Use same ARGFAIL value for any remaining parsing errors
   toys.exitval = 125;
-  xparsetimespec(*toys.optargs, &TT.its.it_value);
-  if (TT.k) xparsetimespec(TT.k, &TT.kts);
+  xparsetimeval(*toys.optargs, &TT.itv.it_value);
+  if (TT.k) xparsetimeval(TT.k, &TT.ktv);
 
   TT.nextsig = SIGTERM;
   if (TT.s && -1 == (TT.nextsig = sig_to_num(TT.s)))
@@ -75,8 +82,7 @@
     int status;
 
     xsignal(SIGALRM, handler);
-    if (timer_create(CLOCK_MONOTONIC, &se, &TT.timer)) perror_exit("timer");
-    if (timer_settime(TT.timer, 0, &TT.its, 0)) perror_exit("timer_settime");
+    setitimer(ITIMER_REAL, &TT.itv, (void *)toybuf);
 
     status = xwaitpid(TT.pid);
     if (FLAG(preserve_status) || !toys.exitval) toys.exitval = status;
diff --git a/toys/other/truncate.c b/toys/other/truncate.c
index 7adeb62..40eb1e5 100644
--- a/toys/other/truncate.c
+++ b/toys/other/truncate.c
@@ -53,7 +53,7 @@
 
 void truncate_main(void)
 {
-  int cr = !FLAG(c);
+  int cr = !(toys.optflags&FLAG_c);
 
   if (-1 != (TT.type = stridx("+-<>/%", *TT.s))) TT.s++;
   TT.size = atolx(TT.s);
diff --git a/toys/other/uclampset.c b/toys/other/uclampset.c
deleted file mode 100644
index acf50bd..0000000
--- a/toys/other/uclampset.c
+++ /dev/null
@@ -1,89 +0,0 @@
-/* uclampset.c - The quota version of "nice".
- *
- * Copyright 2021 The Android Open Source Project
- *
- * See https://man7.org/linux/man-pages/man1/uclampset.1.html
-
-USE_UCLAMPSET(NEWTOY(uclampset, "p#am#<-1>1024M#<-1>1024R", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT))
-
-config UCLAMPSET
-  bool "uclampset"
-  default y
-  help
-    usage: uclampset [-m MIN] [-M MAX] {-p PID | COMMAND...}
-
-    Set or query process utilization limits ranging from 0 to 1024, or -1 to
-    reset to system default. With no arguments, prints current values.
-
-    -m MIN      Reserve at least this much CPU utilization for task
-    -M MAX      Limit task to at most this much CPU utilization
-    -p PID	Apply to PID rather than new COMMAND
-    -R	Reset child processes to default values on fork
-    -a	Apply to all threads for the given PID
-*/
-
-#define FOR_uclampset
-#include "toys.h"
-
-GLOBALS(
-  long M, m, p;
-)
-
-// Added to 5.3 kernel (commit a509a7cd7974): too new to rely on headers
-#ifndef SCHED_FLAG_RESET_ON_FORK
-#define SCHED_FLAG_RESET_ON_FORK 0x01
-#define SCHED_FLAG_KEEP_POLICY 0x08
-#define SCHED_FLAG_KEEP_PARAMS 0x10
-#define SCHED_FLAG_UTIL_CLAMP_MIN 0x20
-#define SCHED_FLAG_UTIL_CLAMP_MAX 0x40
-#endif
-
-static void do_uclampset(pid_t pid)
-{
-  unsigned *sa = (void *)toybuf; // sa[12] is min, sa[13] is max
-  char *comm, buf[32];
-
-  if (FLAG(R)|FLAG(m)|FLAG(M)) {
-    if (syscall(__NR_sched_setattr, pid, sa, 0))
-      perror_exit("sched_setattr for pid %d", pid);
-  } else {
-    sprintf(buf, "/proc/%u/comm", pid);
-    comm = chomp(xreadfile(buf, 0, 0));
-    if (syscall(__NR_sched_getattr, pid, sa, *sa, 0))
-      perror_exit("sched_getattr for pid %d", pid);
-    printf("%s (%d) util_clamp: min: %u max: %u\n", comm, pid, sa[12], sa[13]);
-    free(comm);
-  }
-}
-
-static int task_callback(struct dirtree *new)
-{
-  if (!new->parent) return DIRTREE_RECURSE;
-  if (isdigit(*new->name)) do_uclampset(atoi(new->name));
-
-  return 0;
-}
-
-void uclampset_main(void)
-{
-  unsigned *sa = (void *)toybuf;
-  long long *flags = (void *)(sa+2);
-  char buf[32];
-
-  sa[0]  = 14*4; // size
-  sa[12] = TT.m;
-  sa[13] = TT.M;
-  *flags = SCHED_FLAG_KEEP_POLICY | SCHED_FLAG_KEEP_PARAMS;
-  if (FLAG(R)) *flags |= SCHED_FLAG_RESET_ON_FORK;
-  if (FLAG(m)) *flags |= SCHED_FLAG_UTIL_CLAMP_MIN;
-  if (FLAG(M)) *flags |= SCHED_FLAG_UTIL_CLAMP_MAX;
-
-  if (!FLAG(p)) {
-    if (toys.optc < 1) error_exit("Need -p PID or CMD [ARG...]");
-    do_uclampset(getpid());
-    xexec(toys.optargs);
-  } else if (FLAG(a)) {
-    sprintf(buf, "/proc/%lu/task", TT.p);
-    dirtree_read(buf, task_callback);
-  } else do_uclampset(TT.p);
-}
diff --git a/toys/other/uptime.c b/toys/other/uptime.c
index 6c0c805..001af02 100644
--- a/toys/other/uptime.c
+++ b/toys/other/uptime.c
@@ -28,7 +28,7 @@
   struct sysinfo info;
   time_t t;
   struct tm *tm;
-  unsigned int weeks, days, hours, minutes;
+  unsigned int days, hours, minutes;
   struct utmpx *entry;
   int users = 0;
 
@@ -37,7 +37,7 @@
   time(&t);
 
   // Just show the time of boot?
-  if (FLAG(s)) {
+  if (toys.optflags & FLAG_s) {
     t -= info.uptime;
     tm = localtime(&t);
     strftime(toybuf, sizeof(toybuf), "%F %T", tm);
@@ -54,27 +54,29 @@
   hours = info.uptime%24;
   days = info.uptime/24;
 
-  if (FLAG(p)) {
-    weeks = days/7;
+  if (toys.optflags & FLAG_p) {
+    int weeks = days/7;
     days %= 7;
-    xprintf("up %d week%s, %d day%s, %d hour%s, %d minute%s, ",
+
+    xprintf("up %d week%s, %d day%s, %d hour%s, %d minute%s\n",
         weeks, (weeks!=1)?"s":"",
         days, (days!=1)?"s":"",
         hours, (hours!=1)?"s":"",
         minutes, (minutes!=1)?"s":"");
-  } else {
-    xprintf(" %02d:%02d:%02d up ", tm->tm_hour, tm->tm_min, tm->tm_sec);
-    if (days) xprintf("%d day%s, ", days, (days!=1)?"s":"");
-    if (hours) xprintf("%2d:%02d, ", hours, minutes);
-    else printf("%d min, ", minutes);
-
-    // Obtain info about logged on users
-    setutxent();
-    while ((entry = getutxent())) if (entry->ut_type == USER_PROCESS) users++;
-    endutxent();
-    printf(" %d user%s, ", users, (users!=1) ? "s" : "");
+    return;
   }
 
+  xprintf(" %02d:%02d:%02d up ", tm->tm_hour, tm->tm_min, tm->tm_sec);
+  if (days) xprintf("%d day%s, ", days, (days!=1)?"s":"");
+  if (hours) xprintf("%2d:%02d, ", hours, minutes);
+  else printf("%d min, ", minutes);
+
+  // Obtain info about logged on users
+  setutxent();
+  while ((entry = getutxent())) if (entry->ut_type == USER_PROCESS) users++;
+  endutxent();
+
+  printf(" %d user%s, ", users, (users!=1) ? "s" : "");
   printf(" load average: %.02f, %.02f, %.02f\n", info.loads[0]/65536.0,
     info.loads[1]/65536.0, info.loads[2]/65536.0);
 }
diff --git a/toys/other/watch.c b/toys/other/watch.c
index 06559e2..af65004 100644
--- a/toys/other/watch.c
+++ b/toys/other/watch.c
@@ -67,7 +67,7 @@
 {
   char *cmdv[] = {"/bin/sh", "-c", 0, 0}, *cmd, *ss;
   long long now, then = millitime();
-  unsigned width, height, i, cmdlen, len, xx QUIET, yy QUIET, active QUIET;
+  unsigned width, height, i, cmdlen, len, xx = xx, yy = yy, active = active;
   struct pollfd pfd[2];
   pid_t pid = 0;
   int fds[2], cc;
diff --git a/toys/other/xxd.c b/toys/other/xxd.c
index 3a070df..99321ee 100644
--- a/toys/other/xxd.c
+++ b/toys/other/xxd.c
@@ -10,7 +10,7 @@
  * xxd -p "plain" output:
  *   "4c696e75782076657273696f6e20342e392e302d342d616d643634202864"
 
-USE_XXD(NEWTOY(xxd, ">1c#<0>256l#o#g#<1=2iprs#[!rs]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_XXD(NEWTOY(xxd, ">1c#l#o#g#<1=2iprs#[!rs]", TOYFLAG_USR|TOYFLAG_BIN))
 
 config XXD
   bool "xxd"
@@ -18,12 +18,12 @@
   help
     usage: xxd [-c n] [-g n] [-i] [-l n] [-o n] [-p] [-r] [-s n] [file]
 
-    Hexdump a file to stdout. If no file is listed, copy from stdin.
+    Hexdump a file to stdout.  If no file is listed, copy from stdin.
     Filename "-" is a synonym for stdin.
 
     -c n	Show n bytes per line (default 16)
     -g n	Group bytes by adding a ' ' every n bytes (default 2)
-    -i	Output include file (CSV hex bytes, plus C header/footer if not stdin)
+    -i	Include file output format (comma-separated hex byte literals)
     -l n	Limit of n bytes before stopping (default is no limit)
     -o n	Add n to display offset
     -p	Plain hexdump (30 bytes/line, no grouping)
@@ -44,16 +44,15 @@
   long long limit = TT.l;
   int i, len, space;
 
-  if (FLAG(s)) {
+  if (toys.optflags&FLAG_s) {
     xlseek(fd, TT.s, SEEK_SET);
     pos = TT.s;
     if (limit) limit += TT.s;
   }
 
   while (0<(len = readall(fd, toybuf,
-                          (limit && limit-pos<TT.c)?limit-pos:TT.c)))
-  {
-    if (!FLAG(p)) printf("%08llx: ", TT.o + pos);
+                          (limit && limit-pos<TT.c)?limit-pos:TT.c))) {
+    if (!(toys.optflags&FLAG_p)) printf("%08llx: ", TT.o + pos);
     pos += len;
     space = 2*TT.c+TT.c/TT.g+1;
 
@@ -65,7 +64,7 @@
       }
     }
 
-    if (!FLAG(p)) {
+    if (!(toys.optflags&FLAG_p)) {
       printf("%*s", space, "");
       for (i=0; i<len; i++)
         putchar((toybuf[i]>=' ' && toybuf[i]<='~') ? toybuf[i] : '.');
@@ -77,11 +76,13 @@
 
 static void do_xxd_include(int fd, char *name)
 {
+  long long total = 0;
   int c = 1, i, len;
 
   // The original xxd outputs a header/footer if given a filename (not stdin).
   // We don't, which means that unlike the original we can implement -ri.
   while ((len = read(fd, toybuf, sizeof(toybuf))) > 0) {
+    total += len;
     for (i = 0; i < len; ++i) {
       printf("%s%#.02x", c > 1 ? ", " : "  ", toybuf[i]);
       if (c++ == TT.c) {
@@ -107,48 +108,54 @@
   FILE *fp = xfdopen(fd, "r");
   int tmp;
 
-  // -ri is a very easy special case.
-  if (FLAG(i)) while (fscanf(fp, " 0x%02x,", &tmp) == 1) xputc(tmp);
-  else while (!feof(fp)) {
-    int col = 0;
+  if (toys.optflags&FLAG_i) {
+    // -ri is a very easy special case.
+    while (fscanf(fp, " 0x%02x,", &tmp) == 1) {
+      fputc(tmp & 0xff, stdout);
+    }
+  } else {
+    while (!feof(fp)) {
+      int col = 0;
 
-    // Each line of a regular hexdump starts with an offset/address.
-    // Each line of a plain hexdump just goes straight into the bytes.
-    if (!FLAG(p)) {
-      long long pos;
+      // Each line of a regular hexdump starts with an offset/address.
+      // Each line of a plain hexdump just goes straight into the bytes.
+      if (!(toys.optflags&FLAG_p)) {
+        long long pos;
 
-      if (fscanf(fp, "%llx: ", &pos) == 1) {
-        if (fseek(stdout, pos, SEEK_SET) != 0) {
-          // TODO: just write out zeros if non-seekable?
-          perror_exit("%s: seek failed", name);
+        if (fscanf(fp, "%llx: ", &pos) == 1) {
+          if (fseek(stdout, pos, SEEK_SET) != 0) {
+            // TODO: just write out zeros if non-seekable?
+            perror_exit("%s: seek failed", name);
+          }
         }
       }
-    }
 
-    // A plain hexdump can have as many bytes per line as you like,
-    // but a non-plain hexdump assumes garbage after it's seen the
-    // specified number of bytes.
-    while (FLAG(p) || col < TT.c) {
-      int n1, n2;
+      // A plain hexdump can have as many bytes per line as you like,
+      // but a non-plain hexdump assumes garbage after it's seen the
+      // specified number of bytes.
+      while (toys.optflags&FLAG_p || col < TT.c) {
+        int n1, n2;
 
-      // If we're at EOF or EOL or we read some non-hex...
-      if ((n1 = n2 = dehex(fgetc(fp))) < 0 || (n2 = dehex(fgetc(fp))) < 0) {
-        // If we're at EOL, start on that line.
-        if (n1 == -2 || n2 == -2) continue;
-        // Otherwise, skip to the next line.
-        break;
+        // If we're at EOF or EOL or we read some non-hex...
+        if ((n1 = n2 = dehex(fgetc(fp))) < 0 || (n2 = dehex(fgetc(fp))) < 0) {
+          // If we're at EOL, start on that line.
+          if (n1 == -2 || n2 == -2) continue;
+          // Otherwise, skip to the next line.
+          break;
+        }
+
+        fputc((n1 << 4) | (n2 & 0xf), stdout);
+        col++;
+
+        // Is there any grouping going on? Ignore a single space.
+        tmp = fgetc(fp);
+        if (tmp != ' ') ungetc(tmp, fp);
       }
 
-      fputc((n1 << 4) | (n2 & 0xf), stdout);
-      col++;
-
-      // Is there any grouping going on? Ignore a single space.
-      tmp = fgetc(fp);
-      if (tmp != ' ') ungetc(tmp, fp);
+      // Skip anything else on this line (such as the ASCII dump).
+      while ((tmp = fgetc(fp)) != EOF && tmp != '\n')
+        ;
     }
-
-    // Skip anything else on this line (such as the ASCII dump).
-    while ((tmp = fgetc(fp)) != EOF && tmp != '\n');
   }
 
   if (ferror(fp)) perror_msg_raw(name);
@@ -157,11 +164,13 @@
 
 void xxd_main(void)
 {
-  if (!TT.c) TT.c = FLAG(i) ? 12 : 16;
+  if (TT.c < 0 || TT.c > 256) error_exit("invalid -c: %ld", TT.c);
+  if (TT.c == 0) TT.c = (toys.optflags&FLAG_i)?12:16;
 
   // Plain style is 30 bytes/line, no grouping.
-  if (FLAG(p)) TT.c = TT.g = 30;
+  if (toys.optflags&FLAG_p) TT.c = TT.g = 30;
 
   loopfiles(toys.optargs,
-    FLAG(r) ? do_xxd_reverse : (FLAG(i) ? do_xxd_include : do_xxd));
+    toys.optflags&FLAG_r ? do_xxd_reverse
+      : (toys.optflags&FLAG_i ? do_xxd_include : do_xxd));
 }
diff --git a/toys/pending/README b/toys/pending/README
index de44b02..2eb83e1 100644
--- a/toys/pending/README
+++ b/toys/pending/README
@@ -1,4 +1,4 @@
-Pending (unfinished) commands
+pending (see toys/pending/README)
 
 Commands in this directory are external submissions awaiting review and/or
 cleanup before being "promoted" to one of the other directories.
diff --git a/toys/pending/arp.c b/toys/pending/arp.c
index 5f7c4a1..eaecfc7 100644
--- a/toys/pending/arp.c
+++ b/toys/pending/arp.c
@@ -2,7 +2,7 @@
  *
  * Copyright 2014 Sandeep Sharma <sandeep.jack2756@gmail.com>
  * Copyright 2014 Kyungwan Han <asura321@gamil.com>
- * No Standard
+ * No Standard 
 
 USE_ARP(NEWTOY(arp, "vi:nDsdap:A:H:[+Ap][!sd]", TOYFLAG_USR|TOYFLAG_BIN))
 
@@ -17,17 +17,17 @@
     [-v]  [-H HWTYPE] [-i IF] -s HOSTNAME HWADDR [netmask MASK] pub
     [-v]  [-H HWTYPE] [-i IF] -Ds HOSTNAME IFACE [netmask MASK] pub
 
-    Manipulate ARP cache.
+    Manipulate ARP cache
 
-    -a	Display (all) hosts
-    -s	Set new ARP entry
-    -d	Delete a specified entry
-    -v	Verbose
-    -n	Don't resolve names
-    -i IFACE	Network interface
-    -D	Read <hwaddr> from given device
-    -A,-p AF	Protocol family
-    -H HWTYPE	Hardware address type
+    -a    Display (all) hosts
+    -s    Set new ARP entry
+    -d    Delete a specified entry
+    -v    Verbose
+    -n    Don't resolve names
+    -i IF Network interface
+    -D    Read <hwaddr> from given device
+    -A,-p AF  Protocol family
+    -H    HWTYPE Hardware address type
 
 */
 
@@ -40,12 +40,12 @@
     char *af_type_A;
     char *af_type_p;
     char *interface;
-
+    
     int sockfd;
     char *device;
 )
 
-struct arpreq req;
+struct arpreq req; //Global request structure 
 
 struct type {
   char *name;
@@ -53,7 +53,7 @@
 };
 
 struct type hwtype[] = {
-  {"ether", ARPHRD_ETHER },
+  {"ether", ARPHRD_ETHER }, 
   {"loop" ,ARPHRD_LOOPBACK},
   {"ppp" ,ARPHRD_PPP},
   {"infiniband" ,ARPHRD_INFINIBAND},
@@ -61,14 +61,14 @@
 };
 
 struct type aftype[] = {
-  {"inet", AF_INET },
+  {"inet", AF_INET }, 
   {"inet6" ,AF_INET6},
   {"unspec" ,AF_UNSPEC},
   {NULL, -1},
 };
 
 struct type flag_type[] = {
-  {"PERM", ATF_PERM },
+  {"PERM", ATF_PERM }, 
   {"PUB" ,ATF_PUBL},
   {"DONTPUB" ,ATF_DONTPUB},
   {"TRAIL" ,ATF_USETRAILERS},
@@ -78,18 +78,25 @@
 static int get_index(struct type arr[], char *name)
 {
   int i;
-
-  for (i = 0; arr[i].name; i++)
+  
+  for (i = 0; arr[i].name; i++) 
     if (!strcmp(arr[i].name, name)) break;
   return arr[i].val;
 }
 
 static void resolve_host(char *host, struct sockaddr *sa)
 {
-  struct addrinfo *ai = xgetaddrinfo(host, NULL, AF_INET, SOCK_STREAM, 0, 0);
+  struct addrinfo hints, *res = NULL;
+  int ret;
 
-  memcpy(sa, ai->ai_addr, ai->ai_addrlen);
-  freeaddrinfo(ai);
+  memset(&hints, 0, sizeof hints);
+  hints.ai_family = AF_INET;
+  hints.ai_socktype = SOCK_STREAM;
+  if ((ret = getaddrinfo(host, NULL, &hints, &res))) 
+    perror_exit("%s", gai_strerror(ret));
+
+  memcpy(sa, res->ai_addr, res->ai_addrlen);
+  freeaddrinfo(res);
 }
 
 static void check_flags(int *i, char** argv)
@@ -135,7 +142,7 @@
   
   if (!toys.optargs[1]) error_exit("bad syntax");
 
-  if (!FLAG(D)) {
+  if (!(toys.optflags & FLAG_D)) {
     char *ptr = toys.optargs[1];
     char *p = ptr, *hw_addr = req.arp_ha.sa_data;
 
@@ -155,7 +162,7 @@
 
     xstrncpy(ifre.ifr_name, toys.optargs[1], IFNAMSIZ);
     xioctl(TT.sockfd, SIOCGIFHWADDR, &ifre);
-    if (FLAG(H) && ifre.ifr_hwaddr.sa_family != ARPHRD_ETHER)
+    if ((toys.optflags & FLAG_H) && (ifre.ifr_hwaddr.sa_family != ARPHRD_ETHER)) 
       error_exit("protocol type mismatch");
     memcpy(&req.arp_ha, &(ifre.ifr_hwaddr), sizeof(req.arp_ha));
   }
@@ -165,12 +172,12 @@
   req.arp_flags = flags;
   xstrncpy(req.arp_dev, TT.device, sizeof(req.arp_dev));
   xioctl(TT.sockfd, SIOCSARP, &req);
-
-  if (FLAG(v)) xprintf("Entry set for %s\n", toys.optargs[0]);
+  
+  if (toys.optflags & FLAG_v) xprintf("Entry set for %s\n", toys.optargs[0]);
   return 0;
 }
 
-static int ip_to_host(struct sockaddr *sa, int flag)
+static int ip_to_host(struct sockaddr *sa, int flag) 
 {
   int status = 0;
   char hbuf[NI_MAXHOST] = {0,}, sbuf[NI_MAXSERV] = {0,}; 
@@ -187,51 +194,55 @@
 
 static int delete_entry(void)
 {
-  int flags = ATF_PERM;
-
+  int flags;
+  
+  flags = ATF_PERM;
   if (toys.optargs[1]) check_flags(&flags, (toys.optargs+1));
   req.arp_flags = flags;
   xstrncpy(req.arp_dev, TT.device, sizeof(req.arp_dev));
   xioctl(TT.sockfd, SIOCDARP, &req);
-
-  if (FLAG(v)) xprintf("Delete entry for  %s\n", toys.optargs[0]);
+  
+  if (toys.optflags & FLAG_v) xprintf("Delete entry for  %s\n", toys.optargs[0]);
   return 0;
 }
 
 void arp_main(void)
 {
   struct sockaddr sa;
-  char ip[16], hw_addr[30], mask[16], dev[16], *host_ip = NULL;
-  FILE *fp;
-  int h_type, type, flag, i, entries = 0, disp = 0;
+  char ip[128], hw_addr[128], mask[12], dev[128], *host_ip = NULL, *buf;
+  int h_type, type, flag, i, fd, entries = 0, disp = 0;
 
   TT.device = "";
   memset(&sa, 0, sizeof(sa));
+  memset(&req, 0, sizeof(req));
   TT.sockfd = xsocket(AF_INET, SOCK_STREAM, 0);
 
-  if (FLAG(A) || FLAG(p)) {
-    if ((type = get_index(aftype,
-            (TT.af_type_A)?TT.af_type_A:TT.af_type_p)) != AF_INET)
+  if ((toys.optflags & FLAG_A) || (toys.optflags & FLAG_p)) {
+    if ((type = get_index(aftype, 
+            (TT.af_type_A)?TT.af_type_A:TT.af_type_p)) != AF_INET) 
       error_exit((type != -1)?"only inet supported by kernel":"unknown family");
-  }
+  } 
 
   req.arp_ha.sa_family = ARPHRD_ETHER;
-  if (FLAG(H)) {
-    if ((type = get_index(hwtype, TT.hw_type)) != ARPHRD_ETHER)
+  if (toys.optflags & FLAG_H) {
+    if ((type = get_index(hwtype, TT.hw_type)) != ARPHRD_ETHER) 
       error_exit((type != -1)?"h/w type not supported":"unknown h/w type");
     req.arp_ha.sa_family = type;
   }
 
-  if (FLAG(s) || FLAG(d)) {
-    if (!toys.optargs[0]) error_exit("-%c needs a host name", FLAG(d)?'d':'s');
+  if (((toys.optflags & FLAG_s) || toys.optflags & FLAG_d)) { 
+    if (!toys.optargs[0]) error_exit("host name req");
     resolve_host(toys.optargs[0], &sa);
     memcpy(&req.arp_pa, &sa, sizeof(struct sockaddr));
-
-    if (FLAG(s) && !set_entry()) return;
-    if (FLAG(d) && !delete_entry()) return;
   }
 
-  // Show arp cache.
+  if ((toys.optflags & FLAG_s) && !set_entry()) return;
+  if ((toys.optflags & FLAG_d) && !delete_entry()) return; 
+
+  //show arp chache
+  fd = xopenro("/proc/net/arp");
+  buf = get_line(fd);
+  free(buf); //skip first line
 
   if (toys.optargs[0]) {
     resolve_host(toys.optargs[0], &sa);
@@ -239,27 +250,28 @@
     host_ip = xstrdup(toybuf);
   }
 
-  fp = xfopen("/proc/net/arp", "r");
-  fgets(toybuf, sizeof(toybuf), fp); // Skip header.
-  while (fscanf(fp, "%15s 0x%x 0x%x %29s %15s %15s",
-                ip, &h_type, &flag, hw_addr, mask, dev) == 6) {
+  while ((buf = get_line(fd))) {
     char *host_name = "?";
-
+    
+    if ((sscanf(buf, "%s 0x%x 0x%x %s %s %s\n", ip,
+        &h_type, &flag, hw_addr, mask, dev )) != 6) break;
     entries++;
-    if ((FLAG(H) && get_index(hwtype, TT.hw_type) != h_type) ||
-      (FLAG(i) && strcmp(TT.interface, dev)) ||
-      (toys.optargs[0] && strcmp(host_ip, ip))) {
+    if (((toys.optflags & FLAG_H) && (get_index(hwtype, TT.hw_type) != h_type))
+     || ((toys.optflags & FLAG_i) && strcmp(TT.interface, dev))
+     || (toys.optargs[0] && strcmp(host_ip, ip))) {
+      free(buf);
       continue;
     }
 
-    resolve_host(ip, &sa);
-    if (FLAG(n)) ip_to_host(&sa, NI_NUMERICHOST);
-    else if (!ip_to_host(&sa, NI_NAMEREQD)) host_name = toybuf;
-
+    resolve_host(buf, &sa);
+    if (!(toys.optflags & FLAG_n)) { 
+      if (!ip_to_host(&sa, NI_NAMEREQD)) host_name = toybuf;
+    } else ip_to_host(&sa, NI_NUMERICHOST);
+    
     disp++;
     printf("%s (%s) at" , host_name, ip);
 
-    for (i = 0; hwtype[i].name; i++)
+    for (i = 0; hwtype[i].name; i++) 
       if (hwtype[i].val & h_type) break;
     if (!hwtype[i].name) error_exit("unknown h/w type");
 
@@ -270,20 +282,21 @@
 
     if (flag & ATF_NETMASK) printf("netmask %s ", mask);
 
-    for (i = 0; flag_type[i].name; i++)
+    for (i = 0; flag_type[i].name; i++) 
       if (flag_type[i].val & flag) printf(" %s", flag_type[i].name);
 
     printf(" on %s\n", dev);
+    free(buf);
   }
-
-  if (FLAG(v))
+  
+  if (toys.optflags & FLAG_v) 
     xprintf("Entries: %d\tSkipped: %d\tFound: %d\n",
         entries, entries - disp, disp);
-  if (toys.optargs[0] && !disp)
-    xprintf("%s (%s) -- no entry\n", toys.optargs[0], host_ip);
-
+  if (!disp) xprintf("No Match found in %d entries\n", entries);
+  
   if (CFG_TOYBOX_FREE) {
     free(host_ip);
-    fclose(fp);
+    free(buf);
+    xclose(fd);
   }
 }
diff --git a/toys/pending/bc.c b/toys/pending/bc.c
index 3713140..2d92755 100644
--- a/toys/pending/bc.c
+++ b/toys/pending/bc.c
@@ -45,11 +45,6 @@
   uint16_t line_len;
 )
 
-struct str_len {
-  char *str;
-  long len;
-};
-
 #define BC_VM ((BcVm*) TT.vm)
 
 typedef enum BcStatus {
diff --git a/toys/pending/bootchartd.c b/toys/pending/bootchartd.c
index 7808428..3590c81 100644
--- a/toys/pending/bootchartd.c
+++ b/toys/pending/bootchartd.c
@@ -29,7 +29,7 @@
 #include "toys.h"
 
 GLOBALS(
-  char timestamp[32];
+  char buf[32];
   long msec;
   int proc_accounting;
 
@@ -41,7 +41,7 @@
   int rfd = open(fname, O_RDONLY);
 
   if (rfd != -1) {
-    xwrite(wfd, TT.timestamp, strlen(TT.timestamp));
+    xwrite(wfd, TT.buf, strlen(TT.buf));
     xsendfile(rfd, wfd);
     close(rfd);
     xwrite(wfd, "\n", 1);
@@ -55,7 +55,7 @@
   pid_t pid;
   DIR *proc_dir = opendir("/proc");
 
-  fputs(TT.timestamp, fp);
+  fputs(TT.buf, fp);
   while ((pid_dir = readdir(proc_dir))) {
     char filename[64];
     int fd;
@@ -134,7 +134,6 @@
 
 static void start_logging()
 {
-  struct timespec ts;
   int proc_stat_fd = xcreate("proc_stat.log",  
       O_WRONLY | O_CREAT | O_TRUNC, 0644);
   int proc_diskstats_fd = xcreate("proc_diskstats.log",  
@@ -149,16 +148,31 @@
     xclose(kp_fd);
     acct("kernel_procs_acct");
   }
+  memset(TT.buf, 0, sizeof(TT.buf));
   while (--tcnt && !toys.signal) {
-    clock_gettime(CLOCK_BOOTTIME, &ts);
-    sprintf(TT.timestamp, "%ld.%02d\n", (long) ts.tv_sec,
-        (int) (ts.tv_nsec/10000000));
+    int i = 0, j = 0, fd = open("/proc/uptime", O_RDONLY);
+    if (fd < 0) goto wait;
+    char *line = get_line(fd);
+
+    if (!line)  goto wait;
+    while (line[i] != ' ') {
+      if (line[i] == '.') {
+        i++;
+        continue;
+      }
+      TT.buf[j++] = line[i++];
+    }
+    TT.buf[j++] = '\n';
+    TT.buf[j] = 0;
+    free(line);
+    close(fd);
     dump_data_in_file("/proc/stat", proc_stat_fd);
     dump_data_in_file("/proc/diskstats", proc_diskstats_fd);
     // stop proc dumping in 2 secs if getty or gdm, kdm, xdm found 
     if (dump_proc_data(proc_ps_fp))
       if (tcnt > 2 * 1000 / TT.msec) tcnt = 2 * 1000 / TT.msec;
     fflush(0);
+wait:
     msleep(TT.msec);
   }
   xclose(proc_stat_fd);
diff --git a/toys/pending/chsh.c b/toys/pending/chsh.c
index 8d3390e..bf40978 100644
--- a/toys/pending/chsh.c
+++ b/toys/pending/chsh.c
@@ -8,7 +8,7 @@
 
 config CHSH
   bool "chsh"
-  default n
+  default y
   help
     usage: chsh [-s SHELL] [USER]
 
diff --git a/toys/pending/crond.c b/toys/pending/crond.c
index 81cc844..df8b5f1 100644
--- a/toys/pending/crond.c
+++ b/toys/pending/crond.c
@@ -371,29 +371,26 @@
   if (!(dp = opendir("."))) loginfo(LOG_EXIT, "chdir(%s)", ".");
 
   while ((entry = readdir(dp))) {
+    int fd;
+    char *line;
     CRONFILE *cfile;
-    FILE *fp;
-    char *line = 0;
-    size_t allocated_length = 0;
 
-    if (isdotdot(entry->d_name)) continue;
+    if (entry->d_name[0] == '.' && (!entry->d_name[1] ||
+          (entry->d_name[1] == '.' && !entry->d_name[2]))) 
+      continue;
 
     if (!getpwnam(entry->d_name)) {
       loginfo(LOG_LEVEL7, "ignoring file '%s' (no such user)", entry->d_name);
       continue;
     }
-
-    if (!(fp = fopen(entry->d_name, "r"))) continue;
+    if ((fd = open(entry->d_name, O_RDONLY)) < 0) continue;
 
     // one node for each user
     cfile = xzalloc(sizeof(CRONFILE));
     cfile->username = xstrdup(entry->d_name);
 
-    while (getline(&line, &allocated_length, fp) > 0) {
+    for (; (line = get_line(fd)); free(line))
       parse_line(line, cfile);
-    }
-    free(line);
-    fclose(fp);
 
     // If there is no job for a cron, remove the VAR list.
     if (!cfile->job) {
@@ -413,6 +410,7 @@
       dlist_add_nomalloc((struct double_list **)&gclist,
           (struct double_list *)cfile);
     }
+    close(fd);
   }
   closedir(dp);
 }
diff --git a/toys/pending/diff.c b/toys/pending/diff.c
index 4dd0165..e93c622 100644
--- a/toys/pending/diff.c
+++ b/toys/pending/diff.c
@@ -427,8 +427,8 @@
   char *reset = NULL;
 
   if (c != ' ' && (toys.optflags & FLAG_color)) {
-    printf("\e[%dm", c == '+' ? 32 : 31);
-    reset = "\e[0m";
+    printf("\033[%dm", c == '+' ? 32 : 31);
+    reset = "\033[0m";
   }
 
   for (i = a; i <= b; i++) {
@@ -639,7 +639,7 @@
   TT.status = change; //update status, may change bcoz of -w etc.
 
   if (!(toys.optflags & FLAG_q) && change) {  //start of !FLAG_q
-    if (toys.optflags & FLAG_color) printf("\e[1m");
+    if (toys.optflags & FLAG_color) printf("\033[1m");
     if (toys.optflags & FLAG_L) printf("--- %s\n", llist->arg);
     else show_label("---", files[0], &(TT).st[0]);
     if (((toys.optflags & FLAG_L) && !llist->next) || !(toys.optflags & FLAG_L))
@@ -648,7 +648,7 @@
       while (llist->next) llist = llist->next;
       printf("+++ %s\n", llist->arg);
     }
-    if (toys.optflags & FLAG_color) printf("\e[0m");
+    if (toys.optflags & FLAG_color) printf("\033[0m");
 
     struct diff *t, *ptr1 = d, *ptr2 = d;
     while (i) {
@@ -683,7 +683,7 @@
       start2 = MAX(1, ptr1->c - (ptr1->a - ptr1->suff));
       end2 = ptr2->prev - ptr2->b + ptr2->d;
 
-      if (toys.optflags & FLAG_color) printf("\e[36m");
+      if (toys.optflags & FLAG_color) printf("\033[36m");
       printf("@@ -%ld", start1 ? ptr1->suff: (ptr1->suff -1));
       if (end1 != -1) printf(",%ld ", ptr2->prev-ptr1->suff + 1);
       else putchar(' ');
@@ -692,7 +692,7 @@
       if ((end2 - start2 +1) != 1) printf(",%ld ", (end2 - start2 +1));
       else putchar(' ');
       printf("@@");
-      if (toys.optflags & FLAG_color) printf("\e[0m");
+      if (toys.optflags & FLAG_color) printf("\033[0m");
       putchar('\n');
 
       for (t = ptr1; t <= ptr2; t++) {
diff --git a/toys/pending/hexdump.c b/toys/pending/hexdump.c
deleted file mode 100644
index 5e367a2..0000000
--- a/toys/pending/hexdump.c
+++ /dev/null
@@ -1,155 +0,0 @@
-/* hexdump.c - Dump file content in hexadecimal format to stdout
- *
- * Copyright 2021 Moritz Röhrich <moritz@ildefons.de>
- *
- * No standard
- *
- * TODO:
- *  - Implement format strings (see man (1) hexdump)
-
-USE_HEXDUMP(NEWTOY(hexdump, "bcCdn#<0os#<0vx[!bcCdox]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_HD(OLDTOY(hd, hexdump, TOYFLAG_USR|TOYFLAG_BIN))
-
-config HEXDUMP
-  bool "hexdump"
-  default n
-  help
-    usage: hexdump [-bcCdovx] [-n LEN] [-s SKIP] [FILE...]
-
-    Dump file(s) in hexadecimal format.
-
-    -n LEN	Show LEN bytes of output
-    -s SKIP	Skip bytes of input
-    -v	Verbose (don't combine identical lines)
-
-    Display type:
-    -b One byte octal   -c One byte character -C Canonical (hex + ASCII)
-    -d Two byte decimal -o Two byte octal     -x Two byte hexadecimal (default)
-
-config HD
-  bool "hd"
-  default HEXDUMP
-  help
-    usage: hd [FILE...]
-
-    Display file(s) in cannonical hex+ASCII format.
-*/
-
-#define FOR_hexdump
-#include "toys.h"
-
-GLOBALS(
-    long s, n;
-
-    long long len, pos, ppos;
-    const char *fmt;
-    unsigned int fn, bc;  // file number and byte count
-    char linebuf[16];  // line buffer - serves double duty for sqeezing repeat
-                       // lines and for accumulating full lines accross file
-                       // boundaries if necessesary.
-)
-
-const char *make_printable(unsigned char byte) {
-  switch (byte) {
-    case '\0': return "\\0";
-    case '\a': return "\\a";
-    case '\b': return "\\b";
-    case '\t': return "\\t";
-    case '\n': return "\\n";
-    case '\v': return "\\v";
-    case '\f': return "\\f";
-    default: return "??";  // for all unprintable bytes
-  }
-}
-
-void do_hexdump(int fd, char *name)
-{
-  unsigned short block, adv, i;
-  int sl, fs;  // skip line, file size
-
-  TT.fn++;  // keep track of how many files have been printed.
-  // skipp ahead, if necessary skip entire files:
-  if (FLAG(s) && (TT.s-TT.pos>0)) {
-    fs = xlseek(fd, 0L, SEEK_END);
-
-    if (fs < TT.s) {
-      TT.pos += fs;
-      TT.ppos += fs;
-    } else {
-      xlseek(fd, TT.s-TT.pos, SEEK_SET);
-      TT.ppos = TT.s;
-      TT.pos = TT.s;
-    }
-  }
-
-  for (sl = 0;
-       0 < (TT.len = readall(fd, toybuf,
-                             (TT.n && TT.s+TT.n-TT.pos<16-(TT.bc%16))
-                                ? TT.s+TT.n-TT.pos : 16-(TT.bc%16)));
-       TT.pos += TT.len) {
-    // This block compares the data read from file to the last line printed.
-    // If they don't match a new line is printed, else the line is skipped.
-    // If a * has already been printed to indicate a skipped line, printing the
-    // * is also skipped.
-    for (i = 0; i < 16 && i < TT.len; i++){
-      if (FLAG(v) || TT.len < 16 || toybuf[i] != TT.linebuf[i]) goto newline;
-    }
-    if (sl == 0) {
-      printf("*\n");
-      sl = 1;
-    }
-    TT.ppos += TT.len;
-    continue;
-
-newline:
-    strncpy(TT.linebuf+(TT.bc%16), toybuf, TT.len);
-    TT.bc = TT.bc % 16 + TT.len;
-    sl = 0;
-    if (TT.pos + TT.bc == TT.s+TT.n || TT.fn == toys.optc || TT.bc == 16) {
-      if (!FLAG(C) && !FLAG(c)) {
-        printf("%07llx", TT.ppos);
-        adv = FLAG(b) ? 1 : 2;
-        for (i = 0; i < TT.bc; i += adv) {
-          block = (FLAG(b) || i == TT.bc-1)
-            ? TT.linebuf[i] : (TT.linebuf[i] | TT.linebuf[i+1] << 8);
-          printf(TT.fmt, block);
-        }
-      } else if (FLAG(C)) {
-        printf("%08llx", TT.ppos);
-        for (i = 0; i < 16; i++) {
-          if (!(i % 8)) putchar(' ');
-          if (i < TT.bc) printf(" %02x", TT.linebuf[i]);
-          else printf("   ");
-        }
-        printf("  |");
-        for (i = 0; i < TT.bc; i++) {
-          if (TT.linebuf[i] < ' ' || TT.linebuf[i] > '~') putchar('.');
-          else putchar(TT.linebuf[i]);
-        }
-        putchar('|');
-      } else {
-        printf("%07llx", TT.ppos);
-        for (i = 0; i < TT.bc; i++) {
-          if (TT.linebuf[i] >= ' ' && TT.linebuf[i] <= '~')
-            printf("%4c", TT.linebuf[i]);
-          else printf("%4s", make_printable(TT.linebuf[i]));
-        }
-      }
-      putchar('\n');
-      TT.ppos += TT.bc;
-    }
-  }
-
-  if (TT.len < 0) perror_exit("read");
-}
-
-void hexdump_main(void)
-{
-  if FLAG(b) TT.fmt = " %03o";
-  else if FLAG(d) TT.fmt = " %05d";
-  else if FLAG(o) TT.fmt = " %06o";
-  else TT.fmt = " %04x";
-
-  loopfiles(toys.optargs, do_hexdump);
-  FLAG(C) ? printf("%08llx\n", TT.pos) : printf("%07llx\n", TT.pos);
-}
diff --git a/toys/pending/host.c b/toys/pending/host.c
new file mode 100644
index 0000000..1610301
--- /dev/null
+++ b/toys/pending/host.c
@@ -0,0 +1,220 @@
+/* host.c - DNS lookup utility
+ *
+ * Copyright 2014 Rich Felker <dalias@aerifal.cx>
+ *
+ * No standard, but there's a version in bind9
+
+USE_HOST(NEWTOY(host, "<1>2avt:", TOYFLAG_USR|TOYFLAG_BIN))
+
+config HOST
+  bool "host"
+  default n
+  help
+    usage: host [-av] [-t TYPE] NAME [SERVER]
+
+    Perform DNS lookup on NAME, which can be a domain name to lookup,
+    or an IPv4 dotted or IPv6 colon-separated address to reverse lookup.
+    SERVER (if present) is the DNS server to use.
+
+    -a	-v -t ANY
+    -t TYPE	query records of type TYPE
+    -v	verbose
+*/
+
+#define FOR_host
+#include "toys.h"
+
+GLOBALS(
+  char *type_str;
+)
+
+#include <resolv.h>
+
+#define PL_IP 1
+#define PL_NAME 2
+#define PL_DATA 3
+#define PL_TEXT 4
+#define PL_SOA 5
+#define PL_MX 6
+#define PL_SRV 7
+
+static const struct rrt {
+  const char *name;
+  const char *msg;
+  int pl;
+  int af;
+} rrt[] = {
+  [1] = { "A", "has address", PL_IP, AF_INET },
+  [28] = { "AAAA", "has address", PL_IP, AF_INET6 },
+  [2] = { "NS", "name server", PL_NAME },
+  [5] = { "CNAME", "is a nickname for", PL_NAME },
+  [16] = { "TXT", "descriptive text", PL_TEXT },
+  [6] = { "SOA", "start of authority", PL_SOA },
+  [12] = { "PTR", "domain name pointer", PL_NAME },
+  [15] = { "MX", "mail is handled", PL_MX },
+  [33] = { "SRV", "mail is handled", PL_SRV },
+  [255] = { "*", 0, 0 },
+};
+
+static const char rct[16][32] = {
+  "Success",
+  "Format error",
+  "Server failure",
+  "Non-existant domain",
+  "Not implemented",
+  "Refused",
+};
+
+void host_main(void)
+{
+  int verbose=(toys.optflags & (FLAG_a|FLAG_v)), type,
+      i, j, ret, sec, count, rcode, qlen, alen, pllen = 0,
+      abuf_len = 65536; // Largest TCP response.
+  unsigned ttl, pri, v[5];
+  unsigned char *abuf = xmalloc(abuf_len);
+  char *rrname = xmalloc(MAXDNAME);
+  unsigned char qbuf[280], *p;
+  char *name, *nsname, plname[640], ptrbuf[128];
+  struct addrinfo *ai, iplit_hints = { .ai_flags = AI_NUMERICHOST };
+
+  name = *toys.optargs;
+  nsname = toys.optargs[1];
+
+  if (!TT.type_str && (toys.optflags & FLAG_a)) TT.type_str = "255";
+  if (!getaddrinfo(name, 0, &iplit_hints, &ai)) {
+    unsigned char *a;
+    static const char xdigits[] = "0123456789abcdef";
+
+    if (ai->ai_family == AF_INET) {
+      a = (void *)&((struct sockaddr_in *)ai->ai_addr)->sin_addr;
+      snprintf(ptrbuf, sizeof(ptrbuf), "%d.%d.%d.%d.in-addr.arpa",
+        a[3], a[2], a[1], a[0]);
+    } else if (ai->ai_family == AF_INET6) {
+      a = (void *)&((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
+      for (j=0, i=15; i>=0; i--) {
+        ptrbuf[j++] = xdigits[a[i]&15];
+        ptrbuf[j++] = '.';
+        ptrbuf[j++] = xdigits[a[i]>>4];
+        ptrbuf[j++] = '.';
+      }
+      strcpy(ptrbuf+j, "ip6.arpa");
+    }
+    name = ptrbuf;
+    if (!TT.type_str) TT.type_str="12";
+  } else if (!TT.type_str) TT.type_str="1";
+
+  if (TT.type_str[0]-'0' < 10u) type = atoi(TT.type_str);
+  else {
+    type = -1;
+    for (i=0; i<ARRAY_LEN(rrt); i++) {
+      if (rrt[i].name && !strcasecmp(TT.type_str, rrt[i].name)) {
+        type = i;
+        break;
+      }
+    }
+    if (!strcasecmp(TT.type_str, "any")) type = 255;
+    if (type < 0) error_exit("Invalid query type: %s", TT.type_str);
+  }
+
+  qlen = res_mkquery(0, name, 1, type, 0, 0, 0, qbuf, sizeof(qbuf));
+  if (qlen < 0) error_exit("Invalid query parameters: %s", name);
+
+  if (nsname) {
+    struct addrinfo ns_hints = { .ai_socktype = SOCK_DGRAM };
+
+    if ((ret = getaddrinfo(nsname, "53", &ns_hints, &ai)) < 0)
+      error_exit("Error looking up server name: %s", gai_strerror(ret));
+    int s = xsocket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
+    xconnect(s, ai->ai_addr, ai->ai_addrlen);
+    setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &(struct timeval){ .tv_sec = 5 },
+      sizeof(struct timeval));
+    printf("Using domain server %s:\n", nsname);
+    send(s, qbuf, qlen, 0);
+    alen = recv(s, abuf, abuf_len, 0);
+  } else alen = res_send(qbuf, qlen, abuf, abuf_len);
+
+  if (alen < 12) error_exit("Host not found.");
+
+  rcode = abuf[3] & 15;
+
+  if (verbose) {
+    printf("rcode = %d (%s), ancount = %d\n",
+      rcode, rct[rcode], 256*abuf[6] + abuf[7]);
+    if (!(abuf[2] & 4)) printf("The following answer is not authoritative:\n");
+  }
+
+  if (rcode) error_exit("Host not found.");
+
+  p = abuf + 12;
+  for (sec=0; sec<4; sec++) {
+    count = 256*abuf[4+2*sec] + abuf[5+2*sec];
+    if (verbose && count>0 && sec>1) 
+      puts(sec==2 ? "For authoritative answers, see:"
+        : "Additional information:");
+
+    for (; count--; p += pllen) {
+      p += dn_expand(abuf, abuf+alen, p, rrname, MAXDNAME);
+      type = (p[0]<<8) + p[1];
+      p += 4;
+      if (!sec) continue;
+      ttl = (p[0]<<24)+(p[1]<<16)+(p[2]<<8)+p[3];
+      p += 4;
+      pllen = (p[0]<<8) + p[1];
+      p += 2;
+
+      switch (type<ARRAY_LEN(rrt) ? rrt[type].pl : 0) {
+      case PL_IP:
+        inet_ntop(rrt[type].af, p, plname, sizeof(plname));
+        break;
+      case PL_NAME:
+        dn_expand(abuf, abuf+alen, p, plname, sizeof(plname));
+        break;
+      case PL_TEXT:
+        snprintf(plname, sizeof(plname), "\"%.*s\"", pllen, p);
+        break;
+      case PL_SOA:
+        i = dn_expand(abuf, abuf+alen, p, plname, sizeof(plname) - 1);
+        strcat(plname, " ");
+        i += dn_expand(abuf, abuf+alen, p+i, plname+strlen(plname),
+          sizeof(plname)-strlen(plname));
+        for (j=0; j<5; j++)
+          v[j] = (p[i+4*j]<<24)+(p[1+i+4*j]<<16)+(p[2+i+4*j]<<8)+p[3+i+4*j];
+        snprintf(plname+strlen(plname), sizeof(plname)-strlen(plname),
+          "(\n\t\t%u\t;serial (version)\n"
+          "\t\t%u\t;refresh period\n"
+          "\t\t%u\t;retry interval\n"
+          "\t\t%u\t;expire time\n"
+          "\t\t%u\t;default ttl\n"
+          "\t\t)", v[0], v[1], v[2], v[3], v[4]);
+        break;
+      case PL_MX:
+        pri = (p[0]<<8)+p[1];
+        snprintf(plname, sizeof(plname), verbose ? "%d " : "(pri=%d) by ", pri);
+        dn_expand(abuf, abuf+alen, p+2, plname+strlen(plname),
+          sizeof(plname) - strlen(plname));
+        break;
+      case PL_SRV:
+        for (j=0; j<3; j++) v[j] = (p[2*j]<<8) + p[1+2*j];
+        snprintf(plname, sizeof(plname), "%u %u %u ", v[0], v[1], v[2]);
+        dn_expand(abuf, abuf+alen, p+6, plname+strlen(plname),
+          sizeof(plname) - strlen(plname));
+        break;
+      default:
+        printf("%s unsupported RR type %u\n", rrname, type);
+        continue;
+      }
+
+      if (verbose)
+        printf("%s\t%u\tIN %s\t%s\n", rrname, ttl, rrt[type].name, plname);
+      else if (rrt[type].msg)
+        printf("%s %s %s\n", rrname, rrt[type].msg, plname);
+    }
+    if (!verbose && sec==1) break;
+  }
+
+  if (CFG_TOYBOX_FREE) {
+    free(abuf);
+    free(rrname);
+  }
+  toys.exitval = rcode;
+}
diff --git a/toys/pending/init.c b/toys/pending/init.c
index 05afb71..afc9a3e 100644
--- a/toys/pending/init.c
+++ b/toys/pending/init.c
@@ -93,7 +93,7 @@
   tcsetattr(fd, TCSANOW, &terminal);
 }
 
-static void add_new_action(int action, char *command, char *term)
+static void add_new_action(uint8_t action,char *command,char *term)
 {
   struct action_list_seed *x,**y;
 
@@ -120,66 +120,72 @@
   *y = x;
 }
 
-static void parse_inittab(void)
+static void inittab_parsing(void)
 {
-  char *line = 0;
-  size_t allocated_length = 0;
-  int line_number = 0;
+  int i, fd, line_number = 0, token_count = 0;
+  char *p, *q, *extracted_token, *tty_name = NULL, *command = NULL, *tmp;
+  uint8_t action = 0;
   char *act_name = "sysinit\0wait\0once\0respawn\0askfirst\0ctrlaltdel\0"
                     "shutdown\0restart\0";
-  FILE *fp = fopen("/etc/inittab", "r");
 
-  if (!fp) {
+  fd = open("/etc/inittab", O_RDONLY);
+  if (fd < 0) {
     error_msg("Unable to open /etc/inittab. Using Default inittab");
     add_new_action(SYSINIT, "/etc/init.d/rcS", "");
     add_new_action(RESPAWN, "/sbin/getty -n -l /bin/sh -L 115200 tty1 vt100", "");
-    return;
-  }
+  } else {
+    while((q = p = get_line(fd))) { //read single line from /etc/inittab
+      char *x;
 
-  while (getline(&line, &allocated_length, fp) > 0) {
-    char *p = line, *x, *tty_name = 0, *command = 0, *extracted_token, *tmp;
-    int action = 0, token_count = 0, i;
+      if ((x = strchr(p, '#'))) *x = '\0';
+      line_number++;
+      token_count = 0;
+      action = 0;
+      tty_name = command = NULL;
 
-    if ((x = strchr(p, '#'))) *x = '\0';
-    line_number++;
-    action = 0;
-
-    while ((extracted_token = strsep(&p,":"))) {
-      token_count++;
-      switch (token_count) {
-        case 1:
-          if (*extracted_token) {
-            if (!strncmp(extracted_token, "/dev/", 5))
-              tty_name = xmprintf("%s",extracted_token);
-            else tty_name = xmprintf("/dev/%s",extracted_token);
-          } else tty_name = xstrdup("");
-          break;
-        case 2:
-          break;
-        case 3:
-          for (tmp = act_name, i = 0; *tmp; i++, tmp += strlen(tmp) +1) {
-            if (!strcmp(tmp, extracted_token)) {
-              action = 1 << i;
-              break;
+      while ((extracted_token = strsep(&p,":"))) {
+        token_count++;
+        switch (token_count) {
+          case 1:
+            if (*extracted_token) {
+              if (!strncmp(extracted_token, "/dev/", 5))
+                tty_name = xmprintf("%s",extracted_token);
+              else tty_name = xmprintf("/dev/%s",extracted_token);
+            } else tty_name = xstrdup("");
+            break;
+          case 2:
+            break;
+          case 3:
+            for (tmp = act_name, i = 0; *tmp; i++, tmp += strlen(tmp) +1) {
+              if (!strcmp(tmp, extracted_token)) {
+                action = 1 << i;
+                break;
+              }
             }
-          }
-          if (!*tmp) error_msg("Invalid action at line number %d ---- ignoring",line_number);
-          break;
-        case 4:
-          command = xstrdup(extracted_token);
-          break;
-        default:
-          error_msg("Bad inittab entry at line %d", line_number);
-          break;
-      }
-    }  //while token
+            if (!*tmp) error_msg("Invalid action at line number %d ---- ignoring",line_number);
+            break;
+          case 4:
+            command = xstrdup(extracted_token);
+            break;
+          default:
+            error_msg("Bad inittab entry at line %d", line_number);
+            break;
+        }
+      }  //while token
 
-    if (token_count == 4 && action) add_new_action(action, command, tty_name);
-    free(tty_name);
-    free(command);
+      if (q) free(q);
+      if (token_count != 4) {
+        free(tty_name);
+        free(command);
+        continue;
+      }
+      if (action) add_new_action(action, command, tty_name);
+      free(tty_name);
+      free(command);
+    } //while line
+
+    close(fd);
   }
-  free(line);
-  fclose(fp);
 }
 
 static void reload_inittab(void)
@@ -198,7 +204,7 @@
     }
     y = &(*y)->next;
   }
-  parse_inittab();
+  inittab_parsing();
 }
 
 static void run_command(char *command)
@@ -326,7 +332,7 @@
 {
   sigset_t signal_set_c;
 
-  xsignal_all_killers(SIG_DFL);
+  sigatexit(SIG_DFL);
   sigfillset(&signal_set_c);
   sigprocmask(SIG_UNBLOCK,&signal_set_c, NULL);
 
@@ -472,7 +478,7 @@
   putenv("SHELL=/bin/sh");
   putenv("USER=root");
 
-  parse_inittab();
+  inittab_parsing();  
   xsignal(SIGUSR1, halt_poweroff_reboot_handler);//halt
   xsignal(SIGUSR2, halt_poweroff_reboot_handler);//poweroff
   xsignal(SIGTERM, halt_poweroff_reboot_handler);//reboot
diff --git a/toys/pending/ip.c b/toys/pending/ip.c
index 6676ffe..d8c891a 100644
--- a/toys/pending/ip.c
+++ b/toys/pending/ip.c
@@ -34,7 +34,6 @@
 #include <net/if_arp.h>
 #include <ifaddrs.h>
 #include <fnmatch.h>
-#include <linux/ip.h> // Centos 7.2 EOL June 30 2024
 #include <linux/if_tunnel.h>
 
 #ifndef IP_DF
diff --git a/toys/pending/lsof.c b/toys/pending/lsof.c
index e4b5311..5ab3af9 100644
--- a/toys/pending/lsof.c
+++ b/toys/pending/lsof.c
@@ -115,7 +115,7 @@
 
   if (!fp) return;
 
-  if (getline(&line, &line_length, fp) <= 0) return; // Skip header.
+  if (!getline(&line, &line_length, fp)) return; // Skip header.
 
   while (getline(&line, &line_length, fp) > 0) {
     fn(line, family, type);
@@ -330,10 +330,10 @@
 {
   FILE *fp;
   unsigned long long offset;
+  char device[10];
   long inode;
-  char *line = NULL, device[10]; // xxx:xxxxx\0
+  char *line = NULL;
   size_t line_length = 0;
-  struct file_info *fi;
 
   snprintf(toybuf, sizeof(toybuf), "/proc/%d/maps", pi->pid);
   fp = fopen(toybuf, "r");
@@ -342,8 +342,10 @@
   while (getline(&line, &line_length, fp) > 0) {
     int name_pos;
 
-    if (sscanf(line, "%*x-%*x %*s %llx %9s %ld %n",
+    if (sscanf(line, "%*x-%*x %*s %llx %s %ld %n",
                &offset, device, &inode, &name_pos) >= 3) {
+      struct file_info *fi;
+
       // Ignore non-file maps.
       if (inode == 0 || !strcmp(device, "00:00")) continue;
       // TODO: show unique maps even if they have a non-zero offset?
diff --git a/toys/pending/modprobe.c b/toys/pending/modprobe.c
index 45f8ea2..7424e7c 100644
--- a/toys/pending/modprobe.c
+++ b/toys/pending/modprobe.c
@@ -16,17 +16,18 @@
     modprobe utility - inserts modules and dependencies.
 
     -a  Load multiple MODULEs
-    -b  Apply blacklist to module names too
-    -D  Show dependencies
     -d  Load modules from DIR, option may be used multiple times
     -l  List (MODULE is a pattern)
-    -q  Quiet
     -r  Remove MODULE (stacks) or do autoclean
-    -s  Log to syslog
+    -q  Quiet
     -v  Verbose
+    -s  Log to syslog
+    -D  Show dependencies
+    -b  Apply blacklist to module names too
 */
 #define FOR_modprobe
 #include "toys.h"
+#include <sys/syscall.h>
 
 GLOBALS(
   struct arg_list *dirs;
@@ -36,6 +37,10 @@
   int nudeps, symreq;
 )
 
+/* Note: if "#define DBASE_SIZE" modified, 
+ * Please update GLOBALS dbase[256] accordingly.
+ */
+#define DBASE_SIZE  256
 #define MODNAME_LEN 256
 
 // Modules flag definations
@@ -141,7 +146,7 @@
 
   path2mod(mod, name);
   for (i = 0; name[i]; i++) hash = ((hash*31) + hash) + name[i];
-  hash %= ARRAY_LEN(TT.dbase);
+  hash %= DBASE_SIZE;
   for (temp = TT.dbase[hash]; temp; temp = temp->next) {
     modentry = (struct module_s *) temp->arg;
     if (!strcmp(modentry->name, name)) return modentry;
@@ -154,7 +159,7 @@
 }
 
 /*
- * Read a line from file with \ continuation and skip commented lines.
+ * Read a line from file with \ continuation and escape commented line.
  * Return the line in allocated string (*li)
  */
 static int read_line(FILE *fl, char **li)
@@ -219,7 +224,7 @@
     free(filename);
     return 0;
   }
-  for (line = linecp = NULL; read_line(fc, &line) >= 0;
+  for (line = linecp = NULL; read_line(fc, &line) > 0; 
       free(line), free(linecp), line = linecp = NULL) {
     char *tk = NULL;
 
@@ -233,18 +238,17 @@
         break;
       }
     }
-    // Every command requires at least one argument.
-    if (tcount < 2) continue;
+    if (!tk) continue; 
     // process the tokens[0] contains first word of config line.
     if (!strcmp(tokens[0], "alias")) {
       struct arg_list *temp;
-      char alias[MODNAME_LEN], *realname;
+      char aliase[MODNAME_LEN], *realname;
 
       if (!tokens[2]) continue;
-      path2mod(tokens[1], alias);
+      path2mod(tokens[1], aliase);
       for (temp = TT.probes; temp; temp = temp->next) {
         modent = (struct module_s *) temp->arg;
-        if (fnmatch(alias, modent->name, 0)) continue;
+        if (fnmatch(aliase, modent->name, 0)) continue;
         realname = path2mod(tokens[2], NULL);
         llist_add(&modent->rnames, realname);
         if (modent->flags & MOD_NDDEPS) {
@@ -278,16 +282,17 @@
 // Show matched modules else return -1 on failure.
 static int depmode_read_entry(char *cmdname)
 {
-  char *line, *name;
+  char *line;
   int ret = -1;
   FILE *fe = xfopen("modules.dep", "r");
 
-  while (read_line(fe, &line) >= 0) {
+  while (read_line(fe, &line) > 0) {
     char *tmp = strchr(line, ':');
 
     if (tmp) {
       *tmp = '\0';
-      name = basename(line);
+     char *name = basename(line);
+
       tmp = strchr(name, '.');
       if (tmp) *tmp = '\0';
       if (!cmdname || !fnmatch(cmdname, name, 0)) {
@@ -309,7 +314,7 @@
   struct module_s *mod;
   FILE *fe = xfopen("modules.dep", "r");
 
-  for (; read_line(fe, &line) >= 0; free(line)) {
+  for (; read_line(fe, &line) > 0; free(line)) {
     char *tmp = strchr(line, ':');
 
     if (tmp) {
@@ -338,22 +343,47 @@
 }
 
 // Remove a module from the Linux Kernel. if !modules does auto remove.
-static int rm_mod(char *modules)
+static int rm_mod(char *modules, unsigned flags)
 {
   char *s;
 
   if (modules && (s = strend(modules, ".ko"))) *s = 0;
-  return syscall(__NR_delete_module, modules, O_NONBLOCK);
+  errno = 0;
+  syscall(__NR_delete_module, modules, flags ? : O_NONBLOCK|O_EXCL);
+
+  return errno;
 }
 
-// Insert module; simpler than insmod(1) because we already flattened the array
-// of flags, and don't need to support loading from stdin.
+// Insert module same as insmod implementation.
 static int ins_mod(char *modules, char *flags)
 {
-  int fd = xopenro(modules), rc = syscall(__NR_finit_module, fd, flags, 0);
+  char *buf = NULL;
+  int len, res;
+  int fd = xopenro(modules);
 
+  while (flags && strlen(toybuf) + strlen(flags) + 2 < sizeof(toybuf)) {
+    strcat(toybuf, flags);
+    strcat(toybuf, " ");
+  }
+
+#ifdef __NR_finit_module
+  res = syscall(__NR_finit_module, fd, toybuf, 0);
+  if (!res || errno != ENOSYS) {
+    xclose(fd);
+    return res;
+  }
+#endif
+
+  // TODO xreadfile()
+
+  len = fdlength(fd);
+  buf = xmalloc(len);
+  xreadall(fd, buf, len);
   xclose(fd);
-  return rc;
+
+  res = syscall(__NR_init_module, buf, len, toybuf);
+  if (CFG_TOYBOX_FREE && buf != toybuf) free(buf);
+  return res;
 }
 
 // Add module in probes list, if not loaded.
@@ -394,13 +424,13 @@
 }
 
 // Probes a single module and loads all its dependencies.
-static void go_probe(struct module_s *m)
+static int go_probe(struct module_s *m)
 {
   int rc = 0, first = 1;
 
   if (!(m->flags & MOD_FNDDEPMOD)) {
     if (!FLAG(q)) error_msg("module %s not found in modules.dep", m->name);
-    return;
+    return -ENOENT;
   }
   if (FLAG(v)) printf("go_prob'ing %s\n", m->name);
   if (!FLAG(r)) m->dep = llist_rev(m->dep);
@@ -415,7 +445,7 @@
     // are we removing ?
     if (FLAG(r)) {
       if (m2->flags & MOD_ALOADED) {
-        if (rm_mod(m2->name)) {
+        if ((rc = rm_mod(m2->name, O_EXCL))) {
           if (first) {
             perror_msg("can't unload module %s", m2->name);
             break;
@@ -455,6 +485,7 @@
     }
     m2->flags |= MOD_ALOADED;
   }
+  return rc;
 }
 
 void modprobe_main(void)
@@ -467,7 +498,7 @@
   if (toys.optc<1 && !FLAG(r) == !FLAG(l)) help_exit("bad syntax");
   // Check for -r flag without arg if yes then do auto remove.
   if (FLAG(r) && !toys.optc) {
-    if (rm_mod(0)) perror_exit("rmmod");
+    if (rm_mod(0, O_NONBLOCK|O_EXCL)) perror_exit("rmmod");
     return;
   }
 
@@ -498,7 +529,7 @@
     procline = NULL;
   }
   fclose(fs);
-  if (FLAG(a) || FLAG(r)) for (; *argv; argv++) add_mod(*argv);
+  if (FLAG(a) || FLAG(r)) while (argv) add_mod(*argv++);
   else {
     add_mod(*argv);
     TT.cmdopts = add_cmdopt(argv);
diff --git a/toys/pending/openvt.c b/toys/pending/openvt.c
new file mode 100644
index 0000000..3cc97da
--- /dev/null
+++ b/toys/pending/openvt.c
@@ -0,0 +1,102 @@
+/* openvt.c - Run a program on a new VT
+ *
+ * Copyright 2014 Vivek Kumar Bhagat <vivek.bhagat89@gmail.com>
+ *
+ * No Standard
+
+USE_OPENVT(NEWTOY(openvt, "c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
+USE_DEALLOCVT(NEWTOY(deallocvt, ">1", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_NEEDROOT))
+
+config OPENVT
+  bool "openvt"
+  default n
+  depends on TOYBOX_FORK
+  help
+    usage: openvt [-c NUM] [-sw] [COMMAND...]
+
+    Start a program on a new virtual terminal.
+
+    -c NUM  Use VT NUM
+    -s    Switch to new VT
+    -w    Wait for command to exit
+
+    Together -sw switch back to originating VT when command completes.
+
+config DEALLOCVT
+  bool "deallocvt"
+  default n
+  help
+    usage: deallocvt [NUM]
+
+    Deallocate unused virtual terminals, either a specific /dev/ttyNUM, or all.
+*/
+
+#define FOR_openvt
+#include "toys.h"
+#include <linux/vt.h>
+#include <linux/kd.h>
+
+GLOBALS(
+  long c;
+)
+
+int open_console(void)
+{
+  char arg = 0, *console_name[] = {"/dev/tty", "/dev/tty0", "/dev/console"};
+  int i, fd;
+
+  for (i = 0; i < ARRAY_LEN(console_name); i++) {
+    if (0>(fd = open(console_name[i], O_RDWR))) continue;
+    if (!ioctl(fd, KDGKBTYPE, &arg)) return fd;
+    close(fd);
+  }
+  for (fd = 0; fd < 3; fd++) if (!ioctl(fd, KDGKBTYPE, &arg)) return fd;
+  error_exit("can't open console");
+}
+
+void openvt_main(void)
+{
+  struct vt_stat vstate;
+  int fd;
+  pid_t pid;
+
+  // find current console
+  if (-1 == (ioctl(fd = open_console(), VT_GETSTATE, &vstate)) ||
+      (!TT.c && 0>=(TT.c = xioctl(fd, VT_OPENQRY, &fd))))
+    perror_exit("can't find open VT");
+
+  sprintf(toybuf, "/dev/tty%ld", TT.c);
+  close(0);  //new vt becomes stdin
+  dup2(dup2(xopen_stdio(toybuf, O_RDWR), 1), 2);
+  if (FLAG(s)) {
+    ioctl(0, VT_ACTIVATE, (int)TT.c);
+    ioctl(0, VT_WAITACTIVE, (int)TT.c);
+  }
+
+  if (!(pid = xfork())) {
+    setsid();
+    ioctl(0, TIOCSCTTY, 0);
+    if (fd>2) close(fd);
+    xexec(toys.optargs);
+  }
+
+  if (FLAG(w)) {
+    while (-1 == waitpid(pid, NULL, 0) && errno == EINTR);
+    if (FLAG(s)) {
+      ioctl(fd, VT_ACTIVATE, vstate.v_active);
+      ioctl(fd, VT_WAITACTIVE, vstate.v_active);
+      ioctl(fd, VT_DISALLOCATE, (int)TT.c);
+    }
+  }
+  close(fd);
+}
+
+void deallocvt_main(void)
+{
+  int fd, vt_num = 0; // 0 = all
+
+  if (*toys.optargs) vt_num = atolx_range(*toys.optargs, 1, 63);
+  if (-1 == ioctl(fd = open_console(), VT_DISALLOCATE, vt_num))
+    perror_exit("%d", vt_num);
+  close(fd);
+}
diff --git a/toys/other/readelf.c b/toys/pending/readelf.c
similarity index 82%
rename from toys/other/readelf.c
rename to toys/pending/readelf.c
index 29e2724..e6e1623 100644
--- a/toys/other/readelf.c
+++ b/toys/pending/readelf.c
@@ -8,7 +8,7 @@
 
 config READELF
   bool "readelf"
-  default y
+  default n
   help
     usage: readelf [-adehlnSs] [-p SECTION] [-x SECTION] [file...]
 
@@ -54,12 +54,8 @@
 
 static long long elf_get(char **p, int len)
 {
-  long long result;
+  long long result = ((TT.endian == 2) ? peek_be : peek_le)(*p, len);
 
-  if (*p+len-TT.elf>TT.size)
-    perror_exit("Access off end: %td[%d] of %lld\n", *p-TT.elf, len, TT.size);
-
-  result = ((TT.endian == 2) ? peek_be : peek_le)(*p, len);
   *p += len;
   return result;
 }
@@ -122,15 +118,17 @@
 static int find_section(char *spec, struct sh *s)
 {
   char *end;
-  unsigned i;
+  int i;
 
   // Valid section number?
-  i = estrtol(spec, &end, 0);
-  if (!errno && !*end && i<TT.shnum) return get_sh(i, s);
+  errno = 0;
+  i = strtoul(spec, &end, 0);
+  if (!errno && !*end && i < TT.shnum) return get_sh(i, s);
 
   // Search the section names.
-  for (i=0; i<TT.shnum; i++)
+  for (i=0; i<TT.shnum; i++) {
     if (get_sh(i, s) && !strcmp(s->name, spec)) return 1;
+  }
 
   error_msg("%s: no section '%s", TT.f, spec);
   return 0;
@@ -245,16 +243,17 @@
   char *symtab = TT.elf+table->offset, *ndx;
   int numsym = table->size/(TT.bits ? 24 : 16), i;
 
-  if (!numsym) return;
+  if (numsym == 0) return;
 
   xputc('\n');
   printf("Symbol table '%s' contains %d entries:\n"
          "   Num:    %*s  Size Type    Bind   Vis      Ndx Name\n",
          table->name, numsym, 5+8*TT.bits, "Value");
   for (i=0; i<numsym; i++) {
-    unsigned st_name = elf_int(&symtab), st_value, st_shndx, st_info, st_other;
+    unsigned st_name = elf_int(&symtab), st_value, st_shndx;
+    unsigned char st_info, st_other;
     unsigned long st_size;
-    char *name, buf[16];
+    char *name;
 
     // The various fields were moved around for 64-bit.
     if (TT.bits) {
@@ -271,13 +270,12 @@
       st_shndx = elf_short(&symtab);
     }
 
-    // TODO: why do we trust name to be null terminated?
     name = TT.elf + strtab->offset + st_name;
     if (name >= TT.elf+TT.size) name = "???";
 
     if (!st_shndx) ndx = "UND";
     else if (st_shndx==0xfff1) ndx = "ABS";
-    else sprintf(ndx = buf, "%d", st_shndx);
+    else sprintf(ndx = toybuf, "%d", st_shndx);
 
     // TODO: look up and show any symbol versions with @ or @@.
 
@@ -287,11 +285,10 @@
   }
 }
 
-static int notematch(int namesz, char **p, char *expected)
+static int notematch(int namesz, char **p, char *expected, int len)
 {
-  if (namesz!=strlen(expected)+1 || strcmp(*p, expected)) return 0;
+  if (namesz != len || memcmp(*p, expected, namesz)) return 0;
   *p += namesz;
-
   return 1;
 }
 
@@ -301,46 +298,44 @@
 
   if (size > TT.size || offset > TT.size-size) {
     printf("Bad note bounds %lu/%lu\n", offset, size);
-
     return;
   }
 
-  printf("  %-20s%11s\tDescription\n", "Owner", "Data size");
+  printf("  %-20s %10s\tDescription\n", "Owner", "Data size");
   while (note < TT.elf+offset+size) {
     char *p = note, *desc;
     unsigned namesz=elf_int(&p), descsz=elf_int(&p), type=elf_int(&p), j=0;
 
-    if (namesz > size || descsz > size)
-      return error_msg("%s: bad note @%lu", TT.f, offset);
+    if (namesz > size || descsz > size) {
+      error_msg("%s: bad note @%lu", TT.f, offset);
+      return;
+    }
     printf("  %-20.*s 0x%08x\t", namesz, p, descsz);
-    if (notematch(namesz, &p, "GNU")) {
+    if (notematch(namesz, &p, "GNU", 4)) {
       if (type == 1) {
         printf("NT_GNU_ABI_TAG\tOS: %s, ABI: %u.%u.%u",
           !elf_int(&p)?"Linux":"?", elf_int(&p), elf_int(&p), elf_int(&p)), j=1;
       } else if (type == 3) {
-// TODO should this set j=1?
         printf("NT_GNU_BUILD_ID\t");
         for (;j<descsz;j++) printf("%02x", *p++);
       } else if (type == 4) {
         printf("NT_GNU_GOLD_VERSION\t%.*s", descsz, p), j=1;
       } else p -= 4;
-    } else if (notematch(namesz, &p, "Android")) {
+    } else if (notematch(namesz, &p, "Android", 8)) {
       if (type == 1) {
         printf("NT_VERSION\tAPI level %u", elf_int(&p)), j=1;
         if (descsz>=132) printf(", NDK %.64s (%.64s)", p, p+64);
       } else p -= 8;
-    } else if (notematch(namesz, &p, "CORE")) {
+    } else if (notematch(namesz, &p, "CORE", 5)) {
       if (*(desc = nt_type_core(type)) != '0') printf("%s", desc), j=1;
-// TODO else p -= 5?
-    } else if (notematch(namesz, &p, "LINUX")) {
+    } else if (notematch(namesz, &p, "LINUX", 6)) {
       if (*(desc = nt_type_linux(type)) != '0') printf("%s", desc), j=1;
-// TODO else p -= 6?
     }
 
     // If we didn't do custom output above, show a hex dump.
     if (!j) {
       printf("0x%x\t", type);
-      for (;j<descsz;j++) printf("%c%02x", j ? ' ' : '\t', *p++/*note[16+j]*/);
+      for (;j<descsz;j++) printf("%c%02x",!j?'\t':' ', *p++/*note[16+j]*/);
     }
     xputc('\n');
     note += 3*4 + ((namesz+3)&~3) + ((descsz+3)&~3);
@@ -355,13 +350,17 @@
   char *hdr = TT.elf;
   int type, machine, version, flags, entry, ehsize, phnum, shstrndx, i, j, w;
 
-  if (TT.size < 45 || memcmp(hdr, "\177ELF", 4)) 
-    return error_msg("%s: not ELF", TT.f);
+  if (TT.size < 45 || memcmp(hdr, "\177ELF", 4)) {
+    error_msg("%s: not ELF", TT.f);
+    return;
+  }
 
   TT.bits = hdr[4] - 1;
   TT.endian = hdr[5];
-  if (TT.bits<0 || TT.bits>1 || TT.endian<1 || TT.endian>2 || hdr[6]!=1)
-    return error_msg("%s: bad ELF", TT.f);
+  if (TT.bits<0 || TT.bits>1 || TT.endian<1 || TT.endian>2 || hdr[6]!=1) {
+    error_msg("%s: bad ELF", TT.f);
+    return;
+  }
 
   hdr += 16; // EI_NIDENT
   type = elf_short(&hdr);
@@ -383,7 +382,7 @@
   if (FLAG(h)) {
     printf("ELF Header:\n");
     printf("  Magic:   ");
-    for (i=0; i<16; i++) printf("%02x%c", TT.elf[i], (i==15) ? '\n' : ' ');
+    for (i=0; i<16; i++) printf("%02x%c", TT.elf[i], i==15?'\n':' ');
     printf("  Class:                             ELF%d\n", TT.bits?64:32);
     printf("  Data:                              2's complement, %s endian\n",
            (TT.endian==2)?"big":"little");
@@ -406,16 +405,24 @@
     printf("  Number of section headers:         %d\n", TT.shnum);
     printf("  Section header string table index: %d\n", shstrndx);
   }
-  if (TT.phoff > TT.size) return error_msg("%s: bad phoff", TT.f);
-  if (TT.shoff > TT.size) return error_msg("%s: bad shoff", TT.f);
+  if (TT.phoff > TT.size) {
+    error_msg("%s: bad phoff", TT.f);
+    return;
+  }
+  if (TT.shoff > TT.size) {
+    error_msg("%s: bad shoff", TT.f);
+    return;
+  }
 
   // Set up the section header string table so we can use section header names.
   // Core files have shstrndx == 0.
   TT.shstrtab = 0;
   TT.shstrtabsz = 0;
-  if (shstrndx) {
-    if (!get_sh(shstrndx, &shstr) || shstr.type != 3 /*SHT_STRTAB*/)
-      return error_msg("%s: bad shstrndx", TT.f);
+  if (shstrndx != 0) {
+    if (!get_sh(shstrndx, &shstr) || shstr.type != 3 /*SHT_STRTAB*/) {
+      error_msg("%s: bad shstrndx", TT.f);
+      return;
+    }
     TT.shstrtab = TT.elf+shstr.offset;
     TT.shstrtabsz = shstr.size;
   }
@@ -424,10 +431,12 @@
   if (FLAG(S)) {
     if (!TT.shnum) printf("\nThere are no sections in this file.\n");
     else {
-      if (!FLAG(h))
+      if (!FLAG(h)) {
         printf("There are %d section headers, starting at offset %#llx:\n",
                TT.shnum, TT.shoff);
-      printf("\nSection Headers:\n"
+      }
+      printf("\n"
+             "Section Headers:\n"
              "  [Nr] %-17s %-15s %-*s %-6s %-6s ES Flg Lk Inf Al\n",
              "Name", "Type", w, "Address", "Off", "Size");
     }
@@ -447,42 +456,48 @@
     if (FLAG(S)) {
       char sh_flags[12] = {}, *p = sh_flags;
 
-      for (j=0; j<12; j++) if (s.flags&(1<<j)) *p++ = "WAXxMSILOTC"[j];
+      for (j=0; j<12; j++) if (s.flags&(1<<j)) *p++="WAXxMSILOTC"[j];
       printf("  [%2d] %-17s %-15s %0*llx %06llx %06llx %02llx %3s %2d %2d %2lld\n",
              i, s.name, sh_type(s.type), w, s.addr, s.offset, s.size,
              s.entsize, sh_flags, s.link, s.info, s.addralign);
     }
   }
-  if (FLAG(S) && TT.shnum) 
-    printf("Key:\n  (W)rite, (A)lloc, e(X)ecute, (M)erge, (S)trings, (I)nfo\n"
+  if (FLAG(S) && TT.shnum) {
+    printf("Key:\n"
+           "  (W)rite, (A)lloc, e(X)ecute, (M)erge, (S)trings, (I)nfo\n"
            "  (L)ink order, (O)S, (G)roup, (T)LS, (C)ompressed, x=unknown\n");
+  }
 
   if (FLAG(l)) {
     xputc('\n');
     if (!phnum) printf("There are no program headers in this file.\n");
     else {
-      if (!FLAG(h))
-        printf("Elf file type is %s\nEntry point %#x\n"
-          "There are %d program headers, starting at offset %lld\n\n",
-          et_type(type), entry, phnum, TT.phoff);
+      if (!FLAG(h)) {
+        printf("Elf file type is %s\n"
+        "Entry point %#x\n"
+        "There are %d program headers, starting at offset %lld\n"
+        "\n",
+        et_type(type), entry, phnum, TT.phoff);
+      }
       printf("Program Headers:\n"
              "  %-14s %-8s %-*s   %-*s   %-7s %-7s Flg Align\n", "Type",
              "Offset", w, "VirtAddr", w, "PhysAddr", "FileSiz", "MemSiz");
-      for (i = 0; i<phnum; i++) {
+      for (i=0; i<phnum; i++) {
         if (!get_ph(i, &ph)) continue;
         printf("  %-14s 0x%06llx 0x%0*llx 0x%0*llx 0x%05llx 0x%05llx %c%c%c %#llx\n",
                ph_type(ph.type), ph.offset, w, ph.vaddr, w, ph.paddr,
-               ph.filesz, ph.memsz, (ph.flags&4)?'R':' ', (ph.flags&2)?'W':' ',
-               (ph.flags&1)?'E':' ', ph.align);
+               ph.filesz, ph.memsz, ph.flags&4?'R':' ', ph.flags&2?'W':' ',
+               ph.flags&1?'E':' ', ph.align);
         if (ph.type == 3 /*PH_INTERP*/ && ph.filesz<TT.size &&
             ph.offset<TT.size && ph.filesz - 1 < TT.size - ph.offset) {
-// TODO: ph.filesz of 0 prints unlimited length string
           printf("      [Requesting program interpreter: %*s]\n",
                  (int) ph.filesz-1, TT.elf+ph.offset);
         }
       }
 
-      printf("\n Section to Segment mapping:\n  Segment Sections...\n");
+      printf("\n"
+             " Section to Segment mapping:\n"
+             "  Segment Sections...\n");
       for (i=0; i<phnum; i++) {
         if (!get_ph(i, &ph)) continue;
         printf("   %02d     ", i);
@@ -507,16 +522,16 @@
     else if (!dynamic.entsize) printf("Bad dynamic entry size 0!\n");
     else {
       printf("Dynamic section at offset 0x%llx contains %lld entries:\n"
-             "  %-*s %-20s %s\n", dynamic.offset, dynamic.size/dynamic.entsize,
+             "  %-*s %-20s %s\n",
+             dynamic.offset, dynamic.size/dynamic.entsize,
              w+2, "Tag", "Type", "Name/Value");
       while (dyn < end) {
         unsigned long long tag = elf_long(&dyn), val = elf_long(&dyn);
         char *type = dt_type(tag);
 
-        printf(" 0x%0*llx %-20s ", w, tag, type+(*type!='0'));
+        printf(" 0x%0*llx %-20s ", w, tag, *type=='0' ? type : type+1);
         if (*type == 'd') printf("%lld\n", val);
         else if (*type == 'b') printf("%lld (bytes)\n", val);
-// TODO: trusting this %s to be null terminated
         else if (*type == 's') printf("%s\n", TT.elf+dynstr.offset+val);
         else if (*type == 'f' || *type == 'F') {
           struct bitname { int bit; char *s; }
@@ -528,9 +543,11 @@
           int mask;
 
           if (*type == 'F') printf("Flags: ");
-          for (j=0; names[j].s; j++)
-            if (val & (mask=(1<<names[j].bit)))
+          for (j=0; names[j].s; j++) {
+            if (val & (mask=(1<<names[j].bit))) {
               printf("%s%s", names[j].s, (val &= ~mask) ? " " : "");
+            }
+          }
           if (val) printf("0x%llx", val);
           xputc('\n');
         } else if (*type == 'N' || *type == 'R' || *type == 'S') {
@@ -541,7 +558,8 @@
           printf("%s: [%s]\n", *type=='N' ? "Shared library" :
             (*type=='R' ? "Library runpath" : "Library soname"), s);
         } else if (*type == 'P') {
-          j = strlen(type = dt_type(val));
+          type = dt_type(val);
+          j = strlen(type);
           if (*type != '0') type += 2, j -= 3;
           printf("%*.*s\n", j, j, type);
         } else printf("0x%llx\n", val);
@@ -574,39 +592,44 @@
     }
   }
 
-  if (FLAG(x) && find_section(TT.x, &s)) {
-    char *p = TT.elf+s.offset;
-    long offset = 0;
+  if (FLAG(x)) {
+    if (find_section(TT.x, &s)) {
+      char *p = TT.elf+s.offset;
+      long offset = 0;
 
-    printf("\nHex dump of section '%s':\n", s.name);
-    while (offset < s.size) {
-      int space = 2*16 + 16/4;
+      printf("\nHex dump of section '%s':\n", s.name);
+      while (offset < s.size) {
+        int space = 2*16 + 16/4;
 
-      printf("  0x%08lx ", offset);
-      for (i=0; i<16 && offset < s.size; offset++)
-        space -= printf("%02x%s", *p++, " "+!!(++i%4));
-      printf("%*s", space, "");
-      for (p -= i; i; i--, p++) putchar((*p>=' ' && *p<='~') ? *p : '.');
-      xputc('\n');
+        printf("  0x%08lx ", offset);
+        for (i=0; i<16 && offset < s.size; offset++) {
+          space -= printf("%02x%s", *p++, ++i%4 ? "" : " ");
+        }
+        printf("%*s", space, "");
+        for (p-=i; i; i--, p++) putchar(*p>=' ' && *p<='~' ? *p : '.');
+        xputc('\n');
+      }
+      printf("\n");
     }
-    xputc('\n');
   }
 
-  if (FLAG(p) && find_section(TT.p, &s)) {
-    char *begin = TT.elf+s.offset, *end = begin + s.size, *p = begin;
-    int any = 0;
+  if (FLAG(p)) {
+    if (find_section(TT.p, &s)) {
+      char *begin = TT.elf+s.offset, *end = begin + s.size, *p = begin;
+      int any = 0;
 
-    printf("\nString dump of section '%s':\n", s.name);
-    for (; p < end; p++) {
-      if (isprint(*p)) {
-        printf("  [%6tx]  ", p-begin);
-        while (p < end && isprint(*p)) putchar(*p++);
-        xputc('\n');
-        any=1;
+      printf("\nString dump of section '%s':\n", s.name);
+      for (; p < end; p++) {
+        if (isprint(*p)) {
+          printf("  [%6tx]  ", p-begin);
+          while (p < end && isprint(*p)) putchar(*p++);
+          xputc('\n');
+          any=1;
+        }
       }
+      if (!any) printf("  No strings found in this section.\n");
+      printf("\n");
     }
-    if (!any) printf("  No strings found in this section.\n");
-    xputc('\n');
   }
 }
 
@@ -630,7 +653,7 @@
       else if (!sb.st_size) error_msg("%s: empty", TT.f);
       else if (!S_ISREG(sb.st_mode)) error_msg("%s: not a regular file",TT.f);
       else {
-        TT.elf = xmmap(0, TT.size=sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
+        TT.elf = xmmap(NULL, TT.size=sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
         scan_elf();
         munmap(TT.elf, TT.size);
       }
diff --git a/toys/pending/sh.c b/toys/pending/sh.c
index 8f45c17..ab2408a 100644
--- a/toys/pending/sh.c
+++ b/toys/pending/sh.c
@@ -41,8 +41,6 @@
  * {/}, [[/]], (/), function assignment
 
 USE_SH(NEWTOY(cd, ">1LP[-LP]", TOYFLAG_NOFORK))
-USE_SH(NEWTOY(declare, "pAailunxr", TOYFLAG_NOFORK))
- // TODO tpgfF
 USE_SH(NEWTOY(eval, 0, TOYFLAG_NOFORK))
 USE_SH(NEWTOY(exec, "^cla:", TOYFLAG_NOFORK))
 USE_SH(NEWTOY(exit, 0, TOYFLAG_NOFORK))
@@ -81,33 +79,13 @@
   default n
   depends on SH
   help
-    usage: cd [-PL] [-] [path]
+    usage: cd [-PL] [path]
 
-    Change current directory. With no arguments, go $HOME. Sets $OLDPWD to
-    previous directory: cd - to return to $OLDPWD.
+    Change current directory.  With no arguments, go $HOME.
 
     -P	Physical path: resolve symlinks in path
     -L	Local path: .. trims directories off $PWD (default)
 
-config DECLARE
-  bool
-  default n
-  depends on SH
-  help
-    usage: declare [-pAailunxr] [NAME...]
-
-    Set or print variable attributes and values.
-
-    -p	Print variables instead of setting
-    -A	Associative array
-    -a	Indexed array
-    -i	Integer
-    -l	Lower case
-    -n	Name reference (symlink)
-    -r	Readonly
-    -u	Uppercase
-    -x	Export
-
 config EXIT
   bool
   default n
@@ -256,7 +234,7 @@
   long long SECONDS;
   char *isexec, *wcpat;
   unsigned options, jobcnt, LINENO;
-  int hfd, pid, bangpid, varslen, srclvl, recursion;
+  int hfd, pid, bangpid, varslen, cdcount, srclvl, recursion;
 
   // Callable function array
   struct sh_function {
@@ -307,7 +285,7 @@
     struct sh_process *next, *prev; // | && ||
     struct arg_list *delete;   // expanded strings
     // undo redirects, a=b at start, child PID, exit status, has !, job #
-    int *urd, envlen, pid, exit, flags, job, dash;
+    int *urd, envlen, pid, exit, not, job, dash;
     long long when; // when job backgrounded/suspended
     struct sh_arg *raw, arg;
   } *pp; // currently running process
@@ -330,12 +308,6 @@
 #define OPT_C	0x200
 #define OPT_x	0x400
 
-// only export $PWD and $OLDPWD on first cd
-#define OPT_cd  0x80000000
-
-// struct sh_process->flags
-#define PFLAG_NOT    1
-
 static void syntax_err(char *s)
 {
   error_msg("syntax error: %s", s);
@@ -350,7 +322,6 @@
   struct dirent *DE;
   char *s, *ss = 0, buf[4096], *sss = buf;
 
-  if (!X) return;
   for (; (DE = readdir(X));) {
     if (atoi(DE->d_name) == fd) continue;
     s = xreadlink(ss = xmprintf("/proc/self/fd/%s", DE->d_name));
@@ -402,7 +373,7 @@
 #define VAR_TOLOWER   (1<<5)
 #define VAR_TOUPPER   (1<<4)
 #define VAR_NAMEREF   (1<<3)
-#define VAR_EXPORT    (1<<2)
+#define VAR_GLOBAL    (1<<2)
 #define VAR_READONLY  (1<<1)
 #define VAR_MAGIC     (1<<0)
 
@@ -415,10 +386,7 @@
   return s;
 }
 
-// TODO: this has to handle VAR_NAMEREF, but return dangling symlink
-// Also, unset -n, also "local ISLINK" to parent var.
-// Return sh_vars * or 0 if not found.
-// Sets *pff to function (only if found), only returns whiteouts if pff not NULL
+// Return index of variable within this list
 static struct sh_vars *findvar(char *name, struct sh_fcall **pff)
 {
   int len = varend(name)-name;
@@ -428,13 +396,11 @@
   if (len) do {
     struct sh_vars *var = ff->vars+ff->varslen;
 
-    if (var) while (var--!=ff->vars) {
-      if (strncmp(var->str, name, len) || var->str[len]!='=') continue;
-      if (pff) *pff = ff;
-      else if (var->flags&VAR_WHITEOUT) return 0;
-
-      return var;
-    }
+    if (!var) continue;
+    if (pff) *pff = ff;
+    while (var-- != ff->vars)
+      if (pff || !(var->flags&VAR_WHITEOUT))
+        if (!strncmp(var->str, name, len) && var->str[len] == '=') return var;
   } while ((ff = ff->next)!=TT.ff);
 
   return 0;
@@ -452,144 +418,50 @@
   return ff->vars+ff->varslen++;
 }
 
-static char **nospace(char **ss)
+// TODO function to resolve a string into a number for $((1+2)) etc
+long long do_math(char **s)
 {
-  while (isspace(**ss)) ++*ss;
+  long long ll;
 
-  return ss;
+  while (isspace(**s)) ++*s;
+  ll = strtoll(*s, s, 0);
+  while (isspace(**s)) ++*s;
+
+  return ll;
 }
 
-/*
-15L ( [ . -> ++ --
-14R (all prefix operators)
-++ -- + - ! ~ (typecast) * & sizeof
-13L * / %
-12L + -
-11L << >>
-10L < <= > >=
-9L == !=
-8L & (bitwise)
-7L ^ (xor)
-6L |
-5L &&
-4L ||
-3R ? :
-2R (assignments) = += -= *= /= %= &= ^= |= <<= >>=
-1L ,
-
-*/
-
-// Recursively calculate string into dd, returns 0 if failed, ss = error point
-static int recalculate(long long *dd, char **ss, int lvl)
+// declare -aAilnrux
+// ft
+static struct sh_vars *setvar_found(char *s, struct sh_vars *var)
 {
-  long long ee, ff;
-  char cc = **nospace(ss);
+  long flags;
 
-  // TODO: assignable (variable)
-  // Always start handling unary prefixes, parenthetical blocks, and constants
-  if (cc=='+' || cc=='-') {
-    ++*ss;
-    if (!recalculate(dd, ss, 1)) return 0;
-    if (cc=='-') *dd = -*dd;
-  } else if (cc=='(') {
-    ++*ss;
-    if (!recalculate(dd, ss, 1)) return 0;
-    if (**ss!=')') return 0;
-    else ++*ss;
-  } else if (isdigit(cc)) *dd = strtoll(*ss, ss, 0); //TODO overflow?
-  else if (!lvl && (!cc || cc==')')) {
-    *dd = 0;
-    return 1;
-  } else return 0;
-
-  // x^y binds first
-  if (lvl<4) while (strstart(nospace(ss), "**")) {
-    if (!recalculate(&ee, ss, 4)) return 0;
-    if (ee<0) perror_msg("** < 0");
-    for (ff = *dd, *dd = 1; ee; ee--) *dd *= ff;
-  }
-
-  // w*x/y%z bind next
-  if (lvl<3) while ((cc = **nospace(ss))) {
-    if (cc=='*' || cc=='/' || cc=='%') {
-      ++*ss;
-      if (!recalculate(&ee, ss, 3)) return 0;
-      if (cc=='*') *dd *= ee;
-      else if (cc=='%') *dd %= ee;
-      else if (!ee) {
-        perror_msg("/0");
-        return 0;
-      } else *dd /= ee;
-    } else break;
-  }
-
-  // x+y-z
-  if (lvl<2) while ((cc = **nospace(ss))) {
-    if (cc=='+' || cc=='-') {
-      ++*ss;
-      if (!recalculate(&ee, ss, 2)) return 0;
-      if (cc=='+') *dd += ee;
-      else *dd -= ee;
-    } else break;
-  }
-  nospace(ss);
-
-  return 1;
-}
-
-static int calculate(long long *ll, char *equation)
-{
-  char *ss = equation;
-
-  // TODO: error_msg->sherror_msg() with LINENO for scripts
-  if (!recalculate(ll, &ss, 0) || *ss) {
-    perror_msg("bad math: %s @ %d", equation, (int)(ss-equation));
+  if ((flags = var->flags&~VAR_WHITEOUT)&VAR_READONLY) {
+    error_msg("%.*s: read only", (int)(strchr(s, '=')-s), s);
+    free(s);
 
     return 0;
+  } else var->flags = flags;
+
+// TODO if (flags&(VAR_TOUPPER|VAR_TOLOWER)) 
+// unicode _is stupid enough for upper/lower case to be different utf8 byte
+// lengths. example: lowercase of U+0130 (C4 B0) is U+0069 (69)
+// TODO VAR_INT
+// TODO VAR_ARRAY VAR_DICT
+
+  if (flags&VAR_MAGIC) {
+    char *ss = strchr(s, '=')+1;
+
+    if (*s == 'S') TT.SECONDS = millitime() - 1000*do_math(&ss);
+    else if (*s == 'R') srandom(do_math(&ss));
+// TODO: trailing garbage after do_math()?
+  } else {
+    if (!(flags&VAR_NOFREE)) free(var->str);
+    else var->flags ^= VAR_NOFREE;
+    var->str = s;
   }
 
-  return 1;
-}
-
-// Return length of utf8 char @s fitting in len, writing value into *cc
-int getutf8(char *s, int len, int *cc)
-{
-  unsigned wc;
-
-  if (len<0) wc = len = 0;
-  else if (1>(len = utf8towc(&wc, s, len))) wc = *s, len = 1;
-  if (cc) *cc = wc;
-
-  return len;
-}
-
-// get value of variable starting at s.
-static char *getvar(char *s)
-{
-  struct sh_vars *var = findvar(s, 0);
-
-  if (!var) return 0;
-
-  if (var->flags & VAR_MAGIC) {
-    char c = *var->str;
-
-    if (c == 'S') sprintf(toybuf, "%lld", (millitime()-TT.SECONDS)/1000);
-    else if (c == 'R') sprintf(toybuf, "%ld", random()&((1<<16)-1));
-    else if (c == 'L') sprintf(toybuf, "%u", TT.ff->pl->lineno);
-    else if (c == 'G') sprintf(toybuf, "TODO: GROUPS");
-    else if (c == 'B') sprintf(toybuf, "%d", getpid());
-    else if (c == 'E') {
-      struct timespec ts;
-
-      clock_gettime(CLOCK_REALTIME, &ts);
-      sprintf(toybuf, "%lld%c%06ld", (long long)ts.tv_sec, (s[5]=='R')*'.',
-              ts.tv_nsec/1000);
-    }
-
-    return toybuf;
-  }
-
-  return varend(var->str)+1;
+  return var;
 }
 
 // Update $IFS cache in function call stack after variable assignment
@@ -599,133 +471,24 @@
     do ff->ifs = s+4; while ((ff = ff->next) != TT.ff->prev);
 }
 
-// declare -aAilnrux
-// ft
-// TODO VAR_ARRAY VAR_DICT
-
-// Assign new name=value string for existing variable. s takes x=y or x+=y
-static struct sh_vars *setvar_found(char *s, int freeable, struct sh_vars *var)
+static struct sh_vars *setvar(char *s)
 {
-  char *ss, *sss, *sd, buf[24];
-  long ii, jj, kk, flags = var->flags&~VAR_WHITEOUT;
-  long long ll;
-  int cc, vlen = varend(s)-s;
+  struct sh_fcall *ff;
+  struct sh_vars *var;
 
-  if (flags&VAR_READONLY) {
-    error_msg("%.*s: read only", vlen, s);
-    goto bad;
-  }
-
-  // If += has no old value (addvar placeholder or empty old var) yank the +
-  if (s[vlen]=='+' && (var->str==s || !strchr(var->str, '=')[1])) {
-    ss = xmprintf("%.*s%s", vlen, s, s+vlen+1);
-    if (var->str==s) {
-      if (!freeable++) var->flags |= VAR_NOFREE;
-    } else if (freeable++) free(s);
-    s = ss;
-  }
-
-  // Handle VAR_NAMEREF mismatch by replacing name
-  if (strncmp(var->str, s, vlen)) {
-    ss = s+vlen+(s[vlen]=='+')+1;
-    ss = xmprintf("%.*s%s", (vlen = varend(var->str)-var->str)+1, var->str, ss);
-    if (freeable++) free(s);
-    s = ss;
-  }
-
-  // utf8 aware case conversion, two pass (measure, allocate, convert) because
-  // unicode IS stupid enough for upper/lower case to be different utf8 byte
-  // lengths, for example lowercase of U+023a (c8 ba) is U+2c65 (e2 b1 a5)
-  if (flags&(VAR_TOUPPER|VAR_TOLOWER)) {
-    for (jj = kk = 0, sss = 0; jj<2; jj++, sss = sd = xmalloc(vlen+kk+2)) {
-      sd = jj ? stpncpy(sss, s, vlen+1) : (void *)&sss;
-      for (ss = s+vlen+1; (ii = getutf8(ss, 4, &cc)); ss += ii) {
-        kk += wctoutf8(sd, (flags&VAR_TOUPPER) ? towupper(cc) : towlower(cc));
-        if (jj) {
-          sd += kk;
-          kk = 0;
-        }
-      }
-    }
-    *sd = 0;
-    if (freeable++) free(s);
-    s = sss;
-  }
-
-  // integer variables treat += differently
-  ss = s+vlen+(s[vlen]=='+')+1;
-  if (flags&VAR_INT) {
-    if (!calculate(&ll, ss)) goto bad;
-    sprintf(buf, "%lld", ll);
-    if (flags&VAR_MAGIC) {
-      if (*s == 'S') {
-        ll *= 1000;
-        TT.SECONDS = (s[vlen]=='+') ? TT.SECONDS+ll : millitime()-ll;
-      } else if (*s == 'R') srandom(ll);
-      if (freeable) free(s);
-
-      // magic can't be whiteout or nofree, and keeps old string
-      return var;
-    } else if (s[vlen]=='+' || strcmp(buf, ss)) {
-      if (s[vlen]=='+') ll += atoll(strchr(var->str, '=')+1);
-      ss = xmprintf("%.*s=%lld", vlen, s, ll);
-      if (freeable++) free(s);
-      s = ss;
-    }
-  } else if (s[vlen]=='+' && !(flags&VAR_MAGIC)) {
-    ss = xmprintf("%s%s", var->str, ss);
-    if (freeable++) free(s);
-    s = ss;
-  }
-
-  // Replace old string with new one, adjusting nofree status
-  if (flags&VAR_NOFREE) flags ^= VAR_NOFREE;
-  else free(var->str);
-  if (!freeable) flags |= VAR_NOFREE;
-  var->str = s;
-  var->flags = flags;
-
-  return var;
-bad:
-  if (freeable) free(s);
-
-  return 0;
-}
-
-// Creates new variables (local or global) and handles +=
-// returns 0 on error, else sh_vars of new entry.
-static struct sh_vars *setvar_long(char *s, int freeable, struct sh_fcall *ff)
-{
-  struct sh_vars *vv = 0, *was;
-  char *ss;
-
-  if (!s) return 0;
-  ss = varend(s);
-  if (ss[*ss=='+']!='=') {
+  if (s[varend(s)-s] != '=') {
     error_msg("bad setvar %s\n", s);
-    if (freeable) free(s);
+    free(s);
+
     return 0;
   }
+  if (!(var = findvar(s, &ff))) ff = TT.ff->prev;
+  cache_ifs(s, ff);
+  if (!var) return addvar(s, TT.ff->prev);
 
-  // Add if necessary, set value, and remove again if we added but set failed
-  if (!(was = vv = findvar(s, &ff))) (vv = addvar(s, ff))->flags = VAR_NOFREE;
-  if (!(vv = setvar_found(s, freeable, vv))) {
-    int ii = vv-ff->vars;
-
-    if (!was) memmove(ff->vars+ii, ff->vars+ii+1, (ff->varslen--)-ii);
-  } else cache_ifs(vv->str, ff);
-
-  return vv;
+  return setvar_found(s, var);
 }
 
-// Set variable via a malloced "name=value" (or "name+=value") string.
-// Returns sh_vars * or 0 for failure (readonly, etc)
-static struct sh_vars *setvar(char *str)
-{
-  return setvar_long(str, 0, TT.ff->prev);
-}
-
-
 // returns whether variable found (whiteout doesn't count)
 static int unsetvar(char *name)
 {
@@ -758,6 +521,27 @@
   return setvar(xmprintf("%s=%s", name, val));
 }
 
+// get value of variable starting at s.
+static char *getvar(char *s)
+{
+  struct sh_vars *var = findvar(s, 0);
+
+  if (!var) return 0;
+
+  if (var->flags & VAR_MAGIC) {
+    char c = *var->str;
+
+    if (c == 'S') sprintf(toybuf, "%lld", (millitime()-TT.SECONDS)/1000);
+    else if (c == 'R') sprintf(toybuf, "%ld", random()&((1<<16)-1));
+    else if (c == 'L') sprintf(toybuf, "%u", TT.ff->pl->lineno);
+    else if (c == 'G') sprintf(toybuf, "TODO: GROUPS");
+
+    return toybuf;
+  }
+
+  return varend(var->str)+1;
+}
+
 // TODO: keep variable arrays sorted for binary search
 
 // create array of variables visible in current function.
@@ -792,28 +576,26 @@
 // malloc declare -x "escaped string"
 static char *declarep(struct sh_vars *var)
 {
-  char *types = "rxnuliaA", *esc = "$\"\\`", *in, flags[16], *out = flags, *ss;
+  char *types = "-rgnuliaA", *in = types, flags[16], *out = flags, *ss;
   int len;
 
-  for (len = 0; types[len]; len++) if (var->flags&(2<<len)) *out++ = types[len];
-  if (out==flags) *out++ = '-';
+  while (*++in) if (var->flags&(1<<(in-types))) *out++ = *in;
+  if (in == types) *out++ = *types;
   *out = 0;
   len = out-flags;
 
-  for (in = var->str; *in; in++) len += !!strchr(esc, *in);
-  len += in-var->str;
+  for (in = types = varend(var->str); *in; in++) len += !!strchr("$\"\\`", *in);
+  len += in-types;
   ss = xmalloc(len+15);
 
-  len = varend(var->str)-var->str;
-  out = ss + sprintf(ss, "declare -%s %.*s", flags, len, var->str);
-  if (var->flags != VAR_MAGIC)  {
-    out = stpcpy(out, "=\"");
-    for (in = var->str+len+1; *in; *out++ = *in++)
-      if (strchr(esc, *in)) *out++ = '\\';
-    *out++ = '"';
+  out = ss + sprintf(ss, "declare -%s \"", out);
+  while (*types) {
+    if (strchr("$\"\\`", *types)) *out++ = '\\';
+    *out++ = *types++;
   }
+  *out++ = '"';
   *out = 0;
-
+ 
   return ss; 
 }
 
@@ -908,8 +690,8 @@
         if (!*end || (*end=='\n' && !end[1])) return early ? end : 0;
       } else if (ii=='$' && -1!=(qq = stridx("({[", *end))) {
         if (strstart(&end, "((")) {
-          end--;
           toybuf[quote++] = 255;
+          end++;
         } else toybuf[quote++] = ")}]"[qq];
       } else if (*end=='(' && strchr("?*+@!", ii)) toybuf[quote++] = ')';
       else {
@@ -989,8 +771,8 @@
 static char *pl2str(struct sh_pipeline *pl, int one)
 {
   struct sh_pipeline *end = 0, *pp;
-  int len QUIET, i;
-  char *ss;
+  int len = len, i;
+  char *s, *ss;
 
   // Find end of block (or one argument)
   if (one) end = pl->next;
@@ -1002,10 +784,12 @@
   for (ss = 0;; ss = xmalloc(len+1)) {
     for (pp = pl; pp != end; pp = pp->next) {
       if (pp->type == 'F') continue; // TODO fix this
-      for (i = len = 0; i<=pp->arg->c; i++)
-        len += snprintf(ss+len, ss ? INT_MAX : 0, " %s"+!i,
-           pp->arg->v[i] ? : ";"+(pp->next==end));
+      for (i = len = 0; i<pp->arg->c; i++)
+        len += snprintf(ss+len, ss ? INT_MAX : 0, "%s ", pp->arg->v[i]);
+      if (!(s = pp->arg->v[pp->arg->c])) s = ";"+(pp->next==end);
+      len += snprintf(ss+len, ss ? INT_MAX : 0, s);
     }
+
     if (ss) return ss;
   }
 
@@ -1144,8 +928,8 @@
   // On nommu vfork, exec /proc/self/exe, and pipe state data to ourselves.
   } else {
     int pipes[2];
-    unsigned i;
-    char **oldenv = environ, *ss = str ? : pl2str(TT.ff->pl->next, 0);
+    unsigned len, i;
+    char **oldenv = environ, *s, *ss = str ? : pl2str(TT.ff->pl->next, 0);
     struct sh_vars **vv;
 
     // open pipe to child
@@ -1166,16 +950,15 @@
 
     // marshall context to child
     close(254);
-    dprintf(pipes[1], "%lld %u %u %u %u\n", TT.SECONDS,
-      TT.options, TT.LINENO, TT.pid, TT.bangpid);
-
-    for (i = 0, vv = visible_vars(); vv[i]; i++)
-      dprintf(pipes[1], "%u %lu\n%.*s", (unsigned)strlen(vv[i]->str),
-              vv[i]->flags, (int)strlen(vv[i]->str), vv[i]->str);
+    for (i = 0, vv = visible_vars(); vv[i]; i++) {
+      if (vv[i]->flags&VAR_WHITEOUT) continue;
+      dprintf(pipes[1], "%s\n", s = declarep(vv[i]));
+      free(s);
+    }
     free(vv);
 
     // send command
-    dprintf(pipes[1], "0 0\n%.*s\n", len, ss);
+    dprintf(pipes[1], "%.*s\n", len, ss);
     if (!str) free(ss);
     close(pipes[1]);
   }
@@ -1210,7 +993,7 @@
 // if len, save length of next wc (whether or not it's in list)
 static int utf8chr(char *wc, char *chrs, int *len)
 {
-  unsigned wc1, wc2;
+  wchar_t wc1, wc2;
   int ll;
 
   if (len) *len = 1;
@@ -1262,6 +1045,18 @@
   return s;
 }
 
+// Return length of utf8 char @s fitting in len, writing value into *cc
+int getutf8(char *s, int len, int *cc)
+{
+  wchar_t wc;
+
+  if (len<0) wc = len = 0;
+  else if (1>(len = utf8towc(&wc, s, len))) wc = *s, len = 1;
+  if (cc) *cc = wc;
+
+  return len;
+}
+
 #define WILD_SHORT 1 // else longest match
 #define WILD_CASE  2 // case insensitive
 #define WILD_ANY   4 // advance through pattern instead of str
@@ -1285,10 +1080,10 @@
     } else if (dd>=deck->c || pp!=(long)deck->v[dd]) {
       if (ss<len) {
         if (flags&WILD_CASE) {
-          ss += getutf8(str+ss, len-ss, &c);
-          c = towupper(c);
-          pp += getutf8(pattern+pp, pp-plen, &i);
-          i = towupper(i);
+          c = towupper(getutf8(str+ss, len-ss, &i));
+          ss += i;
+          i = towupper(getutf8(pattern+pp, pp-plen, &j));
+          pp += j;
         } else c = str[ss++], i = pattern[pp++];
         if (c==i) continue;
       }
@@ -1548,7 +1343,7 @@
   if (!dt) return arg_add(arg, pattern);
   while (dt) {
     while (dt->child) dt = dt->child;
-    arg_add(arg, push_arg(delete, dirtree_path(dt, 0)));
+    arg_add(arg, dirtree_path(dt, 0));
     do {
       pp = (void *)dt;
       if ((dt = dt->parent)) dt->child = dt->child->next;
@@ -1663,23 +1458,9 @@
       s = str+ii-1;
       kk = parse_word(s, 1, 0)-s;
       if (str[ii] == '[' || *toybuf == 255) {
-        struct sh_arg aa = {0};
-        long long ll;
-
-        // Expand $VARS in math string
-        ss = str+ii+1+(str[ii]=='(');
-        push_arg(delete, ss = xstrndup(ss, kk - (3+2*(str[ii]!='['))));
-        expand_arg_nobrace(&aa, ss, NO_PATH|NO_SPLIT, delete, 0);
-        s = ss = (aa.v && *aa.v) ? *aa.v : "";
-        free(aa.v);
-
-        // Recursively calculate result
-        if (!recalculate(&ll, &s, 0) || *s) {
-          error_msg("bad math: %s @ %ld", ss, (s-ss)+1);
-          goto fail;
-        }
-        ii += kk-1;
-        push_arg(delete, ifs = xmprintf("%lld", ll));
+        s += 2+(str[ii]!='[');
+        kk -= 3+2*(str[ii]!='[');
+dprintf(2, "TODO: do math for %.*s\n", kk, s);
       } else {
         // Run subshell and trim trailing newlines
         s += (jj = 1+(cc == '$'));
@@ -1732,16 +1513,17 @@
 
         if (cc == '}') ifs = (void *)1;
         else if (strchr("#!", cc)) ss++;
-        if (!(jj = varend(ss)-ss)) while (isdigit(ss[jj])) jj++;
-        if (!jj && strchr("#$_*", *ss)) jj++;
+        jj = varend(ss)-ss;
+        if (!jj) while (isdigit(ss[jj])) jj++;
+        if (!jj && strchr("#$!_*", *ss)) jj++;
         // parameter or operator? Maybe not a prefix: ${#-} vs ${#-x}
         if (!jj && strchr("-?@", *ss)) if (ss[++jj]!='}' && ss[-1]!='{') ss--;
         slice = ss+jj;        // start of :operation
 
         if (!jj) {
+          ifs = (void *)1;
           // literal ${#} or ${!} wasn't a prefix
           if (strchr("#!", cc)) ifs = getvar_special(--ss, 1, &kk, delete);
-          else ifs = (void *)1;  // unrecognized char ala ${~}
         } else if (ss[-1]=='{'); // not prefix, fall through
         else if (cc == '#') {  // TODO ${#x[@]}
           dd = !!strchr("@*", *ss);  // For ${#@} or ${#*} do normal ${#}
@@ -1824,7 +1606,7 @@
     // Fetch separator to glue string back together with
     *sep = 0;
     if (((qq&1) && cc=='*') || (flags&NO_SPLIT)) {
-      unsigned wc;
+      wchar_t wc;
 
       nosplit++;
       if (flags&SEMI_IFS) strcpy(sep, " ");
@@ -1854,23 +1636,24 @@
         else if (dd == '+')
           push_arg(delete, ifs = slashcopy(slice+xx+1, "}", 0));
         else if (xx) { // ${x::}
-          long long la = 0, lb = LLONG_MAX, lc = 1;
+          long long la, lb, lc;
 
-          ss = ++slice;
-          if ((lc = recalculate(&la, &ss, 0)) && *ss == ':') {
-            ss++;
-            lc = recalculate(&lb, &ss, 0);
+// TODO don't redo math in loop
+          ss = slice+1;
+          la = do_math(&s);
+          if (s && *s == ':') {
+            s++;
+            lb = do_math(&s);
+          } else lb = LLONG_MAX;
+          if (s && *s != '}') {
+            error_msg("%.*s: bad '%c'", (int)(slice-ss), ss, *s);
+            s = 0;
           }
-          if (!lc || *ss != '}') {
-            for (s = ss; *s != '}' && *s != ':'; s++);
-            error_msg("bad %.*s @ %ld", (int)(s-slice), slice, ss-slice);
-//TODO fix error message
-            goto fail;
-          }
+          if (!s) goto fail;
 
           // This isn't quite what bash does, but close enough.
           if (!(lc = aa.c)) lc = strlen(ifs);
-          else if (!la && !yy && strchr("@*", *slice)) {
+          else if (!la && !yy && strchr("@*", slice[1])) {
             aa.v--; // ${*:0} shows $0 even though default is 1-indexed
             aa.c++;
             yy++;
@@ -2146,7 +1929,7 @@
     }
   }
 
-// TODO NO_SPLIT with braces? (Collate with spaces?)
+// TODO NOSPLIT with braces? (Collate with spaces?)
   // If none, pass on verbatim
   if (!blist) return expand_arg_nobrace(arg, old, flags, delete, 0);
 
@@ -2286,8 +2069,10 @@
   for (j = skip; j<arg->c; j++) {
     int saveclose = 0, bad = 0;
 
-    if (!strcmp(s = arg->v[j], "!")) {
-      pp->flags ^= PFLAG_NOT;
+    s = arg->v[j];
+
+    if (!strcmp(s, "!")) {
+      pp->not ^= 1;
 
       continue;
     }
@@ -2502,8 +2287,8 @@
     // convert vars in-place and use original sh_arg alloc to add one more
     aa.v = environ = (void *)vv;
     for (aa.c = uu = 0; vv[uu]; uu++) {
-      if ((vv[uu]->flags&(VAR_WHITEOUT|VAR_EXPORT))==VAR_EXPORT) {
-        if (*(pp = vv[uu]->str)=='_' && pp[1]=='=') sss = aa.v+aa.c;
+      if ((vv[uu]->flags&(VAR_WHITEOUT|VAR_GLOBAL))==VAR_GLOBAL) {
+        if (*(pp = vv[uu]->str)=='_' && pp[1] == '=') sss = aa.v+aa.c;
         aa.v[aa.c++] = pp;
       }
     }
@@ -2539,15 +2324,14 @@
 // Execute a single command at TT.ff->pl
 static struct sh_process *run_command(void)
 {
-  char *s, *ss, *sss;
+  char *s, *sss;
   struct sh_arg *arg = TT.ff->pl->arg;
-  int envlen, funk = TT.funcslen, jj = 0, prefix = 0;
+  int envlen, funk = TT.funcslen, jj = 0, locals = 0;
   struct sh_process *pp;
 
   // Count leading variable assignments
   for (envlen = 0; envlen<arg->c; envlen++)
-    if ((ss = varend(arg->v[envlen]))==arg->v[envlen] || ss[*ss=='+']!='=')
-      break;
+    if ((s = varend(arg->v[envlen])) == arg->v[envlen] || *s != '=') break;
   pp = expand_redir(arg, envlen, 0);
 
   // Are we calling a shell function?  TODO binary search
@@ -2564,22 +2348,30 @@
       pp->delete = 0;
     }
     addvar(0, TT.ff); // function context (not source) so end_function deletes
-    prefix = 1;  // create local variables for function prefix assignment
+    locals = 1;
   }
 
   // perform any assignments
-  if (envlen) for (; jj<envlen && !pp->exit; jj++) {
+  if (envlen) {
+    struct sh_fcall *ff;
     struct sh_vars *vv;
 
-    if ((sss = expand_one_arg(ss = arg->v[jj], SEMI_IFS, 0))) {
-      if (!prefix && sss==ss) sss = xstrdup(sss);
-      if ((vv = setvar_long(sss, sss!=ss, prefix ? TT.ff : TT.ff->prev))) {
-        if (prefix) vv->flags |= VAR_EXPORT;
-        continue;
+    for (; jj<envlen && !pp->exit; jj++) {
+      if (!(vv = findvar(s = arg->v[jj], &ff))) ff = locals?TT.ff:TT.ff->prev;
+      else if (vv->flags&VAR_READONLY) ff = 0;
+      else if (locals && ff!=TT.ff) vv = 0, ff = TT.ff;
+
+      if (!vv&&ff) (vv = addvar(s, ff))->flags = VAR_NOFREE|(VAR_GLOBAL*locals);
+      if (!(sss = expand_one_arg(s, SEMI_IFS, 0))) pp->exit = 1;
+      else {
+        if (!setvar_found(sss, vv)) continue;
+        if (sss==s) {
+          if (!locals) vv->str = xstrdup(sss);
+          else vv->flags |= VAR_NOFREE;
+        }
+        cache_ifs(vv->str, ff ? : TT.ff);
       }
     }
-    pp->exit = 1;
-    break;
   }
 
   // Do the thing
@@ -2592,11 +2384,9 @@
 
   // call shell function
   else if (funk != TT.funcslen) {
-    s = 0; // $_ set on return, not here
     (TT.ff->func = TT.functions[funk])->refcount++;
     TT.ff->pl = TT.ff->func->pipeline;
     TT.ff->arg = pp->arg;
-// TODO: unredirect(pp->urd) called below but haven't traversed function yet
   } else {
     struct toy_list *tl = toy_find(*pp->arg.v);
 
@@ -2609,7 +2399,7 @@
 // TODO: figure out when can exec instead of forking, ala sh -c blah
 
     // Is this command a builtin that should run in this process?
-    if ((jj&TOYFLAG_NOFORK) || ((jj&TOYFLAG_MAYFORK) && !prefix)) {
+    if ((jj&TOYFLAG_NOFORK) || ((jj&TOYFLAG_MAYFORK) && !locals)) {
       sigjmp_buf rebound;
       char temp[jj = offsetof(struct toy_context, rebound)];
 
@@ -2623,7 +2413,6 @@
       memset(&TT, 0, offsetof(struct sh_data, SECONDS));
       if (!sigsetjmp(rebound, 1)) {
         toys.rebound = &rebound;
-//dprintf(2, "%d builtin", getpid()); for (int xx = 0; xx<=pp->arg.c; xx++) dprintf(2, "{%s}", pp->arg.v[xx]); dprintf(2, "\n");
         toy_singleinit(tl, pp->arg.v);
         tl->toy_main();
         xflush(0);
@@ -2640,7 +2429,7 @@
   // cleanup process
   unredirect(pp->urd);
   pp->urd = 0;
-  if (prefix && funk == TT.funcslen) end_function(0);
+  if (locals && funk == TT.funcslen) end_function(0);
   if (s) setvarval("_", s);
 
   return pp;
@@ -2888,10 +2677,8 @@
 
       // Stop at EOL. Discard blank pipeline segment, else end segment
       if (end == start) done++;
-      if (!pl->type && !arg->c) {
-        free_pipeline(dlist_lpop(ppl));
-        pl = *ppl ? (*ppl)->prev : 0;
-      } else pl->count = -1;
+      if (!pl->type && !arg->c) free_pipeline(dlist_lpop(ppl));
+      else pl->count = -1;
 
       continue;
     }
@@ -3126,7 +2913,12 @@
   if (s) syntax_err(s);
   llist_traverse(*ppl, free_pipeline);
   *ppl = 0;
-  llist_traverse(*expect, free);
+  while (*expect) {
+    struct double_list *del = dlist_pop(expect);
+
+    if (del->data != (void *)1) free(del->data);
+    free(del);
+  }
   *expect = 0;
 
   return 0-!!s;
@@ -3180,7 +2972,7 @@
 // Wait for pid to exit and remove from jobs table, returning process or 0.
 struct sh_process *wait_job(int pid, int nohang)
 {
-  struct sh_process *pp = pp;
+  struct sh_process *pp;
   int ii, status, minus, plus;
 
   if (TT.jobs.c<1) return 0;
@@ -3218,7 +3010,7 @@
       pp->pid = 0;
     }
     // TODO handle set -o pipefail here
-    rc = (pp->flags&PFLAG_NOT) ? !pp->exit : pp->exit;
+    rc = pp->not ? !pp->exit : pp->exit;
   }
 
   while ((pp = wait_job(-1, 1)) && (TT.options&FLAG_i)) {
@@ -3692,35 +3484,34 @@
 }
 
 // export existing "name" or assign/export name=value string (making new copy)
-static void set_varflags(char *str, unsigned set_flags, unsigned unset_flags)
+static void export(char *str)
 {
   struct sh_vars *shv = 0;
-  struct sh_fcall *ff;
   char *s;
 
   // Make sure variable exists and is updated
   if (strchr(str, '=')) shv = setvar(xstrdup(str));
-  else if (!(shv = findvar(str, &ff))) {
-    if (!set_flags) return;
+  else if (!(shv = findvar(str, 0))) {
     shv = addvar(str = xmprintf("%s=", str), TT.ff->prev);
     shv->flags = VAR_WHITEOUT;
-  } else if (shv->flags&VAR_WHITEOUT) shv->flags |= VAR_EXPORT;
-  if (!shv || (shv->flags&VAR_EXPORT)) return;
+  } else if (shv->flags&VAR_WHITEOUT) shv->flags |= VAR_GLOBAL;
+  if (!shv || (shv->flags&VAR_GLOBAL)) return;
 
   // Resolve magic for export (bash bug compatibility, really should be dynamic)
   if (shv->flags&VAR_MAGIC) {
     s = shv->str;
     shv->str = xmprintf("%.*s=%s", (int)(varend(str)-str), str, getvar(str));
-    if (!(shv->flags&VAR_NOFREE)) free(s);
-    else shv->flags ^= VAR_NOFREE;
+    free(s);
   }
-  shv->flags |= set_flags;
-  shv->flags &= ~unset_flags;
+  shv->flags |= VAR_GLOBAL;
 }
 
-static void export(char *str)
+static void unexport(char *str)
 {
-  set_varflags(str, VAR_EXPORT, 0);
+  struct sh_vars *shv = findvar(str, 0);
+
+  if (shv) shv->flags &=~VAR_GLOBAL;
+  if (strchr(str, '=')) setvar(str);
 }
 
 FILE *fpathopen(char *name)
@@ -3743,7 +3534,7 @@
 {
   struct sh_pipeline *pl = 0;
   struct double_list *expect = 0;
-  unsigned lineno = TT.LINENO, more = 0, wc;
+  unsigned lineno = TT.LINENO, more = 0;
   int cc, ii;
   char *new;
 
@@ -3763,12 +3554,14 @@
 //dprintf(2, "%d getline from %p %s\n", getpid(), ff, new); debug_show_fds();
     // did we exec an ELF file or something?
     if (!TT.LINENO++ && name && new) {
+      wchar_t wc;
+
       // A shell script's first line has no high bytes that aren't valid utf-8.
       for (ii = 0; new[ii] && 0<(cc = utf8towc(&wc, new+ii, 4)); ii += cc);
       if (new[ii]) {
 is_binary:
         if (name) error_msg("'%s' is binary", name); // TODO syntax_err() exit?
-        if (new != (void *)1) free(new);
+        free(new);
         new = 0;
       }
     }
@@ -3804,63 +3597,27 @@
   return more;
 }
 
-// On nommu we had to exec(), so parent environment is passed via a pipe.
-static void nommu_reentry(void)
-{
-  struct stat st;
-  int ii, pid, ppid, len;
-  unsigned long ll;
-  char *s = 0;
-  FILE *fp;
-
-  // Sanity check
-  if (!fstat(254, &st) && S_ISFIFO(st.st_mode)) {
-    for (ii = len = 0; (s = environ[ii]); ii++) {
-      if (*s!='@') continue;
-      sscanf(s, "@%u,%u%n", &pid, &ppid, &len);
-      break;
-    }
-  }
-  if (!s || s[len] || pid!=getpid() || ppid!=getppid()) error_exit(0);
-
-// TODO signal setup before this so fscanf can't EINTR.
-// TODO marshall TT.jobcnt TT.funcslen: child needs jobs and function list
-  // Marshall magics: $SECONDS $- $LINENO $$ $!
-  if (5!=fscanf(fp = fdopen(254, "r"), "%lld %u %u %u %u%*[^\n]", &TT.SECONDS,
-      &TT.options, &TT.LINENO, &TT.pid, &TT.bangpid)) error_exit(0);
-
-  // Read named variables: type, len, var=value\0
-  for (;;) {
-    len = ll = 0;
-    fscanf(fp, "%u %lu%*[^\n]", &len, &ll);
-    fgetc(fp); // Discard the newline fscanf didn't eat.
-    if (!len) break;
-    (s = xmalloc(len+1))[len] = 0;
-    for (ii = 0; ii<len; ii += pid)
-      if (1>(pid = fread(s+ii, 1, len-ii, fp))) error_exit(0);
-    set_varflags(s, ll, 0);
-  }
-
-  // Perform subshell command(s)
-  do_source(0, fp);
-  xexit();
-}
-
 // init locals, sanitize environment, handle nommu subshell handoff
 static void subshell_setup(void)
 {
-  int ii, from, uid = getuid();
+  int ii, from, pid, ppid, zpid, myppid = getppid(), len, uid = getuid();
   struct passwd *pw = getpwuid(uid);
-  char *s, *ss, *magic[] = {"SECONDS", "RANDOM", "LINENO", "GROUPS", "BASHPID",
-    "EPOCHREALTIME", "EPOCHSECONDS"},
+  char *s, *ss, *magic[] = {"SECONDS", "RANDOM", "LINENO", "GROUPS"},
     *readonly[] = {xmprintf("EUID=%d", geteuid()), xmprintf("UID=%d", uid),
-                   xmprintf("PPID=%d", getppid())};
+                   xmprintf("PPID=%d", myppid)};
+  struct stat st;
   struct sh_vars *shv;
   struct utsname uu;
 
+  // Create initial function context
+  call_function();
+  TT.ff->arg.v = toys.optargs;
+  TT.ff->arg.c = toys.optc;
+
   // Initialize magic and read only local variables
-  for (ii = 0; ii<ARRAY_LEN(magic) && (s = magic[ii]); ii++)
-    initvar(s, "")->flags = VAR_MAGIC+VAR_INT*('G'!=*s)+VAR_READONLY*('B'==*s);
+  srandom(TT.SECONDS = millitime());
+  for (ii = 0; ii<ARRAY_LEN(magic); ii++)
+    initvar(magic[ii], "")->flags = VAR_MAGIC|(VAR_INT*('G'!=*magic[ii]));
   for (ii = 0; ii<ARRAY_LEN(readonly); ii++)
     addvar(readonly[ii], TT.ff)->flags = VAR_READONLY|VAR_INT;
 
@@ -3889,16 +3646,30 @@
   initvar("PS4", "+ ");
 
   // Ensure environ copied and toys.envc set, and clean out illegal entries
-  for (from = 0; (s = environ[from]); from++) {
+  TT.ff->ifs = " \t\n";
+
+  for (from = pid = ppid = zpid = 0; (s = environ[from]); from++) {
+
+    // If nommu subshell gets handoff
+    if (!CFG_TOYBOX_FORK && !toys.stacktop) {
+      len = 0;
+      sscanf(s, "@%d,%d%n", &pid, &ppid, &len);
+      if (s[len]) pid = ppid = 0;
+      if (*s == '$' && s[1] == '=') zpid = atoi(s+2);
+// TODO marshall $- to subshell like $$
+    }
+
+    // Filter out non-shell variable names from inherited environ.
     if (*varend(s) != '=') continue;
-    if (!(shv = findvar(s, 0))) addvar(s, TT.ff)->flags = VAR_EXPORT|VAR_NOFREE;
+
+    if (!(shv = findvar(s, 0))) addvar(s, TT.ff)->flags = VAR_GLOBAL|VAR_NOFREE;
     else if (shv->flags&VAR_READONLY) continue;
     else {
       if (!(shv->flags&VAR_NOFREE)) {
         free(shv->str);
         shv->flags ^= VAR_NOFREE;
       }
-      shv->flags |= VAR_EXPORT;
+      shv->flags |= VAR_GLOBAL;
       shv->str = s;
     }
     cache_ifs(s, TT.ff);
@@ -3917,16 +3688,27 @@
       ss = s;
     } else if (*toybuf) s = toybuf; // from /proc/self/exe
   }
-  setvarval("_", s)->flags |= VAR_EXPORT;
+  setvarval("_", s)->flags |= VAR_GLOBAL;
   free(ss);
-
-  // TODO: this is in pipe, not environment
-  if (!(ss = getvar("SHLVL"))) export("SHLVL=1"); // Bash 5.0
+  if (!(ss = getvar("SHLVL"))) export("SHLVL=1");
   else {
     char buf[16];
 
     sprintf(buf, "%u", atoi(ss+6)+1);
-    setvarval("SHLVL", buf)->flags |= VAR_EXPORT;
+    setvarval("SHLVL", buf)->flags |= VAR_GLOBAL;
+  }
+
+//TODO indexed array,associative array,integer,local,nameref,readonly,uppercase
+//          if (s+1<ss && strchr("aAilnru", *s)) {
+
+  // Are we a nofork subshell? (check magic env variable and pipe status)
+  if (!CFG_TOYBOX_FORK && !toys.stacktop && pid==getpid() && ppid==myppid) {
+    if (fstat(254, &st) || !S_ISFIFO(st.st_mode)) error_exit(0);
+    TT.pid = zpid;
+    fcntl(254, F_SETFD, FD_CLOEXEC);
+    do_source(0, fdopen(254, "r"));
+
+    xexit();
   }
 }
 
@@ -3935,12 +3717,10 @@
   char *cc = 0;
   FILE *ff;
 
-//unsigned uu; dprintf(2, "%d main", getpid()); for (uu = 0; toys.argv[uu]; uu++) dprintf(2, " %s", toys.argv[uu]); dprintf(2, "\n");
-
   signal(SIGPIPE, SIG_IGN);
   TT.options = OPT_B;
   TT.pid = getpid();
-  srandom(TT.SECONDS = millitime());
+  TT.SECONDS = time(0);
 
   // TODO euid stuff?
   // TODO login shell?
@@ -3962,17 +3742,10 @@
     TT.options |= toys.optflags&0xff;
   }
 
-  // Create initial function context
-  call_function();
-  TT.ff->arg.v = toys.optargs;
-  TT.ff->arg.c = toys.optc;
-  TT.ff->ifs = " \t\n";
-
-  // Set up environment variables.
-  // Note: can call run_command() which blanks argument sections of TT and this,
-  // so parse everything we need from shell command line before here.
-  if (CFG_TOYBOX_FORK || toys.stacktop) subshell_setup(); // returns
-  else nommu_reentry(); // does not return
+  // Read environment for exports from parent shell. Note, calls run_sh()
+  // which blanks argument sections of TT and this, so parse everything
+  // we need from shell command line before that.
+  subshell_setup();
 
   if (TT.options&FLAG_i) {
     if (!getvar("PS1")) setvarval("PS1", getpid() ? "\\$ " : "# ");
@@ -3995,62 +3768,73 @@
 
 /********************* shell builtin functions *************************/
 
+#define CLEANUP_sh
 #define FOR_cd
 #include "generated/flags.h"
 void cd_main(void)
 {
-  char *from, *to = 0, *dd = *toys.optargs ? : (getvar("HOME") ? : "/"),
-       *pwd = FLAG(P) ? 0 : getvar("PWD"), *zap = 0;
-  struct stat st1, st2;
+  char *home = getvar("HOME") ? : "/", *pwd = getvar("PWD"), *from, *to = 0,
+    *dd = xstrdup(*toys.optargs ? *toys.optargs : home);
+  int bad = 0;
 
   // TODO: CDPATH? Really?
 
-  // For cd - use $OLDPWD as destination directory
-  if (!strcmp(dd, "-") && (!(dd = getvar("OLDPWD")) || !*dd))
-    return perror_msg("No $OLDPWD");
+  // prepend cwd or $PWD to relative path
+  if (*dd != '/') {
+    from = pwd ? : (to = getcwd(0, 0));
+    if (!from) setvarval("PWD", "(nowhere)");
+    else {
+      from = xmprintf("%s/%s", from, dd);
+      free(dd);
+      free(to);
+      dd = from;
+    }
+  }
 
-  if (*dd == '/') pwd = 0;
+  if (FLAG(P)) {
+    struct stat st;
+    char *pp;
 
-  // Did $PWD move out from under us?
-  if (pwd && !stat(".", &st1))
-    if (stat(pwd, &st2) || st1.st_dev!=st2.st_dev || st1.st_ino!=st2.st_ino)
-      pwd = 0;
-
-  // Handle logical relative path
-  if (pwd) {
-    zap = xmprintf("%s/%s", pwd, dd);
+    // Does this directory exist?
+    if ((pp = xabspath(dd, 1)) && stat(pp, &st) && !S_ISDIR(st.st_mode))
+      bad++, errno = ENOTDIR;
+    else {
+      free(dd);
+      dd = pp;
+    }
+  } else {
 
     // cancel out . and .. in the string
-    for (from = to = zap; *from;) {
+    for (from = to = dd; *from;) {
       if (*from=='/' && from[1]=='/') from++;
       else if (*from!='/' || from[1]!='.') *to++ = *from++;
       else if (!from[2] || from[2]=='/') from += 2;
       else if (from[2]=='.' && (!from[3] || from[3]=='/')) {
         from += 3;
-        while (to>zap && *--to != '/');
+        while (to>dd && *--to != '/');
       } else *to++ = *from++;
     }
-    if (to == zap) to++;
-    if (to-zap>1 && to[-1]=='/') to--;
+    if (to == dd) to++;
+    if (to-dd>1 && to[-1]=='/') to--;
     *to = 0;
   }
 
-  // If logical chdir doesn't work, fall back to physical
-  if (!zap || chdir(zap)) {
-    free(zap);
-    if (chdir(dd)) return perror_msg("%s", dd);
-    if (!(dd = getcwd(0, 0))) dd = xstrdup("(nowhere)");
-  } else dd = zap;
-
-  if ((pwd = getvar("PWD"))) setvarval("OLDPWD", pwd);
-  setvarval("PWD", dd);
-  free(dd);
-
-  if (!(TT.options&OPT_cd)) {
-    export("OLDPWD");
-    export("PWD");
-    TT.options |= OPT_cd;
+  if (bad || chdir(dd)) perror_msg("chdir '%s'", dd);
+  else {
+    if (pwd) {
+      setvarval("OLDPWD", pwd);
+      if (TT.cdcount == 1) {
+        export("OLDPWD");
+        TT.cdcount++;
+      }
+    }
+    setvarval("PWD", dd);
+    if (!TT.cdcount) {
+      export("PWD");
+      TT.cdcount++;
+    }
   }
+  free(dd);
 }
 
 void exit_main(void)
@@ -4124,6 +3908,7 @@
 }
 
 // TODO need test: unset clears var first and stops, function only if no var.
+#define CLEANUP_cd
 #define FOR_unset
 #include "generated/flags.h"
 
@@ -4152,6 +3937,7 @@
   }
 }
 
+#define CLEANUP_unset
 #define FOR_export
 #include "generated/flags.h"
 
@@ -4165,12 +3951,11 @@
     unsigned uu;
 
     for (uu = 0; vv[uu]; uu++) {
-      if ((vv[uu]->flags&(VAR_WHITEOUT|VAR_EXPORT))==VAR_EXPORT) {
+      if ((vv[uu]->flags&(VAR_WHITEOUT|VAR_GLOBAL))==VAR_GLOBAL) {
         xputs(eq = declarep(vv[uu]));
         free(eq);
       }
     }
-    free(vv);
 
     return;
   }
@@ -4178,53 +3963,16 @@
   // set/move variables
   for (arg = toys.optargs; *arg; arg++) {
     eq = varend(*arg);
-    if (eq == *arg || (*eq && eq[*eq=='+'] != '=')) {
+    if (eq == *arg || (*eq && *eq != '=')) {
       error_msg("bad %s", *arg);
       continue;
     }
 
-    if (FLAG(n)) set_varflags(*arg, 0, VAR_EXPORT);
+    if (FLAG(n)) unexport(*arg);
     else export(*arg);
   }
 }
 
-#define FOR_declare
-#include "generated/flags.h"
-
-void declare_main(void)
-{
-  unsigned uu, fl = toys.optflags&(FLAG(p)-1);
-  char *ss, **arg;
-// TODO: need a show_vars() to collate all the visible_vars() loop output
-// TODO: -g support including -gp
-// TODO: dump everything key=value and functions too
-  if (!toys.optc) {
-    struct sh_vars **vv = visible_vars();
-
-    for (uu = 0; vv[uu]; uu++) {
-      if ((vv[uu]->flags&VAR_WHITEOUT) || (fl && !(vv[uu]->flags&fl))) continue;
-      xputs(ss = declarep(vv[uu]));
-      free(ss);
-    }
-    free(vv);
-  } else if (FLAG(p)) for (arg = toys.optargs; *arg; arg++) {
-    struct sh_vars *vv = *varend(ss = *arg) ? 0 : findvar(ss, 0);
-
-    if (!vv) perror_msg("%s: not found", ss);
-    else {
-      xputs(ss = declarep(vv));
-      free(ss);
-    }
-  } else for (arg = toys.optargs; *arg; arg++) {
-    ss = varend(*arg);
-    if (ss == *arg || (*ss && ss[*ss=='+'] != '=')) {
-      error_msg("bad %s", *arg);
-      continue;
-    }
-    set_varflags(*arg, toys.optflags<<1, 0); // TODO +x unset
-  }
-}
-
 void eval_main(void)
 {
   char *s;
@@ -4241,6 +3989,7 @@
   free(s);
 }
 
+#define CLEANUP_export
 #define FOR_exec
 #include "generated/flags.h"
 
@@ -4324,6 +4073,7 @@
   }
 }
 
+#define CLEANUP_exec
 #define FOR_local
 #include "generated/flags.h"
 
@@ -4360,7 +4110,7 @@
 
     // Add local inheriting global status and setting whiteout if blank.
     if (!var || ff!=ff2) {
-      int flags = var ? var->flags&VAR_EXPORT : 0;
+      int flags = var ? var->flags&VAR_GLOBAL : 0;
 
       var = addvar(xmprintf("%s%s", *arg, *eq ? "" : "="), ff);
       var->flags = flags|(VAR_WHITEOUT*!*eq);
@@ -4399,6 +4149,7 @@
   --TT.srclvl;
 }
 
+#define CLEANUP_local
 #define FOR_wait
 #include "generated/flags.h"
 
diff --git a/toys/pending/strace.c b/toys/pending/strace.c
deleted file mode 100644
index ae8fca9..0000000
--- a/toys/pending/strace.c
+++ /dev/null
@@ -1,614 +0,0 @@
-/* strace.c - Trace system calls.
- *
- * Copyright 2020 The Android Open Source Project
- *
- * See https://man7.org/linux/man-pages/man2/syscall.2.html
-
-USE_STRACE(NEWTOY(strace, "^p#s#v", TOYFLAG_USR|TOYFLAG_SBIN))
-
-config STRACE
-  bool "strace"
-  default n
-  help
-    usage: strace [-fv] [-p PID] [-s NUM] COMMAND [ARGS...]
-
-    Trace systems calls made by a process.
-
-    -s	String length limit.
-    -v	Dump all of large structs/arrays.
-*/
-
-#include <sys/ptrace.h>
-#include <sys/user.h>
-
-#define FOR_strace
-#include "toys.h"
-
-GLOBALS(
-  long s, p;
-
-  char ioctl[32], *fmt;
-  long regs[256/sizeof(long)], syscall;
-  pid_t pid;
-  int arg;
-)
-
-  struct user_regs_struct regs;
-
-
-// Syscall args from https://man7.org/linux/man-pages/man2/syscall.2.html
-// REG_ORDER is args 0-6, SYSCALL, RESULT
-#if defined(__ARM_EABI__)
-static const char REG_ORDER[] = {0,1,2,3,4,5,7,0};
-#elif defined(__ARM_ARCH) && __ARM_ARCH == 8
-static const char REG_ORDER[] = {0,1,2,3,4,5,8,0};
-#elif defined(__i386__)
-// ebx,ecx,edx,esi,edi,ebp,orig_eax,eax
-static const char REG_ORDER[] = {0,1,2,3,4,5,11,6};
-#elif defined(__m68k__)
-// d1,d2,d3,d4,d5,a0,orig_d0,d0
-static const char REG_ORDER[] = {0,1,2,3,4,7,16,14};
-#elif defined(__PPC__) || defined(__PPC64__)
-static const char REG_ORDER[] = {3,4,5,6,7,8,0,3};
-#elif defined(__s390__) // also covers s390x
-// r2,r3,r4,r5,r6,r7,r1,r2 but mask+addr before r0 so +2
-static const char REG_ORDER[] = {4,5,6,7,8,9,3,4};
-#elif defined(__sh__)
-static const char REG_ORDER[] = {4,5,6,7,0,1,3,0};
-#elif defined(__x86_64__)
-// rdi,rsi,rdx,r10,r8,r9,orig_rax,rax
-static const char REG_ORDER[] = {14,13,12,7,9,8,15,10};
-#else
-#error unsupported architecture
-#endif
-
-#define C(x) case x: return #x
-
-#define FS_IOC_FSGETXATTR 0x801c581f
-#define FS_IOC_FSSETXATTR 0x401c5820
-#define FS_IOC_GETFLAGS 0x80086601
-#define FS_IOC_SETFLAGS 0x40086602
-#define FS_IOC_GETVERSION 0x80087601
-#define FS_IOC_SETVERSION 0x40047602
-struct fsxattr {
-  unsigned fsx_xflags;
-  unsigned fsx_extsize;
-  unsigned fsx_nextents;
-  unsigned fsx_projid;
-  unsigned fsx_cowextsize;
-  char fsx_pad[8];
-};
-
-static char *strioctl(int i)
-{
-  switch (i) {
-    C(FS_IOC_FSGETXATTR);
-    C(FS_IOC_FSSETXATTR);
-    C(FS_IOC_GETFLAGS);
-    C(FS_IOC_GETVERSION);
-    C(FS_IOC_SETFLAGS);
-    C(FS_IOC_SETVERSION);
-    C(SIOCGIFADDR);
-    C(SIOCGIFBRDADDR);
-    C(SIOCGIFCONF);
-    C(SIOCGIFDSTADDR);
-    C(SIOCGIFFLAGS);
-    C(SIOCGIFHWADDR);
-    C(SIOCGIFMAP);
-    C(SIOCGIFMTU);
-    C(SIOCGIFNETMASK);
-    C(SIOCGIFTXQLEN);
-    C(TCGETS);
-    C(TCSETS);
-    C(TIOCGWINSZ);
-    C(TIOCSWINSZ);
-  }
-  sprintf(toybuf, "%#x", i);
-  return toybuf;
-}
-
-// TODO: move to lib, implement errno(1)?
-static char *strerrno(int e)
-{
-  switch (e) {
-    // uapi errno-base.h
-    C(EPERM);
-    C(ENOENT);
-    C(ESRCH);
-    C(EINTR);
-    C(EIO);
-    C(ENXIO);
-    C(E2BIG);
-    C(ENOEXEC);
-    C(EBADF);
-    C(ECHILD);
-    C(EAGAIN);
-    C(ENOMEM);
-    C(EACCES);
-    C(EFAULT);
-    C(ENOTBLK);
-    C(EBUSY);
-    C(EEXIST);
-    C(EXDEV);
-    C(ENODEV);
-    C(ENOTDIR);
-    C(EISDIR);
-    C(EINVAL);
-    C(ENFILE);
-    C(EMFILE);
-    C(ENOTTY);
-    C(ETXTBSY);
-    C(EFBIG);
-    C(ENOSPC);
-    C(ESPIPE);
-    C(EROFS);
-    C(EMLINK);
-    C(EPIPE);
-    C(EDOM);
-    C(ERANGE);
-    // uapi errno.h
-    C(EDEADLK);
-    C(ENAMETOOLONG);
-    C(ENOLCK);
-    C(ENOSYS);
-    C(ENOTEMPTY);
-    C(ELOOP);
-    C(ENOMSG);
-    // ...etc; fill in as we see them in practice?
-  }
-  sprintf(toybuf, "%d", e);
-  return toybuf;
-}
-
-#undef C
-
-static void xptrace(int req, pid_t pid, void *addr, void *data)
-{
-  if (ptrace(req, pid, addr, data)) perror_exit("ptrace pid %d", pid);
-}
-
-static void get_regs()
-{
-  xptrace(PTRACE_GETREGS, TT.pid, 0, TT.regs);
-}
-
-static void ptrace_struct(long addr, void *dst, size_t bytes)
-{
-  int offset = 0, i;
-  long v;
-
-  for (i=0; i<bytes; i+=sizeof(long)) {
-    errno = 0;
-    v = ptrace(PTRACE_PEEKDATA, TT.pid, addr + offset);
-    if (errno) perror_exit("PTRACE_PEEKDATA failed");
-    memcpy(dst + offset, &v, sizeof(v));
-    offset += sizeof(long);
-  }
-}
-
-// TODO: this all relies on having the libc structs match the kernel structs,
-// which isn't always true for glibc...
-static void print_struct(long addr)
-{
-  if (!addr) { // All NULLs look the same...
-    fprintf(stderr, "NULL");
-    while (*TT.fmt != '}') ++TT.fmt;
-    ++TT.fmt;
-  } else if (strstart(&TT.fmt, "ifreq}")) {
-    struct ifreq ir;
-
-    ptrace_struct(addr, &ir, sizeof(ir));
-    // TODO: is this always an ioctl? use TT.regs[REG_ORDER[1]] to work out what to show.
-    fprintf(stderr, "{...}");
-  } else if (strstart(&TT.fmt, "fsxattr}")) {
-    struct fsxattr fx;
-
-    ptrace_struct(addr, &fx, sizeof(fx));
-    fprintf(stderr, "{fsx_xflags=%#x, fsx_extsize=%d, fsx_nextents=%d, "
-        "fsx_projid=%d, fsx_cowextsize=%d}", fx.fsx_xflags, fx.fsx_extsize,
-        fx.fsx_nextents, fx.fsx_projid, fx.fsx_cowextsize);
-  } else if (strstart(&TT.fmt, "long}")) {
-    long l;
-
-    ptrace_struct(addr, &l, sizeof(l));
-    fprintf(stderr, "%ld", l);
-  } else if (strstart(&TT.fmt, "longx}")) {
-    long l;
-
-    ptrace_struct(addr, &l, sizeof(l));
-    fprintf(stderr, "%#lx", l);
-  } else if (strstart(&TT.fmt, "rlimit}")) {
-    struct rlimit rl;
-
-    ptrace_struct(addr, &rl, sizeof(rl));
-    fprintf(stderr, "{rlim_cur=%lld, rlim_max=%lld}",
-        (long long)rl.rlim_cur, (long long)rl.rlim_max);
-  } else if (strstart(&TT.fmt, "sigset}")) {
-    long long ss;
-    int i;
-
-    ptrace_struct(addr, &ss, sizeof(ss));
-    fprintf(stderr, "[");
-    for (i=0; i<64;++i) {
-      // TODO: use signal names, fix spacing
-      if (ss & (1ULL<<i)) fprintf(stderr, "%d ", i);
-    }
-    fprintf(stderr, "]");
-  } else if (strstart(&TT.fmt, "stat}")) {
-    struct stat sb;
-
-    ptrace_struct(addr, &sb, sizeof(sb));
-    // TODO: decode IFMT bits in st_mode
-    if (FLAG(v)) {
-      // TODO: full atime/mtime/ctime dump.
-      fprintf(stderr, "{st_dev=makedev(%#x, %#x), st_ino=%ld, st_mode=%o, "
-          "st_nlink=%ld, st_uid=%d, st_gid=%d, st_blksize=%ld, st_blocks=%ld, "
-          "st_size=%lld, st_atime=%ld, st_mtime=%ld, st_ctime=%ld}",
-          dev_major(sb.st_dev), dev_minor(sb.st_dev), sb.st_ino, sb.st_mode,
-          sb.st_nlink, sb.st_uid, sb.st_gid, sb.st_blksize, sb.st_blocks,
-          (long long)sb.st_size, sb.st_atime, sb.st_mtime, sb.st_ctime);
-    } else {
-      fprintf(stderr, "{st_mode=%o, st_size=%lld, ...}", sb.st_mode,
-        (long long)sb.st_size);
-    }
-  } else if (strstart(&TT.fmt, "termios}")) {
-    struct termios to;
-
-    ptrace_struct(addr, &to, sizeof(to));
-    fprintf(stderr, "{c_iflag=%#lx, c_oflag=%#lx, c_cflag=%#lx, c_lflag=%#lx}",
-        (long)to.c_iflag, (long)to.c_oflag, (long)to.c_cflag, (long)to.c_lflag);
-  } else if (strstart(&TT.fmt, "timespec}")) {
-    struct timespec ts;
-
-    ptrace_struct(addr, &ts, sizeof(ts));
-    fprintf(stderr, "{tv_sec=%lld, tv_nsec=%lld}",
-        (long long)ts.tv_sec, (long long)ts.tv_nsec);
-  } else if (strstart(&TT.fmt, "winsize}")) {
-    struct winsize ws;
-
-    ptrace_struct(addr, &ws, sizeof(ws));
-    fprintf(stderr, "{ws_row=%hu, ws_col=%hu, ws_xpixel=%hu, ws_ypixel=%hu}",
-        ws.ws_row, ws.ws_col, ws.ws_xpixel, ws.ws_ypixel);
-  } else abort();
-}
-
-static void print_ptr(long addr)
-{
-  if (!addr) fprintf(stderr, "NULL");
-  else fprintf(stderr, "0x%lx", addr);
-}
-
-static void print_string(long addr)
-{
-  long offset = 0, total = 0;
-  int done = 0, i;
-
-  fputc('"', stderr);
-  while (!done) {
-    errno = 0;
-    long v = ptrace(PTRACE_PEEKDATA, TT.pid, addr + offset);
-    if (errno) return;
-    memcpy(toybuf, &v, sizeof(v));
-    for (i=0; i<sizeof(v); ++i) {
-      if (!toybuf[i]) {
-        // TODO: handle the case of dumping n bytes (e.g. read()/write()), not
-        // just NUL-terminated strings.
-        done = 1;
-        break;
-      }
-      if (isprint(toybuf[i])) fputc(toybuf[i], stderr);
-      else {
-        // TODO: reuse an existing escape function.
-        fputc('\\', stderr);
-        if (toybuf[i] == '\n') fputc('n', stderr);
-        else if (toybuf[i] == '\r') fputc('r', stderr);
-        else if (toybuf[i] == '\t') fputc('t', stderr);
-        else fprintf(stderr, "x%2.2x", toybuf[i]);
-      }
-      if (++total >= TT.s) {
-        done = 1;
-        break;
-      }
-    }
-    offset += sizeof(v);
-  }
-  fputc('"', stderr);
-}
-
-static void print_bitmask(int bitmask, long v, char *zero, ...)
-{
-  va_list ap;
-  int first = 1;
-
-  if (!v && zero) {
-    fprintf(stderr, "%s", zero);
-    return;
-  }
-
-  va_start(ap, zero);
-  for (;;) {
-    int this = va_arg(ap, int);
-    char *name;
-
-    if (!this) break;
-    name = va_arg(ap, char*);
-    if (bitmask) {
-      if (v & this) {
-        fprintf(stderr, "%s%s", first?"":"|", name);
-        first = 0;
-        v &= ~this;
-      }
-    } else {
-      if (v == this) {
-        fprintf(stderr, "%s", name);
-        v = 0;
-        break;
-      }
-    }
-  }
-  va_end(ap);
-  if (v) fprintf(stderr, "%s%#lx", first?"":"|", v);
-}
-
-static void print_flags(long v)
-{
-#define C(n) n, #n
-  if (strstart(&TT.fmt, "access|")) {
-    print_bitmask(1, v, "F_OK", C(R_OK), C(W_OK), C(X_OK), 0);
-  } else if (strstart(&TT.fmt, "mmap|")) {
-    print_bitmask(1, v, 0, C(MAP_SHARED), C(MAP_PRIVATE), C(MAP_32BIT),
-        C(MAP_ANONYMOUS), C(MAP_FIXED), C(MAP_GROWSDOWN), C(MAP_HUGETLB),
-        C(MAP_DENYWRITE), 0);
-  } else if (strstart(&TT.fmt, "open|")) {
-    print_bitmask(1, v, "O_RDONLY", C(O_WRONLY), C(O_RDWR), C(O_CLOEXEC),
-        C(O_CREAT), C(O_DIRECTORY), C(O_EXCL), C(O_NOCTTY), C(O_NOFOLLOW),
-        C(O_TRUNC), C(O_ASYNC), C(O_APPEND), C(O_DSYNC), C(O_EXCL),
-        C(O_NOATIME), C(O_NONBLOCK), C(O_PATH), C(O_SYNC),
-        0x4000, "O_DIRECT", 0x8000, "O_LARGEFILE", 0x410000, "O_TMPFILE", 0);
-  } else if (strstart(&TT.fmt, "prot|")) {
-    print_bitmask(1,v,"PROT_NONE",C(PROT_READ),C(PROT_WRITE),C(PROT_EXEC),0);
-  } else abort();
-}
-
-static void print_alternatives(long v)
-{
-  if (strstart(&TT.fmt, "rlimit^")) {
-    print_bitmask(0, v, "RLIMIT_CPU", C(RLIMIT_FSIZE), C(RLIMIT_DATA),
-        C(RLIMIT_STACK), C(RLIMIT_CORE), C(RLIMIT_RSS), C(RLIMIT_NPROC),
-        C(RLIMIT_NOFILE), C(RLIMIT_MEMLOCK), C(RLIMIT_AS), C(RLIMIT_LOCKS),
-        C(RLIMIT_SIGPENDING), C(RLIMIT_MSGQUEUE), C(RLIMIT_NICE),
-        C(RLIMIT_RTPRIO), C(RLIMIT_RTTIME), 0);
-  } else if (strstart(&TT.fmt, "seek^")) {
-    print_bitmask(0, v, "SEEK_SET", C(SEEK_CUR), C(SEEK_END), C(SEEK_DATA),
-        C(SEEK_HOLE), 0);
-  } else if (strstart(&TT.fmt, "sig^")) {
-    print_bitmask(0, v, "SIG_BLOCK", C(SIG_UNBLOCK), C(SIG_SETMASK), 0);
-  } else abort();
-}
-
-static void print_args()
-{
-  int i;
-
-  // Loop through arguments and print according to format string
-  for (i = 0; *TT.fmt; i++, TT.arg++) {
-    long v = TT.regs[REG_ORDER[TT.arg]];
-    char *s, ch;
-
-    if (i) fprintf(stderr, ", ");
-    switch (ch = *TT.fmt++) {
-      case 'd': fprintf(stderr, "%ld", v); break; // decimal
-      case 'f': if ((int) v == AT_FDCWD) fprintf(stderr, "AT_FDCWD");
-                else fprintf(stderr, "%ld", v);
-                break;
-      case 'i': fprintf(stderr, "%s", strioctl(v)); break; // decimal
-      case 'm': fprintf(stderr, "%03o", (unsigned) v); break; // mode for open()
-      case 'o': fprintf(stderr, "%ld", v); break; // off_t
-      case 'p': print_ptr(v); break;
-      case 's': print_string(v); break;
-      case 'S': // The libc-reserved signals aren't known to num_to_sig().
-                // TODO: use an strace-only routine for >= 32?
-                if (!(s = num_to_sig(v))) fprintf(stderr, "%ld", v);
-                else fprintf(stderr, "SIG%s", s);
-                break;
-      case 'z': fprintf(stderr, "%zd", v); break; // size_t
-      case 'x': fprintf(stderr, "%lx", v); break; // hex
-
-      case '{': print_struct(v); break;
-      case '|': print_flags(v); break;
-      case '^': print_alternatives(v); break;
-
-      case '/': return; // Separates "enter" and "exit" arguments.
-
-      default: fprintf(stderr, "?%c<0x%lx>", ch, v); break;
-    }
-  }
-}
-
-static void print_enter(void)
-{
-  char *name;
-
-  get_regs();
-  TT.syscall = TT.regs[REG_ORDER[6]];
-  if (TT.syscall == __NR_ioctl) {
-    name = "ioctl";
-    switch (TT.regs[REG_ORDER[1]]) {
-      case FS_IOC_FSGETXATTR: TT.fmt = "fi/{fsxattr}"; break;
-      case FS_IOC_FSSETXATTR: TT.fmt = "fi{fsxattr}"; break;
-      case FS_IOC_GETFLAGS: TT.fmt = "fi/{longx}"; break;
-      case FS_IOC_GETVERSION: TT.fmt = "fi/{long}"; break;
-      case FS_IOC_SETFLAGS: TT.fmt = "fi{long}"; break;
-      case FS_IOC_SETVERSION: TT.fmt = "fi{long}"; break;
-      //case SIOCGIFCONF: struct ifconf
-      case SIOCGIFADDR:
-      case SIOCGIFBRDADDR:
-      case SIOCGIFDSTADDR:
-      case SIOCGIFFLAGS:
-      case SIOCGIFHWADDR:
-      case SIOCGIFMAP:
-      case SIOCGIFMTU:
-      case SIOCGIFNETMASK:
-      case SIOCGIFTXQLEN: TT.fmt = "fi/{ifreq}"; break;
-      case SIOCSIFADDR:
-      case SIOCSIFBRDADDR:
-      case SIOCSIFDSTADDR:
-      case SIOCSIFFLAGS:
-      case SIOCSIFHWADDR:
-      case SIOCSIFMAP:
-      case SIOCSIFMTU:
-      case SIOCSIFNETMASK:
-      case SIOCSIFTXQLEN: TT.fmt = "fi{ifreq}"; break;
-      case TCGETS: TT.fmt = "fi/{termios}"; break;
-      case TCSETS: TT.fmt = "fi{termios}"; break;
-      case TIOCGWINSZ: TT.fmt = "fi/{winsize}"; break;
-      case TIOCSWINSZ: TT.fmt = "fi{winsize}"; break;
-      default:
-        TT.fmt = (TT.regs[REG_ORDER[0]]&1) ? "fip" : "fi/p";
-        break;
-    }
-  } else switch (TT.syscall) {
-#define SC(n,f) case __NR_ ## n: name = #n; TT.fmt = f; break
-    SC(access, "s|access|");
-    SC(arch_prctl, "dp");
-    SC(brk, "p");
-    SC(close, "d");
-    SC(connect, "fpd"); // TODO: sockaddr
-    SC(dup, "f");
-    SC(dup2, "ff");
-    SC(dup3, "ff|open|");
-    SC(execve, "spp");
-    SC(exit_group, "d");
-    SC(fcntl, "fdp"); // TODO: probably needs special case
-    SC(fstat, "f/{stat}");
-    SC(futex, "pdxppx");
-    SC(getdents64, "dpz");
-    SC(geteuid, "");
-    SC(getuid, "");
-
-    SC(getxattr, "sspz");
-    SC(lgetxattr, "sspz");
-    SC(fgetxattr, "fspz");
-
-    SC(lseek, "fo^seek^");
-    SC(lstat, "s/{stat}");
-    SC(mmap, "pz|prot||mmap|fx");
-    SC(mprotect, "pz|prot|");
-    SC(mremap, "pzzdp"); // TODO: flags
-    SC(munmap, "pz");
-    SC(nanosleep, "{timespec}/{timespec}");
-    SC(newfstatat, "fs/{stat}d");
-    SC(open, "sd|open|m");
-    SC(openat, "fs|open|m");
-    SC(poll, "pdd");
-    SC(prlimit64, "d^rlimit^{rlimit}/{rlimit}");
-    SC(read, "d/sz");
-    SC(readlinkat, "s/sz");
-    SC(rt_sigaction, "Sppz");
-    SC(rt_sigprocmask, "^sig^{sigset}/{sigset}z");
-    SC(set_robust_list, "pd");
-    SC(set_tid_address, "p");
-    SC(socket, "ddd"); // TODO: flags
-    SC(stat, "s/{stat}");
-    SC(statfs, "sp");
-    SC(sysinfo, "p");
-    SC(umask, "m");
-    SC(uname, "p");
-    SC(write, "dsz");
-    default:
-      sprintf(name = toybuf, "SYS_%ld", TT.syscall);
-      TT.fmt = "pppppp";
-      break;
-  }
-
-  fprintf(stderr, "%s(", name);
-  TT.arg = 0;
-  print_args();
-}
-
-static void print_exit(void)
-{
-  long result;
-
-  get_regs();
-  result = TT.regs[REG_ORDER[7]];
-  if (*TT.fmt) print_args();
-  fprintf(stderr, ") = ");
-  if (result >= -4095UL)
-    fprintf(stderr, "-1 %s (%s)", strerrno(-result), strerror(-result));
-  else if (TT.syscall==__NR_mmap || TT.syscall==__NR_brk) print_ptr(result);
-  else fprintf(stderr, "%ld", result);
-  fputc('\n', stderr);
-}
-
-static int next(void)
-{
-  int status;
-
-  for (;;) {
-    ptrace(PTRACE_SYSCALL, TT.pid, 0, 0);
-    waitpid(TT.pid, &status, 0);
-    // PTRACE_O_TRACESYSGOOD sets bit 7 to indicate a syscall.
-    if (WIFSTOPPED(status) && WSTOPSIG(status) & 0x80) return 1;
-    if (WIFEXITED(status)) return 0;
-    fprintf(stderr, "[stopped %d (%x)]\n", status, WSTOPSIG(status));
-  }
-}
-
-static void strace_detach(int s)
-{
-  xptrace(PTRACE_DETACH, TT.pid, 0, 0);
-  exit(1);
-}
-
-void strace_main(void)
-{
-  int status;
-
-  if (!FLAG(s)) TT.s = 32;
-
-  if (FLAG(p)) {
-    if (*toys.optargs) help_exit("No arguments with -p");
-    TT.pid = TT.p;
-    signal(SIGINT, strace_detach);
-    // TODO: PTRACE_SEIZE instead?
-    xptrace(PTRACE_ATTACH, TT.pid, 0, 0);
-  } else {
-    if (!*toys.optargs) help_exit("Needs 1 argument");
-    TT.pid = xfork();
-    if (!TT.pid) {
-      errno = 0;
-      ptrace(PTRACE_TRACEME);
-      if (errno) perror_exit("PTRACE_TRACEME failed");
-      raise(SIGSTOP);
-      toys.stacktop = 0;
-      xexec(toys.optargs);
-    }
-  }
-
-  do {
-    waitpid(TT.pid, &status, 0);
-  } while (!WIFSTOPPED(status));
-
-  // TODO: PTRACE_O_TRACEEXIT
-  // TODO: PTRACE_O_TRACEFORK/PTRACE_O_TRACEVFORK/PTRACE_O_TRACECLONE for -f.
-  errno = 0;
-  ptrace(PTRACE_SETOPTIONS, TT.pid, 0, PTRACE_O_TRACESYSGOOD);
-  if (errno) perror_exit("PTRACE_SETOPTIONS PTRACE_O_TRACESYSGOOD failed");
-
-  // TODO: real strace swallows the failed execve()s if it started the child
-
-  for (;;) {
-    if (!next()) break;
-    print_enter();
-    if (!next()) break;
-    print_exit();
-  }
-
-  // TODO: support -f and keep track of children.
-  waitpid(TT.pid, &status, 0);
-  if (WIFEXITED(status))
-    fprintf(stderr, "+++ exited with %d +++\n", WEXITSTATUS(status));
-  if (WIFSTOPPED(status))
-    fprintf(stderr, "+++ stopped with %d +++\n", WSTOPSIG(status));
-}
diff --git a/toys/pending/syslogd.c b/toys/pending/syslogd.c
index 8c60dcd..87aa228 100644
--- a/toys/pending/syslogd.c
+++ b/toys/pending/syslogd.c
@@ -310,7 +310,7 @@
   return write(tf->logfd, toybuf, len);
 }
 
-//Parse message and write to file.
+//Parse messege and write to file.
 static void logmsg(char *msg, int len)
 {
   time_t now;
@@ -321,7 +321,7 @@
 
   char *omsg = msg;
   int olen = len, fac, lvl;
-
+  
   if (*msg == '<') { // Extract the priority no.
     pri = (int) strtoul(msg + 1, &p, 10);
     if (*p == '>') msg = p + 1;
@@ -342,7 +342,7 @@
   fac = LOG_FAC(pri);
   lvl = LOG_PRI(pri);
 
-  if (toys.optflags & FLAG_K) len = sprintf(toybuf, "<%d> %s", pri, msg);
+  if (toys.optflags & FLAG_K) len = sprintf(toybuf, "<%d> %s\n", pri, msg);
   else {
     char facbuf[12], pribuf[12];
 
@@ -351,8 +351,8 @@
 
     p = "local";
     if (!uname(&uts)) p = uts.nodename;
-    if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s", ts, msg);
-    else len = sprintf(toybuf, "%s %s %s.%s %s", ts, p, facstr, lvlstr, msg);
+    if (toys.optflags & FLAG_S) len = sprintf(toybuf, "%s %s\n", ts, msg);
+    else len = sprintf(toybuf, "%s %s %s.%s %s\n", ts, p, facstr, lvlstr, msg);
   }
   if (lvl >= TT.log_prio) return;
 
@@ -454,7 +454,7 @@
     nfds++;
   }
   if (!nfds) {
-    error_msg("Can't open single socket for listening.");
+    error_msg("Can't open single socket for listenning.");
     goto clean_and_exit;
   }
 
@@ -524,19 +524,8 @@
       for (tsd = TT.lsocks; tsd; tsd = tsd->next) {
         int sd = tsd->sd;
         if (FD_ISSET(sd, &rfds)) {
-          // Buffer is of 1 KiB, hence reading only 1022 bytes, reserving 1
-          // for '\n' and 1 for '\0'
-          int len = read(sd, buffer, 1022);
-
-          // The syslog function's documentation says that a trailing '\n' is
-          // optional. We trim any that are present, and then append one.
-          while (len > 0 &&
-                 (buffer[len - 1] == '\n' || buffer[len - 1] == '\0')) {
-            --len;
-          }
-
+          int len = read(sd, buffer, 1023); //buffer is of 1K, hence readingonly 1023 bytes, 1 for NUL
           if (len > 0) {
-            buffer[len++] = '\n';
             buffer[len] = '\0';
             if((toys.optflags & FLAG_D) && (len == last_len))
               if (!memcmp(last_buf, buffer, len)) break;
diff --git a/toys/pending/tftpd.c b/toys/pending/tftpd.c
index b1ebb01..f945aba 100644
--- a/toys/pending/tftpd.c
+++ b/toys/pending/tftpd.c
@@ -84,21 +84,6 @@
     perror_exit("sendto failed");
 }
 
-// Advance to the next option or value. Returns NULL if there are no
-// more options.
-static char *next_token(char *at, char *end)
-{
-  if (at == NULL) return NULL;
-
-  for (; at < end; at++) {
-    if (*at == '\0') {
-      at++;
-      break;
-    }
-  }
-  return (at < end) ? at : NULL;
-}
-
 // Used to send / receive packets.
 static void do_action(struct sockaddr *srcaddr, struct sockaddr *dstaddr,
     socklen_t socklen, char *file, int opcode, int tsize, int blksize)
@@ -223,7 +208,7 @@
         break;
       }
     }
-
+    
     // server will receive DATA pkt and write the data.
     if ((opcode == TFTPD_OP_WRQ) && (pktopcode == TFTPD_OP_DATA)) {
       if (rblockno == blockno) {
@@ -233,7 +218,7 @@
           send_errpkt(dstaddr, socklen, "write error");
           break;
         }
-
+      
         if (nw != blksize) done = 1;
       }
       continue;
@@ -251,11 +236,10 @@
 
 void tftpd_main(void)
 {
-  int fd = 0, recvmsg_len, opcode, blksize = TFTPD_BLKSIZE, tsize = 0, set =1, bflag = 0;
+  int fd = 0, recvmsg_len, rbuflen, opcode, blksize = TFTPD_BLKSIZE, tsize = 0, set =1;
   struct sockaddr_storage srcaddr, dstaddr;
   socklen_t socklen = sizeof(struct sockaddr_storage);
   char *buf = toybuf;
-  char *end;
 
   memset(&srcaddr, 0, sizeof(srcaddr));
   if (getsockname(0, (struct sockaddr *)&srcaddr, &socklen)) help_exit(0);
@@ -264,7 +248,6 @@
   if (*toys.optargs) xchroot(*toys.optargs);
 
   recvmsg_len = recvfrom(fd, toybuf, blksize, 0, (void *)&dstaddr, &socklen);
-  end = toybuf + recvmsg_len;
 
   TT.sfd = xsocket(dstaddr.ss_family, SOCK_DGRAM, 0);
   if (setsockopt(TT.sfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&set,
@@ -292,29 +275,32 @@
     return;
   }
 
-  buf = next_token(buf, end);
+  buf += strlen(buf) + 1; //1 '\0'.
   // As per RFC 1350, mode is case in-sensitive.
-  if (buf == NULL || strcasecmp(buf, "octet")) {
+  if (buf >= toybuf+recvmsg_len || strcasecmp(buf, "octet")) {
     send_errpkt((struct sockaddr*)&dstaddr, socklen, "packet format error");
     return;
   }
 
   //RFC2348. e.g. of size type: "ttype1\0ttype1_val\0...ttypeN\0ttypeN_val\0"
-  for (buf = next_token(buf, end); buf != NULL; buf = next_token(buf, end)) {
-    char *opt = buf;
-    buf = next_token(buf, end);
-    if (buf == NULL) break; // Missing value.
+  buf += strlen(buf) + 1;
+  rbuflen = toybuf + recvmsg_len - buf;
+  if (rbuflen) {
+    int jump = 0, bflag = 0;
 
-    if (!bflag && !strcasecmp(opt, "blksize")) {
-      errno = 0;
-      blksize = strtoul(buf, NULL, 10);
-      if (errno || blksize > 65564 || blksize < 8) blksize = TFTPD_BLKSIZE;
-      bflag ^= 1;
-    } else if (!tsize && !strcasecmp(opt, "tsize")) tsize ^= 1;
+    for (; rbuflen; rbuflen -= jump, buf += jump) {
+      if (!bflag && !strcasecmp(buf, "blksize")) { //get blksize
+        errno = 0;
+        blksize = strtoul(buf, NULL, 10);
+        if (errno || blksize > 65564 || blksize < 8) blksize = TFTPD_BLKSIZE;
+        bflag ^= 1;
+      } else if (!tsize && !strcasecmp(buf, "tsize")) tsize ^= 1;
+      
+      jump += strlen(buf) + 1;
+    }
+    tsize &= (opcode == TFTPD_OP_RRQ);
   }
 
-  tsize &= (opcode == TFTPD_OP_RRQ);
-
   //do send / receive file.
   do_action((struct sockaddr*)&srcaddr, (struct sockaddr*)&dstaddr,
       socklen, toybuf + 2, opcode, tsize, blksize);
diff --git a/toys/pending/unicode.c b/toys/pending/unicode.c
new file mode 100644
index 0000000..0a9eb24
--- /dev/null
+++ b/toys/pending/unicode.c
@@ -0,0 +1,65 @@
+/* unicode.c - convert between Unicode and UTF-8
+ *
+ * Copyright 2020 The Android Open Source Project.
+ *
+ * Loosely based on the Plan9/Inferno unicode(1).
+
+USE_UNICODE(NEWTOY(unicode, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+
+config UNICODE
+  bool "unicode"
+  default n
+  help
+    usage: unicode [[min]-max]
+
+    Convert between Unicode code points and UTF-8, in both directions.
+*/
+
+#define FOR_unicode
+#include "toys.h"
+
+static void codepoint(unsigned wc) {
+  char *low="NULSOHSTXETXEOTENQACKBELBS HT LF VT FF CR SO SI DLEDC1DC2DC3DC4"
+            "NAKSYNETBCANEM SUBESCFS GS RS US ";
+  unsigned n, i;
+
+  printf("U+%04X : ", wc);
+  if (wc < ' ') printf("%.3s", low+(wc*3));
+  else if (wc == 0x7f) printf("DEL");
+  else {
+    toybuf[n = wctoutf8(toybuf, wc)] = 0;
+    printf("%s%s", toybuf, n>1 ? " :":"");
+    if (n>1) for (i = 0; i < n; i++) printf(" %#02x", toybuf[i]);
+  }
+  xputc('\n');
+}
+
+void unicode_main(void)
+{
+  unsigned from, to;
+  char next, **args;
+
+  for (args = toys.optargs; *args; args++) {
+    // unicode 660-666 => table of `U+0600 : ٠ : 0xd9 0xa0` etc.
+    if (sscanf(*args, "%x-%x%c", &from, &to, &next) == 2) {
+      while (from <= to) codepoint(from++);
+
+    // unicode 666 => just `U+0666 : ٦ : 0xd9 0xa6`.
+    } else if (sscanf(*args, "%x%c", &from, &next) == 1) {
+      codepoint(from);
+
+    // unicode hello => table showing every character in the string.
+    } else {
+      char *s = *args;
+      size_t l = strlen(s);
+      wchar_t wc;
+      int n;
+
+      while ((n = utf8towc(&wc, s, l)) > 0) {
+        codepoint(wc);
+        s += n;
+        l -= n;
+      }
+    }
+  }
+}
diff --git a/toys/pending/userdel.c b/toys/pending/userdel.c
index 51ee67c..8307c0f 100644
--- a/toys/pending/userdel.c
+++ b/toys/pending/userdel.c
@@ -27,7 +27,6 @@
   char *filenamesfx = NULL, *sfx = NULL, *line = NULL;
   FILE *exfp, *newfp;
   int ulen = strlen(username);
-  size_t allocated_length = 0;
   struct flock lock;
 
   filenamesfx = xmprintf("%s+", filename);
@@ -50,9 +49,10 @@
 
   newfp = xfopen(filenamesfx, "w+");
 
-  while (getline(&line, &allocated_length, exfp) > 0) {
+  while ((line = get_line(fileno(exfp))) != NULL){
     sprintf(toybuf, "%s:",username);
-    if (strncmp(line, toybuf, ulen+1)) {
+    if (!strncmp(line, toybuf, ulen+1)) goto LOOP;
+    else {
       char *n, *p = strrchr(line, ':');
 
       if (p && *++p && (n = strstr(p, username))) {
@@ -72,8 +72,9 @@
         if (!n) fprintf(newfp, "%s\n", line);
       } else fprintf(newfp, "%s\n", line);
     }
+LOOP:
+    free(line);
   }
-  free(line);
   fcntl(fileno(exfp), F_SETLK, &lock);
   fclose(exfp);
   errno = 0;
@@ -90,8 +91,9 @@
 
 void userdel_main(void)
 {
-  struct passwd *pwd = xgetpwnam(*toys.optargs);
+  struct passwd *pwd = NULL;
 
+  pwd = xgetpwnam(*toys.optargs);
   update_password("/etc/passwd", pwd->pw_name, NULL);
   update_password("/etc/shadow", pwd->pw_name, NULL);
 
@@ -104,7 +106,7 @@
   update_groupfiles("/etc/group", *toys.optargs);
   update_groupfiles("/etc/gshadow", *toys.optargs);
 
-  if (FLAG(r)) {
+  if (toys.optflags & FLAG_r) {
     char *arg[] = {"rm", "-fr", pwd->pw_dir, NULL, NULL};
 
     sprintf(toybuf, "/var/spool/mail/%s",pwd->pw_name);
diff --git a/toys/pending/vi.c b/toys/pending/vi.c
index bbb0a90..da43d5d 100644
--- a/toys/pending/vi.c
+++ b/toys/pending/vi.c
@@ -84,7 +84,7 @@
 //get utf8 length and width at same time
 static int utf8_lnw(int *width, char *s, int bytes)
 {
-  unsigned wc;
+  wchar_t wc;
   int length = 1;
 
   if (*s == '\t') *width = TT.tabstop;
@@ -518,16 +518,13 @@
 
   if (filename) {
     int fd = open(filename, O_RDONLY);
-    long long size;
+    size_t size;
+    char *data;
 
-    if (fd == -1 || !(size = fdlength(fd))) {
-      insert_str("", 0, 0, 0, STACK);
-      TT.filesize = 0;
-
-      return 0;
-    }
-    insert_str(xmmap(0, size, PROT_READ, MAP_SHARED, fd, 0), 0, size,size,MMAP);
+    if (fd == -1) return 0;
+    data = xmmap(0, size = fdlength(fd), PROT_READ, MAP_SHARED, fd, 0);
     xclose(fd);
+    insert_str(data, 0, size, size, MMAP);
     TT.filesize = text_filesize();
   }
 
@@ -559,6 +556,7 @@
   else chmod(toybuf, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
   xrename(toybuf, filename);
   linelist_load(filename);
+
 }
 
 //jump into valid offset index
@@ -1294,9 +1292,9 @@
 {
   int ret = 0;
   if (wc < 32 && TT.list) {
-    xputsn("\e[1m");
+    tty_esc("1m");
     ret = crunch_escape(out,cols,wc);
-    xputsn("\e[m");
+    tty_esc("m");
   } else if (wc == 0x09) {
     if (out) {
       int i = TT.tabstop;
@@ -1314,9 +1312,10 @@
 {
   int columns = 0, col, bytes;
   char *start, *end;
-  unsigned wc;
 
   for (end = start = *str; *end && n>0; columns += col, end += bytes, n -= bytes) {
+    wchar_t wc;
+
     if ((bytes = utf8towc(&wc, end, 4))>0 && (col = wcwidth(wc))>=0) {
       if (!escmore || wc>255 || !strchr(escmore, wc)) {
         if (width-columns<col) break;
@@ -1368,10 +1367,10 @@
   if (TT.drawn_row<0 || TT.cur_row<0 || TT.scr_row<0) redraw = 3;
   else if (abs(scroll)>TT.screen_height/2) redraw = 3;
 
-  xputsn("\e[H"); // jump to top left
-  if (redraw&2) xputsn("\e[2J\e[H");   //clear screen
-  else if (scroll>0) printf("\e[%dL", scroll);  //scroll up
-  else if (scroll<0) printf("\e[%dM", -scroll); //scroll down
+  tty_jump(0, 0);
+  if (redraw&2) tty_esc("2J"), tty_esc("H");   //clear screen
+  else if (scroll>0) printf("\033[%dL", scroll);  //scroll up
+  else if (scroll<0) printf("\033[%dM", -scroll); //scroll down
 
   SOL = text_sol(TT.cursor);
   bytes = text_getline(toybuf, SOL, ARRAY_LEN(toybuf));
@@ -1388,7 +1387,8 @@
   end = line;
 
 
-  printf("\e[%u;0H\e[2K", y+1);
+  tty_jump(0, y);
+  tty_esc("2K");
   //find cursor position
   aw = crunch_nstr(&end, INT_MAX, bytes, 0, "\t\n", vi_crunch);
 
@@ -1453,14 +1453,14 @@
       scroll++, draw_line++;
     else if (scroll>0) scroll--, draw_line++;
 
-    printf("\e[%u;0H", y+1);
+    tty_jump(0, y);
     if (draw_line) {
-      printf("\e[2K");
+      tty_esc("2K");
       if (line && strlen(line)) {
         aw = crunch_nstr(&line, clip, bytes, 0, "\t\n", vi_crunch);
         crunch_str(&line, TT.screen_width-1, stdout, "\t\n", vi_crunch);
         if ( *line ) printf("@");
-      } else printf("\e[2m~\e[m");
+      } else printf("\033[2m~\033[m");
     }
     if (SSOL+bytes < TT.filesize)  {
       line = toybuf;
@@ -1472,8 +1472,9 @@
   TT.drawn_row = TT.scr_row, TT.drawn_col = clip;
 
   // Finished updating visual area, show status line.
-  printf("\e[%u;0H\e[2K", TT.screen_height+1);
-  if (TT.vi_mode == 2) printf("\e[1m-- INSERT --\e[m");
+  tty_jump(0, TT.screen_height);
+  tty_esc("2K");
+  if (TT.vi_mode == 2) printf("\033[1m-- INSERT --\033[m");
   if (!TT.vi_mode) {
     cx_scr = printf("%s", TT.il->data);
     cy_scr = TT.screen_height;
@@ -1482,12 +1483,13 @@
     // TODO: the row,col display doesn't show the cursor column
     // TODO: real vi shows the percentage by lines, not bytes
     sprintf(toybuf, "%zu/%zuC  %zu%%  %d,%d", TT.cursor, TT.filesize,
-      (100*TT.cursor)/(TT.filesize ? : 1), TT.cur_row+1, TT.cur_col+1);
+      (100*TT.cursor)/TT.filesize, TT.cur_row+1, TT.cur_col+1);
     if (TT.cur_col != cx_scr) sprintf(toybuf+strlen(toybuf),"-%d", cx_scr+1);
   }
-  printf("\e[%u;%uH%s\e[%u;%uH", TT.screen_height+1,
-    (int) (1+TT.screen_width-strlen(toybuf)),
-    toybuf, cy_scr+1, cx_scr+1);
+  tty_jump(TT.screen_width-strlen(toybuf), TT.screen_height);
+  printf("%s", toybuf);
+
+  tty_jump(cx_scr, cy_scr);
   xflush(1);
 }
 
@@ -1507,11 +1509,12 @@
   TT.il->alloc = 80, TT.yank.alloc = 128;
 
   linelist_load(0);
+  TT.screen = TT.cursor = 0;
 
   TT.vi_mov_flag = 0x20000000;
   TT.vi_mode = 1, TT.tabstop = 8;
-
   TT.screen_width = 80, TT.screen_height = 24;
+
   terminal_size(&TT.screen_width, &TT.screen_height);
   TT.screen_height -= 1;
 
@@ -1522,7 +1525,7 @@
   set_terminal(0, 1, 0, 0);
   //writes stdout into different xterm buffer so when we exit
   //we dont get scroll log full of junk
-  xputsn("\e[?1049h");
+  tty_esc("?1049h");
 
   for (;;) {
     int key = 0;
@@ -1693,5 +1696,5 @@
   linelist_unload();
   free(TT.il->data), free(TT.il), free(TT.yank.data);
   tty_reset();
-  xputsn("\e[?1049l");
+  tty_esc("?1049l");
 }
diff --git a/toys/pending/wget.c b/toys/pending/wget.c
index 9e100e8..5c85889 100644
--- a/toys/pending/wget.c
+++ b/toys/pending/wget.c
@@ -1,350 +1,226 @@
-/* wget.c - Simple downloader to get the resource file from a HTTP server
+/* wget.c - Simple downloader to get the resource file in HTTP server
  *
  * Copyright 2016 Lipi C.H. Lee <lipisoft@gmail.com>
- * Copyright 2021 Eric Molitor <eric@molitor.org>
  *
- * Relevant sources of information
- * -------------------------------
- * HTTP 1.1: https://www.rfc-editor.org/rfc/rfc7230
- * Chunked Encoding: https://www.rfc-editor.org/rfc/rfc7230#section-4.1
- * UTF-8 Encoded Header Values https://www.rfc-editor.org/rfc/rfc5987
- *
- * Test URLs
- * ---------
- * Chunked Encoding: https://jigsaw.w3.org/HTTP/ChunkedScript
- * Redirect 301: https://jigsaw.w3.org/HTTP/300/301.html
- * Redirect 302: https://jigsaw.w3.org/HTTP/300/302.html
- * TLS 1.0: https://tls-v1-0.badssl.com:1010/
- * TLS 1.1: https://tls-v1-1.badssl.com:1011/
- * TLS 1.2: https://tls-v1-2.badssl.com:1012/
- * TLS 1.3: https://tls13.1d.pw/
- * Transfer Encoding [gzip|deflate]: https://jigsaw.w3.org/HTTP/TE/bar.txt
- *
- *
- * todo: Add support for configurable TLS versions
- * todo: Add support for ftp
- * todo: Add support for Transfer Encoding (gzip|deflate)
- * todo: Add support for RFC5987
 
-USE_WGET(NEWTOY(wget, "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):", TOYFLAG_USR|TOYFLAG_BIN))
+USE_WGET(NEWTOY(wget, "(no-check-certificate)O:", TOYFLAG_USR|TOYFLAG_BIN))
 
 config WGET
   bool "wget"
   default n
   help
-    usage: wget [OPTIONS]... [URL]
-        --max-redirect          maximum redirections allowed
-    -d, --debug                 print lots of debugging information
-    -O, --output-document=FILE  specify output filename
-    -p, --post-data=DATA        send data in body of POST request
+    usage: wget -O filename URL
+    -O filename: specify output filename
+    URL: uniform resource location, FTP/HTTP only, not HTTPS
 
     examples:
-      wget http://www.example.com
-
-config WGET_LIBTLS
-  bool "Enable HTTPS support for wget via LibTLS"
-  default n
-  depends on WGET && !WGET_OPENSSL
-  help
-    Enable HTTPS support for wget by linking to LibTLS.
-    Supports using libtls, libretls or libtls-bearssl.
-
-config WGET_OPENSSL
-  bool "Enable HTTPS support for wget via OpenSSL"
-  default n
-  depends on WGET && !WGET_LIBTLS
-  help
-    Enable HTTPS support for wget by linking to OpenSSL.
+      wget -O index.html http://www.example.com
+      wget -O sample.jpg ftp://ftp.example.com:21/sample.jpg
 */
 
 #define FOR_wget
 #include "toys.h"
 
-#if CFG_WGET_LIBTLS
-#define WGET_SSL 1
-#include <tls.h>
-#elif CFG_WGET_OPENSSL
-#define WGET_SSL 1
-#include <openssl/crypto.h>
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#else
-#define WGET_SSL 0
-#endif
-#define HTTPS (WGET_SSL && TT.https)
-
-
 GLOBALS(
-  char *p, *O;
-  long max_redirect;
-
-  int sock, https;
-  char *url;
-#if CFG_WGET_LIBTLS
-  struct tls *tls;
-#elif CFG_WGET_OPENSSL
-  struct ssl_ctx_st *ctx;
-  struct ssl_st *ssl;
-#endif
+  char *filename;
 )
 
-// get http info in URL
-static void wget_info(char *url, char **host, char **port, char **path)
-{
-  char *ss = url;
+// extract hostname and port from url
+static unsigned get_hn(const char *url, char *hostname) {
+  unsigned i;
 
-  // Must start with case insensitive http:// or https://
-  if (strncmp(url, "http", 4)) url = 0;
-  else {
-    url += 4;
-    if ((TT.https = WGET_SSL && toupper(*url=='s'))) url++;
-    if (!strstart(&url, "://")) url = 0;
+  for (i = 0; url[i] != '\0' && url[i] != '/'; i++) {
+    if(i >= 1024) error_exit("too long hostname in URL");
+    hostname[i] = url[i];
   }
-  if (!url) error_exit("unsupported protocol: %s", ss);
+  hostname[i] = '\0';
 
-  if ((*path = strchr(*host = url, '/'))) *((*path)++) = 0;
-  else *path = "";
-
-  // Get port number and trim literal IPv6 addresses
-  if (**host=='[' && (ss = strchr(++*host, ']'))) {
-    *ss++ = 0;
-    *port = (*ss==':') ? ++ss : 0;
-  } else if ((*port = strchr(*host, ':'))) *(*port++) = 0;
-  if (!*port) *port = HTTPS ? "443" : "80";
+  return i;
 }
 
-static void wget_connect(char *host, char *port)
-{
-  if (!HTTPS)
-    TT.sock = xconnectany(xgetaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, 0));
-  else {
-#if CFG_WGET_LIBTLS
-    struct tls_config *cfg = NULL;
-    uint32_t protocols;
-    if (!(TT.tls = tls_client()))
-      error_exit("tls_client: %s", tls_error(TT.tls));
-    if (!(cfg = tls_config_new()))
-      error_exit("tls_config_new: %s", tls_config_error(cfg));
-    if (tls_config_parse_protocols(&protocols, "tlsv1.2"))
-      error_exit("tls_config_parse_protocols");
-    if (tls_config_set_protocols(cfg, protocols))
-      error_exit("tls_config_set_protocols: %s", tls_config_error(cfg));
-    if (tls_configure(TT.tls, cfg))
-      error_exit("tls_configure: %s", tls_error(TT.tls));
-    tls_config_free(cfg);
+// extract port number
+static unsigned get_port(const char *url, char *port, unsigned url_i) {
+  unsigned i;
+  for (i = 0; url[i] != '\0' && url[i] != '/'; i++, url_i++) {
+    if('0' <= url[i] && url[i] <= '9') port[i] = url[i];
+    else error_exit("wrong decimal port number");
+  }
+  if(i <= 6) port[i] = '\0';
+  else error_exit("too long port number");
 
-    if (tls_connect(TT.tls, host, port))
-      error_exit("tls_connect: %s", tls_error(TT.tls));
-#elif CFG_WGET_OPENSSL
-    SSL_library_init();
-    OpenSSL_add_all_algorithms();
-    SSL_load_error_strings();
-    ERR_load_crypto_strings();
+  return url_i;
+}
 
-    TT.ctx = SSL_CTX_new(TLS_client_method());
-    if (!TT.ctx) error_exit("SSL_CTX_new");
-
-    TT.sock = xconnectany(xgetaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, 0));
-
-    TT.ssl = SSL_new(TT.ctx);
-    if (!TT.ssl)
-      error_exit("SSL_new: %s", ERR_error_string(ERR_get_error(), NULL));
-
-    if (!SSL_set_tlsext_host_name(TT.ssl, host))
-      error_exit("SSL_set_tlsext_host_name: %s",
-                 ERR_error_string(ERR_get_error(), NULL));
-
-    SSL_set_fd(TT.ssl, TT.sock);
-    if (SSL_connect(TT.ssl) == -1)
-      error_exit("SSL_set_fd: %s", ERR_error_string(ERR_get_error(), NULL));
-
-    if (FLAG(d)) printf("TLS: %s\n", SSL_get_cipher(TT.ssl));
-#endif
+static void strip_v6_brackets(char* hostname) {
+  size_t len = strlen(hostname);
+  if (len > 1023) {
+    error_exit("hostname too long, %d bytes\n", len);
+  }
+  char * closing_bracket = strchr(hostname, ']');
+  if (closing_bracket && closing_bracket == hostname + len - 1) {
+    if (strchr(hostname, '[') == hostname) {
+      hostname[len-1] = 0;
+      memmove(hostname, hostname + 1, len - 1);
+    }
   }
 }
 
-static size_t wget_read(void *buf, size_t len)
-{
-  if (!HTTPS) return xread(TT.sock, buf, len);
-  else {
-    char *err = 0;
-    int ret;
+// get http infos in URL
+static void get_info(const char *url, char* hostname, char *port, char *path) {
+  unsigned i = 7, len;
+  char ftp = !strncmp(url, "ftp://", 6);
 
-#if CFG_WGET_LIBTLS
-    if ((ret = tls_read(TT.tls, buf, len))<0) err = tls_error(TT.tls);
-#elif CFG_WGET_OPENSSL
-    if ((ret = SSL_read(TT.ssl, buf, len))<0)
-      err = ERR_error_string(ERR_get_error(), 0);
-#endif
-    if (err) error_exit("https read: %s", err);
+  if (ftp) i--;
+  else if (strncmp(url, "http://", i)) error_exit("only FTP/HTTP support");
+  len = get_hn(url+i, hostname);
+  i += len;
 
-    return ret;
+  // `hostname` now contains `host:port`, where host can be any of: a raw IPv4
+  // address; a bracketed, raw IPv6 address, or a hostname. Extract port, if it exists,
+  // by searching for the last ':' in the hostname string.
+  char *port_delim = strrchr(hostname, ':');
+  char use_default_port = 1;
+  if (port_delim) {
+    // Found a colon; is there a closing bracket after it? If so,
+    // then this colon was in the middle of a bracketed IPv6 address
+    if (!strchr(port_delim, ']')) {
+      // No closing bracket; this is a real port
+      use_default_port = 0;
+      get_port(port_delim + 1, port, 0);
+
+      // Mark the new end of the hostname string
+      *port_delim = 0;
+    }
   }
+
+  if (use_default_port) {
+    strcpy(port, "80");
+  }
+
+  // This is a NOP if hostname is not a bracketed IPv6 address
+  strip_v6_brackets(hostname);
+
+  // get uri in URL
+  if (url[i] == '\0') strcpy(path, "/");
+  else if (url[i] == '/') {
+    if (strlen(url+i) < 1024) strcpy(path, url+i);
+    else error_exit("too long path in URL");
+  } else error_exit("wrong URL");
+
+  if (ftp) xexec((char *[]){"ftpget", hostname, TT.filename, path, 0});
 }
 
-static void wget_write(void *buf, size_t len)
-{
-  if (!HTTPS) xwrite(TT.sock, buf, len);
-  else {
-    char *err = 0;
+// connect to any IPv4 or IPv6 server
+static int conn_svr(const char *hostname, const char *port) {
+  struct addrinfo hints, *result, *rp;
+  int sock;
 
-#if CFG_WGET_LIBTLS
-    if (len != tls_write(TT.tls, buf, len)) err = tls_error(TT.tls);
-#elif CFG_WGET_OPENSSL
-    if (len != SSL_write(TT.ssl, buf, len))
-      err = ERR_error_string(ERR_get_error(), 0);
-#endif
-    if (err) error_exit("https write: %s", err);
+  memset(&hints, 0, sizeof(struct addrinfo));
+  hints.ai_family = AF_UNSPEC;
+  hints.ai_socktype = SOCK_STREAM;
+  hints.ai_flags = 0;
+  hints.ai_protocol = 0;
+
+  if ((errno = getaddrinfo(hostname, port, &hints, &result)))
+    error_exit("getaddrinfo: %s", gai_strerror(errno));
+
+  // try all address list(IPv4 or IPv6) until success
+  for (rp = result; rp; rp = rp->ai_next) {
+    if ((sock = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol))
+        == -1) {
+      perror_msg("socket error");
+      continue;
+    }
+    if (connect(sock, rp->ai_addr, rp->ai_addrlen) != -1)
+      break; // succeed in connecting to any server IP
+    else perror_msg("connect error");
+    close(sock);
   }
+  freeaddrinfo(result);
+  if(!rp) error_exit("can't connect");
+
+  return sock;
 }
 
-static void wget_close()
-{
-  if (TT.sock) {
-      xclose(TT.sock);
-      TT.sock = 0;
-  }
-
-#if CFG_WGET_LIBTLS
-  if (TT.tls) {
-    tls_close(TT.tls);
-    tls_free(TT.tls);
-    TT.tls = 0;
-  }
-#elif CFG_WGET_OPENSSL
-  if (TT.ssl) {
-    SSL_shutdown(TT.ssl);
-    SSL_free(TT.ssl);
-    TT.ssl = 0;
-  }
-
-  if (TT.ctx) {
-    SSL_CTX_free(TT.ctx);
-    TT.ctx = 0;
-  }
-#endif
+// make HTTP request header field
+static void mk_fld(char *name, char *value) {
+  strcat(toybuf, name);
+  strcat(toybuf, ": ");
+  strcat(toybuf, value);
+  strcat(toybuf, "\r\n");
 }
 
-static char *wget_find_header(char *header, char *val)
-{
-  char *result = strcasestr(header, val);
+// get http response body starting address and its length
+static char *get_body(ssize_t len, ssize_t *body_len) {
+  int i;
 
-  if (result) {
-    result += strlen(val);
-    result[strcspn(result, "\r\n")] = 0;
-  }
+  for (i = 0; i < len-4; i++)
+    if (!strncmp(toybuf+i, "\r\n\r\n", 4)) break;
 
-  return result;
+  *body_len = len - i - 4;
+  return toybuf+i+4;
 }
 
 void wget_main(void)
 {
-  long status = 0;
-  size_t len, c_len = 0;
-  int fd = 0;
-  char *body, *index, *host, *port, *path, *chunked, *ss;
-  char agent[] = "toybox wget/" TOYBOX_VERSION;
+  int sock, redirects = 10;
+  FILE *fp;
+  ssize_t len, body_len;
+  char *body, *result, *rc, *r_str, *redir_loc = 0;
+  char ua[] = "toybox wget/" TOYBOX_VERSION, hostname[1024], port[6], path[1024];
 
-  TT.url = xstrdup(*toys.optargs);
+  // TODO extract filename to be saved from URL
+  if (!(toys.optflags & FLAG_O)) help_exit("no filename");
+  if (fopen(TT.filename, "r")) error_exit("'%s' already exists", TT.filename);
 
-  // Ask server for URL, following redirects until success
-  while (status != 200) {
-    if (!TT.max_redirect--) error_exit("Too many redirects");
+  if(!toys.optargs[0]) help_exit("no URL");
+  get_info(toys.optargs[0], hostname, port, path);
 
-    // Connect and write request
-    wget_info(TT.url, &host, &port, &path);
-    if (TT.p) sprintf(toybuf, "Content-Length: %ld\r\n", strlen(TT.p));
-    ss = xmprintf("%s /%s HTTP/1.1\r\nHost: %s\r\nUser-Agent: %s\r\n"
-                  "Connection: close\r\n%s\r\n%s", FLAG(p) ? "POST" : "GET",
-                  path, host, agent, FLAG(p) ? toybuf : "", FLAG(p)?TT.p:"");
-    if (FLAG(d)) printf("--- Request\n%s", ss);
-    wget_connect(host, port);
-    wget_write(ss, strlen(ss));
-    free(ss);
+  for (;; redirects--) {
+    sock = conn_svr(hostname, port);
+    // compose HTTP request
+    sprintf(toybuf, "GET %s HTTP/1.1\r\n", path);
+    mk_fld("Host", hostname);
+    mk_fld("User-Agent", ua);
+    mk_fld("Connection", "close");
+    strcat(toybuf, "\r\n");
 
-    // Read HTTP response into toybuf (probably with some body at end)
-    for (index = toybuf;
-      (len = wget_read(index, sizeof(toybuf)-(index-toybuf)))>0; index += len);
+    // send the HTTP request
+    len = strlen(toybuf);
+    if (write(sock, toybuf, len) != len) perror_exit("write error");
 
-    // Split response into header and body, and null terminate header.
-    // (RFC7230 says header cannot contain NUL.)
-    if (!(body = memmem(ss = toybuf, index-toybuf, "\r\n\r\n", 4)))
-      error_exit("response header too large");
-    *body = 0;
-    body += 4;
-    len = index-body;
-    if (FLAG(d)) printf("--- Response\n%s\n\n", toybuf);
+    // read HTTP response
+    if ((len = read(sock, toybuf, 4096)) == -1) perror_exit("read error");
+    if (!strstr(toybuf, "\r\n\r\n")) error_exit("too long HTTP response");
+    body = get_body(len, &body_len);
+    redir_loc = strstr(toybuf, "Location: ");
+    result = strtok(toybuf, "\r");
+    strtok(result, " ");
+    rc = strtok(NULL, " ");
+    r_str = strtok(NULL, " ");
 
-    status = strstart(&ss, "HTTP/1.1 ") ? strtol(ss, 0, 10) : 0;
-    if ((status == 301) || (status == 302)) {
-      if (!(ss = wget_find_header(toybuf, "Location: ")))
-        error_exit("bad redirect");
-      free(TT.url);
-      TT.url = xstrdup(ss);
-      wget_close();
-    } else if (status != 200) error_exit("response: %ld", status);
+    // HTTP res code check
+    if (!strcmp(rc, "301") || !strcmp(rc, "302")) {
+      char* eol = 0;
+      if ((eol = strchr(redir_loc, '\r')) > 0) *eol = 0;
+      else if (redir_loc) error_exit("Could not parse redirect URL");
+      if (redirects < 0) error_exit("Too many redirects");
+
+      printf("Redirection: %s %s \n", rc, r_str);
+      printf("%s \n", redir_loc);
+      redir_loc = redir_loc+strlen("Location: ");
+      close(sock);
+      get_info(redir_loc, hostname, port, path);
+    } else if (!strcmp(rc, "200")) break;
+    else error_exit("res: %s(%s)", rc, r_str);
   }
 
-  // Open output file
-  if (TT.O && !strcmp(TT.O, "-")) fd = 1;
-  else if (!TT.O) {
-    ss = wget_find_header(toybuf, "Content-Disposition: attachment; filename=");
-    if (!ss && strchr(path, '/')) ss = getbasename(path);
-    if (!ss || !*ss ) ss = "index.html";
-    if (!access((TT.O = ss), F_OK)) error_exit("%s already exists", TT.O);
-  }
-  // TODO: don't allow header/basename to write to stdout
-  if (!fd) fd = xcreate(TT.O, (O_WRONLY|O_CREAT|O_TRUNC), 0644);
 
-  // If chunked we offset the first buffer by 2 character, meaning it is
-  // pointing at half of the header boundary, aka '\r\n'. This simplifies
-  // parsing of the first c_len length by allowing the do while loop to fall
-  // through on the first iteration and parse the first c_len size.
-  chunked = wget_find_header(toybuf, "transfer-encoding: chunked");
-  if (chunked) memmove(toybuf, body-2, len += 2);
-  else memmove(toybuf, body, len);
-
-  // len is the size remaining in toybuf
-  // c_len is the size of the remaining bytes in the current chunk
-  do {
-    if (chunked) {
-      if (c_len > 0) { // We have an incomplete c_len to write
-        if (len <= c_len) { // Buffer is less than the c_len so full write
-          xwrite(fd, toybuf, len);
-          c_len = c_len - len;
-          len = 0;
-        } else { // Buffer is larger than the c_len so partial write
-          xwrite(fd, toybuf, c_len);
-          len = len - c_len;
-          memmove(toybuf, toybuf + c_len, len);
-          c_len = 0;
-        }
-      }
-
-      // If len is less than 2 we can't validate the chunk boundary so fall
-      // through and go read more into toybuf.
-      if (!c_len && (len > 2)) {
-        char *c;
-        if (strncmp(toybuf, "\r\n", 2) != 0) error_exit("chunk boundary");
-
-        // If we can't find the end of the new chunk signature fall through and
-        // read more into toybuf.
-        c = memmem(toybuf + 2, len - 2, "\r\n",2);
-        if (c) {
-          c_len = strtol(toybuf + 2, NULL, 16);
-          if (!c_len) break; // A c_len of zero means we are complete
-          len = len - (c - toybuf) - 2;
-          memmove(toybuf, c + 2, len);
-        }
-      }
-
-      if (len == sizeof(toybuf)) error_exit("chunk overflow");
-    } else {
-      xwrite(fd, toybuf, len);
-      len = 0;
-    }
-  } while ((len += wget_read(toybuf + len, sizeof(toybuf) - len)) > 0);
-
-  wget_close();
-  free(TT.url);
+  if (!(fp = fopen(TT.filename, "w"))) perror_exit("fopen error");
+  if (fwrite(body, 1, body_len, fp) != body_len)
+    error_exit("fwrite error");
+  while ((len = read(sock, toybuf, 4096)) > 0)
+    if (fwrite(toybuf, 1, len, fp) != len)
+      error_exit("fwrite error");
+  if (fclose(fp) == EOF) perror_exit("fclose error");
 }
diff --git a/toys/posix/cal.c b/toys/posix/cal.c
index 1d2b16a..33b15a1 100644
--- a/toys/posix/cal.c
+++ b/toys/posix/cal.c
@@ -4,19 +4,18 @@
  *
  * See http://opengroup.org/onlinepubs/9699919799/utilities/cal.html
 
-USE_CAL(NEWTOY(cal, ">3h", TOYFLAG_USR|TOYFLAG_BIN))
+USE_CAL(NEWTOY(cal, ">2h", TOYFLAG_USR|TOYFLAG_BIN))
 
 config CAL
   bool "cal"
   default y
   help
-    usage: cal [[[DAY] MONTH] YEAR]
+    usage: cal [[MONTH] YEAR]
 
     Print a calendar.
 
     With one argument, prints all months of the specified year.
     With two arguments, prints calendar for month and year.
-    With three arguments, highlights day within month and year.
 
     -h	Don't highlight today
 */
@@ -28,41 +27,36 @@
   struct tm *now;
 )
 
-// Thirty days hath september april june and november. February is just weird.
-static int monthlen(struct tm *tm)
-{
-  int len = 31, month = tm->tm_mon, year = tm->tm_year;
-
-  if (tm->tm_mon==1) {
-    len = 28;
-    if (!(year&3) && !((year%100) && !(year%400))) len++;
-  } else if ((month+(month>6))&1) len = 30;
-
-  return len;
-}
-
 // Write calendar into buffer: each line is 20 chars wide, end indicated
 // by empty string.
 
 static char *calstrings(char *buf, struct tm *tm)
 {
-  int wday, mday, start, len, line;
   char temp[21];
+  int wday, mday, start, len, line;
 
   // header
   len = strftime(temp, 21, "%B %Y", tm);
   len += (20-len)/2;
-  buf += sprintf(buf, "%*s%*s ", len, temp, 20-len, "")+1;
-  buf += sprintf(buf, "Su Mo Tu We Th Fr Sa ")+1;
+  buf += sprintf(buf, "%*s%*s ", len, temp, 20-len, "");
+  buf++;
+  buf += sprintf(buf, "Su Mo Tu We Th Fr Sa ");
+  buf++;
 
   // What day of the week does this month start on?
-  if (tm->tm_mday>1) start = (36+tm->tm_wday-tm->tm_mday)%7;
+  if (tm->tm_mday>1)
+    start = (36+tm->tm_wday-tm->tm_mday)%7;
   else start = tm->tm_wday;
 
   // What day does this month end on?  Alas, libc doesn't tell us...
-  len = monthlen(tm);
+  len = 31;
+  if (tm->tm_mon == 1) {
+    int year = tm->tm_year;
+    len = 28;
+    if (!(year & 3) && !((year&100) && !(year&400))) len++;
+  } else if ((tm->tm_mon+(tm->tm_mon>6 ? 1 : 0)) & 1) len = 30;
 
-  for (mday = line = 0; line<6; line++) {
+  for (mday=line=0;line<6;line++) {
     for (wday=0; wday<7; wday++) {
       char *pat = "   ";
       if (!mday ? wday==start : mday<len) {
@@ -100,15 +94,13 @@
     buf += sizeof(struct tm);
 
     // Last argument is year, one before that (if any) is month.
-    tm->tm_year = atolx_range(toys.optargs[--toys.optc], 1, 9999) - 1900;
+    tm->tm_year = atolx_range(toys.optargs[--toys.optc], 1, 9999);
+    tm->tm_year -= 1900;
     tm->tm_mday = 1;
     tm->tm_hour = 12;  // noon to avoid timezone weirdness
     if (toys.optc) {
-      tm->tm_mon = atolx_range(toys.optargs[--toys.optc], 1, 12)-1;
-      if (toys.optc) {
-        tm->tm_mday = atolx_range(toys.optargs[--toys.optc], 1, monthlen(tm));
-        TT.now = tm;
-      }
+      tm->tm_mon = atolx_range(toys.optargs[--toys.optc], 1, 12);
+      tm->tm_mon--;
 
     // Print 12 months of the year
 
diff --git a/toys/posix/cmp.c b/toys/posix/cmp.c
index 8e33c92..d1c73f1 100644
--- a/toys/posix/cmp.c
+++ b/toys/posix/cmp.c
@@ -4,19 +4,17 @@
  *
  * See http://opengroup.org/onlinepubs/9699919799/utilities/cmp.html
 
-USE_CMP(NEWTOY(cmp, "<1>4ls(silent)(quiet)n#<1[!ls]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
+USE_CMP(NEWTOY(cmp, "<1>2ls(silent)(quiet)[!ls]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)))
 
 config CMP
   bool "cmp"
   default y
   help
-    usage: cmp [-ls] [-n LEN] FILE1 [FILE2 [SKIP1 [SKIP2]]]
+    usage: cmp [-l] [-s] FILE1 [FILE2 [SKIP1 [SKIP2]]]
 
-    Compare the contents of files (vs stdin if only one given), optionally
-    skipping bytes at start.
+    Compare the contents of two files. (Or stdin and file if only one given.)
 
     -l	Show all differing bytes
-    -n LEN	Compare at most LEN bytes
     -s	Silent
 */
 
@@ -24,22 +22,16 @@
 #include "toys.h"
 
 GLOBALS(
-  long n;
-
   int fd;
   char *name;
 )
 
-// We hijack loopfiles() to open and understand the "-" filename for us.
 static void do_cmp(int fd, char *name)
 {
   int i, len1, len2, min_len, size = sizeof(toybuf)/2;
   long byte_no = 1, line_no = 1;
   char *buf2 = toybuf+size;
 
-  if (toys.optc>(i = 2+!!TT.fd) && lskip(fd, atolx(toys.optargs[i])))
-    error_exit("EOF on %s", name);
-
   // First time through, cache the data and return.
   if (!TT.fd) {
     TT.name = name;
@@ -51,17 +43,19 @@
 
   toys.exitval = 0;
 
-  for (;!FLAG(n) || TT.n;) {
-    if (FLAG(n)) TT.n -= size = minof(size, TT.n);
+  for (;;) {
     len1 = readall(TT.fd, toybuf, size);
     len2 = readall(fd, buf2, size);
-    min_len = minof(len1, len2);
+
+    min_len = len1 < len2 ? len1 : len2;
     for (i=0; i<min_len; i++) {
       if (toybuf[i] != buf2[i]) {
         toys.exitval = 1;
-        if (FLAG(l)) printf("%ld %o %o\n", byte_no, toybuf[i], buf2[i]);
+        if (toys.optflags & FLAG_l)
+          printf("%ld %o %o\n", byte_no, toybuf[i], buf2[i]);
         else {
-          if (!FLAG(s)) printf("%s %s differ: char %ld, line %ld\n",
+          if (!(toys.optflags & FLAG_s)) 
+            printf("%s %s differ: char %ld, line %ld\n",
               TT.name, name, byte_no, line_no);
           goto out;
         }
@@ -70,20 +64,21 @@
       if (toybuf[i] == '\n') line_no++;
     }
     if (len1 != len2) {
-      if (!FLAG(s)) error_msg("EOF on %s", len1 < len2 ? TT.name : name);
-      else toys.exitval = 1;
+      if (!(toys.optflags & FLAG_s))
+        fprintf(stderr, "cmp: EOF on %s\n", len1 < len2 ? TT.name : name);
+      toys.exitval = 1;
       break;
     }
     if (len1 < 1) break;
   }
 out:
   if (CFG_TOYBOX_FREE) close(TT.fd);
-  xexit();
 }
 
 void cmp_main(void)
 {
   toys.exitval = 2;
-  loopfiles_rw(toys.optargs, O_CLOEXEC|(WARN_ONLY*!FLAG(s)), 0, do_cmp);
+  loopfiles_rw(toys.optargs, O_CLOEXEC|(WARN_ONLY*!(toys.optflags&FLAG_s)), 0,
+    do_cmp);
   if (toys.optc == 1) do_cmp(0, "-");
 }
diff --git a/toys/posix/comm.c b/toys/posix/comm.c
index 2d118b7..c5c8f85 100644
--- a/toys/posix/comm.c
+++ b/toys/posix/comm.c
@@ -27,29 +27,29 @@
 
 static void writeline(const char *line, int col)
 {
-  if (!col && FLAG(1)) return;
+  if (col == 0 && toys.optflags & FLAG_1) return;
   else if (col == 1) {
-    if (FLAG(2)) return;
-    if (!FLAG(1)) putchar('\t');
+    if (toys.optflags & FLAG_2) return;
+    if (!(toys.optflags & FLAG_1)) putchar('\t');
   } else if (col == 2) {
-    if (FLAG(3)) return;
-    if (!FLAG(1)) putchar('\t');
-    if (!FLAG(2)) putchar('\t');
+    if (toys.optflags & FLAG_3) return;
+    if (!(toys.optflags & FLAG_1)) putchar('\t');
+    if (!(toys.optflags & FLAG_2)) putchar('\t');
   }
   puts(line);
 }
 
 void comm_main(void)
 {
-  FILE *file[2];
+  int file[2];
   char *line[2];
   int i;
 
   if (toys.optflags == 7) return;
 
   for (i = 0; i < 2; i++) {
-    file[i] = xfopen(toys.optargs[i], "r");
-    line[i] = xgetline(file[i]);
+    file[i] = xopenro(toys.optargs[i]);
+    line[i] = get_line(file[i]);
   }
 
   while (line[0] && line[1]) {
@@ -59,22 +59,22 @@
       writeline(line[0], 2);
       for (i = 0; i < 2; i++) {
         free(line[i]);
-        line[i] = xgetline(file[i]);
+        line[i] = get_line(file[i]);
       }
     } else {
       i = order < 0 ? 0 : 1;
       writeline(line[i], i);
       free(line[i]);
-      line[i] = xgetline(file[i]);
+      line[i] = get_line(file[i]);
     }
   }
 
-  // Print rest of the longer file.
+  /* print rest of the longer file */
   for (i = line[0] ? 0 : 1; line[i];) {
     writeline(line[i], i);
     free(line[i]);
-    line[i] = xgetline(file[i]);
+    line[i] = get_line(file[i]);
   }
 
-  if (CFG_TOYBOX_FREE) for (i = 0; i < 2; i++) fclose(file[i]);
+  if (CFG_TOYBOX_FREE) for (i = 0; i < 2; i++) xclose(file[i]);
 }
diff --git a/toys/posix/cp.c b/toys/posix/cp.c
index 7b9889a..8eaecc9 100644
--- a/toys/posix/cp.c
+++ b/toys/posix/cp.c
@@ -15,7 +15,7 @@
 // options shared between mv/cp must be in same order (right to left)
 // for FLAG macros to work out right in shared infrastructure.
 
-USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu][+Rr]", TOYFLAG_BIN))
+USE_CP(NEWTOY(cp, "<1(preserve):;D(parents)RHLPprudaslvnF(remove-destination)fit:T[-HLPd][-niu]", TOYFLAG_BIN))
 USE_MV(NEWTOY(mv, "<1vnF(remove-destination)fit:T[-ni]", TOYFLAG_BIN))
 USE_INSTALL(NEWTOY(install, "<1cdDpsvt:m:o:g:", TOYFLAG_USR|TOYFLAG_BIN))
 
@@ -124,10 +124,9 @@
 static int cp_node(struct dirtree *try)
 {
   int fdout = -1, cfd = try->parent ? try->parent->extra : AT_FDCWD,
-      save = DIRTREE_SAVE*(CFG_MV && toys.which->name[0] == 'm'), rc = 0,
       tfd = dirtree_parentfd(try);
   unsigned flags = toys.optflags;
-  char *s = 0, *catch = try->parent ? try->name : TT.destname, *err = "%s";
+  char *catch = try->parent ? try->name : TT.destname, *err = "%s";
   struct stat cst;
 
   if (!dirtree_notdotdot(try)) return 0;
@@ -136,13 +135,8 @@
   if (S_ISDIR(try->st.st_mode) && try->again) {
     fdout = try->extra;
     err = 0;
-
-    // If mv child had a problem, free data and don't try to delete parent dir.
-    if (try->child) {
-      save = 0;
-      llist_traverse(try->child, free);
-    }
   } else {
+
     // -d is only the same as -r for symlinks, not for directories
     if (S_ISLNK(try->st.st_mode) && (flags & FLAG_d)) flags |= FLAG_r;
 
@@ -156,27 +150,35 @@
       error_msg("'%s' is '%s'", catch, err = dirtree_path(try, 0));
       free(err);
 
-      return save;
+      return 0;
     }
 
     // Handle -inuvF
+
     if (!faccessat(cfd, catch, F_OK, 0) && !S_ISDIR(cst.st_mode)) {
-      if (S_ISDIR(try->st.st_mode))
+      char *s;
+
+      if (S_ISDIR(try->st.st_mode)) {
         error_msg("dir at '%s'", s = dirtree_path(try, 0));
-      else if ((flags & FLAG_F) && unlinkat(cfd, catch, 0))
+        free(s);
+        return 0;
+      } else if ((flags & FLAG_F) && unlinkat(cfd, catch, 0)) {
         error_msg("unlink '%s'", catch);
+        return 0;
+      } else if (flags & FLAG_n) return 0;
+      else if ((flags & FLAG_u) && nanodiff(&try->st.st_mtim, &cst.st_mtim)>0)
+        return 0;
       else if (flags & FLAG_i) {
         fprintf(stderr, "%s: overwrite '%s'", toys.which->name,
           s = dirtree_path(try, 0));
-        if (yesno(0)) rc++;
-      } else if (!((flags&FLAG_u) && nanodiff(&try->st.st_mtim, &cst.st_mtim)>0)
-                 && !(flags & FLAG_n)) rc++;
-      free(s);
-      if (!rc) return save;
+        free(s);
+        if (!yesno(0)) return 0;
+      }
     }
 
     if (flags & FLAG_v) {
-      printf("%s '%s'\n", toys.which->name, s = dirtree_path(try, 0));
+      char *s = dirtree_path(try, 0);
+      printf("%s '%s'\n", toys.which->name, s);
       free(s);
     }
 
@@ -190,7 +192,7 @@
       if (S_ISDIR(try->st.st_mode)) {
         struct stat st2;
 
-        if (!(flags & (FLAG_a|FLAG_r))) {
+        if (!(flags & (FLAG_a|FLAG_r|FLAG_R))) {
           err = "Skipped dir '%s'";
           catch = try->name;
           break;
@@ -244,11 +246,13 @@
       } else if (!S_ISREG(try->st.st_mode)
                  && (try->parent || (flags & (FLAG_a|FLAG_P|FLAG_r))))
       {
+        int i;
+
         // make symlink, or make block/char/fifo/socket
         if (S_ISLNK(try->st.st_mode)
-            ? readlinkat0(tfd, try->name, toybuf, sizeof(toybuf)) &&
-              (!unlinkat(cfd, catch, 0) || ENOENT == errno) &&
-              !symlinkat(toybuf, cfd, catch)
+            ? ((i = readlinkat0(tfd, try->name, toybuf, sizeof(toybuf))) &&
+               ((!unlinkat(cfd, catch, 0) || ENOENT == errno) &&
+                !symlinkat(toybuf, cfd, catch)))
             : !mknodat(cfd, catch, try->st.st_mode, try->st.st_rdev))
         {
           err = 0;
@@ -257,7 +261,7 @@
 
       // Copy contents of file.
       } else {
-        int fdin, ii;
+        int fdin;
 
         fdin = openat(tfd, try->name, O_RDONLY);
         if (fdin < 0) {
@@ -282,9 +286,8 @@
             xattr_flist(fdin, list, listlen);
             list[listlen-1] = 0; // I do not trust this API.
             for (name = list; name-list < listlen; name += strlen(name)+1) {
-              // context copies security, xattr copies everything else
-              ii = strncmp(name, "security.", 9) ? _CP_xattr : _CP_context;
-              if (!(TT.pflags&ii)) continue;
+              if (!(TT.pflags&_CP_xattr) && strncmp(name, "security.", 9))
+                continue;
               if ((len = xattr_fget(fdin, name, 0, 0))>0) {
                 value = xmalloc(len);
                 if (len == xattr_fget(fdin, name, value, len))
@@ -304,6 +307,8 @@
 
   // Did we make a thing?
   if (fdout != -1) {
+    int rc;
+
     // Inability to set --preserve isn't fatal, some require root access.
 
     // ownership
@@ -337,21 +342,23 @@
       xclose(fdout);
     }
 
-    if (save)
+    if (CFG_MV && toys.which->name[0] == 'm')
       if (unlinkat(tfd, try->name, S_ISDIR(try->st.st_mode) ? AT_REMOVEDIR :0))
         err = "%s";
   }
 
   if (err) {
+    char *f = 0;
+
     if (catch == try->name) {
-      s = dirtree_path(try, 0);
+      f = dirtree_path(try, 0);
       while (try->parent) try = try->parent;
-      catch = xmprintf("%s%s", TT.destname, s+strlen(try->name));
-      free(s);
-      s = catch;
-    } else s = 0;
+      catch = xmprintf("%s%s", TT.destname, f+strlen(try->name));
+      free(f);
+      f = catch;
+    }
     perror_msg(err, catch);
-    free(s);
+    free(f);
   }
   return 0;
 }
@@ -465,7 +472,7 @@
 
 void mv_main(void)
 {
-  toys.optflags |= FLAG_d|FLAG_p|FLAG_r;
+  toys.optflags |= FLAG_d|FLAG_p|FLAG_R;
 
   cp_main();
 }
@@ -477,6 +484,7 @@
 static inline int cp_flag_v(void) { return FLAG_v; };
 
 // Switch to install's flag context
+#define CLEANUP_cp
 #define FOR_install
 #include <generated/flags.h>
 
diff --git a/toys/posix/cpio.c b/toys/posix/cpio.c
index 5ecd56d..35b74b3 100644
--- a/toys/posix/cpio.c
+++ b/toys/posix/cpio.c
@@ -16,7 +16,7 @@
  *
  * todo: export/import linux file list text format ala gen_initramfs_list.sh
 
-USE_CPIO(NEWTOY(cpio, "(ignore-devno)(renumber-inodes)(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
+USE_CPIO(NEWTOY(cpio, "(quiet)(no-preserve-owner)md(make-directories)uH:p|i|t|F:v(verbose)o|[!pio][!pot][!pF]", TOYFLAG_BIN))
 
 config CPIO
   bool "cpio"
@@ -243,7 +243,6 @@
   } else {
     char *name = 0;
     size_t size = 0;
-    unsigned inode = 0;
 
     for (;;) {
       struct stat st;
@@ -270,8 +269,6 @@
       if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode)) st.st_size = 0;
       if (st.st_size >> 32) perror_msg("skipping >2G file '%s'", name);
       else {
-        if (FLAG(renumber_inodes)) st.st_ino = ++inode;
-        if (FLAG(ignore_devno)) st.st_rdev = 0;
         llen = sprintf(toybuf,
           "070701%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
           (int)st.st_ino, st.st_mode, st.st_uid, st.st_gid, (int)st.st_nlink,
diff --git a/toys/posix/cut.c b/toys/posix/cut.c
index c4f34f9..61b2b40 100644
--- a/toys/posix/cut.c
+++ b/toys/posix/cut.c
@@ -10,13 +10,13 @@
  *
  * todo: -n, -s with -c
 
-USE_CUT(NEWTOY(cut, "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbfF]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_CUT(NEWTOY(cut, "b*|c*|f*|F*|C*|O(output-delimiter):d:sDn[!cbf]", TOYFLAG_USR|TOYFLAG_BIN))
 
 config CUT
   bool "cut"
   default y
   help
-    usage: cut [-Ds] [-bcCfF LIST] [-dO DELIM] [FILE...]
+    usage: cut [-Ds] [-bcfF LIST] [-dO DELIM] [FILE...]
 
     Print selected parts of lines from each FILE to standard output.
 
@@ -42,36 +42,26 @@
   char *d, *O;
   struct arg_list *select[5]; // we treat them the same, so loop through
 
-  unsigned line;
   int pairs;
   regex_t reg;
 )
 
+
 // Apply selections to an input line, producing output
 static void cut_line(char **pline, long len)
 {
-  unsigned *pairs = (void *)toybuf, wc;
+  unsigned *pairs = (void *)toybuf;
   char *line;
-  int i, j, k;
+  int i, j;
 
   if (!pline) return;
   line = *pline;
   if (len && line[len-1]=='\n') line[--len] = 0;
-  TT.line++;
 
   // Loop through selections
   for (i=0; i<TT.pairs; i++) {
     unsigned start = pairs[2*i], end = pairs[(2*i)+1], count;
-    char *s = line, *ss, *sss;
-
-    // when the delimiter is \n output lines.
-    if (*TT.d == '\n') {
-      if (TT.line<start || TT.line>end) {
-        if (i+1 == TT.pairs) return;
-        continue;
-      }
-      goto write_line;
-    }
+    char *s = line, *ss;
 
     // input: start/end position, count=difference between them
     // output: s = start of string, len = bytes to output
@@ -82,20 +72,8 @@
     count = end-start;
 
     // Find start and end of output string for the relevant selection type
-    if (FLAG(b)) {
-      if (!FLAG(n)) s += start;
-      else {
-        if (end>len) end = len;
-        for (sss = ss = s; (k = (ss-line))<end;) {
-          if (0>(j = utf8towc(&wc, ss, len))) ss++;
-          else {
-            if (((ss += j)-line)<=end) sss = ss;
-            if ((ss-line)<=start) s = ss;
-          }
-        }
-        if (!(count = sss-s)) continue;
-      }
-    } else if (FLAG(C)) {
+    if (toys.optflags&FLAG_b) s += start;
+    else if (toys.optflags&FLAG_C) {
       // crunch_str() currently assumes that combining characters get
       // escaped, to provide an unambiguous visual representation.
       // This assumes the input string is null terminated.
@@ -106,7 +84,9 @@
       crunch_str(&ss, count, 0, 0, 0);
       count = ss-s;
 
-    } else if (FLAG(c)) {
+    } else if (toys.optflags&FLAG_c) {
+      wchar_t wc;
+      char *sss;
 
       // Find start
       ss = line+len;
@@ -133,7 +113,7 @@
         if (j) start = count;
         else end = start;
         while (*ss && start) {
-          if (FLAG(f)) {
+          if (toys.optflags&FLAG_f) {
             if (!strchr(TT.d, *ss++)) continue;
             if (!--start && j) ss--;
           } else {
@@ -150,9 +130,8 @@
 
       // If we never encountered even one separator, print whole line (posix!)
       if (!j && end == start) {
-        if (FLAG(D)) break;
-        if (FLAG(s)) return;
-write_line:
+        if (toys.optflags&FLAG_D) break;
+        if (toys.optflags&FLAG_s) return;
         fwrite(line, len, 1, stdout);
         break;
       } else if (!*s) continue;
@@ -213,11 +192,11 @@
     error_exit("-s needs -Ff");
   if ((toys.optflags&(FLAG_d|FLAG_f|FLAG_F))==FLAG_d)
     error_exit("-d needs -Ff");
-  if (!TT.d) TT.d = (FLAG(F)) ? "[[:space:]][[:space:]]*" : "\t";
-  if (FLAG(F)) xregcomp(&TT.reg, TT.d, REG_EXTENDED);
+  if (!TT.d) TT.d = (toys.optflags&FLAG_F) ? "[[:space:]][[:space:]]*" : "\t";
+  if (toys.optflags&FLAG_F) xregcomp(&TT.reg, TT.d, REG_EXTENDED);
   if (!TT.O) {
-    if (FLAG(F)) TT.O = " ";
-    else if (FLAG(f)) TT.O = TT.d;
+    if (toys.optflags&FLAG_F) TT.O = " ";
+    else if (toys.optflags&FLAG_f) TT.O = TT.d;
   }
 
   // Parse ranges, which are attached to a selection type (only one can be set)
@@ -228,7 +207,7 @@
   if (!TT.pairs) error_exit("no selections");
 
   // Sort and collate selections
-  if (!FLAG(D)) {
+  if (!(toys.optflags&FLAG_D)) {
     int from, to;
     unsigned *pairs = (void *)toybuf;
 
diff --git a/toys/posix/date.c b/toys/posix/date.c
index 99a4169..86c2d34 100644
--- a/toys/posix/date.c
+++ b/toys/posix/date.c
@@ -7,7 +7,7 @@
  * Note: setting a 2 year date is 50 years back/forward from today,
  * not posix's hardwired magic dates.
 
-USE_DATE(NEWTOY(date, "d:D:I(iso)(iso-8601):;r:s:u(utc)[!dr]", TOYFLAG_BIN))
+USE_DATE(NEWTOY(date, "d:D:I(iso)(iso-8601):;r:u(utc)[!dr]", TOYFLAG_BIN))
 
 config DATE
   bool "date"
@@ -21,7 +21,6 @@
     -D	+FORMAT for SET or -d (instead of MMDDhhmm[[CC]YY][.ss])
     -I RES	ISO 8601 with RESolution d=date/h=hours/m=minutes/s=seconds/n=ns
     -r	Use modification time of FILE instead of current date
-    -s DATE	Set the system clock to DATE.
     -u	Use UTC instead of current timezone
 
     Supported input formats:
@@ -60,7 +59,7 @@
 #include "toys.h"
 
 GLOBALS(
-  char *s, *r, *I, *D, *d;
+  char *r, *I, *D, *d;
 
   unsigned nano;
 )
@@ -171,11 +170,6 @@
     TT.nano = ts.tv_nsec;
   }
 
-  if (FLAG(s)) {
-    if (setdate) help_exit("can't set two dates at once");
-    setdate = TT.s;
-  }
-
   // Fall through if no arguments
   if (!setdate);
   // Display the date?
diff --git a/toys/posix/df.c b/toys/posix/df.c
index caf8cf8..b8f298f 100644
--- a/toys/posix/df.c
+++ b/toys/posix/df.c
@@ -101,12 +101,12 @@
     if (FLAG(i)) {
       suap[0] = mt->statvfs.f_files;
       suap[1] = mt->statvfs.f_files - mt->statvfs.f_ffree;
-      suap[2] = geteuid() ? mt->statvfs.f_favail : mt->statvfs.f_ffree;
+      suap[2] = getuid() ? mt->statvfs.f_favail : mt->statvfs.f_ffree;
     } else {
       block = maxof(mt->statvfs.f_frsize, 1);
       suap[0] = mt->statvfs.f_blocks;
       suap[1] = mt->statvfs.f_blocks - mt->statvfs.f_bfree;
-      suap[2] = geteuid() ? mt->statvfs.f_bavail : mt->statvfs.f_bfree;
+      suap[2] = getuid() ? mt->statvfs.f_bavail : mt->statvfs.f_bfree;
     }
 
     // Scale and convert to strings
diff --git a/toys/posix/echo.c b/toys/posix/echo.c
index 6817ce2..9b7b922 100644
--- a/toys/posix/echo.c
+++ b/toys/posix/echo.c
@@ -17,15 +17,23 @@
   help
     usage: echo [-neE] [ARG...]
 
-    Write each argument to stdout, one space between each, followed by a newline.
+    Write each argument to stdout, with one space between each, followed
+    by a newline.
 
     -n	No trailing newline
     -E	Print escape sequences literally (default)
     -e	Process the following escape sequences:
-    	\\  Backslash		\0NNN Octal (1-3 digit)	\xHH Hex (1-2 digit)
-    	\a  Alert (beep/flash)	\b  Backspace		\c  Stop here (no \n)
-    	\f  Form feed		\n  Newline		\r  Carriage return
-    	\t  Horizontal tab	\v  Vertical tab
+    	\\	Backslash
+    	\0NNN	Octal values (1 to 3 digits)
+    	\a	Alert (beep/flash)
+    	\b	Backspace
+    	\c	Stop output here (avoids trailing newline)
+    	\f	Form feed
+    	\n	Newline
+    	\r	Carriage return
+    	\t	Horizontal tab
+    	\v	Vertical tab
+    	\xHH	Hexadecimal values (1 to 2 digits)
 */
 
 #define FOR_echo
diff --git a/toys/posix/env.c b/toys/posix/env.c
index 8e560a2..750ba49 100644
--- a/toys/posix/env.c
+++ b/toys/posix/env.c
@@ -4,8 +4,6 @@
  *
  * http://opengroup.org/onlinepubs/9699919799/utilities/env.html
  *
- * Note: env bypasses shell builtins, so don't xexec().
- *
  * Deviations from posix: "-" argument and -0
 
 USE_ENV(NEWTOY(env, "^i0u*", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_ARGFAIL(125)))
@@ -32,8 +30,7 @@
 
 void env_main(void)
 {
-  char **ev = toys.optargs, **ee = 0, **set QUIET, *path = getenv("PATH");
-  struct string_list *sl = 0;
+  char **ev = toys.optargs;
   struct arg_list *u;
 
   // If first nonoption argument is "-" treat it as -i
@@ -42,25 +39,16 @@
     ev++;
   }
 
-  if (FLAG(i)) ee = set = xzalloc(sizeof(void *)*(toys.optc+1));
+  if (FLAG(i)) xclearenv();
   else for (u = TT.u; u; u = u->next) xunsetenv(u->arg);
 
-  for (; *ev; ev++) {
-    if (strchr(*ev, '=')) {
-      if (FLAG(i)) *set++ = *ev;
-      else xsetenv(xstrdup(*ev), 0);
-      if (!strncmp(*ev, "PATH=", 5)) path=(*ev)+5;
-    } else {
-      // unfortunately, posix has no exec combining p and e, so do p ourselves
-      if (!strchr(*ev, '/') && path) {
-         errno = ENOENT;
-         for (sl = find_in_path(path, *ev); sl; sl = sl->next)
-           execve(sl->str, ev, ee ? : environ);
-      } else execve(*ev, ev, ee ? : environ);
-      perror_msg("exec %s", *ev);
-      _exit(126+(errno == ENOENT));
+  for (; *ev; ev++)
+    if (strchr(*ev, '=')) xsetenv(xstrdup(*ev), 0);
+    else {
+      // a common use of env is to bypass shell builtins
+      toys.stacktop = 0;
+      xexec(ev);
     }
-  }
 
-  for (ev = ee ? : environ; *ev; ev++) xprintf("%s%c", *ev, '\n'*!FLAG(0));
+  for (ev = environ; *ev; ev++) xprintf("%s%c", *ev, '\n'*!FLAG(0));
 }
diff --git a/toys/posix/expand.c b/toys/posix/expand.c
index e15d30d..f3cd44d 100644
--- a/toys/posix/expand.c
+++ b/toys/posix/expand.c
@@ -43,7 +43,7 @@
     }
     if (!len) break;
     for (i=0; i<len; i++) {
-      unsigned blah;
+      wchar_t blah;
       int width = utf8towc(&blah, toybuf+i, len-i);
       char c;
 
diff --git a/toys/posix/file.c b/toys/posix/file.c
index 2e65bcf..ecb3fc4 100644
--- a/toys/posix/file.c
+++ b/toys/posix/file.c
@@ -25,6 +25,7 @@
 
 GLOBALS(
   int max_name_len;
+
   off_t len;
 )
 
@@ -32,13 +33,14 @@
 // anyway, so calculate struct offsets manually. (It's a fixed ABI.)
 static void do_elf_file(int fd)
 {
-  unsigned endian = toybuf[5], bits = toybuf[4]-1, i, j, dynamic = 0,
-           stripped = 1, phentsize, phnum, shsize, shnum, bail = 0;
-  int64_t (*elf_int)(void *ptr, unsigned size) = (endian==2)?peek_be:peek_le;
-  char *map = MAP_FAILED;
-  unsigned long phoff, shoff;
+  int endian = toybuf[5], bits = toybuf[4], i, j, dynamic = 0, stripped = 1,
+      phentsize, phnum, shsize, shnum;
+  int64_t (*elf_int)(void *ptr, unsigned size);
+  char *map = 0;
+  long phoff, shoff;
 
   printf("ELF ");
+  elf_int = (endian==2) ? peek_be : peek_le;
 
   // executable type
   i = elf_int(toybuf+16, 2);
@@ -46,32 +48,41 @@
   else if (i == 2) printf("executable");
   else if (i == 3) printf("shared object");
   else if (i == 4) printf("core dump");
-  else {
-    printf("(bad type %d)", i);
-    bail++;
-  }
-  if (elf_int(toybuf+36+12*!!bits, 4) & 0x8000) printf(" (fdpic)");
+  else printf("(bad type %d)", i);
+  if (elf_int(toybuf+36+12*(bits==2), 4) & 0x8000) printf(" (fdpic)");
   printf(", ");
 
   // "64-bit"
-  if (bits&~1) {
+  if (bits == 1) printf("32-bit ");
+  else if (bits == 2) printf("64-bit ");
+  else {
     printf("(bad class %d) ", bits);
-    bail++;
-  } else printf("%d-bit ", 32<<bits);
+    bits = 0;
+  }
 
   // "LSB"
   if (endian == 1) printf("LSB ");
   else if (endian == 2) printf("MSB ");
   else {
-    printf("(bad endian %d) ", endian);
-    bail++;
+    printf("(bad endian %d) \n", endian);
+    endian = 0;
   }
 
   // "x86".
   printf("%s", elf_arch_name(elf_int(toybuf+18, 2)));
 
+  bits--;
   // If what we've seen so far doesn't seem consistent, bail.
-  if (bail) goto bad;
+  if (!((bits&1)==bits && endian)) {
+    printf(", corrupt?\n");
+    return;
+  }
+
+  // Parsing ELF means following tables that may point to data earlier in
+  // the file, so sequential reading involves buffering unknown amounts of
+  // data. Just skip it if we can't mmap.
+  if (MAP_FAILED == (map = mmap(0, TT.len, PROT_READ, MAP_SHARED, fd, 0)))
+    goto bad;
 
   // Stash what we need from the header; it's okay to reuse toybuf after this.
   phentsize = elf_int(toybuf+42+12*bits, 2);
@@ -84,43 +95,33 @@
   // With binutils, phentsize seems to only be non-zero if phnum is non-zero.
   // Such ELF files are rare, but do exist. (Android's crtbegin files, say.)
   if (phnum && (phentsize != 32+24*bits)) {
-    printf(", bad phentsize %d?", phentsize);
-    goto bad;
-  }
-  if (phoff>TT.len || phnum*phentsize>TT.len-phoff) {
-    printf(", bad phoff %lu?", phoff);
-    goto bad;
-  }
-  if (shoff>TT.len || shnum*shsize>TT.len-shoff) {
-    printf(", bad shoff %lu?", phoff);
+    printf(", corrupt phentsize %d?", phentsize);
     goto bad;
   }
 
   // Parsing ELF means following tables that may point to data earlier in
   // the file, so sequential reading involves buffering unknown amounts of
   // data. Just skip it if we can't mmap.
-  if (MAP_FAILED == (map = mmap(0, TT.len, PROT_READ, MAP_SHARED, fd, 0))) {
-    perror_msg("mmap");
+  if (MAP_FAILED == (map = mmap(0, TT.len, PROT_READ, MAP_SHARED, fd, 0)))
     goto bad;
-  }
 
-  // Read the phdrs for dynamic vs static. (Note: fields reordered on 64 bit)
+  // We need to read the phdrs for dynamic vs static.
+  // (Note: fields got reordered for 64 bit)
+  if (phoff<0 || phoff>TT.len || phnum*phentsize>TT.len-phoff) goto bad;
   for (i = 0; i<phnum; i++) {
     char *phdr = map+phoff+i*phentsize;
-    unsigned p_type = elf_int(phdr, 4);
+    int p_type = elf_int(phdr, 4);
     unsigned long long p_offset, p_filesz;
 
-    // TODO: what does PT_DYNAMIC without PT_INTERP mean?
-    if (p_type-2>2) continue; // 2 = PT_DYNAMIC, 3 = PT_INTERP, 4 = PT_NOTE
-    dynamic |= p_type==2;
-    p_offset = elf_int(phdr+(4<<bits), 4<<bits);
-    p_filesz = elf_int(phdr+(16<<bits), 4<<bits);
-    if (p_type==3) {
-      if (p_filesz>TT.len || p_offset>TT.len-p_filesz) {
-        printf(", bad phdr %d?", i);
-        goto bad;
-      }
-      // TODO: if (int)<0 prints endlessly, could go off end of map?
+    if (p_type==2 /*PT_DYNAMIC*/) dynamic = 1;
+    if (p_type!=3 /*PT_INTERP*/ && p_type!=4 /*PT_NOTE*/) continue;
+
+    j = bits+1;
+    p_offset = elf_int(phdr+4*j, 4*j);
+    p_filesz = elf_int(phdr+16*j, 4*j);
+
+    if (p_type==3 /*PT_INTERP*/) {
+      if (p_filesz>TT.len || p_offset>TT.len-p_filesz) goto bad;
       printf(", dynamic (%.*s)", (int)p_filesz, map+p_offset);
     }
   }
@@ -128,24 +129,19 @@
 
   // We need to read the shdrs for stripped/unstripped and any notes.
   // Notes are in program headers *and* section headers, but some files don't
-  // contain program headers, so check here. (Note: fields reordered on 64 bit)
+  // contain program headers, so we prefer to check here.
+  // (Note: fields got reordered for 64 bit)
+  if (shoff<0 || shoff>TT.len || shnum*shsize>TT.len-shoff) goto bad;
   for (i = 0; i<shnum; i++) {
     char *shdr = map+shoff+i*shsize;
     unsigned long sh_offset;
     int sh_type, sh_size;
 
-    if (shdr>map+TT.len-(8+(4<<bits))) {
-      printf(", bad shdr %d?", i);
-      goto bad;
-    }
+    if (shdr>map+TT.len-(8+4*(bits+1))) goto bad;
     sh_type = elf_int(shdr+4, 4);
-    sh_offset = elf_int(shdr+8+(8<<bits), 4<<bits);
-    sh_size = elf_int(shdr+8+(12<<bits), 4);
-    if (sh_type == 8 /*SHT_NOBITS*/) sh_size = 0;
-    if (sh_offset>TT.len || sh_size>TT.len-sh_offset) {
-      printf(", bad shdr %d?", i);
-      goto bad;
-    }
+    sh_offset = elf_int(shdr+8+8*(bits+1), 4*(bits+1));
+    sh_size = elf_int(shdr+8+12*(bits+1), 4);
+    if (sh_offset>TT.len || sh_size>TT.len-sh_offset) goto bad;
 
     if (sh_type == 2 /*SHT_SYMTAB*/) {
       stripped = 0;
@@ -160,26 +156,22 @@
       while (sh_size >= 3*4) { // Don't try to read a truncated entry.
         unsigned n_namesz, n_descsz, n_type, notesz;
 
-        if (note>map+TT.len-3*4) {
-          printf(", bad note %d?", i);
-          goto bad;
-        }
+        if (note>map+TT.len-3*4) goto bad;
 
         n_namesz = elf_int(note, 4);
         n_descsz = elf_int(note+4, 4);
         n_type = elf_int(note+8, 4);
         notesz = 3*4 + ((n_namesz+3)&~3) + ((n_descsz+3)&~3);
+        if (notesz<n_namesz || notesz<n_descsz) goto bad;
 
-        // Are the name/desc sizes consistent, and does the claimed size of
-        // the note actually fit in the section?
-        if (notesz<n_namesz || notesz<n_descsz || notesz>sh_size) {
-          printf(", bad note %d size?", i);
-          goto bad;
-        }
+        // Does the claimed size of this note actually fit in the section?
+        if (notesz > sh_size) goto bad;
 
-        if (n_namesz==4 && !memcmp(note+12, "GNU", 4) && n_type==3) {
-          printf(", BuildID=");
-          for (j = 0; j<n_descsz; j++) printf("%02x", note[16+j]);
+        if (n_namesz==4 && !memcmp(note+12, "GNU", 4)) {
+          if (n_type==3 /*NT_GNU_BUILD_ID*/) {
+            printf(", BuildID=");
+            for (j = 0; j < n_descsz; ++j) printf("%02x", note[16 + j]);
+          }
         } else if (n_namesz==8 && !memcmp(note+12, "Android", 8)) {
           if (n_type==1 /*.android.note.ident*/ && n_descsz >= 4) {
             printf(", for Android %d", (int)elf_int(note+20, 4));
@@ -199,22 +191,22 @@
 bad:
   xputc('\n');
 
-  if (map != MAP_FAILED) munmap(map, TT.len);
+  if (map && map != MAP_FAILED) munmap(map, TT.len);
 }
 
 static void do_regular_file(int fd, char *name)
 {
-  char *s = toybuf;
+  char *s;
   unsigned len, magic;
 
   // zero through elf shnum, just in case
-  memset(s, 0, 80);
-  if ((len = readall(fd, s, sizeof(toybuf)-8))<0) perror_msg("%s", name);
+  memset(toybuf, 0, 80);
+  if ((len = readall(fd, s = toybuf, sizeof(toybuf)))<0) perror_msg("%s", name);
 
   if (!len) xputs("empty");
   // 45 bytes: https://www.muppetlabs.com/~breadbox/software/tiny/teensy.html
   else if (len>=45 && strstart(&s, "\177ELF")) do_elf_file(fd);
-  else if (strstart(&s, "!<arch>\n")) xputs("ar archive");
+  else if (len>=8 && strstart(&s, "!<arch>\n")) xputs("ar archive");
   else if (len>28 && strstart(&s, "\x89PNG\x0d\x0a\x1a\x0a")) {
     // PNG is big-endian: https://www.w3.org/TR/PNG/#7Integers-and-byte-order
     int chunk_length = peek_be(s, 4);
@@ -229,8 +221,10 @@
                                 "grayscale with alpha", 0, "color RGBA"};
 
       if (s[9]<ARRAY_LEN(colors)) c = colors[s[9]];
+      if (!c) c = "unknown";
+
       xprintf(", %d x %d, %d-bit/%s, %sinterlaced", (int)peek_be(s, 4),
-        (int)peek_be(s+4, 4), s[8], c ? : "unknown", s[12] ? "" : "non-");
+        (int)peek_be(s+4, 4), s[8], c, s[12] ? "" : "non-");
     }
 
     xputc('\n');
@@ -241,78 +235,62 @@
       s-3, (int)peek_le(s, 2), (int)peek_le(s+2, 2));
 
   // TODO: parsing JPEG for width/height is harder than GIF or PNG.
-  else if (len>32 && !memcmp(s, "\xff\xd8", 2)) xputs("JPEG image data");
+  else if (len>32 && !memcmp(toybuf, "\xff\xd8", 2)) xputs("JPEG image data");
 
-  else if (len>8 && strstart(&s, "\xca\xfe\xba\xbe")) {
-    unsigned count = peek_be(s, 4), i, arch;
-
-    // 0xcafebabe can be a Java class file or a Mach-O universal binary.
-    // Java major version numbers start with 0x2d for JDK 1.1, and realistically
-    // you're never going to see more than 2 architectures in a binary anyway...
-    if (count<0x2d && len>=(count*20)) {
-      // https://eclecticlight.co/2020/07/28/universal-binaries-inside-fat-headers/
-      xprintf("Mach-O universal binary with %u architecture%s:",
-        count, count == 1 ? "" : "s");
-      for (i = 0, s += 4; i < count; i++, s += 20) {
-        arch = peek_be(s, 4);
-	if (arch == 0x00000007) name = "i386";
-        else if (arch == 0x01000007) name = "x86_64";
-	else if (arch == 0x0000000c) name = "arm";
-        else if (arch == 0x0100000c) name = "arm64";
-        else name = "unknown";
-        xprintf(" [%s]", name);
-      }
-      xprintf("\n");
-    } else {
-      // https://en.wikipedia.org/wiki/Java_class_file#General_layout
-      xprintf("Java class file, version %d.%d (Java 1.%d)\n",
-        (int)peek_be(s+2, 2), (int)peek_be(s, 2), (int)peek_be(s+2, 2)-44);
-    }
+  // https://en.wikipedia.org/wiki/Java_class_file#General_layout
+  else if (len>8 && strstart(&s, "\xca\xfe\xba\xbe"))
+    xprintf("Java class file, version %d.%d (Java 1.%d)\n",
+      (int)peek_be(s+2, 2), (int)peek_be(s, 2), (int)peek_be(s+2, 2)-44);
 
   // https://source.android.com/devices/tech/dalvik/dex-format#dex-file-magic
-  } else if (len>8 && strstart(&s, "dex\n") && !s[3])
+  else if (len>8 && strstart(&s, "dex\n") && s[3] == 0)
     xprintf("Android dex file, version %s\n", s);
 
   // https://people.freebsd.org/~kientzle/libarchive/man/cpio.5.txt
   // the lengths for cpio are size of header + 9 bytes, since any valid
   // cpio archive ends with a record for "TARGET!!!"
-  else if (len>6 && strstart(&s, "07070")) {
+  else if (len>85 && strstart(&s, "07070")) {
     char *cpioformat = "unknown type";
 
-    if (*s == '7') cpioformat = "pre-SVR4 or odc";
-    else if (*s == '1') cpioformat = "SVR4 with no CRC";
-    else if (*s == '2') cpioformat = "SVR4 with CRC";
+    if (toybuf[5] == '7') cpioformat = "pre-SVR4 or odc";
+    else if (toybuf[5] == '1') cpioformat = "SVR4 with no CRC";
+    else if (toybuf[5] == '2') cpioformat = "SVR4 with CRC";
     xprintf("ASCII cpio archive (%s)\n", cpioformat);
-  } else if (len>33 && ((magic=peek(&s,2))==0143561 || magic==070707)) {
+  } else if (len>33 && (magic=peek(&s,2), magic==0143561 || magic==070707)) {
     if (magic == 0143561) printf("byte-swapped ");
     xputs("cpio archive");
   // tar archive (old, ustar/pax, or gnu)
   } else if (len>500 && is_tar_header(s))
     xprintf("%s tar archive%s\n", s[257] ? "POSIX" : "old",
-      (s[262]!=' ' || s[263]!=' ')?"":" (GNU)");
+      strncmp(s+262,"  ",2)?"":" (GNU)");
   // zip/jar/apk archive, ODF/OOXML document, or such
   else if (len>5 && strstart(&s, "PK\03\04")) {
+    int ver = toybuf[4];
+
     xprintf("Zip archive data");
-    if (*s) xprintf(", requires at least v%d.%d to extract", *s/10, *s%10);
+    if (ver) xprintf(", requires at least v%d.%d to extract", ver/10, ver%10);
     xputc('\n');
   } else if (len>9 && strstart(&s, "7z\xbc\xaf\x27\x1c")) {
+    int ver = toybuf[6]*10+toybuf[7];
+
     xprintf("7-zip archive data");
-    if (*s || s[1]) xprintf(", version %d.%d", *s, s[1]);
+    if (ver) xprintf(", version %d.%d", ver/10, ver%10);
     xputc('\n');
   } else if (len>4 && strstart(&s, "BZh") && isdigit(*s))
     xprintf("bzip2 compressed data, block size = %c00k\n", *s);
-  else if (len>31 && peek_be(s, 7) == 0xfd377a585a0000UL)
+  else if (len > 31 && peek_be(s, 7) == 0xfd377a585a0000UL)
     xputs("xz compressed data");
   else if (len>10 && strstart(&s, "\x1f\x8b")) xputs("gzip compressed data");
   else if (len>32 && !memcmp(s+1, "\xfa\xed\xfe", 3)) {
-    int bit = (*s==0xce) ? 32 : 64;
-    char *what = 0;
+    int bit = s[0]=='\xce'?32:64;
+    char *what;
 
     xprintf("Mach-O %d-bit ", bit);
 
     if (s[4] == 7) what = (bit==32)?"x86":"x86-";
     else if (s[4] == 12) what = "arm";
     else if (s[4] == 18) what = "ppc";
+    else what = NULL;
     if (what) xprintf("%s%s ", what, (bit==32)?"":"64");
     else xprintf("(bad arch %d) ", s[4]);
 
@@ -344,14 +322,14 @@
   } else if (len>32 && !memcmp(s, "RIF", 3) && !memcmp(s+8, "WAVEfmt ", 8)) {
     // https://en.wikipedia.org/wiki/WAV
     int le = (s[3] == 'F');
-    int format = le ? peek_le(s+20, 2) : peek_be(s+20, 2);
-    int channels = le ? peek_le(s+22, 2) : peek_be(s+22, 2);
-    int hz = le ? peek_le(s+24, 4) : peek_be(s+24, 4);
-    int bits = le ? peek_le(s+34, 2) : peek_be(s+34, 2);
+    int format = le ? peek_le(s+20,2) : peek_be(s+20,2);
+    int channels = le ? peek_le(s+22,2) : peek_be(s+22,2);
+    int hz = le ? peek_le(s+24,4) : peek_be(s+24,4);
+    int bits = le ? peek_le(s+34,2) : peek_be(s+34,2);
 
     xprintf("WAV audio, %s, ", le ? "LE" : "BE");
-    if (bits) xprintf("%d-bit, ", bits);
-    if (channels==1||channels==2) xprintf("%s, ",(channels==1)?"mono":"stereo");
+    if (bits != 0) xprintf("%d-bit, ", bits);
+    if (channels==1||channels==2) xprintf("%s, ", channels==1?"mono":"stereo");
     else xprintf("%d-channel, ", channels);
     xprintf("%d Hz, ", hz);
     // See https://tools.ietf.org/html/rfc2361, though there appear to be bugs
@@ -368,53 +346,59 @@
     else if (format == 0xfffe) xprintf("extensible");
     else xprintf("unknown format %d", format);
     xputc('\n');
-  } else if (len>12 && peek_be(s, 4)==0x10000) xputs("TrueType font");
-  else if (len>12 && !memcmp(s, "ttcf\x00", 5)) {
+  } else if (len>12 && !memcmp(s, "\x00\x01\x00\x00", 4)) {
+    xputs("TrueType font");
+  } else if (len>12 && !memcmp(s, "ttcf\x00", 5)) {
     xprintf("TrueType font collection, version %d, %d fonts\n",
             (int)peek_be(s+4, 2), (int)peek_be(s+8, 4));
 
   // https://docs.microsoft.com/en-us/typography/opentype/spec/otff
-  } else if (len>12 && strstart(&s, "OTTO")) xputs("OpenType font");
-  else if (strstart(&s, "BC\xc0\xde")) xputs("LLVM IR bitcode");
-  else if (strstart(&s,"-----BEGIN CERTIFICATE-----")) xputs("PEM certificate");
+  } else if (len>12 && !memcmp(s, "OTTO", 4)) {
+    xputs("OpenType font");
+  } else if (len>4 && !memcmp(s, "BC\xc0\xde", 4)) {
+    xputs("LLVM IR bitcode");
+  } else if (strstart(&s, "-----BEGIN CERTIFICATE-----")) {
+    xputs("PEM certificate");
 
   // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680547(v=vs.85).aspx
-  else if (len>0x70 && !memcmp(s, "MZ", 2) &&
-      (magic=peek_le(s+0x3c,4))<len-4 && !memcmp(s+magic, "\x50\x45\0", 4)) {
+  } else if (len>0x70 && !memcmp(s, "MZ", 2) &&
+      (magic=peek_le(s+0x3c,4))<len-4 && !memcmp(s+magic, "\x50\x45\0\0", 4)) {
     xprintf("MS PE32%s executable %s", (peek_le(s+magic+24, 2)==0x20b)?"+":"",
         (peek_le(s+magic+22, 2)&0x2000)?"(DLL) ":"");
     if (peek_le(s+magic+20, 2)>70) {
       char *types[] = {0, "native", "GUI", "console", "OS/2", "driver", "CE",
-          "EFI", "EFI boot", "EFI runtime", "EFI ROM", "XBOX", 0, "boot"}, *nn;
-      unsigned type = peek_le(s+magic+92, 2);
+          "EFI", "EFI boot", "EFI runtime", "EFI ROM", "XBOX", 0, "boot"};
+      int type = peek_le(s+magic+92, 2);
+      char *name = (type>0 && type<ARRAY_LEN(types))?types[type]:0;
 
-      nn = (type<ARRAY_LEN(types)) ? types[type] : 0;
-      xprintf("(%s) ", nn ? : "unknown");
+      xprintf("(%s) ", name?name:"unknown");
     }
-    xprintf("x86%s\n", (peek_le(s+magic+4, 2)==0x14c) ? "" : "-64");
+    xprintf("%s\n", (peek_le(s+magic+4, 2)==0x14c)?"x86":"x86-64");
 
     // https://en.wikipedia.org/wiki/BMP_file_format
-  } else if (len>0x32 && !memcmp(s, "BM", 2) && !peek_be(s+6, 4)) {
-    xprintf("BMP image, %d x %d, %d bpp\n", (int)peek_le(s+18, 4),
-            (int)peek_le(s+22,4), (int)peek_le(s+28, 2));
+  } else if (len > 0x32 && !memcmp(s, "BM", 2) && !memcmp(s+6, "\0\0\0\0", 4)) {
+    int w = peek_le(s+0x12,4), h = peek_le(s+0x16,4), bpp = peek_le(s+0x1c,2);
+
+    xprintf("BMP image, %d x %d, %d bpp\n", w, h, bpp);
 
     // https://github.com/torvalds/linux/blob/master/tools/perf/Documentation/perf.data-file-format.txt
-  } else if (len>=104 && strstart(&s, "PERFILE2")) xputs("Linux perf data");
+  } else if (len>=104 && !memcmp(s, "PERFILE2", 8)) {
+    xputs("Linux perf data");
 
     // https://android.googlesource.com/platform/system/core/+/master/libsparse/sparse_format.h
-  else if (len>28 && peek_le(s, 4) == 0xed26ff3a) {
+  } else if (len>28 && peek_le(s, 4) == 0xed26ff3a) {
     xprintf("Android sparse image v%d.%d, %d %d-byte blocks (%d chunks)\n",
-        (int)peek_le(s+4, 2), (int)peek_le(s+6, 2), (int)peek_le(s+16, 4),
-        (int)peek_le(s+12, 4), (int)peek_le(s+20, 4));
+        (int) peek_le(s+4, 2), (int) peek_le(s+6, 2), (int) peek_le(s+16, 4),
+        (int) peek_le(s+12, 4), (int) peek_le(s+20, 4));
 
     // https://android.googlesource.com/platform/system/tools/mkbootimg/+/refs/heads/master/include/bootimg/bootimg.h
   } else if (len>1632 && !memcmp(s, "ANDROID!", 8)) {
-    xprintf("Android boot image v%d\n", (int)peek_le(s+40, 4));
+    xprintf("Android boot image v%d\n", (int) peek_le(s+40, 4));
 
     // https://source.android.com/devices/architecture/dto/partitions
   } else if (len>32 && peek_be(s, 4) == 0xd7b7ab1e) {
-    xprintf("Android DTB/DTBO v%d, %d entries\n", (int)peek_be(s+28, 4),
-            (int)peek_be(s+16, 4));
+    xprintf("Android DTB/DTBO v%d, %d entries\n", (int) peek_be(s+28, 4),
+        (int) peek_be(s+16, 4));
 
     // frameworks/base/core/java/com/android/internal/util/BinaryXmlSerializer.java
   } else if (len>4 && !memcmp(s, "ABX", 3)) {
@@ -430,14 +414,13 @@
       // Whitespace is allowed between the #! and the interpreter
       while (isspace(*s)) s++;
       if (strstart(&s, "/usr/bin/env")) while (isspace(*s)) s++;
-      for (what = s; *s && !isspace(*s); s++);
+      for (what = s; (s-toybuf)<len && !isspace(*s); s++);
       strcpy(s, " script");
 
     // Distinguish ASCII text, UTF-8 text, or data
     } else for (i = 0; i<len; ++i) {
-      if (!(isprint(s[i]) || isspace(s[i]))) {
-        unsigned wc;
-
+      if (!(isprint(toybuf[i]) || isspace(toybuf[i]))) {
+        wchar_t wc;
         if ((bytes = utf8towc(&wc, s+i, len-i))>0 && wcwidth(wc)>=0) {
           i += bytes-1;
           if (!what) what = "UTF-8 text";
@@ -455,8 +438,11 @@
 {
   char **arg;
 
-  for (arg = toys.optargs; *arg; ++arg)
-    TT.max_name_len = maxof(strlen(*arg), TT.max_name_len);
+  for (arg = toys.optargs; *arg; ++arg) {
+    int name_len = strlen(*arg);
+
+    if (name_len > TT.max_name_len) TT.max_name_len = name_len;
+  }
 
   // Can't use loopfiles here because it doesn't call function when can't open
   for (arg = toys.optargs; *arg; arg++) {
@@ -468,36 +454,31 @@
       xprintf("%s: %*s", name, (int)(TT.max_name_len - strlen(name)), "");
 
     sb.st_size = 0;
-    if (!fd && (FLAG(L) ? stat : lstat)(name, &sb)) {
-      xprintf("cannot open: %s\n", strerror(errno));
+    if (fd || !(FLAG(L) ? stat : lstat)(name, &sb)) {
+      if (!fd && !FLAG(s) && (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))) {
+        sprintf(what = toybuf, "%s special (%u/%u)",
+            S_ISBLK(sb.st_mode) ? "block" : "character",
+            dev_major(sb.st_rdev), dev_minor(sb.st_rdev));
+      } else if (fd || S_ISREG(sb.st_mode)) {
+        TT.len = sb.st_size;
+        // This test identifies an empty file we don't have permission to read
+        if (!fd && !sb.st_size) what = "empty";
+        else if ((fd = openro(name, O_RDONLY)) != -1) {
+          do_regular_file(fd, name);
+          if (fd) close(fd);
+          continue;
+        }
+      } else if (S_ISFIFO(sb.st_mode)) what = "fifo";
+      else if (S_ISDIR(sb.st_mode)) what = "directory";
+      else if (S_ISSOCK(sb.st_mode)) what = "socket";
+      else if (S_ISLNK(sb.st_mode)) {
+        char *lnk = xreadlink(name);
 
-      continue;
-    }
-
-    if (!fd && !FLAG(s) && (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode))) {
-      sprintf(what = toybuf, "%s special (%u/%u)",
-          S_ISBLK(sb.st_mode) ? "block" : "character",
-          dev_major(sb.st_rdev), dev_minor(sb.st_rdev));
-    } else if (fd || S_ISREG(sb.st_mode)) {
-      TT.len = sb.st_size;
-      // This test identifies an empty file we don't have permission to read
-      if (!fd && !sb.st_size) what = "empty";
-      else if ((fd = openro(name, O_RDONLY)) != -1) {
-        do_regular_file(fd, name);
-        if (fd) close(fd);
-
-        continue;
+        sprintf(what = toybuf, "%ssymbolic link to %s",
+            stat(name, &sb) ? "broken " : "", lnk);
+        free(lnk);
       }
-    } else if (S_ISFIFO(sb.st_mode)) what = "fifo";
-    else if (S_ISDIR(sb.st_mode)) what = "directory";
-    else if (S_ISSOCK(sb.st_mode)) what = "socket";
-    else if (S_ISLNK(sb.st_mode)) {
-      char *lnk = xreadlink(name);
-
-      sprintf(what = toybuf, "%ssymbolic link to %s",
-          stat(name, &sb) ? "broken " : "", lnk);
-      free(lnk);
-    }
-    xputs(what);
+      xputs(what);
+    } else xprintf("cannot open: %s\n", strerror(errno));
   }
 }
diff --git a/toys/posix/find.c b/toys/posix/find.c
index bca7c67..3824f0c 100644
--- a/toys/posix/find.c
+++ b/toys/posix/find.c
@@ -7,7 +7,6 @@
  * Our "unspecified" behavior for no paths is to use "."
  * Parentheses can only stack 4096 deep
  * Not treating two {} as an error, but only using last
- * TODO: -context
 
 USE_FIND(NEWTOY(find, "?^HL[-HL]", TOYFLAG_USR|TOYFLAG_BIN))
 
@@ -23,22 +22,21 @@
     -H  Follow command line symlinks         -L  Follow all symlinks
 
     Match filters:
-    -name  PATTERN   filename with wildcards   -iname      ignore case -name
-    -path  PATTERN   path name with wildcards  -ipath      ignore case -path
+    -name  PATTERN   filename with wildcards  (-iname case insensitive)
+    -path  PATTERN   path name with wildcards (-ipath case insensitive)
     -user  UNAME     belongs to user UNAME     -nouser     user ID not known
     -group GROUP     belongs to group GROUP    -nogroup    group ID not known
     -perm  [-/]MODE  permissions (-=min /=any) -prune      ignore dir contents
     -size  N[c]      512 byte blocks (c=bytes) -xdev       only this filesystem
     -links N         hardlink count            -atime N[u] accessed N units ago
     -ctime N[u]      created N units ago       -mtime N[u] modified N units ago
+    -newer FILE      newer mtime than FILE     -mindepth N at least N dirs down
+    -depth           ignore contents of dir    -maxdepth N at most N dirs down
     -inum N          inode number N            -empty      empty files and dirs
+    -type [bcdflps]  type is (block, char, dir, file, symlink, pipe, socket)
     -true            always true               -false      always false
     -context PATTERN security context          -executable access(X_OK) perm+ACL
-    -samefile FILE   hardlink to FILE          -quit       exit immediately
-    -depth           ignore contents of dir    -maxdepth N at most N dirs down
-    -newer FILE      newer mtime than FILE     -mindepth N at least N dirs down
     -newerXY FILE    X=acm time > FILE's Y=acm time (Y=t: FILE is literal time)
-    -type [bcdflps]  type is (block, char, dir, file, symlink, pipe, socket)
 
     Numbers N may be prefixed by a - (less than) or + (greater than). Units for
     -Xtime are d (days, default), h (hours), m (minutes), or s (seconds).
@@ -212,7 +210,7 @@
 {
   int pcount = 0, print = 0, not = 0, active = !!new, test = active, recurse;
   struct double_list *argdata = TT.argdata;
-  char *s, **ss, *arg;
+  char *s, **ss;
 
   recurse = DIRTREE_STATLESS|DIRTREE_COMEAGAIN|
     (DIRTREE_SYMFOLLOW*!!(toys.optflags&FLAG_L));
@@ -266,10 +264,10 @@
   // not: a pending ! applies to this test (only set if performing tests)
   // print: saw one of print/ok/exec, no need for default -print
 
-  if (TT.filter) for (ss = TT.filter; (s = *ss); ss++) {
+  if (TT.filter) for (ss = TT.filter; *ss; ss++) {
     int check = active && test;
 
-    // if (!new) perform one-time setup, if (check) perform test
+    s = *ss;
 
     // handle ! ( ) using toybuf as a stack
     if (*s != '-') {
@@ -307,7 +305,7 @@
       if (new && check)
         test = !unlinkat(dirtree_parentfd(new), new->name,
           S_ISDIR(new->st.st_mode) ? AT_REMOVEDIR : 0);
-    } else if (!strcmp(s, "depth") || !strcmp(s, "d")) TT.depth = 1;
+    } else if (!strcmp(s, "depth")) TT.depth = 1;
     else if (!strcmp(s, "o") || !strcmp(s, "or")) {
       if (not) goto error;
       if (active) {
@@ -354,27 +352,18 @@
       if (check && S_ISDIR(new->st.st_mode) && !TT.depth) recurse = 0;
     } else if (!strcmp(s, "executable")) {
       if (check && faccessat(dirtree_parentfd(new), new->name,X_OK,0)) test = 0;
-    } else if (!strcmp(s, "quit")) {
-      if (check) {
-        execdir(0, 1);
-        xexit();
-      }
 
     // Remaining filters take an argument
     } else {
-      arg = *++ss;
       if (!strcmp(s, "name") || !strcmp(s, "iname")
         || !strcmp(s, "wholename") || !strcmp(s, "iwholename")
-        || !strcmp(s, "path") || !strcmp(s, "ipath")
-        || !strcmp(s, "lname") || !strcmp(s, "ilname"))
+        || !strcmp(s, "path") || !strcmp(s, "ipath"))
       {
         int i = (*s == 'i'), is_path = (s[i] != 'n');
-        char *path = 0, *name = new ? new->name : arg;
+        char *arg = ss[1], *path = 0, *name = new ? new->name : arg;
 
         // Handle path expansion and case flattening
-        if (new && s[i] == 'l')
-          name = path = xreadlinkat(dirtree_parentfd(new), new->name);
-        else if (new && is_path) name = path = dirtree_path(new, 0);
+        if (new && is_path) name = path = dirtree_path(new, 0);
         if (i) {
           if ((check || !new) && name) name = strlower(name);
           if (!new) dlist_add(&TT.argdata, name);
@@ -382,7 +371,7 @@
         }
 
         if (check) {
-          test = !fnmatch(arg, path ? name : basename(name),
+          test = !fnmatch(arg, is_path ? name : basename(name),
             FNM_PATHNAME*(!is_path));
           if (i) free(name);
         }
@@ -392,15 +381,17 @@
           char *path = dirtree_path(new, 0), *context;
 
           if (lsm_get_context(path, &context) != -1) {
-            test = !fnmatch(arg, context, 0);
+            test = !fnmatch(ss[1], context, 0);
             free(context);
           } else test = 0;
           free(path);
         }
       } else if (!strcmp(s, "perm")) {
         if (check) {
-          int match_min = *arg == '-', match_any = *arg == '/';
-          mode_t m1 = string_to_mode(arg+(match_min || match_any), 0),
+          char *m = ss[1];
+          int match_min = *m == '-',
+              match_any = *m == '/';
+          mode_t m1 = string_to_mode(m+(match_min || match_any), 0),
                  m2 = new->st.st_mode & 07777;
 
           if (match_min || match_any) m2 &= m1;
@@ -410,42 +401,44 @@
         if (check) {
           int types[] = {S_IFBLK, S_IFCHR, S_IFDIR, S_IFLNK, S_IFIFO,
                          S_IFREG, S_IFSOCK}, i;
+          char *t = ss[1];
 
-          for (; *arg; arg++) {
-            if (*arg == ',') continue;
-            i = stridx("bcdlpfs", *arg);
-            if (i<0) error_exit("bad -type '%c'", *arg);
+          for (; *t; t++) {
+            if (*t == ',') continue;
+            i = stridx("bcdlpfs", *t);
+            if (i<0) error_exit("bad -type '%c'", *t);
             if ((new->st.st_mode & S_IFMT) == types[i]) break;
           }
-          test = *arg;
+          test = *t;
         }
 
       } else if (strchr("acm", *s)
         && (!strcmp(s+1, "time") || !strcmp(s+1, "min")))
       {
         if (check) {
+          char *copy = ss[1];
           time_t thyme = (int []){new->st.st_atime, new->st.st_ctime,
                                   new->st.st_mtime}[stridx("acm", *s)];
-          int len = strlen(arg), uu, units = (s[1]=='m') ? 60 : 86400;
+          int len = strlen(copy), uu, units = (s[1]=='m') ? 60 : 86400;
 
-          if (len && -1!=(uu = stridx("dhms",tolower(arg[len-1])))) {
-            arg = xstrdup(arg);
-            arg[--len] = 0;
+          if (len && -1!=(uu = stridx("dhms",tolower(copy[len-1])))) {
+            copy = xstrdup(copy);
+            copy[--len] = 0;
             units = (int []){86400, 3600, 60, 1}[uu];
           }
-          test = compare_numsign(TT.now - thyme, units, arg);
-          if (*ss != arg) free(arg);
+          test = compare_numsign(TT.now - thyme, units, copy);
+          if (copy != ss[1]) free(copy);
         }
       } else if (!strcmp(s, "size")) {
-        if (check) test = compare_numsign(new->st.st_size, 512, arg);
+        if (check) test = compare_numsign(new->st.st_size, 512, ss[1]);
       } else if (!strcmp(s, "links")) {
-        if (check) test = compare_numsign(new->st.st_nlink, 0, arg);
+        if (check) test = compare_numsign(new->st.st_nlink, 0, ss[1]);
       } else if (!strcmp(s, "inum")) {
-        if (check) test = compare_numsign(new->st.st_ino, 0, arg);
+        if (check) test = compare_numsign(new->st.st_ino, 0, ss[1]);
       } else if (!strcmp(s, "mindepth") || !strcmp(s, "maxdepth")) {
         if (check) {
           struct dirtree *dt = new;
-          int i = 0, d = atolx(arg);
+          int i = 0, d = atolx(ss[1]);
 
           while ((dt = dt->parent)) i++;
           if (s[1] == 'i') {
@@ -457,7 +450,7 @@
           }
         }
       } else if (!strcmp(s, "user") || !strcmp(s, "group")
-              || !strncmp(s, "newer", 5) || !strcmp(s, "samefile"))
+              || strstart(&s, "newer"))
       {
         int macoff[] = {offsetof(struct stat, st_mtim),
           offsetof(struct stat, st_atim), offsetof(struct stat, st_ctim)};
@@ -467,51 +460,45 @@
             uid_t uid;
             gid_t gid;
             struct timespec tm;
-            struct {
-              dev_t d;
-              ino_t i;
-            };
-          };
+          } u;
         } *udl;
-        struct stat st;
 
         if (!new) {
-          if (arg) {
+          if (ss[1]) {
             udl = xmalloc(sizeof(*udl));
             dlist_add_nomalloc(&TT.argdata, (void *)udl);
 
-            if (strchr("sn", *s)) {
-              if (*s=='n' && s[5] && (s[7] || !strchr("Bmac", s[5]) || !strchr("tBmac", s[6])))
+            if (s != 1+*ss) {
+              if (*s && (s[2] || !strchr("Bmac", *s) || !strchr("tBmac", s[1])))
                 goto error;
-              if (*s=='s' || !s[5] || s[6]!='t') {
-                xstat(arg, &st);
-                if (*s=='s') udl->d = st.st_dev, udl->i = st.st_ino;
-                else udl->tm = *(struct timespec *)(((char *)&st)
-                               + macoff[!s[5] ? 0 : stridx("ac", s[6])+1]);
-              } else if (s[6] == 't') {
+              if (!*s || s[1]!='t') {
+                struct stat st;
+
+                xstat(ss[1], &st);
+                udl->u.tm = *(struct timespec *)(((char *)&st)
+                  + macoff[!*s ? 0 : stridx("ac", s[1])+1]);
+              } else if (s[1] == 't') {
                 unsigned nano;
 
-                xparsedate(arg, &(udl->tm.tv_sec), &nano, 1);
-                udl->tm.tv_nsec = nano;
+                xparsedate(ss[1], &(udl->u.tm.tv_sec), &nano, 1);
+                udl->u.tm.tv_nsec = nano;
               }
-            } else if (*s == 'u') udl->uid = xgetuid(arg);
-            else udl->gid = xgetgid(arg);
+            } else if (*s == 'u') udl->u.uid = xgetuid(ss[1]);
+            else udl->u.gid = xgetgid(ss[1]);
           }
         } else {
           udl = (void *)llist_pop(&argdata);
           if (check) {
-            if (*s == 'u') test = new->st.st_uid == udl->uid;
-            else if (*s == 'g') test = new->st.st_gid == udl->gid;
-            else if (*s == 's')
-              test = new->st.st_dev == udl->d && new->st.st_ino == udl->i;
+            if (*s == 'u') test = new->st.st_uid == udl->u.uid;
+            else if (*s == 'g') test = new->st.st_gid == udl->u.gid;
             else {
               struct timespec *tm = (void *)(((char *)&new->st)
                 + macoff[!s[5] ? 0 : stridx("ac", s[5])+1]);
 
               if (s[5] == 'B') test = 0;
-              else test = (tm->tv_sec == udl->tm.tv_sec)
-                ? tm->tv_nsec > udl->tm.tv_nsec
-                : tm->tv_sec > udl->tm.tv_sec;
+              else test = (tm->tv_sec == udl->u.tm.tv_sec)
+                ? tm->tv_nsec > udl->u.tm.tv_nsec
+                : tm->tv_sec > udl->u.tm.tv_sec;
             }
           }
         }
@@ -527,10 +514,10 @@
           int len;
 
           // catch "-exec" with no args and "-exec \;"
-          if (!arg || !strcmp(arg, ";")) error_exit("'%s' needs 1 arg", s);
+          if (!ss[1] || !strcmp(ss[1], ";")) error_exit("'%s' needs 1 arg", s);
 
           dlist_add_nomalloc(&TT.argdata, (void *)(aa = xzalloc(sizeof(*aa))));
-          aa->argstart = ss;
+          aa->argstart = ++ss;
           aa->curly = -1;
 
           // Record command line arguments to -exec
@@ -554,19 +541,19 @@
 
         // collect names and execute commands
         } else {
-          char *name;
+          char *name, *ss1 = ss[1];
           struct execdir_data *bb;
 
           // Grab command line exec argument list
           aa = (void *)llist_pop(&argdata);
-          ss += aa->arglen;
+          ss += aa->arglen + 1;
 
           if (!check) goto cont;
           // name is always a new malloc, so we can always free it.
           name = aa->dir ? xstrdup(new->name) : dirtree_path(new, 0);
 
           if (*s == 'o') {
-            fprintf(stderr, "[%s] %s", arg, name);
+            fprintf(stderr, "[%s] %s", ss1, name);
             if (!(test = yesno(0))) {
               free(name);
               goto cont;
@@ -603,7 +590,7 @@
         int len;
 
         print++;
-        if (check) for (fmt = arg; *fmt; fmt++) {
+        if (check) for (fmt = ss[1]; *fmt; fmt++) {
           // Print the parts that aren't escapes
           if (*fmt == '\\') {
             unsigned u;
@@ -637,7 +624,10 @@
               else if (ch == 'g') ll = (long)getgroupname(new->st.st_gid);
               else if (ch == 'u') ll = (long)getusername(new->st.st_uid);
               else if (ch == 'l') {
-                ll = (long)(ff = xreadlinkat(dirtree_parentfd(new), new->name));
+                char *path = dirtree_path(new, 0);
+
+                ll = (long)(ff = xreadlink(path));
+                free(path);
                 if (!ll) ll = (long)"";
               } else if (ch == 'M') {
                 mode_to_string(new->st.st_mode, buf);
@@ -670,7 +660,7 @@
       // This test can go at the end because we do a syntax checking
       // pass first. Putting it here gets the error message (-unknown
       // vs -known noarg) right.
-      if (!check && !arg) error_exit("'%s' needs 1 arg", s-1);
+      if (!*++ss) error_exit("'%s' needs 1 arg", --s);
     }
 cont:
     // Apply pending "!" to result
diff --git a/toys/posix/getconf.c b/toys/posix/getconf.c
index a8017b2..c5e0548 100644
--- a/toys/posix/getconf.c
+++ b/toys/posix/getconf.c
@@ -55,7 +55,7 @@
 // confstr(), or output the macro value directly.
 
 // Probe the live system
-static struct config sysconfs[] = {
+struct config sysconfs[] = {
   /* POSIX */
 #define CONF(n) {"_POSIX_" #n,_SC_ ## n}
   CONF(ADVISORY_INFO), CONF(BARRIERS), CONF(ASYNCHRONOUS_IO),
@@ -118,7 +118,7 @@
 };
 
 // Probe the live system with a path
-static struct config pathconfs[] = {
+struct config pathconfs[] = {
 #undef CONF
 #define CONF(n) {#n,_PC_ ## n}
   CONF(ASYNC_IO), CONF(CHOWN_RESTRICTED), CONF(FILESIZEBITS), CONF(LINK_MAX),
@@ -129,14 +129,14 @@
 };
 
 // Strings out of a header
-static struct config confstrs[] = {
+struct config confstrs[] = {
 #undef CONF
 #define CONF(n) {#n,_CS_ ## n}
   CONF(PATH), CONF(V7_ENV)
 };
 
 // Integers out of a header
-static struct config limits[] = {
+struct config limits[] = {
 #undef CONF
 #define CONF(n) {#n,n}
   CONF(_POSIX_AIO_LISTIO_MAX), CONF(_POSIX_AIO_MAX), CONF(_POSIX_ARG_MAX),
@@ -167,7 +167,7 @@
 };
 
 // Names we need to handle ourselves (default to blank but shouldn't error)
-static struct config others[] = {
+struct config others[] = {
   {"LFS_CFLAGS", 0}, {"LFS_LDFLAGS", 0}, {"LFS_LIBS", 0}
 };
 
diff --git a/toys/posix/grep.c b/toys/posix/grep.c
index 0474f7d..52d1013 100644
--- a/toys/posix/grep.c
+++ b/toys/posix/grep.c
@@ -10,7 +10,7 @@
 * echo hello | grep -f </dev/null
 *
 
-USE_GREP(NEWTOY(grep, "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcL(files-without-match)l(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EF]", TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)|TOYFLAG_LINEBUF))
+USE_GREP(NEWTOY(grep, "(line-buffered)(color):;(exclude-dir)*S(exclude)*M(include)*ZzEFHIab(byte-offset)h(no-filename)ino(only-matching)rRsvwcl(files-with-matches)q(quiet)(silent)e*f*C#B#A#m#x[!wx][!EFw]", TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)|TOYFLAG_LINEBUF))
 USE_EGREP(OLDTOY(egrep, grep, TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)|TOYFLAG_LINEBUF))
 USE_FGREP(OLDTOY(fgrep, grep, TOYFLAG_BIN|TOYFLAG_ARGFAIL(2)|TOYFLAG_LINEBUF))
 
@@ -44,10 +44,9 @@
     -x  whole line               -z  input NUL terminated
 
     display modes: (default: matched line)
-    -L  filenames with no match  -Z  output is NUL terminated
-    -c  count of matching lines  -l  filenames with a match
+    -c  count of matching lines  -l  show only matching filenames
     -o  only matching part       -q  quiet (errors only)
-    -s  silent (no error msg)
+    -s  silent (no error msg)    -Z  output NUL terminated
 
     output prefix (default: filename if checking more than 1 file)
     -H  force filename           -b  byte offset of match
@@ -125,7 +124,7 @@
   if (!FLAG(a) && !lseek(fd, 0, SEEK_CUR)) {
     char buf[256];
     int len, i = 0;
-    unsigned wc;
+    wchar_t wc;
 
     // If the first 256 bytes don't parse as utf8, call it binary.
     if (0<(len = read(fd, buf, 256))) {
@@ -264,14 +263,12 @@
       }
       matched++;
       TT.found = 1;
-
-      // Are we NOT showing the matching text?
       if (FLAG(q)) {
         toys.exitval = 0;
         xexit();
       }
-      if (FLAG(L) || FLAG(l)) {
-        if (FLAG(l)) xprintf("%s%c", name, TT.outdelim);
+      if (FLAG(l)) {
+        xprintf("%s%c", name, TT.outdelim);
         free(line);
         fclose(file);
         return;
@@ -299,9 +296,9 @@
             outline(FLAG(color) ? 0 : line, ':', name, lcount, bcount, ulen);
           if (FLAG(color)) {
             xputsn(TT.grey);
-            if (mm->rm_so) xputsl(start, mm->rm_so);
+            if (mm->rm_so) xputsl(line, mm->rm_so);
             xputsn(TT.red);
-            xputsl(start+mm->rm_so, mm->rm_eo-mm->rm_so);
+            xputsl(line+mm->rm_so, mm->rm_eo-mm->rm_so);
           }
 
           if (TT.A) after = TT.A+1;
@@ -310,6 +307,7 @@
 
       start += mm->rm_eo;
       if (mm->rm_so == mm->rm_eo) break;
+      if (!FLAG(o) && FLAG(color)) break;
     } while (*start);
     offset += len;
 
@@ -355,8 +353,7 @@
     if (FLAG(m) && mcount >= TT.m) break;
   }
 
-  if (FLAG(L)) xprintf("%s%c", name, TT.outdelim);
-  else if (FLAG(c)) outline(0, ':', name, mcount, 0, 1);
+  if (FLAG(c)) outline(0, ':', name, mcount, 0, 1);
 
   // loopfiles will also close the fd, but this frees an (opaque) struct.
   fclose(file);
@@ -461,11 +458,11 @@
     toys.optflags &= ~FLAG_color;
 
   if (FLAG(color)) {
-    TT.purple = "\e[35m";
-    TT.cyan = "\e[36m";
-    TT.red = "\e[1;31m";
-    TT.green = "\e[32m";
-    TT.grey = "\e[m";
+    TT.purple = "\033[35m";
+    TT.cyan = "\033[36m";
+    TT.red = "\033[1;31m";
+    TT.green = "\033[32m";
+    TT.grey = "\033[0m";
   } else TT.purple = TT.cyan = TT.red = TT.green = TT.grey = "";
 
   if (FLAG(R)) toys.optflags |= FLAG_r;
diff --git a/toys/posix/kill.c b/toys/posix/kill.c
index 2eaba03..2767659 100644
--- a/toys/posix/kill.c
+++ b/toys/posix/kill.c
@@ -51,6 +51,7 @@
 
 // But kill's flags are a subset of killall5's
 
+#define CLEANUP_kill
 #define FOR_killall5
 #include "generated/flags.h"
 
diff --git a/toys/posix/ls.c b/toys/posix/ls.c
index 1551105..d9cd90b 100644
--- a/toys/posix/ls.c
+++ b/toys/posix/ls.c
@@ -84,7 +84,7 @@
       for (i = 0; i<len; i++) {
         *to++ = '\\';
         if (strchr(TT.escmore, from[i])) *to++ = from[i];
-        else if (-1 != (j = stridx("\\\a\b\e\f\n\r\t\v", from[i])))
+        else if (-1 != (j = stridx("\\\a\b\033\f\n\r\t\v", from[i])))
           *to++ = "\\abefnrtv"[j];
         else to += sprintf(to, "%03o", from[i]);
       }
@@ -457,12 +457,12 @@
 
     if (FLAG(color)) {
       color = color_from_mode(st->st_mode);
-      if (color) printf("\e[%d;%dm", color>>8, color&255);
+      if (color) printf("\033[%d;%dm", color>>8, color&255);
     }
 
     ss = dt->name;
     crunch_str(&ss, INT_MAX, stdout, TT.escmore, crunch_qb);
-    if (color) printf("\e[0m");
+    if (color) printf("\033[0m");
 
     if ((FLAG(l)||FLAG(o)||FLAG(n)||FLAG(g)) && S_ISLNK(mode)) {
       printf(" -> ");
@@ -472,11 +472,11 @@
         if (fstatat(dirfd, dt->symlink, &st2, 0)) color = 256+31;
         else color = color_from_mode(st2.st_mode);
 
-        if (color) printf("\e[%d;%dm", color>>8, color&255);
+        if (color) printf("\033[%d;%dm", color>>8, color&255);
       }
 
       zprint(zap, "s", 0, (unsigned long)dt->symlink);
-      if (!zap && color) printf("\e[0m");
+      if (!zap && color) printf("\033[0m");
     }
 
     if (et) xputc(et);
diff --git a/toys/posix/nl.c b/toys/posix/nl.c
index af95d94..ef2d7ab 100644
--- a/toys/posix/nl.c
+++ b/toys/posix/nl.c
@@ -4,10 +4,10 @@
  *
  * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/nl.html
  *
- * Deviations from posix: only one logical page (no -ip), no sections (-dfh),
- * add -E, support multiple FILE, -n output is long not int.
+ * This implements a subset: only one logical page (-ip), no sections (-dfh).
+ * todo: -l
 
-USE_NL(NEWTOY(nl, "v#=1l#w#<0=6b:n:s:E", TOYFLAG_USR|TOYFLAG_BIN))
+USE_NL(NEWTOY(nl, "v#=1l#w#<0=6Eb:n:s:", TOYFLAG_USR|TOYFLAG_BIN))
 
 config NL
   bool "nl"
@@ -34,7 +34,8 @@
   long w, l, v;
 
   // Count of consecutive blank lines for -l has to persist between files
-  long lcount, slen;
+  long lcount;
+  long slen;
 )
 
 static void do_nl(char **pline, long len)
@@ -70,10 +71,10 @@
   sprintf(toybuf, "%%%s%s", clip, "*ld%s");
 
   if (!TT.b) TT.b = "t";
-  if (*TT.b=='p' && TT.b[1])
-    xregcomp((void *)(toybuf+16), TT.b+1, REG_NOSUB|FLAG(E)*REG_EXTENDED);
-  else if (!TT.b[0] || TT.b[1] || !strchr("atn", *TT.b))
-    error_exit("bad -b '%s'", TT.b);
+  if (*TT.b == 'p' && TT.b[1])
+    xregcomp((void *)(toybuf+16), TT.b+1,
+      REG_NOSUB | (toys.optflags&FLAG_E)*REG_EXTENDED);
+  else if (!strchr("atn", *TT.b)) error_exit("bad -b '%s'", TT.b);
 
   loopfiles_lines(toys.optargs, do_nl);
 }
diff --git a/toys/posix/paste.c b/toys/posix/paste.c
index 43c2569..7d9ba94 100644
--- a/toys/posix/paste.c
+++ b/toys/posix/paste.c
@@ -45,7 +45,7 @@
 
     for (i = any = dcount = dlen = 0; seq || i<TT.files; i++) {
       size_t blen;
-      unsigned wc;
+      wchar_t wc;
       FILE *ff = seq ? *fps : fps[i];
 
       // Read and output line, preserving embedded NUL bytes.
diff --git a/toys/posix/patch.c b/toys/posix/patch.c
index 4b8c61c..f0aad4e 100644
--- a/toys/posix/patch.c
+++ b/toys/posix/patch.c
@@ -8,11 +8,12 @@
  * TODO:
  * -b backup
  * -N ignore already applied
+ * -d chdir first
  * -D define wrap #ifdef and #ifndef around changes
  * -o outfile output here instead of in place
  * -r rejectfile write rejected hunks to this file
+ *
  * -E remove empty files --remove-empty-files
- * git syntax (rename, etc)
 
 USE_PATCH(NEWTOY(patch, ">2(no-backup-if-mismatch)(dry-run)"USE_TOYBOX_DEBUG("x")"F#g#fulp#d:i:Rs(quiet)", TOYFLAG_USR|TOYFLAG_BIN))
 
@@ -20,7 +21,7 @@
   bool "patch"
   default y
   help
-    usage: patch [-Rlsu] [-d DIR] [-i PATCH] [-p DEPTH] [-F FUZZ] [--dry-run] [FILE [PATCH]]
+    usage: patch [-d DIR] [-i PATCH] [-p DEPTH] [-F FUZZ] [-Rlsu] [--dry-run] [FILE [PATCH]]
 
     Apply a unified diff to one or more files.
 
@@ -54,25 +55,6 @@
   char *tempname;
 )
 
-// TODO xgetline() instead, but replace_tempfile() wants fd...
-char *get_line(int fd)
-{
-  char c, *buf = NULL;
-  long len = 0;
-
-  for (;;) {
-    if (1>read(fd, &c, 1)) break;
-    if (!(len & 63)) buf=xrealloc(buf, len+65);
-    if ((buf[len++]=c) == '\n') break;
-  }
-  if (buf) {
-    buf[len]=0;
-    if (buf[--len]=='\n') buf[len]=0;
-  }
-
-  return buf;
-}
-
 // Dispose of a line of input, either by writing it out or discarding it.
 
 // state < 2: just free
diff --git a/toys/posix/ps.c b/toys/posix/ps.c
index 3884097..304fe00 100644
--- a/toys/posix/ps.c
+++ b/toys/posix/ps.c
@@ -43,13 +43,12 @@
  *       at right edge? (Not adjusting to screen size at all? Header wraps?)
  * TODO: top: thread support and SMP
  * TODO: pgrep -f only searches the amount of cmdline that fits in toybuf.
- * TODO: pgrep qemu-system-i386 never matches because one char too long
 
 USE_PS(NEWTOY(ps, "k(sort)*P(ppid)*aAdeflMno*O*p(pid)*s*t*Tu*U*g*G*wZ[!ol][+Ae][!oO]", TOYFLAG_BIN|TOYFLAG_LOCALE))
 // stayroot because iotop needs root to read other process' proc/$$/io
 // TOP and IOTOP have a large common option block used for common processing,
 // the default values are different but the flags are in the same order.
-USE_TOP(NEWTOY(top, ">0O*h" "Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
+USE_TOP(NEWTOY(top, ">0O*" "Hk*o*p*u*s#<1d%<100=3000m#n#<1bq[!oO]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_LOCALE))
 USE_IOTOP(NEWTOY(iotop, ">0AaKO" "Hk*o*p*u*s#<1=7d%<100=3000m#n#<1bq", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_STAYROOT|TOYFLAG_LOCALE))
 USE_PGREP(NEWTOY(pgrep, "?cld:u*U*t*s*P*g*G*fnovxL:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
 USE_PKILL(NEWTOY(pkill,    "?Vu*U*t*s*P*g*G*fnovxl:[-no]", TOYFLAG_USR|TOYFLAG_BIN))
@@ -89,12 +88,11 @@
   bool "top"
   default y
   help
-    usage: top [-Hhbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]
+    usage: top [-Hbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]
 
     Show process activity in real time.
 
     -H	Show threads
-    -h	Usage graphs instead of text
     -k	Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)
     -o	Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)
     -O	Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)
@@ -107,8 +105,8 @@
     -u	Show these USERs
     -q	Quiet (no header lines)
 
-    Cursor UP/DOWN or LEFT/RIGHT to move list, SHIFT LEFT/RIGHT to change sort,
-    space to force update, R to reverse sort, Q to exit.
+    Cursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force
+    update, R to reverse sort, Q to exit.
 
 # Requires CONFIG_IRQ_TIME_ACCOUNTING in the kernel for /proc/$$/io
 config IOTOP
@@ -211,7 +209,7 @@
 
   struct ptr_len gg, GG, pp, PP, ss, tt, uu, UU;
   struct dirtree *threadparent;
-  unsigned width, height, scroll;
+  unsigned width, height;
   dev_t tty;
   void *fields, *kfields;
   long long ticks, bits, time;
@@ -639,14 +637,11 @@
 static void show_ps(void *p)
 {
   struct procpid *tb = p;
-  struct ofields *field = TT.fields;
-  int pad, len, width = TT.width, abslen, sign, olen, scroll, extra = 0;
-
-  // Skip TT.scroll many fields (but not last one)
-  for (scroll = TT.scroll; scroll && field->next; scroll--) field = field->next;
+  struct ofields *field;
+  int pad, len, width = TT.width, abslen, sign, olen, extra = 0;
 
   // Loop through fields to display
-  for (; field; field = field->next) {
+  for (field = TT.fields; field; field = field->next) {
     char *out = string_field(tb, field);
 
     // Output the field, appropriately padded
@@ -1129,10 +1124,7 @@
 static long long get_headers(struct ofields *field, char *buf, int blen)
 {
   long long bits = 0;
-  int len = 0, scroll;
-
-  // Skip TT.scroll many fields (but not last one)
-  for (scroll = TT.scroll; scroll && field->next; scroll--) field = field->next;
+  int len = 0;
 
   for (; field; field = field->next) {
     len += snprintf(buf+len, blen-len, " %*s"+!bits, field->len,
@@ -1408,7 +1400,6 @@
     if (CFG_TOYBOX_FREE) free(tbsort);
   }
 
-  if (!TT.kcount) toys.exitval = 1;
   if (CFG_TOYBOX_FREE) {
     free(TT.gg.ptr);
     free(TT.GG.ptr);
@@ -1422,6 +1413,7 @@
   }
 }
 
+#define CLEANUP_ps
 #define FOR_top
 #include "generated/flags.h"
 
@@ -1464,8 +1456,8 @@
 
   if (FLAG(b)) puts(toybuf);
   else {
-    printf("%s%-*.*s%s\r\n", rev?"\e[7m":"", rev?TT.width:0, TT.width, toybuf,
-      rev?"\e[0m":"");
+    printf("%s%-*.*s%s\r\n", rev?"\033[7m":"", rev?TT.width:0, TT.width, toybuf,
+      rev?"\033[0m":"");
   }
 
   return line-1;
@@ -1473,36 +1465,7 @@
 
 static void top_cursor_cleanup(void)
 {
-  xputsn("\e[?25h");
-}
-
-// Show a three color bar graph. spans: 0 total size, 1used, 2 nice, 3 sys
-static void bargraph(char *label, unsigned width, unsigned long span[4])
-{
-  char percent[16];
-  long long ll;
-  unsigned i, color, len;
-
-  if (!*span) ++*span;
-  i = ((span[1]+(unsigned long long)span[2]+span[3])*1000)/ *span;
-  len = sprintf(percent, "%u.%u", i/10, i%10);
-
-  printf("%s[", label);
-  for (ll = i = color = 0; i<width; i++) {
-    while (ll<1 && color<4) {
-      if (color++!=3) {
-        ll += span[color]*width;
-        if (ll<*span/2) continue;
-      }
-      // green, red, blue, grey
-      if (color==4) printf("\e[1;2;37m");
-      else printf("\e[%um", (char[]){32,34,31}[color-1]);
-      break;
-    }
-    if (color<4) ll -= *span;
-    printf("%c", width-i>len ? (color==4 ? ' ' : '|') : percent[len-(width-i)]);
-  }
-  printf("\e[0m]");
+  tty_esc("?25h");
 }
 
 static void top_common(
@@ -1526,7 +1489,7 @@
   if (!FLAG(b)) {
     setbuf(stdout, stdout_buf);
     sigatexit(top_cursor_cleanup);
-    xputsn("\e[?25l");
+    tty_esc("?25l");
   }
 
   toys.signal = SIGWINCH;
@@ -1601,7 +1564,7 @@
       if (recalc) {
         qsort(mix.tb, mix.count, sizeof(struct procpid *), (void *)ksort);
         if (!FLAG(b)) {
-          printf("\e[H\e[J");
+          printf("\033[H\033[J");
           if (toys.signal) {
             toys.signal = 0;
             terminal_probesize(&TT.width, &TT.height);
@@ -1617,8 +1580,7 @@
           char hr[4][32];
           long long ll, up = 0;
           long run[6];
-          int j, k, cpus = sysconf(_SC_NPROCESSORS_CONF);
-
+          int j, k;
 
           // Count running, sleeping, stopped, zombie processes.
           // The kernel has more states (and different sets in different
@@ -1641,7 +1603,6 @@
               pos = strafter(toybuf+256, (char *[]){"MemTotal:","\nMemFree:",
                     "\nBuffers:","\nSwapTotal:","\nSwapFree:","\nCached:"}[i]);
               run[i] = pos ? atol(pos) : 0;
-              if (FLAG(h)) continue;
               k = (*run>=10000000);
               human_readable_long(hr[j+!!j], run[i]>>(10*k), 9, k+1, HR_NODOT);
               if (j==1) human_readable_long(hr[1], (run[i-1]-run[i])>>(10*k),
@@ -1653,24 +1614,17 @@
                 lines = header_line(lines, 0);
               }
             }
-            if (FLAG(h)) {
-              unsigned long swp[] = {run[3], 0, 0, run[3]-run[4]},
-                mem[] = {run[0], run[0]-run[1]-run[2]-run[5], run[2], run[5]};
-
-              bargraph("Mem", 34, mem);
-              bargraph(" Swp", 34, swp);
-              xprintf("\r\n");
-            }
           }
           pos = toybuf;
-          pos += sprintf(pos, "%d%%cpu", cpus*100);
-          j = 4+(cpus>10);
+          i = sysconf(_SC_NPROCESSORS_CONF);
+          pos += sprintf(pos, "%d%%cpu", i*100);
+          j = 4+(i>10);
 
           // If a processor goes idle it's powered down and its idle ticks don't
           // advance, so calculate idle time as potential time - used.
           if (mix.count) up = mix.tb[0]->slot[SLOT_upticks];
           if (!up) up = 1;
-          now = up*cpus;
+          now = up*i;
           ll = stats[3] = stats[11] = 0;
           for (i = 0; i<8; i++) ll += stats[i]-stats[i+8];
           stats[3] = now - llabs(ll);
@@ -1679,7 +1633,7 @@
             ll = (llabs(stats[i]-stats[i+8])*1000)/up;
             pos += sprintf(pos, "% *lld%%%s", j, (ll+5)/10, cpufields[i]);
           }
-        // Display "iotop" header.
+          lines = header_line(lines, 0);
         } else {
           struct ofields *field;
           struct procpid tb;
@@ -1701,10 +1655,9 @@
               field->len, string_field(&tb, field));
           }
           *--pos = 0;
+          lines = header_line(lines, 0);
         }
 
-        lines = header_line(lines, 0);
-        // print line of header labels for currently displayed fields
         get_headers(TT.fields, pos = toybuf, sizeof(toybuf));
         for (i = 0, is = ' '; *pos; pos++) {
           was = is;
@@ -1717,16 +1670,18 @@
         *pos = 0;
         lines = header_line(lines, 1);
       }
-      if (!recalc && !FLAG(b)) printf("\e[%dH\e[J", 1+TT.height-lines);
+      if (!recalc && !FLAG(b))
+        printf("\033[%dH\033[J", 1+TT.height-lines);
+      recalc = 1;
 
       for (i = 0; i<lines && i+topoff<mix.count; i++) {
         // Running processes are shown in bold.
         int bold = !FLAG(b) && mix.tb[i+topoff]->state == 'R';
 
         if (!FLAG(b) && i) putchar('\n');
-        if (bold) printf("\e[1m");
+        if (bold) printf("\033[1m");
         show_ps(mix.tb[i+topoff]);
-        if (bold) printf("\e[m");
+        if (bold) printf("\033[m");
       }
 
       if (TT.top.n && !--TT.top.n) {
@@ -1746,7 +1701,6 @@
         break;
       } else fflush(stdout);
 
-      recalc = 1;
       i = scan_key_getsize(scratch, timeout-now, &TT.width, &TT.height);
       if (i==-1 || i==3 || toupper(i)=='Q') {
         done++;
@@ -1764,18 +1718,21 @@
         ((struct ofields *)TT.kfields)->reverse *= -1;
       else {
         i -= 256;
-        if (i == (KEY_SHIFT|KEY_LEFT)) setsort(TT.sortpos-1);
-        else if (i == (KEY_SHIFT|KEY_RIGHT)) setsort(TT.sortpos+1);
-        else if (i == KEY_RIGHT) TT.scroll++;
-        else if (i == KEY_LEFT && TT.scroll) TT.scroll--;
-        else if (recalc-- && i == KEY_UP) topoff--;
-        else if (i == KEY_DOWN) topoff++;
-        else if (i == KEY_PGDN) topoff += lines;
-        else if (i == KEY_PGUP) topoff -= lines;
-        else continue;
-        if (topoff<0) topoff = 0;
-        if (topoff>mix.count) topoff = mix.count;
+        if (i == KEY_LEFT) setsort(TT.sortpos-1);
+        else if (i == KEY_RIGHT) setsort(TT.sortpos+1);
+        // KEY_UP is 0, so at end of strchr
+        else if (strchr((char []){KEY_DOWN,KEY_PGUP,KEY_PGDN,KEY_UP}, i)) {
+          recalc = 0;
+
+          if (i == KEY_UP) topoff--;
+          else if (i == KEY_DOWN) topoff++;
+          else if (i == KEY_PGDN) topoff += lines;
+          else if (i == KEY_PGUP) topoff -= lines;
+          if (topoff<0) topoff = 0; 
+          if (topoff>mix.count) topoff = mix.count;
+        }
       }
+      continue;
     }
 
     free(mix.tb);
@@ -1830,6 +1787,7 @@
   top_common(merge_deltas);
 }
 
+#define CLEANUP_top
 #define FOR_iotop
 #include "generated/flags.h"
 
@@ -1860,6 +1818,7 @@
 // context, so force pgrep's flags on even when building pkill standalone.
 // (All the pgrep/pkill functions drop out when building ps standalone.)
 #define FORCE_FLAGS
+#define CLEANUP_iotop
 #define FOR_pgrep
 #include "generated/flags.h"
 
@@ -1973,6 +1932,7 @@
   if (TT.pgrep.d) xputc('\n');
 }
 
+#define CLEANUP_pgrep
 #define FOR_pkill
 #include "generated/flags.h"
 
diff --git a/toys/posix/sed.c b/toys/posix/sed.c
index cea12ea..d5a4a83 100644
--- a/toys/posix/sed.c
+++ b/toys/posix/sed.c
@@ -881,7 +881,7 @@
       for (cc = line; *cc; cc++) if (*cc == '\\' && cc[1] == ';') break;
       delim = *cc;
       *cc = 0;
-      fd = xcreate(line, O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, 0644);
+      fd = xcreate(line, O_WRONLY|O_CREAT|O_TRUNC, 0644);
       *cc = delim;
 
       command->w = reg - (char *)command;
diff --git a/toys/posix/sleep.c b/toys/posix/sleep.c
index 73f03fb..846df80 100644
--- a/toys/posix/sleep.c
+++ b/toys/posix/sleep.c
@@ -23,8 +23,8 @@
 
 void sleep_main(void)
 {
-  struct timespec ts;
+  struct timespec tv;
 
-  xparsetimespec(*toys.optargs, &ts);
-  toys.exitval = !!nanosleep(&ts, NULL);
+  tv.tv_sec = xparsetime(*toys.optargs, 9, &tv.tv_nsec);
+  toys.exitval = !!nanosleep(&tv, NULL);
 }
diff --git a/toys/posix/sort.c b/toys/posix/sort.c
index c06b2a5..9f38be8 100644
--- a/toys/posix/sort.c
+++ b/toys/posix/sort.c
@@ -61,7 +61,7 @@
   char *o, *T, S;
 
   void *key_list;
-  unsigned linecount;
+  int linecount;
   char **lines, *name;
 )
 
@@ -72,7 +72,8 @@
 
 #define FLAG_bb (1<<31)  // Ignore trailing blanks
 
-struct sort_key {
+struct sort_key
+{
   struct sort_key *next_key;  // linked list
   unsigned range[4];          // start word, start char, end word, end char
   int flags;
@@ -114,7 +115,7 @@
         }
       }
     }
-    if (!j) start = end;
+    if (!j) start=end;
   }
 
   // Key with explicit separator starts after the separator
@@ -193,7 +194,7 @@
     }
     if (yinf) return dy<0 ? 1 : -1;
 
-    return dx<dy ? -1 : dx>dy;
+    return dx>dy ? 1 : (dx<dy ? -1 : 0);
   } else if (flags & FLAG_M) {
     struct tm thyme;
     int dx;
@@ -226,11 +227,14 @@
       }
     }
     return *x ? !!*y : -1;
-  // This is actually an integer sort with decimals sorted by string fallback.
   } else if (flags & FLAG_n) {
-    long long dx = atoll(x), dy = atoll(y);
+    // Full floating point version of -n
+    if (CFG_SORT_FLOAT) {
+      double dx = atof(x), dy = atof(y);
 
-    return dx<dy ? -1 : dx>dy;
+      return dx>dy ? 1 : (dx<dy ? -1 : 0);
+    // Integer version of -n for tiny systems
+    } else return atoi(x)-atoi(y);
 
   // Ascii sort
   } else return ((flags&FLAG_f) ? strcasecmp : strcmp)(x, y);
@@ -243,8 +247,8 @@
   char *x, *y, *xx = *(char **)xarg, *yy = *(char **)yarg;
   struct sort_key *key;
 
-  for (key=(void *)TT.key_list; !retval && key; key = key->next_key) {
-    flags = key->flags ? : toys.optflags;
+  for (key=(struct sort_key *)TT.key_list; !retval && key; key = key->next_key){
+    flags = key->flags ? key->flags : toys.optflags;
 
     // Chop out and modify key chunks, handling -dfib
 
@@ -283,8 +287,10 @@
 
   // handle -c here so we don't allocate more memory than necessary.
   if (FLAG(c)) {
-    if (TT.lines && compare_keys((void *)&TT.lines, &line)>-!!FLAG(u))
-      error_exit("%s: Check line %u\n", TT.name, TT.linecount);
+    int j = FLAG(u) ? -1 : 0;
+
+    if (TT.lines && compare_keys((void *)&TT.lines, &line)>j)
+      error_exit("%s: Check line %d\n", TT.name, TT.linecount);
     free(TT.lines);
     TT.lines = (void *)line;
   } else {
@@ -304,9 +310,7 @@
 
 void sort_main(void)
 {
-  int idx, jdx, fd = 1;
-
-  if (FLAG(u)) toys.optflags |= FLAG_s;
+  int idx, fd = 1;
 
   // Parse -k sort keys.
   if (TT.k) {
@@ -314,32 +318,39 @@
 
     for (arg = TT.k; arg; arg = arg->next) {
       struct sort_key *key = add_key();
-      char *temp, *temp2, *optlist;
+      char *temp;
       int flag;
 
       idx = 0;
       temp = arg->arg;
       while (*temp) {
         // Start of range
-        key->range[2*idx] = strtol(temp, &temp, 10);
-        if (*temp=='.') key->range[(2*idx)+1] = strtol(temp+1, &temp, 10);
+        key->range[2*idx] = (unsigned)strtol(temp, &temp, 10);
+        if (*temp=='.')
+          key->range[(2*idx)+1] = (unsigned)strtol(temp+1, &temp, 10);
 
         // Handle flags appended to a key type.
         for (;*temp;temp++) {
+          char *temp2, *optlist;
 
-          // Second comma becomes an "Unknown key" error.
+          // Note that a second comma becomes an "Unknown key" error.
+
           if (*temp==',' && !idx++) {
             temp++;
             break;
           }
 
           // Which flag is this?
+
           optlist = toys.which->options;
           temp2 = strchr(optlist, *temp);
-          flag = 1<<(optlist-temp2+strlen(optlist)-1);
+          flag = (1<<(optlist-temp2+strlen(optlist)-1));
 
           // Was it a flag that can apply to a key?
-          if (!temp2 || flag>FLAG_x || (flag&(FLAG_u|FLAG_c|FLAG_s|FLAG_z))) {
+
+          if (!temp2 || flag>FLAG_x
+            || (flag&(FLAG_u|FLAG_c|FLAG_s|FLAG_z)))
+          {
             toys.exitval = 2;
             error_exit("Unknown key option.");
           }
@@ -369,8 +380,11 @@
 
   // handle unique (-u)
   if (FLAG(u)) {
+    int jdx;
+
     for (jdx=0, idx=1; idx<TT.linecount; idx++) {
-      if (!compare_keys(&TT.lines[jdx], &TT.lines[idx])) free(TT.lines[idx]);
+      if (!compare_keys(&TT.lines[jdx], &TT.lines[idx]))
+        free(TT.lines[idx]);
       else TT.lines[++jdx] = TT.lines[idx];
     }
     if (TT.linecount) TT.linecount = jdx+1;
diff --git a/toys/posix/split.c b/toys/posix/split.c
index 293343b..daf6422 100644
--- a/toys/posix/split.c
+++ b/toys/posix/split.c
@@ -8,13 +8,13 @@
  * - should splitting an empty file produce an empty outfile? (Went with "no".)
  * - permissions on output file
 
-USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1n#<1[!bl][!bn][!ln]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_SPLIT(NEWTOY(split, ">2a#<1=2>9b#<1l#<1[!bl]", TOYFLAG_USR|TOYFLAG_BIN))
 
 config SPLIT
   bool "split"
   default y
   help
-    usage: split [-a SUFFIX_LEN] [-b BYTES] [-l LINES] [-n PARTS] [INPUT [OUTPUT]]
+    usage: split [-a SUFFIX_LEN] [-b BYTES] [-l LINES] [INPUT [OUTPUT]]
 
     Copy INPUT (or stdin) data to a series of OUTPUT (or "x") files with
     alphabetically increasing suffix (aa, ab, ac... az, ba, bb...).
@@ -22,14 +22,13 @@
     -a	Suffix length (default 2)
     -b	BYTES/file (10, 10k, 10m, 10g...)
     -l	LINES/file (default 1000)
-    -n	PARTS many equal length files
 */
 
 #define FOR_split
 #include "toys.h"
 
 GLOBALS(
-  long n, l, b, a;
+  long l, b, a;
 
   char *outfile;
 )
@@ -42,10 +41,8 @@
 
   // posix doesn't cover permissions on output file, so copy input (or 0777)
   st.st_mode = 0777;
-  st.st_size = 0;
   fstat(infd, &st);
 
-  if (TT.n && (TT.b = st.st_size/TT.n)<1) return error_msg("%s: no size", in);
   len = pos = filenum = bytesleft = linesleft = 0;
   for (;;) {
     int i, j;
@@ -66,7 +63,7 @@
         j /= 26;
       }
       if (j) error_exit("bad suffix");
-      bytesleft = TT.b + ((filenum == TT.n) ? st.st_size%TT.n : 0);
+      bytesleft = TT.b;
       linesleft = TT.l;
       xclose(outfd);
       outfd = xcreate(TT.outfile, O_RDWR|O_CREAT|O_TRUNC, st.st_mode & 0777);
@@ -98,7 +95,7 @@
 
 void split_main(void)
 {
-  if (!TT.b && !TT.l && !TT.n) TT.l = 1000;
+  if (!TT.b && !TT.l) TT.l = 1000;
 
   // Allocate template for output filenames
   TT.outfile = xmprintf("%s%*c", (toys.optc == 2) ? toys.optargs[1] : "x",
diff --git a/toys/posix/tail.c b/toys/posix/tail.c
index f34e10c..89ec70e 100644
--- a/toys/posix/tail.c
+++ b/toys/posix/tail.c
@@ -6,22 +6,20 @@
  *
  * Deviations from posix: -f waits for pipe/fifo on stdin (nonblock?).
 
-USE_TAIL(NEWTOY(tail, "?fFs:c(bytes)-n(lines)-[-cn][-fF]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TAIL(NEWTOY(tail, "?fc-n-[-cn]", TOYFLAG_USR|TOYFLAG_BIN))
 
 config TAIL
   bool "tail"
   default y
   help
-    usage: tail [-n|c NUMBER] [-f|F] [-s SECONDS] [FILE...]
+    usage: tail [-n|c NUMBER] [-f] [FILE...]
 
     Copy last lines from files to stdout. If no files listed, copy from
     stdin. Filename "-" is a synonym for stdin.
 
     -n	Output the last NUMBER lines (default 10), +X counts from start
     -c	Output the last NUMBER bytes, +NUMBER counts from start
-    -f	Follow FILE(s) by descriptor, waiting for more data to be appended
-    -F	Follow FILE(s) by filename, waiting for more data, and retrying
-    -s	Used with -F, sleep SECONDS between retries (default 1)
+    -f	Follow FILE(s), waiting for more data to be appended
 */
 
 #define FOR_tail
@@ -29,16 +27,9 @@
 
 GLOBALS(
   long n, c;
-  char *s;
 
-  int file_no, last_fd, ss;
+  int file_no, last_fd;
   struct xnotify *not;
-  struct {
-    char *path;
-    int fd;
-    dev_t dev;
-    ino_t ino;
-  } *F;
 )
 
 struct line_list {
@@ -132,81 +123,17 @@
   return 1;
 }
 
-// For -f and -F
-static void tail_continue()
-{
-  long long pos;
-  char *path;
-  struct stat sb;
-  int i = 0, fd, len;
-
-  for (i = 0; ; i++) {
-    if (FLAG(f)) fd = xnotify_wait(TT.not, &path);
-    else {
-      if (i == TT.file_no) {
-        i = 0;
-        msleep(TT.ss);
-      }
-      fd = TT.F[i].fd;
-      path = TT.F[i].path;
- 
-      if (stat(TT.F[i].path, &sb)) {
-        if (fd >= 0) {
-          close(fd);
-          TT.F[i].fd = -1;
-          error_msg("file inaccessible: %s\n", TT.F[i].path);
-        }
-        continue;
-      }
-
-      if (fd<0 || sb.st_dev!=TT.F[i].dev || sb.st_ino!=TT.F[i].ino) {
-        if (fd>=0) close(fd);
-        if (-1 == (TT.F[i].fd = fd = open(path, O_RDONLY))) continue;
-        error_msg("following new file: %s\n", path);
-        TT.F[i].dev = sb.st_dev;
-        TT.F[i].ino = sb.st_ino;
-      } else if (sb.st_size <= (pos = lseek(fd, 0, SEEK_CUR))) {
-        if (pos == sb.st_size) continue;
-        error_msg("file truncated: %s\n", path);
-        lseek(fd, 0, SEEK_SET);
-      }
-    }
-
-    while ((len = read(fd, toybuf, sizeof(toybuf)))>0) {
-      if (TT.file_no>1 && TT.last_fd != fd) {
-        TT.last_fd = fd;
-        xprintf("\n==> %s <==\n", path);
-      }
-      xwrite(1, toybuf, len);
-    }
-  }
-}
-
 // Called for each file listed on command line, and/or stdin
 static void do_tail(int fd, char *name)
 {
   long bytes = TT.c, lines = TT.n;
   int linepop = 1;
 
-  if (FLAG(F)) {
-    if (!fd) perror_exit("no -F with '-'");
-  } else if (fd == -1) return;
-  if (FLAG(f) || FLAG(F)) {
+  if (FLAG(f)) {
     char *s = name;
-    struct stat sb;
 
     if (!fd) sprintf(s = toybuf, "/proc/self/fd/%d", fd);
-
-    if (FLAG(f)) xnotify_add(TT.not, fd, s);
-    if (FLAG(F)) {
-      if (fd != -1) {
-        if (fstat(fd, &sb)) perror_exit("%s", name);
-        TT.F[TT.file_no].dev = sb.st_dev;
-        TT.F[TT.file_no].ino = sb.st_ino;
-      }
-      TT.F[TT.file_no].fd = fd;
-      TT.F[TT.file_no].path = s;
-    }
+    if (xnotify_add(TT.not, fd, s)) perror_exit("-f on '%s' failed", s);
   }
 
   if (TT.file_no++) xputc('\n');
@@ -290,21 +217,33 @@
   if (!FLAG(n) && !FLAG(c)) {
     char *arg = *args;
 
-    // handle old "-42" style arguments, else default to last 10 lines
+    // handle old "-42" style arguments
     if (arg && *arg == '-' && arg[1]) {
       TT.n = atolx(*(args++));
       toys.optc--;
-    } else TT.n = -10;
+    } else {
+      // if nothing specified, default -n to -10
+      TT.n = -10;
+    }
   }
 
-  if (FLAG(F)) TT.F = xzalloc(toys.optc*sizeof(*TT.F));
-  else if (FLAG(f)) TT.not = xnotify_init(toys.optc);
-  TT.ss = TT.s ? xparsemillitime(TT.s) : 1000;
+  if (FLAG(f)) TT.not = xnotify_init(toys.optc);
+  loopfiles_rw(args, O_RDONLY|WARN_ONLY|(O_CLOEXEC*!FLAG(f)), 0, do_tail);
 
-  loopfiles_rw(args,
-    O_RDONLY|WARN_ONLY|LOOPFILES_ANYWAY|(O_CLOEXEC*!(FLAG(f) || FLAG(F))),
-    0, do_tail);
+  if (FLAG(f) && TT.file_no) {
+    for (;;) {
+      char *path;
+      int fd = xnotify_wait(TT.not, &path), len;
 
-  // Wait for more data when following files
-  if (TT.file_no && (FLAG(F) || FLAG(f))) tail_continue();
+      // Read new data.
+      while ((len = read(fd, toybuf, sizeof(toybuf)))>0) {
+        if (TT.last_fd != fd) {
+          TT.last_fd = fd;
+          xprintf("\n==> %s <==\n", path);
+        }
+
+        xwrite(1, toybuf, len);
+      }
+    }
+  }
 }
diff --git a/toys/posix/tar.c b/toys/posix/tar.c
index 9cf1a5c..c4fb4fa 100644
--- a/toys/posix/tar.c
+++ b/toys/posix/tar.c
@@ -17,13 +17,13 @@
  * Why --exclude pattern but no --include? tar cvzf a.tgz dir --include '*.txt'
  *
 
-USE_TAR(NEWTOY(tar, "&(strip-components)#(selinux)(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]", TOYFLAG_USR|TOYFLAG_BIN))
+USE_TAR(NEWTOY(tar, "&(restrict)(full-time)(no-recursion)(numeric-owner)(no-same-permissions)(overwrite)(exclude)*(mode):(mtime):(group):(owner):(to-command):o(no-same-owner)p(same-permissions)k(keep-old)c(create)|h(dereference)x(extract)|t(list)|v(verbose)I(use-compress-program):J(xz)j(bzip2)z(gzip)S(sparse)O(to-stdout)P(absolute-names)m(touch)X(exclude-from)*T(files-from)*C(directory):f(file):a[!txc][!jzJa]", TOYFLAG_USR|TOYFLAG_BIN))
 
 config TAR
   bool "tar"
   default y
   help
-    usage: tar [-cxt] [-fvohmjkOS] [-XTCf NAME] [--selinux] [FILE...]
+    usage: tar [-cxt] [-fvohmjkOS] [-XTCf NAME] [FILE...]
 
     Create, extract, or list files in a .tar (or compressed t?z) file.
 
@@ -34,13 +34,13 @@
     J  xz compression        j  bzip2 compression     z  gzip compression
     O  Extract to stdout     X  exclude names in FILE T  include names in FILE
 
-    --exclude        FILENAME to exclude  --full-time         Show seconds with -tv
-    --mode MODE      Adjust permissions   --owner NAME[:UID]  Set file ownership
-    --mtime TIME     Override timestamps  --group NAME[:GID]  Set file group
-    --sparse         Record sparse files  --selinux           Save/restore labels
-    --restrict       All under one dir    --no-recursion      Skip dir contents
-    --numeric-owner  Use numeric uid/gid, not user/group names
-    --strip-components NUM  Ignore first NUM directory components when extracting
+    --exclude        FILENAME to exclude    --full-time   Show seconds with -tv
+    --mode MODE      Adjust modes           --mtime TIME  Override timestamps
+    --owner NAME     Set file owner to NAME --group NAME  Set file group to NAME
+    --sparse         Record sparse files
+    --restrict       All archive contents must extract under one subdirectory
+    --numeric-owner  Save/use/display uid and gid, not user/group name
+    --no-recursion   Don't store directory contents
     -I PROG          Filter through PROG to compress or PROG -d to decompress
 */
 
@@ -52,12 +52,11 @@
   struct arg_list *T, *X;
   char *I, *to_command, *owner, *group, *mtime, *mode;
   struct arg_list *exclude;
-  long strip_components;
 
   struct double_list *incl, *excl, *seen;
   struct string_list *dirs;
   char *cwd;
-  int fd, ouid, ggid, hlc, warn, adev, aino, sparselen, pid;
+  int fd, ouid, ggid, hlc, warn, adev, aino, sparselen;
   long long *sparse;
   time_t mtt;
 
@@ -109,10 +108,8 @@
   unsigned long long val = 0;
 
   // When tar value too big or octal, use binary encoding with high bit set
-  if (128&*str) while (--len) {
-    if (val<<8 < val) error_exit("bad header");
-    val = (val<<8)+*++str;
-  } else {
+  if (128&*str) while (--len) val = (val<<8)+*++str;
+  else {
     while (len && *str == ' ') str++;
     while (len && *str>='0' && *str<='7') val = val*8+*str++-'0', len--;
     if (len && *str && *str != ' ') error_exit("bad header");
@@ -122,15 +119,16 @@
 }
 #define OTOI(x) otoi(x, sizeof(x))
 
-static void write_prefix_block(char *data, int len, char type)
+static void write_longname(char *name, char type)
 {
   struct tar_hdr tmp;
+  int sz = strlen(name) +1;
 
   memset(&tmp, 0, sizeof(tmp));
-  sprintf(tmp.name, "././@%s", type=='x' ? "PaxHeaders" : "LongLink");
+  strcpy(tmp.name, "././@LongLink");
   ITOO(tmp.uid, 0);
   ITOO(tmp.gid, 0);
-  ITOO(tmp.size, len);
+  ITOO(tmp.size, sz);
   ITOO(tmp.mtime, 0);
   tmp.type = type;
   strcpy(tmp.magic, "ustar  ");
@@ -147,15 +145,8 @@
 
   // write header and name, padded with NUL to block size
   xwrite(TT.fd, &tmp, 512);
-  xwrite(TT.fd, data, len);
-  if (len%512) xwrite(TT.fd, toybuf, 512-(len%512));
-}
-
-static void maybe_prefix_block(char *data, int check, int type)
-{
-  int len = strlen(data);
-
-  if (len>check) write_prefix_block(data, len+1, type);
+  xwrite(TT.fd, name, sz);
+  if (sz%512) xwrite(TT.fd, toybuf, 512-(sz%512));
 }
 
 static struct double_list *filter(struct double_list *lst, char *name)
@@ -226,17 +217,13 @@
     if (!(lnk = strstr(lnk, ".."))) break;
     if (lnk == hname || lnk[-1] == '/') {
       if (!lnk[2]) goto done;
-      if (lnk[2]=='/') {
-        lnk = hname = lnk+3;
-        continue;
-      }
-    }
-    lnk += 2;
+      if (lnk[2]=='/') lnk = hname = lnk+3;
+    } else lnk+= 2;
   }
   if (!*hname) goto done;
 
   if (TT.warn && hname != name) {
-    dprintf(2, "removing leading '%.*s' from member names\n",
+    fprintf(stderr, "removing leading '%.*s' from member names\n",
            (int)(hname-name), name);
     TT.warn = 0;
   }
@@ -286,7 +273,7 @@
       perror_msg("readlink");
       goto done;
     }
-    maybe_prefix_block(lnk, sizeof(hdr.link), 'K');
+    if (strlen(lnk) > sizeof(hdr.link)) write_longname(lnk, 'K');
     strncpy(hdr.link, lnk, sizeof(hdr.link));
     if (!i) free(lnk);
   } else if (S_ISREG(st->st_mode)) {
@@ -303,44 +290,15 @@
     goto done;
   }
 
-  // write out 'x' prefix header for --selinux data
-  if (FLAG(selinux)) {
-    int start = 0, sz = 0, temp, len = 0;
-    char *buf = 0, *sec = "security.selinux";
+  if (strlen(hname) > sizeof(hdr.name)) write_longname(hname, 'L');
 
-    for (;;) {
-      // First time get length, second time read data into prepared buffer
-      len = (S_ISLNK(st->st_mode) ? xattr_lget : xattr_get)
-        (name, sec, buf+start, sz);
-
-      // Handle data or error
-      if (len>999999 || (sz && len>sz)) len = -1, errno = E2BIG;
-      if (buf || len<1) {
-        if (len>0) {
-          strcpy(buf+start+sz, "\n");
-          write_prefix_block(buf, start+sz+2, 'x');
-        } else if (errno==ENODATA || errno==ENOTSUP) len = 0;
-        if (len) perror_msg("getfilecon %s", name);
-
-        free(buf);
-        break;
-      }
-
-      // Allocate buffer. Length includes prefix: calculate twice (wrap 99->100)
-      temp = snprintf(0, 0, "%d", sz = (start = 22)+len+1);
-      start += temp + (temp != snprintf(0, 0, "%d", temp+sz));
-      buf = xmprintf("%u RHT.%s=%.*s", start+len+1, sec, sz = len, "");
-    }
-  }
-
-  maybe_prefix_block(hname, sizeof(hdr.name), 'L');
   if (!FLAG(numeric_owner)) {
     if ((TT.owner || (pw = bufgetpwuid(st->st_uid))) &&
         ascii_fits(st->st_uid, sizeof(hdr.uid)))
-      strncpy(hdr.uname, TT.owner ? : pw->pw_name, sizeof(hdr.uname));
+      strncpy(hdr.uname, TT.owner ? TT.owner : pw->pw_name, sizeof(hdr.uname));
     if ((TT.group || (gr = bufgetgrgid(st->st_gid))) &&
         ascii_fits(st->st_gid, sizeof(hdr.gid)))
-      strncpy(hdr.gname, TT.group ? : gr->gr_name, sizeof(hdr.gname));
+      strncpy(hdr.gname, TT.group ? TT.group : gr->gr_name, sizeof(hdr.gname));
   }
 
   TT.sparselen = 0;
@@ -387,7 +345,7 @@
   itoo(hdr.chksum, sizeof(hdr.chksum)-1, tar_cksum(&hdr));
   hdr.chksum[7] = ' ';
 
-  if (FLAG(v)) dprintf(1+(TT.fd==1), "%s\n", hname);
+  if (FLAG(v)) dprintf((TT.fd==1) ? 2 : 1, "%s\n", hname);
 
   // Write header and data to archive
   xwrite(TT.fd, &hdr, 512);
@@ -441,7 +399,7 @@
 
   // Barf if name not in TT.cwd
   if (name) {
-    if (!(ss = s = xabspath(name, isdir ? ABS_LAST : 0))) {
+    if (!(ss = s = xabspath(name, -1-isdir))) {
       error_msg("'%s' bad symlink", name);
 
       return 1;
@@ -521,15 +479,7 @@
 static void extract_to_disk(void)
 {
   char *name = TT.hdr.name;
-  int ala = TT.hdr.mode, strip;
-
-  for (strip = 0; strip < TT.strip_components; strip++) {
-    char *s = strchr(name, '/');
-
-    if (s && s[1]) name = s+1;
-    else if (S_ISDIR(ala)) return;
-    else break;
-  }
+  int ala = TT.hdr.mode;
 
   if (dirflush(name, S_ISDIR(ala))) {
     if (S_ISREG(ala) && !TT.hdr.link_target) skippy(TT.hdr.size);
@@ -542,8 +492,10 @@
       return perror_msg(":%s: can't mkdir", name);
 
   // remove old file, if exists
-  if (!FLAG(k) && !S_ISDIR(ala) && rmdir(name) && errno!=ENOENT && unlink(name))
-    return perror_msg("can't remove: %s", name);
+  if (!FLAG(k) && !S_ISDIR(ala) && unlink(name)) {
+    if (errno==EISDIR && !rmdir(name));
+    else if (errno!=ENOENT) return perror_msg("can't remove: %s", name);
+  }
 
   if (S_ISREG(ala)) {
     // hardlink?
@@ -552,16 +504,17 @@
         return perror_msg("can't link '%s' -> '%s'", name, TT.hdr.link_target);
     // write contents
     } else {
-      int fd = WARN_ONLY|O_WRONLY|O_CREAT|(FLAG(overwrite) ? O_TRUNC : O_EXCL);
-
-      if ((fd = xcreate(name, fd, ala&07777)) != -1) sendfile_sparse(fd);
-      else return skippy(TT.hdr.size);
+      int fd = xcreate(name,
+        WARN_ONLY|O_WRONLY|O_CREAT|(FLAG(overwrite)?O_TRUNC:O_EXCL),
+        ala & 07777);
+      if (fd != -1) sendfile_sparse(fd);
+      else skippy(TT.hdr.size);
     }
   } else if (S_ISDIR(ala)) {
     if ((mkdir(name, 0700) == -1) && errno != EEXIST)
-      return perror_msg("%s: can't create", name);
+      return perror_msg("%s: can't create", TT.hdr.name);
   } else if (S_ISLNK(ala)) {
-    if (symlink(TT.hdr.link_target, name))
+    if (symlink(TT.hdr.link_target, TT.hdr.name))
       return perror_msg("can't link '%s' -> '%s'", name, TT.hdr.link_target);
   } else if (mknod(name, ala, TT.hdr.device))
     return perror_msg("can't create '%s'", name);
@@ -572,20 +525,20 @@
 
     if (TT.owner) TT.hdr.uid = TT.ouid;
     else if (!FLAG(numeric_owner) && *TT.hdr.uname) {
-      struct passwd *pw = bufgetpwnamuid(TT.hdr.uname, 0);
+      struct passwd *pw = getpwnam(TT.hdr.uname);
       if (pw && (TT.owner || !FLAG(numeric_owner))) TT.hdr.uid = pw->pw_uid;
     }
 
     if (TT.group) TT.hdr.gid = TT.ggid;
     else if (!FLAG(numeric_owner) && *TT.hdr.uname) {
-      struct group *gr = bufgetgrnamgid(TT.hdr.gname, 0);
+      struct group *gr = getgrnam(TT.hdr.gname);
       if (gr) TT.hdr.gid = gr->gr_gid;
     }
 
     if (lchown(name, u, g)) perror_msg("chown %d:%d '%s'", u, g, name);;
   }
 
-  if (!S_ISLNK(ala)) chmod(name, FLAG(p) ? ala : ala&0777);
+  if (!S_ISLNK(ala)) chmod(TT.hdr.name, FLAG(p) ? ala : ala&0777);
 
   // Apply mtime.
   if (!FLAG(m)) {
@@ -600,7 +553,7 @@
       strcpy(sl->str+sizeof(long long), name);
       sl->next = TT.dirs;
       TT.dirs = sl;
-    } else wsettime(name, TT.hdr.mtime);
+    } else wsettime(TT.hdr.name, TT.hdr.mtime);
   }
 }
 
@@ -608,7 +561,7 @@
 {
   struct double_list *walk, *delete;
   struct tar_hdr tar;
-  int i, sefd = -1, and = 0;
+  int i, and = 0;
   unsigned maj, min;
   char *s;
 
@@ -641,54 +594,43 @@
     if ((tar.type<'0' || tar.type>'7') && tar.type!='S'
         && (*tar.magic && tar.type))
     {
-      // Skip to next record if unknown type or payload > 1 megabyte
-      if (!strchr("KLx", tar.type) || TT.hdr.size>1<<20) skippy(TT.hdr.size);
-      // Read link or long name
-      else if (tar.type != 'x')
-        alloread(tar.type=='K'?&TT.hdr.link_target:&TT.hdr.name, TT.hdr.size);
-      // Loop through 'x' payload records in "LEN NAME=VALUE\n" format
-      else {
-        char *p, *pp, *buf = 0;
-        unsigned i, len, n;
+      // Long name extension header?
+      if (tar.type == 'K') alloread(&TT.hdr.link_target, TT.hdr.size);
+      else if (tar.type == 'L') alloread(&TT.hdr.name, TT.hdr.size);
+      else if (tar.type == 'x') {
+        char *p, *buf = 0;
+        int i, len, n = 0;
 
+        // Posix extended record "LEN NAME=VALUE\n" format
         alloread(&buf, TT.hdr.size);
         for (p = buf; (p-buf)<TT.hdr.size; p += len) {
-          i = TT.hdr.size-(p-buf);
-          if (1!=sscanf(p, "%u %n", &len, &n) || len<n+4 || len>i || n>i) {
+          i = sscanf(p, "%u path=%n", &len, &n);
+          if (i<1 || len<4 || len>TT.hdr.size) {
             error_msg("bad header");
             break;
           }
           p[len-1] = 0;
-          pp = p+n;
-          // Ignore "RHT." prefix, if any.
-          strstart(&pp, "RHT.");
-          if ((FLAG(selinux) && !(FLAG(t)|FLAG(O)))
-              && strstart(&pp, "security.selinux="))
-          {
-            i = strlen(pp);
-            sefd = xopen("/proc/self/attr/fscreate", O_WRONLY|WARN_ONLY);
-            if (sefd==-1 ||  i!=write(sefd, pp, i))
-              perror_msg("setfscreatecon %s", pp);
-          } else if (strstart(&pp, "path=")) {
-            free(TT.hdr.name);
-            TT.hdr.name = xstrdup(pp);
+          if (n) {
+            TT.hdr.name = xstrdup(p+n);
             break;
           }
         }
         free(buf);
-      }
+
+      // Ignore everything else.
+      } else skippy(TT.hdr.size);
 
       continue;
     }
 
     // Handle sparse file type
-    TT.sparselen = 0;
     if (tar.type == 'S') {
       char sparse[512];
       int max = 8;
 
       // Load 4 pairs of offset/len from S block, plus 21 pairs from each
       // continuation block, list says where to seek/write sparse file contents
+      TT.sparselen = 0;
       s = 386+(char *)&tar;
       *sparse = i = 0;
 
@@ -712,7 +654,10 @@
       TT.sparselen /= 2;
       if (TT.sparselen)
         TT.hdr.ssize = TT.sparse[2*TT.sparselen-1]+TT.sparse[2*TT.sparselen-2];
-    } else TT.hdr.ssize = TT.hdr.size;
+    } else {
+      TT.sparselen = 0;
+      TT.hdr.ssize = TT.hdr.size;
+    }
 
     // At this point, we have something to output. Convert metadata.
     TT.hdr.mode = OTOI(tar.mode)&0xfff;
@@ -724,18 +669,18 @@
     maj = OTOI(tar.major);
     min = OTOI(tar.minor);
     TT.hdr.device = dev_makedev(maj, min);
-    TT.hdr.uname = xstrndup(TT.owner ? : tar.uname, sizeof(tar.uname));
-    TT.hdr.gname = xstrndup(TT.group ? : tar.gname, sizeof(tar.gname));
+    TT.hdr.uname = xstrndup(TT.owner ? TT.owner : tar.uname, sizeof(tar.uname));
+    TT.hdr.gname = xstrndup(TT.group ? TT.group : tar.gname, sizeof(tar.gname));
 
     if (TT.owner) TT.hdr.uid = TT.ouid;
     else if (!FLAG(numeric_owner)) {
-      struct passwd *pw = bufgetpwnamuid(TT.hdr.uname, 0);
+      struct passwd *pw = getpwnam(TT.hdr.uname);
       if (pw && (TT.owner || !FLAG(numeric_owner))) TT.hdr.uid = pw->pw_uid;
     }
 
     if (TT.group) TT.hdr.gid = TT.ggid;
     else if (!FLAG(numeric_owner)) {
-      struct group *gr = bufgetgrnamgid(TT.hdr.gname, 0);
+      struct group *gr = getgrnam(TT.hdr.gname);
       if (gr) TT.hdr.gid = gr->gr_gid;
     }
 
@@ -826,12 +771,6 @@
       } else extract_to_disk();
     }
 
-    if (sefd != -1) {
-      // zero length write resets fscreate context to default
-      (void)write(sefd, 0, 0);
-      close(sefd);
-      sefd = -1;
-    }
     free(TT.hdr.name);
     free(TT.hdr.link_target);
     free(TT.hdr.uname);
@@ -869,20 +808,8 @@
 
   // Get possible early errors out of the way
   if (!geteuid()) toys.optflags |= FLAG_p;
-  if (TT.owner) {
-    if (!(s = strchr(TT.owner, ':'))) TT.ouid = xgetuid(TT.owner);
-    else {
-      TT.owner = xstrndup(TT.owner, s++-TT.owner);
-      TT.ouid = atolx_range(s, 0, INT_MAX);
-    }
-  }
-  if (TT.group) {
-    if (!(s = strchr(TT.group, ':'))) TT.ggid = xgetgid(TT.group);
-    else {
-      TT.group = xstrndup(TT.group, s++-TT.group);
-      TT.ggid = atolx_range(s, 0, INT_MAX);
-    }
-  }
+  if (TT.owner) TT.ouid = xgetuid(TT.owner);
+  if (TT.group) TT.ggid = xgetgid(TT.group);
   if (TT.mtime) xparsedate(TT.mtime, &TT.mtt, (void *)&s, 1);
 
   // Collect file list.
@@ -907,7 +834,7 @@
   }
 
   // Get destination directory
-  TT.cwd = xabspath(s = xgetcwd(), ABS_PATH);
+  TT.cwd = xabspath(s = xgetcwd(), 1);
   free(s);
 
   // Remember archive inode so we don't overwrite it or add it to itself
@@ -945,7 +872,7 @@
         FLAG(j) ? "bzcat" : FLAG(J) ? "xzcat" : "zcat");
 
       // Toybox provides more decompressors than compressors, so try them first
-      TT.pid = xpopen_both(zcat ? (char *[]){zcat->str, 0} :
+      xpopen_both(zcat ? (char *[]){zcat->str, 0} :
         (char *[]){archiver, "-d", 0}, pipefd);
       if (CFG_TOYBOX_FREE) llist_traverse(zcat, free);
 
@@ -986,8 +913,6 @@
 
     unpack_tar(hdr);
     dirflush(0, 0);
-    // Shut up archiver about inability to write all trailing NULs to pipe buf
-    if (TT.pid>0) kill(TT.pid, 9);
 
     // Each time a TT.incl entry is seen it's moved to the end of the list,
     // with TT.seen pointing to first seen list entry. Anything between
@@ -1024,12 +949,11 @@
     }
     do {
       TT.warn = 1;
-      dirtree_flagread(dl->data, FLAG(h) ? DIRTREE_SYMFOLLOW : 0, add_to_tar);
+      dirtree_flagread(dl->data, FLAG(h)?DIRTREE_SYMFOLLOW:0, add_to_tar);
     } while (TT.incl != (dl = dl->next));
 
     writeall(TT.fd, toybuf, 1024);
   }
-  if (toys.exitval) error_msg("had errors");
 
   if (CFG_TOYBOX_FREE) {
     llist_traverse(TT.excl, llist_free_double);
diff --git a/toys/posix/time.c b/toys/posix/time.c
index 1becad1..d99d2db 100644
--- a/toys/posix/time.c
+++ b/toys/posix/time.c
@@ -4,11 +4,12 @@
  *
  * See http://pubs.opengroup.org/onlinepubs/9699919799/utilities/time.html
 
-USE_TIME(NEWTOY(time, "<1^pv[-pv]", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
+USE_TIME(NEWTOY(time, "<1^pv", TOYFLAG_USR|TOYFLAG_BIN|TOYFLAG_MAYFORK))
 
 config TIME
   bool "time"
   default y
+  depends on TOYBOX_FLOAT
   help
     usage: time [-pv] COMMAND...
 
@@ -16,45 +17,41 @@
     (real = clock on the wall, user = cpu used by command's code,
     system = cpu used by OS on behalf of command.)
 
-    -p	POSIX format output
+    -p	POSIX format output (default)
     -v	Verbose
 */
 
 #define FOR_time
 #include "toys.h"
 
-
 void time_main(void)
 {
-  struct timespec ts, ts2;
-  struct rusage ru;
-  long long sec[3];
-  int stat, ii, idx, nano[3];
   pid_t pid;
-  char *labels[] = {"\nreal"+!!FLAG(p), "user", "sys"}, **label = labels,
-       *vlabels[] ={"Real", "User", "System"}, tab = toys.optflags ? ' ' : '\t';
+  struct timeval tv, tv2;
 
-  if (FLAG(v)) label = vlabels;
-  clock_gettime(CLOCK_MONOTONIC, &ts);
+  gettimeofday(&tv, NULL);
   if (!(pid = XVFORK())) xexec(toys.optargs);
-  wait4(pid, &stat, 0, &ru);
-  clock_gettime(CLOCK_MONOTONIC, &ts2);
-  sec[0] = nanodiff(&ts, &ts2);
-  nano[0] = (sec[0] % 1000000000)/(toys.optflags ? 1000 : 1000000);
-  sec[0] /= 1000000000;
-  sec[1] = ru.ru_utime.tv_sec, nano[1] = ru.ru_utime.tv_usec;
-  sec[2] = ru.ru_stime.tv_sec, nano[2] = ru.ru_stime.tv_usec;
-  for (ii = idx = 0; ii<3; ii++)
-    idx += sprintf(toybuf+idx, "%s%s%c%lld.%0*d\n", label[ii],
-                   FLAG(v) ? " time (s):" : "", tab, sec[ii],
-                   6>>!toys.optflags, nano[ii]);
-  if (FLAG(v)) idx += sprintf(toybuf+idx,
-    "Max RSS (KiB): %ld\nMajor faults: %ld\n"
-    "Minor faults: %ld\nFile system inputs: %ld\nFile system outputs: %ld\n"
-    "Voluntary context switches: %ld\nInvoluntary context switches: %ld\n",
-    ru.ru_maxrss, ru.ru_majflt, ru.ru_minflt, ru.ru_inblock,
-    ru.ru_oublock, ru.ru_nvcsw, ru.ru_nivcsw);
-  writeall(2, toybuf, idx);
+  else {
+    int stat;
+    struct rusage ru;
+    float r, u, s;
 
-  toys.exitval = WIFEXITED(stat) ? WEXITSTATUS(stat) : WTERMSIG(stat);
+    wait4(pid, &stat, 0, &ru);
+    gettimeofday(&tv2, NULL);
+    if (tv.tv_usec > tv2.tv_usec) {
+      tv2.tv_usec += 1000000;
+      tv2.tv_sec--;
+    }
+    r = (tv2.tv_sec-tv.tv_sec)+((tv2.tv_usec-tv.tv_usec)/1000000.0);
+    u = ru.ru_utime.tv_sec+(ru.ru_utime.tv_usec/1000000.0);
+    s = ru.ru_stime.tv_sec+(ru.ru_stime.tv_usec/1000000.0);
+    if (FLAG(v)) fprintf(stderr, "Real time (s): %f\nSystem time (s): %f\n"
+      "User time (s): %f\nMax RSS (KiB): %ld\nMajor faults: %ld\n"
+      "Minor faults: %ld\nFile system inputs: %ld\nFile system outputs: %ld\n"
+      "Voluntary context switches: %ld\nInvoluntary context switches: %ld\n",
+      r, s, u, ru.ru_maxrss, ru.ru_majflt, ru.ru_minflt, ru.ru_inblock,
+      ru.ru_oublock, ru.ru_nvcsw, ru.ru_nivcsw);
+    else fprintf(stderr, "real %f\nuser %f\nsys %f\n", r, u, s);
+    toys.exitval = WIFEXITED(stat) ? WEXITSTATUS(stat) : WTERMSIG(stat);
+  }
 }
diff --git a/toys/posix/tty.c b/toys/posix/tty.c
index 6116f13..9a833d5 100644
--- a/toys/posix/tty.c
+++ b/toys/posix/tty.c
@@ -12,8 +12,10 @@
   help
     usage: tty [-s]
 
-    Show filename of terminal connected to stdin. If none print "not a tty"
-    and exit with nonzero status.
+    Show filename of terminal connected to stdin.
+
+    Prints "not a tty" and exits with nonzero status if no terminal
+    is connected to stdin.
 
     -s	Silent, exit code only
 */
@@ -24,6 +26,7 @@
 {
   char *tty = ttyname(0);
 
+  if (!toys.optflags) puts(tty ? tty : "not a tty");
+
   toys.exitval = !tty;
-  if (!toys.optflags) puts(tty ? : "not a tty");
 }
diff --git a/toys/posix/uname.c b/toys/posix/uname.c
index fe44ced..d93fc7a 100644
--- a/toys/posix/uname.c
+++ b/toys/posix/uname.c
@@ -4,9 +4,8 @@
  *
  * See http://opengroup.org/onlinepubs/9699919799/utilities/uname.html
 
-USE_UNAME(NEWTOY(uname, "aomvrns", TOYFLAG_BIN))
+USE_UNAME(NEWTOY(uname, "oamvrns[+os]", TOYFLAG_BIN))
 USE_ARCH(NEWTOY(arch, 0, TOYFLAG_USR|TOYFLAG_BIN))
-USE_LINUX32(NEWTOY(linux32, 0, TOYFLAG_USR|TOYFLAG_BIN))
 
 config ARCH 
   bool "arch"
@@ -16,14 +15,6 @@
 
     Print machine (hardware) name, same as uname -m.
 
-config LINUX32
-  bool "linux32"
-  default y
-  help
-    usage: linux32 [COMMAND...]
-
-    Tell uname -m to line to autoconf (to build 32 bit binaries on 64 bit kernel).
-
 config UNAME
   bool "uname"
   default y
@@ -37,30 +28,59 @@
     -r	Kernel Release number
     -v	Kernel Version 
     -m	Machine (hardware) name
-    -o	Userspace type
-    -a	All of the above (in order)
+    -a	All of the above
 */
 
 #define FOR_uname
 #define FORCE_FLAGS
 #include "toys.h"
 
+// If a 32 bit x86 build environment working in a chroot under an x86-64
+// kernel returns x86_64 for -m it confuses ./configure.  Special case it.
+
+#if defined(__i686__)
+#define GROSS "i686"
+#elif defined(__i586__)
+#define GROSS "i586"
+#elif defined(__i486__)
+#define GROSS "i486"
+#elif defined(__i386__)
+#define GROSS "i386"
+#endif
+
 void uname_main(void)
 {
-  int i, needspace = 0;
-  char *c;
+  int i, flags = toys.optflags, needspace=0;
+  struct utsname u;
 
-  uname((void *)toybuf);
-  if (!toys.optflags) toys.optflags = FLAG_s;
-  for (i=0; i<6; i++) if (toys.optflags & ((1<<i)|FLAG_a)) {
-    if (i==5) c = " Toybox"+!needspace;
-    else {
-      c = toybuf+sizeof(((struct utsname *)0)->sysname)*i;
-      if (needspace++) *(--c)=' '; // Can't decrement first entry
+  uname(&u);
+
+  if (!flags) flags = FLAG_s;
+  for (i=0; i<5; i++) {
+    char *c = ((char *) &u)+(sizeof(u.sysname)*i);
+
+    if (flags & ((1<<i)|FLAG_a)) {
+      int len = strlen(c);
+
+      // This problem originates in autoconf, so of course the solution
+      // is horribly ugly.
+#ifdef GROSS
+      if (i==4 && !strcmp(c,"x86_64")) {
+        printf(GROSS);
+        continue;
+      }
+#endif
+
+      if (needspace++) {
+        // We can't decrement on the first entry, because
+        // needspace would be 0
+        *(--c)=' ';
+        len++;
+      }
+      xwrite(1, c, len);
     }
-    xputsn(c);
   }
-  xputc('\n');
+  putchar('\n');
 }
 
 void arch_main(void)
@@ -68,9 +88,3 @@
   toys.optflags = FLAG_m;
   uname_main();
 }
-
-void linux32_main(void)
-{
-  personality(PER_LINUX32);
-  xexec(toys.optc ? toys.optargs : (char *[]){"/bin/sh", 0});
-}
diff --git a/toys/posix/uudecode.c b/toys/posix/uudecode.c
index 43f8861..4d87ce1 100644
--- a/toys/posix/uudecode.c
+++ b/toys/posix/uudecode.c
@@ -27,7 +27,7 @@
 void uudecode_main(void)
 {
   FILE *ifp = stdin;
-  int ofd, idx = 0, m QUIET, n;
+  int ofd, idx = 0, m = m, n;
   size_t allocated_length;
   char *line = 0, mode[16],
        *class[] = {"begin%*[ ]%15s%*[ ]%n", "begin-base64%*[ ]%15s%*[ ]%n"};
diff --git a/toys/posix/wc.c b/toys/posix/wc.c
index 118e775..910e469 100644
--- a/toys/posix/wc.c
+++ b/toys/posix/wc.c
@@ -74,7 +74,6 @@
 
   for (;;) {
     int pos, done = 0, len2 = read(fd, toybuf+len, sizeof(toybuf)-len);
-    unsigned wchar;
 
     if (len2<0) perror_msg_raw(name);
     else len += len2;
@@ -86,6 +85,8 @@
       if (FLAG(m)) {
         // If we've consumed next wide char
         if (--clen<1) {
+          wchar_t wchar;
+
           // next wide size, don't count invalid, fetch more data if necessary
           clen = utf8towc(&wchar, toybuf+pos, len-pos);
           if (clen == -1) continue;
diff --git a/www/.htaccess b/www/.htaccess
deleted file mode 100644
index d687228..0000000
--- a/www/.htaccess
+++ /dev/null
@@ -1 +0,0 @@
-Xbithack on
diff --git a/www/about.html b/www/about.html
index cb37e4f..0c8637e 100755
--- a/www/about.html
+++ b/www/about.html
@@ -16,7 +16,7 @@
 (<a href=http://landley.net/talks/celf-2013.txt>outline</a>,
 <a href=https://www.youtube.com/watch?v=SGmtP5Lg_t0>video</a>), Google
 <a href=https://lwn.net/Articles/629362/>merged toybox into AOSP</a> and
-began shipping toybox in Android Marshmallow in 2015.</p>
+began shipping toybox in Android Mashmallow.</p>
 
 <p>Toybox aims to provide one quarter of a theoretical "minimal native
 development environment", which is the simplest Linux system capable of
diff --git a/www/code.html b/www/code.html
index 6cbaf7d..25a1819 100644
--- a/www/code.html
+++ b/www/code.html
@@ -241,13 +241,7 @@
 NEWTOY(), the first few global variables will be initialized by the automatic
 argument parsing logic, and the type and order of these variables must
 correspond to the arguments specified in NEWTOY().
-(See <a href="#lib_args">lib/args.c</a> for details.)</p>
-
-<blockquote><p>NOTE: the GLOBALS() block creates a "this.filename" entry
-in generated/globals.h. If your toys/*/filename.c does not match the first
-command name, you'll need to "#define TT this.filename" yourself before
-#including toys.h if you want to use TT globals</p></blockquote>
-</li>
+(See <a href="#lib_args">lib/args.c</a> for details.)</p></li>
 
 <li><p>Rename hello_main() to yourcommand_main().  This is the main() function
 where execution of your command starts. Your command line options are
diff --git a/www/design.html b/www/design.html
index 014437c..e651913 100644
--- a/www/design.html
+++ b/www/design.html
@@ -1,29 +1,25 @@
 <html><head><title>The design of toybox</title></head>
 <!--#include file="header.html" -->
 
-<h2>Topics</h2>
-<ul>
-<li><a href=#goals><h3>Design Goals</h3></a></li>
-<li><a href=#portability><h3>Portability Issues</h3></a></li>
-<li><a href=#license><h3>License</a></h3></a></li>
-<li><a href=#codestyle><h3>Coding Style</h3></a></li>
-</ul>
-<hr />
-
 <a name="goals"><b><h2><a href="#goals">Design goals</a></h2></b>
 
 <p>Toybox should be simple, small, fast, and full featured. In that order.</p>
 
-<p>It should be possible to get about <a href=https://en.wikipedia.org/wiki/Pareto_principle>80% of the way</a> to each goal
-before they really start to fight.
-When these goals need to be balanced off against each other, keeping the code
+<p>When these goals need to be balanced off against each other, keeping the code
 as simple as it can be to do what it does is the most important (and hardest)
 goal. Then keeping it small is slightly more important than making it fast.
 Features are the reason we write code in the first place but this has all
 been implemented before so if we can't do a better job why bother?</p>
 
+<p>It should be possible to get 80% of the way to each goal
+before they really start to fight. Here they are in reverse order
+of importance:</p>
+
 <b><h3>Features</h3></b>
 
+<p>These days toybox is the command line of Android, so anything the android
+guys say to do gets at the very least closely listened to.</p>
+
 <p>Toybox should provide the command line utilities of a build
 environment capable of recompiling itself under itself from source code.
 This minimal build system conceptually consists of 4 parts: toybox,
@@ -38,20 +34,18 @@
 should be solved by toybox including the missing dependencies itself
 (see "Shared Libraries" below).</p>
 
-<p>Toybox may also provide some "convenience" utilties
+<p>Finally, toybox may provide some "convenience" utilties
 like top and vi that aren't necessarily used in a build but which turn
 the minimal build environment into a minimal development environment
 (supporting edit/compile/test cycles in a text console), configure
 network infrastructure for communication with other systems (in a build
 cluster), and so on.</p>
 
-<p>And these days toybox is the command line of Android, so anything the android
-guys say to do gets at the very least closely listened to.</p>
-
-<p>The hard part is deciding what NOT to include. A project without boundaries
-will bloat itself to death. One of the hardest but most important things a
-project must do is draw a line and say "no, this is somebody else's problem,
-not something we should do."
+<p>The hard part is deciding what NOT to include.
+A project without boundaries will bloat itself
+to death. One of the hardest but most important things a project must
+do is draw a line and say "no, this is somebody else's problem, not
+something we should do."
 Some things are simply outside the scope of the project: even though
 posix defines commands for compiling and linking, we're not going to include
 a compiler or linker (and support for a potentially infinite number of hardware
@@ -74,10 +68,7 @@
 
 <b><h3>Speed</h3></b>
 
-<p>Quick smoketest: use the "time" command, and if you haven't got a test
-case that's embarassing enough to motivate digging, move on.</p>
-
-<p>It's easy to say a lot about optimizing for speed (which is why this section
+<p>It's easy to say lots about optimizing for speed (which is why this section
 is so long), but at the same time it's the optimization we care the least about.
 The essence of speed is being as efficient as possible, which means doing as
 little work as possible.  A design that's small and simple gets you 90% of the
@@ -86,17 +77,16 @@
 advice:</p>
 
 <p>First, understand the darn problem you're trying to solve.  You'd think
-I wouldn't have to say this, and yet.  Trying to find a faster sorting
+I wouldn't have to say this, but I do.  Trying to find a faster sorting
 algorithm is no substitute for figuring out a way to skip the sorting step
 entirely.  The fastest way to do anything is not to have to do it at all,
 and _all_ optimization boils down to avoiding unnecessary work.</p>
 
-<p>Speed is easy to measure; there are dozens of profiling tools for Linux,
-but sticking in calls to "millitime()" out of lib.c and subtracting
-(or doing two clock_gettime() calls and then nanodiff() on them) is
-quick and easy. Don't waste too much time trying to optimize something you
-can't measure, and there's no much point speeding up things you don't spend
-much time doing anyway.</p>
+<p>Speed is easy to measure; there are dozens of profiling tools for Linux
+(although personally I find the "time" command a good starting place).
+Don't waste too much time trying to optimize something you can't measure,
+and there's no much point speeding up things you don't spend much time doing
+anyway.</p>
 
 <p>Understand the difference between throughput and latency.  Faster
 processors improve throughput, but don't always do much for latency.
@@ -108,12 +98,6 @@
 of speed unless you are in the middle of a tight loop that's you've already
 proven isn't running fast enough.)</p>
 
-<p>The lowest hanging optimization fruit is usually either "don't make
-unnecessary copies of data" or "use a reasonable block size in your
-I/O transactions instead of byte-at-a-time".
-Start by looking for those, most of the rest of this advice is just explaining
-why they're bad.</p>
-
 <p>"Locality of reference" is generally nice, in all sorts of contexts.
 It's obvious that waiting for disk access is 1000x slower than doing stuff in
 RAM (and making the disk seek is 10x slower than sequential reads/writes),
@@ -163,7 +147,7 @@
 entire OS freezing solid).  Modern operating systems seldom run out of
 memory gracefully.</p>
 
-<p>It's usually better to be simple than clever. Many people think that mmap()
+<p>Also, it's better to be simple than clever.  Many people think that mmap()
 is faster than read() because it avoids a copy, but twiddling with the memory
 management is itself slow, and can cause unnecessary CPU cache flushes.  And
 if a read faults in dozens of pages sequentially, but your mmap iterates
@@ -176,7 +160,7 @@
 things up rather than made them worse.  (And understanding what's really going
 on underneath is a big help to making it happen faster.)</p>
 
-<p>Another reason to be simple than clever is optimization
+<p>In general, being simple is better than being clever.  Optimization
 strategies change with time.  For example, decades ago precalculating a table
 of results (for things like isdigit() or cosine(int degrees)) was clearly
 faster because processors were so slow.  Then processors got faster and grew
@@ -185,108 +169,54 @@
 had to go out to DRAM).  Then cache sizes got bigger (the Pentium M has
 2 megabytes of L2 cache) and the table fit in cache, so the table became
 fast again...  Predicting how changes in hardware will affect your algorithm
-is difficult, and using ten year old optimization advice can produce
-laughably bad results.  Being simple and efficient should give at least a
-reasonable starting point.</p>
-
-<p>Even at the design level, a lot of simple algorithms scale terribly but
-perform fine with small data sets. When small datasets are the common case,
-"better" versions that trade higher throughput for worse latency can
-consistently perform worse.
-So if you think you're only ever going to feed the algorithm small data sets,
-maybe just do the simple thing and wait for somebody to complain. For example,
-you probably don't need to sort and binary search the contents of
-/etc/passwd, because even 50k users is still a reasonably manageable data
-set for a readline/strcmp loop, and that's the userbase of a fairly major
-<a href=https://en.wikipedia.org/wiki/List_of_United_States_public_university_campuses_by_enrollment>university</a>.
-Instead commands like "ls" call bufgetpwuid() out of lib/lib.c
-which keeps a linked list of recently seen items, avoiding reparsing entirely
-and trusting locality of reference to bring up the same dozen or so entries
-for "ls -l /dev" or similar. The pathological failure mode of "simple
-linked list" is to perform exactly as badly as constantly rescanning a
-huge /etc/passwd, so this simple optimization shouldn't ever make performance
-worse (modulo possible memory exhaustion and thus swap thrashing).
-On the other hand, toybox's multiplexer does sort and binary
-search its command list to minimize the latency of each command startup,
-because the sort is a compile-time cost done once per build,
-and the whole of command startup
-is a "hot path" that should do as little work as possible because EVERY
-command has to go through it every time before performing any other function
-so tiny gains are worthwhile. (These decisions aren't perfect, the point is
-to show that thought went into them.)</p>
+is difficult, and using ten year old optimization advice and produce
+laughably bad results.  But being simple and efficient is always going to
+give at least a reasonable result.</p>
 
 <p>The famous quote from Ken Thompson, "When in doubt, use brute force",
 applies to toybox.  Do the simple thing first, do as little of it as possible,
 and make sure it's right.  You can always speed it up later.</p>
 
 <b><h3>Size</h3></b>
-<p>Quick smoketest: build toybox with and without the command (or the change),
-and maybe run "nm --size-sort" on files in generated/unstripped.
-(See make bloatcheck below for toybox's built in nm size diff-er.)</p>
-
 <p>Again, being simple gives you most of this. An algorithm that does less work
-is generally smaller. Understand the problem, treat size as a cost, and
+is generally smaller.  Understand the problem, treat size as a cost, and
 get a good bang for the byte.</p>
 
-<p>What "size" means depends on context: there are at least a half dozen
-different metrics in two broad categories: space used on disk/flash/ROM,
-and space used in memory at runtime.</p>
-
-<p>Your executable file has at least
-four main segments (text = executable code, rodata = read only data,
-data = writeable variables initialized to a value other than zero,
-bss = writeable data initialized to zero). Text and rodata are shared between multiple instances of the program running
-simultaneously, the other 4 aren't. Only text, rodata, and data take up
-space in the binary, bss, stack and heap only matter at runtime. You can
-view toybox's symbols with "nm generated/unstripped/toybox", the T/R/D/B
-lets you know the segment the symbol lives in. (Lowercase means it's
-local/static.)</p>
-
-<p>Then at runtime there's
-heap size (where malloc() memory lives) and stack size (where local
-variables and function call arguments and return addresses live). And
-on 32 bit systems mmap() can have a constrained amount of virtual memory
-(usually a couple gigabytes: the limits on 64 bit systems are generally big
-enough it doesn't come up)</p>
-
-<p>Optimizing for binary size is generally good: less code is less to go
-wrong, and executing fewer instructions makes your program run faster (and
-fits more of it in cache). On embedded systems, binary size is especially
-precious because flash is expensive and code may need binary auditing for
-security. Small stack size
+<p>Understand the difference between binary size, heap size, and stack size.
+Your binary is the executable file on disk, your heap is where malloc() memory
+lives, and your stack is where local variables (and function call return
+addresses) live.  Optimizing for binary size is generally good: executing
+fewer instructions makes your program run faster (and fits more of it in
+cache).  On embedded systems, binary size is especially precious because
+flash is expensive (and its successor, MRAM, even more so).  Small stack size
 is important for nommu systems because they have to preallocate their stack
-and can't make it bigger via page fault. And everybody likes a small heap.</p>
+and can't make it bigger via page fault.  And everybody likes a small heap.</p>
 
-<p>Measure the right things. Especially with modern optimizers, expecting
+<p>Measure the right things.  Especially with modern optimizers, expecting
 something to be smaller is no guarantee it will be after the compiler's done
-with it. Will total binary size is the final result, it isn't always the most
-accurate indicator of the impact of a given change, because lots of things
-get combined and rounded during compilation and linking (and things like
-ASAN disable optimization). Toybox has scripts/bloatcheck to compare two versions
-of a program and show size changes in each symbol (using "nm --size-sort").
-You can "make baseline" to build a baseline version to compare against,
-and then apply your changes and "make bloatcheck" to compare against
-the saved baseline version.</p>
+with it.  Binary size isn't the most accurate indicator of the impact of a
+given change, because lots of things get combined and rounded during
+compilation and linking.  Matt Mackall's bloat-o-meter is a python script
+which compares two versions of a program, and shows size changes in each
+symbol (using the "nm" command behind the scenes).  To use this, run
+"make baseline" to build a baseline version to compare against, and
+then "make bloatometer" to compare that baseline version against the current
+code.</p>
 
-<p>Avoid special cases. Whenever you see similar chunks of code in more than
+<p>Avoid special cases.  Whenever you see similar chunks of code in more than
 one place, it might be possible to combine them and have the users call shared
-code (perhaps out of lib/*.c). This is the most commonly cited trick, which
-doesn't make it easy to work out HOW to share. If seeing two lines of code do
-the same thing makes you slightly uncomfortable, you've got the right mindset,
-but "reuse" requires the "re" to have benefit, and infrastructure in search
-of a user will generally bit-rot before it finds one.</p>
+code. (This is the most commonly cited trick, which doesn't make it easy. If
+seeing two lines of code do the same thing makes you slightly uncomfortable,
+you've got the right mindset.)</p>
 
-<p>The are a lot of potential microoptimizations (on some architectures
-using char instead of int as a loop index is noticeably slower, on some
-architectures C bitfields are surprisingly inefficient, & is often faster
-than % in a tight loop, conditional assignment avoids branch prediction
-failures...) but they're generally not worth doing unless you're trying to
-speed up the middle of a tight inner loop chewing through a large amount
-of data (such as a compression algorithm). For data pumps sane blocking
-and fewer system calls (buffer some input/output and do a big read/write
-instead of a bunch of little small ones) is usually the big win. But
-be careful about cacheing stuff: the two persistently hard problems in computer
-science are naming things, cache coherency, and off by one errors.</p>
+<p>Some specific advice: Using a char in place of an int when doing math
+produces significantly larger code on some platforms (notably arm),
+because each time the compiler has to emit code to convert it to int, do the
+math, and convert it back.  Bitfields have this problem on most platforms.
+Because of this, using char to index a for() loop is probably not a net win,
+although using char (or a bitfield) to store a value in a structure that's
+repeated hundreds of times can be a good tradeoff of binary size for heap
+space.</p>
 
 <b><h3>Simplicity</h3></b>
 
@@ -385,7 +315,6 @@
 <a href=http://blog.outer-court.com/archive/2005-08-24-n14.html>why
 programmers should strive to be lazy and dumb</a>?</p>
 
-<hr>
 <a name="portability"><b><h2><a href="#portability">Portability issues</a></h2></b>
 
 <b><h3>Platforms</h3></b>
@@ -397,156 +326,51 @@
 
 <p>I don't do windows.</p>
 
-<a name="standards" />
-<b><h3>Standards</h3></b>
-
-<p>Toybox is implemented with reference to
-<a href=http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf>c99</a>,
-<a href=roadmap.html#susv4>Posix 2008</a>,
-<a href=#bits>LP64</a>,
-<a href=roadmap.html#sigh>LSB 4.1</a>,
-the <a href=https://www.kernel.org/doc/man-pages/>Linux man pages</a>,
-various <a href=https://www.rfc-editor.org/rfc-index.html>IETF RFCs</a>,
-the linux kernel source's
-<a href=https://www.kernel.org/doc/Documentation/>Documentation</a> directory,
-utf8 and unicode, and our terminal control outputs ANSI
-<a href=https://man7.org/linux/man-pages/man4/console_codes.4.html>escape sequences</a>.
-Toybox gets <a href=faq.html#cross>tested</a> with gcc and llvm on glibc,
-musl-libc, and bionic, plus occasional <a href=https://github.com/landley/toybox/blob/master/kconfig/freebsd_miniconfig>FreeBSD</a> and
-<a href=https://github.com/landley/toybox/blob/master/kconfig/macos_miniconfig>MacOS</a> builds for subsets
-of the commands.</p>
-
-<p>For the build environment and runtime environment, toybox depends on
-posix-2008 libc features such as the openat() family of
+<p>We depend on C99 and posix-2008 libc features such as the openat() family of
 functions. We also root around in the linux /proc directory a lot (no other
 way to implement "ps" at the moment), and assume certain "modern" linux kernel
-behavior (for example <a href=https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b6a2fea39318>linux 2.6.22</a>
-expanded the 128k process environment size limit to 2 gigabytes, then it was
+behavior such as large environment sizes (<a href=https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=b6a2fea39318>linux commit b6a2fea39318</a>, went into 2.6.22
+released <a href=faq.html#support_horizon>July 2007</a>, expanding the 128k
+limit to 2 gigabytes. But it was then
 trimmed back down to 10 megabytes, and when I asked for a way to query the
 actual value from the kernel if it was going to keep changing
-like that <a href=https://lkml.org/lkml/2017/11/5/204>Linus declined</a>).
-We make an effort to support <a href=faq.html#support_horizon>older kernels</a>
-and other implementations (primarily MacOS and BSD) but we don't always
-police their corner cases very closely.</p>
-
-<p><b>Why not just use the newest version of each standard?</b>
-
-<p>Partly to <a href=faq.html#support_horizon>support older systems</a>:
-you can't fix a bug in the old system if you can't build in the old
-environment.</p>
-
-<p>Partly because toybox's maintainer has his own corollary to Moore's law:
-50% of what you know about programming the hardware is obsolete every 18
-months, but the advantage of C &amp; Unix it's usually the same 50% cycling
-out over and over.</p>
-
-<p>But mostly because the updates haven't added anything we care about.
-Posix-2008 switched some things to larger (64 bit) data types and added the
-openat() family of functions (which take a directory filehandle instead of
-using the Current Working Directory),
-but the 2013 and 2018 releases of posix were basically typo fixes: still
-release 7, still SUSv4. (An eventual release 8 might be interesting but
-it's not out yet.) We use C99 instead of C11 or newer because the new stuff
-was mostly about threading (atomic variables and such), and except for using
-// style single line comments we're more or less writing C89 code anyway.
-The main other new thing of interest in C99 was explicit width data
-types (uint32_t and friends), which LP64 handles for us.</p>
-
-<p>We're ignoring new versions of the Linux Foundation's standards (LSB, FHS)
-entirely, for the same reason Debian is: they're not good at maintaining
-standards. (The Linux Foundation acquiring the Free Standards Group worked
-out about as well as Microsoft buying Nokia.)</p>
-
-<p>We refer to current versions of man7.org because it's
-not easily versioned (the website updates regularly) and because
-Michael Kerrisk does a good job maintaining it so far. That said, we
-try to "provide new" in our commands but "depend on old" in our build scripts.
-(For example, we didn't start using "wait -n" until it had been in bash for 7
-years, and even then people depending on Centos' 10 year support horizon
-complained.)</p>
-
-<p>Using newer vs older RFCs, and upgrading between versions, is a per-case
-judgement call.</p>
-
-<p><b>How strictly do you adhere to these standards?</b>
-
-<p>...ish? The man pages have a lot of stuff that's not in posix,
-and there's no "init" or "mount" in posix, you can't implement "ps"
-without replying on non-posix APIs....</p>
-
-<p>When the options a command offers visibly contradict posix, we try to have
-a "deviations from posix" section at the top of the source listing the
-differences, but that's about what we provide not what we used from the OS
-or build environment.</p>
-
-<p>The build needs bash (not a pure-posix sh), and building on MacOS requires
-"gsed" (because Mac's sed is terrible), but toybox is explicitly self-hosting
-and any failure to build under the tool versions we provide would be a bug
-needing to be fixed.</p>
-
-<p>Within the code, everything in main.c and lib/*.c has to build
-on every supported Linux version, compiler, and library, plus BSD and MacOS.
-We mostly try to keep #if/else staircases for portability issues to
-lib/portability.[ch].</p>
-
-<p>Portability of individual commands varies: we sometimes program directly
-against linux kernel APIs (unavoidable when accessing /proc and /sys),
-individual commands are allowed to #include &lt;linux/*.h&gt; (common
-headers and library files are not, except maybe lib/portability.* within an
-appropriate #ifdef),  we only really test against Linux errno values
-(unless somebody on BSD submits a bug), and a few commands outright cheat
-(the way ifconfig checks for ioctl numbers in the 0x89XX range). This is
-the main reason some commands build on BSD/MacOS and some don't.</p>
+like that, <a href=https://lkml.org/lkml/2017/11/5/204>Linus declined</a>).
+In theory this shouldn't prevent us from working on
+older kernels or other implementations (ala BSD), but we don't police their
+corner cases.</p>
 
 <a name="bits" />
 <b><h3>32/64 bit</h3></b>
 <p>Toybox should work on both 32 bit and 64 bit systems. 64 bit desktop
-hardware went mainstream <a href=https://web.archive.org/web/20040307000108mp_/http://developer.intel.com/technology/64bitextensions/faq.htm>in 2005</a>
-and was essentially ubiquitous <a href=faq.html#support_horizon>by 2012</a>,
-but 32 bit hardware will continue to be important in embedded devices for years to come.</p>
+hardware went mainstream in 2005 and was essentially ubiquitous
+by the end of the decade, but 32 bit hardware will continue to be important
+in embedded devices for several more years.</p>
 
-<p>Toybox relies on the
-<a href=http://archive.opengroup.org/public/tech/aspen/lp64_wp.htm>LP64 standard</a>
-which Linux, MacOS X, and BSD all implement, and which modern 64 bit processors such as
-x86-64 were <a href=http://www.pagetable.com/?p=6>explicitly designed to
-support</a>. (Here's the original <a href=https://web.archive.org/web/20020905181545/http://www.unix.org/whitepapers/64bit.html>LP64 white paper</a>.)</p>
+<p>Toybox relies on the fact that on any Unix-like platform, pointer and long
+are always the same size (on both 32 and 64 bit). Pointer and int are _not_
+the same size on 64 bit systems, but pointer and long are.
+This is guaranteed by the LP64 memory model, a Unix standard (which Linux
+and MacOS X both implement, and which modern 64 bit processors such as
+x86-64 were <a href=http://www.pagetable.com/?p=6>designed for</a>).</p>
 
-<p>LP64 defines explicit sizes for all the basic C integer types, and
-guarantees that on any Unix-like platform "long" and "pointer" types
-are always the same size (the processor's register size).
-This means it's safe to assign pointers into
-longs and vice versa without losing data: on 32 bit systems both are 32 bit,
-on 64 bit systems both are 64 bit.</p>
+<p>Back
+before unix.org went down, they hosted the
+<a href=https://web.archive.org/web/20020905181545/http://www.unix.org/whitepapers/64bit.html>LP64 standard</a> and
+<a href=https://web.archive.org/web/20020921185209/http://www.unix.org/version2/whatsnew/lp64_wp.html>the LP64 rationale</a>, but the important part is
+LP64 gives all the basic C integer types defined sizes:</p>
 
 <table border=1 cellpadding=10 cellspacing=2>
-<tr><td>C type</td><td>char</td><td>short</td><td>int</td><td>long</td><td>long long</td></tr>
-<tr><td>32 bit<br />sizeof</td><td>8 bits</td><td>16 bits</td><td>32 bits</td><td>32 bits</td><td>64 bits</td></tr>
-<tr><td>64 bit<br />sizeof</td><td>8 bits</td><td>16 bits</td><td>32 bits</td><td>64 bits</td><td>64 bits</td></tr>
+<tr><td>C type</td><td>32 bit<br />sizeof</td><td>64 bit<br />sizeof</td></tr>
+<tr><td>char</td><td>1 byte</td><td>1 byte</td></tr>
+<tr><td>short</td><td>2 bytes</td><td>2 bytes</td></tr>
+<tr><td>int</td><td>4 bytes</td><td>4 bytes</td></tr>
+<tr><td>long</td><td>4 bytes</td><td>8 bytes</td></tr>
+<tr><td>long long</td><td>8 bytes</td><td>8 bytes</td></tr>
 </table>
 
-<p>LP64 eliminates the need to use c99 "uint32_t" and friends: the basic
-C types all have known size/behavior, and the only type whose
-size varies is "long", which is the natural register size of the processor.</p>
-
-<p>Note that Windows doesn't work like this, and I don't care, but if you're
-curious here are <a href=https://devblogs.microsoft.com/oldnewthing/20050131-00/?p=36563>the insane legacy reasons why this is broken on Windows</a>.</a></p>
-
-<p>The main squishy bit in LP64 is that "long long" was defined as
-"at least" 64 bits instead of "exactly" 64 bits, and the standards body
-that issued it collapsed in the wake of the <a href=https://en.wikipedia.org/wiki/Unix_wars>proprietary unix wars</a> (all
-those lawsuits between AT&amp;T/BSDI/Novell/Caldera/SCO), so is
-not available to issue an official correction. Then again a processor
-with 128-bit general purpose registers wouldn't be commercially viable
-<a href=https://landley.net/notes-2011.html#26-06-2011>until 2053</a>
-(because 2005+32*1.5), and with the S-curve of Moore's Law slowly
-<a href=http://www.acm.org/articles/people-of-acm/2016/david-patterson>bending back down</a> as
-atomic limits and <a href=http://www.cnet.com/news/end-of-moores-law-its-not-just-about-physics/>exponential cost increases</a> produce increasing
-drag.... (The original Moore's Law curve would mean that in the year 2022
-a high end workstation would have around 8 terabytes of RAM, available retail.
-Most don't even come with
-that much disk space.) At worst we don't need to care for decades, the
-S-curve bending down means probably not in our lifetimes, and
-atomic limits may mean "never". So I'm ok treating "long long" as exactly 64 bits.</p>
+<p>Note that Windows doesn't work like this, and I don't care.
+<a href=https://devblogs.microsoft.com/oldnewthing/20050131-00/?p=36563>The
+insane legacy reasons why this is broken on Windows are explained here.</a></p>
 
 <b><h3>Signedness of char</h3></b>
 <p>On platforms like x86, variables of type char default to unsigned.  On
@@ -618,7 +442,8 @@
 <p>(This is why we use an external https wrapper program, because depending on
 openssl or similar to be linked in would change the behavior of toybox.)</p>
 
-<hr /><a name="license" /><h2>License</h2>
+<a name="license" />
+<h2>License</h2>
 
 <p>Toybox is licensed <a href=license.html>0BSD</a>, which is a public domain
 equivalent license approved by <a href=https://spdx.org/licenses/0BSD.html>SPDX</a>. This works like other BSD licenses except that it doesn't
@@ -637,7 +462,8 @@
 license, such as the xz decompressor or
 <a href=https://github.com/mkj/dropbear/blob/master/libtommath/LICENSE>libtommath</a> and <a href=https://github.com/mkj/dropbear/blob/master/libtomcrypt/LICENSE>libtomcrypt</a>.</p>
 
-<hr /><a name="codestyle" /><h2>Coding style</h2>
+<a name="codestyle" />
+<h2>Coding style</h2>
 
 <p>The real coding style holy wars are over things that don't matter
 (whitespace, indentation, curly bracket placement...) and thus have no
@@ -685,20 +511,8 @@
 (In C "char *a, b;" and "char* a, b;" mean the same thing: "a" is a pointer
 but "b" is not. Spacing it the second way is not how C works.)</p>
 
-<p>We wrap lines at 80 columns. Part of the reason for this I (toybox's
-founder Rob) have mediocre eyesight (so tend to increase the font size in
-terminal windows and web browsers), and program in a lot of coffee shops
-on laptops with a smallish sceen. I'm aware this <a href=http://lkml.iu.edu/hypermail/linux/kernel/2005.3/08168.html>exasperates Linus torvalds</a>
-(with his 8-character tab indents where just being in a function eats 8 chars
-and 4 more indent levels eats half of an 80 column terminal), but you've
-gotta break somewhere and even Linus admits there isn't another obvious
-place to do so. (80 columns came from punched cards, which came
-from civil war era dollar bill sorting boxes IBM founder Herman Hollerith
-bought secondhand when bidding to run the 1890 census. "Totally arbitrary"
-plus "100 yeas old" = standard.)</p>
-
-<p>If statements with a single line body go on the same line when the result
-fits in 80 columns, on a second line when it doesn't. We usually only use
+<p>If statements with a single line body go on the same line if the result
+fits in 80 columns, on a second line if it doesn't. We usually only use
 curly brackets if we need to, either because the body is multiple lines or
 because we need to distinguish which if an else binds to. Curly brackets go
 on the same line as the test/loop statement. The exception to both cases is
diff --git a/www/doc/mount.html b/www/doc/mount.html
deleted file mode 100644
index 8936265..0000000
--- a/www/doc/mount.html
+++ /dev/null
@@ -1,196 +0,0 @@
-<h2>How mount actually works</h2>
-
-<p>The <a href=https://landley.net/toybox/help.html#mount>mount comand</a>
-calls the <a href=https://man7.org/linux/man-pages/man2/mount.2.html>mount
-system call</a>, which has five arguments:</p>
-
-<blockquote><b>
-int mount(const char *source, const char *target, const char *filesystemtype,
-          unsigned long mountflags, const void *data);
-</b></blockquote>
-
-<p>The command "<b>mount -t ext2 /dev/sda1 /path/to/mntpoint -o ro,noatime</b>"
-parses its command line arguments to feed them into those five system call
-arguments. In this example, the <b>source</b> is "/dev/sda1", the <b>target</b>
-is "/path/to/mountpoint", and the <b>filesystemtype</b> is "ext2".
-
-<p>The other two syscall arguments (<b>mountflags</b> and </b>data</b>)
-come from the "-o option,option,option" argument. The mountflags argument goes
-to the VFS (explained below), and the data argument is passed to the filesystem
-driver.</p>
-
-<p>The mount command's options string is a list of comma separated values. If
-there's more than one -o argument on the mount command line, they get glued
-together (in order) with a comma. The mount command also checks the file
-<b>/etc/fstab</b> for default options, and the options you specify on the command
-line get appended to those defaults (if any). Most other command line mount
-flags are just synonyms for adding option flags (for example
-"mount -o remount -w" is equivalent to "mount -o remount,rw"). Behind the
-scenes they all get appended to the -o string and fed to a common parser.</p>
-
-<p>VFS stands for "Virtual File System" and is the common infrastructure shared
-by different filesystems. It handles common things like making the filesystem
-read only. The mount command assembles an option string to supply to the "data"
-argument of the option syscall, but first it parses it for VFS options
-(ro,noexec,nodev,nosuid,noatime...) each of which corresponds to a flag
-from <b>#include &lt;sys/mount.h&gt;</b>. The mount command removes those options
-from the string and sets the corresponding bit in mountflags, then the
-remaining options (if any) form the data argument for the filesystem driver.</p>
-
-<blockquote>
-<p>Implementation details: the mountflag MS_SILENCE gets set by
-default even if there's nothing in /etc/fstab. Some actions (such as --bind
-and --move mounts, I.E. -o bind and -o move) are just VFS actions and don't
-require any specific filesystem at all. The "-o remount" flag requires looking
-up the filesystem in /proc/mounts and reassembling the full option string
-because you don't _just_ pass in the changed flags but have to reassemble
-the complete new filesystem state to give the system call. Some of the options
-in /etc/fstab are for the mount command (such as "user" which only does
-anything if the mount command has the suid bit set) and don't get passed
-through to the system call.</p>
-</blockquote>
-
-<p>When mounting a new filesystem, the "<b>filesystem</b>" argument to the mount system
-call specifies which filesystem driver to use. All the loaded drivers are
-listed in /proc/filesystems, but calling mount can also trigger a module load
-request to add another. A filesystem driver is responsible for putting files
-and subdirectories under the mount point: any time you open, close, read,
-write, truncate, list the contents of a directory, move, or delete a file,
-you're talking to a filesystem driver to do it. (Or when you call
-ioctl(), stat(), statvfs(), utime()...)</p>
-
-<h2>Four filesystem types (block backed, server backed, ramfs, synthetic).</h2>
-
-<p>Different drivers implement different filesystems, which come in four
-different types: the filesystem's backing store can be a fixed length
-block of storage, the backing store can be some server the driver connects to,
-the files can remain in memory with no backing store,
-or the filesystem driver can algorithmically create the filesystem's contents
-on the fly.</p>
-
-<ol>
-<li><h3>Block device backed filesystems, such as ext2 and vfat.</h3>
-
-<p>This kind of filesystem driver acts as a lens to look at a block device
-through. The source argument for block backed filesystems is a path to a
-block device (such as "/dev/hda1") which stores the contents of the
-filesystem in a fixed length block of sequential storage, with a seperate
-driver providing that block device.</p>
-
-<p>Block backed filesystems are the "conventional" filesystem type most people
-think of when they mount things. The name means that the "backing store"
-(where the data lives when the system is switched off) is on a block device.</p>
-</li>
-
-<li><h3>Server backed filesystems, such as cifs/samba or fuse.</h3>
-
-<p>These drivers convert filesystem operations into a sequential stream of
-bytes, which it can send through a pipe to talk to a program. The filesystem
-server could be a local Filesystem in Userspace daemon (connected to a local
-process through a pipe filehandle), behind a network socket (CIFS and v9fs),
-behind a char device (/dev/ttyS0), and so on. The common attribute is there's
-some program on the other end sending and receiving a sequential bytestream.
-The backing store is a server somewhere, and the filesystem driver is talking
-to a process that reads and writes data in some known protocol.</p>
-
-<p>The source argument for these filesystems indicates where the filesystem
-lives. It's often in a URL-like format for network filesystems, but it's
-really just a blob of data that the filesystem driver understands.</p>
-
-<p>A lot of server backed filesystems want to open their own connection so they
-don't have to pass their data through a persistent local userspace process,
-not really for performance reasons but because in low memory situations a
-chicken-and-egg situation can develop where all the process's pages have
-been swapped out but the filesystem needs to write data to its backing
-store in order to free up memory so it can swap the process's pages back in.
-If this mechanism is providing the root filesystem, this can deadlock and
-freeze the system solid. So while you _can_ pass some of them a filehandle,
-more often than not you don't.</p>
-
-<p>These are also known as "pipe backed" filesystems (or "network filesystems"
-because that's a common case, although a network doesn't need to be inolved).
-Conceptually they're char device backed filesystems analogous to the block
-backed filesystems (block devices provide seekable storage, char devices
-provide serial I/O), but you don't commonly specify a character device in
-/dev when mounting them because you're talking to a specific server process,
-not a whole machine.</p>
-</li>
-
-<li><h3>Ram backed filesystems (ramfs and tmpfs).</h3>
-
-<p>These are very simple filesystems that don't implement a backing store,
-but just keep the data in memory. Data
-written to these gets stored in the disk cache, and the driver ignores requests
-to flush it to backing store (reporting all the pages as pinned and
-unfreeable).</p>
-
-<p>These filesystem drivers essentially mount the VFS's page/dentry cache as if it was a
-filesystem. (Page cache stores file contents, dentry cache stores directory
-entries.) They grow and shrink dynamically as needed: when you write files
-into them they allocate more memory to store it, and when you delete files
-the memory is freed.</p>
-
-<p>The "ramfs" driver provides the simplest possible ram filesystem,
-which is too simple for most real use cases. The "tmpfs" driver adds
-a size limitation (by default 50% of system RAM, but it's adjustable as a mount
-option) so the system doesn't run out of memory and lock up if you
-"cat /dev/zero > file", can report how much space is remaining
-when asked (ramfs always says 0 bytes free), and can write its data
-out to swap space (like processes do) when the system is under memory pressure.</p>
-
-<blockquote>
-<p>Note that "ramdisk" is not the same as "ramfs". The ramdisk driver uses a
-chunk of memory to implement a block device, and then you can format that
-block device and mount it with a block device backed filesystem driver.
-(This is the same "two device drivers" approach you always have with block
-backed filesystems: one driver provides /dev/ram0 and the second driver mounts
-it as vfat.) Ram disks are significantly less efficient than ramfs,
-allocating a fixed amount of memory up front for the block device instead of
-dynamically resizing itself as files are written into an deleted from the
-page and dentry caches the way ramfs does.</p>
-</blockquote>
-
-<p>Initramfs (I.E. rootfs) is a ram backed filesystem mounted on / which
-can't be unmounted for the same reason PID 1 can't exit. The boot
-process can extract a cpio.gz archive into it (either statically linked
-into the kernel or loaded as a second file by the bootloader), and
-if it contains an executable "init" binary at the top level that
-will be run as PID 1. If you specify "root=" on the kernel command line,
-initramfs will be ramfs and will get overmounted with the specified
-filesystem if no "/init" binary can be run out of the initramfs.
-If you don't specify root= then initramfs will be tmpfs, which is probably
-what you want when the system is running from initramfs.</p>
-</li>
-
-<li><h3>Synthetic filesystems (proc, sysfs, devtmpfs, devpts...)</h3>
-
-<p>These filesystems don't have any backing store because they don't
-store arbitrary data the way the first three types of filesystems do.</p>
-
-<p>Instead they present artificial contents, which can represent processes or
-hardware or anything the driver writer wants them to show. Listing or reading
-from these files calls a driver function that produces whatever output it's
-programmed to, and writing to these files submits data to the driver which
-can do anything it wants with it.</p>
-
-<p>Synthetic filesystems are often implemented to provide monitoring and control
-knobs for parts of the operating system, as an alternative to adding more
-system calls (or ioctl, sysctl, etc). They provide a more human friendly user
-interface which programs can use but which users can also interact with
-directly from the command line via "cat" and redirecting the output of
-"echo" into special files.</p>
-
-<blockquote>
-<p>The first synthetic filesystem in Linux was "proc", which was initially
-intended to provide a directory for each process in the system to provide
-information to tools like "ps" and "top" (the /proc/[0-9]* entries)
-but became a dumping ground for any information the kernel wanted to export.
-Eventually the kernel developers <a href=https://lwn.net/Articles/57369/>genericized</a>
-the synthetic filesystem infrastructure so the system could have multiple
-different synthetic filesystems, but /proc remains full
-unrelated historic legacy exports kept for backwards compatibility.</p>
-</blockquote>
-</li>
-</ol>
-
-<p>TODO: explain overmounts, mount --move, mount namespaces.</p>
diff --git a/www/doc/mount.txt b/www/doc/mount.txt
new file mode 100644
index 0000000..f538c46
--- /dev/null
+++ b/www/doc/mount.txt
@@ -0,0 +1,163 @@
+Here's how mount actually works:
+
+The mount comand calls the mount system call, which has five arguments you
+can see on the "man 2 mount" page:
+
+  int mount(const char *source, const char *target, const char *filesystemtype,
+            unsigned long mountflags, const void *data);
+
+The command "mount -t ext2 /dev/sda1 /path/to/mntpoint -o ro,noatime",
+parses its command line arguments to feed them into those five system call
+arguments. In this example, the source is "/dev/sda1", the target is
+"/path/to/mountpoint", and the filesystemtype is "ext2".
+
+The other two syscall arguments (mountflags and data) come from the
+"-o option,option,option" argument. The mountflags argument goes to the VFS
+(explained below), and the data argument is passed to the filesystem driver.
+
+The mount command's options string is a list of comma separated values. If
+there's more than one -o argument on the mount command line, they get glued
+together (in order) with a comma. The mount command also checks the file
+/etc/fstab for default options, and the options you specify on the command
+line get appended to those defaults (if any). Most other command line mount
+flags are just synonyms for adding option flags (for example
+"mount -o remount -w" is equivalent to "mount -o remount,rw"). Behind the
+scenes they all get appended to the -o string and fed to a common parser.
+
+VFS stands for "Virtual File System" and is the common infrastructure shared
+by different filesystems. It handles common things like making the filesystem
+read only. The mount command assembles an option string to supply to the "data"
+argument of the option syscall, but first it parses it for VFS options
+(ro,noexec,nodev,nosuid,noatime...) each of which corresponds to a flag
+from #include <sys/mount.h>. The mount command removes those options from the
+sting and sets the corresponding bit in mountflags, then the remaining options
+(if any) form the data argument for the filesystem driver.
+
+A few quick implementation details: the mountflag MS_SILENCE gets set by
+default even if there's nothing in /etc/fstab. Some actions (such as --bind
+and --move mounts, I.E. -o bind and -o move) are just VFS actions and don't
+require any specific filesystem at all. The "-o remount" flag requires looking
+up the filesystem in /proc/mounts and reassembling the full option string
+because you don't _just_ pass in the changed flags but have to reassemble
+the complete new filesystem state to give the system call. Some of the options
+in /etc/fstab are for the mount command (such as "user" which only does
+anything if the mount command has the suid bit set) and don't get passed
+through to the system call.
+
+When mounting a new filesystem, the "filesystem" argument to the mount system
+call specifies which filesystem driver to use. All the loaded drivers are
+listed in /proc/filesystems, but calling mount can also trigger a module load
+request to add another. A filesystem driver is responsible for putting files
+and subdirectories under the mount point: any time you open, close, read,
+write, truncate, list the contents of a directory, move, or delete a file,
+you're talking to a filesystem driver to do it. (Or when you call
+ioctl(), stat(), statvfs(), utime()...)
+
+Different drivers implement different filesystems, which have four categories:
+
+1) Block device backed filesystems, such as ext2 and vfat.
+
+This kind of filesystem driver acts as a lens to look at a block device
+through. The source argument for block backed filesystems is a path to a
+block device, such as "/dev/hda1", which stores the contents of the
+filesystem in a fixed block of sequential storage, and there's a seperate
+driver providing that block device.
+
+Block backed filesystems are the "conventional" filesystem type most people
+think of when they mount things. The name means that the "backing store"
+(where the data lives when the system is switched off) is on a block device.
+
+2) Server backed filesystems, such as cifs/samba or fuse.
+
+These drivers convert filesystem operations into a sequential stream of
+bytes, which it can send through a pipe to talk to a program. The filesystem
+server could be a local Filesystem in Userspace daemon (connected to a local
+process through a pipe filehandle), behind a network socket (CIFS and v9fs),
+behind a char device (/dev/ttyS0), and so on. The common attribute is there's
+some program on the other end sending and receiving a sequential bytestream.
+The backing store is a server somewhere, and the filesystem driver is talking
+to a process that reads and writes data in some known protocol.
+
+The source argument for these filesystems indicates where the filesystem lives. It's often in a URL-like format for network filesystems, but it's really just a blob of data that the filesystem driver understands.
+
+A lot of server backed filesystems want to open their own connection so they
+don't have to pass their data through a persistent local userspace process,
+not really for performance reasons but because in low memory situations a
+chicken-and-egg situation can develop where all the process's pages have
+been swapped out but the filesystem needs to write data to its backing
+store in order to free up memory so it can swap the process's pages back in.
+If this mechanism is providing the root filesystem, this can deadlock and
+freeze the system solid. So while you _can_ pass some of them a filehandle,
+more often than not you don't.
+
+These are also known as "pipe backed" filesystems (or "network filesystems"
+because that's a common case, although a network doesn't need to be inolved).
+Conceptually they're char device backed filesystems (analogus to the block
+device backed ones), but you don't commonly specify a character device in
+/dev when mounting them because you're talking to a specific server process,
+not a whole machine.
+
+3) Ram backed filesystems, such as ramfs and tmpfs.
+
+These are very simple filesystems that don't implement a backing store. Data
+written to these gets stored in the disk cache, and the driver ignores requests
+to flush it to backing store (reporting all the pages as pinned and
+unfreeable).
+
+These drivers essentially mount the VFS's page/dentry cache as if it was a
+filesystem. (Page cache stores file contents, dentry cache stores directory
+entries.) They grow and shrink dynamically, as needed: when you write files
+into them they allocate more memory to store it, and when you delete files
+the memory is freed.
+
+There's a simple one (ramfs) that does only that, and a more complex one (tmpfs)
+which adds a size limitation (by default 50%, but it's adjustable as a mount
+option) so the system doesn't run out of memory and lock up if you
+"cat /dev/zero > file", and can also report how much space is remaining
+when asked (ramfs always says 0 bytes free). The other thing tmpfs does
+is write its data out to swap space (like processes do) when the system
+is under memory proessure.
+
+Note that "ramdisk" is not the same as "ramfs". The ramdisk driver uses a
+chunk of memory to implement a block device, and then you can format that
+block device and mount it with a block device backed filesystem driver.
+(This is the same "two device drivers" approach you always have with block
+backed filesystems: one driver provides /dev/ram0 and the second driver mounts
+it as vfat.) Ram disks are significantly less efficient than ramfs,
+allocating a fixed amount of memory up front for the block device instead of
+dynamically resizing itself as files are written into an deleted from the
+page and dentry caches the way ramfs does.
+
+Note: initramfs cpio, tmpfs as rootfs.
+
+4) Synthetic filesystems, such as proc, sysfs, devpts...
+
+These filesystems don't have any backing store either, because they don't
+store arbitrary data the way the first three types of filesystems do.
+
+Instead they present artificial contents, which can represent processes or
+hardware or anything the driver writer wants them to show. Listing or reading
+from these files calls a driver function that produces whatever output it's
+programmed to, and writing to these files submits data to the driver which
+can do anything it wants with it.
+
+Synthetic ilesystems are often implemented to provide monitoring and control
+knobs for parts of the operating system. It's an alternative to adding more
+system calls (or ioctl, sysctl, etc), and provides a more human friendly user
+interface which programs can use but which users can also interact with
+directly from the command line via "cat" and redirecting the output of
+"echo" into special files.
+
+
+Those are the four types of filesystems: backing store can be a fixed length
+block of storage, backing store can be some server the driver connects to,
+backing store can not exist and the files merely reside in the disk cache,
+or the filesystem driver can just make up its contents programmatically.
+
+And that's how filesystems get mounted, using the mount system call which has
+five arguments. The "filesystem" argument specifies the driver implementing
+one of those filesystems, and the "source" and "data" arguments get fed to
+that driver. The "target" and "mountflags" arguments get parsed (and handled)
+by the generic VFS infrastructure. (The filesystem driver can peek at the
+VFS data, but generally doesn't need to care. The VFS tells the filesystem
+what to do, in response to what userspace said to do.)
diff --git a/www/doc/ext2.html b/www/ext2.html
similarity index 100%
rename from www/doc/ext2.html
rename to www/ext2.html
diff --git a/www/faq.html b/www/faq.html
index e6fa616..803d7b5 100755
--- a/www/faq.html
+++ b/www/faq.html
@@ -252,8 +252,8 @@
 single command's standalone version (which should behave identically,
 but that's why we test). You can set TEST_HOST=1 to test the host version
 instead of the toybox version (in theory they should work the same),
-and VERBOSE=all to see diffs of the expected and actual output for all
-failing tests. The default VERBOSE=fail stops at the first such failure.</p>
+and VERBOSE=1 to see diffs of the expected and actual output when a
+test fails. Set VERBOSE=fail to stop at the first such failure.</p>
 
 <hr /><h2><a name="when" />Q: When were historical toybox versions released?</h2>
 
diff --git a/www/git/index.html b/www/git/index.html
deleted file mode 100644
index bade8d1..0000000
--- a/www/git/index.html
+++ /dev/null
@@ -1 +0,0 @@
-Not browseable: <b>git clone https://landley.net/toybox/git</b>
diff --git a/www/header.html b/www/header.html
index 4acc95a..9857e2c 100644
--- a/www/header.html
+++ b/www/header.html
@@ -23,11 +23,7 @@
   </ul>
   <b>Download</b>
   <ul>
-    <li>Git repo:
-      <ul><li><a href="https://github.com/landley/toybox">github</a></li>
-          <li><a href=https://landley.net/toybox/git>local</a></li>
-      </ul>
-    </li>
+    <li><a href="https://github.com/landley/toybox">Source control</a></li>
     <li><a href="downloads">Releases</a></li>
     <li><a href="bin">Binaries</a></li>
   </ul>
@@ -39,7 +35,7 @@
     <ul>
       <li>(<a href="https://www.mail-archive.com/toybox@lists.landley.net">mirror</a>)</li>
     </ul>
-    <li>IRC #toybox on libera.chat</li>
+    <li>IRC #toybox on freenode.net</li>
     <li><a href=https://github.com/landley/toybox/commits/master.atom>Commit RSS feed</a></li>
     <li><a href="/notes.html">Maintainer's Blog</a></li>
     <li><a href=cleanup.html>Cleanup</a></li>
diff --git a/www/news.html b/www/news.html
index cc85450..7a36a12 100644
--- a/www/news.html
+++ b/www/news.html
@@ -1,334 +1,13 @@
 <html><head><title>toybox news</title>
 <!--#include file="header.html" -->
 
-<p>Toybox combines the most common Linux command line utilities together
+<p>Toybox combines common Linux command line utilities together
 into a single BSD-licensed executable that's simple, small, fast,
 reasonably standards-compliant, and powerful enough to turn Android into
 a development environment. See the links on the left for details.</p>
 
 <h2>News</h2>
 
-<a name="30-11-2021" /><a href="#30-11-2021"><hr><h2><b>November 30, 2021</b></h2></a>
-<blockquote><p>
-Busy? We'll I've just got this bulldozer to lie in front of or otherwise it'll
-knock my house down but otherwise no, not especially, why?</p>
-<p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
-
-<p><a href=downloads/toybox-0.8.6.tar.gz>Toybox 0.8.6</a>
-(<a href=https://github.com/landley/toybox/releases/tag/0.8.6>git commit</a>)
-is out, with prebuilt <a href=downloads/binaries/0.8.6>static binaries</a> and
-<a href=downloads/binaries/mkroot/0.8.6>mkroot images</a>
-bootable under QEMU (using vanilla linux-5.15).</p>
-
-<p><u>Make root</u>: The <a href=faq.html#mkroot>system builder</a> got upgraded, with better
-logging and layout of the output directory, plus <a href=https://github.com/landley/toybox/blob/0.8.6/scripts/mkroot.sh>scripts/mkroot.sh</a>
-should be easier to read and understand now.
-(Also added basic support for the <a href=http://lists.landley.net/pipermail/toybox-landley.net/2021-August/012497.html>qualcomm hexagon</a>,
-although it just builds a chroot filesystem, you can't boot a hexagon kernel under qemu
-<a href=https://lists.nongnu.org/archive/html/qemu-devel/2021-07/msg06430.html>quite yet</a>.)</p>
-</p>
-
-<p><u>New commands</u>: Rob added <b>linux32</b>.
-Dan Brown added <b>sha256sum</b> (and the related 224/384/512 variants).
-In pending, Elliott contributed <b>strace</b> and
-Moritz Röhrich contributed <b>hexdump</b>.</p>
-
-<p><u>Features</u>:
-Elliott added <b>date -s</b>, <b>pmap -p</b>, <b>tail -F -s</b>, <b>kill -0</b>,
-<b>reboot/halt/poweroff -d</b>, taught <b>file</b> to
-recognize Mach-o universal binaries, made Android's <b>log</b>
-take input from stdin when it has no arguments, added <b>tail --bytes --lines</b>
-(the --long synonyms for -c and -n),
-added <b>i2cdetect -q</b>, taught <b>i2cdump</b> to write XX for
-read failures, made <b>timeout</b> use the monotonic clock,
-and modernized the output of <b>uptime</b>.</p>
-
-<p>Rob added <b>find -quit -lname -ilname</b> and <b>-d</b> as a synonym for -depth,
-taught <b>cut -d $'\n'</b>
-to cut by line and added posix <b>cut -nb</b> (which wraps to the start of -c
-utf8 characters), added <b>cpio --ignore-devno --renumber-inodes</b>,
-taught <b>cal</b> to use 3 arguments (day month year), added <b>tar --selinux</b>
-support and a "had errors" message at the end, made <b>uname -o</b>
-say "Toybox", and fixed the <b>grep -Fw</b> combination (used by the 64 bit
-powerpc kernel build).</p>
-
-<p>Ella-0 added <b>split -n</b>. Peter Collingbourne added <b>grep -L</b>.</p>
-
-<p><u>Outside world</u>: The 0BSD license is <a href=https://lwn.net/Articles/868882/>now part</a> of the
-<a href=https://standards.iso.org/ittf/PubliclyAvailableStandards/>ISO-5962</a>
-standard. Of the currently <a href=https://github.com/search?q=license%3A0bsd&type=Repositories&ref=advsearch>38k 0BSD licensed projects on github</a> toybox
-isn't even the most popular, it's fourth.</p>
-
-<p>Elliott asked that toybox's <b>cut -DF</b> feature (a cheaper
-alternative to <b>awk '{print $3}'</b> be supported by other packages so
-it might someday make it into posix, so Rob
-<a href=http://lists.busybox.net/pipermail/busybox/2021-June/088886.html>submitted it to busybox</a>
-where it was <a href=https://git.busybox.net/busybox/commit/?id=0068ce2fa0e3>eventually merged</a>.</p>
-
-<p>Added a local <a href=https://landley.net/toybox/git>git mirror</a> for
-those reluctant to trust Microsoft Github.</p>
-
-<p>In the web nav bar, our <a href=https://isfreenodedeadyet.com/>freenode</a>
-channel moved to libera.chat
-(like <a href=https://boingboing.net/2021/05/19/freenode-irc-staff-quit-after-new-owner-seizes-control.html>everyone else's</a>;
-<a href=https://lwn.net/Articles/856543/>there</a>
-<a href=https://hackaday.com/2021/05/20/freenode-debacle-prompts-staff-exodus-new-network/>was</a>
-<a href=https://twitter.com/marcan42/status/1396280769778098185>a</a>
-<a href=https://twitter.com/mjg59/status/1396237336988446722>certain</a>
-<a href=https://www.devever.net/~hl/freenode_abuse>amount</a>
-<a href=https://twitter.com/TwitchiH/status/1395756163527028739>of</a>
-<a href=https://twitter.com/joepie91/status/1395364883303182339>drama</a>
-<a href=https://twitter.com/RichFelker/status/1404816846734385164>involved</a>).</p>
-
-<p><u>Pending</u>: lots more work on <b>toysh</b>: it has basic $((math)) support
-now, += assignment, the "declare" command and corresponding variable
-types (declare -i, declare -u, etc), several bugfixes, greatly
-improved support for background processes on NOMMU systems, and a bunch
-more sh.test entries.</p>
-
-<p>Elliott fixed <b>modprobe</b>'s parsing of short lines. Rob fixed a
-division by zero error when <b>vi</b> tries to edit a zero length file.
-Anqi Dong made sure that syslogd messages sent to sockets end with a
-newline. Eric Molitor significantly upgrade <b>wget</b> with http 1.1,
-chunked encoding, and (external library) https (TLS 1.2) support,
-plus several bugfixes. Michael Hope fixed <b>tftpd</b>'s option parsing.</p>
-
-<p><u>Documentation</u>: The roadmap.html and status.html pages
-got noticeable updates. (status.html is now directly generated by
-scripts/mkstatus.py, the old status.html wrapper that server-side-included
-status.gen has been removed).
-The <a href=design.html>design</a>
-page provides better links to the LP64 documentation, and the
-<a href=code.html>code</a> page explains a corner case where the filename
-and first command name expect to match (and how to work around it if they don't).
-Some website files weren't in the repository: two jpegs linked from html
-files, and the www/.htaccess file that triggers the server side includes
-in the navigation menu is now checked in. Johannes Schmitz fixed a
-typo in about.html.</p>
-
-<p>The <b>shred</b> usage line now includes all options.
-The <b>logwrapper</b> command now warns when it isn't built standalone.
-The <b>help</b> command no longer shows a header line about toybox unless
-it's called with no arguments. (It still shows it for command --help.)
-The --help option no longer needs to be the first option, and is
-checked before the "Not root" error message for restricted commands.</p>
-
-<p><u>Bugfixes</u>:
-Elliott made <b>ps</b> exit with status 1 if no processes were shown (for LTP),
-fixed an off-by-one in <b>dmesg</b> and a bounds check in <b>netstat</b>,
-fixed <b>pidof -s</b>, and taught <b>rmmod</b> to handle multiple arguments.
-Denys Vlasenko pointed out that <b>free -t</b> is "total" not "terabytes".
-Samanta Navarro pointed out a leftover 32 bit limitation in argument groups.
-Mikhail Kashkarov fixed mkdir's error handling for existing directories
-without -p.
-Rob fixed the 32 bit <b>readelf</b> build on Android, fixed a race condition
-in <b>tar</b> leading
-to the occasional spurious archiver warning,
-<a href=https://github.com/landley/toybox/commit/127cff38809e>changed cp</a>
-to work around a posix violation in the kernel, made xparsedate() handle more
-whitespace and ignore trailing + or - (a NOP timezone), made <b>su</b> log the
-right username, switched getuid() checks to geteuid() in <b>df</b> and <b>ping</b>,
-fixed a place in the test suite where do_test()
-could get confused by symlinks in the $PATH (calling realpath too early
-and losing the name of the command being run),
-made <b>env -i</b> use the old $PATH to run its command,
-and made <b>grep --color</b> highlight all matches.</p>
-
-<p>Worked around a bug in glibc+gcc 9.3 where linking against librt.a
-(for things like timer_create()) pulls in libgcc_eh.a which uses
-threads, meaning you can't statically link against librt.a from
-a non-threaded app. (I hadn't noticed because it works fine with the musl
-and llvm/bionic toolchains, only fails statically linking on e.g. debian.)
-The <a href=https://github.com/torvalds/linux/commit/d18760560593>kernel fix</a> for the cpio encrypted filesystem issue worked around in 0.8.5 made
-it in. Similarly, the
-FS_IOC_{GET,SET}{VERSION,FLAGS} ioctl family are <a href=https://www.spinics.net/lists/linux-api/msg49101.html>historically broken</a>
-(taking an unsigned int argument while advertising signed long),
-which <a href=https://github.com/landley/toybox/commit/dcfac5c983ad>we fixed</a> and reported upstream to a long
-round of bikeshedding (sadly
-the result seems to have been the man page maintainer
-<a href=https://git.kernel.org/pub/scm/docs/man-pages/man-pages.git/commit/man2?id=3de87d46840d>giving up</a>
-on documenting ioctls at all.</p>
-
-<p><u>Cleanups</u>:
-<b>cut</b> switched to FLAG() macros and no longer allows -f with -F,
-<b>eject</b> uses FLAG() macros and the linux/eject.h header,
-prettycool@protonmail added tabs to <b>time</b>'s output, and Rob removed
-the floating point dependency from time. Minor cleanups
-to lsattr, lspci, nsenter, xxd, file, insmod, modprobe, arp, bootchartd, pmap,
-comm, lsof, blkid, crond, init, userdel, makedevs, and scripts/make.sh.
-The "int fd = fd;"
-initialization hack to shut up gcc's "may be used uninitalized, but isn't" false
-positive warning has been replaced by a QUIET macro that resolves
-to nothing on llvm (which doesn't have the gcc bug).
-Ryan Pritchard reported a bug where <b>alias ls="ls --color"</b> would prevent
---help or --version from being the first argument to the command, which was
-a pain to fix without breaking things like <b>echo -- --version</b> and
-<b>basename -s --help file--help</b>.
-(Both toy_singleinit() in main.c _and_ get_optflags() in lib/args.c now
-check for those.)</p>
-
-<p><u>Infrastructure</u>:
-xabspath() now has a more granular (flag based) control interface.</p>
-
-<p><b>scripts/make.sh</b> now uses wait -n (available since bash 4.3 in February 2014)
-to keep the processors busier during a parallel build.
-Tests are now running in a subshell, which means functions and local
-variables defined in one don't pollute others during "make tests".
-
-<p>Guo Chuang reported that lsattr won't build on an 8 year old version of
-<a href=https://github.com/landley/toybox/pull/292#issuecomment-899895909>centos</a>,
-which is still supported for 2 more years because Red Hat can
-be paid to have a 10 year support horizon, longer than toybox's 7. Rob
-fixed it (and merged a similarly ancient compilation failure fix when
-building pending/ip.c against a 3.10 kernel),
-but the <a href=http://lists.landley.net/pipermail/toybox-landley.net/2021-August/012537.html>philosophal argument</a>
-remains <a href=http://lists.landley.net/pipermail/toybox-landley.net/2021-September/012603.html>unresolved</a>.</p>
-
-<p>Standalone builds can now override the .config file location with
-KCONFIG_CONFIG same as the multiplexer build. scripts/single.sh can
-now cope with a missing .config file (it uses the defconfig values
-for the CONFIG_TOYBOX_* global symbols).
-"make install_airlock" no longer needs host versions of sha256sum and sha512sum.</p>
-
-<p>In the test suite, <b>VERBOSE=spam</b> now shows expands successful tests
-like it would for errors.</p>
-
-<p><b>scripts/record-commands</b> got updated and logwrapper got renamed <b>logpath</b>.</p>
-
-<a name="19-05-2021" /><a href="#19-05-2021"><hr><h2><b>May 19, 2021</b></h2></a>
-<blockquote><p>It was of course a descendant of these eccentric poets
-who invented the spurious tales of impending doom which enabled the people of
-Golgafrincham to rid themselves of the useless third of their population.
-The other two-thirds stayed firmly at home and lived full, rich and happy lives
-until they were all suddenly wiped out by a virulent disease contracted from
-a dirty telephone.</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
-
-<p><a href=downloads/toybox-0.8.5.tar.gz>Toybox 0.8.5</a>
-(<a href=https://github.com/landley/toybox/releases/tag/0.8.5>git commit</a>)
-is out, with prebuilt <a href=downloads/binaries/0.8.5>static binaries</a> and
-<a href=downloads/binaries/mkroot/0.8.5>mkroot images</a>
-bootable under QEMU (using vanilla linux-5.12, except that s390 needed another
-<a href=http://lkml.iu.edu/hypermail/linux/kernel/2105.2/02904.html>perl
-removal patch</a>).</p>
-
-<p>This development cycle had thirty commits to sh.c fixing bugs and adding
-features to <b>toysh</b>. Shell functions and local variables are now implemented,
-along with the "set" builtin and trace support, and job control is
-about halfway in. The shell as a whole is <a href=https://en.wikipedia.org/wiki/Ninety%E2%80%93ninety_rule>maybe 80% done</a>, but still
-has some obvious gaps like $((math)) and interactive command line
-history/editing, plus a bunch of testing.</p>
-
-<p><u>New commands</u>:
-Moritz Röhrich added <b>pwgen</b> and <b>base32</b>, and
-Elliott Hughes added <b>unicode</b>. The
-<b>readelf</b> command got promoted out of pending, and
-<b>sha3sum</b> is now switched on in defconfig.</p>
-
-<p>Michael Christensen added <b>chsh</b> to pending, which hasn't been promoted
-yet because it's part of a group of commands (useradd, userdel, groupadd,
-groupdel) that should all be promoted together at some point
-(and depend on lib/passwd.c, which could use some more work).</p>
-
-<p><u>Upgrades</u>:
-<b>cpio</b> now supports extracting multiple concatenated archives.
-<b>file</b> now recognizes android's new XML binary format.
-<b>devmem</b> now works on nommu, can handle 0x prefxes on the address,
-and prints
-hex or decimal output to match the address type.
-<b>df</b> -a now shows overmounted filesystems.
-<b>test</b> -k checks the sticky bit.
-Added -t to <b>install</b>, <b>cp</b>, and <b>mv</b>, and -u to <b>cp</b>
-and <b>cpio</b>.
-<b>find</b> -executable checks that _we_ can execute them (u+x could be owned
-by a different user or have selinux weirdness).</p>
-
-<p>Elliott added several features to <b>date</b> (--iso, %:z output format, and
---utc as a synonym for -u), added a <b>sed</b> s///x option,
-added units to <b>ulimit</b> output, and
-made several UI changes to <b>hexedit</b> including a color
-mode (which is now the default, press x to toggle between old and new
-display), masked out the file type in <b>chmod</b> error messages and
-taught it to handle complex modes (like u+s+s), 
-hardened <b>file</b> and <b>readelf</b> against invalid input,
-added a portability.h workaround for macos statvfs for <b>df</b>,
-enabled line buffering in <b>echo</b> and <b>yes</b>,
-and significatly sped up <b>tr</b>. Rob similarly optimized <b>seq</b>
-and <b>count</b>.</p>
-
-<p><b>make tests</b> now defaults to VERBOSE=fail (and now has VERBOSE=all to
-continue after failure, and VERBOSE=quiet to show FAIL: lines without
-diff -u output).
-Cleanups to tee, netstat, file, and df. Added "static" annotations in a
-lot of commands, made more things use FLAG() macros. Ethan Sommer pointed out
-an unnecessary wrapper function in chgrp.
-In pending, Elliott did some cleanups and bugfixes to gettty, telnet, telnetd,
-tftpd, init, modprobe, and dd, and added more features to vi.
-Rob did some cleanup on modprobe.</p>
-
-<p><u>Bugfixes</u>:
-Yi-Yo Chiang fixed a <b>rm</b> bug where -f could get confused by read
-only filesystems and produce an error trying to unlink a nonexistent
-file, pointed out <b>install</b> -D was broken when the target file
-already exists, pointed out a <b>cpio</b> interaction with certain encrypted
-filesystems where readlink() wouldn't write as much payload as the header
-promised (corrupting the archive) and fixed another cpio bug where -t test
-mode would chown() files, and fixed quoting in mount.test.
-Elliott fixed a sequencing issue in <b>setsid</b>'s system calls,
-fixed some <b>sed</b> tests (sed's lie-to-autoconf --version
-output was preventing toyonly tests from triggering) and
-fixed <b>tar</b>'s base 256 output for very large files.
-Nir Lichtman pointed out that <b>rm</b> -p shouldn't try to rmdir / at the end,
-Luke Frankart pointed out a typo that broke <b>test</b> checking file modes,
-Firas Khalil Khana fixed a duplicate entry in the roadmap,
-Ethan Sommer fixed <b>install</b> -Dt,
-Andy Hu requested that <b>mount</b> handle mixed options like
--tnomsdos,smbfs.
-Denys Nykula reported a <b>chmod</b> regression,
-asm89 pointed out a <b>netcat</b> bug writing transactions larger than
-4k,
-Daniel Santana fixed <b>df</b> combining -P and -k,
-Robin Hsu fixed <b>grep</b> getting confused by libc setting errno when
-a library function call succeeded.
-Puck Meerburg taught the <b>gunzip</b> code not to be confused by FEXTRA entries
-(as described in RFC 1952) and added a test suite entry for that.</p>
-
-<p><b>find</b> handles empty arguments properly now (with test), <b>date</b>
--I with no arguments no longer segfaults, <b>grep</b> -f /dev/null no
-longer adds a "" regex matching everything, -z no longer splits patterns
-on \n, and -o can print zero length matches,
-<b>cp</b> -t works with one argument and with --parents.
-<b>readelf</b> displays properly in 80 columns and doesn't reject .bss
-off end of file, and <b>sed</b> s///2 now works when there isn't more than one
-match.
-<b>tar</b> now removes empty directories where it wants to put a non-directory.
-<b>microcom</b> sets serial device terminal attributes correctly.</p>
-
-<p>The prebuilt x86-64 binaries shouldn't segfault on older x86-64 processors
-anymore (workaround for gcc bug).
-Cross compiling was sometimes confusing install.sh because it created
-a hyphenated "toybox-$TARGET" and then tried to make symlinks to just "toybox".</p>
-
-<p><u>Build</u>:
-CONFIG_TOYBOX_I18N went away: toybox builds always support utf8 now.
-Ella-0 added OpenBSD support (but not a separate defconfig, try
-"make freebsd_defconfig").</p>
-
-<p><u>Library</u>:
-utf8towc() is now unsigned instead of wchar_t, matching wctoutf8().
-xclose() tests if fd is -1 so the caller doesn't have to.
-txpect (the test suite's built-in "expect", implemented in shell) can
-now do regex matches, and sh.test uses this.</p>
-
-<p>Elliott added the failing regex to the xregcomp() error message, and
-made multiple portability tweaks (header tweaks to build in more
-environments, running tests on Raspberry Pi OS and under mksh,
-fix utf8 locale selection on macos).</p>
-
-<p><u>Docs</u>:
-<b>chmod</b>'s help text explains why o+s doesn't set +t (and has a
-test for it). The <b>echo</b> help text is more compact.
-Checked in a better conversion of <a href=https://landley.net/toybox/toycans.png>toycans.png</a>.</p>
-
 <a name="24-10-2020" /><a href="#24-10-2020"><hr><h2><b>October 24, 2020</b></h2></a>
 <blockquote><p>
 "We are now cruising at a level of two to the power of twenty-five thousand to
@@ -386,8 +65,8 @@
 when wordwrapping (previously hardwired to 80 columns).
 If you're curious, I checked in my <a href=www/release.txt>release procedure
 checklist</a>, and
-fixed a stale link in the nav bar on the left ("statistics" changed domains).
-Firas Khalil Khana fixed some issues in the roadmap, and Rob
+vixed a stale link in the nav bar on the left ("statistics" changed domains).
+Firas Khaliki Khana fixed some issues in the roadmap, and Rob
 tweaked the roadmap so status.html is slightly more current.</p>
 
 <p><u>Tests</u>:
@@ -499,7 +178,7 @@
 trying to do you, kill you, rip you off, everything. If you're going to
 survive out there, you've really got to know where your
 <a href=towel.jpg>towel</a> is.</p>
-<p>- The Hitchhiker's Guide to the Galaxy</p>
+<p>- The Hitchhiker's Guide to the Galaxy.</p>
 </blockquote>
 
 <p>Despite everything <a href=downloads/toybox-0.8.3.tar.gz>Toybox 0.8.3</a>
@@ -1298,7 +977,7 @@
 <a name="31-10-2018" /><a href="#31-10-2018"><hr><h2><b>October 31, 2018</b></h2></a>
 <blockquote><p>
 "In the beginning the Universe was created.
-This has made a lot of people very angry and been widely regarded as a bad move."</p><p>- The Hitchhiker's Guide to the Galaxy
+This has made a lot of people very angry and been widely regarded as a bad move." - The Hitchhiker's Guide to the Galaxy.
 </p>
 </blockquote>
 
@@ -2156,7 +1835,7 @@
 <blockquote><p>"I checked it very thoroughly," said the computer, "and that
 quite definitely is the answer. I think the problem, to be quite honest with
 you, is that you've never actually known what the question is."
-</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+- The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.7.0.tar.gz>Toybox 0.7.0</a>
 (<a href=https://github.com/landley/toybox/releases/tag/0.7.0>git commit</a>)
@@ -2317,7 +1996,7 @@
 not from Guildford after all, but from a small planet somewhere in the vicinity
 of Betelgeuse?" Arthur shrugged in a so-so sort of way. "I don't know," he
 said, taking a pull of beer. "Why - do you think it's the sort of thing you're
-likely to say?"</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+likely to say?" - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.6.1.tar.gz>Toybox 0.6.1</a>
 (<a href=https://github.com/landley/toybox/releases/tag/0.6.1>git commit</a>)
@@ -2467,7 +2146,7 @@
 The reason why it was published in the form of a micro sub meson electronic
 component is that if it were printed in normal book form, an interstellar
 hitchhiker would require several inconveniently large buildings to carry it
-around in.</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+around in." - The Hitchhiker's Guide to the Galaxy </p></blockquote>
 
 <p><a href=downloads/toybox-0.6.0.tar.gz>Toybox 0.6.0</a>
 (<a href=https://github.com/landley/toybox/releases/tag/0.6.0>git commit</a>)
@@ -2706,7 +2385,7 @@
 <a name="25-02-2015" /><a href="#25-02-2015"><hr><h2><b>February 25, 2015</b></h2></a>
 <blockquote><p>"A common mistake that people make when trying to design
 something completely foolproof is to underestimate the ingenuity of
-complete fools."</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+complete fools."</p><p>- The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.5.2.tar.gz>Toybox 0.5.2</a>
 (<a href=/hg/toybox/shortlog/1702>commit 1702</a>) is out.</p>
@@ -2854,7 +2533,7 @@
 
 <a name="19-11-2014" /><a href="#19-11-2014"><hr><h2><b>November 19, 2014</b></h2></a>
 
-<blockquote><p>"This time it was right, it would work, and no one would have to get nailed to anything."</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+<blockquote><p>"This time it was right, it would work, and no one would have to get nailed to anything." - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.5.1.tar.bz2>Toybox 0.5.1</a>
 (<a href=/hg/toybox/shortlog/1566>commit 1566</a>) is out.</p>
@@ -2935,7 +2614,7 @@
 <blockquote><p>"There is an art, it says, or rather, a knack to flying.
 The knack lies in learning how to throw yourself at the ground and miss...
 Clearly, it is this second part, the missing, which presents the
-difficulties."</p><p>- The Hitchhiker's Guide to the Galaxy<p></blockquote>
+difficulties." - The Hitchhiker's Guide to the Galaxy.<p></blockquote>
 
 <p><a href=downloads/toybox-0.5.0.tar.bz2>Toybox 0.5.0</a>
 (<a href=/hg/toybox/shortlog/1512>commit 1512</a>) is out.</p>
@@ -3088,7 +2767,7 @@
 solutions were suggested for this problem, but most of these were largely
 concerned with the movement of small green pieces of paper, which was odd
 because on the whole it wasn't the small green pieces of paper that were
-unhappy."</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+unhappy." - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.4.9.tar.bz2>Toybox 0.4.9</a> (<a href=/hg/toybox/shortlog/1385>commit 1385</a>) is out.</p>
 
@@ -3209,7 +2888,7 @@
 which was so amazingly intelligent that even before the data banks
 had been connected up it had started from "I think therefore I am" and got as
 far as the existence of rice pudding and income tax before anyone managed to
-turn it off.</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+turn it off. - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.4.8.tar.bz2>Toybox 0.4.8</a> is based on
 <a href=http://landley.net/hg/toybox/shortlog/1262>commit 1262</a>. And
@@ -3291,8 +2970,8 @@
 at the end. Each page on the website should now have its own title.</p>
 
 <a name="18-11-2013" /><a href="#18-11-2013"><hr><h2><b>November 18, 2013</b></h2></a>
-<blockquote><p>"Space," it says, "is big. Really big. You just won't believe how vastly, hugely, mindbogglingly big it is. I mean, you may think it's a long way down the street to the chemist's, but that's just peanuts to space."</p><p>-
-The Hitchhiker's Guide to the Galaxy</p></blockquote>
+<blockquote><p>"Space," it says, "is big. Really big. You just won't believe how vastly, hugely, mindbogglingly big it is. I mean, you may think it's a long way down the street to the chemist's, but that's just peanuts to space." -
+The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.4.7.tar.bz2>Toybox 0.4.7</a> is based on
 <a href=http://landley.net/hg/toybox/shortlog/1122>commit 1122</a>.</p>
@@ -3331,7 +3010,7 @@
 <blockquote><p>"Think of a number," said the computer, "any number."
 Arthur told the computer the telephone number of King's Cross railway
 station passenger inquiries, on the grounds that it must have some function,
-and this might turn out to be it.</p><p>- The Hitchhiker's Guide to the Galaxy</p>
+and this might turn out to be it. - The Hitchhiker's Guide to the Galaxy</p>
 </blockquote>
 
 <p><a href=downloads/toybox-0.4.6.tar.bz2>Toybox 0.4.6</a> is based on
@@ -3465,7 +3144,8 @@
 <a name="02-07-2013" /><a href="#02-07-2013"><hr><h2><b>July 2, 2013</b></h2></a>
 <blockquote><p>"Time is an illusion. Lunchtime doubly so." "Very deep. You
 should send that in to the Reader's Digest. They've got a page for people
-like you."</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+like you." -
+The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.4.5.tar.bz2>Toybox 0.4.5</a> is based on
 <a href=http://landley.net/hg/toybox/shortlog/941>commit 941</a>. It adds
@@ -3577,7 +3257,7 @@
 
 <a name="14-03-2013" /><a href="#14-03-2013"><hr><h2><b>March 14, 2013</b></h2></a>
 <blockquote><p>"Ford, you're turning into a penguin. Stop it." -
-</p><p>The Hitchhiker's Guide to the Galaxy</p></blockquote>
+The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.4.4.tar.bz2>Toybox 0.4.4</a> is based on
 <a href=http://landley.net/hg/toybox/shortlog/813>commit 813</a>, adding
@@ -3599,7 +3279,7 @@
 (klibc, sash, sbase, s6...) to see what commands they include.</p>
 
 <a name="18-01-2013" /><a href="#18-01-2013"><hr><h2><b>January 18, 2013</b></h2></a>
-<blockquote><p>This must be Thursday. I never could get the hang of Thursdays.</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+<blockquote><p>This must be Thursday. I never could get the hang of Thursdays. - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.4.3.tar.bz2>Toybox 0.4.3</a> is based on
 <a href=http://landley.net/hg/toybox/shortlog/793>commit 793</a>. There
@@ -3643,7 +3323,7 @@
 <blockquote><p>"The major difference between a thing that might go wrong and a
 thing that cannot possibly go wrong is that when a thing that cannot possibly
 go wrong goes wrong it usually turns out to be impossible to get at or repair."
-</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+</p><p>- The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.4.2.tar.bz2>Toybox 0.4.2</a> is based on
 <a href=http://landley.net/hg/toybox/shortlog/749>commit 749</a> and is
@@ -3692,7 +3372,7 @@
 
 <a name="13-11-2012" /><a href="#13-11-2012"><hr><h2><b>November 13, 2012</b></h2></a>
 <blockquote><p>"Rule Six: The winning team shall be the first team that wins."
-</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+- The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.4.1.tar.bz2>Toybox 0.4.1</a> is based on
 <a href=http://landley.net/hg/toybox/shortlog/691>commit 691</a>.</p>
@@ -3757,7 +3437,7 @@
 <a name="23-07-2012" /><a href="#23-07-2012"><hr><h2><b>July 23, 2012</b></h2></a>
 <blockquote><p>"Ford", Arthur said. "There's an infinite number of monkeys
 out here who want to talk to us about this script for Hamlet they've worked
-out."</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+out." - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.4.0.tar.bz2>Toybox 0.4.0</a> is based on
 <a href=http://landley.net/hg/toybox/shortlog/640>commit 640</a>.</p>
@@ -3780,7 +3460,7 @@
 pending output on exit.</p>
 
 <a name="25-06-2012" /><a href="#25-06-2012"><hr><h2><b>June 25, 2012</b></h2></a>
-<blockquote><p>"For a moment, nothing happened. Then, after a second or so, nothing continued to happen."</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+<blockquote><p>"For a moment, nothing happened. Then, after a second or so, nothing continued to happen." - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p><a href=downloads/toybox-0.3.1.tar.bz2>Toybox 0.3.1</a> is based on commit
 <a href=http://landley.net/hg/toybox/shortlog/607>commit 607</a>. It's
@@ -3801,7 +3481,7 @@
 wheel, New York, wars and so on - whilst all the dolphins had ever done was
 muck about in the water having a good time. But conversely, the dolphins had
 always believed that they were far more intelligent than man - for precisely
-the same reasons."</p><p>- The Hitchhiker's Guide to the Galaxy</p></blockquote>
+the same reasons." - The Hitchhiker's Guide to the Galaxy.</p></blockquote>
 
 <p>It's well past time for <a href=downloads/toybox-0.3.0.tar.bz2>toybox 0.3.0</a>,
 so here it is, based
@@ -3865,7 +3545,7 @@
 <blockquote><p>"They went unnoticed at Goonhilly, passed over Cape Canaveral
 without a blip, and Woomera and Jodrell Bank looked straight through them.
 Which was a pity, because it was exactly the sort of thing they'd been looking
-for all these years."</p><p>- The Hitchhiker's Guide to the Galaxy</p>
+for all these years."</p></p>- The Hitchhiker's Guide to the Galaxy.</p>
 </p></blockquote>
 
 <p>Here's <a href=downloads/toybox-0.2.1.tar.bz2>toybox 0.2.1</a> based
diff --git a/www/roadmap.html b/www/roadmap.html
index 551eb2e..41b3866 100644
--- a/www/roadmap.html
+++ b/www/roadmap.html
@@ -2,19 +2,42 @@
 <!--#include file="header.html" -->
 <title>Toybox Roadmap</title>
 
-<h2>Roadmap sections</h2>
+<h2>Goals and use cases</h2>
+
+<p>We have several potential use cases for a new set of command line
+utilities, and are using those to determine which commands to implement
+for Toybox's 1.0 release. (Most of these have their own section in the
+<a href=status.html>status page</a>.)</p>
+
+<p>The most interesting publicly available standards are POSIX-2008
+(also known as the Single
+Unix Specification version 4) and the Linux Standard Base (version 4.1).
+The main test harness is including toybox in <a href=https://landley.net/aboriginal/about.html>Aboriginal Linux</a> and if that can
+build itself using the result to <a href=https://github.com/landley/control-images>build Linux From Scratch</a> (version 6.8).
+We also aim to replace Android's Toolbox.</p>
+
+<p>At a secondary level we'd like to meet other use cases. We've analyzed
+the commands provided by similar projects (klibc, sash, sbase, embutils,
+nash, and beastiebox), along with various vendor configurations of busybox,
+and some end user requests.</p>
+
+<p>Finally, we'd like to provide a good replacement for the Bash shell,
+which was the first program Linux ever ran and remains the standard shell
+of Linux no matter what Ubuntu says. This doesn't mean including the full
+set of Bash 4.x functionality, but does involve {various,features} &lt(beyond)
+posix.</p>
+
+<p>See the <a href=status.html>status page</a> for the categorized command list
+and progress towards implementing it. There's also a
+<a href=todo.html>historical todo list</a> from the project's 2011 relaunch.</p>
 
 <ul>
-<li><a href=#goals>Introduction</a></li>
 <li><a href=#susv4>POSIX-2008/SUSv4</a></li>
 <li><a href=#sigh>Linux "Standard" Base</a></li>
-<li><a href=#rfc>IETF RFCs and Man Pages</a></li>
 <li><a href=#dev_env>Development Environment</a></li>
 <li><a href=#android>Android Toolbox</a></li>
 <li><a href=#aosp>Building AOSP</a></li>
 <li><a href=#tizen>Tizen Core</a></li>
-<li><a href=#yocto>Yocto</a></li>
-<li><a href=#fhs>Filesystem Hierachy Standard</a></li>
 <li><a href=#buildroot>buildroot</a></li>
 <li>Miscelaneous: <a href=#klibc>klibc</a>, <a href=#glibc>glibc</a>,
 <a href=#sash>sash</a>, <a href=#sbase>sbase</a>,
@@ -22,46 +45,6 @@
 <li><a href=#packages>Other Packages</a></li>
 </ul>
 
-<a name="goals" />
-<h2>Introduction (Goals and use cases)</h2>
-
-<p>We have several potential use cases for a new set of command line
-utilities, and are using those to determine which commands to implement
-for Toybox's 1.0 release. Most of these have their own section in the
-<a href=status.html>status page</a>, showing current progress towards
-commplation.</p>
-
-<p>The most interesting publicly available standards are A) POSIX-2008 (also
-known as SUSv4), B) the Linux Standard Base version 4.1, and C) the official
-<a href=https://www.kernel.org/doc/man-pages/>Linux man pages</a>.
-But they include commands we've decided not implement, exclude
-commands or features we have, and don't always entirely match reality.</p>
-
-<p>The most thorough real world test (other than a large interactive
-userbase) is using toybox as the command line in a build system such as
-<a href=https://landley.net/aboriginal/about.html>Aboriginal
-Linux</a>, having it rebuild itself from source code, and using the result
-to <a href=https://github.com/landley/control-images>build Linux From Scratch</a>.
-The current "minimal native development system" goal is to use
-<a href=faq.html#mkroot>mkroot</a>
-plus <a href=faq.html#cross>musl-cross-make</a> to hermetically build
-<a href=https://source.android.com>AOSP</a>.</p>
-
-<p>We've also checked what commands were provided by similar projects
-(klibc, sash, sbase, embutils,
-nash, and beastiebox), looked at various vendor configurations of busybox,
-and collected end user requests.</p>
-
-<p>Finally, we'd like to provide a good replacement for the Bash shell,
-which was the first program Linux ever ran and remains the standard shell
-of Linux (no matter what Ubuntu says). This doesn't necessarily mean including
-every last Bash 5.x feature, but does involve {various,features} &lt(beyond)
-posix.</p>
-
-<p>See the <a href=status.html>status page</a> for the categorized command list
-and progress towards implementing it. There's also a
-<a href=todo.html>historical todo list</a> from the project's 2011 relaunch.</p>
-
 <hr />
 <a name="standards">
 <h2>Use case: standards compliance.</h2>
@@ -70,58 +53,44 @@
 <p>The best standards describe reality rather than attempting to impose a
 new one. A good standard should document, not legislate.
 Standards which document existing reality tend to be approved by
-more than one standards body, such ANSI and ISO both approving <a href=https://landley.net/c99-draft.html>C99</a>. That's why IEEE 1003.1-2008,
-the Single Unix Specification version 4, and the Open Group Base Specification
-edition 7 are all the same standard from three sources, but most people just
-call it "posix" (portable operating system derived from unix).
-It's available <a href=https://pubs.opengroup.org/onlinepubs/9699919799>online in full</a>, and may be downloaded as a tarball.
-Previous versions (<a href=https://pubs.opengroup.org/onlinepubs/009695399/>SUSv3</a> and
-<a href=https://pubs.opengroup.org/onlinepubs/7990989775/>SUSv2</a>)
-are also available.
-(Note: 
-<a href=https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/>Posix
-2008</a> was reissued in 2013 and 2018, the first was minor wordsmithing
-with no behavioral changes, the second was to renew a ten year timeout
-to still be considered a "current standard" by some government regulations.
-It's still posix-2008/SUSv4/issue 7.)</p>
+more than one standards body, such ANSI and ISO both approving <a href=https://landley.net/c99-draft.html>C99</a>. That's why
+the IEEE POSIX committee's 2008 standard, the Single Unix Specification version
+4, and the Open Group Base Specification edition 7 are all the same standard
+from three sources, but most people just call it "posix" (portable operating
+system derived from unix). It's available <a href=https://pubs.opengroup.org/onlinepubs/9699919799>online in full</a>, and may be downloaded as a tarball...
+with a caveat.</p>
+
+<p>Although previous versions of Posix have their own
+stable URLs (where you can still find
+<a href=https://pubs.opengroup.org/onlinepubs/009695399/>SUSv3</a> and
+<a href=https://pubs.opengroup.org/onlinepubs/7990989775/>SUSv2</a>),
+the 2008 release of SUSv4 was replaced by a 2013 release also claiming
+to be SUSv4, then again by a 2018 release still at the same URL. Similarly,
+the other version numbers claim not to have changed, but instead adopted some
+sort of "Windows 95" naming scheme ("The Open Group Base Specifications Issue
+7, 2018 edition"). Since a moving target isn't a standard, we've stuck
+with the 2008 version and ignored whatever changes they make
+until they stop this forced-upgrade-behind-your back nonsense.
+Luckily you can still find the original content
+<a href=https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/>here</a>.
+(We haven't changed the URLs in each command to the longer version yet,
+but can if conflicts arise.)</p>
 
 <h3>Why not just use posix for everything?</h3>
 
-<p>Unfortunately, Posix describes an incomplete subset of reality, because
-it was designed to. It started with proprietary unix vendors collaborating to
-describe the functionality their fragmented APIs could agree on, which was then
-incorporated into <a href=https://nvlpubs.nist.gov/nistpubs/Legacy/FIPS/fipspub151-2-1993.pdf>US federal procurement standards</a>
-as a <a href=https://www.youtube.com/watch?v=nwrTTXOg-KI>compliance requirement</a>
-for things like navy contracts, giving large corporations
-like IBM and Microsoft millions of dollars of incentive
-to punch holes in the standard big enough to drive
-<a href=https://en.wikipedia.org/wiki/Microsoft_POSIX_subsystem>Windows NT</a> and
-<a href=http://www.naspa.net/magazine/1996/May/T9605006.PDF>OS/360</a> through.
-When open source projects like Linux started developing on the internet
-(enabled by the 1993 relaxation of the National Science Foundation's
-"Acceptable Use Policy" allowing everyone to connect to the internet,
-previously restricted to approved government/military/university organizations),
-Posix <a href=http://www.opengroup.org/testing/fips/policy_info.html>ignored
-the upstarts</a> and Linux eventually
-<a href=https://www.linuxjournal.com/article/3417>returned the favor</a>,
-leaving Posix behind.</p>
-
-<p>The result is a "standard" that lacks any mention of commands like
-"init" or "mount" required to actually boot a system.
-It describes logname but not login. It provides ipcrm
+<p>Unfortunately posix describes an incomplete subset of reality,
+lacking any mention of commands such as init or mount required to
+actually boot a system. It describes logname but not login. It provides ipcrm
 and ipcs, but not ipcmk, so you can use System V IPC resources but not create
 them. And widely used real-world commands such as tar and cpio (the basis
 of initramfs and RPM) which were present in earlier
 versions of the standard have been removed, while obsolete commands like
 cksum, compress, sccs and uucp remain with no mention of modern counterparts
-like crc32/sha1sum, gzip/xz, svn/git or scp/rsync. Meanwhile posix' description
-of the commands
+like crc32/sha1sum, gzip/xz, svn/git or scp/rsync. Meanwhile the commands
 themselves are missing dozens of features and specify silly things like ebcdic
 support in dd or that wc should use %d (not %lld) for byte counts. So
 we have to extensively filter posix to get a useful set of recommendations.</p>
 
-<h3>Analysis</h3>
-
 <p>Starting with the
 <a href="http://pubs.opengroup.org/onlinepubs/9699919799.2008edition/idx/utilities.html">full "utilities" list</a>,
 we first remove generally obsolete
@@ -131,18 +100,18 @@
 qalter qdel qhold qmove qmsg qrerun qrls qselect qsig qstat qsub).</p>
 
 <p>Some commands are for a compiler toolchain (ar c99 cflow ctags cxref gencat
-iconv lex m4 make nm strings strip tsort yacc) which is outside of toybox's
+iconv lex m4 make nm strings strip tsort yacc), which is outside of toybox's
 mandate and should be supplied externally. (Again, some of these may be
 revisited later, but not for toybox 1.0.)</p>
 
 <p>Some commands are part of a command shell, and can't be implemented as
 separate executables (alias bg cd command fc fg getopts hash jobs kill read
-type ulimit umask unalias wait). These may be revisited as part of the built-in
+type ulimit umask unalias wait). These may be revisited as part of a built-in
 toybox shell, but are not exported into $PATH via symlinks. (If you fork a
 child process and have it "cd" then exit, you've accomplished nothing.)
 Again, what posix provides is incomplete: a shell also needs exit, if, while,
 for, case, export, set, unset, trap, exec... (And for bash compatibility
-function, source, declare...)</p>
+function, source...)</p>
 
 <p>A few other commands are judgement calls, providing command-line
 internationalization support (iconv locale localedef), System V inter-process
@@ -153,8 +122,7 @@
 exactly?  (cups?)  The standard defines crontab but not crond. What is
 pathchk supposed to be portable _to_? (Linux accepts 255 byte path components
 with any char except NUL or / and no max length on the total path, and
-<a href=https://yarchive.net/comp/linux/utf8.html>EXPLICITLY</a>
-doesn't care if it's an invalid utf8 sequence.)</p>
+EXPLICITLY doesn't care if it's an invalid utf8 sequence.)</p>
 
 <p>Removing all of that leaves the following commands, which toybox should
 implement:</p>
@@ -175,41 +143,37 @@
 
 <p>One attempt to supplement POSIX towards an actual usable system was the
 Linux Standard Base. Unfortunately, the quality of this "standard" is
-fairly low, largely due to the Free Standards Group that maintained it
-being consumed by <a href=https://landley.net/notes-2010.html#18-07-2010>the Linux Foundation</a> in 2007.</p>
+fairly low.</p>
 
-<p>Where POSIX allowed its standards process to be compromised
-by leaving things out (but what
-they DID standardize tends to be respected, if sometimes obsolete),
-the Linux Standard Base's failure mode is different. They respond to
+<p>POSIX allowed its standards process to be compromised
+by leaving things out, thus allowing IBM mainframes and Windows NT to drive
+a truck through the holes and declare themselves compilant. But it means what
+they DID standardize tends to be respected (if sometimes obsolete).</p>
+
+<p>The Linux Standard Base's failure mode is different, they respond to
 pressure by including anything their members pay them enough to promote,
 such as allowing Red Hat to push
 RPM into the standard even though all sorts of distros (Debian, Slackware, Arch,
-Gentoo, Android) don't use it and never will. This means anything in the LSB is
+Gentoo) don't use it and never will. This means anything in the LSB is
 at best a suggestion: arbitrary portions of this standard are widely
 ignored.</p>
 
-<p>The <a href=https://mjg59.dreamwidth.org/39546.html>community perception</a>
-seems to be that the Linux Standard Base is
+<p>The community perception seems to be that the Linux Standard Base is
 the best standard money can buy, I.E. the Linux Foundation is supported by
 financial donations from large companies and the LSB
 <a href=https://www.softwarefreedom.org/blog/2016/apr/11/lf/>represents the interests
-of those donors</a> regardless of technical merit. (The Linux Foundation, which
+of those donors</a> more than technical merit. (The Linux Foundation, which
 maintains the LSB, isn't a 501c3. It's a 501c6, the
-same kind of legal entity as the Tobacco Institute and
-<a href=https://lwn.net/Articles/706585/>Microsoft's</a>
-old "<a href=https://en.wikipedia.org/wiki/Don%27t_Copy_That_Floppy>Don't Copy That Floppy</a>" program.) Debian officially
-<a href=http://lwn.net/Articles/658809>washed its hands of LSB</a> by
-refusing to adopt release 5.0 in 2015, and no longer even pretends to support
-it (which affect Debian derivatives like Ubuntu and Knoppix). Toybox has
-stayed on 4.1 for similar reasons: a lot of historical effort went into
-producing the standard before the Linux Foundation took over.</p>
+same kind of legal entity as the Tobacco Institute and Microsoft's old
+"Don't Copy That Floppy" program.) Debian officially
+<a href=http://lwn.net/Articles/658809>washed its hands of LSB</a> when 5.0
+came out in 2015, and no longer even pretends to support it (which may affect
+Debian derivatives like Ubuntu and Knoppix). Toybox hasn't moved to 5.0 for
+similar reasons.</p>
 
 <p>That said, Posix by itself isn't enough, and this is the next most
 comprehensive standards effort for Linux so far, so we salvage what we can.</p>
 
-<h3>Analysis</h3>
-
 <p>The LSB specifies a <a href=http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/cmdbehav.html>list of command line
 utilities</a>:</p>
 
@@ -249,23 +213,12 @@
 </span>
 </b></blockquote>
 
-<h3><a name=rfc /><a href="#rfc">IETF RFCs and Man Pages</a></h3>
-
-<p>They're very nice, but there's thousands of them.</p>
+<h3><a name=rfc /><a href="#rfc">IETF RFCs</a></h3>
 
 <p>Discussion of standards wouldn't be complete without the Internet
-Engineering Task Force's "<a href=https://www.rfc-editor.org/in-notes/rfc-index.txt>Request For Comments</a>" collection and Michael Kerrisk's
-<a href=https://www.kernel.org/doc/man-pages/>Linux man-pages project</a>.
-Except these aren't standards, they're collections of documentation with
-low barriers to inclusion. They're not saying "you should support
-X", they're saying "if you do, here's how".
-Thus neither really helps us select which commands to include.</p>
+Engineering Task Force's "<a href=https://www.rfc-editor.org/in-notes/rfc-index.txt>Request For Comments</a>" collection.</p>
 
-<p>The man pages website includes the commands in git, yum, perf, postgres,
-flatpack... Great for examining the features of a command you've
-already decided to include, useless for deciding _what_ to include.</p>
-
-<p>The RFCs are more about protocols than commands. The noise level is
+<p>These are more about protocols than commands. The noise level is
 extremely high: there's thousands of RFCs, many describing a proposed idea
 that never took off, and less than 1% of the resulting documents are
 currently relevant to toybox. And the documents are numbered based on the
@@ -276,9 +229,9 @@
 they <a href=https://www.ietf.org/rfc/rfc4330.txt>document</a> is to find an <a href=https://www.ietf.org/rfc/rfc1769.txt>earlier version</a> to read first.</p>
 
 <p>That said, RFC documents can be useful (especially for networking protocols)
-and the four URL templates the recommended starting files
+and the three URL templates the recommended starting files
 for new commands (toys/example/skeleton.c or toys/example/hello.c depending on how much
-plumbing you want to start with) provide point to posix, lsb, man, and
+plumbing you want to start with) provide point to are posix, lsb, and
 rfc pages.</p>
 
 <hr />
@@ -337,7 +290,7 @@
 supply adequate replacements:</p>
 
 <blockquote><b>
-awk dd diff expr fdisk ftpd gzip less route sh tr unxz vi wget xzcat
+awk dd diff expr fdisk ftpd gzip less route sh sha512sum tr unxz vi wget xzcat
 </b></blockquote>
 
 <p>All of those except awk, ftpd, and less have partial implementations
@@ -360,7 +313,7 @@
 <a href=http://landley.net/aboriginal/about.html#hairball>modifying the AOSP build</a>
 to reduce dependencies. (It's fairly likely we'll have to add at least
 a read-only git utility so repo can download the build's source code,
-but that's actually <a href=https://www.youtube.com/watch?v=I-lGyn3PHP4>not
+but that's actually <a href=https://www.youtube.com/watch?v=P7n6G2IL6eo>not
 that hard</a>. We'll probably also need our own "make" at some point after
 1.0, which is its own moving target thanks to cmake and ninja and so on.)
 The ongoing Android <a href=http://lists.landley.net/pipermail/toybox-landley.net/2018-January/009330.html>hermetic build</a> work is already advancing
@@ -520,33 +473,21 @@
 <hr />
 <h2><a name=tizen /><a href="#tizen">Use case: Tizen Core</a></h2>
 
-<p>A side effect of the Linux Foundation following the money to the
-exclusion of all else is they "support" their donors' myriad often
-contradictory pet projects with elaborate announcements and press releases.
-Long ago when Nokia's Maemo merged
-with Intel's Moblin to form <a href=https://www.linuxfoundation.org/press-release/linux-foundation-to-host-meego-project/>MeeGo</a>, there were believable <a href=https://www.linuxfoundation.org/press-release/public-support-for-the-meego-project/>statements</a>
-about unifying fragmented vendor efforts. Then MeeGo merged with
-<a href=http://en.wikipedia.org/wiki/LiMo_Foundation>LiMo</a> to
-<a href=notes-2012.html#16-05-2012>form Tizen</a>,
-which became a Samsung-only project (that <a href=https://www.androidheadlines.com/2021/05/samsung-tvs-continue-use-tizen-os.html>still ships</a>
-inside <a href=https://twitter.com/cstross/status/1453747613686288385>televisions</a>,
-but was otherwise subsumed into <a href=https://www.theverge.com/2021/5/18/22440483/samsung-smartwatch-google-wearos-tizen-watch>Android GO</a>).</p>
-
-<p>Along the way, the Tizen project expressed a desire to eliminate GPLv3 software
-from its core system, and in installing toybox as
+<p>The Tizen project has expressed a desire to eliminate GPLv3 software
+from its core system, and is installing toybox as
 <a href=https://wiki.tizen.org/wiki/Toybox>part of this process</a>.</p>
 
-<p>They had a fairly long list of new commands they wanted to see in toybox:</p>
+<p>They have a fairly long list of new commands they'd like to see in toybox:</p>
 
 <blockquote><b>
-<span id=tizen_cmd>
+<span id=tizen>
 arch base64 users unexpand shred join csplit
 hostid nproc runcon sha224sum sha256sum sha384sum sha512sum sha3sum mkfs.vfat fsck.vfat 
-dosfslabel uname pinky diff3 sdiff zcmp zdiff zegrep zfgrep zless zmore
+dosfslabel uname stdbuf pinky diff3 sdiff zcmp zdiff zegrep zfgrep zless zmore
 </span>
 </b></blockquote>
 
-<p>In addition, they wanted to use several commands then in pending:</p>
+<p>In addition, they'd like to use several commands currently in pending:</p>
 
 <blockquote><b>
 <span id=tizen>
@@ -555,108 +496,28 @@
 </b></blockquote>
 
 <p>Also, tizen uses a different Linux Security Module called SMACK, so
-many of the SELinux options ala ls -Z needed smack alternatives in an
-if/else setup. (We added lib/lsm.h to abstract this.)</p>
-
-<hr />
-<h2><a name=yocto /><a href="#yocto">Use case: Yocto</a></h2>
-
-<p>Another project the Linux Foundation is paid to appreciate is Yocto,
-which was designed to fix the ongoing proprietary fragmentation problem
-(now in Linux build systems instead of vendor unix forks) by being the
-build system equivalent of a glue trap. While proclaiming that having the
-"minimum level of standardization" contributes to a "strong ecosystem",
-Yocto uses a "<a href=https://www.yoctoproject.org/software-overview/layers/>layered</a>"
-design where everybody who touches it is encouraged to add more and more layers
-of metadata on top of what came before, until they wind up <a href=https://github.com/varigit/variscite-bsp-platform>using repo</a> just to manage
-the layers (let alone their contents). But -- and this is the
-important bit -- all these dispirate forks are called "yocto" and built on
-top of giant piles of code the Linux Foundation can take credit for
-since they filed the serial numbers off OpenEmbedded.</p>
-
-<p>Yocto's "core-image-minimal" target (only 3,106 build steps in the 3.3
-release, which believe it or not is
-<a href=https://landley.net/notes-2019.html#06-02-2019>an improvement</a>) builds a busybox-based system with the following commands:</p>
-
-<blockquote><b>
-<span id=yocto_cmd>
-addgroup adduser ascii sh awk base32 basename blkid bunzip2 bzcat bzip2 cat
-chattr chgrp chmod chown chroot chvt clear cmp cp cpio crc32 cut date dc dd
-deallocvt delgroup deluser depmod df diff dirname dmesg dnsdomainname du
-dumpkmap dumpleases echo egrep env expr false fbset fdisk fgrep find flock
-free fsck fstrim fuser getopt getty grep groups gunzip gzip head hexdump
-hostname hwclock id ifconfig ifdown ifup insmod ip kill killall klogd less
-ln loadfont loadkmap logger logname logread losetup ls lsmod lzcat md5sum
-mesg microcom mkdir mkfifo mknod mkswap mktemp modprobe more mount mountpoint
-mv nc netstat nohup nproc nslookup od openvt patch pgrep pidof pivot_root
-printf ps pwd rdate readlink realpath reboot renice reset resize rev rfkill
-rm rmdir rmmod route run-parts sed seq setconsole setsid sh sha1sum sha256sum
-shuf sleep sort start-stop-daemon stat strings stty sulogin swapoff swapon
-switch_root sync sysctl syslogd tail tar tee telnet test tftp time top touch
-tr true ts tty udhcpc udhcpd umount uname uniq unlink unzip uptime users
-usleep vi watch wc wget which who whoami xargs xzcat yes zcat
-</span>
-</b></blockquote>
-
-
-
-<a name="fhs" />
-<hr /><a href=fhs>Filesystem Hierachy Standard</a>
-<h2>Filesystem Hierarchy Standard:</h2>
-
-<p>Another standard taken over by the Linux Foundation. (At least the
-links to this one didn't <a href=http://lanana.org/>go 404</a> the
-instant they took it over). Of historical interest due to what it
-managed to achieve before they chased away the hobbyists maintaining it.
-Only one version (3.0 in 2015) has been released since the Linux Foundation
-absorbed the FHS. The previous release, Version 2.3, was released in 2004.
-The Linux Foundation did not retain earlier versions. The contents of
-the relevant sections appear identical between the two versions, the
-Linux Foundation just added section numbers.</p>
-
-<p><a href=https://refspects.linuxfoundation.org/FHS_3.0/fhs-3.0.html>FHS 3.0</a>
-section 3.4.2 requires commands to be in the /bin directory, and then 3.4.3
-has an optional list,
-and then 3.16.2 and 3.16.3 similarly cover /sbin. There are linux
-specific sections in 6.1.2 and 6.1.6 but everything in them is obsolete.</p>
-
-<p>The /bin options include csh but not bash, and ed but not vi.
-The /sbin options have update which seems obsolete (filesystem
-buffers haven't needed a userspace process to flush them for DECADES),
-fastboot and fasthalt (reboot and halt have -nf), and
-fsck.* and mkfs.* that don't actually specify any specific filesystems.
-Removing that gives us:</p>
-
-<blockquote><b>
-<span id=fhs_cmd>
-cat chgrp chmod chown cp date dd df dmesg echo false hostname kill ln
-login ls mkdir mknod more mount mv ps pwd rm rmdir sed sh stty su sync true
-umount uname tar cpio gzip gunzip zcat netstat ping
-shutdown fdisk getty halt ifconfig init mkswap reboot route swapon swapoff
-</span>
-</b></blockquote>
+many of the SELinux options ala ls -Z need smack alternatives in an
+if/else setup.</p>
 
 <hr /><a name=buildroot />
 <h2>buildroot:</h2>
 
-<p>If a toybox-based development environment is to support running
-buildroot under it, the <a href=https://buildroot.org/downloads/manual/manual.html#requirement-mandatory>mandatory packages</a>
+<p>The <a href=https://buildroot.org/downloads/manual/manual.html#requirement-mandatory>mandatory packages</a>
 section of the buildroot manual lists:</p>
 
-<blockquote><p><b>
+<blockquote><p>
 which sed make bash patch gzip bzip2 tar cpio unzip rsync file bc wget
-</b></p></blockquote>
+</p></blockquote>
 
 <p>(It also lists binutils gcc g++ perl python, and for debian it wants
 build-essential. And it wants file to be in /usr/bin because
 <a href=https://git.busybox.net/buildroot/tree/support/dependencies/dependencies.sh?h=2018.02.x#n84>libtool
 breaks otherwise</a>.)</p>
 
-<p>Oddly, buildroot can't NOT cross compile. Buildroot does not support a cross toolchain that lives in "/usr/bin"
+<p>Buildroot does not support a cross toolchain that lives in "/usr/bin"
 with a prefix of "" (if you try, and chop out the test for a blank prefix,
-it dies trying to run "/usr/bin/-gcc"). You can patch your way to
-making it work if you try, but buildroot's developers explicitly do not
-support this.</p>
+it dies trying to run "/usr/bin/-gcc"). But you can patch your way to
+making it work if you try.</p>
 
 <hr /><a name=klibc />
 <h2>klibc:</h2>
@@ -668,7 +529,7 @@
 <a href=http://www.infoworld.com/d/data-center/perl-isnt-going-anywhere-better-or-worse-211580>requires perl to build</a>, and seems like an ideal candidate for
 replacement.</p>
 
-<p>In addition to a C library less general-purpose than bionic (let alone
+<p>In addition to a C library even less capable than bionic (obsoleted by
 musl), klibc builds a random assortment of executables to run init scripts
 with. There's no multiplexer command, these are individual executables:</p>
 
@@ -691,20 +552,26 @@
 (And sha1hash is just an unpolished sha1sum anyway.)</p>
 
 <p>The run-init command is more commonly called switch_root, nuke is just
-"rm -rf -- $@", and minips is more commonly called "ps": I'm not doing aliases
-for these oddball names.
-The "kinit" command is another gratuitous rename, it's init running as PID 1.
+"rm -rf -- $@", and minips is more commonly called "ps". I'm not doing aliases
+for the oddball names.</p>
+
+<p>Yet more stale forks of dash and gzip sucked in here (see "dubious
+license terms" above), adding nothing to the other projects we've looked at.
+But we still need sh, gunzip, gzip, and zcat to replace this package.</p>
+
+<p>At the time I did the initial analysis toybox already had cat, chroot, dmesg, false,
+kill, ln, losetup, ls, mkdir, mkfifo, readlink, rm, switch_root, sleep, sync,
+true, and uname.</p>
+
+<p>The low hanging fruit is cpio, dd, ps, mv, and pivot_root.</p>
+
+<p>The "kinit" command is another gratuitous rename, it's init running as PID 1.
 The halt, poweroff, and reboot commands work with it.</p>
 
-<p>Yet more stale forks of dash and gzip got sucked in here (see "dubious
-license terms" above).
-
-<p>In theory "blkid" or "file" handle fstype (and df for mounted filesystems),
-but we could do fstype.</p>
-
-<p>We should implement nfsmount, and probably smbmount
-and p9mount even though this hasn't got one. The reason these aren't
-in the base "mount" command is they interactively query login credentials.</p>
+<p>I've got mount and umount queued up already, fstype and nfsmount go with
+those. (And probably smbmount and p9mount, but this hasn't got one. Those
+are all about querying for login credentials, probably workable into the
+base mount command.)</p>
 
 <p>The ipconfig command here has a built in dhcp client, so it's ifconfig
 and dhcpcd and maybe some other stuff.</p>
@@ -718,12 +585,12 @@
 make use of klibc for this.
 Given the history of swsusp/hibernate (and 
 <a href=http://lwn.net/Articles/333007>TuxOnIce</a>
-and <a href=http://lwn.net/Articles/242107>kexec jump</a>...) I've lost track
+and <a href=http://lwn.net/Articles/242107>kexec jump</a>) I've lost track
 of the current state of the art here. Ah, Documentation/power/userland-swsusp.txt
 has the API docs, and <a href=http://suspend.sf.net>here's a better
 tool</a>...</p>
 
-<p>This gives us a klibc command list:</p>
+<p>So the list of things actually in klibc are:</p>
 
 <blockquote><b>
 <span id=klibc_cmd>
@@ -750,26 +617,29 @@
 mtrace nscd rpcent rpcinfo tzselect zdump zic
 </b></blockquote>
 
-<p>Of those, musl libc only implements ldd. Of the rest:</p>
+<p>Of those, musl libc only implements ldd.</p>
 
-<ul>
-<li><b>catchsegv</b> is a rudimentary debugger, probably out of scope for toybox.</li>
-<li><b>iconv</b> has been <a href="#susv4">previously discussed</a>.</li>
-<li><b>iconvconfig</b> is only relevant if iconv is user-configurable; musl uses a
-non-configurable iconv.</li>
-<li><b>getconf</b> is a posix utility which displays several variables from 
-unistd.h; it probably belongs in the development toolchain.</li>
-<li><b>getent</b> handles retrieving entries from passwd-style databases
-(in a rather lame way) and is trivially replacable by grep.</li>
-<li><b>locale</b> was discussed under <a href=#susv4>posix</a>.
-localedef compiles locale definitions, which musl currently does not use.</li>
-<li><b>mtrace</b> is a perl script to use the malloc debugging that glibc has built-in;
-this is not relevant for musl, and would necessarily vary with libc.</li>
-<li><b>nscd</b> is a name service caching daemon, which is not yet relevant for musl.</li>
-<li><b>rpcinfo</b> and <b>rpcent</b> are related to the Remote Procedure Calls
-layer (an old sun technology used by some userspace NFS implementations),
-which musl does not include and debian does not install by default.</li>
-</ul>
+<p>catchsegv is a rudimentary debugger, probably out of scope for toybox.</p>
+
+<p>iconv has been <a href="#susv4">previously discussed</a>.</p>
+
+<p>iconvconfig is only relevant if iconv is user-configurable; musl uses a
+non-configurable iconv.</p>
+
+<p>getconf is a posix utility which displays several variables from 
+unistd.h; it probably belongs in the development toolchain.</p>
+
+<p>getent handles retrieving entries from passwd-style databases
+(in a rather lame way) and is trivially replacable by grep.</p>
+
+<p>locale was discussed under <a href=#susv4>posix</a>.
+localedef compiles locale definitions, which musl currently does not use.</p>
+
+<p>mtrace is a perl script to use the malloc debugging that glibc has built-in;
+this is not relevant for musl, and would necessarily vary with libc. </p>
+
+<p>nscd is a name service caching daemon, which is not yet relevant for musl.
+rpcinfo and rpcent are related to rpc, which musl does not include.</p>
 
 <p>The remaining commands involve glibc's bundled timezone database,
 which seems to be derived from the <a href=http://www.iana.org/time-zones>IANA
@@ -777,17 +647,14 @@
 standards body's database like glibc does, these are of no interest,
 but for completeness:</p>
 
-<ul>
-<li><b>tzselect</b> outputs a TZ variable correponding to user input. 
+<p>tzselect outputs a TZ variable correponding to user input. 
 The documentation does not indicate how to use it in a script, but it seems
-that Debian may have done so.</li>
-<li><b>zdump</b> prints current time in each of several timezones, optionally
-outputting a great deal of extra information about each timezone.</li>
-<li><b>zic</b> converts a description of a timezone to a file in tz format.</li>
-</ul>
+that Debian may have done so.
+zdump prints current time in each of several timezones, optionally
+outputting a great deal of extra information about each timezone.
+zic converts a description of a timezone to a file in tz format.</p>
 
-<p>We implemented getconf, and I could see maybe arguing for ncsd.
-The rest are not relevant to toybox.</p>
+<p>None of glibc's bundled commands are currently of interest to toybox.</p>
 
 </b></blockquote>
 
@@ -1227,7 +1094,7 @@
 blockdev rpm2cpio arping brctl dumpleases fsck
 tcpsvd tftpd
 factor fallocate fsfreeze inotifyd lspci nbd-client partprobe strings
-base32 base64 mix
+base64 mix
 reset hexedit nsenter shred
 fsync insmod ionice lsmod lsusb rmmod vmstat xxd top iotop
 lsof ionice compress dhcp dhcpd addgroup delgroup host iconv ip
@@ -1239,9 +1106,6 @@
 ascii crc32 devmem fmt i2cdetect i2cdump i2cget i2cset mcookie prlimit sntp ulimit uuidgen dhcp6 ipaddr iplink iproute iprule iptunnel cd exit toysh bash traceroute6
 blkdiscard rtcwake
 watchdog
-pwgen readelf unicode
-rsync
-linux32 hd strace
 </span>
 </b></blockquote>
 
diff --git a/www/status.html b/www/status.html
new file mode 100755
index 0000000..8a1a585
--- /dev/null
+++ b/www/status.html
@@ -0,0 +1,9 @@
+<html><head><title>toybox current status</title>
+<!--#include file="header.html" -->
+<title>Toybox Status</title>
+
+<!--#include file="status.gen" -->
+
+<p>See the <a href=roadmap.html>Roadmap page</a> for more information.</p>
+
+<!-- #include "footer.html" -->
diff --git a/www/towel.jpg b/www/towel.jpg
deleted file mode 100644
index f836310..0000000
--- a/www/towel.jpg
+++ /dev/null
Binary files differ
diff --git a/www/toycans-big.jpg b/www/toycans-big.jpg
deleted file mode 100644
index 70e9638..0000000
--- a/www/toycans-big.jpg
+++ /dev/null
Binary files differ