aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-09-14 13:19:57 +1000
committerNguyễn Thái Ngọc Duy <pclouds@gmail.com>2010-09-14 13:19:57 +1000
commitec71cb6575290eb6ad716e4f620db445d8e1bcd3 (patch)
tree219a5dba000e0ad98ff563bc6f7d45d274d3a178
parentb5139d7cd8982d9b683cb1babf0bd759076aaab0 (diff)
parent6814cbc9288601840aedb372e2bd84dab76ffa43 (diff)
downloadbusybox-w32-ec71cb6575290eb6ad716e4f620db445d8e1bcd3.tar.gz
busybox-w32-ec71cb6575290eb6ad716e4f620db445d8e1bcd3.tar.bz2
busybox-w32-ec71cb6575290eb6ad716e4f620db445d8e1bcd3.zip
Merge branch 'origin/master' (early part)
-rw-r--r--Config.in14
-rw-r--r--Makefile.custom1
-rw-r--r--archival/Config.src2
-rw-r--r--archival/bz/compress.c1
-rw-r--r--archival/libunarchive/unxz/README1
-rw-r--r--archival/lzo1x_9x.c1
-rw-r--r--archival/unzip.c1
-rw-r--r--console-tools/Config.src13
-rw-r--r--coreutils/Config.src1
-rw-r--r--coreutils/cut.c1
-rw-r--r--coreutils/date.c2
-rw-r--r--coreutils/dos2unix.c2
-rw-r--r--coreutils/expr.c1
-rw-r--r--coreutils/ls.c2
-rw-r--r--coreutils/readlink.c5
-rw-r--r--coreutils/stty.c339
-rw-r--r--debianutils/Config.src1
-rw-r--r--debianutils/mktemp.c2
-rw-r--r--docs/busybox_footer.pod1
-rw-r--r--docs/busybox_header.pod1
-rw-r--r--docs/cgi/cl.html2
-rw-r--r--docs/cgi/env.html2
-rw-r--r--docs/cgi/in.html2
-rw-r--r--docs/cgi/interface.html2
-rw-r--r--docs/cgi/out.html2
-rw-r--r--docs/contributing.txt2
-rw-r--r--docs/ifupdown_design.txt28
-rw-r--r--docs/posix_conformance.txt1
-rw-r--r--e2fsprogs/Config.src3
-rw-r--r--e2fsprogs/old_e2fsprogs/e2fsck.c34
-rw-r--r--e2fsprogs/old_e2fsprogs/e2fsck.h2
-rw-r--r--e2fsprogs/old_e2fsprogs/e2p/ostype.c2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/alloc.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/alloc_tables.c4
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bb_inode.c6
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bitops.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/block.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bmap.c3
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/bmove.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/brel.h1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/closefs.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/cmp_bitmaps.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/dir_iterate.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/dirblock.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/dupfs.c2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/e2image.h13
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext2_ext_attr.h1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ext2fsP.h2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/freefs.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/get_pathname.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/ind_block.c2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/inline.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/inode.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/inode_io.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/jfs_dat.h2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/lookup.c2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/mkdir.c3
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/mkjournal.c2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/namei.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/newdir.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/read_bb.c2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/read_bb_file.c2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/res_gdt.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/rs_bitmap.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/rw_bitmaps.c2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/swapfs.c2
-rw-r--r--e2fsprogs/old_e2fsprogs/ext2fs/unlink.c1
-rw-r--r--e2fsprogs/old_e2fsprogs/util.c1
-rw-r--r--editors/sed.c13
-rw-r--r--editors/vi.c20
-rw-r--r--examples/bootfloppy/display.txt1
-rw-r--r--examples/bootfloppy/etc/fstab1
-rw-r--r--examples/bootfloppy/etc/inittab1
-rw-r--r--examples/bootfloppy/etc/profile1
-rwxr-xr-xexamples/bootfloppy/mkrootfs.sh1
-rw-r--r--examples/inittab1
-rwxr-xr-xexamples/udhcp/sample.bound2
-rwxr-xr-xexamples/udhcp/sample.renew2
-rw-r--r--include/applets.src.h1
-rw-r--r--include/libbb.h26
-rw-r--r--include/usage.src.h33
-rw-r--r--init/Config.src12
-rw-r--r--init/bootchartd.c19
-rw-r--r--init/halt.c14
-rw-r--r--init/init.c35
-rw-r--r--init/reboot.h30
-rw-r--r--libbb/Config.src3
-rw-r--r--libbb/README1
-rw-r--r--libbb/lineedit.c52
-rw-r--r--libbb/make_directory.c2
-rw-r--r--libbb/selinux_common.c1
-rw-r--r--libbb/xfuncs_printf.c4
-rw-r--r--loginutils/addgroup.c1
-rw-r--r--loginutils/getty.c27
-rw-r--r--loginutils/login.c2
-rw-r--r--loginutils/vlock.c15
-rw-r--r--miscutils/Config.src22
-rw-r--r--miscutils/conspy.c1
-rw-r--r--miscutils/crond.c1
-rw-r--r--miscutils/dc.c65
-rw-r--r--miscutils/hdparm.c4
-rw-r--r--miscutils/ubi_attach_detach.c2
-rw-r--r--modutils/Config.src1
-rw-r--r--modutils/depmod.c76
-rw-r--r--networking/Config.src28
-rw-r--r--networking/httpd.c109
-rw-r--r--networking/ifplugd.c333
-rw-r--r--networking/interface.c1
-rw-r--r--networking/ip.c62
-rw-r--r--networking/libiproute/ip_common.h29
-rw-r--r--networking/libiproute/ip_parse_common_args.c2
-rw-r--r--networking/libiproute/ipaddress.c4
-rw-r--r--networking/libiproute/iplink.c2
-rw-r--r--networking/libiproute/iproute.c2
-rw-r--r--networking/libiproute/iprule.c2
-rw-r--r--networking/libiproute/iptunnel.c2
-rw-r--r--networking/libiproute/libnetlink.c38
-rw-r--r--networking/libiproute/libnetlink.h6
-rw-r--r--networking/libiproute/ll_proto.c1
-rw-r--r--networking/nc.c2
-rw-r--r--networking/ntpd.c2
-rw-r--r--networking/tcpudp.c5
-rw-r--r--networking/telnet.c1
-rw-r--r--networking/traceroute.c1
-rw-r--r--networking/udhcp/Config.src2
-rw-r--r--procps/Config.src4
-rw-r--r--procps/mpstat.c1017
-rw-r--r--scripts/Makefile.host1
-rw-r--r--scripts/Makefile.lib2
-rw-r--r--scripts/basic/docproc.c1
-rwxr-xr-xscripts/find_stray_empty_lines19
-rwxr-xr-xscripts/gen_build_files.sh4
-rwxr-xr-xscripts/kconfig/check.sh1
-rw-r--r--scripts/kconfig/lex.zconf.c_shipped4
-rw-r--r--scripts/kconfig/menu.c1
-rw-r--r--scripts/kconfig/util.c1
-rw-r--r--scripts/kconfig/zconf.hash.c_shipped1
-rw-r--r--scripts/kconfig/zconf.tab.c_shipped2
-rw-r--r--scripts/kconfig/zconf.y2
-rwxr-xr-xscripts/showasm1
-rw-r--r--selinux/Config.src1
-rw-r--r--selinux/setfiles.c1
-rw-r--r--shell/Config.src59
-rw-r--r--shell/Kbuild.src1
-rw-r--r--shell/ash.c87
-rwxr-xr-x[-rw-r--r--]shell/ash_test/ash-redir/redir9.tests0
-rw-r--r--shell/ash_test/ash-signals/signal7.right1
-rwxr-xr-xshell/ash_test/ash-signals/signal7.tests18
-rw-r--r--shell/ash_test/ash-vars/var_bash3.right40
-rwxr-xr-xshell/ash_test/ash-vars/var_bash3.tests47
-rw-r--r--shell/ash_test/ash-vars/var_bash4.right4
-rwxr-xr-xshell/ash_test/ash-vars/var_bash4.tests6
-rw-r--r--shell/cttyhack.c66
-rw-r--r--shell/hush.c19
-rwxr-xr-xshell/hush_test/hush-misc/break1.tests1
-rw-r--r--shell/hush_test/hush-trap/signal7.right1
-rwxr-xr-xshell/hush_test/hush-trap/signal7.tests18
-rw-r--r--shell/shell_common.c7
-rw-r--r--sysklogd/Config.src17
-rw-r--r--sysklogd/klogd.c128
-rw-r--r--sysklogd/syslogd.c26
-rw-r--r--testsuite/basename/basename-works1
-rw-r--r--testsuite/dirname/dirname-works1
-rw-r--r--testsuite/expr/expr-works1
-rw-r--r--testsuite/ln/ln-preserves-soft-links1
-rwxr-xr-xtestsuite/readlink.tests1
-rwxr-xr-xtestsuite/sed.tests7
-rw-r--r--testsuite/testing.sh2
-rwxr-xr-xtestsuite/tr.tests6
-rw-r--r--testsuite/uptime/uptime-works1
-rw-r--r--util-linux/Config.src27
-rw-r--r--util-linux/fdisk.c1
-rw-r--r--util-linux/volume_id/volume_id.c1
173 files changed, 2382 insertions, 948 deletions
diff --git a/Config.in b/Config.in
index 0a90f6a8a..21c28e667 100644
--- a/Config.in
+++ b/Config.in
@@ -29,7 +29,7 @@ menu "General Configuration"
29 29
30config DESKTOP 30config DESKTOP
31 bool "Enable options for full-blown desktop systems" 31 bool "Enable options for full-blown desktop systems"
32 default n 32 default y
33 help 33 help
34 Enable options and features which are not essential. 34 Enable options and features which are not essential.
35 Select this only if you plan to use busybox on full-blown 35 Select this only if you plan to use busybox on full-blown
@@ -61,6 +61,17 @@ config USE_PORTABLE_CODE
61 compiler other than gcc. 61 compiler other than gcc.
62 If you do use gcc, this option may needlessly increase code size. 62 If you do use gcc, this option may needlessly increase code size.
63 63
64config PLATFORM_LINUX
65 bool "Enable Linux-specific applets and features"
66 default y
67 help
68 For the most part, busybox requires only POSIX compatibility
69 from the target system, but some applets and features use
70 Linux-specific interfaces.
71
72 Answering 'N' here will disable such applets and hide the
73 corresponding configuration options.
74
64choice 75choice
65 prompt "Buffer allocation policy" 76 prompt "Buffer allocation policy"
66 default FEATURE_BUFFERS_USE_MALLOC 77 default FEATURE_BUFFERS_USE_MALLOC
@@ -367,6 +378,7 @@ config FEATURE_SUID_CONFIG_QUIET
367config SELINUX 378config SELINUX
368 bool "Support NSA Security Enhanced Linux" 379 bool "Support NSA Security Enhanced Linux"
369 default n 380 default n
381 depends on PLATFORM_LINUX
370 help 382 help
371 Enable support for SELinux in applets ls, ps, and id. Also provide 383 Enable support for SELinux in applets ls, ps, and id. Also provide
372 the option of compiling in SELinux applets. 384 the option of compiling in SELinux applets.
diff --git a/Makefile.custom b/Makefile.custom
index 01d69ddf8..c6577a568 100644
--- a/Makefile.custom
+++ b/Makefile.custom
@@ -125,6 +125,7 @@ docs/busybox.pod: $(srctree)/docs/busybox_header.pod \
125 $(Q)-mkdir -p docs 125 $(Q)-mkdir -p docs
126 $(Q)-( \ 126 $(Q)-( \
127 cat $(srctree)/docs/busybox_header.pod; \ 127 cat $(srctree)/docs/busybox_header.pod; \
128 echo; \
128 applets/usage_pod | sed 's/^[A-Za-z][A-Za-z ]*[a-z]:$$/&\n/'; \ 129 applets/usage_pod | sed 's/^[A-Za-z][A-Za-z ]*[a-z]:$$/&\n/'; \
129 cat $(srctree)/docs/busybox_footer.pod; \ 130 cat $(srctree)/docs/busybox_footer.pod; \
130 ) > docs/busybox.pod 131 ) > docs/busybox.pod
diff --git a/archival/Config.src b/archival/Config.src
index f64b3347b..9a84fd6c6 100644
--- a/archival/Config.src
+++ b/archival/Config.src
@@ -39,7 +39,7 @@ config FEATURE_SEAMLESS_Z
39 39
40config AR 40config AR
41 bool "ar" 41 bool "ar"
42 default y 42 default n # needs to be improved to be able to replace binutils ar
43 help 43 help
44 ar is an archival utility program used to create, modify, and 44 ar is an archival utility program used to create, modify, and
45 extract contents from archives. An archive is a single file holding 45 extract contents from archives. An archive is a single file holding
diff --git a/archival/bz/compress.c b/archival/bz/compress.c
index 640b8872b..b9b0949a9 100644
--- a/archival/bz/compress.c
+++ b/archival/bz/compress.c
@@ -212,7 +212,6 @@ void generateMTFValues(EState* s)
212 wr++; 212 wr++;
213 s->mtfFreq[j+1]++; 213 s->mtfFreq[j+1]++;
214 } 214 }
215
216 } 215 }
217 } 216 }
218 217
diff --git a/archival/libunarchive/unxz/README b/archival/libunarchive/unxz/README
index f79b0a404..c5972f6b8 100644
--- a/archival/libunarchive/unxz/README
+++ b/archival/libunarchive/unxz/README
@@ -133,4 +133,3 @@ Specifying the calling convention
133 For example, on Windows, you may make all functions use the stdcall 133 For example, on Windows, you may make all functions use the stdcall
134 calling convention by defining XZ_FUNC=__stdcall when building and 134 calling convention by defining XZ_FUNC=__stdcall when building and
135 using the functions from XZ Embedded. 135 using the functions from XZ Embedded.
136
diff --git a/archival/lzo1x_9x.c b/archival/lzo1x_9x.c
index 0baed5469..483205155 100644
--- a/archival/lzo1x_9x.c
+++ b/archival/lzo1x_9x.c
@@ -675,7 +675,6 @@ static int min_gain(unsigned ahead, unsigned lit1,
675static void better_match(const lzo_swd_p swd, 675static void better_match(const lzo_swd_p swd,
676 unsigned *m_len, unsigned *m_off) 676 unsigned *m_len, unsigned *m_off)
677{ 677{
678
679 if (*m_len <= M2_MIN_LEN) 678 if (*m_len <= M2_MIN_LEN)
680 return; 679 return;
681 680
diff --git a/archival/unzip.c b/archival/unzip.c
index 84081c021..d9705a56e 100644
--- a/archival/unzip.c
+++ b/archival/unzip.c
@@ -359,7 +359,6 @@ int unzip_main(int argc, char **argv)
359 359
360 default: 360 default:
361 bb_show_usage(); 361 bb_show_usage();
362
363 } 362 }
364 break; 363 break;
365 364
diff --git a/console-tools/Config.src b/console-tools/Config.src
index 6e3191ada..cdb26800e 100644
--- a/console-tools/Config.src
+++ b/console-tools/Config.src
@@ -10,6 +10,7 @@ INSERT
10config CHVT 10config CHVT
11 bool "chvt" 11 bool "chvt"
12 default y 12 default y
13 depends on PLATFORM_LINUX
13 help 14 help
14 This program is used to change to another terminal. 15 This program is used to change to another terminal.
15 Example: chvt 4 (change to terminal /dev/tty4) 16 Example: chvt 4 (change to terminal /dev/tty4)
@@ -17,6 +18,7 @@ config CHVT
17config FGCONSOLE 18config FGCONSOLE
18 bool "fgconsole" 19 bool "fgconsole"
19 default y 20 default y
21 depends on PLATFORM_LINUX
20 help 22 help
21 This program prints active (foreground) console number. 23 This program prints active (foreground) console number.
22 24
@@ -29,12 +31,14 @@ config CLEAR
29config DEALLOCVT 31config DEALLOCVT
30 bool "deallocvt" 32 bool "deallocvt"
31 default y 33 default y
34 depends on PLATFORM_LINUX
32 help 35 help
33 This program deallocates unused virtual consoles. 36 This program deallocates unused virtual consoles.
34 37
35config DUMPKMAP 38config DUMPKMAP
36 bool "dumpkmap" 39 bool "dumpkmap"
37 default y 40 default y
41 depends on PLATFORM_LINUX
38 help 42 help
39 This program dumps the kernel's keyboard translation table to 43 This program dumps the kernel's keyboard translation table to
40 stdout, in binary format. You can then use loadkmap to load it. 44 stdout, in binary format. You can then use loadkmap to load it.
@@ -42,18 +46,21 @@ config DUMPKMAP
42config KBD_MODE 46config KBD_MODE
43 bool "kbd_mode" 47 bool "kbd_mode"
44 default y 48 default y
49 depends on PLATFORM_LINUX
45 help 50 help
46 This program reports and sets keyboard mode. 51 This program reports and sets keyboard mode.
47 52
48config LOADFONT 53config LOADFONT
49 bool "loadfont" 54 bool "loadfont"
50 default y 55 default y
56 depends on PLATFORM_LINUX
51 help 57 help
52 This program loads a console font from standard input. 58 This program loads a console font from standard input.
53 59
54config LOADKMAP 60config LOADKMAP
55 bool "loadkmap" 61 bool "loadkmap"
56 default y 62 default y
63 depends on PLATFORM_LINUX
57 help 64 help
58 This program loads a keyboard translation table from 65 This program loads a keyboard translation table from
59 standard input. 66 standard input.
@@ -61,6 +68,7 @@ config LOADKMAP
61config OPENVT 68config OPENVT
62 bool "openvt" 69 bool "openvt"
63 default y 70 default y
71 depends on PLATFORM_LINUX
64 help 72 help
65 This program is used to start a command on an unused 73 This program is used to start a command on an unused
66 virtual terminal. 74 virtual terminal.
@@ -92,6 +100,7 @@ config FEATURE_RESIZE_PRINT
92config SETCONSOLE 100config SETCONSOLE
93 bool "setconsole" 101 bool "setconsole"
94 default y 102 default y
103 depends on PLATFORM_LINUX
95 help 104 help
96 This program redirects the system console to another device, 105 This program redirects the system console to another device,
97 like the current tty while logged in via telnet. 106 like the current tty while logged in via telnet.
@@ -106,6 +115,7 @@ config FEATURE_SETCONSOLE_LONG_OPTIONS
106config SETFONT 115config SETFONT
107 bool "setfont" 116 bool "setfont"
108 default y 117 default y
118 depends on PLATFORM_LINUX
109 help 119 help
110 Allows to load console screen map. Useful for i18n. 120 Allows to load console screen map. Useful for i18n.
111 121
@@ -127,6 +137,7 @@ config DEFAULT_SETFONT_DIR
127config SETKEYCODES 137config SETKEYCODES
128 bool "setkeycodes" 138 bool "setkeycodes"
129 default y 139 default y
140 depends on PLATFORM_LINUX
130 help 141 help
131 This program loads entries into the kernel's scancode-to-keycode 142 This program loads entries into the kernel's scancode-to-keycode
132 map, allowing unusual keyboards to generate usable keycodes. 143 map, allowing unusual keyboards to generate usable keycodes.
@@ -134,12 +145,14 @@ config SETKEYCODES
134config SETLOGCONS 145config SETLOGCONS
135 bool "setlogcons" 146 bool "setlogcons"
136 default y 147 default y
148 depends on PLATFORM_LINUX
137 help 149 help
138 This program redirects the output console of kernel messages. 150 This program redirects the output console of kernel messages.
139 151
140config SHOWKEY 152config SHOWKEY
141 bool "showkey" 153 bool "showkey"
142 default y 154 default y
155 depends on PLATFORM_LINUX
143 help 156 help
144 Shows keys pressed. 157 Shows keys pressed.
145 158
diff --git a/coreutils/Config.src b/coreutils/Config.src
index d4c9e0541..0eb70af55 100644
--- a/coreutils/Config.src
+++ b/coreutils/Config.src
@@ -591,6 +591,7 @@ config FEATURE_SPLIT_FANCY
591config STAT 591config STAT
592 bool "stat" 592 bool "stat"
593 default y 593 default y
594 depends on PLATFORM_LINUX # statfs()
594 help 595 help
595 display file or filesystem status. 596 display file or filesystem status.
596 597
diff --git a/coreutils/cut.c b/coreutils/cut.c
index 53f343a33..696478bb2 100644
--- a/coreutils/cut.c
+++ b/coreutils/cut.c
@@ -37,7 +37,6 @@ static int cmpfunc(const void *a, const void *b)
37{ 37{
38 return (((struct cut_list *) a)->startpos - 38 return (((struct cut_list *) a)->startpos -
39 ((struct cut_list *) b)->startpos); 39 ((struct cut_list *) b)->startpos);
40
41} 40}
42 41
43static void cut_file(FILE *file, char delim, const struct cut_list *cut_lists, unsigned nlists) 42static void cut_file(FILE *file, char delim, const struct cut_list *cut_lists, unsigned nlists)
diff --git a/coreutils/date.c b/coreutils/date.c
index c737f09f3..cb41724af 100644
--- a/coreutils/date.c
+++ b/coreutils/date.c
@@ -72,7 +72,7 @@
72//config:config FEATURE_DATE_NANO 72//config:config FEATURE_DATE_NANO
73//config: bool "Support %[num]N nanosecond format specifier" 73//config: bool "Support %[num]N nanosecond format specifier"
74//config: default n 74//config: default n
75//config: depends on DATE 75//config: depends on DATE && PLATFORM_LINUX # syscall(__NR_clock_gettime)
76//config: help 76//config: help
77//config: Support %[num]N format specifier. Adds ~250 bytes of code. 77//config: Support %[num]N format specifier. Adds ~250 bytes of code.
78//config: 78//config:
diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c
index 1c8b4af1b..98eaec172 100644
--- a/coreutils/dos2unix.c
+++ b/coreutils/dos2unix.c
@@ -94,7 +94,7 @@ int dos2unix_main(int argc UNUSED_PARAM, char **argv)
94 do { 94 do {
95 /* might be convert(NULL) if there is no filename given */ 95 /* might be convert(NULL) if there is no filename given */
96 convert(*argv, conv_type); 96 convert(*argv, conv_type);
97 } while (*++argv); 97 } while (*argv && *++argv);
98 98
99 return 0; 99 return 0;
100} 100}
diff --git a/coreutils/expr.c b/coreutils/expr.c
index f40edad4e..8988340f1 100644
--- a/coreutils/expr.c
+++ b/coreutils/expr.c
@@ -341,7 +341,6 @@ static VALUE *eval6(void)
341 freev(i2); 341 freev(i2);
342 } 342 }
343 return v; 343 return v;
344
345} 344}
346 345
347/* Handle : operator (pattern matching). 346/* Handle : operator (pattern matching).
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 717b3f493..279d30c69 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -52,7 +52,6 @@
52 52
53 53
54enum { 54enum {
55
56TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */ 55TERMINAL_WIDTH = 80, /* use 79 if terminal has linefold bug */
57COLUMN_GAP = 2, /* includes the file type char */ 56COLUMN_GAP = 2, /* includes the file type char */
58 57
@@ -120,7 +119,6 @@ LIST_LONG = LIST_MODEBITS | LIST_NLINKS | LIST_ID_NAME | LIST_SIZE | \
120SPLIT_DIR = 1, 119SPLIT_DIR = 1,
121SPLIT_FILE = 0, 120SPLIT_FILE = 0,
122SPLIT_SUBDIR = 2, 121SPLIT_SUBDIR = 2,
123
124}; 122};
125 123
126/* "[-]Cadil1", POSIX mandated options, busybox always supports */ 124/* "[-]Cadil1", POSIX mandated options, busybox always supports */
diff --git a/coreutils/readlink.c b/coreutils/readlink.c
index 20df38b96..2ed5e2cac 100644
--- a/coreutils/readlink.c
+++ b/coreutils/readlink.c
@@ -36,7 +36,6 @@ int readlink_main(int argc UNUSED_PARAM, char **argv)
36{ 36{
37 char *buf; 37 char *buf;
38 char *fname; 38 char *fname;
39 char pathbuf[PATH_MAX];
40 39
41 IF_FEATURE_READLINK_FOLLOW( 40 IF_FEATURE_READLINK_FOLLOW(
42 unsigned opt; 41 unsigned opt;
@@ -56,7 +55,7 @@ int readlink_main(int argc UNUSED_PARAM, char **argv)
56 logmode = LOGMODE_NONE; 55 logmode = LOGMODE_NONE;
57 56
58 if (opt & 1) { /* -f */ 57 if (opt & 1) { /* -f */
59 buf = realpath(fname, pathbuf); 58 buf = xmalloc_realpath(fname);
60 } else { 59 } else {
61 buf = xmalloc_readlink_or_warn(fname); 60 buf = xmalloc_readlink_or_warn(fname);
62 } 61 }
@@ -65,7 +64,7 @@ int readlink_main(int argc UNUSED_PARAM, char **argv)
65 return EXIT_FAILURE; 64 return EXIT_FAILURE;
66 printf((opt & 2) ? "%s" : "%s\n", buf); 65 printf((opt & 2) ? "%s" : "%s\n", buf);
67 66
68 if (ENABLE_FEATURE_CLEAN_UP && !opt) 67 if (ENABLE_FEATURE_CLEAN_UP)
69 free(buf); 68 free(buf);
70 69
71 fflush_stdout_and_exit(EXIT_SUCCESS); 70 fflush_stdout_and_exit(EXIT_SUCCESS);
diff --git a/coreutils/stty.c b/coreutils/stty.c
index c40d718af..33f7b21dd 100644
--- a/coreutils/stty.c
+++ b/coreutils/stty.c
@@ -115,6 +115,113 @@
115# define CSTATUS Control('t') 115# define CSTATUS Control('t')
116#endif 116#endif
117 117
118/* Save us from #ifdef forest plague */
119#ifndef BSDLY
120# define BSDLY 0
121#endif
122#ifndef CIBAUD
123# define CIBAUD 0
124#endif
125#ifndef CRDLY
126# define CRDLY 0
127#endif
128#ifndef CRTSCTS
129# define CRTSCTS 0
130#endif
131#ifndef ECHOCTL
132# define ECHOCTL 0
133#endif
134#ifndef ECHOKE
135# define ECHOKE 0
136#endif
137#ifndef ECHOPRT
138# define ECHOPRT 0
139#endif
140#ifndef FFDLY
141# define FFDLY 0
142#endif
143#ifndef IEXTEN
144# define IEXTEN 0
145#endif
146#ifndef IMAXBEL
147# define IMAXBEL 0
148#endif
149#ifndef IUCLC
150# define IUCLC 0
151#endif
152#ifndef IXANY
153# define IXANY 0
154#endif
155#ifndef NLDLY
156# define NLDLY 0
157#endif
158#ifndef OCRNL
159# define OCRNL 0
160#endif
161#ifndef OFDEL
162# define OFDEL 0
163#endif
164#ifndef OFILL
165# define OFILL 0
166#endif
167#ifndef OLCUC
168# define OLCUC 0
169#endif
170#ifndef ONLCR
171# define ONLCR 0
172#endif
173#ifndef ONLRET
174# define ONLRET 0
175#endif
176#ifndef ONOCR
177# define ONOCR 0
178#endif
179#ifndef OXTABS
180# define OXTABS 0
181#endif
182#ifndef TABDLY
183# define TABDLY 0
184#endif
185#ifndef TAB1
186# define TAB1 0
187#endif
188#ifndef TAB2
189# define TAB2 0
190#endif
191#ifndef TOSTOP
192# define TOSTOP 0
193#endif
194#ifndef VDSUSP
195# define VDSUSP 0
196#endif
197#ifndef VEOL2
198# define VEOL2 0
199#endif
200#ifndef VFLUSHO
201# define VFLUSHO 0
202#endif
203#ifndef VLNEXT
204# define VLNEXT 0
205#endif
206#ifndef VREPRINT
207# define VREPRINT 0
208#endif
209#ifndef VSTATUS
210# define VSTATUS 0
211#endif
212#ifndef VSWTCH
213# define VSWTCH 0
214#endif
215#ifndef VTDLY
216# define VTDLY 0
217#endif
218#ifndef VWERASE
219# define VWERASE 0
220#endif
221#ifndef XCASE
222# define XCASE 0
223#endif
224
118/* Which speeds to set */ 225/* Which speeds to set */
119enum speed_setting { 226enum speed_setting {
120 input_speed, output_speed, both_speeds 227 input_speed, output_speed, both_speeds
@@ -167,13 +274,13 @@ enum {
167 IDX_cbreak, 274 IDX_cbreak,
168 IDX_crt, 275 IDX_crt,
169 IDX_dec, 276 IDX_dec,
170#ifdef IXANY 277#if IXANY
171 IDX_decctlq, 278 IDX_decctlq,
172#endif 279#endif
173#if defined(TABDLY) || defined(OXTABS) 280#if TABDLY || OXTABS
174 IDX_tabs, 281 IDX_tabs,
175#endif 282#endif
176#if defined(XCASE) && defined(IUCLC) && defined(OLCUC) 283#if XCASE && IUCLC && OLCUC
177 IDX_lcase, 284 IDX_lcase,
178 IDX_LCASE, 285 IDX_LCASE,
179#endif 286#endif
@@ -196,13 +303,13 @@ static const char mode_name[] =
196 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 ) 303 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 )
197 MI_ENTRY("crt", combination, OMIT, 0, 0 ) 304 MI_ENTRY("crt", combination, OMIT, 0, 0 )
198 MI_ENTRY("dec", combination, OMIT, 0, 0 ) 305 MI_ENTRY("dec", combination, OMIT, 0, 0 )
199#ifdef IXANY 306#if IXANY
200 MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 ) 307 MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 )
201#endif 308#endif
202#if defined(TABDLY) || defined(OXTABS) 309#if TABDLY || OXTABS
203 MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 ) 310 MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 )
204#endif 311#endif
205#if defined(XCASE) && defined(IUCLC) && defined(OLCUC) 312#if XCASE && IUCLC && OLCUC
206 MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 ) 313 MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 )
207 MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 ) 314 MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 )
208#endif 315#endif
@@ -217,7 +324,7 @@ static const char mode_name[] =
217 MI_ENTRY("cstopb", control, REV, CSTOPB, 0 ) 324 MI_ENTRY("cstopb", control, REV, CSTOPB, 0 )
218 MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 ) 325 MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 )
219 MI_ENTRY("clocal", control, REV, CLOCAL, 0 ) 326 MI_ENTRY("clocal", control, REV, CLOCAL, 0 )
220#ifdef CRTSCTS 327#if CRTSCTS
221 MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 ) 328 MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 )
222#endif 329#endif
223 MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 ) 330 MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 )
@@ -232,74 +339,78 @@ static const char mode_name[] =
232 MI_ENTRY("ixon", input, REV, IXON, 0 ) 339 MI_ENTRY("ixon", input, REV, IXON, 0 )
233 MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 ) 340 MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 )
234 MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 ) 341 MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 )
235#ifdef IUCLC 342#if IUCLC
236 MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 ) 343 MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 )
237#endif 344#endif
238#ifdef IXANY 345#if IXANY
239 MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 ) 346 MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 )
240#endif 347#endif
241#ifdef IMAXBEL 348#if IMAXBEL
242 MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 ) 349 MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 )
243#endif 350#endif
244 MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 ) 351 MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 )
245#ifdef OLCUC 352#if OLCUC
246 MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 ) 353 MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 )
247#endif 354#endif
248#ifdef OCRNL 355#if OCRNL
249 MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 ) 356 MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 )
250#endif 357#endif
251#ifdef ONLCR 358#if ONLCR
252 MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 ) 359 MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 )
253#endif 360#endif
254#ifdef ONOCR 361#if ONOCR
255 MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 ) 362 MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 )
256#endif 363#endif
257#ifdef ONLRET 364#if ONLRET
258 MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 ) 365 MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 )
259#endif 366#endif
260#ifdef OFILL 367#if OFILL
261 MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 ) 368 MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 )
262#endif 369#endif
263#ifdef OFDEL 370#if OFDEL
264 MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 ) 371 MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 )
265#endif 372#endif
266#ifdef NLDLY 373#if NLDLY
267 MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY) 374 MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY)
268 MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY) 375 MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY)
269#endif 376#endif
270#ifdef CRDLY 377#if CRDLY
271 MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY) 378 MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY)
272 MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY) 379 MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY)
273 MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY) 380 MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY)
274 MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY) 381 MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY)
275#endif 382#endif
276 383
277#ifdef TABDLY 384#if TABDLY
278 MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY) 385 MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY)
386# if TAB2
279 MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY) 387 MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY)
388# endif
389# if TAB1
280 MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY) 390 MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY)
391# endif
281 MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY) 392 MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY)
282#else 393#else
283# ifdef OXTABS 394# if OXTABS
284 MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 ) 395 MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 )
285# endif 396# endif
286#endif 397#endif
287 398
288#ifdef BSDLY 399#if BSDLY
289 MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY) 400 MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY)
290 MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY) 401 MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY)
291#endif 402#endif
292#ifdef VTDLY 403#if VTDLY
293 MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY) 404 MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY)
294 MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY) 405 MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY)
295#endif 406#endif
296#ifdef FFDLY 407#if FFDLY
297 MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY) 408 MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY)
298 MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY) 409 MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY)
299#endif 410#endif
300 MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 ) 411 MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 )
301 MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 ) 412 MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 )
302#ifdef IEXTEN 413#if IEXTEN
303 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 ) 414 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 )
304#endif 415#endif
305 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 ) 416 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 )
@@ -308,21 +419,21 @@ static const char mode_name[] =
308 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 ) 419 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 )
309 MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 ) 420 MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 )
310 MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 ) 421 MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 )
311#ifdef XCASE 422#if XCASE
312 MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 ) 423 MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 )
313#endif 424#endif
314#ifdef TOSTOP 425#if TOSTOP
315 MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 ) 426 MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 )
316#endif 427#endif
317#ifdef ECHOPRT 428#if ECHOPRT
318 MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 ) 429 MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 )
319 MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 ) 430 MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 )
320#endif 431#endif
321#ifdef ECHOCTL 432#if ECHOCTL
322 MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 ) 433 MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 )
323 MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 ) 434 MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 )
324#endif 435#endif
325#ifdef ECHOKE 436#if ECHOKE
326 MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 ) 437 MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 )
327 MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 ) 438 MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 )
328#endif 439#endif
@@ -346,13 +457,13 @@ static const struct mode_info mode_info[] = {
346 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 ) 457 MI_ENTRY("cbreak", combination, REV | OMIT, 0, 0 )
347 MI_ENTRY("crt", combination, OMIT, 0, 0 ) 458 MI_ENTRY("crt", combination, OMIT, 0, 0 )
348 MI_ENTRY("dec", combination, OMIT, 0, 0 ) 459 MI_ENTRY("dec", combination, OMIT, 0, 0 )
349#ifdef IXANY 460#if IXANY
350 MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 ) 461 MI_ENTRY("decctlq", combination, REV | OMIT, 0, 0 )
351#endif 462#endif
352#if defined(TABDLY) || defined(OXTABS) 463#if TABDLY || OXTABS
353 MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 ) 464 MI_ENTRY("tabs", combination, REV | OMIT, 0, 0 )
354#endif 465#endif
355#if defined(XCASE) && defined(IUCLC) && defined(OLCUC) 466#if XCASE && IUCLC && OLCUC
356 MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 ) 467 MI_ENTRY("lcase", combination, REV | OMIT, 0, 0 )
357 MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 ) 468 MI_ENTRY("LCASE", combination, REV | OMIT, 0, 0 )
358#endif 469#endif
@@ -367,7 +478,7 @@ static const struct mode_info mode_info[] = {
367 MI_ENTRY("cstopb", control, REV, CSTOPB, 0 ) 478 MI_ENTRY("cstopb", control, REV, CSTOPB, 0 )
368 MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 ) 479 MI_ENTRY("cread", control, SANE_SET | REV, CREAD, 0 )
369 MI_ENTRY("clocal", control, REV, CLOCAL, 0 ) 480 MI_ENTRY("clocal", control, REV, CLOCAL, 0 )
370#ifdef CRTSCTS 481#if CRTSCTS
371 MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 ) 482 MI_ENTRY("crtscts", control, REV, CRTSCTS, 0 )
372#endif 483#endif
373 MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 ) 484 MI_ENTRY("ignbrk", input, SANE_UNSET | REV, IGNBRK, 0 )
@@ -382,74 +493,78 @@ static const struct mode_info mode_info[] = {
382 MI_ENTRY("ixon", input, REV, IXON, 0 ) 493 MI_ENTRY("ixon", input, REV, IXON, 0 )
383 MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 ) 494 MI_ENTRY("ixoff", input, SANE_UNSET | REV, IXOFF, 0 )
384 MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 ) 495 MI_ENTRY("tandem", input, REV | OMIT, IXOFF, 0 )
385#ifdef IUCLC 496#if IUCLC
386 MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 ) 497 MI_ENTRY("iuclc", input, SANE_UNSET | REV, IUCLC, 0 )
387#endif 498#endif
388#ifdef IXANY 499#if IXANY
389 MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 ) 500 MI_ENTRY("ixany", input, SANE_UNSET | REV, IXANY, 0 )
390#endif 501#endif
391#ifdef IMAXBEL 502#if IMAXBEL
392 MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 ) 503 MI_ENTRY("imaxbel", input, SANE_SET | REV, IMAXBEL, 0 )
393#endif 504#endif
394 MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 ) 505 MI_ENTRY("opost", output, SANE_SET | REV, OPOST, 0 )
395#ifdef OLCUC 506#if OLCUC
396 MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 ) 507 MI_ENTRY("olcuc", output, SANE_UNSET | REV, OLCUC, 0 )
397#endif 508#endif
398#ifdef OCRNL 509#if OCRNL
399 MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 ) 510 MI_ENTRY("ocrnl", output, SANE_UNSET | REV, OCRNL, 0 )
400#endif 511#endif
401#ifdef ONLCR 512#if ONLCR
402 MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 ) 513 MI_ENTRY("onlcr", output, SANE_SET | REV, ONLCR, 0 )
403#endif 514#endif
404#ifdef ONOCR 515#if ONOCR
405 MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 ) 516 MI_ENTRY("onocr", output, SANE_UNSET | REV, ONOCR, 0 )
406#endif 517#endif
407#ifdef ONLRET 518#if ONLRET
408 MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 ) 519 MI_ENTRY("onlret", output, SANE_UNSET | REV, ONLRET, 0 )
409#endif 520#endif
410#ifdef OFILL 521#if OFILL
411 MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 ) 522 MI_ENTRY("ofill", output, SANE_UNSET | REV, OFILL, 0 )
412#endif 523#endif
413#ifdef OFDEL 524#if OFDEL
414 MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 ) 525 MI_ENTRY("ofdel", output, SANE_UNSET | REV, OFDEL, 0 )
415#endif 526#endif
416#ifdef NLDLY 527#if NLDLY
417 MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY) 528 MI_ENTRY("nl1", output, SANE_UNSET, NL1, NLDLY)
418 MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY) 529 MI_ENTRY("nl0", output, SANE_SET, NL0, NLDLY)
419#endif 530#endif
420#ifdef CRDLY 531#if CRDLY
421 MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY) 532 MI_ENTRY("cr3", output, SANE_UNSET, CR3, CRDLY)
422 MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY) 533 MI_ENTRY("cr2", output, SANE_UNSET, CR2, CRDLY)
423 MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY) 534 MI_ENTRY("cr1", output, SANE_UNSET, CR1, CRDLY)
424 MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY) 535 MI_ENTRY("cr0", output, SANE_SET, CR0, CRDLY)
425#endif 536#endif
426 537
427#ifdef TABDLY 538#if TABDLY
428 MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY) 539 MI_ENTRY("tab3", output, SANE_UNSET, TAB3, TABDLY)
540# if TAB2
429 MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY) 541 MI_ENTRY("tab2", output, SANE_UNSET, TAB2, TABDLY)
542# endif
543# if TAB1
430 MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY) 544 MI_ENTRY("tab1", output, SANE_UNSET, TAB1, TABDLY)
545# endif
431 MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY) 546 MI_ENTRY("tab0", output, SANE_SET, TAB0, TABDLY)
432#else 547#else
433# ifdef OXTABS 548# if OXTABS
434 MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 ) 549 MI_ENTRY("tab3", output, SANE_UNSET, OXTABS, 0 )
435# endif 550# endif
436#endif 551#endif
437 552
438#ifdef BSDLY 553#if BSDLY
439 MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY) 554 MI_ENTRY("bs1", output, SANE_UNSET, BS1, BSDLY)
440 MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY) 555 MI_ENTRY("bs0", output, SANE_SET, BS0, BSDLY)
441#endif 556#endif
442#ifdef VTDLY 557#if VTDLY
443 MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY) 558 MI_ENTRY("vt1", output, SANE_UNSET, VT1, VTDLY)
444 MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY) 559 MI_ENTRY("vt0", output, SANE_SET, VT0, VTDLY)
445#endif 560#endif
446#ifdef FFDLY 561#if FFDLY
447 MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY) 562 MI_ENTRY("ff1", output, SANE_UNSET, FF1, FFDLY)
448 MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY) 563 MI_ENTRY("ff0", output, SANE_SET, FF0, FFDLY)
449#endif 564#endif
450 MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 ) 565 MI_ENTRY("isig", local, SANE_SET | REV, ISIG, 0 )
451 MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 ) 566 MI_ENTRY("icanon", local, SANE_SET | REV, ICANON, 0 )
452#ifdef IEXTEN 567#if IEXTEN
453 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 ) 568 MI_ENTRY("iexten", local, SANE_SET | REV, IEXTEN, 0 )
454#endif 569#endif
455 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 ) 570 MI_ENTRY("echo", local, SANE_SET | REV, ECHO, 0 )
@@ -458,21 +573,21 @@ static const struct mode_info mode_info[] = {
458 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 ) 573 MI_ENTRY("echok", local, SANE_SET | REV, ECHOK, 0 )
459 MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 ) 574 MI_ENTRY("echonl", local, SANE_UNSET | REV, ECHONL, 0 )
460 MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 ) 575 MI_ENTRY("noflsh", local, SANE_UNSET | REV, NOFLSH, 0 )
461#ifdef XCASE 576#if XCASE
462 MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 ) 577 MI_ENTRY("xcase", local, SANE_UNSET | REV, XCASE, 0 )
463#endif 578#endif
464#ifdef TOSTOP 579#if TOSTOP
465 MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 ) 580 MI_ENTRY("tostop", local, SANE_UNSET | REV, TOSTOP, 0 )
466#endif 581#endif
467#ifdef ECHOPRT 582#if ECHOPRT
468 MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 ) 583 MI_ENTRY("echoprt", local, SANE_UNSET | REV, ECHOPRT, 0 )
469 MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 ) 584 MI_ENTRY("prterase", local, REV | OMIT, ECHOPRT, 0 )
470#endif 585#endif
471#ifdef ECHOCTL 586#if ECHOCTL
472 MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 ) 587 MI_ENTRY("echoctl", local, SANE_SET | REV, ECHOCTL, 0 )
473 MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 ) 588 MI_ENTRY("ctlecho", local, REV | OMIT, ECHOCTL, 0 )
474#endif 589#endif
475#ifdef ECHOKE 590#if ECHOKE
476 MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 ) 591 MI_ENTRY("echoke", local, SANE_SET | REV, ECHOKE, 0 )
477 MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 ) 592 MI_ENTRY("crtkill", local, REV | OMIT, ECHOKE, 0 )
478#endif 593#endif
@@ -497,31 +612,31 @@ enum {
497 CIDX_kill, 612 CIDX_kill,
498 CIDX_eof, 613 CIDX_eof,
499 CIDX_eol, 614 CIDX_eol,
500#ifdef VEOL2 615#if VEOL2
501 CIDX_eol2, 616 CIDX_eol2,
502#endif 617#endif
503#ifdef VSWTCH 618#if VSWTCH
504 CIDX_swtch, 619 CIDX_swtch,
505#endif 620#endif
506 CIDX_start, 621 CIDX_start,
507 CIDX_stop, 622 CIDX_stop,
508 CIDX_susp, 623 CIDX_susp,
509#ifdef VDSUSP 624#if VDSUSP
510 CIDX_dsusp, 625 CIDX_dsusp,
511#endif 626#endif
512#ifdef VREPRINT 627#if VREPRINT
513 CIDX_rprnt, 628 CIDX_rprnt,
514#endif 629#endif
515#ifdef VWERASE 630#if VWERASE
516 CIDX_werase, 631 CIDX_werase,
517#endif 632#endif
518#ifdef VLNEXT 633#if VLNEXT
519 CIDX_lnext, 634 CIDX_lnext,
520#endif 635#endif
521#ifdef VFLUSHO 636#if VFLUSHO
522 CIDX_flush, 637 CIDX_flush,
523#endif 638#endif
524#ifdef VSTATUS 639#if VSTATUS
525 CIDX_status, 640 CIDX_status,
526#endif 641#endif
527 CIDX_min, 642 CIDX_min,
@@ -538,31 +653,31 @@ static const char control_name[] =
538 CI_ENTRY("kill", CKILL, VKILL ) 653 CI_ENTRY("kill", CKILL, VKILL )
539 CI_ENTRY("eof", CEOF, VEOF ) 654 CI_ENTRY("eof", CEOF, VEOF )
540 CI_ENTRY("eol", CEOL, VEOL ) 655 CI_ENTRY("eol", CEOL, VEOL )
541#ifdef VEOL2 656#if VEOL2
542 CI_ENTRY("eol2", CEOL2, VEOL2 ) 657 CI_ENTRY("eol2", CEOL2, VEOL2 )
543#endif 658#endif
544#ifdef VSWTCH 659#if VSWTCH
545 CI_ENTRY("swtch", CSWTCH, VSWTCH ) 660 CI_ENTRY("swtch", CSWTCH, VSWTCH )
546#endif 661#endif
547 CI_ENTRY("start", CSTART, VSTART ) 662 CI_ENTRY("start", CSTART, VSTART )
548 CI_ENTRY("stop", CSTOP, VSTOP ) 663 CI_ENTRY("stop", CSTOP, VSTOP )
549 CI_ENTRY("susp", CSUSP, VSUSP ) 664 CI_ENTRY("susp", CSUSP, VSUSP )
550#ifdef VDSUSP 665#if VDSUSP
551 CI_ENTRY("dsusp", CDSUSP, VDSUSP ) 666 CI_ENTRY("dsusp", CDSUSP, VDSUSP )
552#endif 667#endif
553#ifdef VREPRINT 668#if VREPRINT
554 CI_ENTRY("rprnt", CRPRNT, VREPRINT) 669 CI_ENTRY("rprnt", CRPRNT, VREPRINT)
555#endif 670#endif
556#ifdef VWERASE 671#if VWERASE
557 CI_ENTRY("werase", CWERASE, VWERASE ) 672 CI_ENTRY("werase", CWERASE, VWERASE )
558#endif 673#endif
559#ifdef VLNEXT 674#if VLNEXT
560 CI_ENTRY("lnext", CLNEXT, VLNEXT ) 675 CI_ENTRY("lnext", CLNEXT, VLNEXT )
561#endif 676#endif
562#ifdef VFLUSHO 677#if VFLUSHO
563 CI_ENTRY("flush", CFLUSHO, VFLUSHO ) 678 CI_ENTRY("flush", CFLUSHO, VFLUSHO )
564#endif 679#endif
565#ifdef VSTATUS 680#if VSTATUS
566 CI_ENTRY("status", CSTATUS, VSTATUS ) 681 CI_ENTRY("status", CSTATUS, VSTATUS )
567#endif 682#endif
568 /* These must be last because of the display routines */ 683 /* These must be last because of the display routines */
@@ -581,31 +696,31 @@ static const struct control_info control_info[] = {
581 CI_ENTRY("kill", CKILL, VKILL ) 696 CI_ENTRY("kill", CKILL, VKILL )
582 CI_ENTRY("eof", CEOF, VEOF ) 697 CI_ENTRY("eof", CEOF, VEOF )
583 CI_ENTRY("eol", CEOL, VEOL ) 698 CI_ENTRY("eol", CEOL, VEOL )
584#ifdef VEOL2 699#if VEOL2
585 CI_ENTRY("eol2", CEOL2, VEOL2 ) 700 CI_ENTRY("eol2", CEOL2, VEOL2 )
586#endif 701#endif
587#ifdef VSWTCH 702#if VSWTCH
588 CI_ENTRY("swtch", CSWTCH, VSWTCH ) 703 CI_ENTRY("swtch", CSWTCH, VSWTCH )
589#endif 704#endif
590 CI_ENTRY("start", CSTART, VSTART ) 705 CI_ENTRY("start", CSTART, VSTART )
591 CI_ENTRY("stop", CSTOP, VSTOP ) 706 CI_ENTRY("stop", CSTOP, VSTOP )
592 CI_ENTRY("susp", CSUSP, VSUSP ) 707 CI_ENTRY("susp", CSUSP, VSUSP )
593#ifdef VDSUSP 708#if VDSUSP
594 CI_ENTRY("dsusp", CDSUSP, VDSUSP ) 709 CI_ENTRY("dsusp", CDSUSP, VDSUSP )
595#endif 710#endif
596#ifdef VREPRINT 711#if VREPRINT
597 CI_ENTRY("rprnt", CRPRNT, VREPRINT) 712 CI_ENTRY("rprnt", CRPRNT, VREPRINT)
598#endif 713#endif
599#ifdef VWERASE 714#if VWERASE
600 CI_ENTRY("werase", CWERASE, VWERASE ) 715 CI_ENTRY("werase", CWERASE, VWERASE )
601#endif 716#endif
602#ifdef VLNEXT 717#if VLNEXT
603 CI_ENTRY("lnext", CLNEXT, VLNEXT ) 718 CI_ENTRY("lnext", CLNEXT, VLNEXT )
604#endif 719#endif
605#ifdef VFLUSHO 720#if VFLUSHO
606 CI_ENTRY("flush", CFLUSHO, VFLUSHO ) 721 CI_ENTRY("flush", CFLUSHO, VFLUSHO )
607#endif 722#endif
608#ifdef VSTATUS 723#if VSTATUS
609 CI_ENTRY("status", CSTATUS, VSTATUS ) 724 CI_ENTRY("status", CSTATUS, VSTATUS )
610#endif 725#endif
611 /* These must be last because of the display routines */ 726 /* These must be last because of the display routines */
@@ -740,6 +855,7 @@ static void newline(void)
740 wrapf("\n"); 855 wrapf("\n");
741} 856}
742 857
858#ifdef TIOCGWINSZ
743static void set_window_size(int rows, int cols) 859static void set_window_size(int rows, int cols)
744{ 860{
745 struct winsize win = { 0, 0, 0, 0 }; 861 struct winsize win = { 0, 0, 0, 0 };
@@ -760,6 +876,7 @@ static void set_window_size(int rows, int cols)
760bail: 876bail:
761 perror_on_device("%s"); 877 perror_on_device("%s");
762} 878}
879#endif
763 880
764static void display_window_size(int fancy) 881static void display_window_size(int fancy)
765{ 882{
@@ -973,41 +1090,6 @@ static void sane_mode(struct termios *mode)
973 } 1090 }
974} 1091}
975 1092
976/* Save set_mode from #ifdef forest plague */
977#ifndef ONLCR
978#define ONLCR 0
979#endif
980#ifndef OCRNL
981#define OCRNL 0
982#endif
983#ifndef ONLRET
984#define ONLRET 0
985#endif
986#ifndef XCASE
987#define XCASE 0
988#endif
989#ifndef IXANY
990#define IXANY 0
991#endif
992#ifndef TABDLY
993#define TABDLY 0
994#endif
995#ifndef OXTABS
996#define OXTABS 0
997#endif
998#ifndef IUCLC
999#define IUCLC 0
1000#endif
1001#ifndef OLCUC
1002#define OLCUC 0
1003#endif
1004#ifndef ECHOCTL
1005#define ECHOCTL 0
1006#endif
1007#ifndef ECHOKE
1008#define ECHOKE 0
1009#endif
1010
1011static void set_mode(const struct mode_info *info, int reversed, 1093static void set_mode(const struct mode_info *info, int reversed,
1012 struct termios *mode) 1094 struct termios *mode)
1013{ 1095{
@@ -1093,27 +1175,32 @@ static void set_mode(const struct mode_info *info, int reversed,
1093 mode->c_cc[VTIME] = 0; 1175 mode->c_cc[VTIME] = 0;
1094 } 1176 }
1095 } 1177 }
1096 else if (IXANY && info == &mode_info[IDX_decctlq]) { 1178#if IXANY
1179 else if (info == &mode_info[IDX_decctlq]) {
1097 if (reversed) 1180 if (reversed)
1098 mode->c_iflag |= IXANY; 1181 mode->c_iflag |= IXANY;
1099 else 1182 else
1100 mode->c_iflag &= ~IXANY; 1183 mode->c_iflag &= ~IXANY;
1101 } 1184 }
1102 else if (TABDLY && info == &mode_info[IDX_tabs]) { 1185#endif
1186#if TABDLY
1187 else if (info == &mode_info[IDX_tabs]) {
1103 if (reversed) 1188 if (reversed)
1104 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3; 1189 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB3;
1105 else 1190 else
1106 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0; 1191 mode->c_oflag = (mode->c_oflag & ~TABDLY) | TAB0;
1107 } 1192 }
1108 else if (OXTABS && info == &mode_info[IDX_tabs]) { 1193#endif
1194#if OXTABS
1195 else if (info == &mode_info[IDX_tabs]) {
1109 if (reversed) 1196 if (reversed)
1110 mode->c_oflag |= OXTABS; 1197 mode->c_oflag |= OXTABS;
1111 else 1198 else
1112 mode->c_oflag &= ~OXTABS; 1199 mode->c_oflag &= ~OXTABS;
1113 } else 1200 }
1114 if (XCASE && IUCLC && OLCUC 1201#endif
1115 && (info == &mode_info[IDX_lcase] || info == &mode_info[IDX_LCASE]) 1202#if XCASE && IUCLC && OLCUC
1116 ) { 1203 else if (info==&mode_info[IDX_lcase] || info==&mode_info[IDX_LCASE]) {
1117 if (reversed) { 1204 if (reversed) {
1118 mode->c_lflag &= ~XCASE; 1205 mode->c_lflag &= ~XCASE;
1119 mode->c_iflag &= ~IUCLC; 1206 mode->c_iflag &= ~IUCLC;
@@ -1123,7 +1210,9 @@ static void set_mode(const struct mode_info *info, int reversed,
1123 mode->c_iflag |= IUCLC; 1210 mode->c_iflag |= IUCLC;
1124 mode->c_oflag |= OLCUC; 1211 mode->c_oflag |= OLCUC;
1125 } 1212 }
1126 } else if (info == &mode_info[IDX_crt]) { 1213 }
1214#endif
1215 else if (info == &mode_info[IDX_crt]) {
1127 mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE; 1216 mode->c_lflag |= ECHOE | ECHOCTL | ECHOKE;
1128 } else if (info == &mode_info[IDX_dec]) { 1217 } else if (info == &mode_info[IDX_dec]) {
1129 mode->c_cc[VINTR] = 3; /* ^C */ 1218 mode->c_cc[VINTR] = 3; /* ^C */
@@ -1419,7 +1508,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv)
1419 perror_on_device_and_die("%s"); 1508 perror_on_device_and_die("%s");
1420 1509
1421 if (memcmp(&mode, &new_mode, sizeof(mode)) != 0) { 1510 if (memcmp(&mode, &new_mode, sizeof(mode)) != 0) {
1422#ifdef CIBAUD 1511#if CIBAUD
1423 /* SunOS 4.1.3 (at least) has the problem that after this sequence, 1512 /* SunOS 4.1.3 (at least) has the problem that after this sequence,
1424 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2); 1513 tcgetattr (&m1); tcsetattr (&m1); tcgetattr (&m2);
1425 sometimes (m1 != m2). The only difference is in the four bits 1514 sometimes (m1 != m2). The only difference is in the four bits
diff --git a/debianutils/Config.src b/debianutils/Config.src
index 838d8f00c..cbc09b5ce 100644
--- a/debianutils/Config.src
+++ b/debianutils/Config.src
@@ -83,4 +83,3 @@ config WHICH
83 print out their pathnames. 83 print out their pathnames.
84 84
85endmenu 85endmenu
86
diff --git a/debianutils/mktemp.c b/debianutils/mktemp.c
index 2c4e19670..7ce9f1096 100644
--- a/debianutils/mktemp.c
+++ b/debianutils/mktemp.c
@@ -50,7 +50,7 @@ int mktemp_main(int argc UNUSED_PARAM, char **argv)
50 opts = getopt32(argv, "dqtp:", &path); 50 opts = getopt32(argv, "dqtp:", &path);
51 51
52 chp = argv[optind] ? argv[optind] : xstrdup("tmp.XXXXXX"); 52 chp = argv[optind] ? argv[optind] : xstrdup("tmp.XXXXXX");
53 if (chp[0] != '/' || (opts & 8)) 53 if (!strchr(chp, '/') || (opts & 8))
54 chp = concat_path_file(path, chp); 54 chp = concat_path_file(path, chp);
55 55
56 if (opts & 1) { /* -d */ 56 if (opts & 1) { /* -d */
diff --git a/docs/busybox_footer.pod b/docs/busybox_footer.pod
index 5ed937991..47eabaeeb 100644
--- a/docs/busybox_footer.pod
+++ b/docs/busybox_footer.pod
@@ -253,4 +253,3 @@ Tito Ragusa <farmatito@tiscali.it>
253 devfsd and size optimizations in strings, openvt and deallocvt. 253 devfsd and size optimizations in strings, openvt and deallocvt.
254 254
255=cut 255=cut
256
diff --git a/docs/busybox_header.pod b/docs/busybox_header.pod
index 2a99636b1..85a173e82 100644
--- a/docs/busybox_header.pod
+++ b/docs/busybox_header.pod
@@ -80,4 +80,3 @@ been enabled, more detailed usage information will also be available.
80=head1 COMMANDS 80=head1 COMMANDS
81 81
82Currently available applets include: 82Currently available applets include:
83
diff --git a/docs/cgi/cl.html b/docs/cgi/cl.html
index 5779d623e..4f8faae9f 100644
--- a/docs/cgi/cl.html
+++ b/docs/cgi/cl.html
@@ -43,4 +43,4 @@ CGI - Common Gateway Interface
43</p><address><a href="http://hoohoo.ncsa.uiuc.edu/cgi/mailtocgi.html">cgi@ncsa.uiuc.edu</a></address> 43</p><address><a href="http://hoohoo.ncsa.uiuc.edu/cgi/mailtocgi.html">cgi@ncsa.uiuc.edu</a></address>
44 44
45 45
46</body></html> \ No newline at end of file 46</body></html>
diff --git a/docs/cgi/env.html b/docs/cgi/env.html
index 924026b3e..b83c750bf 100644
--- a/docs/cgi/env.html
+++ b/docs/cgi/env.html
@@ -146,4 +146,4 @@ interface specification</a> <p>
146CGI - Common Gateway Interface 146CGI - Common Gateway Interface
147</p><address><a href="http://hoohoo.ncsa.uiuc.edu/cgi/mailtocgi.html">cgi@ncsa.uiuc.edu</a></address> 147</p><address><a href="http://hoohoo.ncsa.uiuc.edu/cgi/mailtocgi.html">cgi@ncsa.uiuc.edu</a></address>
148 148
149</body></html> \ No newline at end of file 149</body></html>
diff --git a/docs/cgi/in.html b/docs/cgi/in.html
index 679306aaa..7ee5fe601 100644
--- a/docs/cgi/in.html
+++ b/docs/cgi/in.html
@@ -30,4 +30,4 @@ interface specification</a> <p>
30CGI - Common Gateway Interface 30CGI - Common Gateway Interface
31</p><address><a href="http://hoohoo.ncsa.uiuc.edu/cgi/mailtocgi.html">cgi@ncsa.uiuc.edu</a></address> 31</p><address><a href="http://hoohoo.ncsa.uiuc.edu/cgi/mailtocgi.html">cgi@ncsa.uiuc.edu</a></address>
32 32
33</body></html> \ No newline at end of file 33</body></html>
diff --git a/docs/cgi/interface.html b/docs/cgi/interface.html
index ea73ce3a2..0be016b4c 100644
--- a/docs/cgi/interface.html
+++ b/docs/cgi/interface.html
@@ -26,4 +26,4 @@ the following is a hotlink to graphic detail.</p><p>
26 26
27CGI - Common Gateway Interface 27CGI - Common Gateway Interface
28</p><address><a href="http://hoohoo.ncsa.uiuc.edu/cgi/mailtocgi.html">cgi@ncsa.uiuc.edu</a></address> 28</p><address><a href="http://hoohoo.ncsa.uiuc.edu/cgi/mailtocgi.html">cgi@ncsa.uiuc.edu</a></address>
29</body></html> \ No newline at end of file 29</body></html>
diff --git a/docs/cgi/out.html b/docs/cgi/out.html
index 2203ee5a0..5266985b5 100644
--- a/docs/cgi/out.html
+++ b/docs/cgi/out.html
@@ -123,4 +123,4 @@ interface specification</a> <p>
123 123
124CGI - Common Gateway Interface 124CGI - Common Gateway Interface
125</p><address><a href="http://hoohoo.ncsa.uiuc.edu/cgi/mailtocgi.html">cgi@ncsa.uiuc.edu</a></address> 125</p><address><a href="http://hoohoo.ncsa.uiuc.edu/cgi/mailtocgi.html">cgi@ncsa.uiuc.edu</a></address>
126</body></html> \ No newline at end of file 126</body></html>
diff --git a/docs/contributing.txt b/docs/contributing.txt
index d06e4a2da..39aaef1b5 100644
--- a/docs/contributing.txt
+++ b/docs/contributing.txt
@@ -426,5 +426,3 @@ you're having difficulty following some of the steps outlined in this
426document don't worry, the folks on the Busybox mailing list are a fairly 426document don't worry, the folks on the Busybox mailing list are a fairly
427good-natured bunch and will work with you to help get your patches into shape 427good-natured bunch and will work with you to help get your patches into shape
428or help you make contributions. 428or help you make contributions.
429
430
diff --git a/docs/ifupdown_design.txt b/docs/ifupdown_design.txt
index 8008e4507..8ab4e51ad 100644
--- a/docs/ifupdown_design.txt
+++ b/docs/ifupdown_design.txt
@@ -10,27 +10,27 @@ for that.
10We are doomed to have problems with ifup/ifdown. Just look as this code: 10We are doomed to have problems with ifup/ifdown. Just look as this code:
11 11
12static const struct dhcp_client_t ext_dhcp_clients[] = { 12static const struct dhcp_client_t ext_dhcp_clients[] = {
13 { "dhcpcd", "<up cmd>", "<down cmd>" }, 13 { "dhcpcd", "<up cmd>", "<down cmd>" },
14 { "dhclient", ........ }, 14 { "dhclient", ........ },
15 { "pump", ........ }, 15 { "pump", ........ },
16 { "udhcpc", ........ }, 16 { "udhcpc", ........ },
17}; 17};
18 18
19static int dhcp_down(struct interface_defn_t *ifd, execfn *exec) 19static int dhcp_down(struct interface_defn_t *ifd, execfn *exec)
20{ 20{
21#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP 21#if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP
22 int i ; 22 int i ;
23 for (i = 0; i < ARRAY_SIZE(ext_dhcp_clients); i++) { 23 for (i = 0; i < ARRAY_SIZE(ext_dhcp_clients); i++) {
24 if (exists_execable(ext_dhcp_clients[i].name)) 24 if (exists_execable(ext_dhcp_clients[i].name))
25 return execute(ext_dhcp_clients[i].stopcmd, ifd, exec); 25 return execute(ext_dhcp_clients[i].stopcmd, ifd, exec);
26 } 26 }
27 bb_error_msg("no dhcp clients found, using static interface shutdown"); 27 bb_error_msg("no dhcp clients found, using static interface shutdown");
28 return static_down(ifd, exec); 28 return static_down(ifd, exec);
29#elif ENABLE_UDHCPC 29#elif ENABLE_UDHCPC
30 return execute("kill " 30 return execute("kill "
31 "`cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", ifd, exec); 31 "`cat /var/run/udhcpc.%iface%.pid` 2>/dev/null", ifd, exec);
32#else 32#else
33 return 0; /* no dhcp support */ 33 return 0; /* no dhcp support */
34#endif 34#endif
35} 35}
36 36
diff --git a/docs/posix_conformance.txt b/docs/posix_conformance.txt
index d9fa116b8..5b616d701 100644
--- a/docs/posix_conformance.txt
+++ b/docs/posix_conformance.txt
@@ -739,4 +739,3 @@ xargs Busybox specific options:
739 739
740zcat POSIX options: None 740zcat POSIX options: None
741zcat Busybox specific options: None 741zcat Busybox specific options: None
742
diff --git a/e2fsprogs/Config.src b/e2fsprogs/Config.src
index f362c6b0a..6043e9b57 100644
--- a/e2fsprogs/Config.src
+++ b/e2fsprogs/Config.src
@@ -33,6 +33,7 @@ config FSCK
33config LSATTR 33config LSATTR
34 bool "lsattr" 34 bool "lsattr"
35 default y 35 default y
36 depends on PLATFORM_LINUX
36 help 37 help
37 lsattr lists the file attributes on a second extended file system. 38 lsattr lists the file attributes on a second extended file system.
38 39
@@ -45,7 +46,7 @@ config LSATTR
45 46
46config TUNE2FS 47config TUNE2FS
47 bool "tune2fs" 48 bool "tune2fs"
48 default y 49 default n # off: it is too limited compared to upstream version
49 help 50 help
50 tune2fs allows the system administrator to adjust various tunable 51 tune2fs allows the system administrator to adjust various tunable
51 filesystem parameters on Linux ext2/ext3 filesystems. 52 filesystem parameters on Linux ext2/ext3 filesystems.
diff --git a/e2fsprogs/old_e2fsprogs/e2fsck.c b/e2fsprogs/old_e2fsprogs/e2fsck.c
index 4c4c78d00..f58fe9286 100644
--- a/e2fsprogs/old_e2fsprogs/e2fsck.c
+++ b/e2fsprogs/old_e2fsprogs/e2fsck.c
@@ -517,7 +517,6 @@ static void dict_insert(dict_t *dict, dnode_t *node, const void *key)
517 } 517 }
518 518
519 dict_root(dict)->color = dnode_black; 519 dict_root(dict)->color = dnode_black;
520
521} 520}
522 521
523/* 522/*
@@ -801,7 +800,6 @@ static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks)
801 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks 800 dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks
802 * sizeof (struct dx_dirblock_info), 801 * sizeof (struct dx_dirblock_info),
803 "dx_block info array"); 802 "dx_block info array");
804
805} 803}
806 804
807/* 805/*
@@ -1724,7 +1722,6 @@ errout:
1724 ext2fs_free_mem(&j_inode); 1722 ext2fs_free_mem(&j_inode);
1725 ext2fs_free_mem(&journal); 1723 ext2fs_free_mem(&journal);
1726 return retval; 1724 return retval;
1727
1728} 1725}
1729 1726
1730static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx, 1727static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx,
@@ -3375,7 +3372,6 @@ static void e2fsck_pass1(e2fsck_t ctx)
3375 e2fsck_write_inode(ctx, ino, inode, 3372 e2fsck_write_inode(ctx, ino, inode,
3376 "pass1"); 3373 "pass1");
3377 } 3374 }
3378
3379 } 3375 }
3380 /* 3376 /*
3381 * If dtime is set, offer to clear it. mke2fs 3377 * If dtime is set, offer to clear it. mke2fs
@@ -3678,7 +3674,6 @@ endit:
3678 3674
3679 ext2fs_free_mem(&block_buf); 3675 ext2fs_free_mem(&block_buf);
3680 ext2fs_free_mem(&inode); 3676 ext2fs_free_mem(&inode);
3681
3682} 3677}
3683 3678
3684/* 3679/*
@@ -4451,8 +4446,7 @@ static void mark_table_blocks(e2fsck_t ctx)
4451 ctx->invalid_bitmaps++; 4446 ctx->invalid_bitmaps++;
4452 } 4447 }
4453 } else { 4448 } else {
4454 ext2fs_mark_block_bitmap(ctx->block_found_map, 4449 ext2fs_mark_block_bitmap(ctx->block_found_map, b);
4455 b);
4456 } 4450 }
4457 } 4451 }
4458 } 4452 }
@@ -4469,10 +4463,9 @@ static void mark_table_blocks(e2fsck_t ctx)
4469 ctx->invalid_bitmaps++; 4463 ctx->invalid_bitmaps++;
4470 } 4464 }
4471 } else { 4465 } else {
4472 ext2fs_mark_block_bitmap(ctx->block_found_map, 4466 ext2fs_mark_block_bitmap(ctx->block_found_map,
4473 fs->group_desc[i].bg_block_bitmap); 4467 fs->group_desc[i].bg_block_bitmap);
4474 } 4468 }
4475
4476 } 4469 }
4477 /* 4470 /*
4478 * Mark block used for the inode bitmap 4471 * Mark block used for the inode bitmap
@@ -4486,8 +4479,8 @@ static void mark_table_blocks(e2fsck_t ctx)
4486 ctx->invalid_bitmaps++; 4479 ctx->invalid_bitmaps++;
4487 } 4480 }
4488 } else { 4481 } else {
4489 ext2fs_mark_block_bitmap(ctx->block_found_map, 4482 ext2fs_mark_block_bitmap(ctx->block_found_map,
4490 fs->group_desc[i].bg_inode_bitmap); 4483 fs->group_desc[i].bg_inode_bitmap);
4491 } 4484 }
4492 } 4485 }
4493 block += fs->super->s_blocks_per_group; 4486 block += fs->super->s_blocks_per_group;
@@ -5588,7 +5581,6 @@ static void e2fsck_pass2(e2fsck_t ctx)
5588 ext2fs_mark_super_dirty(fs); 5581 ext2fs_mark_super_dirty(fs);
5589 } 5582 }
5590 } 5583 }
5591
5592} 5584}
5593 5585
5594#define MAX_DEPTH 32000 5586#define MAX_DEPTH 32000
@@ -9748,7 +9740,6 @@ int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx)
9748 if (print_answer) 9740 if (print_answer)
9749 printf("%s.\n", answer ? 9741 printf("%s.\n", answer ?
9750 _(preen_msg[(int) ptr->prompt]) : _("IGNORED")); 9742 _(preen_msg[(int) ptr->prompt]) : _("IGNORED"));
9751
9752 } 9743 }
9753 9744
9754 if ((ptr->prompt == PROMPT_ABORT) && answer) 9745 if ((ptr->prompt == PROMPT_ABORT) && answer)
@@ -11324,7 +11315,7 @@ static int release_inode_block(ext2_filsys fs, blk_t *block_nr,
11324 if ((blk < fs->super->s_first_data_block) || 11315 if ((blk < fs->super->s_first_data_block) ||
11325 (blk >= fs->super->s_blocks_count)) { 11316 (blk >= fs->super->s_blocks_count)) {
11326 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx); 11317 fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx);
11327 return_abort: 11318 return_abort:
11328 pb->abort = 1; 11319 pb->abort = 1;
11329 return BLOCK_ABORT; 11320 return BLOCK_ABORT;
11330 } 11321 }
@@ -11537,7 +11528,7 @@ static int release_orphan_inodes(e2fsck_t ctx)
11537 } 11528 }
11538 ext2fs_free_mem(&block_buf); 11529 ext2fs_free_mem(&block_buf);
11539 return 0; 11530 return 0;
11540return_abort: 11531 return_abort:
11541 ext2fs_free_mem(&block_buf); 11532 ext2fs_free_mem(&block_buf);
11542 return 1; 11533 return 1;
11543} 11534}
@@ -11618,7 +11609,7 @@ static void check_resize_inode(e2fsck_t ctx)
11618 !(inode.i_mode & LINUX_S_IFREG) || 11609 !(inode.i_mode & LINUX_S_IFREG) ||
11619 (blk < fs->super->s_first_data_block || 11610 (blk < fs->super->s_first_data_block ||
11620 blk >= fs->super->s_blocks_count)) { 11611 blk >= fs->super->s_blocks_count)) {
11621 resize_inode_invalid: 11612 resize_inode_invalid:
11622 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) { 11613 if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) {
11623 memset(&inode, 0, sizeof(inode)); 11614 memset(&inode, 0, sizeof(inode));
11624 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode, 11615 e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode,
@@ -11660,10 +11651,9 @@ static void check_resize_inode(e2fsck_t ctx)
11660 } 11651 }
11661 } 11652 }
11662 11653
11663cleanup: 11654 cleanup:
11664 ext2fs_free_mem(&dind_buf); 11655 ext2fs_free_mem(&dind_buf);
11665 11656}
11666 }
11667 11657
11668static void check_super_block(e2fsck_t ctx) 11658static void check_super_block(e2fsck_t ctx)
11669{ 11659{
@@ -11842,7 +11832,6 @@ static void check_super_block(e2fsck_t ctx)
11842 (gd->bg_free_inodes_count > sb->s_inodes_per_group) || 11832 (gd->bg_free_inodes_count > sb->s_inodes_per_group) ||
11843 (gd->bg_used_dirs_count > sb->s_inodes_per_group)) 11833 (gd->bg_used_dirs_count > sb->s_inodes_per_group))
11844 ext2fs_unmark_valid(fs); 11834 ext2fs_unmark_valid(fs);
11845
11846 } 11835 }
11847 11836
11848 /* 11837 /*
@@ -11902,7 +11891,6 @@ static void check_super_block(e2fsck_t ctx)
11902 fs->super->s_feature_incompat &= 11891 fs->super->s_feature_incompat &=
11903 ~EXT2_FEATURE_INCOMPAT_FILETYPE; 11892 ~EXT2_FEATURE_INCOMPAT_FILETYPE;
11904 ext2fs_mark_super_dirty(fs); 11893 ext2fs_mark_super_dirty(fs);
11905
11906 } 11894 }
11907 } 11895 }
11908 11896
diff --git a/e2fsprogs/old_e2fsprogs/e2fsck.h b/e2fsprogs/old_e2fsprogs/e2fsck.h
index 73d398ff4..fdfa2d84a 100644
--- a/e2fsprogs/old_e2fsprogs/e2fsck.h
+++ b/e2fsprogs/old_e2fsprogs/e2fsck.h
@@ -636,5 +636,3 @@ static inline int tid_geq(tid_t x, tid_t y)
636 int difference = (x - y); 636 int difference = (x - y);
637 return (difference >= 0); 637 return (difference >= 0);
638} 638}
639
640
diff --git a/e2fsprogs/old_e2fsprogs/e2p/ostype.c b/e2fsprogs/old_e2fsprogs/e2p/ostype.c
index 1abe2ba91..6a2f178f3 100644
--- a/e2fsprogs/old_e2fsprogs/e2p/ostype.c
+++ b/e2fsprogs/old_e2fsprogs/e2p/ostype.c
@@ -70,5 +70,3 @@ int main(int argc, char **argv)
70 exit(0); 70 exit(0);
71} 71}
72#endif 72#endif
73
74
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/alloc.c b/e2fsprogs/old_e2fsprogs/ext2fs/alloc.c
index 5021d72c9..cbb63e15a 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/alloc.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/alloc.c
@@ -171,4 +171,3 @@ errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
171 } while (b != finish); 171 } while (b != finish);
172 return EXT2_ET_BLOCK_ALLOC_FAIL; 172 return EXT2_ET_BLOCK_ALLOC_FAIL;
173} 173}
174
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/alloc_tables.c b/e2fsprogs/old_e2fsprogs/ext2fs/alloc_tables.c
index b2d786ed8..7c60e2bf5 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/alloc_tables.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/alloc_tables.c
@@ -97,12 +97,9 @@ errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
97 fs->group_desc[group].bg_inode_table = new_blk; 97 fs->group_desc[group].bg_inode_table = new_blk;
98 } 98 }
99 99
100
101 return 0; 100 return 0;
102} 101}
103 102
104
105
106errcode_t ext2fs_allocate_tables(ext2_filsys fs) 103errcode_t ext2fs_allocate_tables(ext2_filsys fs)
107{ 104{
108 errcode_t retval; 105 errcode_t retval;
@@ -115,4 +112,3 @@ errcode_t ext2fs_allocate_tables(ext2_filsys fs)
115 } 112 }
116 return 0; 113 return 0;
117} 114}
118
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/bb_inode.c b/e2fsprogs/old_e2fsprogs/ext2fs/bb_inode.c
index 1deae54e8..a96789618 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/bb_inode.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/bb_inode.c
@@ -260,9 +260,3 @@ static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
260 *block_nr = blk; 260 *block_nr = blk;
261 return BLOCK_CHANGED; 261 return BLOCK_CHANGED;
262} 262}
263
264
265
266
267
268
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/bitops.c b/e2fsprogs/old_e2fsprogs/ext2fs/bitops.c
index 987061130..3cf157949 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/bitops.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/bitops.c
@@ -88,4 +88,3 @@ void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
88 bb_error_msg("#%lu", arg); 88 bb_error_msg("#%lu", arg);
89#endif 89#endif
90} 90}
91
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/block.c b/e2fsprogs/old_e2fsprogs/ext2fs/block.c
index 498096995..dbd04f846 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/block.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/block.c
@@ -435,4 +435,3 @@ errcode_t ext2fs_block_iterate(ext2_filsys fs,
435 return ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_NO_LARGE | flags, 435 return ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_NO_LARGE | flags,
436 block_buf, xlate_func, &xl); 436 block_buf, xlate_func, &xl);
437} 437}
438
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/bmap.c b/e2fsprogs/old_e2fsprogs/ext2fs/bmap.c
index b2d0279d8..796b0e4f5 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/bmap.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/bmap.c
@@ -259,6 +259,3 @@ done:
259 } 259 }
260 return retval; 260 return retval;
261} 261}
262
263
264
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/bmove.c b/e2fsprogs/old_e2fsprogs/ext2fs/bmove.c
index 635410da5..ec9244d0b 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/bmove.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/bmove.c
@@ -153,4 +153,3 @@ errcode_t ext2fs_move_blocks(ext2_filsys fs,
153 } 153 }
154 return 0; 154 return 0;
155} 155}
156
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/brel.h b/e2fsprogs/old_e2fsprogs/ext2fs/brel.h
index 216fd132c..87bf72be4 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/brel.h
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/brel.h
@@ -84,4 +84,3 @@ errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block,
84#define ext2fs_brel_move(brel, old, new) ((brel)->move((brel), old, new)) 84#define ext2fs_brel_move(brel, old, new) ((brel)->move((brel), old, new))
85#define ext2fs_brel_delete(brel, old) ((brel)->delete((brel), old)) 85#define ext2fs_brel_delete(brel, old) ((brel)->delete((brel), old))
86#define ext2fs_brel_free(brel) ((brel)->free((brel))) 86#define ext2fs_brel_free(brel) ((brel)->free((brel)))
87
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/closefs.c b/e2fsprogs/old_e2fsprogs/ext2fs/closefs.c
index 7ba7f22e2..bfa15e22a 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/closefs.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/closefs.c
@@ -378,4 +378,3 @@ errcode_t ext2fs_close(ext2_filsys fs)
378 ext2fs_free(fs); 378 ext2fs_free(fs);
379 return 0; 379 return 0;
380} 380}
381
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/cmp_bitmaps.c b/e2fsprogs/old_e2fsprogs/ext2fs/cmp_bitmaps.c
index 05b8eb8d7..7f78ff804 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/cmp_bitmaps.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/cmp_bitmaps.c
@@ -70,4 +70,3 @@ errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
70 70
71 return 0; 71 return 0;
72} 72}
73
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/dir_iterate.c b/e2fsprogs/old_e2fsprogs/ext2fs/dir_iterate.c
index b7d873595..eb5dae0a6 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/dir_iterate.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/dir_iterate.c
@@ -217,4 +217,3 @@ next:
217 return BLOCK_ABORT; 217 return BLOCK_ABORT;
218 return 0; 218 return 0;
219} 219}
220
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/dirblock.c b/e2fsprogs/old_e2fsprogs/ext2fs/dirblock.c
index f651338e3..f9c5a104b 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/dirblock.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/dirblock.c
@@ -130,4 +130,3 @@ errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
130{ 130{
131 return ext2fs_write_dir_block2(fs, block, inbuf, 0); 131 return ext2fs_write_dir_block2(fs, block, inbuf, 0);
132} 132}
133
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/dupfs.c b/e2fsprogs/old_e2fsprogs/ext2fs/dupfs.c
index 203c29fe3..d1879377a 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/dupfs.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/dupfs.c
@@ -92,6 +92,4 @@ errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest)
92errout: 92errout:
93 ext2fs_free(fs); 93 ext2fs_free(fs);
94 return retval; 94 return retval;
95
96} 95}
97
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/e2image.h b/e2fsprogs/old_e2fsprogs/ext2fs/e2image.h
index 8d38ecc13..a598d0111 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/e2image.h
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/e2image.h
@@ -37,16 +37,3 @@ struct ext2_image_hdr {
37 __u32 offset_blockmap; /* Byte offset of the inode bitmaps */ 37 __u32 offset_blockmap; /* Byte offset of the inode bitmaps */
38 __u32 offset_reserved[8]; 38 __u32 offset_reserved[8];
39}; 39};
40
41
42
43
44
45
46
47
48
49
50
51
52
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_ext_attr.h b/e2fsprogs/old_e2fsprogs/ext2fs/ext2_ext_attr.h
index cc91bb8d6..ca309c0d0 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_ext_attr.h
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/ext2_ext_attr.h
@@ -50,4 +50,3 @@ struct ext2_ext_attr_entry {
50 sizeof(struct ext2_xattr_entry)) & ~EXT2_EXT_ATTR_ROUND) 50 sizeof(struct ext2_xattr_entry)) & ~EXT2_EXT_ATTR_ROUND)
51#define EXT2_XATTR_SIZE(size) \ 51#define EXT2_XATTR_SIZE(size) \
52 (((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND) 52 (((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND)
53
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext2fsP.h b/e2fsprogs/old_e2fsprogs/ext2fs/ext2fsP.h
index 908b5d9a4..7a02e9a8e 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2fsP.h
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/ext2fsP.h
@@ -85,5 +85,3 @@ extern int ext2fs_process_dir_block(ext2_filsys fs,
85 blk_t ref_block, 85 blk_t ref_block,
86 int ref_offset, 86 int ref_offset,
87 void *priv_data); 87 void *priv_data);
88
89
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/freefs.c b/e2fsprogs/old_e2fsprogs/ext2fs/freefs.c
index 65c4ee794..0c5d48b11 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/freefs.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/freefs.c
@@ -125,4 +125,3 @@ void ext2fs_free_dblist(ext2_dblist dblist)
125 dblist->magic = 0; 125 dblist->magic = 0;
126 ext2fs_free_mem(&dblist); 126 ext2fs_free_mem(&dblist);
127} 127}
128
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/get_pathname.c b/e2fsprogs/old_e2fsprogs/ext2fs/get_pathname.c
index a98b2b9e5..a3bbad851 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/get_pathname.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/get_pathname.c
@@ -153,5 +153,4 @@ errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
153 retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name); 153 retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name);
154 ext2fs_free_mem(&buf); 154 ext2fs_free_mem(&buf);
155 return retval; 155 return retval;
156
157} 156}
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ind_block.c b/e2fsprogs/old_e2fsprogs/ext2fs/ind_block.c
index c86a1c59a..a1038300b 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/ind_block.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/ind_block.c
@@ -67,5 +67,3 @@ errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf)
67#endif 67#endif
68 return io_channel_write_blk(fs->io, blk, 1, buf); 68 return io_channel_write_blk(fs->io, blk, 1, buf);
69} 69}
70
71
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/inline.c b/e2fsprogs/old_e2fsprogs/ext2fs/inline.c
index 9b620a772..d328cc950 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/inline.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/inline.c
@@ -30,4 +30,3 @@
30#include "ext2_fs.h" 30#include "ext2_fs.h"
31#define INCLUDE_INLINE_FUNCS 31#define INCLUDE_INLINE_FUNCS
32#include "ext2fs.h" 32#include "ext2fs.h"
33
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/inode.c b/e2fsprogs/old_e2fsprogs/ext2fs/inode.c
index 5e0d081bd..7a1d5c94b 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/inode.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/inode.c
@@ -764,4 +764,3 @@ errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino)
764 return EXT2_ET_NO_DIRECTORY; 764 return EXT2_ET_NO_DIRECTORY;
765 return 0; 765 return 0;
766} 766}
767
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/inode_io.c b/e2fsprogs/old_e2fsprogs/ext2fs/inode_io.c
index 4bfa93aef..b861d5ff6 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/inode_io.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/inode_io.c
@@ -268,4 +268,3 @@ static errcode_t inode_flush(io_channel channel)
268 268
269 return ext2fs_file_flush(data->file); 269 return ext2fs_file_flush(data->file);
270} 270}
271
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/jfs_dat.h b/e2fsprogs/old_e2fsprogs/ext2fs/jfs_dat.h
index 136635de0..17c586a29 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/jfs_dat.h
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/jfs_dat.h
@@ -60,6 +60,4 @@ typedef struct journal_superblock_s
60 /* Dynamic information describing the current state of the log */ 60 /* Dynamic information describing the current state of the log */
61 __u32 s_sequence; /* first commit ID expected in log */ 61 __u32 s_sequence; /* first commit ID expected in log */
62 __u32 s_start; /* blocknr of start of log */ 62 __u32 s_start; /* blocknr of start of log */
63
64} journal_superblock_t; 63} journal_superblock_t;
65
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/lookup.c b/e2fsprogs/old_e2fsprogs/ext2fs/lookup.c
index 31b30a182..b2e8de8ec 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/lookup.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/lookup.c
@@ -66,5 +66,3 @@ errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
66 66
67 return (ls.found) ? 0 : EXT2_ET_FILE_NOT_FOUND; 67 return (ls.found) ? 0 : EXT2_ET_FILE_NOT_FOUND;
68} 68}
69
70
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/mkdir.c b/e2fsprogs/old_e2fsprogs/ext2fs/mkdir.c
index 93f47b06f..a86ac8e93 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/mkdir.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/mkdir.c
@@ -136,7 +136,4 @@ errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
136cleanup: 136cleanup:
137 ext2fs_free_mem(&block); 137 ext2fs_free_mem(&block);
138 return retval; 138 return retval;
139
140} 139}
141
142
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/mkjournal.c b/e2fsprogs/old_e2fsprogs/ext2fs/mkjournal.c
index db1c8bff3..748d9abc7 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/mkjournal.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/mkjournal.c
@@ -188,7 +188,6 @@ static int mkjournal_proc(ext2_filsys fs,
188 return (BLOCK_CHANGED | BLOCK_ABORT); 188 return (BLOCK_CHANGED | BLOCK_ABORT);
189 else 189 else
190 return BLOCK_CHANGED; 190 return BLOCK_CHANGED;
191
192} 191}
193 192
194/* 193/*
@@ -423,6 +422,5 @@ main(int argc, char **argv)
423 } 422 }
424 ext2fs_close(fs); 423 ext2fs_close(fs);
425 exit(0); 424 exit(0);
426
427} 425}
428#endif 426#endif
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/namei.c b/e2fsprogs/old_e2fsprogs/ext2fs/namei.c
index 14d48fb72..18244613c 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/namei.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/namei.c
@@ -202,4 +202,3 @@ errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
202 ext2fs_free_mem(&buf); 202 ext2fs_free_mem(&buf);
203 return retval; 203 return retval;
204} 204}
205
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/newdir.c b/e2fsprogs/old_e2fsprogs/ext2fs/newdir.c
index 9470e7f56..9f156626d 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/newdir.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/newdir.c
@@ -66,7 +66,6 @@ errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
66 dir->name_len = 2 | filetype; 66 dir->name_len = 2 | filetype;
67 dir->name[0] = '.'; 67 dir->name[0] = '.';
68 dir->name[1] = '.'; 68 dir->name[1] = '.';
69
70 } 69 }
71 *block = buf; 70 *block = buf;
72 return 0; 71 return 0;
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/read_bb.c b/e2fsprogs/old_e2fsprogs/ext2fs/read_bb.c
index 4766157c2..ce77bc9f6 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/read_bb.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/read_bb.c
@@ -94,5 +94,3 @@ errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
94 94
95 return rb.err; 95 return rb.err;
96} 96}
97
98
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/read_bb_file.c b/e2fsprogs/old_e2fsprogs/ext2fs/read_bb_file.c
index 831adcc3a..bf1fc328b 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/read_bb_file.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/read_bb_file.c
@@ -94,5 +94,3 @@ errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f,
94 return ext2fs_read_bb_FILE2(fs, f, bb_list, (void *) invalid, 94 return ext2fs_read_bb_FILE2(fs, f, bb_list, (void *) invalid,
95 call_compat_invalid); 95 call_compat_invalid);
96} 96}
97
98
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/res_gdt.c b/e2fsprogs/old_e2fsprogs/ext2fs/res_gdt.c
index 3c550d511..403463a90 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/res_gdt.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/res_gdt.c
@@ -218,4 +218,3 @@ out_free:
218 ext2fs_free_mem((void *)&dindir_buf); 218 ext2fs_free_mem((void *)&dindir_buf);
219 return retval; 219 return retval;
220} 220}
221
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/rs_bitmap.c b/e2fsprogs/old_e2fsprogs/ext2fs/rs_bitmap.c
index e932b3c9d..32e87b77a 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/rs_bitmap.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/rs_bitmap.c
@@ -104,4 +104,3 @@ errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
104 bmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP; 104 bmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
105 return retval; 105 return retval;
106} 106}
107
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/rw_bitmaps.c b/e2fsprogs/old_e2fsprogs/ext2fs/rw_bitmaps.c
index 0ae0a8234..bba432679 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/rw_bitmaps.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/rw_bitmaps.c
@@ -266,7 +266,6 @@ errcode_t ext2fs_read_block_bitmap(ext2_filsys fs)
266 266
267errcode_t ext2fs_read_bitmaps(ext2_filsys fs) 267errcode_t ext2fs_read_bitmaps(ext2_filsys fs)
268{ 268{
269
270 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 269 EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
271 270
272 if (fs->inode_map && fs->block_map) 271 if (fs->inode_map && fs->block_map)
@@ -293,4 +292,3 @@ errcode_t ext2fs_write_bitmaps(ext2_filsys fs)
293 } 292 }
294 return 0; 293 return 0;
295} 294}
296
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/swapfs.c b/e2fsprogs/old_e2fsprogs/ext2fs/swapfs.c
index 2fca3cfbb..07b757abd 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/swapfs.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/swapfs.c
@@ -66,7 +66,6 @@ void ext2fs_swap_super(struct ext2_super_block * sb)
66 sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]); 66 sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
67 for (i=0; i < 17; i++) 67 for (i=0; i < 17; i++)
68 sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]); 68 sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
69
70} 69}
71 70
72void ext2fs_swap_group_desc(struct ext2_group_desc *gdp) 71void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
@@ -222,7 +221,6 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
222 ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1), 221 ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
223 bufsize - sizeof(struct ext2_inode) - 222 bufsize - sizeof(struct ext2_inode) -
224 t->i_extra_isize - sizeof(__u32), 0); 223 t->i_extra_isize - sizeof(__u32), 0);
225
226} 224}
227 225
228void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t, 226void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/unlink.c b/e2fsprogs/old_e2fsprogs/ext2fs/unlink.c
index 83ac2713e..71a9ffcb9 100644
--- a/e2fsprogs/old_e2fsprogs/ext2fs/unlink.c
+++ b/e2fsprogs/old_e2fsprogs/ext2fs/unlink.c
@@ -97,4 +97,3 @@ errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir,
97 97
98 return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE; 98 return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE;
99} 99}
100
diff --git a/e2fsprogs/old_e2fsprogs/util.c b/e2fsprogs/old_e2fsprogs/util.c
index 64cca05a7..0829f5686 100644
--- a/e2fsprogs/old_e2fsprogs/util.c
+++ b/e2fsprogs/old_e2fsprogs/util.c
@@ -95,7 +95,6 @@ force_check:
95 bb_error_msg("%s is apparently in use by the system", device); 95 bb_error_msg("%s is apparently in use by the system", device);
96 goto force_check; 96 goto force_check;
97 } 97 }
98
99} 98}
100 99
101void parse_journal_opts(char **journal_device, int *journal_flags, 100void parse_journal_opts(char **journal_device, int *journal_flags,
diff --git a/editors/sed.c b/editors/sed.c
index 7af8f867a..7d6e7e79f 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -61,6 +61,10 @@
61#include "libbb.h" 61#include "libbb.h"
62#include "xregex.h" 62#include "xregex.h"
63 63
64enum {
65 OPT_in_place = 1 << 0,
66};
67
64/* Each sed command turns into one of these structures. */ 68/* Each sed command turns into one of these structures. */
65typedef struct sed_cmd_s { 69typedef struct sed_cmd_s {
66 /* Ordered by alignment requirements: currently 36 bytes on x86 */ 70 /* Ordered by alignment requirements: currently 36 bytes on x86 */
@@ -938,8 +942,11 @@ static void process_files(void)
938 942
939 if (matched) { 943 if (matched) {
940 /* once matched, "n,xxx" range is dead, disabling it */ 944 /* once matched, "n,xxx" range is dead, disabling it */
941 if (sed_cmd->beg_line > 0) 945 if (sed_cmd->beg_line > 0
946 && !(option_mask32 & OPT_in_place) /* but not for -i */
947 ) {
942 sed_cmd->beg_line = -2; 948 sed_cmd->beg_line = -2;
949 }
943 sed_cmd->in_match = !( 950 sed_cmd->in_match = !(
944 /* has the ending line come, or is this a single address command? */ 951 /* has the ending line come, or is this a single address command? */
945 (sed_cmd->end_line ? 952 (sed_cmd->end_line ?
@@ -1270,9 +1277,6 @@ static void add_cmd_block(char *cmdstr)
1270int sed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1277int sed_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1271int sed_main(int argc UNUSED_PARAM, char **argv) 1278int sed_main(int argc UNUSED_PARAM, char **argv)
1272{ 1279{
1273 enum {
1274 OPT_in_place = 1 << 0,
1275 };
1276 unsigned opt; 1280 unsigned opt;
1277 llist_t *opt_e, *opt_f; 1281 llist_t *opt_e, *opt_f;
1278 int status = EXIT_SUCCESS; 1282 int status = EXIT_SUCCESS;
@@ -1292,6 +1296,7 @@ int sed_main(int argc UNUSED_PARAM, char **argv)
1292 opt_e = opt_f = NULL; 1296 opt_e = opt_f = NULL;
1293 opt_complementary = "e::f::" /* can occur multiple times */ 1297 opt_complementary = "e::f::" /* can occur multiple times */
1294 "nn"; /* count -n */ 1298 "nn"; /* count -n */
1299 /* -i must be first, to match OPT_in_place definition */
1295 opt = getopt32(argv, "irne:f:", &opt_e, &opt_f, 1300 opt = getopt32(argv, "irne:f:", &opt_e, &opt_f,
1296 &G.be_quiet); /* counter for -n */ 1301 &G.be_quiet); /* counter for -n */
1297 //argc -= optind; 1302 //argc -= optind;
diff --git a/editors/vi.c b/editors/vi.c
index 0f412c362..73e095cf8 100644
--- a/editors/vi.c
+++ b/editors/vi.c
@@ -504,20 +504,17 @@ static int init_text_buffer(char *fn)
504} 504}
505 505
506#if ENABLE_FEATURE_VI_WIN_RESIZE 506#if ENABLE_FEATURE_VI_WIN_RESIZE
507static void query_screen_dimensions(void) 507static int query_screen_dimensions(void)
508{ 508{
509# if ENABLE_FEATURE_VI_ASK_TERMINAL 509 int err = get_terminal_width_height(STDIN_FILENO, &columns, &rows);
510 if (!G.get_rowcol_error)
511 G.get_rowcol_error =
512# endif
513 get_terminal_width_height(STDIN_FILENO, &columns, &rows);
514 if (rows > MAX_SCR_ROWS) 510 if (rows > MAX_SCR_ROWS)
515 rows = MAX_SCR_ROWS; 511 rows = MAX_SCR_ROWS;
516 if (columns > MAX_SCR_COLS) 512 if (columns > MAX_SCR_COLS)
517 columns = MAX_SCR_COLS; 513 columns = MAX_SCR_COLS;
514 return err;
518} 515}
519#else 516#else
520# define query_screen_dimensions() ((void)0) 517# define query_screen_dimensions() (0)
521#endif 518#endif
522 519
523static void edit_file(char *fn) 520static void edit_file(char *fn)
@@ -536,7 +533,7 @@ static void edit_file(char *fn)
536 rows = 24; 533 rows = 24;
537 columns = 80; 534 columns = 80;
538 size = 0; 535 size = 0;
539 query_screen_dimensions(); 536 IF_FEATURE_VI_ASK_TERMINAL(G.get_rowcol_error =) query_screen_dimensions();
540#if ENABLE_FEATURE_VI_ASK_TERMINAL 537#if ENABLE_FEATURE_VI_ASK_TERMINAL
541 if (G.get_rowcol_error /* TODO? && no input on stdin */) { 538 if (G.get_rowcol_error /* TODO? && no input on stdin */) {
542 uint64_t k; 539 uint64_t k;
@@ -546,9 +543,12 @@ static void edit_file(char *fn)
546 if ((int32_t)k == KEYCODE_CURSOR_POS) { 543 if ((int32_t)k == KEYCODE_CURSOR_POS) {
547 uint32_t rc = (k >> 32); 544 uint32_t rc = (k >> 32);
548 columns = (rc & 0x7fff); 545 columns = (rc & 0x7fff);
546 if (columns > MAX_SCR_COLS)
547 columns = MAX_SCR_COLS;
549 rows = ((rc >> 16) & 0x7fff); 548 rows = ((rc >> 16) & 0x7fff);
549 if (rows > MAX_SCR_ROWS)
550 rows = MAX_SCR_ROWS;
550 } 551 }
551 query_screen_dimensions();
552 } 552 }
553#endif 553#endif
554 new_screen(rows, columns); // get memory for virtual screen 554 new_screen(rows, columns); // get memory for virtual screen
@@ -2797,7 +2797,7 @@ static void refresh(int full_screen)
2797 int li, changed; 2797 int li, changed;
2798 char *tp, *sp; // pointer into text[] and screen[] 2798 char *tp, *sp; // pointer into text[] and screen[]
2799 2799
2800 if (ENABLE_FEATURE_VI_WIN_RESIZE) { 2800 if (ENABLE_FEATURE_VI_WIN_RESIZE IF_FEATURE_VI_ASK_TERMINAL(&& !G.get_rowcol_error) ) {
2801 unsigned c = columns, r = rows; 2801 unsigned c = columns, r = rows;
2802 query_screen_dimensions(); 2802 query_screen_dimensions();
2803 full_screen |= (c - columns) | (r - rows); 2803 full_screen |= (c - columns) | (r - rows);
diff --git a/examples/bootfloppy/display.txt b/examples/bootfloppy/display.txt
index 399d326d9..7cae48bb3 100644
--- a/examples/bootfloppy/display.txt
+++ b/examples/bootfloppy/display.txt
@@ -1,4 +1,3 @@
1 1
2This boot floppy is made with Busybox, uClibc, and the Linux kernel. 2This boot floppy is made with Busybox, uClibc, and the Linux kernel.
3Hit RETURN to boot or enter boot parameters at the prompt below. 3Hit RETURN to boot or enter boot parameters at the prompt below.
4
diff --git a/examples/bootfloppy/etc/fstab b/examples/bootfloppy/etc/fstab
index ef14ca2cc..b31f60217 100644
--- a/examples/bootfloppy/etc/fstab
+++ b/examples/bootfloppy/etc/fstab
@@ -1,2 +1 @@
1proc /proc proc defaults 0 0 proc /proc proc defaults 0 0
2
diff --git a/examples/bootfloppy/etc/inittab b/examples/bootfloppy/etc/inittab
index eb3e979ce..1ac9f68ce 100644
--- a/examples/bootfloppy/etc/inittab
+++ b/examples/bootfloppy/etc/inittab
@@ -2,4 +2,3 @@
2::respawn:-/bin/sh 2::respawn:-/bin/sh
3tty2::askfirst:-/bin/sh 3tty2::askfirst:-/bin/sh
4::ctrlaltdel:/bin/umount -a -r 4::ctrlaltdel:/bin/umount -a -r
5
diff --git a/examples/bootfloppy/etc/profile b/examples/bootfloppy/etc/profile
index 8a7c77d78..cf68d3393 100644
--- a/examples/bootfloppy/etc/profile
+++ b/examples/bootfloppy/etc/profile
@@ -5,4 +5,3 @@ echo -n "Processing /etc/profile... "
5# no-op 5# no-op
6echo "Done" 6echo "Done"
7echo 7echo
8
diff --git a/examples/bootfloppy/mkrootfs.sh b/examples/bootfloppy/mkrootfs.sh
index 5cdff21a0..a7fc48b13 100755
--- a/examples/bootfloppy/mkrootfs.sh
+++ b/examples/bootfloppy/mkrootfs.sh
@@ -102,4 +102,3 @@ then
102 rmdir $TARGET_DIR 102 rmdir $TARGET_DIR
103 gzip -9 rootfs 103 gzip -9 rootfs
104fi 104fi
105
diff --git a/examples/inittab b/examples/inittab
index 64fc4fce1..c4e0af514 100644
--- a/examples/inittab
+++ b/examples/inittab
@@ -87,4 +87,3 @@ tty5::respawn:/sbin/getty 38400 tty6
87::ctrlaltdel:/sbin/reboot 87::ctrlaltdel:/sbin/reboot
88::shutdown:/bin/umount -a -r 88::shutdown:/bin/umount -a -r
89::shutdown:/sbin/swapoff -a 89::shutdown:/sbin/swapoff -a
90
diff --git a/examples/udhcp/sample.bound b/examples/udhcp/sample.bound
index 2a95d8b7d..bd3569c77 100755
--- a/examples/udhcp/sample.bound
+++ b/examples/udhcp/sample.bound
@@ -28,4 +28,4 @@ for i in $dns
28do 28do
29 echo adding dns $i 29 echo adding dns $i
30 echo nameserver $i >> $RESOLV_CONF 30 echo nameserver $i >> $RESOLV_CONF
31done \ No newline at end of file 31done
diff --git a/examples/udhcp/sample.renew b/examples/udhcp/sample.renew
index 842bafe91..ea368fc9e 100755
--- a/examples/udhcp/sample.renew
+++ b/examples/udhcp/sample.renew
@@ -28,4 +28,4 @@ for i in $dns
28do 28do
29 echo adding dns $i 29 echo adding dns $i
30 echo nameserver $i >> $RESOLV_CONF 30 echo nameserver $i >> $RESOLV_CONF
31done \ No newline at end of file 31done
diff --git a/include/applets.src.h b/include/applets.src.h
index 6ca0c3230..195598fee 100644
--- a/include/applets.src.h
+++ b/include/applets.src.h
@@ -104,7 +104,6 @@ IF_CPIO(APPLET(cpio, _BB_DIR_BIN, _BB_SUID_DROP))
104IF_CROND(APPLET(crond, _BB_DIR_USR_SBIN, _BB_SUID_DROP)) 104IF_CROND(APPLET(crond, _BB_DIR_USR_SBIN, _BB_SUID_DROP))
105IF_CRONTAB(APPLET(crontab, _BB_DIR_USR_BIN, _BB_SUID_REQUIRE)) 105IF_CRONTAB(APPLET(crontab, _BB_DIR_USR_BIN, _BB_SUID_REQUIRE))
106IF_CRYPTPW(APPLET(cryptpw, _BB_DIR_USR_BIN, _BB_SUID_DROP)) 106IF_CRYPTPW(APPLET(cryptpw, _BB_DIR_USR_BIN, _BB_SUID_DROP))
107IF_CTTYHACK(APPLET(cttyhack, _BB_DIR_BIN, _BB_SUID_DROP))
108IF_CUT(APPLET_NOEXEC(cut, cut, _BB_DIR_USR_BIN, _BB_SUID_DROP, cut)) 107IF_CUT(APPLET_NOEXEC(cut, cut, _BB_DIR_USR_BIN, _BB_SUID_DROP, cut))
109IF_DATE(APPLET(date, _BB_DIR_BIN, _BB_SUID_DROP)) 108IF_DATE(APPLET(date, _BB_DIR_BIN, _BB_SUID_DROP))
110IF_DC(APPLET(dc, _BB_DIR_USR_BIN, _BB_SUID_DROP)) 109IF_DC(APPLET(dc, _BB_DIR_USR_BIN, _BB_SUID_DROP))
diff --git a/include/libbb.h b/include/libbb.h
index 26656de2e..a98affb3a 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -1633,7 +1633,27 @@ extern const char bb_default_login_shell[];
1633/* "sh" */ 1633/* "sh" */
1634#define DEFAULT_SHELL_SHORT_NAME (bb_default_login_shell+6) 1634#define DEFAULT_SHELL_SHORT_NAME (bb_default_login_shell+6)
1635 1635
1636#if ENABLE_FEATURE_DEVFS 1636/* The following devices are the same on all systems. */
1637#define CURRENT_TTY "/dev/tty"
1638#define DEV_CONSOLE "/dev/console"
1639
1640#if defined(__FreeBSD_kernel__)
1641# define CURRENT_VC CURRENT_TTY
1642# define VC_1 "/dev/ttyv0"
1643# define VC_2 "/dev/ttyv1"
1644# define VC_3 "/dev/ttyv2"
1645# define VC_4 "/dev/ttyv3"
1646# define VC_5 "/dev/ttyv4"
1647# define VC_FORMAT "/dev/ttyv%d"
1648#elif defined(__GNU__)
1649# define CURRENT_VC CURRENT_TTY
1650# define VC_1 "/dev/tty1"
1651# define VC_2 "/dev/tty2"
1652# define VC_3 "/dev/tty3"
1653# define VC_4 "/dev/tty4"
1654# define VC_5 "/dev/tty5"
1655# define VC_FORMAT "/dev/tty%d"
1656#elif ENABLE_FEATURE_DEVFS /* from now on, assume Linux naming */
1637# define CURRENT_VC "/dev/vc/0" 1657# define CURRENT_VC "/dev/vc/0"
1638# define VC_1 "/dev/vc/1" 1658# define VC_1 "/dev/vc/1"
1639# define VC_2 "/dev/vc/2" 1659# define VC_2 "/dev/vc/2"
@@ -1680,10 +1700,6 @@ extern const char bb_default_login_shell[];
1680# define FB_0 "/dev/fb0" 1700# define FB_0 "/dev/fb0"
1681#endif 1701#endif
1682 1702
1683/* The following devices are the same on devfs and non-devfs systems. */
1684#define CURRENT_TTY "/dev/tty"
1685#define DEV_CONSOLE "/dev/console"
1686
1687 1703
1688#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0]))) 1704#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
1689 1705
diff --git a/include/usage.src.h b/include/usage.src.h
index 46d64c135..0053a7c4b 100644
--- a/include/usage.src.h
+++ b/include/usage.src.h
@@ -678,17 +678,6 @@ INSERT
678 "\n -S SALT" \ 678 "\n -S SALT" \
679 ) \ 679 ) \
680 680
681#define cttyhack_trivial_usage \
682 "PROG ARGS"
683#define cttyhack_full_usage "\n\n" \
684 "Give PROG a controlling tty if possible." \
685 "\nExample for /etc/inittab (for busybox init):" \
686 "\n ::respawn:/bin/cttyhack /bin/sh" \
687 "\nGiving controlling tty to shell running with PID 1:" \
688 "\n $ exec cttyhack sh" \
689 "\nStarting interactive shell from boot shell script:" \
690 "\n setsid cttyhack sh" \
691
692#define cut_trivial_usage \ 681#define cut_trivial_usage \
693 "[OPTIONS] [FILE]..." 682 "[OPTIONS] [FILE]..."
694#define cut_full_usage "\n\n" \ 683#define cut_full_usage "\n\n" \
@@ -747,28 +736,6 @@ INSERT
747 "$ date\n" \ 736 "$ date\n" \
748 "Wed Apr 12 18:52:41 MDT 2000\n" 737 "Wed Apr 12 18:52:41 MDT 2000\n"
749 738
750#define dc_trivial_usage \
751 "expression..."
752#define dc_full_usage "\n\n" \
753 "Tiny RPN calculator. Operations:\n" \
754 "+, add, -, sub, *, mul, /, div, %, mod, **, exp, and, or, not, eor,\n" \
755 "p - print top of the stack (without altering the stack),\n" \
756 "f - print entire stack, o - pop the value and set output radix\n" \
757 "(value must be 10 or 16).\n" \
758 "Examples: 'dc 2 2 add' -> 4, 'dc 8 8 * 2 2 + /' -> 16\n" \
759
760#define dc_example_usage \
761 "$ dc 2 2 + p\n" \
762 "4\n" \
763 "$ dc 8 8 \\* 2 2 + / p\n" \
764 "16\n" \
765 "$ dc 0 1 and p\n" \
766 "0\n" \
767 "$ dc 0 1 or p\n" \
768 "1\n" \
769 "$ echo 72 9 div 8 mul p | dc\n" \
770 "64\n"
771
772#define dd_trivial_usage \ 739#define dd_trivial_usage \
773 "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" \ 740 "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" \
774 " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]") 741 " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]")
diff --git a/init/Config.src b/init/Config.src
index 590e29890..2cac3573e 100644
--- a/init/Config.src
+++ b/init/Config.src
@@ -89,6 +89,18 @@ config FEATURE_INITRD
89 This does not apply to initramfs, which runs /init as PID 1 and 89 This does not apply to initramfs, which runs /init as PID 1 and
90 requires no special support. 90 requires no special support.
91 91
92config INIT_TERMINAL_TYPE
93 string "Initial terminal type"
94 default "linux"
95 depends on INIT
96 help
97 This is the initial value set by init for the TERM environment
98 variable. This variable is used by programs which make use of
99 extended terminal capabilities.
100
101 Note that on Linux, init attempts to detect serial terminal and
102 sets TERM to "vt102" if one is found.
103
92config HALT 104config HALT
93 bool "poweroff, halt, and reboot" 105 bool "poweroff, halt, and reboot"
94 default y 106 default y
diff --git a/init/bootchartd.c b/init/bootchartd.c
index dae2fe6e9..465a34979 100644
--- a/init/bootchartd.c
+++ b/init/bootchartd.c
@@ -45,12 +45,15 @@
45#include "libbb.h" 45#include "libbb.h"
46/* After libbb.h, since it needs sys/types.h on some systems */ 46/* After libbb.h, since it needs sys/types.h on some systems */
47#include <sys/utsname.h> 47#include <sys/utsname.h>
48#include <sys/mount.h> 48
49#ifndef MS_SILENT 49#ifdef __linux__
50# define MS_SILENT (1 << 15) 50# include <sys/mount.h>
51#endif 51# ifndef MS_SILENT
52#ifndef MNT_DETACH 52# define MS_SILENT (1 << 15)
53# define MNT_DETACH 0x00000002 53# endif
54# ifndef MNT_DETACH
55# define MNT_DETACH 0x00000002
56# endif
54#endif 57#endif
55 58
56#define BC_VERSION_STR "0.8" 59#define BC_VERSION_STR "0.8"
@@ -174,6 +177,7 @@ static char *make_tempdir(void)
174 char template[] = "/tmp/bootchart.XXXXXX"; 177 char template[] = "/tmp/bootchart.XXXXXX";
175 char *tempdir = xstrdup(mkdtemp(template)); 178 char *tempdir = xstrdup(mkdtemp(template));
176 if (!tempdir) { 179 if (!tempdir) {
180#ifdef __linux__
177 /* /tmp is not writable (happens when we are used as init). 181 /* /tmp is not writable (happens when we are used as init).
178 * Try to mount a tmpfs, them cd and lazily unmount it. 182 * Try to mount a tmpfs, them cd and lazily unmount it.
179 * Since we unmount it at once, we can mount it anywhere. 183 * Since we unmount it at once, we can mount it anywhere.
@@ -191,6 +195,9 @@ static char *make_tempdir(void)
191 if (umount2(try_dir, MNT_DETACH) != 0) { 195 if (umount2(try_dir, MNT_DETACH) != 0) {
192 bb_perror_msg_and_die("can't %smount tmpfs", "un"); 196 bb_perror_msg_and_die("can't %smount tmpfs", "un");
193 } 197 }
198#else
199 bb_perror_msg_and_die("can't create temporary directory");
200#endif
194 } else { 201 } else {
195 xchdir(tempdir); 202 xchdir(tempdir);
196 } 203 }
diff --git a/init/halt.c b/init/halt.c
index f1bb2c4a8..abd801fda 100644
--- a/init/halt.c
+++ b/init/halt.c
@@ -8,7 +8,7 @@
8 */ 8 */
9 9
10#include "libbb.h" 10#include "libbb.h"
11#include <sys/reboot.h> 11#include "reboot.h"
12 12
13#if ENABLE_FEATURE_WTMP 13#if ENABLE_FEATURE_WTMP
14#include <sys/utsname.h> 14#include <sys/utsname.h>
@@ -36,18 +36,6 @@ static void write_wtmp(void)
36#define write_wtmp() ((void)0) 36#define write_wtmp() ((void)0)
37#endif 37#endif
38 38
39#ifndef RB_HALT_SYSTEM
40#define RB_HALT_SYSTEM RB_HALT
41#endif
42
43#ifndef RB_POWERDOWN
44/* Stop system and switch power off if possible. */
45# define RB_POWERDOWN 0x4321fedc
46#endif
47#ifndef RB_POWER_OFF
48# define RB_POWER_OFF RB_POWERDOWN
49#endif
50
51 39
52int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 40int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
53int halt_main(int argc UNUSED_PARAM, char **argv) 41int halt_main(int argc UNUSED_PARAM, char **argv)
diff --git a/init/init.c b/init/init.c
index 2eb8f1a54..fa1af6d7c 100644
--- a/init/init.c
+++ b/init/init.c
@@ -12,13 +12,21 @@
12#include "libbb.h" 12#include "libbb.h"
13#include <syslog.h> 13#include <syslog.h>
14#include <paths.h> 14#include <paths.h>
15#include <sys/reboot.h>
16#include <sys/resource.h> 15#include <sys/resource.h>
16#ifdef __linux__
17#include <linux/vt.h> 17#include <linux/vt.h>
18#endif
18#if ENABLE_FEATURE_UTMP 19#if ENABLE_FEATURE_UTMP
19# include <utmp.h> /* DEAD_PROCESS */ 20# include <utmp.h> /* DEAD_PROCESS */
20#endif 21#endif
22#include "reboot.h" /* reboot() constants */
21 23
24/* Used only for sanitizing purposes in set_sane_term() below. On systems where
25 * the baud rate is stored in a separate field, we can safely disable them. */
26#ifndef CBAUD
27# define CBAUD 0
28# define CBAUDEX 0
29#endif
22 30
23/* Was a CONFIG_xxx option. A lot of people were building 31/* Was a CONFIG_xxx option. A lot of people were building
24 * not fully functional init by switching it on! */ 32 * not fully functional init by switching it on! */
@@ -89,13 +97,6 @@ static const char *log_console = VC_5;
89enum { 97enum {
90 L_LOG = 0x1, 98 L_LOG = 0x1,
91 L_CONSOLE = 0x2, 99 L_CONSOLE = 0x2,
92#ifndef RB_HALT_SYSTEM
93 RB_HALT_SYSTEM = 0xcdef0123, /* FIXME: this overflows enum */
94 RB_ENABLE_CAD = 0x89abcdef,
95 RB_DISABLE_CAD = 0,
96 RB_POWER_OFF = 0x4321fedc,
97 RB_AUTOBOOT = 0x01234567,
98#endif
99}; 100};
100 101
101/* Print a message to the specified device. 102/* Print a message to the specified device.
@@ -166,7 +167,9 @@ static void message(int where, const char *fmt, ...)
166 167
167static void console_init(void) 168static void console_init(void)
168{ 169{
170#ifdef VT_OPENQRY
169 int vtno; 171 int vtno;
172#endif
170 char *s; 173 char *s;
171 174
172 s = getenv("CONSOLE"); 175 s = getenv("CONSOLE");
@@ -190,6 +193,7 @@ static void console_init(void)
190 } 193 }
191 194
192 s = getenv("TERM"); 195 s = getenv("TERM");
196#ifdef VT_OPENQRY
193 if (ioctl(STDIN_FILENO, VT_OPENQRY, &vtno) != 0) { 197 if (ioctl(STDIN_FILENO, VT_OPENQRY, &vtno) != 0) {
194 /* Not a linux terminal, probably serial console. 198 /* Not a linux terminal, probably serial console.
195 * Force the TERM setting to vt102 199 * Force the TERM setting to vt102
@@ -198,8 +202,10 @@ static void console_init(void)
198 putenv((char*)"TERM=vt102"); 202 putenv((char*)"TERM=vt102");
199 if (!ENABLE_FEATURE_INIT_SYSLOG) 203 if (!ENABLE_FEATURE_INIT_SYSLOG)
200 log_console = NULL; 204 log_console = NULL;
201 } else if (!s) 205 } else
202 putenv((char*)"TERM=linux"); 206#endif
207 if (!s)
208 putenv((char*)"TERM=" CONFIG_INIT_TERMINAL_TYPE);
203} 209}
204 210
205/* Set terminal settings to reasonable defaults. 211/* Set terminal settings to reasonable defaults.
@@ -220,8 +226,10 @@ static void set_sane_term(void)
220 tty.c_cc[VSTOP] = 19; /* C-s */ 226 tty.c_cc[VSTOP] = 19; /* C-s */
221 tty.c_cc[VSUSP] = 26; /* C-z */ 227 tty.c_cc[VSUSP] = 26; /* C-z */
222 228
229#ifdef __linux__
223 /* use line discipline 0 */ 230 /* use line discipline 0 */
224 tty.c_line = 0; 231 tty.c_line = 0;
232#endif
225 233
226 /* Make it be sane */ 234 /* Make it be sane */
227 tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD; 235 tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD;
@@ -709,10 +717,12 @@ static void restart_handler(int sig UNUSED_PARAM)
709 717
710 run_shutdown_and_kill_processes(); 718 run_shutdown_and_kill_processes();
711 719
720#ifdef RB_ENABLE_CAD
712 /* Allow Ctrl-Alt-Del to reboot the system. 721 /* Allow Ctrl-Alt-Del to reboot the system.
713 * This is how kernel sets it up for init, we follow suit. 722 * This is how kernel sets it up for init, we follow suit.
714 */ 723 */
715 reboot(RB_ENABLE_CAD); /* misnomer */ 724 reboot(RB_ENABLE_CAD); /* misnomer */
725#endif
716 726
717 if (open_stdio_to_tty(a->terminal)) { 727 if (open_stdio_to_tty(a->terminal)) {
718 dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command); 728 dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command);
@@ -855,9 +865,11 @@ int init_main(int argc UNUSED_PARAM, char **argv)
855 ) { 865 ) {
856 bb_show_usage(); 866 bb_show_usage();
857 } 867 }
868#ifdef RB_DISABLE_CAD
858 /* Turn off rebooting via CTL-ALT-DEL - we get a 869 /* Turn off rebooting via CTL-ALT-DEL - we get a
859 * SIGINT on CAD so we can shut things down gracefully... */ 870 * SIGINT on CAD so we can shut things down gracefully... */
860 reboot(RB_DISABLE_CAD); /* misnomer */ 871 reboot(RB_DISABLE_CAD); /* misnomer */
872#endif
861 } 873 }
862 874
863 /* Figure out where the default console should be */ 875 /* Figure out where the default console should be */
@@ -880,6 +892,8 @@ int init_main(int argc UNUSED_PARAM, char **argv)
880 message(L_CONSOLE | L_LOG, "init started: %s", bb_banner); 892 message(L_CONSOLE | L_LOG, "init started: %s", bb_banner);
881#endif 893#endif
882 894
895/* struct sysinfo is linux-specific */
896#ifdef __linux__
883 /* Make sure there is enough memory to do something useful. */ 897 /* Make sure there is enough memory to do something useful. */
884 if (ENABLE_SWAPONOFF) { 898 if (ENABLE_SWAPONOFF) {
885 struct sysinfo info; 899 struct sysinfo info;
@@ -895,6 +909,7 @@ int init_main(int argc UNUSED_PARAM, char **argv)
895 run_actions(SYSINIT); /* wait and removing */ 909 run_actions(SYSINIT); /* wait and removing */
896 } 910 }
897 } 911 }
912#endif
898 913
899 /* Check if we are supposed to be in single user mode */ 914 /* Check if we are supposed to be in single user mode */
900 if (argv[1] 915 if (argv[1]
diff --git a/init/reboot.h b/init/reboot.h
new file mode 100644
index 000000000..949763949
--- /dev/null
+++ b/init/reboot.h
@@ -0,0 +1,30 @@
1/*
2 * Definitions related to the reboot() system call,
3 * shared between init.c and halt.c.
4 */
5
6#include <sys/reboot.h>
7
8#ifndef RB_HALT_SYSTEM
9# if defined(__linux__)
10# define RB_HALT_SYSTEM 0xcdef0123
11# define RB_ENABLE_CAD 0x89abcdef
12# define RB_DISABLE_CAD 0
13# define RB_POWER_OFF 0x4321fedc
14# define RB_AUTOBOOT 0x01234567
15# elif defined(RB_HALT)
16# define RB_HALT_SYSTEM RB_HALT
17# endif
18#endif
19
20/* Stop system and switch power off if possible. */
21#ifndef RB_POWER_OFF
22# if defined(RB_POWERDOWN)
23# define RB_POWER_OFF RB_POWERDOWN
24# elif defined(__linux__)
25# define RB_POWER_OFF 0x4321fedc
26# else
27# warning "poweroff unsupported, using halt as fallback"
28# define RB_POWER_OFF RB_HALT_SYSTEM
29# endif
30#endif
diff --git a/libbb/Config.src b/libbb/Config.src
index 80b1e0d21..9b01757c6 100644
--- a/libbb/Config.src
+++ b/libbb/Config.src
@@ -98,7 +98,7 @@ config FEATURE_USERNAME_COMPLETION
98 98
99config FEATURE_EDITING_FANCY_PROMPT 99config FEATURE_EDITING_FANCY_PROMPT
100 bool "Fancy shell prompts" 100 bool "Fancy shell prompts"
101 default n 101 default y
102 depends on FEATURE_EDITING 102 depends on FEATURE_EDITING
103 help 103 help
104 Setting this option allows for prompts to use things like \w and 104 Setting this option allows for prompts to use things like \w and
@@ -153,6 +153,7 @@ config FEATURE_COPYBUF_KB
153config MONOTONIC_SYSCALL 153config MONOTONIC_SYSCALL
154 bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" 154 bool "Use clock_gettime(CLOCK_MONOTONIC) syscall"
155 default n 155 default n
156 depends on PLATFORM_LINUX
156 help 157 help
157 Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring 158 Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring
158 time intervals (time, ping, traceroute etc need this). 159 time intervals (time, ping, traceroute etc need this).
diff --git a/libbb/README b/libbb/README
index 4f28f7e34..6e63dc5f2 100644
--- a/libbb/README
+++ b/libbb/README
@@ -8,4 +8,3 @@ that you wrote that is mis-attributed, do let me know so we can fix that up.
8 8
9 Erik Andersen 9 Erik Andersen
10 <andersen@codepoet.org> 10 <andersen@codepoet.org>
11
diff --git a/libbb/lineedit.c b/libbb/lineedit.c
index ab418c0ab..866f9230d 100644
--- a/libbb/lineedit.c
+++ b/libbb/lineedit.c
@@ -53,19 +53,15 @@
53#if ENABLE_FEATURE_EDITING 53#if ENABLE_FEATURE_EDITING
54 54
55 55
56#define ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR \ 56#define ENABLE_USERNAME_OR_HOMEDIR \
57 (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT) 57 (ENABLE_FEATURE_USERNAME_COMPLETION || ENABLE_FEATURE_EDITING_FANCY_PROMPT)
58#define IF_FEATURE_GETUSERNAME_AND_HOMEDIR(...) 58#define IF_USERNAME_OR_HOMEDIR(...)
59#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR 59#if ENABLE_USERNAME_OR_HOMEDIR
60#undef IF_FEATURE_GETUSERNAME_AND_HOMEDIR 60# undef IF_USERNAME_OR_HOMEDIR
61#define IF_FEATURE_GETUSERNAME_AND_HOMEDIR(...) __VA_ARGS__ 61# define IF_USERNAME_OR_HOMEDIR(...) __VA_ARGS__
62#endif 62#endif
63 63
64 64
65#define SEQ_CLEAR_TILL_END_OF_SCREEN "\033[J"
66//#define SEQ_CLEAR_TILL_END_OF_LINE "\033[K"
67
68
69#undef CHAR_T 65#undef CHAR_T
70#if ENABLE_UNICODE_SUPPORT 66#if ENABLE_UNICODE_SUPPORT
71# define BB_NUL ((wchar_t)0) 67# define BB_NUL ((wchar_t)0)
@@ -90,14 +86,16 @@ static bool BB_ispunct(CHAR_T c) { return ((unsigned)c < 256 && ispunct(c)); }
90# define BB_isalnum(c) isalnum(c) 86# define BB_isalnum(c) isalnum(c)
91# define BB_ispunct(c) ispunct(c) 87# define BB_ispunct(c) ispunct(c)
92#endif 88#endif
89#if ENABLE_UNICODE_PRESERVE_BROKEN
90# define unicode_mark_raw_byte(wc) ((wc) | 0x20000000)
91# define unicode_is_raw_byte(wc) ((wc) & 0x20000000)
92#else
93# define unicode_is_raw_byte(wc) 0
94#endif
93 95
94 96
95# if ENABLE_UNICODE_PRESERVE_BROKEN 97#define SEQ_CLEAR_TILL_END_OF_SCREEN "\033[J"
96# define unicode_mark_raw_byte(wc) ((wc) | 0x20000000) 98//#define SEQ_CLEAR_TILL_END_OF_LINE "\033[K"
97# define unicode_is_raw_byte(wc) ((wc) & 0x20000000)
98# else
99# define unicode_is_raw_byte(wc) 0
100# endif
101 99
102 100
103enum { 101enum {
@@ -107,7 +105,7 @@ enum {
107 : 0x7ff0 105 : 0x7ff0
108}; 106};
109 107
110#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR 108#if ENABLE_USERNAME_OR_HOMEDIR
111static const char null_str[] ALIGN1 = ""; 109static const char null_str[] ALIGN1 = "";
112#endif 110#endif
113 111
@@ -134,7 +132,7 @@ struct lineedit_statics {
134 int num_ok_lines; /* = 1; */ 132 int num_ok_lines; /* = 1; */
135#endif 133#endif
136 134
137#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR 135#if ENABLE_USERNAME_OR_HOMEDIR
138 char *user_buf; 136 char *user_buf;
139 char *home_pwd_buf; /* = (char*)null_str; */ 137 char *home_pwd_buf; /* = (char*)null_str; */
140#endif 138#endif
@@ -145,7 +143,7 @@ struct lineedit_statics {
145#endif 143#endif
146 144
147#if ENABLE_FEATURE_EDITING_VI 145#if ENABLE_FEATURE_EDITING_VI
148#define DELBUFSIZ 128 146# define DELBUFSIZ 128
149 CHAR_T *delptr; 147 CHAR_T *delptr;
150 smallint newdelflag; /* whether delbuf should be reused yet */ 148 smallint newdelflag; /* whether delbuf should be reused yet */
151 CHAR_T delbuf[DELBUFSIZ]; /* a place to store deleted characters */ 149 CHAR_T delbuf[DELBUFSIZ]; /* a place to store deleted characters */
@@ -191,7 +189,7 @@ extern struct lineedit_statics *const lineedit_ptr_to_statics;
191 barrier(); \ 189 barrier(); \
192 cmdedit_termw = 80; \ 190 cmdedit_termw = 80; \
193 IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines = 1;) \ 191 IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines = 1;) \
194 IF_FEATURE_GETUSERNAME_AND_HOMEDIR(home_pwd_buf = (char*)null_str;) \ 192 IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) \
195} while (0) 193} while (0)
196static void deinit_S(void) 194static void deinit_S(void)
197{ 195{
@@ -200,7 +198,7 @@ static void deinit_S(void)
200 * (otherwise it points to verbatim prompt (NOT malloced) */ 198 * (otherwise it points to verbatim prompt (NOT malloced) */
201 free((char*)cmdedit_prompt); 199 free((char*)cmdedit_prompt);
202#endif 200#endif
203#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR 201#if ENABLE_USERNAME_OR_HOMEDIR
204 free(user_buf); 202 free(user_buf);
205 if (home_pwd_buf != null_str) 203 if (home_pwd_buf != null_str)
206 free(home_pwd_buf); 204 free(home_pwd_buf);
@@ -1677,7 +1675,7 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1677 c = *prmt_ptr++; 1675 c = *prmt_ptr++;
1678 1676
1679 switch (c) { 1677 switch (c) {
1680# if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR 1678# if ENABLE_USERNAME_OR_HOMEDIR
1681 case 'u': 1679 case 'u':
1682 pbuf = user_buf ? user_buf : (char*)""; 1680 pbuf = user_buf ? user_buf : (char*)"";
1683 break; 1681 break;
@@ -1689,7 +1687,7 @@ static void parse_and_put_prompt(const char *prmt_ptr)
1689 case '$': 1687 case '$':
1690 c = (geteuid() == 0 ? '#' : '$'); 1688 c = (geteuid() == 0 ? '#' : '$');
1691 break; 1689 break;
1692# if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR 1690# if ENABLE_USERNAME_OR_HOMEDIR
1693 case 'w': 1691 case 'w':
1694 /* /home/user[/something] -> ~[/something] */ 1692 /* /home/user[/something] -> ~[/something] */
1695 pbuf = cwd_buf; 1693 pbuf = cwd_buf;
@@ -1773,11 +1771,13 @@ static void cmdedit_setwidth(unsigned w, int redraw_flg)
1773 1771
1774static void win_changed(int nsig) 1772static void win_changed(int nsig)
1775{ 1773{
1774 int sv_errno = errno;
1776 unsigned width; 1775 unsigned width;
1777 get_terminal_width_height(0, &width, NULL); 1776 get_terminal_width_height(0, &width, NULL);
1778 cmdedit_setwidth(width, nsig /* - just a yes/no flag */); 1777 cmdedit_setwidth(width, nsig /* - just a yes/no flag */);
1779 if (nsig == SIGWINCH) 1778 if (nsig == SIGWINCH)
1780 signal(SIGWINCH, win_changed); /* rearm ourself */ 1779 signal(SIGWINCH, win_changed); /* rearm ourself */
1780 errno = sv_errno;
1781} 1781}
1782 1782
1783static int lineedit_read_key(char *read_key_buffer) 1783static int lineedit_read_key(char *read_key_buffer)
@@ -1967,7 +1967,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
1967 /* Now initialize things */ 1967 /* Now initialize things */
1968 previous_SIGWINCH_handler = signal(SIGWINCH, win_changed); 1968 previous_SIGWINCH_handler = signal(SIGWINCH, win_changed);
1969 win_changed(0); /* do initial resizing */ 1969 win_changed(0); /* do initial resizing */
1970#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR 1970#if ENABLE_USERNAME_OR_HOMEDIR
1971 { 1971 {
1972 struct passwd *entry; 1972 struct passwd *entry;
1973 1973
@@ -2389,7 +2389,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
2389 } 2389 }
2390#endif 2390#endif
2391 2391
2392/* Stop bug catching using "command_must_not_be_used" trick */ 2392/* End of bug-catching "command_must_not_be_used" trick */
2393#undef command 2393#undef command
2394 2394
2395#if ENABLE_UNICODE_SUPPORT 2395#if ENABLE_UNICODE_SUPPORT
@@ -2423,7 +2423,7 @@ int FAST_FUNC read_line_input(const char *prompt, char *command, int maxsize, li
2423 return len; /* can't return command_len, DEINIT_S() destroys it */ 2423 return len; /* can't return command_len, DEINIT_S() destroys it */
2424} 2424}
2425 2425
2426#else 2426#else /* !FEATURE_EDITING */
2427 2427
2428#undef read_line_input 2428#undef read_line_input
2429int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize) 2429int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize)
@@ -2434,7 +2434,7 @@ int FAST_FUNC read_line_input(const char* prompt, char* command, int maxsize)
2434 return strlen(command); 2434 return strlen(command);
2435} 2435}
2436 2436
2437#endif /* FEATURE_EDITING */ 2437#endif /* !FEATURE_EDITING */
2438 2438
2439 2439
2440/* 2440/*
diff --git a/libbb/make_directory.c b/libbb/make_directory.c
index 1eb8a8a49..4bb79bdf6 100644
--- a/libbb/make_directory.c
+++ b/libbb/make_directory.c
@@ -93,7 +93,7 @@ int FAST_FUNC bb_make_directory(char *path, long mode, int flags)
93 if (mkdir(path, 0777) < 0) { 93 if (mkdir(path, 0777) < 0) {
94 /* If we failed for any other reason than the directory 94 /* If we failed for any other reason than the directory
95 * already exists, output a diagnostic and return -1 */ 95 * already exists, output a diagnostic and return -1 */
96 if (errno != EEXIST 96 if ((errno != EEXIST && errno != EISDIR)
97 || !(flags & FILEUTILS_RECUR) 97 || !(flags & FILEUTILS_RECUR)
98 || ((stat(path, &st) < 0) || !S_ISDIR(st.st_mode)) 98 || ((stat(path, &st) < 0) || !S_ISDIR(st.st_mode))
99 ) { 99 ) {
diff --git a/libbb/selinux_common.c b/libbb/selinux_common.c
index 7b5696754..2acb50e96 100644
--- a/libbb/selinux_common.c
+++ b/libbb/selinux_common.c
@@ -53,4 +53,3 @@ void FAST_FUNC selinux_preserve_fcontext(int fdesc)
53 setfscreatecon_or_die(context); 53 setfscreatecon_or_die(context);
54 freecon(context); 54 freecon(context);
55} 55}
56
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c
index 3e189c2d1..31a6d8e3c 100644
--- a/libbb/xfuncs_printf.c
+++ b/libbb/xfuncs_printf.c
@@ -401,8 +401,12 @@ int FAST_FUNC xsocket(int domain, int type, int protocol)
401 /* Hijack vaguely related config option */ 401 /* Hijack vaguely related config option */
402#if ENABLE_VERBOSE_RESOLUTION_ERRORS 402#if ENABLE_VERBOSE_RESOLUTION_ERRORS
403 const char *s = "INET"; 403 const char *s = "INET";
404# ifdef AF_PACKET
404 if (domain == AF_PACKET) s = "PACKET"; 405 if (domain == AF_PACKET) s = "PACKET";
406# endif
407# ifdef AF_NETLINK
405 if (domain == AF_NETLINK) s = "NETLINK"; 408 if (domain == AF_NETLINK) s = "NETLINK";
409# endif
406IF_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";) 410IF_FEATURE_IPV6(if (domain == AF_INET6) s = "INET6";)
407 bb_perror_msg_and_die("socket(AF_%s,%d,%d)", s, type, protocol); 411 bb_perror_msg_and_die("socket(AF_%s,%d,%d)", s, type, protocol);
408#else 412#else
diff --git a/loginutils/addgroup.c b/loginutils/addgroup.c
index 215e4a9e0..78ca22585 100644
--- a/loginutils/addgroup.c
+++ b/loginutils/addgroup.c
@@ -168,7 +168,6 @@ int addgroup_main(int argc UNUSED_PARAM, char **argv)
168 { 168 {
169 die_if_bad_username(argv[0]); 169 die_if_bad_username(argv[0]);
170 new_group(argv[0], gid); 170 new_group(argv[0], gid);
171
172 } 171 }
173 /* Reached only on success */ 172 /* Reached only on success */
174 return EXIT_SUCCESS; 173 return EXIT_SUCCESS;
diff --git a/loginutils/getty.c b/loginutils/getty.c
index a5e8e906a..7f04d33fb 100644
--- a/loginutils/getty.c
+++ b/loginutils/getty.c
@@ -282,10 +282,8 @@ static void termios_init(struct termios *tp, int speed, struct options *op)
282 * reads will be done in raw mode anyway. Errors will be dealt with 282 * reads will be done in raw mode anyway. Errors will be dealt with
283 * later on. 283 * later on.
284 */ 284 */
285#ifdef __linux__
286 /* flush input and output queues, important for modems! */ 285 /* flush input and output queues, important for modems! */
287 ioctl(0, TCFLSH, TCIOFLUSH); /* tcflush(0, TCIOFLUSH)? - same */ 286 tcflush(0, TCIOFLUSH);
288#endif
289 ispeed = ospeed = speed; 287 ispeed = ospeed = speed;
290 if (speed == B0) { 288 if (speed == B0) {
291 /* Speed was specified as "0" on command line. 289 /* Speed was specified as "0" on command line.
@@ -299,10 +297,13 @@ static void termios_init(struct termios *tp, int speed, struct options *op)
299 cfsetispeed(tp, ispeed); 297 cfsetispeed(tp, ispeed);
300 cfsetospeed(tp, ospeed); 298 cfsetospeed(tp, ospeed);
301 299
302 tp->c_iflag = tp->c_lflag = tp->c_line = 0; 300 tp->c_iflag = tp->c_lflag = 0;
303 tp->c_oflag = OPOST | ONLCR; 301 tp->c_oflag = OPOST | ONLCR;
304 tp->c_cc[VMIN] = 1; 302 tp->c_cc[VMIN] = 1;
305 tp->c_cc[VTIME] = 0; 303 tp->c_cc[VTIME] = 0;
304#ifdef __linux__
305 tp->c_line = 0;
306#endif
306 307
307 /* Optionally enable hardware flow control */ 308 /* Optionally enable hardware flow control */
308#ifdef CRTSCTS 309#ifdef CRTSCTS
@@ -360,10 +361,8 @@ static void auto_baud(char *buf, unsigned size_buf, struct termios *tp)
360 for (bp = buf; bp < buf + nread; bp++) { 361 for (bp = buf; bp < buf + nread; bp++) {
361 if (isdigit(*bp)) { 362 if (isdigit(*bp)) {
362 speed = bcode(bp); 363 speed = bcode(bp);
363 if (speed > 0) { 364 if (speed > 0)
364 tp->c_cflag &= ~CBAUD; 365 cfsetspeed(tp, speed);
365 tp->c_cflag |= speed;
366 }
367 break; 366 break;
368 } 367 }
369 } 368 }
@@ -417,7 +416,7 @@ static char *get_logname(char *logname, unsigned size_logname,
417 416
418 /* Flush pending input (esp. after parsing or switching the baud rate). */ 417 /* Flush pending input (esp. after parsing or switching the baud rate). */
419 sleep(1); 418 sleep(1);
420 ioctl(0, TCFLSH, TCIFLUSH); /* tcflush(0, TCIOFLUSH)? - same */ 419 tcflush(0, TCIOFLUSH);
421 420
422 /* Prompt for and read a login name. */ 421 /* Prompt for and read a login name. */
423 logname[0] = '\0'; 422 logname[0] = '\0';
@@ -526,7 +525,9 @@ static void termios_final(struct options *op, struct termios *tp, struct chardat
526 tp->c_cc[VQUIT] = DEF_QUIT; /* default quit */ 525 tp->c_cc[VQUIT] = DEF_QUIT; /* default quit */
527 tp->c_cc[VEOF] = DEF_EOF; /* default EOF character */ 526 tp->c_cc[VEOF] = DEF_EOF; /* default EOF character */
528 tp->c_cc[VEOL] = DEF_EOL; 527 tp->c_cc[VEOL] = DEF_EOL;
528#ifdef VSWTC
529 tp->c_cc[VSWTC] = DEF_SWITCH; /* default switch character */ 529 tp->c_cc[VSWTC] = DEF_SWITCH; /* default switch character */
530#endif
530 531
531 /* Account for special characters seen in input. */ 532 /* Account for special characters seen in input. */
532 if (cp->eol == CR) { 533 if (cp->eol == CR) {
@@ -572,8 +573,8 @@ static void termios_final(struct options *op, struct termios *tp, struct chardat
572#endif 573#endif
573 574
574 /* Finally, make the new settings effective */ 575 /* Finally, make the new settings effective */
575 /* It's tcsetattr_stdin_TCSANOW() + error check */ 576 if (tcsetattr_stdin_TCSANOW(tp) < 0)
576 ioctl_or_perror_and_die(0, TCSETS, tp, "%s: TCSETS", op->tty); 577 bb_perror_msg_and_die("%s: tcsetattr", op->tty);
577} 578}
578 579
579int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 580int getty_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
@@ -650,8 +651,8 @@ int getty_main(int argc UNUSED_PARAM, char **argv)
650 * by patching the SunOS kernel variable "zsadtrlow" to a larger value; 651 * by patching the SunOS kernel variable "zsadtrlow" to a larger value;
651 * 5 seconds seems to be a good value. 652 * 5 seconds seems to be a good value.
652 */ 653 */
653 /* tcgetattr() + error check */ 654 if (tcgetattr(0, &termios) < 0)
654 ioctl_or_perror_and_die(0, TCGETS, &termios, "%s: TCGETS", options.tty); 655 bb_perror_msg_and_die("%s: tcgetattr", options.tty);
655 656
656 pid = getpid(); 657 pid = getpid();
657#ifdef __linux__ 658#ifdef __linux__
diff --git a/loginutils/login.c b/loginutils/login.c
index 88ed0af78..10012486f 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -264,7 +264,7 @@ int login_main(int argc UNUSED_PARAM, char **argv)
264 264
265 while (1) { 265 while (1) {
266 /* flush away any type-ahead (as getty does) */ 266 /* flush away any type-ahead (as getty does) */
267 ioctl(0, TCFLSH, TCIFLUSH); 267 tcflush(0, TCIFLUSH);
268 268
269 if (!username[0]) 269 if (!username[0])
270 get_username_or_die(username, sizeof(username)); 270 get_username_or_die(username, sizeof(username));
diff --git a/loginutils/vlock.c b/loginutils/vlock.c
index 85f489c22..59aeb54e8 100644
--- a/loginutils/vlock.c
+++ b/loginutils/vlock.c
@@ -15,9 +15,11 @@
15/* Fixed by Erik Andersen to do passwords the tinylogin way... 15/* Fixed by Erik Andersen to do passwords the tinylogin way...
16 * It now works with md5, sha1, etc passwords. */ 16 * It now works with md5, sha1, etc passwords. */
17 17
18#include <sys/vt.h>
19#include "libbb.h" 18#include "libbb.h"
20 19
20#ifdef __linux__
21#include <sys/vt.h>
22
21static void release_vt(int signo UNUSED_PARAM) 23static void release_vt(int signo UNUSED_PARAM)
22{ 24{
23 /* If -a, param is 0, which means: 25 /* If -a, param is 0, which means:
@@ -30,14 +32,17 @@ static void acquire_vt(int signo UNUSED_PARAM)
30 /* ACK to kernel that switch to console is successful */ 32 /* ACK to kernel that switch to console is successful */
31 ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ); 33 ioctl(STDIN_FILENO, VT_RELDISP, VT_ACKACQ);
32} 34}
35#endif
33 36
34int vlock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 37int vlock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
35int vlock_main(int argc UNUSED_PARAM, char **argv) 38int vlock_main(int argc UNUSED_PARAM, char **argv)
36{ 39{
40#ifdef __linux__
37 struct vt_mode vtm; 41 struct vt_mode vtm;
42 struct vt_mode ovtm;
43#endif
38 struct termios term; 44 struct termios term;
39 struct termios oterm; 45 struct termios oterm;
40 struct vt_mode ovtm;
41 struct passwd *pw; 46 struct passwd *pw;
42 47
43 pw = xgetpwuid(getuid()); 48 pw = xgetpwuid(getuid());
@@ -55,6 +60,7 @@ int vlock_main(int argc UNUSED_PARAM, char **argv)
55 + (1 << SIGINT ) 60 + (1 << SIGINT )
56 , SIG_IGN); 61 , SIG_IGN);
57 62
63#ifdef __linux__
58 /* We will use SIGUSRx for console switch control: */ 64 /* We will use SIGUSRx for console switch control: */
59 /* 1: set handlers */ 65 /* 1: set handlers */
60 signal_SA_RESTART_empty_mask(SIGUSR1, release_vt); 66 signal_SA_RESTART_empty_mask(SIGUSR1, release_vt);
@@ -62,12 +68,14 @@ int vlock_main(int argc UNUSED_PARAM, char **argv)
62 /* 2: unmask them */ 68 /* 2: unmask them */
63 sig_unblock(SIGUSR1); 69 sig_unblock(SIGUSR1);
64 sig_unblock(SIGUSR2); 70 sig_unblock(SIGUSR2);
71#endif
65 72
66 /* Revert stdin/out to our controlling tty 73 /* Revert stdin/out to our controlling tty
67 * (or die if we have none) */ 74 * (or die if we have none) */
68 xmove_fd(xopen(CURRENT_TTY, O_RDWR), STDIN_FILENO); 75 xmove_fd(xopen(CURRENT_TTY, O_RDWR), STDIN_FILENO);
69 xdup2(STDIN_FILENO, STDOUT_FILENO); 76 xdup2(STDIN_FILENO, STDOUT_FILENO);
70 77
78#ifdef __linux__
71 xioctl(STDIN_FILENO, VT_GETMODE, &vtm); 79 xioctl(STDIN_FILENO, VT_GETMODE, &vtm);
72 ovtm = vtm; 80 ovtm = vtm;
73 /* "console switches are controlled by us, not kernel!" */ 81 /* "console switches are controlled by us, not kernel!" */
@@ -75,6 +83,7 @@ int vlock_main(int argc UNUSED_PARAM, char **argv)
75 vtm.relsig = SIGUSR1; 83 vtm.relsig = SIGUSR1;
76 vtm.acqsig = SIGUSR2; 84 vtm.acqsig = SIGUSR2;
77 ioctl(STDIN_FILENO, VT_SETMODE, &vtm); 85 ioctl(STDIN_FILENO, VT_SETMODE, &vtm);
86#endif
78 87
79 tcgetattr(STDIN_FILENO, &oterm); 88 tcgetattr(STDIN_FILENO, &oterm);
80 term = oterm; 89 term = oterm;
@@ -95,7 +104,9 @@ int vlock_main(int argc UNUSED_PARAM, char **argv)
95 puts("Password incorrect"); 104 puts("Password incorrect");
96 } while (1); 105 } while (1);
97 106
107#ifdef __linux__
98 ioctl(STDIN_FILENO, VT_SETMODE, &ovtm); 108 ioctl(STDIN_FILENO, VT_SETMODE, &ovtm);
109#endif
99 tcsetattr_stdin_TCSANOW(&oterm); 110 tcsetattr_stdin_TCSANOW(&oterm);
100 fflush_stdout_and_exit(EXIT_SUCCESS); 111 fflush_stdout_and_exit(EXIT_SUCCESS);
101} 112}
diff --git a/miscutils/Config.src b/miscutils/Config.src
index 2f7c50271..cadaabb65 100644
--- a/miscutils/Config.src
+++ b/miscutils/Config.src
@@ -10,6 +10,7 @@ INSERT
10config ADJTIMEX 10config ADJTIMEX
11 bool "adjtimex" 11 bool "adjtimex"
12 default y 12 default y
13 depends on PLATFORM_LINUX
13 help 14 help
14 Adjtimex reads and optionally sets adjustment parameters for 15 Adjtimex reads and optionally sets adjustment parameters for
15 the Linux clock adjustment algorithm. 16 the Linux clock adjustment algorithm.
@@ -24,6 +25,7 @@ config BBCONFIG
24config BEEP 25config BEEP
25 bool "beep" 26 bool "beep"
26 default y 27 default y
28 depends on PLATFORM_LINUX
27 help 29 help
28 The beep applets beeps in a given freq/Hz. 30 The beep applets beeps in a given freq/Hz.
29 31
@@ -180,6 +182,7 @@ config FEATURE_DC_LIBM
180config DEVFSD 182config DEVFSD
181 bool "devfsd (obsolete)" 183 bool "devfsd (obsolete)"
182 default n 184 default n
185 depends on PLATFORM_LINUX
183 select FEATURE_SYSLOG 186 select FEATURE_SYSLOG
184 help 187 help
185 This is deprecated and should NOT be used anymore. 188 This is deprecated and should NOT be used anymore.
@@ -223,6 +226,7 @@ config DEVFSD_VERBOSE
223config FEATURE_DEVFS 226config FEATURE_DEVFS
224 bool "Use devfs names for all devices (obsolete)" 227 bool "Use devfs names for all devices (obsolete)"
225 default n 228 default n
229 depends on PLATFORM_LINUX
226 help 230 help
227 This is obsolete and should NOT be used anymore. 231 This is obsolete and should NOT be used anymore.
228 Use linux >= 2.6 (optionally with hotplug) and mdev instead! 232 Use linux >= 2.6 (optionally with hotplug) and mdev instead!
@@ -242,6 +246,7 @@ config DEVMEM
242config EJECT 246config EJECT
243 bool "eject" 247 bool "eject"
244 default y 248 default y
249 depends on PLATFORM_LINUX
245 help 250 help
246 Used to eject cdroms. (defaults to /dev/cdrom) 251 Used to eject cdroms. (defaults to /dev/cdrom)
247 252
@@ -256,6 +261,7 @@ config FEATURE_EJECT_SCSI
256config FBSPLASH 261config FBSPLASH
257 bool "fbsplash" 262 bool "fbsplash"
258 default y 263 default y
264 depends on PLATFORM_LINUX
259 help 265 help
260 Shows splash image and progress bar on framebuffer device. 266 Shows splash image and progress bar on framebuffer device.
261 Can be used during boot phase of an embedded device. ~2kb. 267 Can be used during boot phase of an embedded device. ~2kb.
@@ -305,6 +311,7 @@ config FLASH_ERASEALL
305config IONICE 311config IONICE
306 bool "ionice" 312 bool "ionice"
307 default y 313 default y
314 depends on PLATFORM_LINUX
308 help 315 help
309 Set/set program io scheduling class and priority 316 Set/set program io scheduling class and priority
310 Requires kernel >= 2.6.13 317 Requires kernel >= 2.6.13
@@ -405,11 +412,12 @@ config FEATURE_LESS_LINENUMS
405 default y 412 default y
406 depends on FEATURE_LESS_DASHCMD 413 depends on FEATURE_LESS_DASHCMD
407 help 414 help
408 Enable "-N" command. 415 Enables "-N" command.
409 416
410config HDPARM 417config HDPARM
411 bool "hdparm" 418 bool "hdparm"
412 default y 419 default y
420 depends on PLATFORM_LINUX
413 help 421 help
414 Get/Set hard drive parameters. Primarily intended for ATA 422 Get/Set hard drive parameters. Primarily intended for ATA
415 drives. Adds about 13k (or around 30k if you enable the 423 drives. Adds about 13k (or around 30k if you enable the
@@ -471,15 +479,15 @@ config MAKEDEVS
471 help 479 help
472 'makedevs' is a utility used to create a batch of devices with 480 'makedevs' is a utility used to create a batch of devices with
473 one command. 481 one command.
474 . 482
475 There are two choices for command line behaviour, the interface 483 There are two choices for command line behaviour, the interface
476 as used by LEAF/Linux Router Project, or a device table file. 484 as used by LEAF/Linux Router Project, or a device table file.
477 . 485
478 'leaf' is traditionally what busybox follows, it allows multiple 486 'leaf' is traditionally what busybox follows, it allows multiple
479 devices of a particluar type to be created per command. 487 devices of a particluar type to be created per command.
480 e.g. /dev/hda[0-9] 488 e.g. /dev/hda[0-9]
481 Device properties are passed as command line arguments. 489 Device properties are passed as command line arguments.
482 . 490
483 'table' reads device properties from a file or stdin, allowing 491 'table' reads device properties from a file or stdin, allowing
484 a batch of unrelated devices to be made with one command. 492 a batch of unrelated devices to be made with one command.
485 User/group names are allowed as an alternative to uid/gid. 493 User/group names are allowed as an alternative to uid/gid.
@@ -526,6 +534,7 @@ config MT
526config RAIDAUTORUN 534config RAIDAUTORUN
527 bool "raidautorun" 535 bool "raidautorun"
528 default y 536 default y
537 depends on PLATFORM_LINUX
529 help 538 help
530 raidautorun tells the kernel md driver to 539 raidautorun tells the kernel md driver to
531 search and start RAID arrays. 540 search and start RAID arrays.
@@ -533,7 +542,7 @@ config RAIDAUTORUN
533config READAHEAD 542config READAHEAD
534 bool "readahead" 543 bool "readahead"
535 default y 544 default y
536 depends on LFS 545 depends on LFS && PLATFORM_LINUX
537 help 546 help
538 Preload the files listed on the command line into RAM cache so that 547 Preload the files listed on the command line into RAM cache so that
539 subsequent reads on these files will not block on disk I/O. 548 subsequent reads on these files will not block on disk I/O.
@@ -550,6 +559,7 @@ config READAHEAD
550config RFKILL 559config RFKILL
551 bool "rfkill" 560 bool "rfkill"
552 default n # doesn't build on Ubuntu 9.04 561 default n # doesn't build on Ubuntu 9.04
562 depends on PLATFORM_LINUX
553 help 563 help
554 Enable/disable wireless devices. 564 Enable/disable wireless devices.
555 565
@@ -570,6 +580,7 @@ config RUNLEVEL
570config RX 580config RX
571 bool "rx" 581 bool "rx"
572 default y 582 default y
583 depends on PLATFORM_LINUX
573 help 584 help
574 Receive files using the Xmodem protocol. 585 Receive files using the Xmodem protocol.
575 586
@@ -641,6 +652,7 @@ config WALL
641config WATCHDOG 652config WATCHDOG
642 bool "watchdog" 653 bool "watchdog"
643 default y 654 default y
655 depends on PLATFORM_LINUX
644 help 656 help
645 The watchdog utility is used with hardware or software watchdog 657 The watchdog utility is used with hardware or software watchdog
646 device drivers. It opens the specified watchdog device special file 658 device drivers. It opens the specified watchdog device special file
diff --git a/miscutils/conspy.c b/miscutils/conspy.c
index 509a0f271..a173d8efd 100644
--- a/miscutils/conspy.c
+++ b/miscutils/conspy.c
@@ -17,6 +17,7 @@
17//config:config CONSPY 17//config:config CONSPY
18//config: bool "conspy" 18//config: bool "conspy"
19//config: default n 19//config: default n
20//config: depends on PLATFORM_LINUX
20//config: help 21//config: help
21//config: A text-mode VNC like program for Linux virtual terminals. 22//config: A text-mode VNC like program for Linux virtual terminals.
22//config: example: conspy NUM shared access to console num 23//config: example: conspy NUM shared access to console num
diff --git a/miscutils/crond.c b/miscutils/crond.c
index 66110bb85..d028eb089 100644
--- a/miscutils/crond.c
+++ b/miscutils/crond.c
@@ -243,7 +243,6 @@ static void ParseField(char *user, char *ary, int modvalue, int off,
243 goto err; 243 goto err;
244 } 244 }
245 } while (n1 != n2); 245 } while (n1 != n2);
246
247 } 246 }
248 if (*ptr != ',') { 247 if (*ptr != ',') {
249 break; 248 break;
diff --git a/miscutils/dc.c b/miscutils/dc.c
index cb4b1e9b1..767d746e0 100644
--- a/miscutils/dc.c
+++ b/miscutils/dc.c
@@ -6,7 +6,39 @@
6#include "libbb.h" 6#include "libbb.h"
7#include <math.h> 7#include <math.h>
8 8
9/* Tiny RPN calculator, because "expr" didn't give me bitwise operations. */ 9//usage:#define dc_trivial_usage
10//usage: "EXPRESSION..."
11//usage:
12//usage:#define dc_full_usage "\n\n"
13//usage: "Tiny RPN calculator. Operations:\n"
14//usage: "+, add, -, sub, *, mul, /, div, %, mod, **, exp, and, or, not, eor,\n"
15//usage: "p - print top of the stack (without popping),\n"
16//usage: "f - print entire stack,\n"
17//usage: "o - pop the value and set output radix (must be 10, 16, 8 or 2).\n"
18//usage: "Examples: 'dc 2 2 add' -> 4, 'dc 8 8 * 2 2 + /' -> 16"
19//usage:
20//usage:#define dc_example_usage
21//usage: "$ dc 2 2 + p\n"
22//usage: "4\n"
23//usage: "$ dc 8 8 \\* 2 2 + / p\n"
24//usage: "16\n"
25//usage: "$ dc 0 1 and p\n"
26//usage: "0\n"
27//usage: "$ dc 0 1 or p\n"
28//usage: "1\n"
29//usage: "$ echo 72 9 div 8 mul p | dc\n"
30//usage: "64\n"
31
32#if 0
33typedef unsigned data_t;
34#define DATA_FMT ""
35#elif 0
36typedef unsigned long data_t;
37#define DATA_FMT "l"
38#else
39typedef unsigned long long data_t;
40#define DATA_FMT "ll"
41#endif
10 42
11 43
12struct globals { 44struct globals {
@@ -73,29 +105,29 @@ static void divide(void)
73 105
74static void mod(void) 106static void mod(void)
75{ 107{
76 unsigned d = pop(); 108 data_t d = pop();
77 109
78 push((unsigned) pop() % d); 110 push((data_t) pop() % d);
79} 111}
80 112
81static void and(void) 113static void and(void)
82{ 114{
83 push((unsigned) pop() & (unsigned) pop()); 115 push((data_t) pop() & (data_t) pop());
84} 116}
85 117
86static void or(void) 118static void or(void)
87{ 119{
88 push((unsigned) pop() | (unsigned) pop()); 120 push((data_t) pop() | (data_t) pop());
89} 121}
90 122
91static void eor(void) 123static void eor(void)
92{ 124{
93 push((unsigned) pop() ^ (unsigned) pop()); 125 push((data_t) pop() ^ (data_t) pop());
94} 126}
95 127
96static void not(void) 128static void not(void)
97{ 129{
98 push(~(unsigned) pop()); 130 push(~(data_t) pop());
99} 131}
100 132
101static void set_output_base(void) 133static void set_output_base(void)
@@ -112,25 +144,30 @@ static void set_output_base(void)
112 144
113static void print_base(double print) 145static void print_base(double print)
114{ 146{
115 unsigned x, i; 147 data_t x, i;
116 148
149 x = (data_t) print;
117 if (base == 10) { 150 if (base == 10) {
118 printf("%g\n", print); 151 if (x == print) /* exactly representable as unsigned integer */
152 printf("%"DATA_FMT"u\n", x);
153 else
154 printf("%g\n", print);
119 return; 155 return;
120 } 156 }
121 157
122 x = (unsigned)print;
123 switch (base) { 158 switch (base) {
124 case 16: 159 case 16:
125 printf("%x\n", x); 160 printf("%"DATA_FMT"x\n", x);
126 break; 161 break;
127 case 8: 162 case 8:
128 printf("%o\n", x); 163 printf("%"DATA_FMT"o\n", x);
129 break; 164 break;
130 default: /* base 2 */ 165 default: /* base 2 */
131 i = (unsigned)INT_MAX + 1; 166 i = MAXINT(data_t) - (MAXINT(data_t) >> 1);
167 /* i is 100000...00000 */
132 do { 168 do {
133 if (x & i) break; 169 if (x & i)
170 break;
134 i >>= 1; 171 i >>= 1;
135 } while (i > 1); 172 } while (i > 1);
136 do { 173 do {
diff --git a/miscutils/hdparm.c b/miscutils/hdparm.c
index 9738620fd..236b1749c 100644
--- a/miscutils/hdparm.c
+++ b/miscutils/hdparm.c
@@ -730,8 +730,8 @@ static void identify(uint16_t *val)
730 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) { 730 if (val[MINOR] && (val[MINOR] <= MINOR_MAX)) {
731 if (like_std < 3) like_std = 3; 731 if (like_std < 3) like_std = 3;
732 std = actual_ver[val[MINOR]]; 732 std = actual_ver[val[MINOR]];
733 if (std) printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR])); 733 if (std)
734 734 printf("\n\tUsed: %s ", nth_string(minor_str, val[MINOR]));
735 } 735 }
736 /* looks like when they up-issue the std, they obsolete one; 736 /* looks like when they up-issue the std, they obsolete one;
737 * thus, only the newest 4 issues need be supported. (That's 737 * thus, only the newest 4 issues need be supported. (That's
diff --git a/miscutils/ubi_attach_detach.c b/miscutils/ubi_attach_detach.c
index 7b92a8afc..0d63a10d5 100644
--- a/miscutils/ubi_attach_detach.c
+++ b/miscutils/ubi_attach_detach.c
@@ -12,12 +12,14 @@
12//config:config UBIATTACH 12//config:config UBIATTACH
13//config: bool "ubiattach" 13//config: bool "ubiattach"
14//config: default n 14//config: default n
15//config: depends on PLATFORM_LINUX
15//config: help 16//config: help
16//config: Attach MTD device to an UBI device. 17//config: Attach MTD device to an UBI device.
17//config: 18//config:
18//config:config UBIDETACH 19//config:config UBIDETACH
19//config: bool "ubidetach" 20//config: bool "ubidetach"
20//config: default n 21//config: default n
22//config: depends on PLATFORM_LINUX
21//config: help 23//config: help
22//config: Detach MTD device from an UBI device. 24//config: Detach MTD device from an UBI device.
23 25
diff --git a/modutils/Config.src b/modutils/Config.src
index a7dcb3ab3..4191d29f2 100644
--- a/modutils/Config.src
+++ b/modutils/Config.src
@@ -4,6 +4,7 @@
4# 4#
5 5
6menu "Linux Module Utilities" 6menu "Linux Module Utilities"
7depends on PLATFORM_LINUX
7 8
8INSERT 9INSERT
9 10
diff --git a/modutils/depmod.c b/modutils/depmod.c
index c734f142b..694f9ea5a 100644
--- a/modutils/depmod.c
+++ b/modutils/depmod.c
@@ -28,16 +28,6 @@ typedef struct module_info {
28 struct module_info *dnext, *dprev; 28 struct module_info *dnext, *dprev;
29} module_info; 29} module_info;
30 30
31enum {
32 ARG_a = (1<<0), /* All modules, ignore mods in argv */
33 ARG_A = (1<<1), /* Only emit .ko that are newer than modules.dep file */
34 ARG_b = (1<<2), /* base directory when modules are in staging area */
35 ARG_e = (1<<3), /* with -F, print unresolved symbols */
36 ARG_F = (1<<4), /* System.map that contains the symbols */
37 ARG_n = (1<<5), /* dry-run, print to stdout only */
38 ARG_r = (1<<6) /* Compat dummy. Linux Makefile uses it */
39};
40
41static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM, 31static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM,
42 void *data, int depth UNUSED_PARAM) 32 void *data, int depth UNUSED_PARAM)
43{ 33{
@@ -58,7 +48,7 @@ static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARA
58 *first = info; 48 *first = info;
59 49
60 info->dnext = info->dprev = info; 50 info->dnext = info->dprev = info;
61 info->name = xasprintf("/%s", fname); 51 info->name = xstrdup(fname + 2); /* skip "./" */
62 info->modname = xstrdup(filename2modname(fname, modname)); 52 info->modname = xstrdup(filename2modname(fname, modname));
63 for (ptr = image; ptr < image + len - 10; ptr++) { 53 for (ptr = image; ptr < image + len - 10; ptr++) {
64 if (strncmp(ptr, "depends=", 8) == 0) { 54 if (strncmp(ptr, "depends=", 8) == 0) {
@@ -134,10 +124,44 @@ static void xfreopen_write(const char *file, FILE *f)
134 bb_perror_msg_and_die("can't open '%s'", file); 124 bb_perror_msg_and_die("can't open '%s'", file);
135} 125}
136 126
127/* Usage:
128 * [-aAenv] [-C FILE or DIR] [-b BASE] [-F System.map] [VERSION] [MODFILES]...
129 * -a --all
130 * Probe all modules. Default if no MODFILES.
131 * -A --quick
132 * Check modules.dep's mtime against module files' mtimes.
133 * -b --basedir BASE
134 * Use $BASE/lib/modules/VERSION
135 * -C --config FILE or DIR
136 * Path to /etc/depmod.conf or /etc/depmod.d/
137 * -e --errsyms
138 * When combined with the -F option, this reports any symbols which
139 * which are not supplied by other modules or kernel.
140 * -F --filesyms System.map
141 * -n --dry-run
142 * Print modules.dep etc to standard output
143 * -v --verbose
144 * Print to stdout all the symbols each module depends on
145 * and the module's file name which provides that symbol.
146 * -r No-op
147 *
148 * So far we only support: [-rn] [-b BASE] [VERSION] [MODFILES]...
149 * -aAeF are accepted but ignored. -vC are not accepted.
150 */
151enum {
152 //OPT_a = (1 << 0), /* All modules, ignore mods in argv */
153 //OPT_A = (1 << 1), /* Only emit .ko that are newer than modules.dep file */
154 OPT_b = (1 << 2), /* base directory when modules are in staging area */
155 //OPT_e = (1 << 3), /* with -F, print unresolved symbols */
156 //OPT_F = (1 << 4), /* System.map that contains the symbols */
157 OPT_n = (1 << 5), /* dry-run, print to stdout only */
158 OPT_r = (1 << 6) /* Compat dummy. Linux Makefile uses it */
159};
160
137int depmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 161int depmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
138int depmod_main(int argc UNUSED_PARAM, char **argv) 162int depmod_main(int argc UNUSED_PARAM, char **argv)
139{ 163{
140 module_info *modules = NULL, *m, *dep; 164 module_info *modules, *m, *dep;
141 const char *moddir_base = "/"; 165 const char *moddir_base = "/";
142 char *moddir, *version; 166 char *moddir, *version;
143 struct utsname uts; 167 struct utsname uts;
@@ -152,36 +176,30 @@ int depmod_main(int argc UNUSED_PARAM, char **argv)
152 /* If a version is provided, then that kernel version's module directory 176 /* If a version is provided, then that kernel version's module directory
153 * is used, rather than the current kernel version (as returned by 177 * is used, rather than the current kernel version (as returned by
154 * "uname -r"). */ 178 * "uname -r"). */
155 if (*argv && sscanf(*argv, "%d.%d.%d", &tmp, &tmp, &tmp) == 3) { 179 if (*argv && sscanf(*argv, "%u.%u.%u", &tmp, &tmp, &tmp) == 3) {
156 version = *argv++; 180 version = *argv++;
157 } else { 181 } else {
158 uname(&uts); 182 uname(&uts);
159 version = uts.release; 183 version = uts.release;
160 } 184 }
161 moddir = concat_path_file(&CONFIG_DEFAULT_MODULES_DIR[1], version); 185 moddir = concat_path_file(&CONFIG_DEFAULT_MODULES_DIR[1], version);
186 xchdir(moddir);
187 if (ENABLE_FEATURE_CLEAN_UP)
188 free(moddir);
162 189
163 /* Scan modules */ 190 /* Scan modules */
191 modules = NULL;
164 if (*argv) { 192 if (*argv) {
165 char *modfile;
166 struct stat sb;
167 do { 193 do {
168 modfile = concat_path_file(moddir, *argv); 194 parse_module(*argv, /*sb (unused):*/ NULL, &modules, 0);
169 xstat(modfile, &sb); 195 } while (*++argv);
170 parse_module(modfile, &sb, &modules, 0);
171 free(modfile);
172 } while (*(++argv));
173 } else { 196 } else {
174 recursive_action(moddir, ACTION_RECURSE, 197 recursive_action(".", ACTION_RECURSE,
175 parse_module, NULL, &modules, 0); 198 parse_module, NULL, &modules, 0);
176 } 199 }
177 200
178 /* Prepare for writing out the dep files */
179 xchdir(moddir);
180 if (ENABLE_FEATURE_CLEAN_UP)
181 free(moddir);
182
183 /* Generate dependency and alias files */ 201 /* Generate dependency and alias files */
184 if (!(option_mask32 & ARG_n)) 202 if (!(option_mask32 & OPT_n))
185 xfreopen_write(CONFIG_DEFAULT_DEPMOD_FILE, stdout); 203 xfreopen_write(CONFIG_DEFAULT_DEPMOD_FILE, stdout);
186 for (m = modules; m != NULL; m = m->next) { 204 for (m = modules; m != NULL; m = m->next) {
187 printf("%s:", m->name); 205 printf("%s:", m->name);
@@ -200,7 +218,7 @@ int depmod_main(int argc UNUSED_PARAM, char **argv)
200 } 218 }
201 219
202#if ENABLE_FEATURE_MODUTILS_ALIAS 220#if ENABLE_FEATURE_MODUTILS_ALIAS
203 if (!(option_mask32 & ARG_n)) 221 if (!(option_mask32 & OPT_n))
204 xfreopen_write("modules.alias", stdout); 222 xfreopen_write("modules.alias", stdout);
205 for (m = modules; m != NULL; m = m->next) { 223 for (m = modules; m != NULL; m = m->next) {
206 const char *fname = bb_basename(m->name); 224 const char *fname = bb_basename(m->name);
@@ -218,7 +236,7 @@ int depmod_main(int argc UNUSED_PARAM, char **argv)
218 } 236 }
219#endif 237#endif
220#if ENABLE_FEATURE_MODUTILS_SYMBOLS 238#if ENABLE_FEATURE_MODUTILS_SYMBOLS
221 if (!(option_mask32 & ARG_n)) 239 if (!(option_mask32 & OPT_n))
222 xfreopen_write("modules.symbols", stdout); 240 xfreopen_write("modules.symbols", stdout);
223 for (m = modules; m != NULL; m = m->next) { 241 for (m = modules; m != NULL; m = m->next) {
224 const char *fname = bb_basename(m->name); 242 const char *fname = bb_basename(m->name);
diff --git a/networking/Config.src b/networking/Config.src
index 449436247..8604c53e9 100644
--- a/networking/Config.src
+++ b/networking/Config.src
@@ -51,18 +51,21 @@ config VERBOSE_RESOLUTION_ERRORS
51config ARP 51config ARP
52 bool "arp" 52 bool "arp"
53 default y 53 default y
54 depends on PLATFORM_LINUX
54 help 55 help
55 Manipulate the system ARP cache. 56 Manipulate the system ARP cache.
56 57
57config ARPING 58config ARPING
58 bool "arping" 59 bool "arping"
59 default y 60 default y
61 depends on PLATFORM_LINUX
60 help 62 help
61 Ping hosts by ARP packets. 63 Ping hosts by ARP packets.
62 64
63config BRCTL 65config BRCTL
64 bool "brctl" 66 bool "brctl"
65 default y 67 default y
68 depends on PLATFORM_LINUX
66 help 69 help
67 Manage ethernet bridges. 70 Manage ethernet bridges.
68 Supports addbr/delbr and addif/delif. 71 Supports addbr/delbr and addif/delif.
@@ -95,6 +98,7 @@ config DNSD
95config ETHER_WAKE 98config ETHER_WAKE
96 bool "ether-wake" 99 bool "ether-wake"
97 default y 100 default y
101 depends on PLATFORM_LINUX
98 help 102 help
99 Send a magic packet to wake up sleeping machines. 103 Send a magic packet to wake up sleeping machines.
100 104
@@ -266,9 +270,18 @@ config FEATURE_HTTPD_PROXY
266 Then a request to /url/myfile will be forwarded to 270 Then a request to /url/myfile will be forwarded to
267 http://hostname[:port]/new/path/myfile. 271 http://hostname[:port]/new/path/myfile.
268 272
273config FEATURE_HTTPD_GZIP
274 bool "Support for GZIP content encoding"
275 default y
276 depends on HTTPD
277 help
278 Makes httpd send files using GZIP content encoding if the
279 client supports it and a pre-compressed <file>.gz exists.
280
269config IFCONFIG 281config IFCONFIG
270 bool "ifconfig" 282 bool "ifconfig"
271 default y 283 default y
284 depends on PLATFORM_LINUX
272 help 285 help
273 Ifconfig is used to configure the kernel-resident network interfaces. 286 Ifconfig is used to configure the kernel-resident network interfaces.
274 287
@@ -316,6 +329,7 @@ config FEATURE_IFCONFIG_BROADCAST_PLUS
316config IFENSLAVE 329config IFENSLAVE
317 bool "ifenslave" 330 bool "ifenslave"
318 default y 331 default y
332 depends on PLATFORM_LINUX
319 help 333 help
320 Userspace application to bind several interfaces 334 Userspace application to bind several interfaces
321 to a logical interface (use with kernel bonding driver). 335 to a logical interface (use with kernel bonding driver).
@@ -323,6 +337,7 @@ config IFENSLAVE
323config IFPLUGD 337config IFPLUGD
324 bool "ifplugd" 338 bool "ifplugd"
325 default y 339 default y
340 depends on PLATFORM_LINUX
326 help 341 help
327 Network interface plug detection daemon. 342 Network interface plug detection daemon.
328 343
@@ -364,7 +379,7 @@ config FEATURE_IFUPDOWN_IP
364config FEATURE_IFUPDOWN_IP_BUILTIN 379config FEATURE_IFUPDOWN_IP_BUILTIN
365 bool "Use busybox ip applet" 380 bool "Use busybox ip applet"
366 default y 381 default y
367 depends on FEATURE_IFUPDOWN_IP 382 depends on FEATURE_IFUPDOWN_IP && PLATFORM_LINUX
368 select IP 383 select IP
369 select FEATURE_IP_ADDRESS 384 select FEATURE_IP_ADDRESS
370 select FEATURE_IP_LINK 385 select FEATURE_IP_LINK
@@ -483,6 +498,7 @@ config FEATURE_INETD_RPC
483config IP 498config IP
484 bool "ip" 499 bool "ip"
485 default y 500 default y
501 depends on PLATFORM_LINUX
486 help 502 help
487 The "ip" applet is a TCP/IP interface configuration and routing 503 The "ip" applet is a TCP/IP interface configuration and routing
488 utility. You generally don't need "ip" to use busybox with 504 utility. You generally don't need "ip" to use busybox with
@@ -598,6 +614,7 @@ config FEATURE_IPCALC_LONG_OPTIONS
598config NAMEIF 614config NAMEIF
599 bool "nameif" 615 bool "nameif"
600 default y 616 default y
617 depends on PLATFORM_LINUX
601 select FEATURE_SYSLOG 618 select FEATURE_SYSLOG
602 help 619 help
603 nameif is used to rename network interface by its MAC address. 620 nameif is used to rename network interface by its MAC address.
@@ -626,6 +643,7 @@ config FEATURE_NAMEIF_EXTENDED
626config NETSTAT 643config NETSTAT
627 bool "netstat" 644 bool "netstat"
628 default y 645 default y
646 depends on PLATFORM_LINUX
629 help 647 help
630 netstat prints information about the Linux networking subsystem. 648 netstat prints information about the Linux networking subsystem.
631 649
@@ -654,6 +672,7 @@ config NSLOOKUP
654config NTPD 672config NTPD
655 bool "ntpd" 673 bool "ntpd"
656 default y 674 default y
675 depends on PLATFORM_LINUX
657 help 676 help
658 The NTP client/server daemon. 677 The NTP client/server daemon.
659 678
@@ -668,6 +687,7 @@ config FEATURE_NTPD_SERVER
668config PING 687config PING
669 bool "ping" 688 bool "ping"
670 default y 689 default y
690 depends on PLATFORM_LINUX
671 help 691 help
672 ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to 692 ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to
673 elicit an ICMP ECHO_RESPONSE from a host or gateway. 693 elicit an ICMP ECHO_RESPONSE from a host or gateway.
@@ -696,12 +716,14 @@ config PSCAN
696config ROUTE 716config ROUTE
697 bool "route" 717 bool "route"
698 default y 718 default y
719 depends on PLATFORM_LINUX
699 help 720 help
700 Route displays or manipulates the kernel's IP routing tables. 721 Route displays or manipulates the kernel's IP routing tables.
701 722
702config SLATTACH 723config SLATTACH
703 bool "slattach" 724 bool "slattach"
704 default y 725 default y
726 depends on PLATFORM_LINUX
705 help 727 help
706 slattach is a small utility to attach network interfaces to serial 728 slattach is a small utility to attach network interfaces to serial
707 lines. 729 lines.
@@ -888,6 +910,7 @@ config TFTP_DEBUG
888config TRACEROUTE 910config TRACEROUTE
889 bool "traceroute" 911 bool "traceroute"
890 default y 912 default y
913 depends on PLATFORM_LINUX
891 help 914 help
892 Utility to trace the route of IP packets. 915 Utility to trace the route of IP packets.
893 916
@@ -924,6 +947,7 @@ config FEATURE_TRACEROUTE_USE_ICMP
924config TUNCTL 947config TUNCTL
925 bool "tunctl" 948 bool "tunctl"
926 default y 949 default y
950 depends on PLATFORM_LINUX
927 help 951 help
928 tunctl creates or deletes tun devices. 952 tunctl creates or deletes tun devices.
929 953
@@ -956,6 +980,7 @@ config UDPSVD
956config VCONFIG 980config VCONFIG
957 bool "vconfig" 981 bool "vconfig"
958 default y 982 default y
983 depends on PLATFORM_LINUX
959 help 984 help
960 Creates, removes, and configures VLAN interfaces 985 Creates, removes, and configures VLAN interfaces
961 986
@@ -990,6 +1015,7 @@ config FEATURE_WGET_LONG_OPTIONS
990config ZCIP 1015config ZCIP
991 bool "zcip" 1016 bool "zcip"
992 default y 1017 default y
1018 depends on PLATFORM_LINUX
993 select FEATURE_SYSLOG 1019 select FEATURE_SYSLOG
994 help 1020 help
995 ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927. 1021 ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927.
diff --git a/networking/httpd.c b/networking/httpd.c
index 8ad7e88b1..3fea3f04c 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -5,23 +5,20 @@
5 * Copyright (C) 2002,2003 Glenn Engel <glenne@engel.org> 5 * Copyright (C) 2002,2003 Glenn Engel <glenne@engel.org>
6 * Copyright (C) 2003-2006 Vladimir Oleynik <dzo@simtreas.ru> 6 * Copyright (C) 2003-2006 Vladimir Oleynik <dzo@simtreas.ru>
7 * 7 *
8 * simplify patch stolen from libbb without using strdup
9 *
10 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
11 * 9 *
12 ***************************************************************************** 10 *****************************************************************************
13 * 11 *
14 * Typical usage: 12 * Typical usage:
15 * for non root user 13 * For non root user:
16 * httpd -p 8080 -h $HOME/public_html 14 * httpd -p 8080 -h $HOME/public_html
17 * or for daemon start from rc script with uid=0: 15 * For daemon start from rc script with uid=0:
18 * httpd -u www 16 * httpd -u www
19 * This is equivalent if www user have uid=80 to 17 * which is equivalent to (assuming user www has uid 80):
20 * httpd -p 80 -u 80 -h /www -c /etc/httpd.conf -r "Web Server Authentication" 18 * httpd -p 80 -u 80 -h $PWD -c /etc/httpd.conf -r "Web Server Authentication"
21 *
22 * 19 *
23 * When an url starts by "/cgi-bin/" it is assumed to be a cgi script. The 20 * When an url starts with "/cgi-bin/" it is assumed to be a cgi script.
24 * server changes directory to the location of the script and executes it 21 * The server changes directory to the location of the script and executes it
25 * after setting QUERY_STRING and other environment variables. 22 * after setting QUERY_STRING and other environment variables.
26 * 23 *
27 * Doc: 24 * Doc:
@@ -29,8 +26,8 @@
29 * 26 *
30 * The applet can also be invoked as an url arg decoder and html text encoder 27 * The applet can also be invoked as an url arg decoder and html text encoder
31 * as follows: 28 * as follows:
32 * foo=`httpd -d $foo` # decode "Hello%20World" as "Hello World" 29 * foo=`httpd -d $foo` # decode "Hello%20World" as "Hello World"
33 * bar=`httpd -e "<Hello World>"` # encode as "&#60Hello&#32World&#62" 30 * bar=`httpd -e "<Hello World>"` # encode as "&#60Hello&#32World&#62"
34 * Note that url encoding for arguments is not the same as html encoding for 31 * Note that url encoding for arguments is not the same as html encoding for
35 * presentation. -d decodes an url-encoded argument while -e encodes in html 32 * presentation. -d decodes an url-encoded argument while -e encodes in html
36 * for page display. 33 * for page display.
@@ -100,15 +97,14 @@
100#if ENABLE_FEATURE_HTTPD_USE_SENDFILE 97#if ENABLE_FEATURE_HTTPD_USE_SENDFILE
101# include <sys/sendfile.h> 98# include <sys/sendfile.h>
102#endif 99#endif
103
104#define DEBUG 0
105
106#define IOBUF_SIZE 8192 /* IO buffer */
107
108/* amount of buffering in a pipe */ 100/* amount of buffering in a pipe */
109#ifndef PIPE_BUF 101#ifndef PIPE_BUF
110# define PIPE_BUF 4096 102# define PIPE_BUF 4096
111#endif 103#endif
104
105#define DEBUG 0
106
107#define IOBUF_SIZE 8192
112#if PIPE_BUF >= IOBUF_SIZE 108#if PIPE_BUF >= IOBUF_SIZE
113# error "PIPE_BUF >= IOBUF_SIZE" 109# error "PIPE_BUF >= IOBUF_SIZE"
114#endif 110#endif
@@ -118,6 +114,7 @@
118static const char DEFAULT_PATH_HTTPD_CONF[] ALIGN1 = "/etc"; 114static const char DEFAULT_PATH_HTTPD_CONF[] ALIGN1 = "/etc";
119static const char HTTPD_CONF[] ALIGN1 = "httpd.conf"; 115static const char HTTPD_CONF[] ALIGN1 = "httpd.conf";
120static const char HTTP_200[] ALIGN1 = "HTTP/1.0 200 OK\r\n"; 116static const char HTTP_200[] ALIGN1 = "HTTP/1.0 200 OK\r\n";
117static const char index_html[] ALIGN1 = "index.html";
121 118
122typedef struct has_next_ptr { 119typedef struct has_next_ptr {
123 struct has_next_ptr *next; 120 struct has_next_ptr *next;
@@ -170,7 +167,6 @@ enum {
170 HTTP_PAYMENT_REQUIRED = 402, 167 HTTP_PAYMENT_REQUIRED = 402,
171 HTTP_BAD_GATEWAY = 502, 168 HTTP_BAD_GATEWAY = 502,
172 HTTP_SERVICE_UNAVAILABLE = 503, /* overload, maintenance */ 169 HTTP_SERVICE_UNAVAILABLE = 503, /* overload, maintenance */
173 HTTP_RESPONSE_SETSIZE = 0xffffffff
174#endif 170#endif
175}; 171};
176 172
@@ -231,9 +227,6 @@ static const struct {
231#endif 227#endif
232}; 228};
233 229
234static const char index_html[] ALIGN1 = "index.html";
235
236
237struct globals { 230struct globals {
238 int verbose; /* must be int (used by getopt32) */ 231 int verbose; /* must be int (used by getopt32) */
239 smallint flg_deny_all; 232 smallint flg_deny_all;
@@ -284,6 +277,10 @@ struct globals {
284#if ENABLE_FEATURE_HTTPD_PROXY 277#if ENABLE_FEATURE_HTTPD_PROXY
285 Htaccess_Proxy *proxy; 278 Htaccess_Proxy *proxy;
286#endif 279#endif
280#if ENABLE_FEATURE_HTTPD_GZIP
281 /* client can handle gzip / we are going to send gzip */
282 smallint content_gzip;
283#endif
287}; 284};
288#define G (*ptr_to_globals) 285#define G (*ptr_to_globals)
289#define verbose (G.verbose ) 286#define verbose (G.verbose )
@@ -326,6 +323,11 @@ enum {
326#define hdr_cnt (G.hdr_cnt ) 323#define hdr_cnt (G.hdr_cnt )
327#define http_error_page (G.http_error_page ) 324#define http_error_page (G.http_error_page )
328#define proxy (G.proxy ) 325#define proxy (G.proxy )
326#if ENABLE_FEATURE_HTTPD_GZIP
327# define content_gzip (G.content_gzip )
328#else
329# define content_gzip 0
330#endif
329#define INIT_G() do { \ 331#define INIT_G() do { \
330 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ 332 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
331 IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \ 333 IF_FEATURE_HTTPD_BASIC_AUTH(g_realm = "Web Server Authentication";) \
@@ -777,7 +779,7 @@ static char *encodeString(const char *string)
777 char *p = out; 779 char *p = out;
778 char ch; 780 char ch;
779 781
780 while ((ch = *string++)) { 782 while ((ch = *string++) != '\0') {
781 /* very simple check for what to encode */ 783 /* very simple check for what to encode */
782 if (isalnum(ch)) 784 if (isalnum(ch))
783 *p++ = ch; 785 *p++ = ch;
@@ -787,7 +789,7 @@ static char *encodeString(const char *string)
787 *p = '\0'; 789 *p = '\0';
788 return out; 790 return out;
789} 791}
790#endif /* FEATURE_HTTPD_ENCODE_URL_STR */ 792#endif
791 793
792/* 794/*
793 * Given a URL encoded string, convert it to plain ascii. 795 * Given a URL encoded string, convert it to plain ascii.
@@ -814,12 +816,12 @@ static unsigned hex_to_bin(unsigned char c)
814 if (v <= 5) 816 if (v <= 5)
815 return v + 10; 817 return v + 10;
816 return ~0; 818 return ~0;
817}
818/* For testing: 819/* For testing:
819void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); } 820void t(char c) { printf("'%c'(%u) %u\n", c, c, hex_to_bin(c)); }
820int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f'); 821int main() { t(0x10); t(0x20); t('0'); t('9'); t('A'); t('F'); t('a'); t('f');
821t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; } 822t('0'-1); t('9'+1); t('A'-1); t('F'+1); t('a'-1); t('f'+1); return 0; }
822*/ 823*/
824}
823static char *decodeString(char *orig, int option_d) 825static char *decodeString(char *orig, int option_d)
824{ 826{
825 /* note that decoded string is always shorter than original */ 827 /* note that decoded string is always shorter than original */
@@ -1034,10 +1036,14 @@ static void send_headers(int responseNum)
1034#endif 1036#endif
1035 "Last-Modified: %s\r\n%s %"OFF_FMT"u\r\n", 1037 "Last-Modified: %s\r\n%s %"OFF_FMT"u\r\n",
1036 tmp_str, 1038 tmp_str,
1037 "Content-length:", 1039 content_gzip ? "Transfer-length:" : "Content-length:",
1038 file_size 1040 file_size
1039 ); 1041 );
1040 } 1042 }
1043
1044 if (content_gzip)
1045 len += sprintf(iobuf + len, "Content-Encoding: gzip\r\n");
1046
1041 iobuf[len++] = '\r'; 1047 iobuf[len++] = '\r';
1042 iobuf[len++] = '\n'; 1048 iobuf[len++] = '\n';
1043 if (infoString) { 1049 if (infoString) {
@@ -1507,7 +1513,22 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
1507 int fd; 1513 int fd;
1508 ssize_t count; 1514 ssize_t count;
1509 1515
1510 fd = open(url, O_RDONLY); 1516 if (content_gzip) {
1517 /* does <url>.gz exist? Then use it instead */
1518 char *gzurl = xasprintf("%s.gz", url);
1519 fd = open(gzurl, O_RDONLY);
1520 free(gzurl);
1521 if (fd != -1) {
1522 struct stat sb;
1523 fstat(fd, &sb);
1524 file_size = sb.st_size;
1525 } else {
1526 IF_FEATURE_HTTPD_GZIP(content_gzip = 0;)
1527 fd = open(url, O_RDONLY);
1528 }
1529 } else {
1530 fd = open(url, O_RDONLY);
1531 }
1511 if (fd < 0) { 1532 if (fd < 0) {
1512 if (DEBUG) 1533 if (DEBUG)
1513 bb_perror_msg("can't open '%s'", url); 1534 bb_perror_msg("can't open '%s'", url);
@@ -1590,8 +1611,11 @@ static NOINLINE void send_file_and_exit(const char *url, int what)
1590 url, found_mime_type); 1611 url, found_mime_type);
1591 1612
1592#if ENABLE_FEATURE_HTTPD_RANGES 1613#if ENABLE_FEATURE_HTTPD_RANGES
1593 if (what == SEND_BODY) 1614 if (what == SEND_BODY /* err pages and ranges don't mix */
1594 range_start = 0; /* err pages and ranges don't mix */ 1615 || content_gzip /* we are sending compressed page: can't do ranges */ ///why?
1616 ) {
1617 range_start = 0;
1618 }
1595 range_len = MAXINT(off_t); 1619 range_len = MAXINT(off_t);
1596 if (range_start) { 1620 if (range_start) {
1597 if (!range_end) { 1621 if (!range_end) {
@@ -1964,7 +1988,7 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1964 if (http_major_version >= '0') { 1988 if (http_major_version >= '0') {
1965 /* Request was with "... HTTP/nXXX", and n >= 0 */ 1989 /* Request was with "... HTTP/nXXX", and n >= 0 */
1966 1990
1967 /* Read until blank line for HTTP version specified, else parse immediate */ 1991 /* Read until blank line */
1968 while (1) { 1992 while (1) {
1969 if (!get_line()) 1993 if (!get_line())
1970 break; /* EOF or error or empty line */ 1994 break; /* EOF or error or empty line */
@@ -1991,9 +2015,9 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
1991 if ((STRNCASECMP(iobuf, "Content-length:") == 0)) { 2015 if ((STRNCASECMP(iobuf, "Content-length:") == 0)) {
1992 /* extra read only for POST */ 2016 /* extra read only for POST */
1993 if (prequest != request_GET 2017 if (prequest != request_GET
1994#if ENABLE_FEATURE_HTTPD_CGI 2018# if ENABLE_FEATURE_HTTPD_CGI
1995 && prequest != request_HEAD 2019 && prequest != request_HEAD
1996#endif 2020# endif
1997 ) { 2021 ) {
1998 tptr = skip_whitespace(iobuf + sizeof("Content-length:") - 1); 2022 tptr = skip_whitespace(iobuf + sizeof("Content-length:") - 1);
1999 if (!tptr[0]) 2023 if (!tptr[0])
@@ -2055,6 +2079,23 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2055 } 2079 }
2056 } 2080 }
2057#endif 2081#endif
2082#if ENABLE_FEATURE_HTTPD_GZIP
2083 if (STRNCASECMP(iobuf, "Accept-Encoding:") == 0) {
2084 /* Note: we do not support "gzip;q=0"
2085 * method of _disabling_ gzip
2086 * delivery. No one uses that, though */
2087 const char *s = strstr(iobuf, "gzip");
2088 if (s) {
2089 // want more thorough checks?
2090 //if (s[-1] == ' '
2091 // || s[-1] == ','
2092 // || s[-1] == ':'
2093 //) {
2094 content_gzip = 1;
2095 //}
2096 }
2097 }
2098#endif
2058 } /* while extra header reading */ 2099 } /* while extra header reading */
2059 } 2100 }
2060 2101
@@ -2183,9 +2224,9 @@ static void mini_httpd(int server_socket)
2183 /* Wait for connections... */ 2224 /* Wait for connections... */
2184 fromAddr.len = LSA_SIZEOF_SA; 2225 fromAddr.len = LSA_SIZEOF_SA;
2185 n = accept(server_socket, &fromAddr.u.sa, &fromAddr.len); 2226 n = accept(server_socket, &fromAddr.u.sa, &fromAddr.len);
2186
2187 if (n < 0) 2227 if (n < 0)
2188 continue; 2228 continue;
2229
2189 /* set the KEEPALIVE option to cull dead connections */ 2230 /* set the KEEPALIVE option to cull dead connections */
2190 setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); 2231 setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
2191 2232
@@ -2226,9 +2267,9 @@ static void mini_httpd_nommu(int server_socket, int argc, char **argv)
2226 /* Wait for connections... */ 2267 /* Wait for connections... */
2227 fromAddr.len = LSA_SIZEOF_SA; 2268 fromAddr.len = LSA_SIZEOF_SA;
2228 n = accept(server_socket, &fromAddr.u.sa, &fromAddr.len); 2269 n = accept(server_socket, &fromAddr.u.sa, &fromAddr.len);
2229
2230 if (n < 0) 2270 if (n < 0)
2231 continue; 2271 continue;
2272
2232 /* set the KEEPALIVE option to cull dead connections */ 2273 /* set the KEEPALIVE option to cull dead connections */
2233 setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1)); 2274 setsockopt(n, SOL_SOCKET, SO_KEEPALIVE, &const_int_1, sizeof(const_int_1));
2234 2275
diff --git a/networking/ifplugd.c b/networking/ifplugd.c
index eb7442881..2f8c90ffc 100644
--- a/networking/ifplugd.c
+++ b/networking/ifplugd.c
@@ -71,16 +71,6 @@ enum {
71# define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:M" 71# define OPTION_STR "+ansfFi:r:It:u:d:m:pqlx:M"
72#endif 72#endif
73 73
74enum { // api mode
75 API_AUTO = 'a',
76 API_ETHTOOL = 'e',
77 API_MII = 'm',
78 API_PRIVATE = 'p',
79 API_WLAN = 'w',
80 API_IFF = 'i',
81};
82static const char api_modes[] ALIGN1 = "aempwi";
83
84enum { // interface status 74enum { // interface status
85 IFSTATUS_ERR = -1, 75 IFSTATUS_ERR = -1,
86 IFSTATUS_DOWN = 0, 76 IFSTATUS_DOWN = 0,
@@ -107,8 +97,6 @@ struct globals {
107 const char *api_mode; 97 const char *api_mode;
108 const char *script_name; 98 const char *script_name;
109 const char *extra_arg; 99 const char *extra_arg;
110
111 smallint (*detect_link_func)(void);
112}; 100};
113#define G (*ptr_to_globals) 101#define G (*ptr_to_globals)
114#define INIT_G() do { \ 102#define INIT_G() do { \
@@ -123,42 +111,12 @@ struct globals {
123} while (0) 111} while (0)
124 112
125 113
126static const char *strstatus(int status) 114/* Utility routines */
127{
128 if (status == IFSTATUS_ERR)
129 return "error";
130 return "down\0up" + (status * 5);
131}
132 115
133static int run_script(const char *action) 116static void set_ifreq_to_ifname(struct ifreq *ifreq)
134{ 117{
135 char *env_PREVIOUS, *env_CURRENT; 118 memset(ifreq, 0, sizeof(struct ifreq));
136 char *argv[5]; 119 strncpy_IFNAMSIZ(ifreq->ifr_name, G.iface);
137 int r;
138
139 bb_error_msg("executing '%s %s %s'", G.script_name, G.iface, action);
140
141 argv[0] = (char*) G.script_name;
142 argv[1] = (char*) G.iface;
143 argv[2] = (char*) action;
144 argv[3] = (char*) G.extra_arg;
145 argv[4] = NULL;
146
147 env_PREVIOUS = xasprintf("%s=%s", IFPLUGD_ENV_PREVIOUS, strstatus(G.iface_prev_status));
148 putenv(env_PREVIOUS);
149 env_CURRENT = xasprintf("%s=%s", IFPLUGD_ENV_CURRENT, strstatus(G.iface_last_status));
150 putenv(env_CURRENT);
151
152 /* r < 0 - can't exec, 0 <= r < 0x180 - exited, >=0x180 - killed by sig (r-0x180) */
153 r = spawn_and_wait(argv);
154
155 unsetenv(IFPLUGD_ENV_PREVIOUS);
156 unsetenv(IFPLUGD_ENV_CURRENT);
157 free(env_PREVIOUS);
158 free(env_CURRENT);
159
160 bb_error_msg("exit code: %d", r & 0xff);
161 return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r;
162} 120}
163 121
164static int network_ioctl(int request, void* data, const char *errmsg) 122static int network_ioctl(int request, void* data, const char *errmsg)
@@ -169,80 +127,7 @@ static int network_ioctl(int request, void* data, const char *errmsg)
169 return r; 127 return r;
170} 128}
171 129
172static void set_ifreq_to_ifname(struct ifreq *ifreq) 130/* Link detection routines and table */
173{
174 memset(ifreq, 0, sizeof(struct ifreq));
175 strncpy_IFNAMSIZ(ifreq->ifr_name, G.iface);
176}
177
178static void up_iface(void)
179{
180 struct ifreq ifrequest;
181
182 if (!G.iface_exists)
183 return;
184
185 set_ifreq_to_ifname(&ifrequest);
186 if (network_ioctl(SIOCGIFFLAGS, &ifrequest, "getting interface flags") < 0) {
187 G.iface_exists = 0;
188 return;
189 }
190
191 if (!(ifrequest.ifr_flags & IFF_UP)) {
192 ifrequest.ifr_flags |= IFF_UP;
193 /* Let user know we mess up with interface */
194 bb_error_msg("upping interface");
195 if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "setting interface flags") < 0)
196 xfunc_die();
197 }
198
199#if 0 /* why do we mess with IP addr? It's not our business */
200 if (network_ioctl(SIOCGIFADDR, &ifrequest, "can't get interface address") < 0) {
201 } else if (ifrequest.ifr_addr.sa_family != AF_INET) {
202 bb_perror_msg("the interface is not IP-based");
203 } else {
204 ((struct sockaddr_in*)(&ifrequest.ifr_addr))->sin_addr.s_addr = INADDR_ANY;
205 network_ioctl(SIOCSIFADDR, &ifrequest, "can't set interface address");
206 }
207 network_ioctl(SIOCGIFFLAGS, &ifrequest, "can't get interface flags");
208#endif
209}
210
211static void maybe_up_new_iface(void)
212{
213 if (!(option_mask32 & FLAG_NO_AUTO))
214 up_iface();
215
216#if 0 /* bloat */
217 struct ifreq ifrequest;
218 struct ethtool_drvinfo driver_info;
219
220 set_ifreq_to_ifname(&ifrequest);
221 driver_info.cmd = ETHTOOL_GDRVINFO;
222 ifrequest.ifr_data = &driver_info;
223 if (network_ioctl(SIOCETHTOOL, &ifrequest, NULL) == 0) {
224 char buf[sizeof("/xx:xx:xx:xx:xx:xx")];
225
226 /* Get MAC */
227 buf[0] = '\0';
228 set_ifreq_to_ifname(&ifrequest);
229 if (network_ioctl(SIOCGIFHWADDR, &ifrequest, NULL) == 0) {
230 sprintf(buf, "/%02X:%02X:%02X:%02X:%02X:%02X",
231 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[0]),
232 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[1]),
233 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[2]),
234 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[3]),
235 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[4]),
236 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[5]));
237 }
238
239 bb_error_msg("using interface %s%s with driver<%s> (version: %s)",
240 G.iface, buf, driver_info.driver, driver_info.version);
241 }
242#endif
243 if (G.api_method_num == 0)
244 G.detect_link_func = NULL;
245}
246 131
247static smallint detect_link_mii(void) 132static smallint detect_link_mii(void)
248{ 133{
@@ -349,18 +234,139 @@ static smallint detect_link_wlan(void)
349 return IFSTATUS_UP; 234 return IFSTATUS_UP;
350} 235}
351 236
237enum { // api mode
238 API_ETHTOOL, // 'e'
239 API_MII, // 'm'
240 API_PRIVATE, // 'p'
241 API_WLAN, // 'w'
242 API_IFF, // 'i'
243 API_AUTO, // 'a'
244};
245
246static const char api_modes[] ALIGN1 = "empwia";
247
248static const struct {
249 const char *name;
250 smallint (*func)(void);
251} method_table[] = {
252 { "SIOCETHTOOL" , &detect_link_ethtool },
253 { "SIOCGMIIPHY" , &detect_link_mii },
254 { "SIOCDEVPRIVATE" , &detect_link_priv },
255 { "wireless extension", &detect_link_wlan },
256 { "IFF_RUNNING" , &detect_link_iff },
257};
258
259
260
261static const char *strstatus(int status)
262{
263 if (status == IFSTATUS_ERR)
264 return "error";
265 return "down\0up" + (status * 5);
266}
267
268static int run_script(const char *action)
269{
270 char *env_PREVIOUS, *env_CURRENT;
271 char *argv[5];
272 int r;
273
274 bb_error_msg("executing '%s %s %s'", G.script_name, G.iface, action);
275
276 argv[0] = (char*) G.script_name;
277 argv[1] = (char*) G.iface;
278 argv[2] = (char*) action;
279 argv[3] = (char*) G.extra_arg;
280 argv[4] = NULL;
281
282 env_PREVIOUS = xasprintf("%s=%s", IFPLUGD_ENV_PREVIOUS, strstatus(G.iface_prev_status));
283 putenv(env_PREVIOUS);
284 env_CURRENT = xasprintf("%s=%s", IFPLUGD_ENV_CURRENT, strstatus(G.iface_last_status));
285 putenv(env_CURRENT);
286
287 /* r < 0 - can't exec, 0 <= r < 0x180 - exited, >=0x180 - killed by sig (r-0x180) */
288 r = spawn_and_wait(argv);
289
290 unsetenv(IFPLUGD_ENV_PREVIOUS);
291 unsetenv(IFPLUGD_ENV_CURRENT);
292 free(env_PREVIOUS);
293 free(env_CURRENT);
294
295 bb_error_msg("exit code: %d", r & 0xff);
296 return (option_mask32 & FLAG_IGNORE_RETVAL) ? 0 : r;
297}
298
299static void up_iface(void)
300{
301 struct ifreq ifrequest;
302
303 if (!G.iface_exists)
304 return;
305
306 set_ifreq_to_ifname(&ifrequest);
307 if (network_ioctl(SIOCGIFFLAGS, &ifrequest, "getting interface flags") < 0) {
308 G.iface_exists = 0;
309 return;
310 }
311
312 if (!(ifrequest.ifr_flags & IFF_UP)) {
313 ifrequest.ifr_flags |= IFF_UP;
314 /* Let user know we mess up with interface */
315 bb_error_msg("upping interface");
316 if (network_ioctl(SIOCSIFFLAGS, &ifrequest, "setting interface flags") < 0)
317 xfunc_die();
318 }
319
320#if 0 /* why do we mess with IP addr? It's not our business */
321 if (network_ioctl(SIOCGIFADDR, &ifrequest, "can't get interface address") < 0) {
322 } else if (ifrequest.ifr_addr.sa_family != AF_INET) {
323 bb_perror_msg("the interface is not IP-based");
324 } else {
325 ((struct sockaddr_in*)(&ifrequest.ifr_addr))->sin_addr.s_addr = INADDR_ANY;
326 network_ioctl(SIOCSIFADDR, &ifrequest, "can't set interface address");
327 }
328 network_ioctl(SIOCGIFFLAGS, &ifrequest, "can't get interface flags");
329#endif
330}
331
332static void maybe_up_new_iface(void)
333{
334 if (!(option_mask32 & FLAG_NO_AUTO))
335 up_iface();
336
337#if 0 /* bloat */
338 struct ifreq ifrequest;
339 struct ethtool_drvinfo driver_info;
340
341 set_ifreq_to_ifname(&ifrequest);
342 driver_info.cmd = ETHTOOL_GDRVINFO;
343 ifrequest.ifr_data = &driver_info;
344 if (network_ioctl(SIOCETHTOOL, &ifrequest, NULL) == 0) {
345 char buf[sizeof("/xx:xx:xx:xx:xx:xx")];
346
347 /* Get MAC */
348 buf[0] = '\0';
349 set_ifreq_to_ifname(&ifrequest);
350 if (network_ioctl(SIOCGIFHWADDR, &ifrequest, NULL) == 0) {
351 sprintf(buf, "/%02X:%02X:%02X:%02X:%02X:%02X",
352 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[0]),
353 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[1]),
354 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[2]),
355 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[3]),
356 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[4]),
357 (uint8_t)(ifrequest.ifr_hwaddr.sa_data[5]));
358 }
359
360 bb_error_msg("using interface %s%s with driver<%s> (version: %s)",
361 G.iface, buf, driver_info.driver, driver_info.version);
362 }
363#endif
364 if (G.api_mode[0] == 'a')
365 G.api_method_num = API_AUTO;
366}
367
352static smallint detect_link(void) 368static smallint detect_link(void)
353{ 369{
354 static const struct {
355 const char *name;
356 smallint (*func)(void);
357 } method[] = {
358 { "SIOCETHTOOL" , &detect_link_ethtool },
359 { "SIOCGMIIPHY" , &detect_link_mii },
360 { "SIOCDEVPRIVATE" , &detect_link_priv },
361 { "wireless extension", &detect_link_wlan },
362 { "IFF_RUNNING" , &detect_link_iff },
363 };
364 smallint status; 370 smallint status;
365 371
366 if (!G.iface_exists) 372 if (!G.iface_exists)
@@ -373,38 +379,34 @@ static smallint detect_link(void)
373 if (!(option_mask32 & FLAG_NO_AUTO)) 379 if (!(option_mask32 & FLAG_NO_AUTO))
374 up_iface(); 380 up_iface();
375 381
376 if (!G.detect_link_func) { 382 if (G.api_method_num == API_AUTO) {
377 if (G.api_method_num == 0) { 383 int i;
378 int i; 384 smallint sv_logmode;
379 smallint sv_logmode; 385
380 386 sv_logmode = logmode;
381 sv_logmode = logmode; 387 for (i = 0; i < ARRAY_SIZE(method_table); i++) {
382 for (i = 0; i < ARRAY_SIZE(method); i++) { 388 logmode = LOGMODE_NONE;
383 logmode = LOGMODE_NONE; 389 status = method_table[i].func();
384 status = method[i].func(); 390 logmode = sv_logmode;
385 logmode = sv_logmode; 391 if (status != IFSTATUS_ERR) {
386 if (status != IFSTATUS_ERR) { 392 G.api_method_num = i;
387 G.detect_link_func = method[i].func; 393 bb_error_msg("using %s detection mode", method_table[i].name);
388 bb_error_msg("using %s detection mode", method[i].name); 394 break;
389 goto _2;
390 }
391 } 395 }
392 goto _1;
393 } 396 }
394 G.detect_link_func = method[G.api_method_num - 1].func; 397 } else {
398 status = method_table[G.api_method_num].func();
395 } 399 }
396 400
397 status = G.detect_link_func();
398 _1:
399 if (status == IFSTATUS_ERR) { 401 if (status == IFSTATUS_ERR) {
400 if (option_mask32 & FLAG_IGNORE_FAIL) 402 if (option_mask32 & FLAG_IGNORE_FAIL)
401 status = IFSTATUS_DOWN; 403 status = IFSTATUS_DOWN;
402 else if (option_mask32 & FLAG_IGNORE_FAIL_POSITIVE) 404 else if (option_mask32 & FLAG_IGNORE_FAIL_POSITIVE)
403 status = IFSTATUS_UP; 405 status = IFSTATUS_UP;
404 else if (G.api_method_num == 0) 406 else if (G.api_mode[0] == 'a')
405 bb_error_msg("can't detect link status"); 407 bb_error_msg("can't detect link status");
406 } 408 }
407 _2: 409
408 if (status != G.iface_last_status) { 410 if (status != G.iface_last_status) {
409 G.iface_prev_status = G.iface_last_status; 411 G.iface_prev_status = G.iface_last_status;
410 G.iface_last_status = status; 412 G.iface_last_status = status;
@@ -475,23 +477,6 @@ static NOINLINE int check_existence_through_netlink(void)
475 return G.iface_exists; 477 return G.iface_exists;
476} 478}
477 479
478static NOINLINE int netlink_open(void)
479{
480 int fd;
481 struct sockaddr_nl addr;
482
483 fd = xsocket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
484
485 memset(&addr, 0, sizeof(addr));
486 addr.nl_family = AF_NETLINK;
487 addr.nl_groups = RTMGRP_LINK;
488 addr.nl_pid = getpid();
489
490 xbind(fd, (struct sockaddr*)&addr, sizeof(addr));
491
492 return fd;
493}
494
495#if ENABLE_FEATURE_PIDFILE 480#if ENABLE_FEATURE_PIDFILE
496static NOINLINE pid_t read_pid(const char *filename) 481static NOINLINE pid_t read_pid(const char *filename)
497{ 482{
@@ -545,6 +530,7 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv)
545 if (pid_from_pidfile > 0 && kill(pid_from_pidfile, 0) == 0) 530 if (pid_from_pidfile > 0 && kill(pid_from_pidfile, 0) == 0)
546 bb_error_msg_and_die("daemon already running"); 531 bb_error_msg_and_die("daemon already running");
547#endif 532#endif
533
548 api_mode_found = strchr(api_modes, G.api_mode[0]); 534 api_mode_found = strchr(api_modes, G.api_mode[0]);
549 if (!api_mode_found) 535 if (!api_mode_found)
550 bb_error_msg_and_die("unknown API mode '%s'", G.api_mode); 536 bb_error_msg_and_die("unknown API mode '%s'", G.api_mode);
@@ -555,7 +541,16 @@ int ifplugd_main(int argc UNUSED_PARAM, char **argv)
555 541
556 xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), ioctl_fd); 542 xmove_fd(xsocket(AF_INET, SOCK_DGRAM, 0), ioctl_fd);
557 if (opts & FLAG_MONITOR) { 543 if (opts & FLAG_MONITOR) {
558 xmove_fd(netlink_open(), netlink_fd); 544 struct sockaddr_nl addr;
545 int fd = xsocket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
546
547 memset(&addr, 0, sizeof(addr));
548 addr.nl_family = AF_NETLINK;
549 addr.nl_groups = RTMGRP_LINK;
550 addr.nl_pid = getpid();
551
552 xbind(fd, (struct sockaddr*)&addr, sizeof(addr));
553 xmove_fd(fd, netlink_fd);
559 } 554 }
560 555
561 write_pidfile(pidfile_name); 556 write_pidfile(pidfile_name);
diff --git a/networking/interface.c b/networking/interface.c
index 659ac36ea..7c6ed82df 100644
--- a/networking/interface.c
+++ b/networking/interface.c
@@ -927,7 +927,6 @@ static void print_bytes_scaled(unsigned long long ull, const char *end)
927 927
928static void ife_print6(struct interface *ptr) 928static void ife_print6(struct interface *ptr)
929{ 929{
930
931 FILE *f; 930 FILE *f;
932 char addr6[40], devname[20]; 931 char addr6[40], devname[20];
933 struct sockaddr_in6 sap; 932 struct sockaddr_in6 sap;
diff --git a/networking/ip.c b/networking/ip.c
index 7a0f308f0..004289667 100644
--- a/networking/ip.c
+++ b/networking/ip.c
@@ -1,14 +1,12 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* 2/*
3 * ip.c "ip" utility frontend. 3 * "ip" utility frontend.
4 * 4 *
5 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. 5 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
6 * 6 *
7 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> 7 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
8 *
9 * 8 *
10 * Changes: 9 * Changes:
11 *
12 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses 10 * Rani Assaf <rani@magic.metawire.com> 980929: resolve addresses
13 * Bernhard Reutner-Fischer rewrote to use index_in_substr_array 11 * Bernhard Reutner-Fischer rewrote to use index_in_substr_array
14 */ 12 */
@@ -24,12 +22,14 @@
24 || ENABLE_FEATURE_IP_TUNNEL \ 22 || ENABLE_FEATURE_IP_TUNNEL \
25 || ENABLE_FEATURE_IP_RULE 23 || ENABLE_FEATURE_IP_RULE
26 24
27static int NORETURN ip_print_help(char **argv UNUSED_PARAM) 25static int FAST_FUNC ip_print_help(char **argv UNUSED_PARAM)
28{ 26{
29 bb_show_usage(); 27 bb_show_usage();
30} 28}
31 29
32static int ip_do(int (*ip_func)(char **argv), char **argv) 30typedef int FAST_FUNC (*ip_func_ptr_t)(char**);
31
32static int ip_do(ip_func_ptr_t ip_func, char **argv)
33{ 33{
34 argv = ip_parse_common_args(argv + 1); 34 argv = ip_parse_common_args(argv + 1);
35 return ip_func(argv); 35 return ip_func(argv);
@@ -78,45 +78,29 @@ int ip_main(int argc UNUSED_PARAM, char **argv)
78 static const char keywords[] ALIGN1 = 78 static const char keywords[] ALIGN1 =
79 IF_FEATURE_IP_ADDRESS("address\0") 79 IF_FEATURE_IP_ADDRESS("address\0")
80 IF_FEATURE_IP_ROUTE("route\0") 80 IF_FEATURE_IP_ROUTE("route\0")
81 IF_FEATURE_IP_ROUTE("r\0")
81 IF_FEATURE_IP_LINK("link\0") 82 IF_FEATURE_IP_LINK("link\0")
82 IF_FEATURE_IP_TUNNEL("tunnel\0" "tunl\0") 83 IF_FEATURE_IP_TUNNEL("tunnel\0")
84 IF_FEATURE_IP_TUNNEL("tunl\0")
83 IF_FEATURE_IP_RULE("rule\0") 85 IF_FEATURE_IP_RULE("rule\0")
84 ; 86 ;
85 enum { 87 static const ip_func_ptr_t ip_func_ptrs[] = {
86 IF_FEATURE_IP_ADDRESS(IP_addr,) 88 ip_print_help,
87 IF_FEATURE_IP_ROUTE(IP_route,) 89 IF_FEATURE_IP_ADDRESS(do_ipaddr,)
88 IF_FEATURE_IP_LINK(IP_link,) 90 IF_FEATURE_IP_ROUTE(do_iproute,)
89 IF_FEATURE_IP_TUNNEL(IP_tunnel, IP_tunl,) 91 IF_FEATURE_IP_ROUTE(do_iproute,)
90 IF_FEATURE_IP_RULE(IP_rule,) 92 IF_FEATURE_IP_LINK(do_iplink,)
91 IP_none 93 IF_FEATURE_IP_TUNNEL(do_iptunnel,)
94 IF_FEATURE_IP_TUNNEL(do_iptunnel,)
95 IF_FEATURE_IP_RULE(do_iprule,)
92 }; 96 };
93 int (*ip_func)(char**) = ip_print_help; 97 ip_func_ptr_t ip_func;
98 int key;
94 99
95 argv = ip_parse_common_args(argv + 1); 100 argv = ip_parse_common_args(argv + 1);
96 if (*argv) { 101 key = *argv ? index_in_substrings(keywords, *argv++) : -1;
97 int key = index_in_substrings(keywords, *argv); 102 ip_func = ip_func_ptrs[key + 1];
98 argv++; 103
99#if ENABLE_FEATURE_IP_ADDRESS
100 if (key == IP_addr)
101 ip_func = do_ipaddr;
102#endif
103#if ENABLE_FEATURE_IP_ROUTE
104 if (key == IP_route)
105 ip_func = do_iproute;
106#endif
107#if ENABLE_FEATURE_IP_LINK
108 if (key == IP_link)
109 ip_func = do_iplink;
110#endif
111#if ENABLE_FEATURE_IP_TUNNEL
112 if (key == IP_tunnel || key == IP_tunl)
113 ip_func = do_iptunnel;
114#endif
115#if ENABLE_FEATURE_IP_RULE
116 if (key == IP_rule)
117 ip_func = do_iprule;
118#endif
119 }
120 return ip_func(argv); 104 return ip_func(argv);
121} 105}
122 106
diff --git a/networking/libiproute/ip_common.h b/networking/libiproute/ip_common.h
index aef325281..30c7e595b 100644
--- a/networking/libiproute/ip_common.h
+++ b/networking/libiproute/ip_common.h
@@ -15,22 +15,21 @@
15 15
16PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 16PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN
17 17
18extern char **ip_parse_common_args(char **argv); 18char FAST_FUNC **ip_parse_common_args(char **argv);
19extern int print_neigh(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg); 19//int FAST_FUNC print_neigh(struct sockaddr_nl *who, struct nlmsghdr *n, void *arg);
20extern int ipaddr_list_or_flush(char **argv, int flush); 20int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush);
21extern int iproute_monitor(char **argv); 21//int FAST_FUNC iproute_monitor(char **argv);
22extern void iplink_usage(void) NORETURN; 22//void FAST_FUNC ipneigh_reset_filter(void);
23extern void ipneigh_reset_filter(void);
24 23
25extern int do_ipaddr(char **argv); 24int FAST_FUNC do_ipaddr(char **argv);
26extern int do_iproute(char **argv); 25int FAST_FUNC do_iproute(char **argv);
27extern int do_iprule(char **argv); 26int FAST_FUNC do_iprule(char **argv);
28extern int do_ipneigh(char **argv); 27//int FAST_FUNC do_ipneigh(char **argv);
29extern int do_iptunnel(char **argv); 28int FAST_FUNC do_iptunnel(char **argv);
30extern int do_iplink(char **argv); 29int FAST_FUNC do_iplink(char **argv);
31extern int do_ipmonitor(char **argv); 30//int FAST_FUNC do_ipmonitor(char **argv);
32extern int do_multiaddr(char **argv); 31//int FAST_FUNC do_multiaddr(char **argv);
33extern int do_multiroute(char **argv); 32//int FAST_FUNC do_multiroute(char **argv);
34 33
35POP_SAVED_FUNCTION_VISIBILITY 34POP_SAVED_FUNCTION_VISIBILITY
36 35
diff --git a/networking/libiproute/ip_parse_common_args.c b/networking/libiproute/ip_parse_common_args.c
index 5e4012b81..bf01528c4 100644
--- a/networking/libiproute/ip_parse_common_args.c
+++ b/networking/libiproute/ip_parse_common_args.c
@@ -22,7 +22,7 @@ family_t preferred_family = AF_UNSPEC;
22smallint oneline; 22smallint oneline;
23char _SL_; 23char _SL_;
24 24
25char **ip_parse_common_args(char **argv) 25char** FAST_FUNC ip_parse_common_args(char **argv)
26{ 26{
27 static const char ip_common_commands[] ALIGN1 = 27 static const char ip_common_commands[] ALIGN1 =
28 "oneline" "\0" 28 "oneline" "\0"
diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
index 381293412..b6f469d0f 100644
--- a/networking/libiproute/ipaddress.c
+++ b/networking/libiproute/ipaddress.c
@@ -415,7 +415,7 @@ static void ipaddr_reset_filter(int _oneline)
415} 415}
416 416
417/* Return value becomes exitcode. It's okay to not return at all */ 417/* Return value becomes exitcode. It's okay to not return at all */
418int ipaddr_list_or_flush(char **argv, int flush) 418int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
419{ 419{
420 static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""dev\0"; 420 static const char option[] ALIGN1 = "to\0""scope\0""up\0""label\0""dev\0";
421 421
@@ -747,7 +747,7 @@ static int ipaddr_modify(int cmd, char **argv)
747} 747}
748 748
749/* Return value becomes exitcode. It's okay to not return at all */ 749/* Return value becomes exitcode. It's okay to not return at all */
750int do_ipaddr(char **argv) 750int FAST_FUNC do_ipaddr(char **argv)
751{ 751{
752 static const char commands[] ALIGN1 = 752 static const char commands[] ALIGN1 =
753 "add\0""delete\0""list\0""show\0""lst\0""flush\0"; 753 "add\0""delete\0""list\0""show\0""lst\0""flush\0";
diff --git a/networking/libiproute/iplink.c b/networking/libiproute/iplink.c
index 8bf892797..9f9218573 100644
--- a/networking/libiproute/iplink.c
+++ b/networking/libiproute/iplink.c
@@ -362,7 +362,7 @@ static int do_change(char **argv, const unsigned rtm)
362} 362}
363 363
364/* Return value becomes exitcode. It's okay to not return at all */ 364/* Return value becomes exitcode. It's okay to not return at all */
365int do_iplink(char **argv) 365int FAST_FUNC do_iplink(char **argv)
366{ 366{
367 static const char keywords[] ALIGN1 = 367 static const char keywords[] ALIGN1 =
368 "add\0""delete\0""set\0""show\0""lst\0""list\0"; 368 "add\0""delete\0""set\0""show\0""lst\0""list\0";
diff --git a/networking/libiproute/iproute.c b/networking/libiproute/iproute.c
index d771a609b..8dba2bf3d 100644
--- a/networking/libiproute/iproute.c
+++ b/networking/libiproute/iproute.c
@@ -869,7 +869,7 @@ static int iproute_get(char **argv)
869} 869}
870 870
871/* Return value becomes exitcode. It's okay to not return at all */ 871/* Return value becomes exitcode. It's okay to not return at all */
872int do_iproute(char **argv) 872int FAST_FUNC do_iproute(char **argv)
873{ 873{
874 static const char ip_route_commands[] ALIGN1 = 874 static const char ip_route_commands[] ALIGN1 =
875 /*0-3*/ "add\0""append\0""change\0""chg\0" 875 /*0-3*/ "add\0""append\0""change\0""chg\0"
diff --git a/networking/libiproute/iprule.c b/networking/libiproute/iprule.c
index 835529ec4..3af6a83a8 100644
--- a/networking/libiproute/iprule.c
+++ b/networking/libiproute/iprule.c
@@ -304,7 +304,7 @@ static int iprule_modify(int cmd, char **argv)
304} 304}
305 305
306/* Return value becomes exitcode. It's okay to not return at all */ 306/* Return value becomes exitcode. It's okay to not return at all */
307int do_iprule(char **argv) 307int FAST_FUNC do_iprule(char **argv)
308{ 308{
309 static const char ip_rule_commands[] ALIGN1 = 309 static const char ip_rule_commands[] ALIGN1 =
310 "add\0""delete\0""list\0""show\0"; 310 "add\0""delete\0""list\0""show\0";
diff --git a/networking/libiproute/iptunnel.c b/networking/libiproute/iptunnel.c
index 257343826..8389ef348 100644
--- a/networking/libiproute/iptunnel.c
+++ b/networking/libiproute/iptunnel.c
@@ -556,7 +556,7 @@ static int do_show(char **argv)
556} 556}
557 557
558/* Return value becomes exitcode. It's okay to not return at all */ 558/* Return value becomes exitcode. It's okay to not return at all */
559int do_iptunnel(char **argv) 559int FAST_FUNC do_iptunnel(char **argv)
560{ 560{
561 static const char keywords[] ALIGN1 = 561 static const char keywords[] ALIGN1 =
562 "add\0""change\0""delete\0""show\0""list\0""lst\0"; 562 "add\0""change\0""delete\0""show\0""list\0""lst\0";
diff --git a/networking/libiproute/libnetlink.c b/networking/libiproute/libnetlink.c
index ba24832d6..8da80b2fc 100644
--- a/networking/libiproute/libnetlink.c
+++ b/networking/libiproute/libnetlink.c
@@ -1,14 +1,13 @@
1/* vi: set sw=4 ts=4: */ 1/* vi: set sw=4 ts=4: */
2/* 2/*
3 * libnetlink.c RTnetlink service routines. 3 * RTnetlink service routines.
4 * 4 *
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License 6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version. 8 * 2 of the License, or (at your option) any later version.
9 *
10 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
11 * 9 *
10 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru>
12 */ 11 */
13 12
14#include <sys/socket.h> 13#include <sys/socket.h>
@@ -17,12 +16,7 @@
17#include "libbb.h" 16#include "libbb.h"
18#include "libnetlink.h" 17#include "libnetlink.h"
19 18
20void FAST_FUNC rtnl_close(struct rtnl_handle *rth) 19void FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
21{
22 close(rth->fd);
23}
24
25int FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
26{ 20{
27 socklen_t addr_len; 21 socklen_t addr_len;
28 22
@@ -44,7 +38,6 @@ int FAST_FUNC xrtnl_open(struct rtnl_handle *rth/*, unsigned subscriptions*/)
44 bb_error_msg_and_die("wrong address family %d", rth->local.nl_family); 38 bb_error_msg_and_die("wrong address family %d", rth->local.nl_family);
45*/ 39*/
46 rth->seq = time(NULL); 40 rth->seq = time(NULL);
47 return 0;
48} 41}
49 42
50int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type) 43int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int type)
@@ -53,10 +46,6 @@ int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int ty
53 struct nlmsghdr nlh; 46 struct nlmsghdr nlh;
54 struct rtgenmsg g; 47 struct rtgenmsg g;
55 } req; 48 } req;
56 struct sockaddr_nl nladdr;
57
58 memset(&nladdr, 0, sizeof(nladdr));
59 nladdr.nl_family = AF_NETLINK;
60 49
61 req.nlh.nlmsg_len = sizeof(req); 50 req.nlh.nlmsg_len = sizeof(req);
62 req.nlh.nlmsg_type = type; 51 req.nlh.nlmsg_type = type;
@@ -65,8 +54,7 @@ int FAST_FUNC xrtnl_wilddump_request(struct rtnl_handle *rth, int family, int ty
65 req.nlh.nlmsg_seq = rth->dump = ++rth->seq; 54 req.nlh.nlmsg_seq = rth->dump = ++rth->seq;
66 req.g.rtgen_family = family; 55 req.g.rtgen_family = family;
67 56
68 return xsendto(rth->fd, (void*)&req, sizeof(req), 57 return rtnl_send(rth, (void*)&req, sizeof(req));
69 (struct sockaddr*)&nladdr, sizeof(nladdr));
70} 58}
71 59
72int FAST_FUNC rtnl_send(struct rtnl_handle *rth, char *buf, int len) 60int FAST_FUNC rtnl_send(struct rtnl_handle *rth, char *buf, int len)
@@ -339,8 +327,10 @@ int FAST_FUNC addattr32(struct nlmsghdr *n, int maxlen, int type, uint32_t data)
339{ 327{
340 int len = RTA_LENGTH(4); 328 int len = RTA_LENGTH(4);
341 struct rtattr *rta; 329 struct rtattr *rta;
342 if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) 330
331 if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) {
343 return -1; 332 return -1;
333 }
344 rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); 334 rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len));
345 rta->rta_type = type; 335 rta->rta_type = type;
346 rta->rta_len = len; 336 rta->rta_len = len;
@@ -354,8 +344,9 @@ int FAST_FUNC addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, in
354 int len = RTA_LENGTH(alen); 344 int len = RTA_LENGTH(alen);
355 struct rtattr *rta; 345 struct rtattr *rta;
356 346
357 if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) 347 if ((int)(NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) {
358 return -1; 348 return -1;
349 }
359 rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len)); 350 rta = (struct rtattr*)(((char*)n) + NLMSG_ALIGN(n->nlmsg_len));
360 rta->rta_type = type; 351 rta->rta_type = type;
361 rta->rta_len = len; 352 rta->rta_len = len;
@@ -397,7 +388,7 @@ int FAST_FUNC rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data
397} 388}
398 389
399 390
400int FAST_FUNC parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) 391void FAST_FUNC parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
401{ 392{
402 while (RTA_OK(rta, len)) { 393 while (RTA_OK(rta, len)) {
403 if (rta->rta_type <= max) { 394 if (rta->rta_type <= max) {
@@ -408,5 +399,4 @@ int FAST_FUNC parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int
408 if (len) { 399 if (len) {
409 bb_error_msg("deficit %d, rta_len=%d!", len, rta->rta_len); 400 bb_error_msg("deficit %d, rta_len=%d!", len, rta->rta_len);
410 } 401 }
411 return 0;
412} 402}
diff --git a/networking/libiproute/libnetlink.h b/networking/libiproute/libnetlink.h
index 41ecfa6d0..4e4d5b7b9 100644
--- a/networking/libiproute/libnetlink.h
+++ b/networking/libiproute/libnetlink.h
@@ -18,8 +18,8 @@ struct rtnl_handle {
18 uint32_t dump; 18 uint32_t dump;
19}; 19};
20 20
21extern int xrtnl_open(struct rtnl_handle *rth) FAST_FUNC; 21extern void xrtnl_open(struct rtnl_handle *rth) FAST_FUNC;
22extern void rtnl_close(struct rtnl_handle *rth) FAST_FUNC; 22#define rtnl_close(rth) (close((rth)->fd))
23extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type) FAST_FUNC; 23extern int xrtnl_wilddump_request(struct rtnl_handle *rth, int fam, int type) FAST_FUNC;
24extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) FAST_FUNC; 24extern int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req, int len) FAST_FUNC;
25extern int xrtnl_dump_filter(struct rtnl_handle *rth, 25extern int xrtnl_dump_filter(struct rtnl_handle *rth,
@@ -42,7 +42,7 @@ extern int addattr_l(struct nlmsghdr *n, int maxlen, int type, void *data, int a
42extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data) FAST_FUNC; 42extern int rta_addattr32(struct rtattr *rta, int maxlen, int type, uint32_t data) FAST_FUNC;
43extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen) FAST_FUNC; 43extern int rta_addattr_l(struct rtattr *rta, int maxlen, int type, void *data, int alen) FAST_FUNC;
44 44
45extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) FAST_FUNC; 45extern void parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len) FAST_FUNC;
46 46
47POP_SAVED_FUNCTION_VISIBILITY 47POP_SAVED_FUNCTION_VISIBILITY
48 48
diff --git a/networking/libiproute/ll_proto.c b/networking/libiproute/ll_proto.c
index 145902b2e..1cd576f1d 100644
--- a/networking/libiproute/ll_proto.c
+++ b/networking/libiproute/ll_proto.c
@@ -126,4 +126,3 @@ int FAST_FUNC ll_proto_a2n(unsigned short *id, char *buf)
126 *id = htons(i); 126 *id = htons(i);
127 return 0; 127 return 0;
128} 128}
129
diff --git a/networking/nc.c b/networking/nc.c
index 0dacaf117..c77137480 100644
--- a/networking/nc.c
+++ b/networking/nc.c
@@ -34,7 +34,7 @@
34//config: 34//config:
35//config:config NC_110_COMPAT 35//config:config NC_110_COMPAT
36//config: bool "Netcat 1.10 compatibility (+2.5k)" 36//config: bool "Netcat 1.10 compatibility (+2.5k)"
37//config: default y 37//config: default n # off specially for Rob
38//config: depends on NC 38//config: depends on NC
39//config: help 39//config: help
40//config: This option makes nc closely follow original nc-1.10. 40//config: This option makes nc closely follow original nc-1.10.
diff --git a/networking/ntpd.c b/networking/ntpd.c
index 14c3a5fbb..e9cfdbddd 100644
--- a/networking/ntpd.c
+++ b/networking/ntpd.c
@@ -592,7 +592,6 @@ filter_datapoints(peer_t *p)
592 p->filter_offset, x, 592 p->filter_offset, x,
593 p->filter_dispersion, 593 p->filter_dispersion,
594 p->filter_jitter); 594 p->filter_jitter);
595
596} 595}
597 596
598static void 597static void
@@ -2061,7 +2060,6 @@ int ntpd_main(int argc UNUSED_PARAM, char **argv)
2061static double 2060static double
2062direct_freq(double fp_offset) 2061direct_freq(double fp_offset)
2063{ 2062{
2064
2065#ifdef KERNEL_PLL 2063#ifdef KERNEL_PLL
2066 /* 2064 /*
2067 * If the kernel is enabled, we need the residual offset to 2065 * If the kernel is enabled, we need the residual offset to
diff --git a/networking/tcpudp.c b/networking/tcpudp.c
index 53e622b56..40f68258e 100644
--- a/networking/tcpudp.c
+++ b/networking/tcpudp.c
@@ -30,9 +30,12 @@
30 */ 30 */
31 31
32#include "libbb.h" 32#include "libbb.h"
33
33/* Wants <limits.h> etc, thus included after libbb.h: */ 34/* Wants <limits.h> etc, thus included after libbb.h: */
35#ifdef __linux__
34#include <linux/types.h> /* for __be32 etc */ 36#include <linux/types.h> /* for __be32 etc */
35#include <linux/netfilter_ipv4.h> 37#include <linux/netfilter_ipv4.h>
38#endif
36 39
37// TODO: move into this file: 40// TODO: move into this file:
38#include "tcpudp_perhost.h" 41#include "tcpudp_perhost.h"
@@ -464,6 +467,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
464 /* setup ucspi env */ 467 /* setup ucspi env */
465 const char *proto = tcp ? "TCP" : "UDP"; 468 const char *proto = tcp ? "TCP" : "UDP";
466 469
470#ifdef SO_ORIGINAL_DST
467 /* Extract "original" destination addr:port 471 /* Extract "original" destination addr:port
468 * from Linux firewall. Useful when you redirect 472 * from Linux firewall. Useful when you redirect
469 * an outbond connection to local handler, and it needs 473 * an outbond connection to local handler, and it needs
@@ -473,6 +477,7 @@ int tcpudpsvd_main(int argc UNUSED_PARAM, char **argv)
473 xsetenv_plain("TCPORIGDSTADDR", addr); 477 xsetenv_plain("TCPORIGDSTADDR", addr);
474 free(addr); 478 free(addr);
475 } 479 }
480#endif
476 xsetenv_plain("PROTO", proto); 481 xsetenv_plain("PROTO", proto);
477 xsetenv_proto(proto, "LOCALADDR", local_addr); 482 xsetenv_proto(proto, "LOCALADDR", local_addr);
478 xsetenv_proto(proto, "REMOTEADDR", remote_addr); 483 xsetenv_proto(proto, "REMOTEADDR", remote_addr);
diff --git a/networking/telnet.c b/networking/telnet.c
index 57997f6b9..e0022b2cb 100644
--- a/networking/telnet.c
+++ b/networking/telnet.c
@@ -150,7 +150,6 @@ static void con_escape(void)
150 cookmode(); 150 cookmode();
151 ret: 151 ret:
152 bb_got_signal = 0; 152 bb_got_signal = 0;
153
154} 153}
155 154
156static void handle_net_output(int len) 155static void handle_net_output(int len)
diff --git a/networking/traceroute.c b/networking/traceroute.c
index 2d3e77011..c18fba8d0 100644
--- a/networking/traceroute.c
+++ b/networking/traceroute.c
@@ -666,7 +666,6 @@ packet_ok(int read_len, len_and_sockaddr *from_lsa,
666 return (type == ICMP6_TIME_EXCEEDED ? -1 : (code<<8)+1); 666 return (type == ICMP6_TIME_EXCEEDED ? -1 : (code<<8)+1);
667 } 667 }
668 } 668 }
669
670 } 669 }
671 670
672# if ENABLE_FEATURE_TRACEROUTE_VERBOSE 671# if ENABLE_FEATURE_TRACEROUTE_VERBOSE
diff --git a/networking/udhcp/Config.src b/networking/udhcp/Config.src
index aac88569b..331dffc2e 100644
--- a/networking/udhcp/Config.src
+++ b/networking/udhcp/Config.src
@@ -8,6 +8,7 @@ INSERT
8config UDHCPD 8config UDHCPD
9 bool "udhcp server (udhcpd)" 9 bool "udhcp server (udhcpd)"
10 default y 10 default y
11 depends on PLATFORM_LINUX
11 help 12 help
12 udhcpd is a DHCP server geared primarily toward embedded systems, 13 udhcpd is a DHCP server geared primarily toward embedded systems,
13 while striving to be fully functional and RFC compliant. 14 while striving to be fully functional and RFC compliant.
@@ -51,6 +52,7 @@ config DHCPD_LEASES_FILE
51config UDHCPC 52config UDHCPC
52 bool "udhcp client (udhcpc)" 53 bool "udhcp client (udhcpc)"
53 default y 54 default y
55 depends on PLATFORM_LINUX
54 help 56 help
55 udhcpc is a DHCP client geared primarily toward embedded systems, 57 udhcpc is a DHCP client geared primarily toward embedded systems,
56 while striving to be fully functional and RFC compliant. 58 while striving to be fully functional and RFC compliant.
diff --git a/procps/Config.src b/procps/Config.src
index e61de5614..1ff6dfd30 100644
--- a/procps/Config.src
+++ b/procps/Config.src
@@ -10,6 +10,7 @@ INSERT
10config FREE 10config FREE
11 bool "free" 11 bool "free"
12 default y 12 default y
13 depends on PLATFORM_LINUX #sysinfo()
13 help 14 help
14 free displays the total amount of free and used physical and swap 15 free displays the total amount of free and used physical and swap
15 memory in the system, as well as the buffers used by the kernel. 16 memory in the system, as well as the buffers used by the kernel.
@@ -104,7 +105,7 @@ config FEATURE_PS_WIDE
104config FEATURE_PS_TIME 105config FEATURE_PS_TIME
105 bool "Enable time and elapsed time output" 106 bool "Enable time and elapsed time output"
106 default y 107 default y
107 depends on PS && DESKTOP 108 depends on PS && DESKTOP && PLATFORM_LINUX #sysinfo()
108 help 109 help
109 Support -o time and -o etime output specifiers. 110 Support -o time and -o etime output specifiers.
110 111
@@ -200,6 +201,7 @@ config FEATURE_SHOW_THREADS
200config UPTIME 201config UPTIME
201 bool "uptime" 202 bool "uptime"
202 default y 203 default y
204 depends on PLATFORM_LINUX #sysinfo()
203 help 205 help
204 uptime gives a one line display of the current time, how long 206 uptime gives a one line display of the current time, how long
205 the system has been running, how many users are currently logged 207 the system has been running, how many users are currently logged
diff --git a/procps/mpstat.c b/procps/mpstat.c
new file mode 100644
index 000000000..7610a68fb
--- /dev/null
+++ b/procps/mpstat.c
@@ -0,0 +1,1017 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Per-processor statistics, based on sysstat version 9.1.2 by Sebastien Godard
4 *
5 * Copyright (C) 2010 Marek Polacek <mmpolacek@gmail.com>
6 *
7 * Licensed under GPLv2, see file License in this tarball for details.
8 */
9
10//applet:IF_MPSTAT(APPLET(mpstat, _BB_DIR_BIN, _BB_SUID_DROP))
11
12//kbuild:lib-$(CONFIG_MPSTAT) += mpstat.o
13
14//config:config MPSTAT
15//config: bool "mpstat"
16//config: default y
17//config: help
18//config: Per-processor statistics
19
20#include "libbb.h"
21#include <sys/utsname.h> /* struct utsname */
22
23//#define debug(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
24#define debug(fmt, ...) ((void)0)
25
26/* Size of /proc/interrupts line, CPU data excluded */
27#define INTERRUPTS_LINE 64
28/* Maximum number of interrupts */
29#define NR_IRQS 256
30#define NR_IRQCPU_PREALLOC 3
31#define MAX_IRQNAME_LEN 16
32#define MAX_PF_NAME 512
33/* sysstat 9.0.6 uses width 8, but newer code which also prints /proc/softirqs
34 * data needs more: "interrupts" in /proc/softirqs have longer names,
35 * most are up to 8 chars, one (BLOCK_IOPOLL) is even longer.
36 * We are printing headers in the " IRQNAME/s" form, experimentally
37 * anything smaller than 10 chars looks ugly for /proc/softirqs stats.
38 */
39#define INTRATE_SCRWIDTH 10
40#define INTRATE_SCRWIDTH_STR "10"
41
42/* System files */
43#define SYSFS_DEVCPU "/sys/devices/system/cpu"
44#define PROCFS_STAT "/proc/stat"
45#define PROCFS_INTERRUPTS "/proc/interrupts"
46#define PROCFS_SOFTIRQS "/proc/softirqs"
47#define PROCFS_UPTIME "/proc/uptime"
48
49
50#if 1
51typedef unsigned long long data_t;
52typedef long long idata_t;
53#define FMT_DATA "ll"
54#define DATA_MAX ULLONG_MAX
55#else
56typedef unsigned long data_t;
57typedef long idata_t;
58#define FMT_DATA "l"
59#define DATA_MAX ULONG_MAX
60#endif
61
62
63struct stats_irqcpu {
64 unsigned interrupt;
65 char irq_name[MAX_IRQNAME_LEN];
66};
67
68struct stats_cpu {
69 data_t cpu_user;
70 data_t cpu_nice;
71 data_t cpu_system;
72 data_t cpu_idle;
73 data_t cpu_iowait;
74 data_t cpu_steal;
75 data_t cpu_irq;
76 data_t cpu_softirq;
77 data_t cpu_guest;
78};
79
80struct stats_irq {
81 data_t irq_nr;
82};
83
84
85/* Globals. Sort by size and access frequency. */
86struct globals {
87 int interval;
88 int count;
89 unsigned cpu_nr; /* Number of CPUs */
90 unsigned irqcpu_nr; /* Number of interrupts per CPU */
91 unsigned softirqcpu_nr; /* Number of soft interrupts per CPU */
92 unsigned options;
93 unsigned hz;
94 unsigned cpu_bitmap_len;
95 smallint p_option;
96 // 9.0.6 does not do it. Try "mpstat -A 1 2" - headers are repeated!
97 //smallint header_done;
98 //smallint avg_header_done;
99 unsigned char *cpu_bitmap; /* Bit 0: global, bit 1: 1st proc... */
100 data_t global_uptime[3];
101 data_t per_cpu_uptime[3];
102 struct stats_cpu *st_cpu[3];
103 struct stats_irq *st_irq[3];
104 struct stats_irqcpu *st_irqcpu[3];
105 struct stats_irqcpu *st_softirqcpu[3];
106 struct tm timestamp[3];
107};
108#define G (*ptr_to_globals)
109#define INIT_G() do { \
110 SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
111} while (0)
112
113/* The selected interrupts statistics (bits in G.options) */
114enum {
115 D_CPU = 1 << 0,
116 D_IRQ_SUM = 1 << 1,
117 D_IRQ_CPU = 1 << 2,
118 D_SOFTIRQS = 1 << 3,
119};
120
121
122/* Does str start with "cpu"? */
123static int starts_with_cpu(const char *str)
124{
125 return !((str[0] - 'c') | (str[1] - 'p') | (str[2] - 'u'));
126}
127
128/* Is option on? */
129static ALWAYS_INLINE int display_opt(int opt)
130{
131 return (opt & G.options);
132}
133
134#if DATA_MAX > 0xffffffff
135/*
136 * Handle overflow conditions properly for counters which can have
137 * less bits than data_t, depending on the kernel version.
138 */
139/* Surprisingly, on 32bit inlining is a size win */
140static ALWAYS_INLINE data_t overflow_safe_sub(data_t prev, data_t curr)
141{
142 data_t v = curr - prev;
143
144 if ((idata_t)v < 0 /* curr < prev - counter overflow? */
145 && prev <= 0xffffffff /* kernel uses 32bit value for the counter? */
146 ) {
147 /* Add 33th bit set to 1 to curr, compensating for the overflow */
148 /* double shift defeats "warning: left shift count >= width of type" */
149 v += ((data_t)1 << 16) << 16;
150 }
151 return v;
152}
153#else
154static ALWAYS_INLINE data_t overflow_safe_sub(data_t prev, data_t curr)
155{
156 return curr - prev;
157}
158#endif
159
160static double percent_value(data_t prev, data_t curr, data_t itv)
161{
162 return ((double)overflow_safe_sub(prev, curr)) / itv * 100;
163}
164
165static double hz_value(data_t prev, data_t curr, data_t itv)
166{
167 //bb_error_msg("curr:%lld prev:%lld G.hz:%u", curr, prev, G.hz);
168 return ((double)overflow_safe_sub(prev, curr)) / itv * G.hz;
169}
170
171static ALWAYS_INLINE data_t jiffies_diff(data_t old, data_t new)
172{
173 data_t diff = new - old;
174 return (diff == 0) ? 1 : diff;
175}
176
177static int is_cpu_in_bitmap(unsigned cpu)
178{
179 return G.cpu_bitmap[cpu >> 3] & (1 << (cpu & 7));
180}
181
182static void write_irqcpu_stats(struct stats_irqcpu *per_cpu_stats[],
183 int total_irqs,
184 data_t itv,
185 int prev, int current,
186 const char *prev_str, const char *current_str)
187{
188 int j;
189 int offset, cpu;
190 struct stats_irqcpu *p0, *q0;
191
192 /* Check if number of IRQs has changed */
193 if (G.interval != 0) {
194 for (j = 0; j <= total_irqs; j++) {
195 p0 = &per_cpu_stats[current][j];
196 if (p0->irq_name[0] != '\0') {
197 q0 = &per_cpu_stats[prev][j];
198 if (strcmp(p0->irq_name, q0->irq_name) != 0) {
199 /* Strings are different */
200 break;
201 }
202 }
203 }
204 }
205
206 /* Print header */
207 printf("\n%-11s CPU", prev_str);
208 {
209 /* A bit complex code to "buy back" space if one header is too wide.
210 * Here's how it looks like. BLOCK_IOPOLL eats too much space,
211 * and latter headers use smaller width to compensate:
212 * ...BLOCK/s BLOCK_IOPOLL/s TASKLET/s SCHED/s HRTIMER/s RCU/s
213 * ... 2.32 0.00 0.01 17.58 0.14 141.96
214 */
215 int expected_len = 0;
216 int printed_len = 0;
217 for (j = 0; j < total_irqs; j++) {
218 p0 = &per_cpu_stats[current][j];
219 if (p0->irq_name[0] != '\0') {
220 int n = (INTRATE_SCRWIDTH-3) - (printed_len - expected_len);
221 printed_len += printf(" %*s/s", n > 0 ? n : 0, skip_whitespace(p0->irq_name));
222 expected_len += INTRATE_SCRWIDTH;
223 }
224 }
225 }
226 bb_putchar('\n');
227
228 for (cpu = 1; cpu <= G.cpu_nr; cpu++) {
229 /* Check if we want stats about this CPU */
230 if (!is_cpu_in_bitmap(cpu) && G.p_option) {
231 continue;
232 }
233
234 printf("%-11s %4u", current_str, cpu - 1);
235
236 for (j = 0; j < total_irqs; j++) {
237 /* IRQ field set only for proc 0 */
238 p0 = &per_cpu_stats[current][j];
239
240 /*
241 * An empty string for irq name means that
242 * interrupt is no longer used.
243 */
244 if (p0->irq_name[0] != '\0') {
245 offset = j;
246 q0 = &per_cpu_stats[prev][offset];
247
248 /*
249 * If we want stats for the time since boot
250 * we have p0->irq != q0->irq.
251 */
252 if (strcmp(p0->irq_name, q0->irq_name) != 0
253 && G.interval != 0
254 ) {
255 if (j) {
256 offset = j - 1;
257 q0 = &per_cpu_stats[prev][offset];
258 }
259 if (strcmp(p0->irq_name, q0->irq_name) != 0
260 && (j + 1 < total_irqs)
261 ) {
262 offset = j + 1;
263 q0 = &per_cpu_stats[prev][offset];
264 }
265 }
266
267 if (strcmp(p0->irq_name, q0->irq_name) == 0
268 || G.interval == 0
269 ) {
270 struct stats_irqcpu *p, *q;
271 p = &per_cpu_stats[current][(cpu - 1) * total_irqs + j];
272 q = &per_cpu_stats[prev][(cpu - 1) * total_irqs + offset];
273 printf("%"INTRATE_SCRWIDTH_STR".2f",
274 (double)(p->interrupt - q->interrupt) / itv * G.hz);
275 } else {
276 printf(" N/A");
277 }
278 }
279 }
280 bb_putchar('\n');
281 }
282}
283
284static data_t get_per_cpu_interval(const struct stats_cpu *scc,
285 const struct stats_cpu *scp)
286{
287 return ((scc->cpu_user + scc->cpu_nice +
288 scc->cpu_system + scc->cpu_iowait +
289 scc->cpu_idle + scc->cpu_steal +
290 scc->cpu_irq + scc->cpu_softirq) -
291 (scp->cpu_user + scp->cpu_nice +
292 scp->cpu_system + scp->cpu_iowait +
293 scp->cpu_idle + scp->cpu_steal +
294 scp->cpu_irq + scp->cpu_softirq));
295}
296
297static void print_stats_cpu_struct(const struct stats_cpu *p,
298 const struct stats_cpu *c,
299 data_t itv)
300{
301 printf(" %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f\n",
302 percent_value(p->cpu_user - p->cpu_guest,
303 /**/ c->cpu_user - c->cpu_guest, itv),
304 percent_value(p->cpu_nice , c->cpu_nice , itv),
305 percent_value(p->cpu_system , c->cpu_system , itv),
306 percent_value(p->cpu_iowait , c->cpu_iowait , itv),
307 percent_value(p->cpu_irq , c->cpu_irq , itv),
308 percent_value(p->cpu_softirq, c->cpu_softirq, itv),
309 percent_value(p->cpu_steal , c->cpu_steal , itv),
310 percent_value(p->cpu_guest , c->cpu_guest , itv),
311 percent_value(p->cpu_idle , c->cpu_idle , itv)
312 );
313}
314
315static void write_stats_core(int prev, int current,
316 const char *prev_str, const char *current_str)
317{
318 struct stats_cpu *scc, *scp;
319 data_t itv, global_itv;
320 int cpu;
321
322 /* Compute time interval */
323 itv = global_itv = jiffies_diff(G.global_uptime[prev], G.global_uptime[current]);
324
325 /* Reduce interval to one CPU */
326 if (G.cpu_nr > 1)
327 itv = jiffies_diff(G.per_cpu_uptime[prev], G.per_cpu_uptime[current]);
328
329 /* Print CPU stats */
330 if (display_opt(D_CPU)) {
331
332 ///* This is done exactly once */
333 //if (!G.header_done) {
334 printf("\n%-11s CPU %%usr %%nice %%sys %%iowait %%irq %%soft %%steal %%guest %%idle\n",
335 prev_str
336 );
337 // G.header_done = 1;
338 //}
339
340 for (cpu = 0; cpu <= G.cpu_nr; cpu++) {
341 data_t per_cpu_itv;
342
343 /* Print stats about this particular CPU? */
344 if (!is_cpu_in_bitmap(cpu))
345 continue;
346
347 scc = &G.st_cpu[current][cpu];
348 scp = &G.st_cpu[prev][cpu];
349 per_cpu_itv = global_itv;
350
351 printf((cpu ? "%-11s %4u" : "%-11s all"), current_str, cpu - 1);
352 if (cpu) {
353 double idle;
354 /*
355 * If the CPU is offline, then it isn't in /proc/stat,
356 * so all values are 0.
357 * NB: Guest time is already included in user time.
358 */
359 if ((scc->cpu_user | scc->cpu_nice | scc->cpu_system |
360 scc->cpu_iowait | scc->cpu_idle | scc->cpu_steal |
361 scc->cpu_irq | scc->cpu_softirq) == 0
362 ) {
363 /*
364 * Set current struct fields to values from prev.
365 * iteration. Then their values won't jump from
366 * zero, when the CPU comes back online.
367 */
368 *scc = *scp;
369 idle = 0.0;
370 goto print_zeros;
371 }
372 /* Compute interval again for current proc */
373 per_cpu_itv = get_per_cpu_interval(scc, scp);
374 if (per_cpu_itv == 0) {
375 /*
376 * If the CPU is tickless then there is no change in CPU values
377 * but the sum of values is not zero.
378 */
379 idle = 100.0;
380 print_zeros:
381 printf(" %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f %7.2f\n",
382 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, idle);
383 continue;
384 }
385 }
386 print_stats_cpu_struct(scp, scc, per_cpu_itv);
387 }
388 }
389
390 /* Print total number of IRQs per CPU */
391 if (display_opt(D_IRQ_SUM)) {
392
393 ///* Print average header, this is done exactly once */
394 //if (!G.avg_header_done) {
395 printf("\n%-11s CPU intr/s\n", prev_str);
396 // G.avg_header_done = 1;
397 //}
398
399 for (cpu = 0; cpu <= G.cpu_nr; cpu++) {
400 data_t per_cpu_itv;
401
402 /* Print stats about this CPU? */
403 if (!is_cpu_in_bitmap(cpu))
404 continue;
405
406 per_cpu_itv = itv;
407 printf((cpu ? "%-11s %4u" : "%-11s all"), current_str, cpu - 1);
408 if (cpu) {
409 scc = &G.st_cpu[current][cpu];
410 scp = &G.st_cpu[prev][cpu];
411 /* Compute interval again for current proc */
412 per_cpu_itv = get_per_cpu_interval(scc, scp);
413 if (per_cpu_itv == 0) {
414 printf(" %9.2f\n", 0.0);
415 continue;
416 }
417 }
418 //bb_error_msg("G.st_irq[%u][%u].irq_nr:%lld - G.st_irq[%u][%u].irq_nr:%lld",
419 // current, cpu, G.st_irq[prev][cpu].irq_nr, prev, cpu, G.st_irq[current][cpu].irq_nr);
420 printf(" %9.2f\n", hz_value(G.st_irq[prev][cpu].irq_nr, G.st_irq[current][cpu].irq_nr, per_cpu_itv));
421 }
422 }
423
424 if (display_opt(D_IRQ_CPU)) {
425 write_irqcpu_stats(G.st_irqcpu, G.irqcpu_nr,
426 itv,
427 prev, current,
428 prev_str, current_str
429 );
430 }
431
432 if (display_opt(D_SOFTIRQS)) {
433 write_irqcpu_stats(G.st_softirqcpu, G.softirqcpu_nr,
434 itv,
435 prev, current,
436 prev_str, current_str
437 );
438 }
439}
440
441/*
442 * Print the statistics
443 */
444static void write_stats(int current)
445{
446 char prev_time[16];
447 char curr_time[16];
448
449 strftime(prev_time, sizeof(prev_time), "%X", &G.timestamp[!current]);
450 strftime(curr_time, sizeof(curr_time), "%X", &G.timestamp[current]);
451
452 write_stats_core(!current, current, prev_time, curr_time);
453}
454
455static void write_stats_avg(int current)
456{
457 write_stats_core(2, current, "Average:", "Average:");
458}
459
460/*
461 * Read CPU statistics
462 */
463static void get_cpu_statistics(struct stats_cpu *cpu, data_t *up, data_t *up0)
464{
465 FILE *fp;
466 char buf[1024];
467
468 fp = xfopen_for_read(PROCFS_STAT);
469
470 while (fgets(buf, sizeof(buf), fp)) {
471 data_t sum;
472 unsigned cpu_number;
473 struct stats_cpu *cp;
474
475 if (!starts_with_cpu(buf))
476 continue; /* not "cpu" */
477
478 cp = cpu; /* for "cpu " case */
479 if (buf[3] != ' ') {
480 /* "cpuN " */
481 if (G.cpu_nr == 0
482 || sscanf(buf + 3, "%u ", &cpu_number) != 1
483 || cpu_number >= G.cpu_nr
484 ) {
485 continue;
486 }
487 cp = &cpu[cpu_number + 1];
488 }
489
490 /* Read the counters, save them */
491 /* Not all fields have to be present */
492 memset(cp, 0, sizeof(*cp));
493 sscanf(buf, "%*s"
494 " %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u"
495 " %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u"
496 " %"FMT_DATA"u %"FMT_DATA"u %"FMT_DATA"u",
497 &cp->cpu_user, &cp->cpu_nice, &cp->cpu_system,
498 &cp->cpu_idle, &cp->cpu_iowait, &cp->cpu_irq,
499 &cp->cpu_softirq, &cp->cpu_steal, &cp->cpu_guest
500 );
501 /*
502 * Compute uptime in jiffies (1/HZ), it'll be the sum of
503 * individual CPU's uptimes.
504 * NB: We have to omit cpu_guest, because cpu_user includes it.
505 */
506 sum = cp->cpu_user + cp->cpu_nice + cp->cpu_system +
507 cp->cpu_idle + cp->cpu_iowait + cp->cpu_irq +
508 cp->cpu_softirq + cp->cpu_steal;
509
510 if (buf[3] == ' ') {
511 /* "cpu " */
512 *up = sum;
513 } else {
514 /* "cpuN " */
515 if (cpu_number == 0 && *up0 != 0) {
516 /* Compute uptime of single CPU */
517 *up0 = sum;
518 }
519 }
520 }
521 fclose(fp);
522}
523
524/*
525 * Read IRQs from /proc/stat
526 */
527static void get_irqs_from_stat(struct stats_irq *irq)
528{
529 FILE *fp;
530 char buf[1024];
531
532 fp = fopen_for_read(PROCFS_STAT);
533 if (!fp)
534 return;
535
536 while (fgets(buf, sizeof(buf), fp)) {
537 //bb_error_msg("/proc/stat:'%s'", buf);
538 if (strncmp(buf, "intr ", 5) == 0) {
539 /* Read total number of IRQs since system boot */
540 sscanf(buf + 5, "%"FMT_DATA"u", &irq->irq_nr);
541 }
542 }
543
544 fclose(fp);
545}
546
547/*
548 * Read stats from /proc/interrupts or /proc/softirqs
549 */
550static void get_irqs_from_interrupts(const char *fname,
551 struct stats_irqcpu *per_cpu_stats[],
552 int irqs_per_cpu, int current)
553{
554 FILE *fp;
555 struct stats_irq *irq_i;
556 struct stats_irqcpu *ic;
557 char *buf;
558 unsigned buflen;
559 unsigned cpu;
560 unsigned irq;
561 int cpu_index[G.cpu_nr];
562 int iindex;
563
564// Moved to caller.
565// Otherwise reading of /proc/softirqs
566// was resetting counts to 0 after we painstakingly collected them from
567// /proc/interrupts. Which resulted in:
568// 01:32:47 PM CPU intr/s
569// 01:32:47 PM all 591.47
570// 01:32:47 PM 0 0.00 <= ???
571// 01:32:47 PM 1 0.00 <= ???
572// for (cpu = 1; cpu <= G.cpu_nr; cpu++) {
573// G.st_irq[current][cpu].irq_nr = 0;
574// //bb_error_msg("G.st_irq[%u][%u].irq_nr=0", current, cpu);
575// }
576
577 fp = fopen_for_read(fname);
578 if (!fp)
579 return;
580
581 buflen = INTERRUPTS_LINE + 16 * G.cpu_nr;
582 buf = xmalloc(buflen);
583
584 /* Parse header and determine, which CPUs are online */
585 iindex = 0;
586 while (fgets(buf, buflen, fp)) {
587 char *cp, *next;
588 next = buf;
589 while ((cp = strstr(next, "CPU")) != NULL
590 && iindex < G.cpu_nr
591 ) {
592 cpu = strtoul(cp + 3, &next, 10);
593 cpu_index[iindex++] = cpu;
594 }
595 if (iindex) /* We found header */
596 break;
597 }
598
599 irq = 0;
600 while (fgets(buf, buflen, fp)
601 && irq < irqs_per_cpu
602 ) {
603 int len;
604 char last_char;
605 char *cp;
606
607 /* Skip over "IRQNAME:" */
608 cp = strchr(buf, ':');
609 if (!cp)
610 continue;
611 last_char = cp[-1];
612
613 ic = &per_cpu_stats[current][irq];
614 len = cp - buf;
615 if (len >= sizeof(ic->irq_name)) {
616 len = sizeof(ic->irq_name) - 1;
617 }
618 safe_strncpy(ic->irq_name, buf, len + 1);
619 //bb_error_msg("%s: irq%d:'%s' buf:'%s'", fname, irq, ic->irq_name, buf);
620 cp++;
621
622 for (cpu = 0; cpu < iindex; cpu++) {
623 char *next;
624 ic = &per_cpu_stats[current][cpu_index[cpu] * irqs_per_cpu + irq];
625 irq_i = &G.st_irq[current][cpu_index[cpu] + 1];
626 ic->interrupt = strtoul(cp, &next, 10);
627 /* Count only numerical IRQs */
628 if (isdigit(last_char)) {
629 irq_i->irq_nr += ic->interrupt;
630 //bb_error_msg("G.st_irq[%u][%u].irq_nr + %u = %lld",
631 // current, cpu_index[cpu] + 1, ic->interrupt, irq_i->irq_nr);
632 }
633 cp = next;
634 }
635 irq++;
636 }
637 fclose(fp);
638 free(buf);
639
640 while (irq < irqs_per_cpu) {
641 /* Number of interrupts per CPU has changed */
642 ic = &per_cpu_stats[current][irq];
643 ic->irq_name[0] = '\0'; /* False interrupt */
644 irq++;
645 }
646}
647
648static void get_uptime(data_t *uptime)
649{
650 FILE *fp;
651 char buf[sizeof(long)*3 * 2 + 4]; /* enough for long.long */
652 unsigned long uptime_sec, decimal;
653
654 fp = fopen_for_read(PROCFS_UPTIME);
655 if (!fp)
656 return;
657 if (fgets(buf, sizeof(buf), fp)) {
658 if (sscanf(buf, "%lu.%lu", &uptime_sec, &decimal) == 2) {
659 *uptime = (data_t)uptime_sec * G.hz + decimal * G.hz / 100;
660 }
661 }
662
663 fclose(fp);
664}
665
666static void get_localtime(struct tm *tm)
667{
668 time_t timer;
669 time(&timer);
670 localtime_r(&timer, tm);
671}
672
673static void alarm_handler(int sig UNUSED_PARAM)
674{
675 signal(SIGALRM, alarm_handler);
676 alarm(G.interval);
677}
678
679static void main_loop(void)
680{
681 unsigned current;
682 unsigned cpus;
683
684 /* Read the stats */
685 if (G.cpu_nr > 1) {
686 G.per_cpu_uptime[0] = 0;
687 get_uptime(&G.per_cpu_uptime[0]);
688 }
689
690 get_cpu_statistics(G.st_cpu[0], &G.global_uptime[0], &G.per_cpu_uptime[0]);
691
692 if (display_opt(D_IRQ_SUM))
693 get_irqs_from_stat(G.st_irq[0]);
694
695 if (display_opt(D_IRQ_SUM | D_IRQ_CPU))
696 get_irqs_from_interrupts(PROCFS_INTERRUPTS, G.st_irqcpu,
697 G.irqcpu_nr, 0);
698
699 if (display_opt(D_SOFTIRQS))
700 get_irqs_from_interrupts(PROCFS_SOFTIRQS, G.st_softirqcpu,
701 G.softirqcpu_nr, 0);
702
703 if (G.interval == 0) {
704 /* Display since boot time */
705 cpus = G.cpu_nr + 1;
706 G.timestamp[1] = G.timestamp[0];
707 memset(G.st_cpu[1], 0, sizeof(G.st_cpu[1][0]) * cpus);
708 memset(G.st_irq[1], 0, sizeof(G.st_irq[1][0]) * cpus);
709 memset(G.st_irqcpu[1], 0, sizeof(G.st_irqcpu[1][0]) * cpus * G.irqcpu_nr);
710 memset(G.st_softirqcpu[1], 0, sizeof(G.st_softirqcpu[1][0]) * cpus * G.softirqcpu_nr);
711
712 write_stats(0);
713
714 /* And we're done */
715 return;
716 }
717
718 /* Set a handler for SIGALRM */
719 alarm_handler(0);
720
721 /* Save the stats we already have. We need them to compute the average */
722 G.timestamp[2] = G.timestamp[0];
723 G.global_uptime[2] = G.global_uptime[0];
724 G.per_cpu_uptime[2] = G.per_cpu_uptime[0];
725 cpus = G.cpu_nr + 1;
726 memcpy(G.st_cpu[2], G.st_cpu[0], sizeof(G.st_cpu[0][0]) * cpus);
727 memcpy(G.st_irq[2], G.st_irq[0], sizeof(G.st_irq[0][0]) * cpus);
728 memcpy(G.st_irqcpu[2], G.st_irqcpu[0], sizeof(G.st_irqcpu[0][0]) * cpus * G.irqcpu_nr);
729 if (display_opt(D_SOFTIRQS)) {
730 memcpy(G.st_softirqcpu[2], G.st_softirqcpu[0],
731 sizeof(G.st_softirqcpu[0][0]) * cpus * G.softirqcpu_nr);
732 }
733
734 current = 1;
735 while (1) {
736 /* Suspend until a signal is received */
737 pause();
738
739 /* Set structures to 0 to distinguish off/online CPUs */
740 memset(&G.st_cpu[current][/*cpu:*/ 1], 0, sizeof(G.st_cpu[0][0]) * G.cpu_nr);
741
742 get_localtime(&G.timestamp[current]);
743
744 /* Read stats */
745 if (G.cpu_nr > 1) {
746 G.per_cpu_uptime[current] = 0;
747 get_uptime(&G.per_cpu_uptime[current]);
748 }
749 get_cpu_statistics(G.st_cpu[current], &G.global_uptime[current], &G.per_cpu_uptime[current]);
750
751 if (display_opt(D_IRQ_SUM))
752 get_irqs_from_stat(G.st_irq[current]);
753
754 if (display_opt(D_IRQ_SUM | D_IRQ_CPU)) {
755 int cpu;
756 for (cpu = 1; cpu <= G.cpu_nr; cpu++) {
757 G.st_irq[current][cpu].irq_nr = 0;
758 }
759 /* accumulates .irq_nr */
760 get_irqs_from_interrupts(PROCFS_INTERRUPTS, G.st_irqcpu,
761 G.irqcpu_nr, current);
762 }
763
764 if (display_opt(D_SOFTIRQS))
765 get_irqs_from_interrupts(PROCFS_SOFTIRQS,
766 G.st_softirqcpu,
767 G.softirqcpu_nr, current);
768
769 write_stats(current);
770
771 if (G.count > 0) {
772 if (--G.count == 0)
773 break;
774 }
775
776 current ^= 1;
777 }
778
779 /* Print average statistics */
780 write_stats_avg(current);
781}
782
783/* Initialization */
784
785/* Get number of clock ticks per sec */
786static ALWAYS_INLINE unsigned get_hz(void)
787{
788 return sysconf(_SC_CLK_TCK);
789}
790
791static void alloc_struct(int cpus)
792{
793 int i;
794 for (i = 0; i < 3; i++) {
795 G.st_cpu[i] = xzalloc(sizeof(G.st_cpu[i][0]) * cpus);
796 G.st_irq[i] = xzalloc(sizeof(G.st_irq[i][0]) * cpus);
797 G.st_irqcpu[i] = xzalloc(sizeof(G.st_irqcpu[i][0]) * cpus * G.irqcpu_nr);
798 G.st_softirqcpu[i] = xzalloc(sizeof(G.st_softirqcpu[i][0]) * cpus * G.softirqcpu_nr);
799 }
800 G.cpu_bitmap_len = (cpus >> 3) + 1;
801 G.cpu_bitmap = xzalloc(G.cpu_bitmap_len);
802}
803
804static void print_header(struct tm *t)
805{
806 char cur_date[16];
807 struct utsname uts;
808
809 /* Get system name, release number and hostname */
810 uname(&uts);
811
812 strftime(cur_date, sizeof(cur_date), "%x", t);
813
814 printf("%s %s (%s)\t%s\t_%s_\t(%u CPU)\n",
815 uts.sysname, uts.release, uts.nodename, cur_date, uts.machine, G.cpu_nr);
816}
817
818/*
819 * Get number of processors in /proc/stat
820 * Return value '0' means one CPU and non SMP kernel.
821 * Otherwise N means N processor(s) and SMP kernel.
822 */
823static int get_cpu_nr(void)
824{
825 FILE *fp;
826 char line[256];
827 int proc_nr = -1;
828
829 fp = xfopen_for_read(PROCFS_STAT);
830 while (fgets(line, sizeof(line), fp)) {
831 if (!starts_with_cpu(line)) {
832 if (proc_nr >= 0)
833 break; /* we are past "cpuN..." lines */
834 continue;
835 }
836 if (line[3] != ' ') { /* "cpuN" */
837 int num_proc;
838 if (sscanf(line + 3, "%u", &num_proc) == 1
839 && num_proc > proc_nr
840 ) {
841 proc_nr = num_proc;
842 }
843 }
844 }
845
846 fclose(fp);
847 return proc_nr + 1;
848}
849
850/*
851 * Get number of interrupts available per processor
852 */
853static int get_irqcpu_nr(const char *f, int max_irqs)
854{
855 FILE *fp;
856 char *line;
857 unsigned linelen;
858 unsigned irq;
859
860 fp = fopen_for_read(f);
861 if (!fp) /* No interrupts file */
862 return 0;
863
864 linelen = INTERRUPTS_LINE + 16 * G.cpu_nr;
865 line = xmalloc(linelen);
866
867 irq = 0;
868 while (fgets(line, linelen, fp)
869 && irq < max_irqs
870 ) {
871 int p = strcspn(line, ":");
872 if ((p > 0) && (p < 16))
873 irq++;
874 }
875
876 fclose(fp);
877 free(line);
878
879 return irq;
880}
881
882//usage:#define mpstat_trivial_usage
883//usage: "[-A] [-I SUM|CPU|ALL|SCPU] [-u] [-P num|ALL] [INTERVAL [COUNT]]"
884//usage:#define mpstat_full_usage "\n\n"
885//usage: "Per-processor statistics\n"
886//usage: "\nOptions:"
887//usage: "\n -A Same as -I ALL -u -P ALL"
888//usage: "\n -I SUM|CPU|ALL|SCPU Report interrupt statistics"
889//usage: "\n -P num|ALL Processor to monitor"
890//usage: "\n -u Report CPU utilization"
891
892int mpstat_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
893int mpstat_main(int UNUSED_PARAM argc, char **argv)
894{
895 char *opt_irq_fmt;
896 char *opt_set_cpu;
897 int i, opt;
898 enum {
899 OPT_ALL = 1 << 0, /* -A */
900 OPT_INTS = 1 << 1, /* -I */
901 OPT_SETCPU = 1 << 2, /* -P */
902 OPT_UTIL = 1 << 3, /* -u */
903 };
904
905 /* Dont buffer data if redirected to a pipe */
906 setbuf(stdout, NULL);
907
908 INIT_G();
909
910 G.interval = -1;
911
912 /* Get number of processors */
913 G.cpu_nr = get_cpu_nr();
914
915 /* Get number of clock ticks per sec */
916 G.hz = get_hz();
917
918 /* Calculate number of interrupts per processor */
919 G.irqcpu_nr = get_irqcpu_nr(PROCFS_INTERRUPTS, NR_IRQS) + NR_IRQCPU_PREALLOC;
920
921 /* Calculate number of soft interrupts per processor */
922 G.softirqcpu_nr = get_irqcpu_nr(PROCFS_SOFTIRQS, NR_IRQS) + NR_IRQCPU_PREALLOC;
923
924 /* Allocate space for structures. + 1 for global structure. */
925 alloc_struct(G.cpu_nr + 1);
926
927 /* Parse and process arguments */
928 opt = getopt32(argv, "AI:P:u", &opt_irq_fmt, &opt_set_cpu);
929 argv += optind;
930
931 if (*argv) {
932 /* Get interval */
933 G.interval = xatoi_u(*argv);
934 G.count = -1;
935 argv++;
936 if (*argv) {
937 /* Get count value */
938 if (G.interval == 0)
939 bb_show_usage();
940 G.count = xatoi_u(*argv);
941 //if (*++argv)
942 // bb_show_usage();
943 }
944 }
945 if (G.interval < 0)
946 G.interval = 0;
947
948 if (opt & OPT_ALL) {
949 G.p_option = 1;
950 G.options |= D_CPU + D_IRQ_SUM + D_IRQ_CPU + D_SOFTIRQS;
951 /* Select every CPU */
952 memset(G.cpu_bitmap, 0xff, G.cpu_bitmap_len);
953 }
954
955 if (opt & OPT_INTS) {
956 static const char v[] = {
957 D_IRQ_CPU, D_IRQ_SUM, D_SOFTIRQS,
958 D_IRQ_SUM + D_IRQ_CPU + D_SOFTIRQS
959 };
960 i = index_in_strings("CPU\0SUM\0SCPU\0ALL\0", opt_irq_fmt);
961 if (i == -1)
962 bb_show_usage();
963 G.options |= v[i];
964 }
965
966 if ((opt & OPT_UTIL) /* -u? */
967 || G.options == 0 /* nothing? (use default then) */
968 ) {
969 G.options |= D_CPU;
970 }
971
972 if (opt & OPT_SETCPU) {
973 char *t;
974 G.p_option = 1;
975
976 for (t = strtok(opt_set_cpu, ","); t; t = strtok(NULL, ",")) {
977 if (strcmp(t, "ALL") == 0) {
978 /* Select every CPU */
979 memset(G.cpu_bitmap, 0xff, G.cpu_bitmap_len);
980 } else {
981 /* Get CPU number */
982 unsigned n = xatoi_u(t);
983 if (n >= G.cpu_nr)
984 bb_error_msg_and_die("not that many processors");
985 n++;
986 G.cpu_bitmap[n >> 3] |= 1 << (n & 7);
987 }
988 }
989 }
990
991 if (!G.p_option)
992 /* Display global stats */
993 G.cpu_bitmap[0] = 1;
994
995 /* Get time */
996 get_localtime(&G.timestamp[0]);
997
998 /* Display header */
999 print_header(&G.timestamp[0]);
1000
1001 /* The main loop */
1002 main_loop();
1003
1004 if (ENABLE_FEATURE_CLEAN_UP) {
1005 /* Clean up */
1006 for (i = 0; i < 3; i++) {
1007 free(G.st_cpu[i]);
1008 free(G.st_irq[i]);
1009 free(G.st_irqcpu[i]);
1010 free(G.st_softirqcpu[i]);
1011 }
1012 free(G.cpu_bitmap);
1013 free(&G);
1014 }
1015
1016 return EXIT_SUCCESS;
1017}
diff --git a/scripts/Makefile.host b/scripts/Makefile.host
index 23bd9ff10..2e628508d 100644
--- a/scripts/Makefile.host
+++ b/scripts/Makefile.host
@@ -153,4 +153,3 @@ $(host-cshlib): %: $(host-cshobjs) FORCE
153 153
154targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\ 154targets += $(host-csingle) $(host-cmulti) $(host-cobjs)\
155 $(host-cxxmulti) $(host-cxxobjs) $(host-cshlib) $(host-cshobjs) 155 $(host-cxxmulti) $(host-cxxobjs) $(host-cshlib) $(host-cshobjs)
156
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index be679b624..3e54ea712 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -168,5 +168,3 @@ cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
168 168
169quiet_cmd_gzip = GZIP $@ 169quiet_cmd_gzip = GZIP $@
170cmd_gzip = gzip -f -9 < $< > $@ 170cmd_gzip = gzip -f -9 < $< > $@
171
172
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c
index 50ef37157..db30019d8 100644
--- a/scripts/basic/docproc.c
+++ b/scripts/basic/docproc.c
@@ -397,4 +397,3 @@ int main(int argc, char **argv)
397 fflush(stdout); 397 fflush(stdout);
398 return exitstatus; 398 return exitstatus;
399} 399}
400
diff --git a/scripts/find_stray_empty_lines b/scripts/find_stray_empty_lines
new file mode 100755
index 000000000..aae18f99b
--- /dev/null
+++ b/scripts/find_stray_empty_lines
@@ -0,0 +1,19 @@
1#!/bin/sh
2
3grep -n -B1 -r $'^\t*}$' . | grep -A1 '.[ch]-[0-9]*-$'
4grep -n -A1 -r $'^\t*{$' . | grep -B1 '.[ch]-[0-9]*-$'
5# or (less surefire ones):
6grep -n -B1 -r $'^\t*}' . | grep -A1 '.[ch]-[0-9]*-$'
7grep -n -A1 -r $'^\t*{' . | grep -B1 '.[ch]-[0-9]*-$'
8
9# find trailing empty lines
10find -type f | while read file; do
11 test x"$file" = x"" && continue
12 tail -n1 $file | while read lastline
13 do
14 #echo "|$file|$lastline"
15 if test x"$lastline" = x""; then
16 echo "$file"
17 fi
18 done
19done
diff --git a/scripts/gen_build_files.sh b/scripts/gen_build_files.sh
index 968158758..18c172d5a 100755
--- a/scripts/gen_build_files.sh
+++ b/scripts/gen_build_files.sh
@@ -53,8 +53,8 @@ fi
53 53
54 src="$srctree/$d/Kbuild.src" 54 src="$srctree/$d/Kbuild.src"
55 dst="$d/Kbuild" 55 dst="$d/Kbuild"
56 mkdir -p -- "$d" 2>/dev/null
57 if test -f "$src"; then 56 if test -f "$src"; then
57 mkdir -p -- "$d" 2>/dev/null
58 #echo " CHK $dst" 58 #echo " CHK $dst"
59 59
60 s=`sed -n 's@^//kbuild:@@p' -- "$srctree/$d"/*.c` 60 s=`sed -n 's@^//kbuild:@@p' -- "$srctree/$d"/*.c`
@@ -73,8 +73,8 @@ fi
73 73
74 src="$srctree/$d/Config.src" 74 src="$srctree/$d/Config.src"
75 dst="$d/Config.in" 75 dst="$d/Config.in"
76 mkdir -p -- "$d" 2>/dev/null
77 if test -f "$src"; then 76 if test -f "$src"; then
77 mkdir -p -- "$d" 2>/dev/null
78 #echo " CHK $dst" 78 #echo " CHK $dst"
79 79
80 s=`sed -n 's@^//config:@@p' -- "$srctree/$d"/*.c` 80 s=`sed -n 's@^//config:@@p' -- "$srctree/$d"/*.c`
diff --git a/scripts/kconfig/check.sh b/scripts/kconfig/check.sh
index fa59cbf9d..15fc29421 100755
--- a/scripts/kconfig/check.sh
+++ b/scripts/kconfig/check.sh
@@ -11,4 +11,3 @@ EOF
11if [ ! "$?" -eq "0" ]; then 11if [ ! "$?" -eq "0" ]; then
12 echo -DKBUILD_NO_NLS; 12 echo -DKBUILD_NO_NLS;
13fi 13fi
14
diff --git a/scripts/kconfig/lex.zconf.c_shipped b/scripts/kconfig/lex.zconf.c_shipped
index 5fc323de3..51f15e175 100644
--- a/scripts/kconfig/lex.zconf.c_shipped
+++ b/scripts/kconfig/lex.zconf.c_shipped
@@ -2235,13 +2235,14 @@ static void zconf_endhelp(void)
2235 */ 2235 */
2236FILE *zconf_fopen(const char *name) 2236FILE *zconf_fopen(const char *name)
2237{ 2237{
2238 char *env, fullname[PATH_MAX+1]; 2238 char *env;
2239 FILE *f; 2239 FILE *f;
2240 2240
2241 f = fopen(name, "r"); 2241 f = fopen(name, "r");
2242 if (!f && name[0] != '/') { 2242 if (!f && name[0] != '/') {
2243 env = getenv(SRCTREE); 2243 env = getenv(SRCTREE);
2244 if (env) { 2244 if (env) {
2245 char *fullname = alloca(strlen(env) + strlen(name) + 2);
2245 sprintf(fullname, "%s/%s", env, name); 2246 sprintf(fullname, "%s/%s", env, name);
2246 f = fopen(fullname, "r"); 2247 f = fopen(fullname, "r");
2247 } 2248 }
@@ -2322,4 +2323,3 @@ char *zconf_curname(void)
2322{ 2323{
2323 return current_pos.file ? current_pos.file->name : "<none>"; 2324 return current_pos.file ? current_pos.file->name : "<none>";
2324} 2325}
2325
diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c
index 0fce20cb7..14cf2ead0 100644
--- a/scripts/kconfig/menu.c
+++ b/scripts/kconfig/menu.c
@@ -394,4 +394,3 @@ struct menu *menu_get_parent_menu(struct menu *menu)
394 } 394 }
395 return menu; 395 return menu;
396} 396}
397
diff --git a/scripts/kconfig/util.c b/scripts/kconfig/util.c
index ef4c83228..263091945 100644
--- a/scripts/kconfig/util.c
+++ b/scripts/kconfig/util.c
@@ -112,4 +112,3 @@ const char *str_get(struct gstr *gs)
112{ 112{
113 return gs->s; 113 return gs->s;
114} 114}
115
diff --git a/scripts/kconfig/zconf.hash.c_shipped b/scripts/kconfig/zconf.hash.c_shipped
index 345f0fc07..d39cf189a 100644
--- a/scripts/kconfig/zconf.hash.c_shipped
+++ b/scripts/kconfig/zconf.hash.c_shipped
@@ -228,4 +228,3 @@ kconf_id_lookup (register const char *str, register unsigned int len)
228 } 228 }
229 return 0; 229 return 0;
230} 230}
231
diff --git a/scripts/kconfig/zconf.tab.c_shipped b/scripts/kconfig/zconf.tab.c_shipped
index b62724da0..a27d256d6 100644
--- a/scripts/kconfig/zconf.tab.c_shipped
+++ b/scripts/kconfig/zconf.tab.c_shipped
@@ -2169,5 +2169,3 @@ void zconfdump(FILE *out)
2169#include "expr.c" 2169#include "expr.c"
2170#include "symbol.c" 2170#include "symbol.c"
2171#include "menu.c" 2171#include "menu.c"
2172
2173
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index 2007a4e02..bef5e92a3 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -473,7 +473,7 @@ void conf_parse(const char *name)
473 menu_finalize(&rootmenu); 473 menu_finalize(&rootmenu);
474 for_all_symbols(i, sym) { 474 for_all_symbols(i, sym) {
475 sym_check_deps(sym); 475 sym_check_deps(sym);
476 } 476 }
477 477
478 sym_change_count = 1; 478 sym_change_count = 1;
479} 479}
diff --git a/scripts/showasm b/scripts/showasm
index 046442653..dc2cd705d 100755
--- a/scripts/showasm
+++ b/scripts/showasm
@@ -18,4 +18,3 @@ then
18fi 18fi
19 19
20objdump -d $1 | sed -n -e '/./{H;$!d}' -e "x;/^.[0-9a-fA-F]* <$2>:/p" 20objdump -d $1 | sed -n -e '/./{H;$!d}' -e "x;/^.[0-9a-fA-F]* <$2>:/p"
21
diff --git a/selinux/Config.src b/selinux/Config.src
index 64a99203e..47d15b6af 100644
--- a/selinux/Config.src
+++ b/selinux/Config.src
@@ -122,4 +122,3 @@ config SESTATUS
122 Displays the status of SELinux. 122 Displays the status of SELinux.
123 123
124endmenu 124endmenu
125
diff --git a/selinux/setfiles.c b/selinux/setfiles.c
index f45e41b2b..989510e3d 100644
--- a/selinux/setfiles.c
+++ b/selinux/setfiles.c
@@ -118,7 +118,6 @@ static void add_exclude(const char *directory)
118 118
119 if (directory == NULL || directory[0] != '/') { 119 if (directory == NULL || directory[0] != '/') {
120 bb_error_msg_and_die("full path required for exclude: %s", directory); 120 bb_error_msg_and_die("full path required for exclude: %s", directory);
121
122 } 121 }
123 if (lstat(directory, &sb)) { 122 if (lstat(directory, &sb)) {
124 bb_error_msg("directory \"%s\" not found, ignoring", directory); 123 bb_error_msg("directory \"%s\" not found, ignoring", directory);
diff --git a/shell/Config.src b/shell/Config.src
index 6389d943a..c9c2439e7 100644
--- a/shell/Config.src
+++ b/shell/Config.src
@@ -62,29 +62,6 @@ config FEATURE_BASH_IS_NONE
62endchoice 62endchoice
63 63
64 64
65config LASH
66 bool "lash (deprecated: aliased to hush)"
67 default n
68 select HUSH
69 help
70 lash is deprecated and will be removed, please migrate to hush.
71
72config MSH
73 bool "msh (deprecated: please use hush)"
74 default n
75 select HUSH
76 help
77 msh is deprecated and will be removed, please migrate to hush.
78 If there is a feature msh has but hush does not, please let us know.
79
80# The minix shell (adds just 30k) is quite complete and handles things
81# like for/do/done, case/esac and all the things you expect a Bourne
82# shell to do. It is not always pedantically correct about Bourne
83# shell grammar (try running the shell testscript "tests/sh.testcases"
84# on it and compare vs bash) but for most things it works quite well.
85# It uses only vfork, so it can be used on uClinux systems.
86
87
88config SH_MATH_SUPPORT 65config SH_MATH_SUPPORT
89 bool "POSIX math support" 66 bool "POSIX math support"
90 default y 67 default y
@@ -158,40 +135,4 @@ config FEATURE_SH_NOFORK
158 135
159 This feature is relatively new. Use with care. 136 This feature is relatively new. Use with care.
160 137
161config CTTYHACK
162 bool "cttyhack"
163 default y
164 help
165 One common problem reported on the mailing list is "can't access tty;
166 job control turned off" error message which typically appears when
167 one tries to use shell with stdin/stdout opened to /dev/console.
168 This device is special - it cannot be a controlling tty.
169
170 Proper solution is to use correct device instead of /dev/console.
171
172 cttyhack provides "quick and dirty" solution to this problem.
173 It analyzes stdin with various ioctls, trying to determine whether
174 it is a /dev/ttyN or /dev/ttySN (virtual terminal or serial line).
175 If it detects one, it closes stdin/out/err and reopens that device.
176 Then it executes given program. Opening the device will make
177 that device a controlling tty. This may require cttyhack
178 to be a session leader.
179
180 Example for /etc/inittab (for busybox init):
181
182 ::respawn:/bin/cttyhack /bin/sh
183
184 Starting an interactive shell from boot shell script:
185
186 setsid cttyhack sh
187
188 Giving controlling tty to shell running with PID 1:
189
190 # exec cttyhack sh
191
192 Without cttyhack, you need to know exact tty name,
193 and do something like this:
194
195 # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1'
196
197endmenu 138endmenu
diff --git a/shell/Kbuild.src b/shell/Kbuild.src
index bce99240f..a669bdfb0 100644
--- a/shell/Kbuild.src
+++ b/shell/Kbuild.src
@@ -8,5 +8,4 @@ lib-y:=
8 8
9INSERT 9INSERT
10 10
11lib-$(CONFIG_CTTYHACK) += cttyhack.o
12lib-$(CONFIG_SH_MATH_SUPPORT) += math.o 11lib-$(CONFIG_SH_MATH_SUPPORT) += math.o
diff --git a/shell/ash.c b/shell/ash.c
index 2cee0c42f..308cc0273 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -193,6 +193,7 @@
193//config: "PS#" may contain volatile content, such as backquote commands. 193//config: "PS#" may contain volatile content, such as backquote commands.
194//config: This option recreates the prompt string from the environment 194//config: This option recreates the prompt string from the environment
195//config: variable each time it is displayed. 195//config: variable each time it is displayed.
196//config:
196 197
197//usage:#define ash_trivial_usage NOUSAGE_STR 198//usage:#define ash_trivial_usage NOUSAGE_STR
198//usage:#define ash_full_usage "" 199//usage:#define ash_full_usage ""
@@ -4844,6 +4845,7 @@ clear_traps(void)
4844 INT_ON; 4845 INT_ON;
4845 } 4846 }
4846 } 4847 }
4848 may_have_traps = 0;
4847} 4849}
4848 4850
4849/* Lives far away from here, needed for forkchild */ 4851/* Lives far away from here, needed for forkchild */
@@ -6615,13 +6617,14 @@ parse_sub_pattern(char *arg, int inquotes)
6615#endif /* ENABLE_ASH_BASH_COMPAT */ 6617#endif /* ENABLE_ASH_BASH_COMPAT */
6616 6618
6617static const char * 6619static const char *
6618subevalvar(char *p, char *str, int strloc, int subtype, 6620subevalvar(char *p, char *varname, int strloc, int subtype,
6619 int startloc, int varflags, int quotes, struct strlist *var_str_list) 6621 int startloc, int varflags, int quotes, struct strlist *var_str_list)
6620{ 6622{
6621 struct nodelist *saveargbackq = argbackq; 6623 struct nodelist *saveargbackq = argbackq;
6622 char *startp; 6624 char *startp;
6623 char *loc; 6625 char *loc;
6624 char *rmesc, *rmescend; 6626 char *rmesc, *rmescend;
6627 char *str;
6625 IF_ASH_BASH_COMPAT(const char *repl = NULL;) 6628 IF_ASH_BASH_COMPAT(const char *repl = NULL;)
6626 IF_ASH_BASH_COMPAT(int pos, len, orig_len;) 6629 IF_ASH_BASH_COMPAT(int pos, len, orig_len;)
6627 int saveherefd = herefd; 6630 int saveherefd = herefd;
@@ -6629,6 +6632,9 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6629 int zero; 6632 int zero;
6630 char *(*scan)(char*, char*, char*, char*, int, int); 6633 char *(*scan)(char*, char*, char*, char*, int, int);
6631 6634
6635 //bb_error_msg("subevalvar(p:'%s',varname:'%s',strloc:%d,subtype:%d,startloc:%d,varflags:%x,quotes:%d",
6636 // p, varname, strloc, subtype, startloc, varflags, quotes);
6637
6632 herefd = -1; 6638 herefd = -1;
6633 argstr(p, (subtype != VSASSIGN && subtype != VSQUESTION) ? EXP_CASE : 0, 6639 argstr(p, (subtype != VSASSIGN && subtype != VSQUESTION) ? EXP_CASE : 0,
6634 var_str_list); 6640 var_str_list);
@@ -6639,11 +6645,15 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6639 6645
6640 switch (subtype) { 6646 switch (subtype) {
6641 case VSASSIGN: 6647 case VSASSIGN:
6642 setvar(str, startp, 0); 6648 setvar(varname, startp, 0);
6643 amount = startp - expdest; 6649 amount = startp - expdest;
6644 STADJUST(amount, expdest); 6650 STADJUST(amount, expdest);
6645 return startp; 6651 return startp;
6646 6652
6653 case VSQUESTION:
6654 varunset(p, varname, startp, varflags);
6655 /* NOTREACHED */
6656
6647#if ENABLE_ASH_BASH_COMPAT 6657#if ENABLE_ASH_BASH_COMPAT
6648 case VSSUBSTR: 6658 case VSSUBSTR:
6649 loc = str = stackblock() + strloc; 6659 loc = str = stackblock() + strloc;
@@ -6704,11 +6714,8 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6704 STADJUST(amount, expdest); 6714 STADJUST(amount, expdest);
6705 return loc; 6715 return loc;
6706#endif 6716#endif
6707
6708 case VSQUESTION:
6709 varunset(p, str, startp, varflags);
6710 /* NOTREACHED */
6711 } 6717 }
6718
6712 resetloc = expdest - (char *)stackblock(); 6719 resetloc = expdest - (char *)stackblock();
6713 6720
6714 /* We'll comeback here if we grow the stack while handling 6721 /* We'll comeback here if we grow the stack while handling
@@ -6742,13 +6749,14 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6742 6749
6743 if (!repl) { 6750 if (!repl) {
6744 repl = parse_sub_pattern(str, varflags & VSQUOTE); 6751 repl = parse_sub_pattern(str, varflags & VSQUOTE);
6752 //bb_error_msg("repl:'%s'", repl);
6745 if (!repl) 6753 if (!repl)
6746 repl = nullstr; 6754 repl = nullstr;
6747 } 6755 }
6748 6756
6749 /* If there's no pattern to match, return the expansion unmolested */ 6757 /* If there's no pattern to match, return the expansion unmolested */
6750 if (str[0] == '\0') 6758 if (str[0] == '\0')
6751 return 0; 6759 return NULL;
6752 6760
6753 len = 0; 6761 len = 0;
6754 idx = startp; 6762 idx = startp;
@@ -6756,6 +6764,7 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6756 while (idx < end) { 6764 while (idx < end) {
6757 try_to_match: 6765 try_to_match:
6758 loc = scanright(idx, rmesc, rmescend, str, quotes, 1); 6766 loc = scanright(idx, rmesc, rmescend, str, quotes, 1);
6767 //bb_error_msg("scanright('%s'):'%s'", str, loc);
6759 if (!loc) { 6768 if (!loc) {
6760 /* No match, advance */ 6769 /* No match, advance */
6761 char *restart_detect = stackblock(); 6770 char *restart_detect = stackblock();
@@ -6794,6 +6803,7 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6794 idx = loc; 6803 idx = loc;
6795 } 6804 }
6796 6805
6806 //bb_error_msg("repl:'%s'", repl);
6797 for (loc = (char*)repl; *loc; loc++) { 6807 for (loc = (char*)repl; *loc; loc++) {
6798 char *restart_detect = stackblock(); 6808 char *restart_detect = stackblock();
6799 if (quotes && *loc == '\\') { 6809 if (quotes && *loc == '\\') {
@@ -6829,6 +6839,7 @@ subevalvar(char *p, char *str, int strloc, int subtype,
6829 STPUTC('\0', expdest); 6839 STPUTC('\0', expdest);
6830 startp = (char *)stackblock() + startloc; 6840 startp = (char *)stackblock() + startloc;
6831 memmove(startp, (char *)stackblock() + workloc, len + 1); 6841 memmove(startp, (char *)stackblock() + workloc, len + 1);
6842 //bb_error_msg("startp:'%s'", startp);
6832 amount = expdest - (startp + len); 6843 amount = expdest - (startp + len);
6833 STADJUST(-amount, expdest); 6844 STADJUST(-amount, expdest);
6834 return startp; 6845 return startp;
@@ -7129,7 +7140,7 @@ evalvar(char *p, int flags, struct strlist *var_str_list)
7129 */ 7140 */
7130 STPUTC('\0', expdest); 7141 STPUTC('\0', expdest);
7131 patloc = expdest - (char *)stackblock(); 7142 patloc = expdest - (char *)stackblock();
7132 if (NULL == subevalvar(p, /* str: */ NULL, patloc, subtype, 7143 if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
7133 startloc, varflags, 7144 startloc, varflags,
7134//TODO: | EXP_REDIR too? All other such places do it too 7145//TODO: | EXP_REDIR too? All other such places do it too
7135 /* quotes: */ flags & (EXP_FULL | EXP_CASE), 7146 /* quotes: */ flags & (EXP_FULL | EXP_CASE),
@@ -11577,8 +11588,11 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
11577 USTPUTC('\\', out); 11588 USTPUTC('\\', out);
11578 } 11589 }
11579#endif 11590#endif
11580 if (dblquote && c != '\\' 11591 /* Backslash is retained if we are in "str" and next char isn't special */
11581 && c != '`' && c != '$' 11592 if (dblquote
11593 && c != '\\'
11594 && c != '`'
11595 && c != '$'
11582 && (c != '"' || eofmark != NULL) 11596 && (c != '"' || eofmark != NULL)
11583 ) { 11597 ) {
11584 USTPUTC(CTLESC, out); 11598 USTPUTC(CTLESC, out);
@@ -11650,7 +11664,7 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
11650 } else { 11664 } else {
11651 /* 11665 /*
11652 * unbalanced parens 11666 * unbalanced parens
11653 * (don't 2nd guess - no error) 11667 * (don't 2nd guess - no error)
11654 */ 11668 */
11655 pungetc(); 11669 pungetc();
11656 USTPUTC(')', out); 11670 USTPUTC(')', out);
@@ -11678,7 +11692,6 @@ readtoken1(int c, int syntax, char *eofmark, int striptabs)
11678 } 11692 }
11679 IF_ASH_ALIAS(if (c != PEOA)) 11693 IF_ASH_ALIAS(if (c != PEOA))
11680 USTPUTC(c, out); 11694 USTPUTC(c, out);
11681
11682 } 11695 }
11683 c = pgetc_fast(); 11696 c = pgetc_fast();
11684 } /* for (;;) */ 11697 } /* for (;;) */
@@ -11844,8 +11857,6 @@ parsesub: {
11844 unsigned char subtype; 11857 unsigned char subtype;
11845 int typeloc; 11858 int typeloc;
11846 int flags; 11859 int flags;
11847 char *p;
11848 static const char types[] ALIGN1 = "}-+?=";
11849 11860
11850 c = pgetc(); 11861 c = pgetc();
11851 if (c > 255 /* PEOA or PEOF */ 11862 if (c > 255 /* PEOA or PEOF */
@@ -11858,7 +11869,8 @@ parsesub: {
11858#endif 11869#endif
11859 USTPUTC('$', out); 11870 USTPUTC('$', out);
11860 pungetc(); 11871 pungetc();
11861 } else if (c == '(') { /* $(command) or $((arith)) */ 11872 } else if (c == '(') {
11873 /* $(command) or $((arith)) */
11862 if (pgetc() == '(') { 11874 if (pgetc() == '(') {
11863#if ENABLE_SH_MATH_SUPPORT 11875#if ENABLE_SH_MATH_SUPPORT
11864 PARSEARITH(); 11876 PARSEARITH();
@@ -11870,6 +11882,7 @@ parsesub: {
11870 PARSEBACKQNEW(); 11882 PARSEBACKQNEW();
11871 } 11883 }
11872 } else { 11884 } else {
11885 /* $VAR, $<specialchar>, ${...}, or PEOA/PEOF */
11873 USTPUTC(CTLVAR, out); 11886 USTPUTC(CTLVAR, out);
11874 typeloc = out - (char *)stackblock(); 11887 typeloc = out - (char *)stackblock();
11875 USTPUTC(VSNORMAL, out); 11888 USTPUTC(VSNORMAL, out);
@@ -11879,76 +11892,85 @@ parsesub: {
11879 if (c == '#') { 11892 if (c == '#') {
11880 c = pgetc(); 11893 c = pgetc();
11881 if (c == '}') 11894 if (c == '}')
11882 c = '#'; 11895 c = '#'; /* ${#} - same as $# */
11883 else 11896 else
11884 subtype = VSLENGTH; 11897 subtype = VSLENGTH; /* ${#VAR} */
11885 } else 11898 } else {
11886 subtype = 0; 11899 subtype = 0;
11900 }
11887 } 11901 }
11888 if (c <= 255 /* not PEOA or PEOF */ && is_name(c)) { 11902 if (c <= 255 /* not PEOA or PEOF */ && is_name(c)) {
11903 /* $[{[#]]NAME[}] */
11889 do { 11904 do {
11890 STPUTC(c, out); 11905 STPUTC(c, out);
11891 c = pgetc(); 11906 c = pgetc();
11892 } while (c <= 255 /* not PEOA or PEOF */ && is_in_name(c)); 11907 } while (c <= 255 /* not PEOA or PEOF */ && is_in_name(c));
11893 } else if (isdigit(c)) { 11908 } else if (isdigit(c)) {
11909 /* $[{[#]]NUM[}] */
11894 do { 11910 do {
11895 STPUTC(c, out); 11911 STPUTC(c, out);
11896 c = pgetc(); 11912 c = pgetc();
11897 } while (isdigit(c)); 11913 } while (isdigit(c));
11898 } else if (is_special(c)) { 11914 } else if (is_special(c)) {
11915 /* $[{[#]]<specialchar>[}] */
11899 USTPUTC(c, out); 11916 USTPUTC(c, out);
11900 c = pgetc(); 11917 c = pgetc();
11901 } else { 11918 } else {
11902 badsub: 11919 badsub:
11903 raise_error_syntax("bad substitution"); 11920 raise_error_syntax("bad substitution");
11904 } 11921 }
11905 if (c != '}' && subtype == VSLENGTH) 11922 if (c != '}' && subtype == VSLENGTH) {
11923 /* ${#VAR didn't end with } */
11906 goto badsub; 11924 goto badsub;
11925 }
11907 11926
11908 STPUTC('=', out); 11927 STPUTC('=', out);
11909 flags = 0; 11928 flags = 0;
11910 if (subtype == 0) { 11929 if (subtype == 0) {
11930 /* ${VAR...} but not $VAR or ${#VAR} */
11931 /* c == first char after VAR */
11911 switch (c) { 11932 switch (c) {
11912 case ':': 11933 case ':':
11913 c = pgetc(); 11934 c = pgetc();
11914#if ENABLE_ASH_BASH_COMPAT 11935#if ENABLE_ASH_BASH_COMPAT
11915 if (c == ':' || c == '$' || isdigit(c)) { 11936 if (c == ':' || c == '$' || isdigit(c)) {
11916 pungetc();
11917 subtype = VSSUBSTR; 11937 subtype = VSSUBSTR;
11918 break; 11938 pungetc();
11939 break; /* "goto do_pungetc" is bigger (!) */
11919 } 11940 }
11920#endif 11941#endif
11921 flags = VSNUL; 11942 flags = VSNUL;
11922 /*FALLTHROUGH*/ 11943 /*FALLTHROUGH*/
11923 default: 11944 default: {
11924 p = strchr(types, c); 11945 static const char types[] ALIGN1 = "}-+?=";
11946 const char *p = strchr(types, c);
11925 if (p == NULL) 11947 if (p == NULL)
11926 goto badsub; 11948 goto badsub;
11927 subtype = p - types + VSNORMAL; 11949 subtype = p - types + VSNORMAL;
11928 break; 11950 break;
11951 }
11929 case '%': 11952 case '%':
11930 case '#': { 11953 case '#': {
11931 int cc = c; 11954 int cc = c;
11932 subtype = c == '#' ? VSTRIMLEFT : VSTRIMRIGHT; 11955 subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT);
11933 c = pgetc(); 11956 c = pgetc();
11934 if (c == cc) 11957 if (c != cc)
11935 subtype++; 11958 goto do_pungetc;
11936 else 11959 subtype++;
11937 pungetc();
11938 break; 11960 break;
11939 } 11961 }
11940#if ENABLE_ASH_BASH_COMPAT 11962#if ENABLE_ASH_BASH_COMPAT
11941 case '/': 11963 case '/':
11942 subtype = VSREPLACE; 11964 subtype = VSREPLACE;
11943 c = pgetc(); 11965 c = pgetc();
11944 if (c == '/') 11966 if (c != '/')
11945 subtype++; /* VSREPLACEALL */ 11967 goto do_pungetc;
11946 else 11968 subtype++; /* VSREPLACEALL */
11947 pungetc();
11948 break; 11969 break;
11949#endif 11970#endif
11950 } 11971 }
11951 } else { 11972 } else {
11973 do_pungetc:
11952 pungetc(); 11974 pungetc();
11953 } 11975 }
11954 if (dblquote || arinest) 11976 if (dblquote || arinest)
@@ -12518,7 +12540,6 @@ evalcmd(int argc UNUSED_PARAM, char **argv)
12518 p = grabstackstr(concat); 12540 p = grabstackstr(concat);
12519 } 12541 }
12520 evalstring(p, ~SKIPEVAL); 12542 evalstring(p, ~SKIPEVAL);
12521
12522 } 12543 }
12523 return exitstatus; 12544 return exitstatus;
12524} 12545}
diff --git a/shell/ash_test/ash-redir/redir9.tests b/shell/ash_test/ash-redir/redir9.tests
index 8befa611c..8befa611c 100644..100755
--- a/shell/ash_test/ash-redir/redir9.tests
+++ b/shell/ash_test/ash-redir/redir9.tests
diff --git a/shell/ash_test/ash-signals/signal7.right b/shell/ash_test/ash-signals/signal7.right
new file mode 100644
index 000000000..ba7453e42
--- /dev/null
+++ b/shell/ash_test/ash-signals/signal7.right
@@ -0,0 +1 @@
Bug detected: 0
diff --git a/shell/ash_test/ash-signals/signal7.tests b/shell/ash_test/ash-signals/signal7.tests
new file mode 100755
index 000000000..c2b1381f9
--- /dev/null
+++ b/shell/ash_test/ash-signals/signal7.tests
@@ -0,0 +1,18 @@
1bug() {
2 trap : exit
3 # Bug was causing sh to be run in subshell,
4 # as if this line is replaced with (sh -c ...; exit $?) &
5 # here:
6 sh -c 'echo REAL_CHILD=$$' &
7 echo PARENTS_IDEA_OF_CHILD=$!
8 wait # make sure bkgd shell completes
9}
10
11bug | {
12while read varval; do
13 eval $varval
14done
15test x"$REAL_CHILD" != x"" \
16&& test x"$REAL_CHILD" = x"$PARENTS_IDEA_OF_CHILD"
17echo "Bug detected: $?"
18}
diff --git a/shell/ash_test/ash-vars/var_bash3.right b/shell/ash_test/ash-vars/var_bash3.right
index f7f14791e..a97c850ea 100644
--- a/shell/ash_test/ash-vars/var_bash3.right
+++ b/shell/ash_test/ash-vars/var_bash3.right
@@ -1,20 +1,20 @@
1a041#c 11 a041#c
2a041#c 22 a041#c
3a\041#c 33 a\041#c
4a\041#c 44 a\041#c
5a\041#c 55 a\041#c
6a\041#c 66 a\041#c
7a\041#c 77 a\041#c
8a\041#c 88 a\041#c
9a\041#c 99 a\041#c
10a\c 1010 a\c
11a\c 1111 a\c
12a\c 1212 a\c
13a\\c 1313 a\\c
14a\\c 1414 a\\c
15a\\c 1515 a\\c
16a\tc 1616 a\tc
17a\tc 1717 a\tc
18a\tc 1818 a\tc
19atc 1919 atc
20a\tc 2020 a\tc
diff --git a/shell/ash_test/ash-vars/var_bash3.tests b/shell/ash_test/ash-vars/var_bash3.tests
index b9050279e..eca3318e2 100755
--- a/shell/ash_test/ash-vars/var_bash3.tests
+++ b/shell/ash_test/ash-vars/var_bash3.tests
@@ -1,41 +1,48 @@
1a='abc' 1a='abc'
2r=${a//b/\041#} 2r=${a//b/\041#}
3echo $r 3echo 1 $r
4echo ${a//b/\041#} 4echo 2 ${a//b/\041#}
5echo "${a//b/\041#}" 5echo 3 "${a//b/\041#}"
6# --- var_bash3.xx
7# +++ var_bash3.right
8# -1 a\041#c
9# +1 a041#c
10# 2 a041#c
11# -3 a041#c
12# +3 a\041#c
6 13
7a='abc' 14a='abc'
8r=${a//b/\\041#} 15r=${a//b/\\041#}
9echo $r 16echo 4 $r
10echo ${a//b/\\041#} 17echo 5 ${a//b/\\041#}
11echo "${a//b/\\041#}" 18echo 6 "${a//b/\\041#}"
12 19
13a='abc' 20a='abc'
14b='\041#' 21b='\041#'
15r=${a//b/$b} 22r=${a//b/$b}
16echo $r 23echo 7 $r
17echo ${a//b/$b} 24echo 8 ${a//b/$b}
18echo "${a//b/$b}" 25echo 9 "${a//b/$b}"
19 26
20a='abc' 27a='abc'
21b='\' 28b='\'
22r="${a//b/$b}" 29r="${a//b/$b}"
23echo $r 30echo 10 $r
24echo ${a//b/$b} 31echo 11 ${a//b/$b}
25echo "${a//b/$b}" 32echo 12 "${a//b/$b}"
26 33
27a='abc' 34a='abc'
28b='\\' 35b='\\'
29r="${a//b/$b}" 36r="${a//b/$b}"
30echo $r 37echo 13 $r
31echo ${a//b/$b} 38echo 14 ${a//b/$b}
32echo "${a//b/$b}" 39echo 15 "${a//b/$b}"
33 40
34a='abc' 41a='abc'
35b='\t' 42b='\t'
36r="${a//b/$b}" 43r="${a//b/$b}"
37echo $r 44echo 16 $r
38echo ${a//b/$b} 45echo 17 ${a//b/$b}
39echo "${a//b/$b}" 46echo 18 "${a//b/$b}"
40echo ${a//b/\t} 47echo 19 ${a//b/\t}
41echo "${a//b/\t}" 48echo 20 "${a//b/\t}"
diff --git a/shell/ash_test/ash-vars/var_bash4.right b/shell/ash_test/ash-vars/var_bash4.right
new file mode 100644
index 000000000..fc3a9e41c
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_bash4.right
@@ -0,0 +1,4 @@
1In assignment: a*b-backslashstar-
2Unquoted: a*b-backslashstar-
3Quoted: a*b-backslashstar-
4Done: 0
diff --git a/shell/ash_test/ash-vars/var_bash4.tests b/shell/ash_test/ash-vars/var_bash4.tests
new file mode 100755
index 000000000..3b323c576
--- /dev/null
+++ b/shell/ash_test/ash-vars/var_bash4.tests
@@ -0,0 +1,6 @@
1FOO='a*b\*c'
2BAR=${FOO//\\*/-backslashstar-}
3echo In assignment: "$BAR"
4echo Unquoted: ${FOO//\\*/-backslashstar-}
5echo Quoted: "${FOO//\\*/-backslashstar-}"
6echo Done: $?
diff --git a/shell/cttyhack.c b/shell/cttyhack.c
index 67736ad62..7a5e1ffd2 100644
--- a/shell/cttyhack.c
+++ b/shell/cttyhack.c
@@ -6,6 +6,62 @@
6 */ 6 */
7#include "libbb.h" 7#include "libbb.h"
8 8
9//applet:IF_CTTYHACK(APPLET(cttyhack, _BB_DIR_BIN, _BB_SUID_DROP))
10
11//kbuild:lib-$(CONFIG_CTTYHACK) += cttyhack.o
12
13//config:config CTTYHACK
14//config: bool "cttyhack"
15//config: default y
16//config: help
17//config: One common problem reported on the mailing list is "can't access tty;
18//config: job control turned off" error message which typically appears when
19//config: one tries to use shell with stdin/stdout opened to /dev/console.
20//config: This device is special - it cannot be a controlling tty.
21//config:
22//config: Proper solution is to use correct device instead of /dev/console.
23//config:
24//config: cttyhack provides "quick and dirty" solution to this problem.
25//config: It analyzes stdin with various ioctls, trying to determine whether
26//config: it is a /dev/ttyN or /dev/ttySN (virtual terminal or serial line).
27//config: If it detects one, it closes stdin/out/err and reopens that device.
28//config: Then it executes given program. Opening the device will make
29//config: that device a controlling tty. This may require cttyhack
30//config: to be a session leader.
31//config:
32//config: Example for /etc/inittab (for busybox init):
33//config:
34//config: ::respawn:/bin/cttyhack /bin/sh
35//config:
36//config: Starting an interactive shell from boot shell script:
37//config:
38//config: setsid cttyhack sh
39//config:
40//config: Giving controlling tty to shell running with PID 1:
41//config:
42//config: # exec cttyhack sh
43//config:
44//config: Without cttyhack, you need to know exact tty name,
45//config: and do something like this:
46//config:
47//config: # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1'
48//config:
49
50//usage:#define cttyhack_trivial_usage
51//usage: "PROG ARGS"
52//usage:#define cttyhack_full_usage "\n\n"
53//usage: "Give PROG a controlling tty if possible."
54//usage: "\nExample for /etc/inittab (for busybox init):"
55//usage: "\n ::respawn:/bin/cttyhack /bin/sh"
56//usage: "\nGiving controlling tty to shell running with PID 1:"
57//usage: "\n $ exec cttyhack sh"
58//usage: "\nStarting interactive shell from boot shell script:"
59//usage: "\n setsid cttyhack sh"
60
61#if !defined(__linux__) && !defined(TIOCGSERIAL) && !ENABLE_WERROR
62# warning cttyhack will not be able to detect a controlling tty on this system
63#endif
64
9/* From <linux/vt.h> */ 65/* From <linux/vt.h> */
10struct vt_stat { 66struct vt_stat {
11 unsigned short v_active; /* active vt */ 67 unsigned short v_active; /* active vt */
@@ -59,13 +115,19 @@ int cttyhack_main(int argc UNUSED_PARAM, char **argv)
59 close(fd); 115 close(fd);
60 } else { 116 } else {
61 /* We don't have ctty (or don't have "/dev/tty" node...) */ 117 /* We don't have ctty (or don't have "/dev/tty" node...) */
62 if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) { 118 if (0) {}
119#ifdef TIOCGSERIAL
120 else if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) {
63 /* this is a serial console */ 121 /* this is a serial console */
64 sprintf(console + 8, "S%d", u.sr.line); 122 sprintf(console + 8, "S%d", u.sr.line);
65 } else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) { 123 }
124#endif
125#ifdef __linux__
126 else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) {
66 /* this is linux virtual tty */ 127 /* this is linux virtual tty */
67 sprintf(console + 8, "S%d" + 1, u.vt.v_active); 128 sprintf(console + 8, "S%d" + 1, u.vt.v_active);
68 } 129 }
130#endif
69 if (console[8]) { 131 if (console[8]) {
70 fd = xopen(console, O_RDWR); 132 fd = xopen(console, O_RDWR);
71 //bb_error_msg("switching to '%s'", console); 133 //bb_error_msg("switching to '%s'", console);
diff --git a/shell/hush.c b/shell/hush.c
index 56a3f4b14..0a420f685 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -224,6 +224,20 @@
224//config: This instructs hush to print commands before execution. 224//config: This instructs hush to print commands before execution.
225//config: Adds ~300 bytes. 225//config: Adds ~300 bytes.
226//config: 226//config:
227//config:config LASH
228//config: bool "lash (deprecated: aliased to hush)"
229//config: default n
230//config: select HUSH
231//config: help
232//config: lash is deprecated and will be removed, please migrate to hush.
233//config:
234//config:config MSH
235//config: bool "msh (deprecated: aliased to hush)"
236//config: default n
237//config: select HUSH
238//config: help
239//config: msh is deprecated and will be removed, please migrate to hush.
240//config:
227 241
228//usage:#define hush_trivial_usage NOUSAGE_STR 242//usage:#define hush_trivial_usage NOUSAGE_STR
229//usage:#define hush_full_usage "" 243//usage:#define hush_full_usage ""
@@ -4094,8 +4108,6 @@ static void insert_bg_job(struct pipe *pi)
4094 4108
4095 if (G_interactive_fd) 4109 if (G_interactive_fd)
4096 printf("[%d] %d %s\n", job->jobid, job->cmds[0].pid, job->cmdtext); 4110 printf("[%d] %d %s\n", job->jobid, job->cmds[0].pid, job->cmdtext);
4097 /* Last command's pid goes to $! */
4098 G.last_bg_pid = job->cmds[job->num_cmds - 1].pid;
4099 G.last_jobid = job->jobid; 4111 G.last_jobid = job->jobid;
4100} 4112}
4101 4113
@@ -4506,7 +4518,6 @@ static NOINLINE int run_pipe(struct pipe *pi)
4506#ifdef CMD_SINGLEWORD_NOGLOB_COND 4518#ifdef CMD_SINGLEWORD_NOGLOB_COND
4507 else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB_COND) { 4519 else if (command->cmd_type == CMD_SINGLEWORD_NOGLOB_COND) {
4508 argv_expanded = expand_strvec_to_strvec_singleword_noglob_cond(argv + command->assignment_cnt); 4520 argv_expanded = expand_strvec_to_strvec_singleword_noglob_cond(argv + command->assignment_cnt);
4509
4510 } 4521 }
4511#endif 4522#endif
4512 else { 4523 else {
@@ -5062,6 +5073,8 @@ static int run_list(struct pipe *pi)
5062 if (G.run_list_level == 1) 5073 if (G.run_list_level == 1)
5063 insert_bg_job(pi); 5074 insert_bg_job(pi);
5064#endif 5075#endif
5076 /* Last command's pid goes to $! */
5077 G.last_bg_pid = pi->cmds[pi->num_cmds - 1].pid;
5065 G.last_exitcode = rcode = EXIT_SUCCESS; 5078 G.last_exitcode = rcode = EXIT_SUCCESS;
5066 debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n"); 5079 debug_printf_exec(": cmd&: exitcode EXIT_SUCCESS\n");
5067 } else { 5080 } else {
diff --git a/shell/hush_test/hush-misc/break1.tests b/shell/hush_test/hush-misc/break1.tests
index 912f149c1..3a6b060d9 100755
--- a/shell/hush_test/hush-misc/break1.tests
+++ b/shell/hush_test/hush-misc/break1.tests
@@ -1,3 +1,2 @@
1while true; do echo A; break; echo B; done 1while true; do echo A; break; echo B; done
2echo OK:$? 2echo OK:$?
3
diff --git a/shell/hush_test/hush-trap/signal7.right b/shell/hush_test/hush-trap/signal7.right
new file mode 100644
index 000000000..ba7453e42
--- /dev/null
+++ b/shell/hush_test/hush-trap/signal7.right
@@ -0,0 +1 @@
Bug detected: 0
diff --git a/shell/hush_test/hush-trap/signal7.tests b/shell/hush_test/hush-trap/signal7.tests
new file mode 100755
index 000000000..c2b1381f9
--- /dev/null
+++ b/shell/hush_test/hush-trap/signal7.tests
@@ -0,0 +1,18 @@
1bug() {
2 trap : exit
3 # Bug was causing sh to be run in subshell,
4 # as if this line is replaced with (sh -c ...; exit $?) &
5 # here:
6 sh -c 'echo REAL_CHILD=$$' &
7 echo PARENTS_IDEA_OF_CHILD=$!
8 wait # make sure bkgd shell completes
9}
10
11bug | {
12while read varval; do
13 eval $varval
14done
15test x"$REAL_CHILD" != x"" \
16&& test x"$REAL_CHILD" = x"$PARENTS_IDEA_OF_CHILD"
17echo "Bug detected: $?"
18}
diff --git a/shell/shell_common.c b/shell/shell_common.c
index 840e03bff..957d71928 100644
--- a/shell/shell_common.c
+++ b/shell/shell_common.c
@@ -435,9 +435,14 @@ shell_builtin_ulimit(char **argv)
435 val <<= l->factor_shift; 435 val <<= l->factor_shift;
436 } 436 }
437//bb_error_msg("opt %c val_str:'%s' val:%lld", opt_char, val_str, (long long)val); 437//bb_error_msg("opt %c val_str:'%s' val:%lld", opt_char, val_str, (long long)val);
438 /* from man bash: "If neither -H nor -S
439 * is specified, both the soft and hard
440 * limits are set. */
441 if (!opts)
442 opts = OPT_hard + OPT_soft;
438 if (opts & OPT_hard) 443 if (opts & OPT_hard)
439 limit.rlim_max = val; 444 limit.rlim_max = val;
440 if ((opts & OPT_soft) || opts == 0) 445 if (opts & OPT_soft)
441 limit.rlim_cur = val; 446 limit.rlim_cur = val;
442//bb_error_msg("setrlimit(%d, %lld, %lld)", l->cmd, (long long)limit.rlim_cur, (long long)limit.rlim_max); 447//bb_error_msg("setrlimit(%d, %lld, %lld)", l->cmd, (long long)limit.rlim_cur, (long long)limit.rlim_max);
443 if (setrlimit(l->cmd, &limit) < 0) { 448 if (setrlimit(l->cmd, &limit) < 0) {
diff --git a/sysklogd/Config.src b/sysklogd/Config.src
index 6d574abb1..1e5987275 100644
--- a/sysklogd/Config.src
+++ b/sysklogd/Config.src
@@ -116,6 +116,22 @@ config KLOGD
116 you wish to record the messages produced by the kernel, 116 you wish to record the messages produced by the kernel,
117 you should enable this option. 117 you should enable this option.
118 118
119config FEATURE_KLOGD_KLOGCTL
120 bool "Use the klogctl() interface"
121 default y
122 depends on KLOGD && PLATFORM_LINUX
123 help
124 The klogd applet supports two interfaces for reading
125 kernel messages. Linux provides the klogctl() interface
126 which allows reading messages from the kernel ring buffer
127 independently from the file system.
128
129 If you answer 'N' here, klogd will use the more portable
130 approach of reading them from /proc or a device node.
131 However, this method requires the file to be available.
132
133 If in doubt, say 'Y'.
134
119config LOGGER 135config LOGGER
120 bool "logger" 136 bool "logger"
121 default y 137 default y
@@ -127,4 +143,3 @@ config LOGGER
127 problems that occur within programs and scripts. 143 problems that occur within programs and scripts.
128 144
129endmenu 145endmenu
130
diff --git a/sysklogd/klogd.c b/sysklogd/klogd.c
index c54e80a35..3468656cc 100644
--- a/sysklogd/klogd.c
+++ b/sysklogd/klogd.c
@@ -4,7 +4,7 @@
4 * 4 *
5 * Copyright (C) 2001 by Gennady Feldman <gfeldman@gena01.com>. 5 * Copyright (C) 2001 by Gennady Feldman <gfeldman@gena01.com>.
6 * Changes: Made this a standalone busybox module which uses standalone 6 * Changes: Made this a standalone busybox module which uses standalone
7 * syslog() client interface. 7 * syslog() client interface.
8 * 8 *
9 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 9 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
10 * 10 *
@@ -19,18 +19,93 @@
19 19
20#include "libbb.h" 20#include "libbb.h"
21#include <syslog.h> 21#include <syslog.h>
22#include <sys/klog.h>
23 22
24static void klogd_signal(int sig) 23
24/* The Linux-specific klogctl(3) interface does not rely on the filesystem and
25 * allows us to change the console loglevel. Alternatively, we read the
26 * messages from _PATH_KLOG. */
27
28#if ENABLE_FEATURE_KLOGD_KLOGCTL
29
30# include <sys/klog.h>
31
32static void klogd_open(void)
33{
34 /* "Open the log. Currently a NOP" */
35 klogctl(1, NULL, 0);
36}
37
38static void klogd_setloglevel(int lvl)
39{
40 /* "printk() prints a message on the console only if it has a loglevel
41 * less than console_loglevel". Here we set console_loglevel = lvl. */
42 klogctl(8, NULL, lvl);
43}
44
45static int klogd_read(char *bufp, int len)
46{
47 return klogctl(2, bufp, len);
48}
49# define READ_ERROR "klogctl(2) error"
50
51static void klogd_close(void)
25{ 52{
26 /* FYI: cmd 7 is equivalent to setting console_loglevel to 7 53 /* FYI: cmd 7 is equivalent to setting console_loglevel to 7
27 * via klogctl(8, NULL, 7). */ 54 * via klogctl(8, NULL, 7). */
28 klogctl(7, NULL, 0); /* "7 -- Enable printk's to console" */ 55 klogctl(7, NULL, 0); /* "7 -- Enable printk's to console" */
29 klogctl(0, NULL, 0); /* "0 -- Close the log. Currently a NOP" */ 56 klogctl(0, NULL, 0); /* "0 -- Close the log. Currently a NOP" */
30 syslog(LOG_NOTICE, "klogd: exiting");
31 kill_myself_with_sig(sig);
32} 57}
33 58
59#else
60
61# include <paths.h>
62# ifndef _PATH_KLOG
63# ifdef __GNU__
64# define _PATH_KLOG "/dev/klog"
65# else
66# error "your system's _PATH_KLOG is unknown"
67# endif
68# endif
69# define PATH_PRINTK "/proc/sys/kernel/printk"
70
71enum { klogfd = 3 };
72
73static void klogd_open(void)
74{
75 int fd = xopen(_PATH_KLOG, O_RDONLY);
76 xmove_fd(fd, klogfd);
77}
78
79static void klogd_setloglevel(int lvl)
80{
81 FILE *fp = fopen_or_warn(PATH_PRINTK, "w");
82 if (fp) {
83 /* This changes only first value:
84 * "messages with a higher priority than this
85 * [that is, with numerically lower value]
86 * will be printed to the console".
87 * The other three values in this pseudo-file aren't changed.
88 */
89 fprintf(fp, "%u\n", lvl);
90 fclose(fp);
91 }
92}
93
94static int klogd_read(char *bufp, int len)
95{
96 return read(klogfd, bufp, len);
97}
98# define READ_ERROR "read error"
99
100static void klogd_close(void)
101{
102 klogd_setloglevel(7);
103 if (ENABLE_FEATURE_CLEAN_UP)
104 close(klogfd);
105}
106
107#endif
108
34#define log_buffer bb_common_bufsiz1 109#define log_buffer bb_common_bufsiz1
35enum { 110enum {
36 KLOGD_LOGBUF_SIZE = sizeof(log_buffer), 111 KLOGD_LOGBUF_SIZE = sizeof(log_buffer),
@@ -38,6 +113,19 @@ enum {
38 OPT_FOREGROUND = (1 << 1), 113 OPT_FOREGROUND = (1 << 1),
39}; 114};
40 115
116/* TODO: glibc openlog(LOG_KERN) reverts to LOG_USER instead,
117 * because that's how they interpret word "default"
118 * in the openlog() manpage:
119 * LOG_USER (default)
120 * generic user-level messages
121 * and the fact that LOG_KERN is a constant 0.
122 * glibc interprets it as "0 in openlog() call means 'use default'".
123 * I think it means "if openlog wasn't called before syslog() is called,
124 * use default".
125 * Convincing glibc maintainers otherwise is, as usual, nearly impossible.
126 * Should we open-code syslog() here to use correct facility?
127 */
128
41int klogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 129int klogd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
42int klogd_main(int argc UNUSED_PARAM, char **argv) 130int klogd_main(int argc UNUSED_PARAM, char **argv)
43{ 131{
@@ -55,34 +143,34 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
55 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); 143 bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv);
56 } 144 }
57 145
58 openlog("kernel", 0, LOG_KERN); 146 logmode = LOGMODE_SYSLOG;
59
60 bb_signals(BB_FATAL_SIGS, klogd_signal);
61 signal(SIGHUP, SIG_IGN);
62 147
63 /* "Open the log. Currently a NOP" */ 148 /* klogd_open() before openlog(), since it might use fixed fd 3,
64 klogctl(1, NULL, 0); 149 * and openlog() also may use the same fd 3 if we swap them:
150 */
151 klogd_open();
152 openlog("kernel", 0, LOG_KERN);
65 153
66 /* "printk() prints a message on the console only if it has a loglevel
67 * less than console_loglevel". Here we set console_loglevel = i. */
68 if (i) 154 if (i)
69 klogctl(8, NULL, i); 155 klogd_setloglevel(i);
156
157 bb_signals(BB_FATAL_SIGS, record_signo);
158 signal(SIGHUP, SIG_IGN);
70 159
71 syslog(LOG_NOTICE, "klogd started: %s", bb_banner); 160 syslog(LOG_NOTICE, "klogd started: %s", bb_banner);
72 161
73 while (1) { 162 while (!bb_got_signal) {
74 int n; 163 int n;
75 int priority; 164 int priority;
76 char *start; 165 char *start;
77 166
78 /* "2 -- Read from the log." */ 167 /* "2 -- Read from the log." */
79 start = log_buffer + used; 168 start = log_buffer + used;
80 n = klogctl(2, start, KLOGD_LOGBUF_SIZE-1 - used); 169 n = klogd_read(start, KLOGD_LOGBUF_SIZE-1 - used);
81 if (n < 0) { 170 if (n < 0) {
82 if (errno == EINTR) 171 if (errno == EINTR)
83 continue; 172 continue;
84 syslog(LOG_ERR, "klogd: error %d in klogctl(2): %m", 173 bb_perror_msg(READ_ERROR);
85 errno);
86 break; 174 break;
87 } 175 }
88 start[n] = '\0'; 176 start[n] = '\0';
@@ -131,5 +219,9 @@ int klogd_main(int argc UNUSED_PARAM, char **argv)
131 } 219 }
132 } 220 }
133 221
222 klogd_close();
223 syslog(LOG_NOTICE, "klogd: exiting");
224 if (bb_got_signal)
225 kill_myself_with_sig(bb_got_signal);
134 return EXIT_FAILURE; 226 return EXIT_FAILURE;
135} 227}
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index 6bc450bf9..37a119b3d 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -546,7 +546,7 @@ static int try_to_resolve_remote(remoteHost_t *rh)
546 if (!rh->remoteAddr) 546 if (!rh->remoteAddr)
547 return -1; 547 return -1;
548 } 548 }
549 return socket(rh->remoteAddr->u.sa.sa_family, SOCK_DGRAM, 0); 549 return xsocket(rh->remoteAddr->u.sa.sa_family, SOCK_DGRAM, 0);
550} 550}
551#endif 551#endif
552 552
@@ -636,11 +636,25 @@ static void do_syslogd(void)
636 if (rh->remoteFD == -1) 636 if (rh->remoteFD == -1)
637 continue; 637 continue;
638 } 638 }
639 /* Send message to remote logger, ignore possible error */ 639
640 /* TODO: on some errors, close and set G.remoteFD to -1 640 /* Send message to remote logger.
641 * so that DNS resolution and connect is retried? */ 641 * On some errors, close and set remoteFD to -1
642 sendto(rh->remoteFD, recvbuf, sz+1, MSG_DONTWAIT, 642 * so that DNS resolution is retried.
643 &(rh->remoteAddr->u.sa), rh->remoteAddr->len); 643 */
644 if (sendto(rh->remoteFD, recvbuf, sz+1,
645 MSG_DONTWAIT | MSG_NOSIGNAL,
646 &(rh->remoteAddr->u.sa), rh->remoteAddr->len) == -1
647 ) {
648 switch (errno) {
649 case ECONNRESET:
650 case ENOTCONN: /* paranoia */
651 case EPIPE:
652 close(rh->remoteFD);
653 rh->remoteFD = -1;
654 free(rh->remoteAddr);
655 rh->remoteAddr = NULL;
656 }
657 }
644 } 658 }
645#endif 659#endif
646 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) { 660 if (!ENABLE_FEATURE_REMOTE_LOG || (option_mask32 & OPT_locallog)) {
diff --git a/testsuite/basename/basename-works b/testsuite/basename/basename-works
index 38907d4c1..7140e9988 100644
--- a/testsuite/basename/basename-works
+++ b/testsuite/basename/basename-works
@@ -1,2 +1 @@
1test x$(basename $(pwd)) = x$(busybox basename $(pwd)) test x$(basename $(pwd)) = x$(busybox basename $(pwd))
2
diff --git a/testsuite/dirname/dirname-works b/testsuite/dirname/dirname-works
index f339c8f73..d673dd937 100644
--- a/testsuite/dirname/dirname-works
+++ b/testsuite/dirname/dirname-works
@@ -1,2 +1 @@
1test x$(dirname $(pwd)) = x$(busybox dirname $(pwd)) test x$(dirname $(pwd)) = x$(busybox dirname $(pwd))
2
diff --git a/testsuite/expr/expr-works b/testsuite/expr/expr-works
index af49ac4d5..5a0fffbdc 100644
--- a/testsuite/expr/expr-works
+++ b/testsuite/expr/expr-works
@@ -56,4 +56,3 @@ busybox expr 0 \>= 1
56if [ $? != 1 ] ; then 56if [ $? != 1 ] ; then
57 exit 1; 57 exit 1;
58fi; 58fi;
59
diff --git a/testsuite/ln/ln-preserves-soft-links b/testsuite/ln/ln-preserves-soft-links
index a8123ece3..3a49bedf4 100644
--- a/testsuite/ln/ln-preserves-soft-links
+++ b/testsuite/ln/ln-preserves-soft-links
@@ -6,4 +6,3 @@ if [ $? != 0 ] ; then
6 exit 0; 6 exit 0;
7fi 7fi
8exit 1; 8exit 1;
9
diff --git a/testsuite/readlink.tests b/testsuite/readlink.tests
index e6822dff1..ecc3ad03e 100755
--- a/testsuite/readlink.tests
+++ b/testsuite/readlink.tests
@@ -29,4 +29,3 @@ testing "readlink -f on a wierd dir" "readlink -f $TESTDIR/../$TESTFILE" "$PWD/$
29 29
30# clean up 30# clean up
31rm -r "$TESTLINK" "$TESTDIR" 31rm -r "$TESTLINK" "$TESTDIR"
32
diff --git a/testsuite/sed.tests b/testsuite/sed.tests
index 3301a25f8..880fc2118 100755
--- a/testsuite/sed.tests
+++ b/testsuite/sed.tests
@@ -270,11 +270,16 @@ testing "sed a cmd ended by double backslash" \
270 | two \\ 270 | two \\
271' 271'
272 272
273# fisrt three lines are deleted; 4th line is matched and printed by "2,3" and by "4" ranges 273# first three lines are deleted; 4th line is matched and printed by "2,3" and by "4" ranges
274testing "sed with N skipping lines past ranges on next cmds" \ 274testing "sed with N skipping lines past ranges on next cmds" \
275 "sed -n '1{N;N;d};1p;2,3p;3p;4p'" \ 275 "sed -n '1{N;N;d};1p;2,3p;3p;4p'" \
276 "4\n4\n" "" "1\n2\n3\n4\n" 276 "4\n4\n" "" "1\n2\n3\n4\n"
277 277
278testing "sed -i with address modifies all files, not only first" \
279 "cp input input2; sed -i -e '1s/foo/bar/' input input2 && cat input input2; rm input2" \
280 "bar\nbar\n" "foo\n" ""
281
282
278# testing "description" "arguments" "result" "infile" "stdin" 283# testing "description" "arguments" "result" "infile" "stdin"
279 284
280exit $FAILCOUNT 285exit $FAILCOUNT
diff --git a/testsuite/testing.sh b/testsuite/testing.sh
index 913d7f8ef..f907deade 100644
--- a/testsuite/testing.sh
+++ b/testsuite/testing.sh
@@ -26,7 +26,7 @@
26# number of failed tests. 26# number of failed tests.
27 27
28# The "optional" function is used to skip certain tests, ala: 28# The "optional" function is used to skip certain tests, ala:
29# optional CONFIG_FEATURE_THINGY 29# optional FEATURE_THINGY
30# 30#
31# The "optional" function checks the environment variable "OPTIONFLAGS", 31# The "optional" function checks the environment variable "OPTIONFLAGS",
32# which is either empty (in which case it always clears SKIP) or 32# which is either empty (in which case it always clears SKIP) or
diff --git a/testsuite/tr.tests b/testsuite/tr.tests
index a1f83bfc6..5dabbb52f 100755
--- a/testsuite/tr.tests
+++ b/testsuite/tr.tests
@@ -15,19 +15,19 @@ testing "tr understands 0-9A-F" \
15 "tr -cd '[0-9A-F]'" \ 15 "tr -cd '[0-9A-F]'" \
16 "19AF" "" "19AFH\n" 16 "19AF" "" "19AFH\n"
17 17
18optional CONFIG_FEATURE_TR_CLASSES 18optional FEATURE_TR_CLASSES
19testing "tr understands [:xdigit:]" \ 19testing "tr understands [:xdigit:]" \
20 "tr -cd '[:xdigit:]'" \ 20 "tr -cd '[:xdigit:]'" \
21 "19AF" "" "19AFH\n" 21 "19AF" "" "19AFH\n"
22SKIP= 22SKIP=
23 23
24optional CONFIG_FEATURE_TR_CLASSES 24optional FEATURE_TR_CLASSES
25testing "tr does not stop after [:digit:]" \ 25testing "tr does not stop after [:digit:]" \
26 "tr '[:digit:]y-z' 111111111123" \ 26 "tr '[:digit:]y-z' 111111111123" \
27 "111abcx23\n" "" "789abcxyz\n" 27 "111abcx23\n" "" "789abcxyz\n"
28SKIP= 28SKIP=
29 29
30optional CONFIG_FEATURE_TR_CLASSES 30optional FEATURE_TR_CLASSES
31testing "tr has correct xdigit sequence" \ 31testing "tr has correct xdigit sequence" \
32 "tr '[:xdigit:]Gg' 1111111151242222333330xX" \ 32 "tr '[:xdigit:]Gg' 1111111151242222333330xX" \
33 "#1111111151242222x333330X\n" "" \ 33 "#1111111151242222x333330X\n" "" \
diff --git a/testsuite/uptime/uptime-works b/testsuite/uptime/uptime-works
index 80e578778..6b168ab0e 100644
--- a/testsuite/uptime/uptime-works
+++ b/testsuite/uptime/uptime-works
@@ -1,2 +1 @@
1busybox uptime busybox uptime
2
diff --git a/util-linux/Config.src b/util-linux/Config.src
index 91d1fc2ce..98953c17b 100644
--- a/util-linux/Config.src
+++ b/util-linux/Config.src
@@ -10,6 +10,7 @@ INSERT
10config ACPID 10config ACPID
11 bool "acpid" 11 bool "acpid"
12 default y 12 default y
13 depends on PLATFORM_LINUX
13 help 14 help
14 acpid listens to ACPI events coming either in textual form from 15 acpid listens to ACPI events coming either in textual form from
15 /proc/acpi/event (though it is marked deprecated it is still widely 16 /proc/acpi/event (though it is marked deprecated it is still widely
@@ -32,6 +33,7 @@ config FEATURE_ACPID_COMPAT
32config BLKID 33config BLKID
33 bool "blkid" 34 bool "blkid"
34 default y 35 default y
36 depends on PLATFORM_LINUX
35 select VOLUMEID 37 select VOLUMEID
36 help 38 help
37 Lists labels and UUIDs of all filesystems. 39 Lists labels and UUIDs of all filesystems.
@@ -41,6 +43,7 @@ config BLKID
41config DMESG 43config DMESG
42 bool "dmesg" 44 bool "dmesg"
43 default y 45 default y
46 depends on PLATFORM_LINUX
44 help 47 help
45 dmesg is used to examine or control the kernel ring buffer. When the 48 dmesg is used to examine or control the kernel ring buffer. When the
46 Linux kernel prints messages to the system log, they are stored in 49 Linux kernel prints messages to the system log, they are stored in
@@ -74,6 +77,7 @@ config FEATURE_DMESG_PRETTY
74config FBSET 77config FBSET
75 bool "fbset" 78 bool "fbset"
76 default y 79 default y
80 depends on PLATFORM_LINUX
77 help 81 help
78 fbset is used to show or change the settings of a Linux frame buffer 82 fbset is used to show or change the settings of a Linux frame buffer
79 device. The frame buffer device provides a simple and unique 83 device. The frame buffer device provides a simple and unique
@@ -102,6 +106,7 @@ config FEATURE_FBSET_READMODE
102config FDFLUSH 106config FDFLUSH
103 bool "fdflush" 107 bool "fdflush"
104 default y 108 default y
109 depends on PLATFORM_LINUX
105 help 110 help
106 fdflush is only needed when changing media on slightly-broken 111 fdflush is only needed when changing media on slightly-broken
107 removable media drives. It is used to make Linux believe that a 112 removable media drives. It is used to make Linux believe that a
@@ -114,12 +119,14 @@ config FDFLUSH
114config FDFORMAT 119config FDFORMAT
115 bool "fdformat" 120 bool "fdformat"
116 default y 121 default y
122 depends on PLATFORM_LINUX
117 help 123 help
118 fdformat is used to low-level format a floppy disk. 124 fdformat is used to low-level format a floppy disk.
119 125
120config FDISK 126config FDISK
121 bool "fdisk" 127 bool "fdisk"
122 default y 128 default y
129 depends on PLATFORM_LINUX
123 help 130 help
124 The fdisk utility is used to divide hard disks into one or more 131 The fdisk utility is used to divide hard disks into one or more
125 logical disks, which are generally called partitions. This utility 132 logical disks, which are generally called partitions. This utility
@@ -187,6 +194,7 @@ config FEATURE_FDISK_ADVANCED
187config FINDFS 194config FINDFS
188 bool "findfs" 195 bool "findfs"
189 default y 196 default y
197 depends on PLATFORM_LINUX
190 select VOLUMEID 198 select VOLUMEID
191 help 199 help
192 Prints the name of a filesystem with given label or UUID. 200 Prints the name of a filesystem with given label or UUID.
@@ -202,6 +210,7 @@ config FLOCK
202config FREERAMDISK 210config FREERAMDISK
203 bool "freeramdisk" 211 bool "freeramdisk"
204 default y 212 default y
213 depends on PLATFORM_LINUX
205 help 214 help
206 Linux allows you to create ramdisks. This utility allows you to 215 Linux allows you to create ramdisks. This utility allows you to
207 delete them and completely free all memory that was used for the 216 delete them and completely free all memory that was used for the
@@ -224,12 +233,14 @@ config FSCK_MINIX
224config MKFS_EXT2 233config MKFS_EXT2
225 bool "mkfs_ext2" 234 bool "mkfs_ext2"
226 default y 235 default y
236 depends on PLATFORM_LINUX
227 help 237 help
228 Utility to create EXT2 filesystems. 238 Utility to create EXT2 filesystems.
229 239
230config MKFS_MINIX 240config MKFS_MINIX
231 bool "mkfs_minix" 241 bool "mkfs_minix"
232 default y 242 default y
243 depends on PLATFORM_LINUX
233 help 244 help
234 The minix filesystem is a nice, small, compact, read-write filesystem 245 The minix filesystem is a nice, small, compact, read-write filesystem
235 with little overhead. If you wish to be able to create minix 246 with little overhead. If you wish to be able to create minix
@@ -247,6 +258,7 @@ config FEATURE_MINIX2
247config MKFS_REISER 258config MKFS_REISER
248 bool "mkfs_reiser" 259 bool "mkfs_reiser"
249 default n 260 default n
261 depends on PLATFORM_LINUX
250 help 262 help
251 Utility to create ReiserFS filesystems. 263 Utility to create ReiserFS filesystems.
252 Note: this applet needs a lot of testing and polishing. 264 Note: this applet needs a lot of testing and polishing.
@@ -254,6 +266,7 @@ config MKFS_REISER
254config MKFS_VFAT 266config MKFS_VFAT
255 bool "mkfs_vfat" 267 bool "mkfs_vfat"
256 default y 268 default y
269 depends on PLATFORM_LINUX
257 help 270 help
258 Utility to create FAT32 filesystems. 271 Utility to create FAT32 filesystems.
259 272
@@ -302,6 +315,7 @@ config HD
302config HWCLOCK 315config HWCLOCK
303 bool "hwclock" 316 bool "hwclock"
304 default y 317 default y
318 depends on PLATFORM_LINUX
305 help 319 help
306 The hwclock utility is used to read and set the hardware clock 320 The hwclock utility is used to read and set the hardware clock
307 on a system. This is primarily used to set the current time on 321 on a system. This is primarily used to set the current time on
@@ -341,6 +355,7 @@ config IPCRM
341config IPCS 355config IPCS
342 bool "ipcs" 356 bool "ipcs"
343 default y 357 default y
358 depends on PLATFORM_LINUX
344 select FEATURE_SUID 359 select FEATURE_SUID
345 help 360 help
346 The ipcs utility is used to provide information on the currently 361 The ipcs utility is used to provide information on the currently
@@ -349,6 +364,7 @@ config IPCS
349config LOSETUP 364config LOSETUP
350 bool "losetup" 365 bool "losetup"
351 default y 366 default y
367 depends on PLATFORM_LINUX
352 help 368 help
353 losetup is used to associate or detach a loop device with a regular 369 losetup is used to associate or detach a loop device with a regular
354 file or block device, and to query the status of a loop device. This 370 file or block device, and to query the status of a loop device. This
@@ -357,6 +373,7 @@ config LOSETUP
357config LSPCI 373config LSPCI
358 bool "lspci" 374 bool "lspci"
359 default y 375 default y
376 #depends on PLATFORM_LINUX
360 help 377 help
361 lspci is a utility for displaying information about PCI buses in the 378 lspci is a utility for displaying information about PCI buses in the
362 system and devices connected to them. 379 system and devices connected to them.
@@ -366,6 +383,7 @@ config LSPCI
366config LSUSB 383config LSUSB
367 bool "lsusb" 384 bool "lsusb"
368 default y 385 default y
386 #depends on PLATFORM_LINUX
369 help 387 help
370 lsusb is a utility for displaying information about USB buses in the 388 lsusb is a utility for displaying information about USB buses in the
371 system and devices connected to them. 389 system and devices connected to them.
@@ -375,6 +393,7 @@ config LSUSB
375config MDEV 393config MDEV
376 bool "mdev" 394 bool "mdev"
377 default y 395 default y
396 depends on PLATFORM_LINUX
378 help 397 help
379 mdev is a mini-udev implementation for dynamically creating device 398 mdev is a mini-udev implementation for dynamically creating device
380 nodes in the /dev directory. 399 nodes in the /dev directory.
@@ -473,6 +492,7 @@ config FEATURE_USE_TERMIOS
473config MOUNT 492config MOUNT
474 bool "mount" 493 bool "mount"
475 default y 494 default y
495 depends on PLATFORM_LINUX
476 help 496 help
477 All files and filesystems in Unix are arranged into one big directory 497 All files and filesystems in Unix are arranged into one big directory
478 tree. The 'mount' utility is used to graft a filesystem onto a 498 tree. The 'mount' utility is used to graft a filesystem onto a
@@ -555,6 +575,7 @@ config FEATURE_MOUNT_FSTAB
555config PIVOT_ROOT 575config PIVOT_ROOT
556 bool "pivot_root" 576 bool "pivot_root"
557 default y 577 default y
578 depends on PLATFORM_LINUX
558 help 579 help
559 The pivot_root utility swaps the mount points for the root filesystem 580 The pivot_root utility swaps the mount points for the root filesystem
560 with some other mounted filesystem. This allows you to do all sorts 581 with some other mounted filesystem. This allows you to do all sorts
@@ -582,12 +603,14 @@ config RDEV
582config READPROFILE 603config READPROFILE
583 bool "readprofile" 604 bool "readprofile"
584 default y 605 default y
606 #depends on PLATFORM_LINUX
585 help 607 help
586 This allows you to parse /proc/profile for basic profiling. 608 This allows you to parse /proc/profile for basic profiling.
587 609
588config RTCWAKE 610config RTCWAKE
589 bool "rtcwake" 611 bool "rtcwake"
590 default y 612 default y
613 depends on PLATFORM_LINUX
591 help 614 help
592 Enter a system sleep state until specified wakeup time. 615 Enter a system sleep state until specified wakeup time.
593 616
@@ -607,6 +630,7 @@ config SCRIPTREPLAY
607config SETARCH 630config SETARCH
608 bool "setarch" 631 bool "setarch"
609 default y 632 default y
633 depends on PLATFORM_LINUX
610 help 634 help
611 The linux32 utility is used to create a 32bit environment for the 635 The linux32 utility is used to create a 32bit environment for the
612 specified program (usually a shell). It only makes sense to have 636 specified program (usually a shell). It only makes sense to have
@@ -616,6 +640,7 @@ config SETARCH
616config SWAPONOFF 640config SWAPONOFF
617 bool "swaponoff" 641 bool "swaponoff"
618 default y 642 default y
643 depends on PLATFORM_LINUX
619 help 644 help
620 This option enables both the 'swapon' and the 'swapoff' utilities. 645 This option enables both the 'swapon' and the 'swapoff' utilities.
621 Once you have created some swap space using 'mkswap', you also need 646 Once you have created some swap space using 'mkswap', you also need
@@ -634,6 +659,7 @@ config FEATURE_SWAPON_PRI
634config SWITCH_ROOT 659config SWITCH_ROOT
635 bool "switch_root" 660 bool "switch_root"
636 default y 661 default y
662 depends on PLATFORM_LINUX
637 help 663 help
638 The switch_root utility is used from initramfs to select a new 664 The switch_root utility is used from initramfs to select a new
639 root device. Under initramfs, you have to use this instead of 665 root device. Under initramfs, you have to use this instead of
@@ -653,6 +679,7 @@ config SWITCH_ROOT
653config UMOUNT 679config UMOUNT
654 bool "umount" 680 bool "umount"
655 default y 681 default y
682 depends on PLATFORM_LINUX
656 help 683 help
657 When you want to remove a mounted filesystem from its current mount 684 When you want to remove a mounted filesystem from its current mount
658 point, for example when you are shutting down the system, the 685 point, for example when you are shutting down the system, the
diff --git a/util-linux/fdisk.c b/util-linux/fdisk.c
index aa718c787..fc02000e5 100644
--- a/util-linux/fdisk.c
+++ b/util-linux/fdisk.c
@@ -2043,7 +2043,6 @@ fix_partition_table_order(void)
2043 fix_chain_of_logicals(); 2043 fix_chain_of_logicals();
2044 2044
2045 printf("Done.\n"); 2045 printf("Done.\n");
2046
2047} 2046}
2048#endif 2047#endif
2049 2048
diff --git a/util-linux/volume_id/volume_id.c b/util-linux/volume_id/volume_id.c
index c8cf946df..f41d4e0d9 100644
--- a/util-linux/volume_id/volume_id.c
+++ b/util-linux/volume_id/volume_id.c
@@ -195,7 +195,6 @@ int FAST_FUNC volume_id_probe_all(struct volume_id *id, /*uint64_t off,*/ uint64
195 ret: 195 ret:
196 volume_id_free_buffer(id); 196 volume_id_free_buffer(id);
197 return (- id->error); /* 0 or -1 */ 197 return (- id->error); /* 0 or -1 */
198
199} 198}
200 199
201/* open volume by device node */ 200/* open volume by device node */