aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2022-04-19 01:14:22 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2022-04-19 01:14:22 +0000
commit52a5af013efa6ca0150d5f07a25cb87361b728a7 (patch)
treed0e498a531fab84c92b3ab6e9eade306d7918165
parentbc93cfd83482cfe1b91c98ae2c294a5c63720f5c (diff)
parenta30dc69f0f91476e8b3acf750d82908c9711724c (diff)
downloadtoybox-52a5af013efa6ca0150d5f07a25cb87361b728a7.tar.gz
Upgrade toybox to 8b97a1fb86b06e329c77c64cdbef29d7738f5840 am: 1ef443927d am: cff1e61b1d am: 0828795579 am: 2cc84e6d13 am: a30dc69f0f
Original change: https://android-review.googlesource.com/c/platform/external/toybox/+/2066960 Change-Id: Ia8548e2fa16d2d054e68f1ba2774d58dfa3dd464 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--.config-device1
-rw-r--r--.config-linux1
-rw-r--r--.config-mac1
-rw-r--r--Config.in6
-rw-r--r--METADATA6
-rw-r--r--Makefile10
-rw-r--r--android/device/generated/config.h2
-rw-r--r--android/device/generated/flags.h41
-rw-r--r--android/device/generated/globals.h21
-rw-r--r--android/device/generated/help.h20
-rw-r--r--android/device/generated/newtoys.h12
-rw-r--r--android/linux/generated/config.h2
-rw-r--r--android/linux/generated/flags.h41
-rw-r--r--android/linux/generated/globals.h21
-rw-r--r--android/linux/generated/help.h20
-rw-r--r--android/linux/generated/newtoys.h12
-rw-r--r--android/mac/generated/config.h2
-rw-r--r--android/mac/generated/flags.h41
-rw-r--r--android/mac/generated/globals.h21
-rw-r--r--android/mac/generated/help.h20
-rw-r--r--android/mac/generated/newtoys.h12
-rwxr-xr-xconfigure15
-rw-r--r--kconfig/kconfig-language.txt284
-rw-r--r--lib/args.c3
-rw-r--r--lib/lib.c34
-rw-r--r--lib/lib.h2
-rw-r--r--lib/portability.c35
-rw-r--r--lib/toyflags.h6
-rw-r--r--lib/xwrap.c7
-rw-r--r--main.c22
-rwxr-xr-xscripts/change.sh6
-rwxr-xr-xscripts/genconfig.sh12
-rwxr-xr-xscripts/install.sh10
-rwxr-xr-xscripts/make.sh104
-rwxr-xr-xscripts/mkroot.sh18
-rw-r--r--scripts/portability.sh18
-rw-r--r--tests/tar.test17
-rw-r--r--toys/example/README25
-rw-r--r--toys/example/hello.c5
-rw-r--r--toys/example/skeleton.c3
-rw-r--r--toys/lsb/mount.c6
-rw-r--r--toys/net/ifconfig.c10
-rw-r--r--toys/other/chvt.c33
-rw-r--r--toys/other/factor.c20
-rw-r--r--toys/other/ionice.c2
-rw-r--r--toys/other/openvt.c115
-rw-r--r--toys/other/readlink.c9
-rw-r--r--toys/pending/openvt.c102
-rw-r--r--toys/pending/sh.c13
-rw-r--r--toys/pending/wget.c258
-rw-r--r--toys/posix/file.c51
-rw-r--r--toys/posix/tar.c82
-rw-r--r--www/roadmap.html2
53 files changed, 967 insertions, 675 deletions
diff --git a/.config-device b/.config-device
index 1605d11f..196378ec 100644
--- a/.config-device
+++ b/.config-device
@@ -8,6 +8,7 @@
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
diff --git a/.config-linux b/.config-linux
index 937a8ebd..0a542595 100644
--- a/.config-linux
+++ b/.config-linux
@@ -8,6 +8,7 @@
# 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
diff --git a/.config-mac b/.config-mac
index dd6a3d9a..3770579e 100644
--- a/.config-mac
+++ b/.config-mac
@@ -8,6 +8,7 @@
# 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
diff --git a/Config.in b/Config.in
index b626f3c1..62185dfb 100644
--- a/Config.in
+++ b/Config.in
@@ -136,12 +136,6 @@ config TOYBOX_DEBUG
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 500cd283..191882c0 100644
--- a/METADATA
+++ b/METADATA
@@ -9,11 +9,11 @@ third_party {
type: GIT
value: "https://github.com/landley/toybox"
}
- version: "8a23ac205cb4995d4510a5af880939eda4a5343e"
+ version: "8b97a1fb86b06e329c77c64cdbef29d7738f5840"
license_type: UNENCUMBERED
last_upgrade_date {
year: 2022
- month: 3
- day: 16
+ month: 4
+ day: 18
}
}
diff --git a/Makefile b/Makefile
index 032e70d4..40987027 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 care called through "make".
+# used when scripts/make.sh and such called through "make".
HOSTCC?=cc
@@ -41,13 +41,13 @@ baseline: generated/unstripped/toybox
bloatcheck: generated/unstripped/toybox_old generated/unstripped/toybox
@scripts/bloatcheck generated/unstripped/toybox_old generated/unstripped/toybox
-install_flat:
+install_flat: toybox
scripts/install.sh --symlink --force
-install_airlock:
+install_airlock: toybox
scripts/install.sh --symlink --force --airlock
-install:
+install: toybox
scripts/install.sh --long --symlink --force
uninstall_flat:
@@ -65,7 +65,7 @@ root_clean:
clean::
@chmod -fR 700 generated || true
- @rm -rf toybox generated change .singleconfig*
+ @rm -rf toybox generated change install .singleconfig*
@echo cleaned
# If singlemake was in generated/ "make clean; make test_ls" wouldn't work.
diff --git a/android/device/generated/config.h b/android/device/generated/config.h
index 6b15e9f3..415d99e8 100644
--- a/android/device/generated/config.h
+++ b/android/device/generated/config.h
@@ -2,6 +2,8 @@
#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
diff --git a/android/device/generated/flags.h b/android/device/generated/flags.h
index 2140209b..ced393db 100644
--- a/android/device/generated/flags.h
+++ b/android/device/generated/flags.h
@@ -1535,9 +1535,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
@@ -2248,9 +2248,9 @@
#undef FLAG_n
#endif
-// openvt c#<1>63sw
+// openvt ^<1c#<1>63sw
#undef OPTSTR_openvt
-#define OPTSTR_openvt "c#<1>63sw"
+#define OPTSTR_openvt "^<1c#<1>63sw"
#ifdef CLEANUP_openvt
#undef CLEANUP_openvt
#undef FOR_openvt
@@ -2534,14 +2534,6 @@
#undef FLAG_n
#endif
-// realpath <1 <1
-#undef OPTSTR_realpath
-#define OPTSTR_realpath "<1"
-#ifdef CLEANUP_realpath
-#undef CLEANUP_realpath
-#undef FOR_realpath
-#endif
-
// reboot d:fn
#undef OPTSTR_reboot
#define OPTSTR_reboot "d:fn"
@@ -3065,9 +3057,9 @@
#undef FLAG_f
#endif
-// tar &(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] &(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 &(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]
#undef OPTSTR_tar
-#define OPTSTR_tar "&(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 "&(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]"
#ifdef CLEANUP_tar
#undef CLEANUP_tar
#undef FOR_tar
@@ -3105,6 +3097,7 @@
#undef FLAG_full_time
#undef FLAG_restrict
#undef FLAG_selinux
+#undef FLAG_strip_components
#endif
// taskset <1^pa <1^pa
@@ -3638,12 +3631,13 @@
#undef FLAG_m
#endif
-// wget <1>1(max-redirect)#<0=20d(debug)O(output-document):
+// wget <1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):
#undef OPTSTR_wget
-#define OPTSTR_wget "<1>1(max-redirect)#<0=20d(debug)O(output-document):"
+#define OPTSTR_wget "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):"
#ifdef CLEANUP_wget
#undef CLEANUP_wget
#undef FOR_wget
+#undef FLAG_p
#undef FLAG_O
#undef FLAG_d
#undef FLAG_max_redirect
@@ -6065,13 +6059,6 @@
#define FLAG_n (1<<4)
#endif
-#ifdef FOR_realpath
-#define CLEANUP_realpath
-#ifndef TT
-#define TT this.realpath
-#endif
-#endif
-
#ifdef FOR_reboot
#define CLEANUP_reboot
#ifndef TT
@@ -6590,6 +6577,7 @@
#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
@@ -7084,9 +7072,10 @@
#ifndef TT
#define TT this.wget
#endif
-#define FLAG_O (FORCED_FLAG<<0)
-#define FLAG_d (FORCED_FLAG<<1)
-#define FLAG_max_redirect (FORCED_FLAG<<2)
+#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)
#endif
#ifdef FOR_which
diff --git a/android/device/generated/globals.h b/android/device/generated/globals.h
index 844f4d02..403077b0 100644
--- a/android/device/generated/globals.h
+++ b/android/device/generated/globals.h
@@ -397,6 +397,12 @@ struct oneit_data {
char *c;
};
+// toys/other/openvt.c
+
+struct openvt_data {
+ long c;
+};
+
// toys/other/pwgen.c
struct pwgen_data {
@@ -862,12 +868,6 @@ struct more_data {
int cin_fd;
};
-// toys/pending/openvt.c
-
-struct openvt_data {
- long c;
-};
-
// toys/pending/route.c
struct route_data {
@@ -1159,10 +1159,10 @@ struct vi_data {
// toys/pending/wget.c
struct wget_data {
- char *filename;
- long redirects;
+ char *p, *O;
+ long max_redirect;
- int sock;
+ int sock, https;
char *url;
#if CFG_WGET_LIBTLS
struct tls *tls;
@@ -1549,6 +1549,7 @@ struct tar_data {
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;
@@ -1678,6 +1679,7 @@ extern union global_union {
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;
@@ -1728,7 +1730,6 @@ extern union global_union {
struct mke2fs_data mke2fs;
struct modprobe_data modprobe;
struct more_data more;
- struct openvt_data openvt;
struct route_data route;
struct sh_data sh;
struct strace_data strace;
diff --git a/android/device/generated/help.h b/android/device/generated/help.h
index bc30cd0a..04e62120 100644
--- a/android/device/generated/help.h
+++ b/android/device/generated/help.h
@@ -4,8 +4,6 @@
#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."
@@ -126,7 +124,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)\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_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"
@@ -216,6 +214,12 @@
#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\""
@@ -312,8 +316,6 @@
#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."
@@ -348,7 +350,7 @@
#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\nexamples:\n wget http://www.example.com"
+#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_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."
@@ -408,10 +410,6 @@
#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_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"
@@ -530,7 +528,7 @@
#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 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 --selinux Record/restore labels\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_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_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)"
diff --git a/android/device/generated/newtoys.h b/android/device/generated/newtoys.h
index ea56d9d5..ade88313 100644
--- a/android/device/generated/newtoys.h
+++ b/android/device/generated/newtoys.h
@@ -1,4 +1,4 @@
-USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT))
+USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT|TOYFLAG_NOHELP))
USE_SH(OLDTOY(-bash, sh, 0))
USE_SH(OLDTOY(-sh, sh, 0))
USE_SH(OLDTOY(-toysh, sh, 0))
@@ -137,7 +137,7 @@ USE_INOTIFYD(NEWTOY(inotifyd, "<2", TOYFLAG_USR|TOYFLAG_BIN))
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))
@@ -201,7 +201,7 @@ 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, "c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
+USE_OPENVT(NEWTOY(openvt, "^<1c#<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))
@@ -224,7 +224,7 @@ USE_PWGEN(NEWTOY(pwgen, ">2r(remove):c(capitalize)n(numerals)y(symbols)s(secure)
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(NEWTOY(realpath, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+USE_REALPATH(OLDTOY(realpath, readlink, TOYFLAG_USR|TOYFLAG_BIN))
USE_REBOOT(NEWTOY(reboot, "d:fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
USE_RENICE(NEWTOY(renice, "<1gpun#|", TOYFLAG_USR|TOYFLAG_BIN))
USE_RESET(NEWTOY(reset, 0, TOYFLAG_USR|TOYFLAG_BIN))
@@ -274,7 +274,7 @@ 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, "&(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, "&(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_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))
@@ -321,7 +321,7 @@ USE_SH(NEWTOY(wait, "n", TOYFLAG_NOFORK))
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):", TOYFLAG_USR|TOYFLAG_BIN))
+USE_WGET(NEWTOY(wget, "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):", 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))
diff --git a/android/linux/generated/config.h b/android/linux/generated/config.h
index 45d2f917..7d2c7302 100644
--- a/android/linux/generated/config.h
+++ b/android/linux/generated/config.h
@@ -2,6 +2,8 @@
#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
diff --git a/android/linux/generated/flags.h b/android/linux/generated/flags.h
index 7a92c8da..2ab033b6 100644
--- a/android/linux/generated/flags.h
+++ b/android/linux/generated/flags.h
@@ -1535,9 +1535,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
@@ -2248,9 +2248,9 @@
#undef FLAG_n
#endif
-// openvt c#<1>63sw
+// openvt ^<1c#<1>63sw
#undef OPTSTR_openvt
-#define OPTSTR_openvt "c#<1>63sw"
+#define OPTSTR_openvt "^<1c#<1>63sw"
#ifdef CLEANUP_openvt
#undef CLEANUP_openvt
#undef FOR_openvt
@@ -2534,14 +2534,6 @@
#undef FLAG_n
#endif
-// realpath <1 <1
-#undef OPTSTR_realpath
-#define OPTSTR_realpath "<1"
-#ifdef CLEANUP_realpath
-#undef CLEANUP_realpath
-#undef FOR_realpath
-#endif
-
// reboot d:fn
#undef OPTSTR_reboot
#define OPTSTR_reboot "d:fn"
@@ -3065,9 +3057,9 @@
#undef FLAG_f
#endif
-// tar &(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] &(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 &(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]
#undef OPTSTR_tar
-#define OPTSTR_tar "&(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 "&(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]"
#ifdef CLEANUP_tar
#undef CLEANUP_tar
#undef FOR_tar
@@ -3105,6 +3097,7 @@
#undef FLAG_full_time
#undef FLAG_restrict
#undef FLAG_selinux
+#undef FLAG_strip_components
#endif
// taskset <1^pa
@@ -3638,12 +3631,13 @@
#undef FLAG_m
#endif
-// wget <1>1(max-redirect)#<0=20d(debug)O(output-document):
+// wget <1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):
#undef OPTSTR_wget
-#define OPTSTR_wget "<1>1(max-redirect)#<0=20d(debug)O(output-document):"
+#define OPTSTR_wget "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):"
#ifdef CLEANUP_wget
#undef CLEANUP_wget
#undef FOR_wget
+#undef FLAG_p
#undef FLAG_O
#undef FLAG_d
#undef FLAG_max_redirect
@@ -6065,13 +6059,6 @@
#define FLAG_n (1<<4)
#endif
-#ifdef FOR_realpath
-#define CLEANUP_realpath
-#ifndef TT
-#define TT this.realpath
-#endif
-#endif
-
#ifdef FOR_reboot
#define CLEANUP_reboot
#ifndef TT
@@ -6590,6 +6577,7 @@
#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
@@ -7084,9 +7072,10 @@
#ifndef TT
#define TT this.wget
#endif
-#define FLAG_O (FORCED_FLAG<<0)
-#define FLAG_d (FORCED_FLAG<<1)
-#define FLAG_max_redirect (FORCED_FLAG<<2)
+#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)
#endif
#ifdef FOR_which
diff --git a/android/linux/generated/globals.h b/android/linux/generated/globals.h
index 844f4d02..403077b0 100644
--- a/android/linux/generated/globals.h
+++ b/android/linux/generated/globals.h
@@ -397,6 +397,12 @@ struct oneit_data {
char *c;
};
+// toys/other/openvt.c
+
+struct openvt_data {
+ long c;
+};
+
// toys/other/pwgen.c
struct pwgen_data {
@@ -862,12 +868,6 @@ struct more_data {
int cin_fd;
};
-// toys/pending/openvt.c
-
-struct openvt_data {
- long c;
-};
-
// toys/pending/route.c
struct route_data {
@@ -1159,10 +1159,10 @@ struct vi_data {
// toys/pending/wget.c
struct wget_data {
- char *filename;
- long redirects;
+ char *p, *O;
+ long max_redirect;
- int sock;
+ int sock, https;
char *url;
#if CFG_WGET_LIBTLS
struct tls *tls;
@@ -1549,6 +1549,7 @@ struct tar_data {
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;
@@ -1678,6 +1679,7 @@ extern union global_union {
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;
@@ -1728,7 +1730,6 @@ extern union global_union {
struct mke2fs_data mke2fs;
struct modprobe_data modprobe;
struct more_data more;
- struct openvt_data openvt;
struct route_data route;
struct sh_data sh;
struct strace_data strace;
diff --git a/android/linux/generated/help.h b/android/linux/generated/help.h
index ae7d47c0..30c24e92 100644
--- a/android/linux/generated/help.h
+++ b/android/linux/generated/help.h
@@ -4,8 +4,6 @@
#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."
@@ -128,7 +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)\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_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"
@@ -218,6 +216,12 @@
#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\""
@@ -314,8 +318,6 @@
#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."
@@ -350,7 +352,7 @@
#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\nexamples:\n wget http://www.example.com"
+#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_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."
@@ -410,10 +412,6 @@
#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_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"
@@ -532,7 +530,7 @@
#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 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 --selinux Record/restore labels\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_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_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)"
diff --git a/android/linux/generated/newtoys.h b/android/linux/generated/newtoys.h
index ea56d9d5..ade88313 100644
--- a/android/linux/generated/newtoys.h
+++ b/android/linux/generated/newtoys.h
@@ -1,4 +1,4 @@
-USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT))
+USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT|TOYFLAG_NOHELP))
USE_SH(OLDTOY(-bash, sh, 0))
USE_SH(OLDTOY(-sh, sh, 0))
USE_SH(OLDTOY(-toysh, sh, 0))
@@ -137,7 +137,7 @@ USE_INOTIFYD(NEWTOY(inotifyd, "<2", TOYFLAG_USR|TOYFLAG_BIN))
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))
@@ -201,7 +201,7 @@ 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, "c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
+USE_OPENVT(NEWTOY(openvt, "^<1c#<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))
@@ -224,7 +224,7 @@ USE_PWGEN(NEWTOY(pwgen, ">2r(remove):c(capitalize)n(numerals)y(symbols)s(secure)
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(NEWTOY(realpath, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+USE_REALPATH(OLDTOY(realpath, readlink, TOYFLAG_USR|TOYFLAG_BIN))
USE_REBOOT(NEWTOY(reboot, "d:fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
USE_RENICE(NEWTOY(renice, "<1gpun#|", TOYFLAG_USR|TOYFLAG_BIN))
USE_RESET(NEWTOY(reset, 0, TOYFLAG_USR|TOYFLAG_BIN))
@@ -274,7 +274,7 @@ 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, "&(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, "&(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_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))
@@ -321,7 +321,7 @@ USE_SH(NEWTOY(wait, "n", TOYFLAG_NOFORK))
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):", TOYFLAG_USR|TOYFLAG_BIN))
+USE_WGET(NEWTOY(wget, "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):", 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))
diff --git a/android/mac/generated/config.h b/android/mac/generated/config.h
index cbb0b434..a9f4bdf9 100644
--- a/android/mac/generated/config.h
+++ b/android/mac/generated/config.h
@@ -2,6 +2,8 @@
#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
diff --git a/android/mac/generated/flags.h b/android/mac/generated/flags.h
index f290c981..516ffc76 100644
--- a/android/mac/generated/flags.h
+++ b/android/mac/generated/flags.h
@@ -1535,9 +1535,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
@@ -2248,9 +2248,9 @@
#undef FLAG_n
#endif
-// openvt c#<1>63sw
+// openvt ^<1c#<1>63sw
#undef OPTSTR_openvt
-#define OPTSTR_openvt "c#<1>63sw"
+#define OPTSTR_openvt "^<1c#<1>63sw"
#ifdef CLEANUP_openvt
#undef CLEANUP_openvt
#undef FOR_openvt
@@ -2534,14 +2534,6 @@
#undef FLAG_n
#endif
-// realpath <1 <1
-#undef OPTSTR_realpath
-#define OPTSTR_realpath "<1"
-#ifdef CLEANUP_realpath
-#undef CLEANUP_realpath
-#undef FOR_realpath
-#endif
-
// reboot d:fn
#undef OPTSTR_reboot
#define OPTSTR_reboot "d:fn"
@@ -3065,9 +3057,9 @@
#undef FLAG_f
#endif
-// tar &(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] &(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 &(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]
#undef OPTSTR_tar
-#define OPTSTR_tar "&(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 "&(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]"
#ifdef CLEANUP_tar
#undef CLEANUP_tar
#undef FOR_tar
@@ -3105,6 +3097,7 @@
#undef FLAG_full_time
#undef FLAG_restrict
#undef FLAG_selinux
+#undef FLAG_strip_components
#endif
// taskset <1^pa
@@ -3638,12 +3631,13 @@
#undef FLAG_m
#endif
-// wget <1>1(max-redirect)#<0=20d(debug)O(output-document):
+// wget <1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):
#undef OPTSTR_wget
-#define OPTSTR_wget "<1>1(max-redirect)#<0=20d(debug)O(output-document):"
+#define OPTSTR_wget "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):"
#ifdef CLEANUP_wget
#undef CLEANUP_wget
#undef FOR_wget
+#undef FLAG_p
#undef FLAG_O
#undef FLAG_d
#undef FLAG_max_redirect
@@ -6065,13 +6059,6 @@
#define FLAG_n (1<<4)
#endif
-#ifdef FOR_realpath
-#define CLEANUP_realpath
-#ifndef TT
-#define TT this.realpath
-#endif
-#endif
-
#ifdef FOR_reboot
#define CLEANUP_reboot
#ifndef TT
@@ -6590,6 +6577,7 @@
#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
@@ -7084,9 +7072,10 @@
#ifndef TT
#define TT this.wget
#endif
-#define FLAG_O (FORCED_FLAG<<0)
-#define FLAG_d (FORCED_FLAG<<1)
-#define FLAG_max_redirect (FORCED_FLAG<<2)
+#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)
#endif
#ifdef FOR_which
diff --git a/android/mac/generated/globals.h b/android/mac/generated/globals.h
index 844f4d02..403077b0 100644
--- a/android/mac/generated/globals.h
+++ b/android/mac/generated/globals.h
@@ -397,6 +397,12 @@ struct oneit_data {
char *c;
};
+// toys/other/openvt.c
+
+struct openvt_data {
+ long c;
+};
+
// toys/other/pwgen.c
struct pwgen_data {
@@ -862,12 +868,6 @@ struct more_data {
int cin_fd;
};
-// toys/pending/openvt.c
-
-struct openvt_data {
- long c;
-};
-
// toys/pending/route.c
struct route_data {
@@ -1159,10 +1159,10 @@ struct vi_data {
// toys/pending/wget.c
struct wget_data {
- char *filename;
- long redirects;
+ char *p, *O;
+ long max_redirect;
- int sock;
+ int sock, https;
char *url;
#if CFG_WGET_LIBTLS
struct tls *tls;
@@ -1549,6 +1549,7 @@ struct tar_data {
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;
@@ -1678,6 +1679,7 @@ extern union global_union {
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;
@@ -1728,7 +1730,6 @@ extern union global_union {
struct mke2fs_data mke2fs;
struct modprobe_data modprobe;
struct more_data more;
- struct openvt_data openvt;
struct route_data route;
struct sh_data sh;
struct strace_data strace;
diff --git a/android/mac/generated/help.h b/android/mac/generated/help.h
index ae7d47c0..30c24e92 100644
--- a/android/mac/generated/help.h
+++ b/android/mac/generated/help.h
@@ -4,8 +4,6 @@
#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."
@@ -128,7 +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)\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_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"
@@ -218,6 +216,12 @@
#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\""
@@ -314,8 +318,6 @@
#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."
@@ -350,7 +352,7 @@
#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\nexamples:\n wget http://www.example.com"
+#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_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."
@@ -410,10 +412,6 @@
#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_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"
@@ -532,7 +530,7 @@
#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 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 --selinux Record/restore labels\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_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_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)"
diff --git a/android/mac/generated/newtoys.h b/android/mac/generated/newtoys.h
index ea56d9d5..ade88313 100644
--- a/android/mac/generated/newtoys.h
+++ b/android/mac/generated/newtoys.h
@@ -1,4 +1,4 @@
-USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT))
+USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT|TOYFLAG_NOHELP))
USE_SH(OLDTOY(-bash, sh, 0))
USE_SH(OLDTOY(-sh, sh, 0))
USE_SH(OLDTOY(-toysh, sh, 0))
@@ -137,7 +137,7 @@ USE_INOTIFYD(NEWTOY(inotifyd, "<2", TOYFLAG_USR|TOYFLAG_BIN))
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))
@@ -201,7 +201,7 @@ 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, "c#<1>63sw", TOYFLAG_BIN|TOYFLAG_NEEDROOT))
+USE_OPENVT(NEWTOY(openvt, "^<1c#<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))
@@ -224,7 +224,7 @@ USE_PWGEN(NEWTOY(pwgen, ">2r(remove):c(capitalize)n(numerals)y(symbols)s(secure)
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(NEWTOY(realpath, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+USE_REALPATH(OLDTOY(realpath, readlink, TOYFLAG_USR|TOYFLAG_BIN))
USE_REBOOT(NEWTOY(reboot, "d:fn", TOYFLAG_SBIN|TOYFLAG_NEEDROOT))
USE_RENICE(NEWTOY(renice, "<1gpun#|", TOYFLAG_USR|TOYFLAG_BIN))
USE_RESET(NEWTOY(reset, 0, TOYFLAG_USR|TOYFLAG_BIN))
@@ -274,7 +274,7 @@ 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, "&(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, "&(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_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))
@@ -321,7 +321,7 @@ USE_SH(NEWTOY(wait, "n", TOYFLAG_NOFORK))
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):", TOYFLAG_USR|TOYFLAG_BIN))
+USE_WGET(NEWTOY(wget, "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):", 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))
diff --git a/configure b/configure
index 368cf216..c718e83b 100755
--- a/configure
+++ b/configure
@@ -15,19 +15,8 @@ fi
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} ${GENERATED:=generated} ${KCONFIG_CONFIG:=.config}
-: ${OUTNAME:=toybox${TARGET:+-$TARGET}}
-: ${UNSTRIPPED:=$GENERATED/unstripped/${OUTNAME/*\//}}
+: ${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}
-# 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
- : ${LDOPTIMIZE:=-Wl,-dead_strip} ${STRIP:=strip}
-else
- : ${LDOPTIMIZE:=-Wl,--gc-sections -Wl,--as-needed} ${STRIP:=strip -s -R .note* -R .comment}
-# LDASNEEDED="-Wl,--as-needed" # must go at end of compiler command line
-fi
diff --git a/kconfig/kconfig-language.txt b/kconfig/kconfig-language.txt
new file mode 100644
index 00000000..d821369c
--- /dev/null
+++ b/kconfig/kconfig-language.txt
@@ -0,0 +1,284 @@
+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 247c1944..2b8da7c7 100644
--- a/lib/args.c
+++ b/lib/args.c
@@ -77,6 +77,7 @@
// ? 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
@@ -254,7 +255,7 @@ static int parse_optflaglist(struct getoptflagstate *gof)
// Parse option string into a linked list of options with attributes.
- if (!*options) gof->stopearly++;
+ if (!*options) gof->stopearly++, gof->noerror++;
while (*options) {
char *temp;
diff --git a/lib/lib.c b/lib/lib.c
index 84af3f48..cf0a9582 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -449,9 +449,10 @@ char *strafter(char *haystack, char *needle)
// Remove trailing \n
char *chomp(char *s)
{
- char *p = strrchr(s, '\n');
+ char *p = s+strlen(s);
+
+ while (p>=s && (p[-1]=='\r' || p[-1]=='\n')) *--p = 0;
- if (p && !p[1]) *p = 0;
return s;
}
@@ -1251,7 +1252,7 @@ char *next_printf(char *s, char **start)
}
// Return cached passwd entries.
-struct passwd *bufgetpwuid(uid_t uid)
+struct passwd *bufgetpwnamuid(char *name, uid_t uid)
{
struct pwuidbuf_list {
struct pwuidbuf_list *next;
@@ -1263,11 +1264,14 @@ struct passwd *bufgetpwuid(uid_t uid)
// If we already have this one, return it.
for (list = pwuidbuf; list; list = list->next)
- if (list->pw.pw_uid == uid) return &(list->pw);
+ if (name ? !strcmp(name, list->pw.pw_name) : list->pw.pw_uid==uid)
+ return &(list->pw);
for (;;) {
list = xrealloc(list, size *= 2);
- errno = getpwuid_r(uid, &list->pw, sizeof(*list)+(char *)list,
+ 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,
size-sizeof(*list), &temp);
if (errno != ERANGE) break;
}
@@ -1283,8 +1287,13 @@ struct passwd *bufgetpwuid(uid_t uid)
return &list->pw;
}
+struct passwd *bufgetpwuid(uid_t uid)
+{
+ return bufgetpwnamuid(0, uid);
+}
+
// Return cached group entries.
-struct group *bufgetgrgid(gid_t gid)
+struct group *bufgetgrnamgid(char *name, gid_t gid)
{
struct grgidbuf_list {
struct grgidbuf_list *next;
@@ -1295,11 +1304,14 @@ struct group *bufgetgrgid(gid_t gid)
unsigned size = 256;
for (list = grgidbuf; list; list = list->next)
- if (list->gr.gr_gid == gid) return &(list->gr);
+ if (name ? !strcmp(name, list->gr.gr_name) : list->gr.gr_gid==gid)
+ return &(list->gr);
for (;;) {
list = xrealloc(list, size *= 2);
- errno = getgrgid_r(gid, &list->gr, sizeof(*list)+(char *)list,
+ 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,
size-sizeof(*list), &temp);
if (errno != ERANGE) break;
}
@@ -1314,6 +1326,12 @@ struct group *bufgetgrgid(gid_t gid)
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 6e9a2640..1721dd67 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -260,7 +260,9 @@ int qstrcmp(const void *a, const void *b);
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);
diff --git a/lib/portability.c b/lib/portability.c
index 5f98138c..89744dd0 100644
--- a/lib/portability.c
+++ b/lib/portability.c
@@ -623,26 +623,45 @@ int get_block_device_size(int fd, unsigned long long* size)
}
#endif
-// TODO copy_file_range
+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
+}
+
// Return bytes copied from in to out. If bytes <0 copy all of in to out.
-// If consuemd isn't null, amount read saved there (return is written or error)
+// If consumed 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 CFG_TOYBOX_COPYFILERANGE
- len = copy_file_range(in, 0, out, 0, bytes, 0);
-#else
- ww = len = read(in, libbuf, len);
-#endif
+ 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 (len<1 && errno==EAGAIN) continue;
if (len<1) break;
if (consumed) *consumed += len;
diff --git a/lib/toyflags.h b/lib/toyflags.h
index c8830874..0c65735c 100644
--- a/lib/toyflags.h
+++ b/lib/toyflags.h
@@ -37,9 +37,3 @@
// 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/xwrap.c b/lib/xwrap.c
index f16ebe03..65e9f4fe 100644
--- a/lib/xwrap.c
+++ b/lib/xwrap.c
@@ -104,7 +104,12 @@ char *xstrndup(char *s, size_t n)
// Die unless we can allocate a copy of this string.
char *xstrdup(char *s)
{
- return xstrndup(s, strlen(s));
+ long len = strlen(s);
+ char *c = xmalloc(++len);
+
+ memcpy(c, s, len);
+
+ return c;
}
void *xmemdup(void *s, long len)
diff --git a/main.c b/main.c
index 95c42fa4..9d9d7061 100644
--- a/main.c
+++ b/main.c
@@ -82,9 +82,9 @@ void show_help(FILE *out, int full)
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);
+ 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 (;;) {
@@ -114,8 +114,9 @@ static void unknown(char *name)
// Parse --help and --version for (almost) all commands
void check_help(char **arg)
{
- if (!CFG_TOYBOX_HELP_DASHDASH || !*arg || (toys.which->flags&TOYFLAG_NOHELP))
- return;
+ 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])
@@ -164,7 +165,6 @@ void toy_init(struct toy_list *which, char *argv[])
void *oldwhich = toys.which;
// Drop permissions for non-suid commands.
-
if (CFG_TOYBOX_SUID) {
if (!toys.which) toys.which = toy_list;
@@ -180,6 +180,7 @@ void toy_init(struct toy_list *which, char *argv[])
error_msg("Not installed suid root");
if ((which->flags & TOYFLAG_NEEDROOT) && euid) {
+ toys.which = which;
check_help(argv+1);
help_exit("Not root");
}
@@ -236,12 +237,13 @@ void toybox_main(void)
// fast path: try to exec immediately.
// (Leave toys.which null to disable suid return logic.)
- // Try dereferencing one layer of symlink
+ // Try dereferencing symlinks until we hit a recognized name
while (s) {
- struct toy_list *tl = toy_find(basename(s));
+ char *ss = basename(s);
+ struct toy_list *tl = toy_find(ss);
- if (tl==toy_list && s!=toys.argv[1]) unknown(basename(s));
- toy_exec_which(toy_find(basename(s)), toys.argv+1);
+ if (tl==toy_list && s!=toys.argv[1]) unknown(ss);
+ toy_exec_which(tl, toys.argv+1);
s = (0<readlink(s, libbuf, sizeof(libbuf))) ? libbuf : 0;
}
diff --git a/scripts/change.sh b/scripts/change.sh
index 99dcfde9..74889aa7 100755
--- a/scripts/change.sh
+++ b/scripts/change.sh
@@ -2,8 +2,10 @@
# 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 generated/instlist &&
+${HOSTCC:-cc} -I . scripts/install.c -o "$UNSTRIPPED"/instlist &&
export PREFIX=${PREFIX:-change/} &&
mkdir -p "$PREFIX" || exit 1
@@ -12,7 +14,7 @@ mkdir -p "$PREFIX" || exit 1
# 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 $(generated/instlist | egrep -vw "sh|help")
+for i in $("$UNSTRIPPED"/instlist | egrep -vw "sh|help")
do
echo -n " $i" &&
scripts/single.sh $i > /dev/null 2>$PREFIX/${i}.bad &&
diff --git a/scripts/genconfig.sh b/scripts/genconfig.sh
index 01b2eaaf..034aa376 100755
--- a/scripts/genconfig.sh
+++ b/scripts/genconfig.sh
@@ -3,10 +3,10 @@
# 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.)
-mkdir -p generated
-
source scripts/portability.sh
+mkdir -p "$GENDIR"
+
probecc()
{
${CROSS_COMPILE}${CC} $CFLAGS $LDFLAGS -xc -o /dev/null - "$@"
@@ -101,10 +101,12 @@ EOF
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) { copyfilerange(0, 0, 1, 0, 123, 0); }
+ int main(void) { syscall(__NR_copy_file_range, 0, 0, 1, 0, 123, 0); }
EOF
probesymbol TOYBOX_HASTIMERS << EOF
#include <signal.h>
@@ -138,8 +140,8 @@ genconfig()
done
}
-probeconfig > generated/Config.probed || rm generated/Config.probed
-genconfig > generated/Config.in || rm generated/Config.in
+probeconfig > "$GENDIR"/Config.probed || rm "$GENDIR"/Config.probed
+genconfig > "$GENDIR"/Config.in || rm "$GENDIR"/Config.in
# Find names of commands that can be built standalone in these C files
toys()
diff --git a/scripts/install.sh b/scripts/install.sh
index d58d075d..842ff9b0 100755
--- a/scripts/install.sh
+++ b/scripts/install.sh
@@ -2,9 +2,9 @@
# Grab default values for $CFLAGS and such.
-source ./configure
+source scripts/portability.sh
-[ -z "$PREFIX" ] && PREFIX="/usr/toybox"
+[ -z "$PREFIX" ] && PREFIX="$PWD/install"
# Parse command line arguments.
@@ -32,8 +32,8 @@ done
echo "Compile instlist..."
NOBUILD=1 scripts/make.sh
-$DEBUG $HOSTCC -I . scripts/install.c -o generated/instlist || exit 1
-COMMANDS="$(generated/instlist $LONG_PATH)"
+$DEBUG $HOSTCC -I . scripts/install.c -o "$UNSTRIPPED"/instlist || exit 1
+COMMANDS="$("$UNSTRIPPED"/instlist $LONG_PATH)"
echo "${UNINSTALL:-Install} commands..."
@@ -106,7 +106,7 @@ done
# 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 tr vi wget sh xzcat bc ar gzip ftpd less awk unxz bison flex make nm"
+PENDING="dd diff expr git tr vi wget bash sh xzcat bc ar gzip ftpd less awk unxz bison flex make nm"
# "gcc" can go away if the kernel guys merge my patch:
# http://lkml.iu.edu/hypermail/linux/kernel/2202.0/01505.html
diff --git a/scripts/make.sh b/scripts/make.sh
index 291ff80a..b7bb6930 100755
--- a/scripts/make.sh
+++ b/scripts/make.sh
@@ -26,9 +26,9 @@ isnewer()
echo "Generate headers from toys/*/*.c..."
-mkdir -p generated/unstripped
+mkdir -p "$UNSTRIPPED"
-if isnewer generated/Config.in toys || isnewer generated/Config.in Config.in
+if isnewer "$GENDIR"/Config.in toys || isnewer "$GENDIR"/Config.in Config.in
then
echo "Extract configuration information from toys/*.c files..."
scripts/genconfig.sh
@@ -39,14 +39,15 @@ fi
# first element of the array). The rest must be sorted in alphabetical order
# for fast binary search.
-if isnewer generated/newtoys.h toys
+if isnewer "$GENDIR"/newtoys.h toys
then
- echo -n "generated/newtoys.h "
+ echo -n "$GENDIR/newtoys.h "
- echo "USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT))" > generated/newtoys.h
+ echo "USE_TOYBOX(NEWTOY(toybox, NULL, TOYFLAG_STAYROOT|TOYFLAG_NOHELP))" \
+ > "$GENDIR"/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/[^ ]* //' >> generated/newtoys.h
+ | $SED 's/[^ ]* //' >> "$GENDIR"/newtoys.h
[ $? -ne 0 ] && exit 1
fi
@@ -55,11 +56,11 @@ fi
# 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" ] && GITHASH="-DTOYBOX_VERSION=\"$(git describe --tags --abbrev=12 2>/dev/null)\""
+[ -d ".git" ] && [ ! -z "$(which git 2>/dev/null)" ] &&
+ GITHASH="-DTOYBOX_VERSION=\"$(git describe --tags --abbrev=12 2>/dev/null)\""
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)"
BUILD="$(echo ${CROSS_COMPILE}${CC} $CFLAGS -I . $OPTIMIZE $GITHASH)"
-LIBFILES="$(ls lib/*.c)"
if [ "${TOYFILES/pending//}" != "$TOYFILES" ]
then
@@ -70,12 +71,13 @@ genbuildsh()
{
# Write a canned build line for use on crippled build machines.
- echo -e "#!/bin/sh\n\nPATH='$PATH'\nBUILD='$BUILD'\nLINK='$LINK'\n"
- echo -e "\$BUILD lib/*.c $TOYFILES \$LINK"
+ 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"
}
-if ! cmp -s <(genbuildsh 2>/dev/null | head -n 4 ; echo LINK="'"$LDOPTIMIZE $LDFLAGS) \
- <(head -n 5 generated/build.sh 2>/dev/null | $SED '5s/ -o .*//')
+if ! cmp -s <(genbuildsh 2>/dev/null | head -n 5) \
+ <(head -n 5 "$GENDIR"/build.sh 2>/dev/null | $SED '5s/ -o .*//')
then
echo -n "Library probe"
@@ -83,27 +85,24 @@ then
# compiler has no way to ignore a library that doesn't exist, so detect
# and skip nonexistent libraries for it.
- > generated/optlibs.dat
+ > "$GENDIR"/optlibs.dat
for i in util crypt m resolv selinux smack attr crypto z log iconv tls ssl
do
echo "int main(int argc, char *argv[]) {return 0;}" | \
- ${CROSS_COMPILE}${CC} $CFLAGS $LDFLAGS -xc - -o generated/libprobe -l$i > /dev/null 2>/dev/null &&
- echo -l$i >> generated/optlibs.dat
+ ${CROSS_COMPILE}${CC} $CFLAGS $LDFLAGS -xc - -o "$GENDIR"/libprobe -l$i > /dev/null 2>/dev/null &&
+ echo -l$i >> "$GENDIR"/optlibs.dat
echo -n .
done
- rm -f generated/libprobe
+ rm -f "$GENDIR"/libprobe
echo
fi
-# LINK needs optlibs.dat, above
-
-LINK="$(echo $LDOPTIMIZE $LDFLAGS -o "$UNSTRIPPED" $(cat generated/optlibs.dat))"
-genbuildsh > generated/build.sh && chmod +x generated/build.sh || exit 1
+genbuildsh > "$GENDIR"/build.sh && chmod +x "$GENDIR"/build.sh || exit 1
#TODO: "make $SED && make" doesn't regenerate config.h because diff .config
-if true #isnewer generated/config.h "$KCONFIG_CONFIG"
+if true #isnewer "$GENDIR"/config.h "$KCONFIG_CONFIG"
then
- echo "Make generated/config.h from $KCONFIG_CONFIG."
+ echo "Make $GENDIR/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
@@ -128,12 +127,12 @@ then
-e 's/.*/#define CFG_& 1/p' \
-e 'g' \
-e 's/.*/#define USE_&(...) __VA_ARGS__/p' \
- $KCONFIG_CONFIG > generated/config.h || exit 1
+ $KCONFIG_CONFIG > "$GENDIR"/config.h || exit 1
fi
-if [ ! -f generated/mkflags ] || [ generated/mkflags -ot scripts/mkflags.c ]
+if [ ! -f "$GENDIR"/mkflags ] || [ "$GENDIR"/mkflags -ot scripts/mkflags.c ]
then
- do_loudly $HOSTCC scripts/mkflags.c -o generated/mkflags || exit 1
+ do_loudly $HOSTCC scripts/mkflags.c -o "$UNSTRIPPED"/mkflags || exit 1
fi
# Process config.h and newtoys.h to generate FLAG_x macros. Note we must
@@ -141,9 +140,9 @@ fi
# 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 generated/flags.h toys "$KCONFIG_CONFIG"
+if isnewer "$GENDIR"/flags.h toys "$KCONFIG_CONFIG"
then
- echo -n "generated/flags.h "
+ echo -n "$GENDIR/flags.h "
# Parse files through C preprocessor twice, once to get flags for current
# .config and once to get flags for allyesconfig
@@ -156,12 +155,12 @@ then
echo '#define OLDTOY(...)'
if [ "$I" == A ]
then
- cat generated/config.h
+ cat "$GENDIR"/config.h
else
- $SED '/USE_.*([^)]*)$/s/$/ __VA_ARGS__/' generated/config.h
+ $SED '/USE_.*([^)]*)$/s/$/ __VA_ARGS__/' "$GENDIR"/config.h
fi
echo '#include "lib/toyflags.h"'
- cat generated/newtoys.h
+ cat "$GENDIR"/newtoys.h
# Run result through preprocessor, glue together " " gaps leftover from USE
# macros, delete comment lines, print any line with a quoted optstring,
@@ -179,7 +178,7 @@ then
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 generated/flags.raw | generated/mkflags > generated/flags.h || exit 1
+ tee "$GENDIR"/flags.raw | "$UNSTRIPPED"/mkflags > "$GENDIR"/flags.h || exit 1
fi
# Extract global structure definitions and flag definitions from toys/*/*.c
@@ -197,9 +196,9 @@ function getglobals()
done
}
-if isnewer generated/globals.h toys
+if isnewer "$GENDIR"/globals.h toys
then
- echo -n "generated/globals.h "
+ echo -n "$GENDIR/globals.h "
GLOBSTRUCT="$(getglobals)"
(
echo "$GLOBSTRUCT"
@@ -208,30 +207,30 @@ then
echo "$GLOBSTRUCT" | \
$SED -n 's/struct \(.*\)_data {/ struct \1_data \1;/p'
echo "} this;"
- ) > generated/globals.h
+ ) > "$GENDIR"/globals.h
fi
-if [ ! -f generated/mktags ] || [ generated/mktags -ot scripts/mktags.c ]
+if [ ! -f "$UNSTRIPPED"/mktags ] || [ "$UNSTRIPPED"/mktags -ot scripts/mktags.c ]
then
- do_loudly $HOSTCC scripts/mktags.c -o generated/mktags || exit 1
+ do_loudly $HOSTCC scripts/mktags.c -o "$UNSTRIPPED"/mktags || exit 1
fi
-if isnewer generated/tags.h toys
+if isnewer "$GENDIR"/tags.h toys
then
- echo -n "generated/tags.h "
+ echo -n "$GENDIR/tags.h "
$SED -n '/TAGGED_ARRAY(/,/^)/{s/.*TAGGED_ARRAY[(]\([^,]*\),/\1/;p}' \
- toys/*/*.c lib/*.c | generated/mktags > generated/tags.h
+ toys/*/*.c lib/*.c | "$UNSTRIPPED"/mktags > "$GENDIR"/tags.h
fi
-if [ ! -f generated/config2help ] || [ generated/config2help -ot scripts/config2help.c ]
+if [ ! -f "$UNSTRIPPED"/config2help ] || [ "$UNSTRIPPED"/config2help -ot scripts/config2help.c ]
then
- do_loudly $HOSTCC scripts/config2help.c -o generated/config2help || exit 1
+ do_loudly $HOSTCC scripts/config2help.c -o "$UNSTRIPPED"/config2help || exit 1
fi
-if isnewer generated/help.h generated/Config.in
+if isnewer "$GENDIR"/help.h "$GENDIR"/Config.in
then
- echo "generated/help.h"
- generated/config2help Config.in $KCONFIG_CONFIG > generated/help.h || exit 1
+ echo "$GENDIR/help.h"
+ "$UNSTRIPPED"/config2help Config.in $KCONFIG_CONFIG > "$GENDIR"/help.h || exit 1
fi
[ ! -z "$NOBUILD" ] && exit 0
@@ -240,16 +239,16 @@ echo -n "Compile $OUTNAME"
[ ! -z "$V" ] && echo
DOTPROG=.
-# This is a parallel version of: do_loudly $BUILD $FILES $LINK || exit 1
+# This is a parallel version of: do_loudly $BUILD $FILES $LLINK || exit 1
# Any headers newer than the oldest generated/obj file?
-X="$(ls -1t generated/obj/* 2>/dev/null | tail -n 1)"
+X="$(ls -1t "$GENDIR"/obj/* 2>/dev/null | tail -n 1)"
# TODO: redo this
if [ ! -e "$X" ] || [ ! -z "$(find toys -name "*.h" -newer "$X")" ]
then
- rm -rf generated/obj && mkdir -p generated/obj || exit 1
+ rm -rf "$GENDIR"/obj && mkdir -p "$GENDIR"/obj || exit 1
else
- rm -f generated/obj/{main,lib_help}.o || exit 1
+ rm -f "$GENDIR"/obj/main.o || exit 1
fi
# build each generated/obj/*.o file in parallel
@@ -258,16 +257,16 @@ unset PENDING LNKFILES CLICK
DONE=0
COUNT=0
-for i in $LIBFILES click $TOYFILES
+for i in lib/*.c click $TOYFILES
do
[ "$i" == click ] && CLICK=1 && continue
X=${i/lib\//lib_}
X=${X##*/}
- OUT="generated/obj/${X%%.c}.o"
+ OUT="$GENDIR/obj/${X%%.c}.o"
LNKFILES="$LNKFILES $OUT"
- # $LIBFILES don't need to be rebuilt if older than .config, $TOYFILES do
+ # Library files don't need to be rebuilt if older than .config.
# ($TOYFILES contents can depend on CONFIG symbols, lib/*.c never should.)
[ "$OUT" -nt "$i" ] && [ -z "$CLICK" -o "$OUT" -nt "$KCONFIG_CONFIG" ] &&
@@ -288,7 +287,8 @@ do
done
[ $DONE -ne 0 ] && exit 1
-do_loudly $BUILD $LNKFILES $LINK || exit 1
+UNSTRIPPED="$UNSTRIPPED/${OUTNAME/*\//}"
+do_loudly $BUILD $LNKFILES $LLINK -o "$UNSTRIPPED" || exit 1
if [ ! -z "$NOSTRIP" ] ||
! do_loudly ${CROSS_COMPILE}${STRIP} "$UNSTRIPPED" -o "$OUTNAME"
then
diff --git a/scripts/mkroot.sh b/scripts/mkroot.sh
index f1ddc505..c099bec7 100755
--- a/scripts/mkroot.sh
+++ b/scripts/mkroot.sh
@@ -11,7 +11,7 @@ for i in "$@"; do
[ "${i/=/}" != "$i" ] && export "$i" || { [ "$i" != -- ] && PKG="$PKG $i"; }
done
-# Set default values for directories (overrideable from command line)
+# 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}
@@ -145,8 +145,9 @@ echo -e 'root:x:0:\nguest:x:500:\nnobody:x:65534:' > "$ROOT"/etc/group || exit 1
# Build static toybox with existing .config if there is one, else defconfig+sh
announce toybox
-[ -e .config ] && [ -z "$PENDING" ] && CONF=silentoldconfig || unset CONF
-for i in $PENDING sh route; do XX="$XX"$'\n'CONFIG_${i^^?}=y; done
+[ ! -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
@@ -204,7 +205,7 @@ else
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,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,NET_VENDOR_NATSEMI,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
@@ -236,10 +237,11 @@ else
# 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 \
- "-append \"panic=1 HOST=$TARGET console=$KARGS \$KARGS\"" \
- ${DTB:+-dtb "$(basename "$DTB")"} > "$OUTPUT/qemu-$TARGET.sh" &&
+ { 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" &&
chmod +x "$OUTPUT/qemu-$TARGET.sh" || exit 1
fi
diff --git a/scripts/portability.sh b/scripts/portability.sh
index 50793ade..3af2be5f 100644
--- a/scripts/portability.sh
+++ b/scripts/portability.sh
@@ -13,20 +13,28 @@ then
[ ! -z "$(command -v gsed 2>/dev/null)" ] && SED=gsed || SED=sed
fi
-# Extra debug plumbing the Android guys want
+# 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
- echo "Enabling ASan..."
# 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="$ASAN_FLAGS $CFLAGS"
- # Run this nonsense against temporary build tools that don't ship too
+ 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.
+# 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.
diff --git a/tests/tar.test b/tests/tar.test
index 6db35185..034a3bfb 100644
--- a/tests/tar.test
+++ b/tests/tar.test
@@ -41,12 +41,12 @@ testing "pass file" "$TAR file | LST" \
# 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 --group root --mtime @0 file | LST" \
+testing "pass user" "tar -c --owner nobody:65534 --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 --mtime @0 file | LST" \
+testing "pass group" "tar c --owner root --group nobody:65534 --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,11 +210,12 @@ toyonly testing "cat tbz | extract dir/file (autodetect)" \
"dir/\ndir/file\ndrwxr-x--- 1494637555 dd/dir\n-rw-r----- 1494637555 dd/dir/file\n" \
"" ""
-yes | (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) > fweep
+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
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
@@ -275,6 +276,14 @@ testcmd 'replace dir with file' '-xf test.tar && cat one/two/three' \
'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
diff --git a/toys/example/README b/toys/example/README
index 0ebc2028..6e73fa18 100644
--- a/toys/example/README
+++ b/toys/example/README
@@ -2,13 +2,22 @@ Example commands
You probably don't want to deploy any of this.
-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)
+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 demo_* commands demonstrate infrastructure, and do regression testing.
+ - hello.c is clean and simple, and an easy way to check the behavior of
+ toybox library functions running in command context.
-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.
+ - 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.
diff --git a/toys/example/hello.c b/toys/example/hello.c
index 3e68f215..ad74eba8 100644
--- a/toys/example/hello.c
+++ b/toys/example/hello.c
@@ -5,7 +5,8 @@
* 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 http://man7.org/linux/man-pages/dir_section_1.html
+ * See https://man7.org/linux/man-pages/man1/intro.1.html
+ * No standard.
USE_HELLO(NEWTOY(hello, 0, TOYFLAG_USR|TOYFLAG_BIN))
@@ -33,5 +34,5 @@ void hello_main(void)
xprintf("Hello world\n");
// Avoid kernel panic if run as init.
- if (getpid() == 1) wait(&TT.unused);
+ if (getpid() == 1) getchar();
}
diff --git a/toys/example/skeleton.c b/toys/example/skeleton.c
index d6712b8e..54080686 100644
--- a/toys/example/skeleton.c
+++ b/toys/example/skeleton.c
@@ -6,7 +6,8 @@
* 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 http://man7.org/linux/man-pages/dir_section_1.html
+ * See https://man7.org/linux/man-pages/man1/intro.1.html
+ * No standard.
// 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)
diff --git a/toys/lsb/mount.c b/toys/lsb/mount.c
index 22021ab9..10e8e9e4 100644
--- a/toys/lsb/mount.c
+++ b/toys/lsb/mount.c
@@ -232,8 +232,7 @@ static void mount_filesystem(char *dev, char *dir, char *type,
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?
@@ -354,8 +353,7 @@ void mount_main(void)
continue;
} else {
if (dir && strcmp(dir, mm->dir)) continue;
- if (dev && strcmp(dev, mm->device) && (dir || strcmp(dev, mm->dir)))
- continue;
+ if (strcmp(dev, mm->device) && (dir || strcmp(dev, mm->dir))) continue;
}
// Don't overmount the same dev on the same directory
diff --git a/toys/net/ifconfig.c b/toys/net/ifconfig.c
index e2944579..e9671bb5 100644
--- a/toys/net/ifconfig.c
+++ b/toys/net/ifconfig.c
@@ -42,6 +42,7 @@ config IFCONFIG
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 -):
@@ -405,6 +406,7 @@ void ifconfig_main(void)
{"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},
@@ -493,6 +495,7 @@ void ifconfig_main(void)
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;
@@ -505,11 +508,12 @@ void ifconfig_main(void)
// Assign value to ifre field and call ioctl? (via IFREQ_OFFSZ.)
if (on < 0) {
- long l = strtoul(*argv, 0, 0);
+ void *dest = ((on = -on)>>16)+(char *)&ifre;
+ // If we're about to set mem_start/io_addr/irq, get other 2 first
if (off == SIOCSIFMAP) xioctl(TT.sockfd, SIOCGIFMAP, &ifre);
- on = -on;
- poke((on>>16) + (char *)&ifre, l, on&15);
+ if (off == SIOCSIFNAME) xstrncpy(dest, *argv, on&0xffff);
+ else poke(dest, strtoul(*argv, 0, 0), on&15);
xioctl(TT.sockfd, off, &ifre);
break;
} else {
diff --git a/toys/other/chvt.c b/toys/other/chvt.c
deleted file mode 100644
index 7d69f9a4..00000000
--- a/toys/other/chvt.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/* 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"
-#include <linux/vt.h>
-
-void chvt_main(void)
-{
- int vt, fd;
- char *consoles[]={"/dev/console", "/dev/vc/0", "/dev/tty", NULL}, **cc;
-
- vt = atoi(*toys.optargs);
- for (cc = consoles; *cc; cc++) if ((fd = open(*cc, O_RDWR)) != -1) break;
-
- if (fd == -1 || ioctl(fd, VT_ACTIVATE, vt) || ioctl(fd, VT_WAITACTIVE, vt))
- perror_exit(0);
-}
diff --git a/toys/other/factor.c b/toys/other/factor.c
index f0e69c5d..47e1267b 100644
--- a/toys/other/factor.c
+++ b/toys/other/factor.c
@@ -2,7 +2,7 @@
*
* Copyright 2014 Rob Landley <rob@landley.net>
*
- * No standard, but it's in coreutils
+ * See https://man7.org/linux/man-pages/man1/factor.1.html
USE_FACTOR(NEWTOY(factor, 0, TOYFLAG_USR|TOYFLAG_BIN))
@@ -19,7 +19,7 @@ config FACTOR
static void factor(char *s)
{
- unsigned long long l, ll;
+ unsigned long long l, ll, lll;
for (;;) {
char *err = s;
@@ -55,9 +55,8 @@ static void factor(char *s)
}
// test odd numbers until square is > remainder or integer wrap.
- for (ll=3; ;ll += 2) {
- long lll = ll*ll;
-
+ for (ll = 3;; ll += 2) {
+ lll = ll*ll;
if (lll>l || lll<ll) {
if (l>1) printf(" %llu", l);
break;
@@ -73,14 +72,11 @@ static void factor(char *s)
void factor_main(void)
{
- if (toys.optc) {
- char **ss;
-
- for (ss = toys.optargs; *ss; ss++) factor(*ss);
- } else for (;;) {
- char *s = 0;
- size_t len = 0;
+ char *s = 0, **ss;
+ size_t len = 0;
+ if (toys.optc) for (ss = toys.optargs; *ss; ss++) factor(*ss);
+ else for (;;) {
if (-1 == getline(&s, &len, stdin)) break;
factor(s);
}
diff --git a/toys/other/ionice.c b/toys/other/ionice.c
index 07a212b2..db3a6f41 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"
diff --git a/toys/other/openvt.c b/toys/other/openvt.c
new file mode 100644
index 00000000..8210587d
--- /dev/null
+++ b/toys/other/openvt.c
@@ -0,0 +1,115 @@
+/* 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/readlink.c b/toys/other/readlink.c
index 55234ccf..3155dcc5 100644
--- a/toys/other/readlink.c
+++ b/toys/other/readlink.c
@@ -4,7 +4,7 @@
// -ef positions match ABS_FILE ABS_PATH
USE_READLINK(NEWTOY(readlink, "<1nqmef(canonicalize)[-mef]", TOYFLAG_USR|TOYFLAG_BIN))
-USE_REALPATH(NEWTOY(realpath, "<1", TOYFLAG_USR|TOYFLAG_BIN))
+USE_REALPATH(OLDTOY(realpath, readlink, TOYFLAG_USR|TOYFLAG_BIN))
config READLINK
bool "readlink"
@@ -39,6 +39,7 @@ void readlink_main(void)
{
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
@@ -52,9 +53,3 @@ void readlink_main(void)
} else toys.exitval = 1;
}
}
-
-void realpath_main(void)
-{
- toys.optflags = FLAG_f;
- readlink_main();
-}
diff --git a/toys/pending/openvt.c b/toys/pending/openvt.c
deleted file mode 100644
index 3cc97daa..00000000
--- a/toys/pending/openvt.c
+++ /dev/null
@@ -1,102 +0,0 @@
-/* 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/pending/sh.c b/toys/pending/sh.c
index 85be8266..8f45c172 100644
--- a/toys/pending/sh.c
+++ b/toys/pending/sh.c
@@ -350,6 +350,7 @@ void debug_show_fds()
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));
@@ -1547,7 +1548,7 @@ static void wildcard_add_files(struct sh_arg *arg, char *pattern,
if (!dt) return arg_add(arg, pattern);
while (dt) {
while (dt->child) dt = dt->child;
- arg_add(arg, dirtree_path(dt, 0));
+ arg_add(arg, push_arg(delete, dirtree_path(dt, 0)));
do {
pp = (void *)dt;
if ((dt = dt->parent)) dt->child = dt->child->next;
@@ -2285,9 +2286,7 @@ static struct sh_process *expand_redir(struct sh_arg *arg, int skip, int *urd)
for (j = skip; j<arg->c; j++) {
int saveclose = 0, bad = 0;
- s = arg->v[j];
-
- if (!strcmp(s, "!")) {
+ if (!strcmp(s = arg->v[j], "!")) {
pp->flags ^= PFLAG_NOT;
continue;
@@ -2889,8 +2888,10 @@ funky:
// Stop at EOL. Discard blank pipeline segment, else end segment
if (end == start) done++;
- if (!pl->type && !arg->c) free_pipeline(dlist_lpop(ppl));
- else pl->count = -1;
+ if (!pl->type && !arg->c) {
+ free_pipeline(dlist_lpop(ppl));
+ pl = *ppl ? (*ppl)->prev : 0;
+ } else pl->count = -1;
continue;
}
diff --git a/toys/pending/wget.c b/toys/pending/wget.c
index bcb42f8d..9e100e87 100644
--- a/toys/pending/wget.c
+++ b/toys/pending/wget.c
@@ -26,7 +26,7 @@
* 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):", TOYFLAG_USR|TOYFLAG_BIN))
+USE_WGET(NEWTOY(wget, "<1>1(max-redirect)#<0=20d(debug)O(output-document):p(post-data):", TOYFLAG_USR|TOYFLAG_BIN))
config WGET
bool "wget"
@@ -36,6 +36,7 @@ config WGET
--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
examples:
wget http://www.example.com
@@ -70,20 +71,14 @@ config WGET_OPENSSL
#else
#define WGET_SSL 0
#endif
+#define HTTPS (WGET_SSL && TT.https)
-#define WGET_FILENAME "Content-Disposition: attachment; filename="
-#define WGET_CHUNKED "transfer-encoding: chunked"
-#define WGET_LOCATION "Location: "
-#define WGET_LIBTLS_PROTOCOLS "tlsv1.2"
-
-#define WGET_IS_HTTP (strncmp(TT.url, "http://", 7) == 0)
-#define WGET_IS_HTTPS (WGET_SSL && (strncmp(TT.url, "https://", 8) == 0))
GLOBALS(
- char *filename;
- long redirects;
+ char *p, *O;
+ long max_redirect;
- int sock;
+ int sock, https;
char *url;
#if CFG_WGET_LIBTLS
struct tls *tls;
@@ -93,65 +88,52 @@ GLOBALS(
#endif
)
-static char *wget_strncaseafter(char *haystack, char *needle)
-{
- char *result = strcasestr(haystack, needle);
- if (result) result = result + strlen(needle);
- return result;
-}
-
// get http info in URL
static void wget_info(char *url, char **host, char **port, char **path)
{
- *host = strafter(url, "://");
- *path = strchr(*host, '/');
-
- if ((*path = strchr(*host, '/'))) {
- **path = '\0';
- *path = *path + 1;
- } else {
- *path = "";
+ char *ss = url;
+
+ // 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;
}
+ if (!url) error_exit("unsupported protocol: %s", ss);
- if ( *host[0] == '[' && strchr(*host, ']') ) { // IPv6
- *port = strafter(*host, "]:");
- *host = *host + 1;
- strchr(*host, ']')[0] = '\0';
- } else { // IPv4
- if ((*port = strchr(*host, ':'))) {
- **port = '\0';
- *port = *port + 1;
- }
- }
+ if ((*path = strchr(*host = url, '/'))) *((*path)++) = 0;
+ else *path = "";
- if (!*port && WGET_IS_HTTP) *port = "80";
- else if (!*port && WGET_IS_HTTPS) *port = "443";
- else if (!*port) error_exit("unsupported protocol");
+ // 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";
}
static void wget_connect(char *host, char *port)
{
- if (WGET_IS_HTTP) {
- struct addrinfo *a =
- xgetaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, 0);
- TT.sock = xconnectany(a);
- } else if (WGET_IS_HTTPS) {
+ 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()) == NULL)
+ if (!(TT.tls = tls_client()))
error_exit("tls_client: %s", tls_error(TT.tls));
- if ((cfg = tls_config_new()) == NULL)
+ if (!(cfg = tls_config_new()))
error_exit("tls_config_new: %s", tls_config_error(cfg));
- if (tls_config_parse_protocols(&protocols, WGET_LIBTLS_PROTOCOLS) != 0)
+ if (tls_config_parse_protocols(&protocols, "tlsv1.2"))
error_exit("tls_config_parse_protocols");
- if (tls_config_set_protocols(cfg, protocols) != 0)
+ if (tls_config_set_protocols(cfg, protocols))
error_exit("tls_config_set_protocols: %s", tls_config_error(cfg));
- if (tls_configure(TT.tls, cfg) != 0)
+ if (tls_configure(TT.tls, cfg))
error_exit("tls_configure: %s", tls_error(TT.tls));
tls_config_free(cfg);
- if (tls_connect(TT.tls, host, port) != 0)
+ if (tls_connect(TT.tls, host, port))
error_exit("tls_connect: %s", tls_error(TT.tls));
#elif CFG_WGET_OPENSSL
SSL_library_init();
@@ -162,9 +144,7 @@ static void wget_connect(char *host, char *port)
TT.ctx = SSL_CTX_new(TLS_client_method());
if (!TT.ctx) error_exit("SSL_CTX_new");
- struct addrinfo *a =
- xgetaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, 0);
- TT.sock = xconnectany(a);
+ TT.sock = xconnectany(xgetaddrinfo(host, port, AF_UNSPEC, SOCK_STREAM, 0, 0));
TT.ssl = SSL_new(TT.ctx);
if (!TT.ssl)
@@ -180,39 +160,42 @@ static void wget_connect(char *host, char *port)
if (FLAG(d)) printf("TLS: %s\n", SSL_get_cipher(TT.ssl));
#endif
- } else error_exit("unsupported protocol");
+ }
}
static size_t wget_read(void *buf, size_t len)
{
- if (WGET_IS_HTTP) return xread(TT.sock, buf, len);
- else if (WGET_IS_HTTPS) {
+ if (!HTTPS) return xread(TT.sock, buf, len);
+ else {
+ char *err = 0;
+ int ret;
+
#if CFG_WGET_LIBTLS
- ssize_t ret = tls_read(TT.tls, buf, len);
- if (ret < 0) error_exit("tls_read: %s", tls_error(TT.tls));
- return ret;
+ if ((ret = tls_read(TT.tls, buf, len))<0) err = tls_error(TT.tls);
#elif CFG_WGET_OPENSSL
- int ret = SSL_read(TT.ssl, buf, (int) len);
- if (ret < 0)
- error_exit("SSL_read: %s", ERR_error_string(ERR_get_error(), NULL));
- return ret;
+ if ((ret = SSL_read(TT.ssl, buf, len))<0)
+ err = ERR_error_string(ERR_get_error(), 0);
#endif
- } else error_exit("unsupported protocol");
+ if (err) error_exit("https read: %s", err);
+
+ return ret;
+ }
}
static void wget_write(void *buf, size_t len)
{
- if (WGET_IS_HTTP) {
- xwrite(TT.sock, buf, len);
- } else if (WGET_IS_HTTPS) {
+ if (!HTTPS) xwrite(TT.sock, buf, len);
+ else {
+ char *err = 0;
+
#if CFG_WGET_LIBTLS
- if (len != tls_write(TT.tls, buf, len))
- error_exit("tls_write: %s", tls_error(TT.tls));
+ if (len != tls_write(TT.tls, buf, len)) err = tls_error(TT.tls);
#elif CFG_WGET_OPENSSL
- if (len != SSL_write(TT.ssl, buf, (int) len))
- error_exit("SSL_write: %s", ERR_error_string(ERR_get_error(), NULL));
+ if (len != SSL_write(TT.ssl, buf, len))
+ err = ERR_error_string(ERR_get_error(), 0);
#endif
- } else error_exit("unsupported protocol");
+ if (err) error_exit("https write: %s", err);
+ }
}
static void wget_close()
@@ -226,120 +209,100 @@ static void wget_close()
if (TT.tls) {
tls_close(TT.tls);
tls_free(TT.tls);
- TT.tls = NULL;
+ TT.tls = 0;
}
#elif CFG_WGET_OPENSSL
if (TT.ssl) {
SSL_shutdown(TT.ssl);
SSL_free(TT.ssl);
- TT.ssl = NULL;
+ TT.ssl = 0;
}
if (TT.ctx) {
SSL_CTX_free(TT.ctx);
- TT.ctx = NULL;
+ TT.ctx = 0;
}
#endif
}
-static char* wget_find_header(char *header, char *val) {
- char *v= wget_strncaseafter(header, val);
- return v;
-}
-
-static int wget_has_header(char *header, char *val)
-{
- return wget_find_header(header, val) != NULL;
-}
-
-static char *wget_redirect(char *header)
-{
- char *redir = wget_find_header(header, WGET_LOCATION);
- if (!redir) error_exit("could not parse redirect URL");
- return xstrndup(redir, stridx(redir, '\r'));
-}
-
-static char *wget_filename(char *header, char *path)
+static char *wget_find_header(char *header, char *val)
{
- char *f = wget_find_header(header, WGET_FILENAME);
- if (f) strchr(f, '\r')[0] = '\0';
+ char *result = strcasestr(header, val);
- if (!f && strchr(path, '/')) f = getbasename(path);
- if (!f || !(*f) ) f = "index.html";
+ if (result) {
+ result += strlen(val);
+ result[strcspn(result, "\r\n")] = 0;
+ }
- return f;
+ return result;
}
void wget_main(void)
{
long status = 0;
size_t len, c_len = 0;
- int fd, chunked;
- char *body, *index, *host, *port, *path;
+ int fd = 0;
+ char *body, *index, *host, *port, *path, *chunked, *ss;
char agent[] = "toybox wget/" TOYBOX_VERSION;
- TT.url = xstrdup(toys.optargs[0]);
+ TT.url = xstrdup(*toys.optargs);
- for (;status != 200; TT.redirects--) {
- if (TT.redirects < 0) error_exit("Too many redirects");
+ // Ask server for URL, following redirects until success
+ while (status != 200) {
+ if (!TT.max_redirect--) error_exit("Too many redirects");
+ // Connect and write request
wget_info(TT.url, &host, &port, &path);
-
- sprintf(toybuf, "GET /%s HTTP/1.1\r\nHost: %s\r\n"
- "User-Agent: %s\r\nConnection: close\r\n\r\n",
- path, host, agent);
- if (FLAG(d)) printf("--- Request\n%s", toybuf);
-
+ 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(toybuf, strlen(toybuf));
-
- // Greedily read the HTTP response until either complete or toybuf is full
- index = toybuf;
- while ((len = wget_read(index, sizeof(toybuf) - (index - toybuf))) > 0)
- index += len;
-
- //Process the response such that
- // Valid ranges toybuf[0...index) valid length is (index - toybuf)
- // Header ranges toybuf[0...body) header length strlen(toybuf)
- // Remnant Body toybuf[body...index) valid remnant body length is len
- //
- // Per RFC7230 the header cannot contain a NUL octet so we NUL terminate at
- // the footer of the header. This allows for normal string functions to be
- // used when processing the header.
- body = memmem(toybuf, index - toybuf, "\r\n\r\n", 4);
- if (!body) error_exit("response header too large");
- body[0] = '\0'; // NUL terminate the headers
- body += 4; // Skip to the head of body
- len = index - body; // Adjust len to be body length
+ wget_write(ss, strlen(ss));
+ free(ss);
+
+ // 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);
+
+ // 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);
- status = strtol(strafter(toybuf, " "), NULL, 10);
+ 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 = wget_redirect(toybuf);
+ TT.url = xstrdup(ss);
wget_close();
} else if (status != 200) error_exit("response: %ld", status);
}
- if (!FLAG(O)) {
- TT.filename = wget_filename(toybuf, path);
- if (!access(TT.filename, F_OK))
- error_exit("%s already exists", TT.filename);
+ // 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);
}
- fd = xcreate(TT.filename, (O_WRONLY|O_CREAT|O_TRUNC), 0644);
-
- chunked = wget_has_header(toybuf, WGET_CHUNKED);
+ // 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.
- if (chunked) {
- len = len + 2;
- memmove(toybuf, body - 2, len);
- } else {
- memmove(toybuf, body, len);
- }
+ 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
@@ -360,7 +323,7 @@ void wget_main(void)
// 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 == 0) && (len > 2)) {
+ if (!c_len && (len > 2)) {
char *c;
if (strncmp(toybuf, "\r\n", 2) != 0) error_exit("chunk boundary");
@@ -369,7 +332,7 @@ void wget_main(void)
c = memmem(toybuf + 2, len - 2, "\r\n",2);
if (c) {
c_len = strtol(toybuf + 2, NULL, 16);
- if (c_len == 0) goto exit; // A c_len of zero means we are complete
+ if (!c_len) break; // A c_len of zero means we are complete
len = len - (c - toybuf) - 2;
memmove(toybuf, c + 2, len);
}
@@ -382,7 +345,6 @@ void wget_main(void)
}
} while ((len += wget_read(toybuf + len, sizeof(toybuf) - len)) > 0);
- exit:
wget_close();
free(TT.url);
-} \ No newline at end of file
+}
diff --git a/toys/posix/file.c b/toys/posix/file.c
index 9330da13..2e65bcfa 100644
--- a/toys/posix/file.c
+++ b/toys/posix/file.c
@@ -69,15 +69,9 @@ static void do_elf_file(int fd)
// "x86".
printf("%s", elf_arch_name(elf_int(toybuf+18, 2)));
- if (bail) goto bad;
// If what we've seen so far doesn't seem consistent, bail.
-
- // 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;
+ if (bail) 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);
@@ -93,15 +87,24 @@ static void do_elf_file(int fd)
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);
+ 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)))
+ if (MAP_FAILED == (map = mmap(0, TT.len, PROT_READ, MAP_SHARED, fd, 0))) {
+ perror_msg("mmap");
goto bad;
+ }
// Read the phdrs for dynamic vs static. (Note: fields reordered on 64 bit)
- if (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);
@@ -113,7 +116,10 @@ static void do_elf_file(int fd)
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) goto bad;
+ 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?
printf(", dynamic (%.*s)", (int)p_filesz, map+p_offset);
}
@@ -123,18 +129,23 @@ static void do_elf_file(int fd)
// 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)
- 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))) goto bad;
+ if (shdr>map+TT.len-(8+(4<<bits))) {
+ printf(", bad shdr %d?", i);
+ 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) goto bad;
+ if (sh_offset>TT.len || sh_size>TT.len-sh_offset) {
+ printf(", bad shdr %d?", i);
+ goto bad;
+ }
if (sh_type == 2 /*SHT_SYMTAB*/) {
stripped = 0;
@@ -149,16 +160,22 @@ static void do_elf_file(int fd)
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) goto bad;
+ if (note>map+TT.len-3*4) {
+ printf(", bad note %d?", i);
+ 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;
- // Does the claimed size of this note actually fit in the section?
- if (notesz > sh_size) 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;
+ }
if (n_namesz==4 && !memcmp(note+12, "GNU", 4) && n_type==3) {
printf(", BuildID=");
diff --git a/toys/posix/tar.c b/toys/posix/tar.c
index bd68873c..9cf1a5c9 100644
--- a/toys/posix/tar.c
+++ b/toys/posix/tar.c
@@ -17,7 +17,7 @@
* Why --exclude pattern but no --include? tar cvzf a.tgz dir --include '*.txt'
*
-USE_TAR(NEWTOY(tar, "&(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, "&(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))
config TAR
bool "tar"
@@ -34,13 +34,13 @@ config TAR
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 modes --mtime TIME Override timestamps
- --owner NAME Set file owner to NAME --group NAME Set file group to NAME
- --sparse Record sparse files --selinux Record/restore labels
- --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
+ --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
-I PROG Filter through PROG to compress or PROG -d to decompress
*/
@@ -52,6 +52,7 @@ GLOBALS(
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;
@@ -225,8 +226,12 @@ static int add_to_tar(struct dirtree *node)
if (!(lnk = strstr(lnk, ".."))) break;
if (lnk == hname || lnk[-1] == '/') {
if (!lnk[2]) goto done;
- if (lnk[2]=='/') lnk = hname = lnk+3;
- } else lnk+= 2;
+ if (lnk[2]=='/') {
+ lnk = hname = lnk+3;
+ continue;
+ }
+ }
+ lnk += 2;
}
if (!*hname) goto done;
@@ -332,10 +337,10 @@ static int add_to_tar(struct dirtree *node)
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 ? TT.owner : pw->pw_name, sizeof(hdr.uname));
+ strncpy(hdr.uname, 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 ? TT.group : gr->gr_name, sizeof(hdr.gname));
+ strncpy(hdr.gname, TT.group ? : gr->gr_name, sizeof(hdr.gname));
}
TT.sparselen = 0;
@@ -516,7 +521,15 @@ error:
static void extract_to_disk(void)
{
char *name = TT.hdr.name;
- int ala = TT.hdr.mode;
+ 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;
+ }
if (dirflush(name, S_ISDIR(ala))) {
if (S_ISREG(ala) && !TT.hdr.link_target) skippy(TT.hdr.size);
@@ -539,17 +552,16 @@ static void extract_to_disk(void)
return perror_msg("can't link '%s' -> '%s'", name, TT.hdr.link_target);
// write contents
} else {
- int fd = xcreate(name,
- WARN_ONLY|O_WRONLY|O_CREAT|(FLAG(overwrite)?O_TRUNC:O_EXCL),
- ala & 07777);
- if (fd != -1) sendfile_sparse(fd);
+ 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);
}
} else if (S_ISDIR(ala)) {
if ((mkdir(name, 0700) == -1) && errno != EEXIST)
- return perror_msg("%s: can't create", TT.hdr.name);
+ return perror_msg("%s: can't create", name);
} else if (S_ISLNK(ala)) {
- if (symlink(TT.hdr.link_target, TT.hdr.name))
+ if (symlink(TT.hdr.link_target, 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);
@@ -560,20 +572,20 @@ static void extract_to_disk(void)
if (TT.owner) TT.hdr.uid = TT.ouid;
else if (!FLAG(numeric_owner) && *TT.hdr.uname) {
- struct passwd *pw = getpwnam(TT.hdr.uname);
+ struct passwd *pw = bufgetpwnamuid(TT.hdr.uname, 0);
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 = getgrnam(TT.hdr.gname);
+ struct group *gr = bufgetgrnamgid(TT.hdr.gname, 0);
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(TT.hdr.name, FLAG(p) ? ala : ala&0777);
+ if (!S_ISLNK(ala)) chmod(name, FLAG(p) ? ala : ala&0777);
// Apply mtime.
if (!FLAG(m)) {
@@ -588,7 +600,7 @@ static void extract_to_disk(void)
strcpy(sl->str+sizeof(long long), name);
sl->next = TT.dirs;
TT.dirs = sl;
- } else wsettime(TT.hdr.name, TT.hdr.mtime);
+ } else wsettime(name, TT.hdr.mtime);
}
}
@@ -712,18 +724,18 @@ static void unpack_tar(char *first)
maj = OTOI(tar.major);
min = OTOI(tar.minor);
TT.hdr.device = dev_makedev(maj, min);
- 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));
+ TT.hdr.uname = xstrndup(TT.owner ? : tar.uname, sizeof(tar.uname));
+ TT.hdr.gname = xstrndup(TT.group ? : tar.gname, sizeof(tar.gname));
if (TT.owner) TT.hdr.uid = TT.ouid;
else if (!FLAG(numeric_owner)) {
- struct passwd *pw = getpwnam(TT.hdr.uname);
+ struct passwd *pw = bufgetpwnamuid(TT.hdr.uname, 0);
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 = getgrnam(TT.hdr.gname);
+ struct group *gr = bufgetgrnamgid(TT.hdr.gname, 0);
if (gr) TT.hdr.gid = gr->gr_gid;
}
@@ -857,8 +869,20 @@ void tar_main(void)
// Get possible early errors out of the way
if (!geteuid()) toys.optflags |= FLAG_p;
- if (TT.owner) TT.ouid = xgetuid(TT.owner);
- if (TT.group) TT.ggid = xgetgid(TT.group);
+ 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.mtime) xparsedate(TT.mtime, &TT.mtt, (void *)&s, 1);
// Collect file list.
diff --git a/www/roadmap.html b/www/roadmap.html
index 865d9515..551eb2eb 100644
--- a/www/roadmap.html
+++ b/www/roadmap.html
@@ -360,7 +360,7 @@ but after toybox 1.0 we plan to try
<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=P7n6G2IL6eo>not
+but that's actually <a href=https://www.youtube.com/watch?v=I-lGyn3PHP4>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