diff options
author | Elliott Hughes <enh@google.com> | 2022-04-19 01:14:22 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2022-04-19 01:14:22 +0000 |
commit | 52a5af013efa6ca0150d5f07a25cb87361b728a7 (patch) | |
tree | d0e498a531fab84c92b3ab6e9eade306d7918165 | |
parent | bc93cfd83482cfe1b91c98ae2c294a5c63720f5c (diff) | |
parent | a30dc69f0f91476e8b3acf750d82908c9711724c (diff) | |
download | toybox-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>
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 @@ -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 @@ -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 } } @@ -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)) @@ -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. @@ -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; @@ -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) { @@ -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) @@ -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 |