Merge lp:~smoser/ubuntu/oneiric/busybox/debian-merge-1.18.4 into lp:ubuntu/oneiric/busybox

Proposed by Scott Moser
Status: Merged
Merge reported by: Clint Byrum
Merged at revision: not available
Proposed branch: lp:~smoser/ubuntu/oneiric/busybox/debian-merge-1.18.4
Merge into: lp:ubuntu/oneiric/busybox
Diff against target: 131942 lines (+46049/-62971)
1014 files modified
.pc/applets-fallback.patch/Config.in (+46/-27)
.pc/applets-fallback.patch/coreutils/chroot.c (+1/-1)
.pc/applets-fallback.patch/include/libbb.h (+136/-102)
.pc/applets-fallback.patch/libbb/execable.c (+1/-1)
.pc/applets-fallback.patch/libbb/messages.c (+1/-10)
.pc/applets-fallback.patch/shell/ash.c (+440/-333)
.pc/applied-patches (+1/-22)
.pc/bootchartd-mounting-tmpfs-is-Linux-specific.patch/init/bootchartd.c (+0/-443)
.pc/cttyhack-serial-console-detection-is-Linux-specific.patch/shell/Config.src (+0/-402)
.pc/cttyhack-serial-console-detection-is-Linux-specific.patch/shell/cttyhack.c (+0/-85)
.pc/dirname-basename-skip-doubledash.diff/coreutils/basename.c (+61/-0)
.pc/dirname-basename-skip-doubledash.diff/coreutils/dirname.c (+22/-0)
.pc/doc-man-name.patch/Makefile.custom (+0/-177)
.pc/grep-o-loop.patch/findutils/grep.c (+0/-771)
.pc/grep-o-loop.patch/testsuite/grep.tests (+0/-102)
.pc/init-console-CRTSCTS.patch/init/init.c (+0/-1047)
.pc/init-console.patch/init/init.c (+281/-20)
.pc/init-halt-portability-improvements.patch/init/Config.src (+0/-127)
.pc/init-halt-portability-improvements.patch/init/halt.c (+0/-125)
.pc/init-halt-portability-improvements.patch/init/init.c (+0/-1047)
.pc/init-loginutils-termios-portability-fixes.patch/init/init.c (+0/-1032)
.pc/init-loginutils-termios-portability-fixes.patch/loginutils/Config.src (+0/-308)
.pc/init-loginutils-termios-portability-fixes.patch/loginutils/getty.c (+0/-736)
.pc/init-loginutils-termios-portability-fixes.patch/loginutils/login.c (+0/-433)
.pc/init-make-the-initial-TERM-value-configurable.patch/init/Config.src (+0/-125)
.pc/init-make-the-initial-TERM-value-configurable.patch/init/init.c (+0/-1047)
.pc/klogd-make-it-work-on-non-linux-systems.patch/sysklogd/Config.src (+0/-131)
.pc/klogd-make-it-work-on-non-linux-systems.patch/sysklogd/klogd.c (+0/-135)
.pc/less-remove-misguided-dependency-on-PLATFORM_LINUX.patch/miscutils/Config.src (+0/-669)
.pc/libbb-conditionalize-AF_-usage-in-error-reporting.patch/libbb/xfuncs_printf.c (+0/-602)
.pc/libbb-conditionalize-AF_-usage-in-error-reporting.patch/networking/Config.src (+0/-1023)
.pc/libbb.h-add-device-names-for-Hurd-and-FreeBSD.patch/include/libbb.h (+0/-1757)
.pc/make_gen_build_files_skip_quilt.patch/scripts/gen_build_files.sh (+48/-53)
.pc/mark-Linux-specific-configuration-options.patch/Config.in (+0/-739)
.pc/mark-Linux-specific-configuration-options.patch/console-tools/Config.src (+0/-163)
.pc/mark-Linux-specific-configuration-options.patch/coreutils/Config.src (+0/-808)
.pc/mark-Linux-specific-configuration-options.patch/coreutils/date.c (+0/-334)
.pc/mark-Linux-specific-configuration-options.patch/e2fsprogs/Config.src (+0/-70)
.pc/mark-Linux-specific-configuration-options.patch/init/Config.src (+0/-125)
.pc/mark-Linux-specific-configuration-options.patch/init/bootchartd.c (+0/-442)
.pc/mark-Linux-specific-configuration-options.patch/libbb/Config.src (+0/-178)
.pc/mark-Linux-specific-configuration-options.patch/loginutils/Config.src (+0/-305)
.pc/mark-Linux-specific-configuration-options.patch/miscutils/Config.src (+0/-652)
.pc/mark-Linux-specific-configuration-options.patch/miscutils/conspy.c (+0/-547)
.pc/mark-Linux-specific-configuration-options.patch/miscutils/ubi_attach_detach.c (+0/-88)
.pc/mark-Linux-specific-configuration-options.patch/modutils/Config.src (+0/-244)
.pc/mark-Linux-specific-configuration-options.patch/networking/Config.src (+0/-1002)
.pc/mark-Linux-specific-configuration-options.patch/networking/udhcp/Config.src (+0/-130)
.pc/mark-Linux-specific-configuration-options.patch/procps/Config.src (+0/-215)
.pc/mark-Linux-specific-configuration-options.patch/shell/Config.src (+0/-401)
.pc/mark-Linux-specific-configuration-options.patch/sysklogd/Config.src (+0/-130)
.pc/mark-Linux-specific-configuration-options.patch/util-linux/Config.src (+0/-945)
.pc/mkdir-fix-p-on-FreeBSD.patch/libbb/make_directory.c (+0/-129)
.pc/readlink-use-xmalloc_realpath.patch/coreutils/readlink.c (+0/-72)
.pc/shell-ash-export-HOME.patch/shell/ash.c (+440/-333)
.pc/static-sh-alias.patch/include/applets.src.h (+0/-445)
.pc/static-sh-alias.patch/include/usage.src.h (+0/-4872)
.pc/static-sh-alias.patch/shell/ash.c (+13139/-0)
.pc/strip.patch/Makefile (+0/-1337)
.pc/stty-sort-out-preprocessor-conditionals.patch/coreutils/Config.src (+0/-810)
.pc/stty-sort-out-preprocessor-conditionals.patch/coreutils/stty.c (+0/-1441)
.pc/swaponoff-FreeBSD-support.patch/util-linux/Config.src (+9/-14)
.pc/swaponoff-FreeBSD-support.patch/util-linux/swaponoff.c (+1/-1)
.pc/swaponoff-FreeBSD-support.patch/util-linux/xmount.c (+1/-1)
.pc/tcpsvd-udpsvd-conditionalize-usage-of-SO_ORIGINAL_DS.patch/networking/Config.src (+0/-1022)
.pc/tcpsvd-udpsvd-conditionalize-usage-of-SO_ORIGINAL_DS.patch/networking/tcpudp.c (+0/-604)
.pc/test-bin.patch/include/applets.src.h (+16/-44)
.pc/u-mount-FreeBSD-support.patch/util-linux/Config.src (+9/-14)
.pc/u-mount-FreeBSD-support.patch/util-linux/Kbuild.src (+1/-1)
.pc/u-mount-FreeBSD-support.patch/util-linux/mount.c (+40/-56)
.pc/u-mount-FreeBSD-support.patch/util-linux/umount.c (+8/-44)
.pc/update-scripts-kconfig-_shipped.patch/scripts/kconfig/lex.zconf.c_shipped (+0/-2325)
.pc/version.patch/Makefile.flags (+1/-1)
.pc/vlock-disable-linux-console-calls-on-other-systems.patch/loginutils/Config.src (+0/-306)
.pc/vlock-disable-linux-console-calls-on-other-systems.patch/loginutils/vlock.c (+0/-101)
Config.in (+34/-27)
Makefile (+29/-10)
Makefile.custom (+1/-0)
Makefile.flags (+1/-1)
README (+1/-1)
TEST_config_nommu (+0/-1)
TEST_config_noprintf (+0/-1)
TEST_config_rh9 (+1/-1)
TODO (+1/-1)
applets/Kbuild.src (+1/-1)
applets/applet_tables.c (+1/-1)
applets/applets.c (+1/-1)
applets/individual.c (+1/-1)
applets/usage.c (+1/-1)
applets/usage_compressed (+7/-0)
applets/usage_pod.c (+1/-1)
archival/Config.src (+2/-2)
archival/Kbuild.src (+3/-4)
archival/ar.c (+11/-12)
archival/bbunzip.c (+8/-8)
archival/bz/LICENSE (+0/-44)
archival/bz/README (+0/-90)
archival/bz/blocksort.c (+0/-1072)
archival/bz/bzlib.c (+0/-431)
archival/bz/bzlib.h (+0/-65)
archival/bz/bzlib_private.h (+0/-219)
archival/bz/compress.c (+0/-687)
archival/bz/huffman.c (+0/-229)
archival/bzip2.c (+13/-11)
archival/cpio.c (+3/-7)
archival/dpkg.c (+11/-10)
archival/dpkg_deb.c (+7/-7)
archival/gzip.c (+9/-15)
archival/libarchive/Kbuild.src (+64/-0)
archival/libarchive/bz/LICENSE (+44/-0)
archival/libarchive/bz/README (+90/-0)
archival/libarchive/bz/blocksort.c (+1072/-0)
archival/libarchive/bz/bzlib.c (+429/-0)
archival/libarchive/bz/bzlib.h (+65/-0)
archival/libarchive/bz/bzlib_private.h (+219/-0)
archival/libarchive/bz/compress.c (+685/-0)
archival/libarchive/bz/huffman.c (+229/-0)
archival/libarchive/data_align.c (+15/-0)
archival/libarchive/data_extract_all.c (+200/-0)
archival/libarchive/data_extract_to_command.c (+134/-0)
archival/libarchive/data_extract_to_stdout.c (+14/-0)
archival/libarchive/data_skip.c (+12/-0)
archival/libarchive/decompress_bunzip2.c (+822/-0)
archival/libarchive/decompress_uncompress.c (+307/-0)
archival/libarchive/decompress_unlzma.c (+465/-0)
archival/libarchive/decompress_unxz.c (+98/-0)
archival/libarchive/decompress_unzip.c (+1252/-0)
archival/libarchive/filter_accept_all.c (+17/-0)
archival/libarchive/filter_accept_list.c (+19/-0)
archival/libarchive/filter_accept_list_reassign.c (+51/-0)
archival/libarchive/filter_accept_reject_list.c (+36/-0)
archival/libarchive/find_list_entry.c (+54/-0)
archival/libarchive/get_header_ar.c (+133/-0)
archival/libarchive/get_header_cpio.c (+186/-0)
archival/libarchive/get_header_tar.c (+461/-0)
archival/libarchive/get_header_tar_bz2.c (+21/-0)
archival/libarchive/get_header_tar_gz.c (+36/-0)
archival/libarchive/get_header_tar_lzma.c (+24/-0)
archival/libarchive/header_list.c (+12/-0)
archival/libarchive/header_skip.c (+10/-0)
archival/libarchive/header_verbose_list.c (+69/-0)
archival/libarchive/init_handle.c (+22/-0)
archival/libarchive/liblzo.h (+93/-0)
archival/libarchive/lzo1x_1.c (+35/-0)
archival/libarchive/lzo1x_1o.c (+35/-0)
archival/libarchive/lzo1x_9x.c (+921/-0)
archival/libarchive/lzo1x_c.c (+296/-0)
archival/libarchive/lzo1x_d.c (+420/-0)
archival/libarchive/open_transformer.c (+54/-0)
archival/libarchive/seek_by_jump.c (+19/-0)
archival/libarchive/seek_by_read.c (+16/-0)
archival/libarchive/unpack_ar_archive.c (+22/-0)
archival/libarchive/unxz/README (+135/-0)
archival/libarchive/unxz/xz.h (+271/-0)
archival/libarchive/unxz/xz_config.h (+123/-0)
archival/libarchive/unxz/xz_dec_bcj.c (+564/-0)
archival/libarchive/unxz/xz_dec_lzma2.c (+1175/-0)
archival/libarchive/unxz/xz_dec_stream.c (+822/-0)
archival/libarchive/unxz/xz_lzma2.h (+204/-0)
archival/libarchive/unxz/xz_private.h (+159/-0)
archival/libarchive/unxz/xz_stream.h (+57/-0)
archival/liblzo.h (+0/-93)
archival/liblzo_interface.h (+0/-71)
archival/libunarchive/Kbuild.src (+0/-61)
archival/libunarchive/data_align.c (+0/-15)
archival/libunarchive/data_extract_all.c (+0/-198)
archival/libunarchive/data_extract_to_command.c (+0/-134)
archival/libunarchive/data_extract_to_stdout.c (+0/-14)
archival/libunarchive/data_skip.c (+0/-12)
archival/libunarchive/decompress_bunzip2.c (+0/-724)
archival/libunarchive/decompress_uncompress.c (+0/-307)
archival/libunarchive/decompress_unlzma.c (+0/-465)
archival/libunarchive/decompress_unxz.c (+0/-106)
archival/libunarchive/decompress_unzip.c (+0/-1255)
archival/libunarchive/filter_accept_all.c (+0/-17)
archival/libunarchive/filter_accept_list.c (+0/-19)
archival/libunarchive/filter_accept_list_reassign.c (+0/-51)
archival/libunarchive/filter_accept_reject_list.c (+0/-36)
archival/libunarchive/find_list_entry.c (+0/-54)
archival/libunarchive/get_header_ar.c (+0/-133)
archival/libunarchive/get_header_cpio.c (+0/-186)
archival/libunarchive/get_header_tar.c (+0/-461)
archival/libunarchive/get_header_tar_bz2.c (+0/-21)
archival/libunarchive/get_header_tar_gz.c (+0/-36)
archival/libunarchive/get_header_tar_lzma.c (+0/-24)
archival/libunarchive/header_list.c (+0/-12)
archival/libunarchive/header_skip.c (+0/-10)
archival/libunarchive/header_verbose_list.c (+0/-69)
archival/libunarchive/init_handle.c (+0/-22)
archival/libunarchive/open_transformer.c (+0/-54)
archival/libunarchive/seek_by_jump.c (+0/-19)
archival/libunarchive/seek_by_read.c (+0/-16)
archival/libunarchive/unpack_ar_archive.c (+0/-22)
archival/libunarchive/unxz/README (+0/-136)
archival/libunarchive/unxz/xz.h (+0/-271)
archival/libunarchive/unxz/xz_config.h (+0/-123)
archival/libunarchive/unxz/xz_dec_bcj.c (+0/-564)
archival/libunarchive/unxz/xz_dec_lzma2.c (+0/-1175)
archival/libunarchive/unxz/xz_dec_stream.c (+0/-822)
archival/libunarchive/unxz/xz_lzma2.h (+0/-204)
archival/libunarchive/unxz/xz_private.h (+0/-159)
archival/libunarchive/unxz/xz_stream.h (+0/-57)
archival/lzo1x_1.c (+0/-35)
archival/lzo1x_1o.c (+0/-35)
archival/lzo1x_9x.c (+0/-922)
archival/lzo1x_c.c (+0/-296)
archival/lzo1x_d.c (+0/-420)
archival/lzop.c (+30/-33)
archival/rpm.c (+2/-2)
archival/rpm.h (+1/-1)
archival/rpm2cpio.c (+2/-2)
archival/tar.c (+8/-7)
archival/unzip.c (+2/-3)
busybox-1.17.1/.indent.pro (+0/-33)
console-tools/Kbuild.src (+1/-1)
console-tools/chvt.c (+1/-1)
console-tools/clear.c (+1/-1)
console-tools/deallocvt.c (+1/-1)
console-tools/dumpkmap.c (+1/-1)
console-tools/fgconsole.c (+1/-1)
console-tools/kbd_mode.c (+3/-3)
console-tools/loadfont.c (+5/-5)
console-tools/loadkmap.c (+1/-1)
console-tools/openvt.c (+1/-1)
console-tools/reset.c (+8/-6)
console-tools/resize.c (+2/-2)
console-tools/setconsole.c (+1/-1)
console-tools/setkeycodes.c (+1/-1)
console-tools/setlogcons.c (+1/-1)
console-tools/showkey.c (+52/-59)
coreutils/Kbuild.src (+1/-1)
coreutils/basename.c (+5/-1)
coreutils/cal.c (+1/-1)
coreutils/cat.c (+1/-1)
coreutils/catv.c (+1/-1)
coreutils/chgrp.c (+1/-1)
coreutils/chmod.c (+1/-1)
coreutils/chown.c (+1/-1)
coreutils/chroot.c (+1/-1)
coreutils/cksum.c (+4/-6)
coreutils/comm.c (+1/-1)
coreutils/cp.c (+1/-1)
coreutils/cut.c (+3/-4)
coreutils/date.c (+86/-43)
coreutils/dd.c (+2/-2)
coreutils/df.c (+1/-1)
coreutils/dirname.c (+3/-1)
coreutils/dos2unix.c (+6/-6)
coreutils/du.c (+1/-1)
coreutils/echo.c (+1/-1)
coreutils/env.c (+4/-4)
coreutils/expand.c (+1/-1)
coreutils/expr.c (+1/-2)
coreutils/false.c (+1/-1)
coreutils/fold.c (+3/-1)
coreutils/fsync.c (+2/-2)
coreutils/head.c (+3/-1)
coreutils/hostid.c (+1/-1)
coreutils/id.c (+3/-1)
coreutils/install.c (+1/-1)
coreutils/length.c (+1/-1)
coreutils/libcoreutils/Kbuild.src (+1/-1)
coreutils/libcoreutils/coreutils.h (+1/-1)
coreutils/ln.c (+1/-1)
coreutils/logname.c (+1/-1)
coreutils/ls.c (+6/-7)
coreutils/md5_sha1_sum.c (+30/-27)
coreutils/mkdir.c (+1/-1)
coreutils/mkfifo.c (+4/-2)
coreutils/mknod.c (+3/-1)
coreutils/mv.c (+34/-14)
coreutils/nice.c (+4/-4)
coreutils/nohup.c (+1/-1)
coreutils/od.c (+17/-17)
coreutils/printenv.c (+3/-1)
coreutils/printf.c (+11/-13)
coreutils/pwd.c (+1/-1)
coreutils/readlink.c (+1/-1)
coreutils/realpath.c (+1/-1)
coreutils/rm.c (+1/-1)
coreutils/rmdir.c (+2/-2)
coreutils/seq.c (+3/-2)
coreutils/sleep.c (+14/-9)
coreutils/sort.c (+4/-4)
coreutils/split.c (+2/-4)
coreutils/stat.c (+11/-14)
coreutils/stty.c (+4/-4)
coreutils/sum.c (+1/-1)
coreutils/sync.c (+1/-1)
coreutils/tac.c (+1/-1)
coreutils/tail.c (+2/-1)
coreutils/tee.c (+6/-6)
coreutils/test.c (+4/-4)
coreutils/test_ptr_hack.c (+1/-1)
coreutils/touch.c (+2/-2)
coreutils/tr.c (+5/-5)
coreutils/true.c (+1/-1)
coreutils/tty.c (+3/-3)
coreutils/uname.c (+1/-1)
coreutils/uniq.c (+4/-4)
coreutils/usleep.c (+1/-1)
coreutils/uudecode.c (+80/-77)
coreutils/uuencode.c (+3/-3)
coreutils/wc.c (+62/-29)
coreutils/who.c (+1/-1)
coreutils/whoami.c (+1/-1)
coreutils/yes.c (+1/-1)
debian/README.source (+33/-0)
debian/changelog (+191/-93)
debian/config/pkg/deb (+49/-32)
debian/config/pkg/initramfs (+36/-20)
debian/config/pkg/static (+43/-27)
debian/config/pkg/udeb (+39/-23)
debian/control (+5/-2)
debian/gbp.conf (+2/-0)
debian/patches/applets-fallback.patch (+24/-12)
debian/patches/blockdev.patch (+0/-210)
debian/patches/bootchartd-mounting-tmpfs-is-Linux-specific.patch (+0/-66)
debian/patches/cttyhack-serial-console-detection-is-Linux-specific.patch (+0/-60)
debian/patches/debian-changes-1:1.17.1-10 (+0/-70)
debian/patches/dirname-basename-skip-doubledash.diff (+31/-0)
debian/patches/doc-man-name.patch (+0/-24)
debian/patches/grep-o-loop.patch (+0/-53)
debian/patches/init-console-CRTSCTS.patch (+0/-15)
debian/patches/init-console.patch (+1/-1)
debian/patches/init-halt-portability-improvements.patch (+0/-185)
debian/patches/init-loginutils-termios-portability-fixes.patch (+0/-199)
debian/patches/init-make-the-initial-TERM-value-configurable.patch (+0/-51)
debian/patches/klogd-make-it-work-on-non-linux-systems.patch (+0/-246)
debian/patches/less-remove-misguided-dependency-on-PLATFORM_LINUX.patch (+0/-27)
debian/patches/libbb-conditionalize-AF_-usage-in-error-reporting.patch (+0/-44)
debian/patches/libbb.h-add-device-names-for-Hurd-and-FreeBSD.patch (+0/-58)
debian/patches/make_gen_build_files_skip_quilt.patch (+6/-8)
debian/patches/mark-Linux-specific-configuration-options.patch (+0/-915)
debian/patches/mkdir-fix-p-on-FreeBSD.patch (+0/-30)
debian/patches/readlink-use-xmalloc_realpath.patch (+0/-50)
debian/patches/series (+3/-28)
debian/patches/shell-ash-export-HOME.patch (+1/-1)
debian/patches/static-sh-alias.patch (+0/-30)
debian/patches/strip.patch (+0/-24)
debian/patches/stty-sort-out-preprocessor-conditionals.patch (+0/-705)
debian/patches/swaponoff-FreeBSD-support.patch (+4/-15)
debian/patches/tcpsvd-udpsvd-conditionalize-usage-of-SO_ORIGINAL_DS.patch (+0/-70)
debian/patches/test-bin.patch (+1/-3)
debian/patches/u-mount-FreeBSD-support.patch (+27/-67)
debian/patches/update-scripts-kconfig-_shipped.patch (+0/-28)
debian/patches/version.patch (+2/-2)
debian/patches/vlock-disable-linux-console-calls-on-other-systems.patch (+0/-104)
debian/rules (+12/-17)
debian/udeb-sizes (+18/-0)
debian/watch (+2/-0)
debianutils/Config.src (+0/-1)
debianutils/Kbuild.src (+1/-1)
debianutils/mktemp.c (+2/-2)
debianutils/pipe_progress.c (+1/-1)
debianutils/run_parts.c (+1/-1)
debianutils/start_stop_daemon.c (+2/-2)
debianutils/which.c (+1/-1)
docs/.gitignore (+1/-1)
docs/busybox_footer.pod (+30/-1)
docs/busybox_header.pod (+0/-1)
docs/cgi/cl.html (+1/-1)
docs/cgi/env.html (+1/-1)
docs/cgi/in.html (+1/-1)
docs/cgi/interface.html (+1/-1)
docs/cgi/out.html (+1/-1)
docs/contributing.txt (+37/-28)
docs/ifupdown_design.txt (+14/-14)
docs/keep_data_small.txt (+1/-1)
docs/new-applet-HOWTO.txt (+17/-17)
docs/posix_conformance.txt (+0/-1)
docs/smallint.txt (+39/-0)
e2fsprogs/Kbuild.src (+1/-1)
e2fsprogs/e2fs_lib.c (+1/-1)
e2fsprogs/fsck.c (+3/-3)
e2fsprogs/old_e2fsprogs/Kbuild.src (+1/-1)
e2fsprogs/old_e2fsprogs/blkid/Kbuild.src (+1/-1)
e2fsprogs/old_e2fsprogs/e2fsck.c (+12/-24)
e2fsprogs/old_e2fsprogs/e2fsck.h (+1/-3)
e2fsprogs/old_e2fsprogs/e2p/Kbuild.src (+1/-1)
e2fsprogs/old_e2fsprogs/e2p/ostype.c (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/Kbuild.src (+1/-1)
e2fsprogs/old_e2fsprogs/ext2fs/alloc.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/alloc_tables.c (+0/-4)
e2fsprogs/old_e2fsprogs/ext2fs/bb_inode.c (+0/-6)
e2fsprogs/old_e2fsprogs/ext2fs/bitops.c (+1/-2)
e2fsprogs/old_e2fsprogs/ext2fs/block.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/bmap.c (+0/-3)
e2fsprogs/old_e2fsprogs/ext2fs/bmove.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/brel.h (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/closefs.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/cmp_bitmaps.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/dir_iterate.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/dirblock.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/dupfs.c (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/e2image.h (+0/-13)
e2fsprogs/old_e2fsprogs/ext2fs/ext2_ext_attr.h (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/ext2fsP.h (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/flushb.c (+3/-3)
e2fsprogs/old_e2fsprogs/ext2fs/freefs.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/get_pathname.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/ind_block.c (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/inline.c (+2/-3)
e2fsprogs/old_e2fsprogs/ext2fs/inode.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/inode_io.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/ismounted.c (+5/-5)
e2fsprogs/old_e2fsprogs/ext2fs/jfs_dat.h (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/lookup.c (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/mkdir.c (+0/-3)
e2fsprogs/old_e2fsprogs/ext2fs/mkjournal.c (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/namei.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/newdir.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/read_bb.c (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/read_bb_file.c (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/res_gdt.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/rs_bitmap.c (+0/-1)
e2fsprogs/old_e2fsprogs/ext2fs/rw_bitmaps.c (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/swapfs.c (+0/-2)
e2fsprogs/old_e2fsprogs/ext2fs/unlink.c (+0/-1)
e2fsprogs/old_e2fsprogs/fsck.c (+2/-10)
e2fsprogs/old_e2fsprogs/lsattr.c (+4/-4)
e2fsprogs/old_e2fsprogs/mke2fs.c (+4/-4)
e2fsprogs/old_e2fsprogs/tune2fs.c (+1/-1)
e2fsprogs/old_e2fsprogs/util.c (+1/-2)
e2fsprogs/old_e2fsprogs/uuid/Kbuild.src (+1/-1)
e2fsprogs/tune2fs.c (+37/-7)
editors/Config.src (+0/-6)
editors/Kbuild.src (+1/-2)
editors/awk.c (+241/-199)
editors/cmp.c (+6/-5)
editors/diff.c (+5/-6)
editors/ed.c (+5/-5)
editors/patch.c (+533/-295)
editors/patch_bbox.c (+306/-0)
editors/patch_toybox.c (+100/-68)
editors/sed.c (+25/-14)
editors/vi.c (+1/-1)
examples/bootfloppy/display.txt (+0/-1)
examples/bootfloppy/etc/fstab (+0/-1)
examples/bootfloppy/etc/inittab (+0/-1)
examples/bootfloppy/etc/profile (+0/-1)
examples/bootfloppy/mkrootfs.sh (+0/-1)
examples/depmod (+1/-1)
examples/depmod.pl (+3/-0)
examples/inittab (+0/-1)
examples/udhcp/sample.bound (+1/-1)
examples/udhcp/sample.renew (+1/-1)
findutils/.gitignore (+0/-3)
findutils/Kbuild.src (+1/-1)
findutils/find.c (+16/-12)
findutils/grep.c (+20/-19)
findutils/xargs.c (+1/-1)
include/applets.src.h (+16/-45)
include/ar.h (+1/-1)
include/archive.h (+238/-0)
include/busybox.h (+15/-7)
include/dump.h (+1/-1)
include/fix_u32.h (+1/-1)
include/grp_.h (+1/-1)
include/libbb.h (+116/-98)
include/liblzo_interface.h (+71/-0)
include/platform.h (+41/-30)
include/pwd_.h (+1/-1)
include/rtc_.h (+3/-3)
include/unarchive.h (+0/-236)
include/unicode.h (+1/-1)
include/usage.src.h (+91/-504)
include/xatonum.h (+1/-1)
include/xregex.h (+2/-2)
init/Config.src (+0/-127)
init/Kbuild.src (+1/-5)
init/bootchartd.c (+5/-1)
init/halt.c (+63/-1)
init/init.c (+255/-13)
init/mesg.c (+21/-3)
init/reboot.h (+0/-1)
libbb/Config.src (+13/-2)
libbb/Kbuild.src (+9/-6)
libbb/README (+0/-1)
libbb/appletlib.c (+13/-11)
libbb/ask_confirmation.c (+1/-1)
libbb/bb_askpass.c (+1/-1)
libbb/bb_basename.c (+1/-1)
libbb/bb_bswap_64.c (+16/-0)
libbb/bb_do_delay.c (+1/-1)
libbb/bb_pwd.c (+1/-1)
libbb/bb_qsort.c (+1/-1)
libbb/bb_strtod.c (+1/-1)
libbb/bb_strtonum.c (+1/-1)
libbb/chomp.c (+1/-1)
libbb/compare_string_array.c (+1/-1)
libbb/concat_path_file.c (+1/-1)
libbb/concat_subpath_file.c (+1/-1)
libbb/copy_file.c (+1/-1)
libbb/copyfd.c (+1/-1)
libbb/crc32.c (+25/-1)
libbb/create_icmp6_socket.c (+1/-1)
libbb/create_icmp_socket.c (+1/-1)
libbb/default_error_retval.c (+2/-2)
libbb/device_open.c (+1/-1)
libbb/die_if_bad_username.c (+1/-1)
libbb/dump.c (+5/-7)
libbb/execable.c (+1/-1)
libbb/fclose_nonstdin.c (+1/-1)
libbb/fflush_stdout_and_exit.c (+1/-1)
libbb/fgets_str.c (+1/-1)
libbb/find_mount_point.c (+1/-1)
libbb/find_pid_by_name.c (+1/-1)
libbb/find_root_device.c (+1/-1)
libbb/full_write.c (+2/-2)
libbb/get_console.c (+1/-1)
libbb/get_cpu_count.c (+47/-0)
libbb/get_last_path_component.c (+1/-1)
libbb/get_line_from_file.c (+1/-1)
libbb/get_volsize.c (+1/-1)
libbb/getopt32.c (+5/-5)
libbb/getpty.c (+1/-1)
libbb/hash_md5_sha.c (+898/-0)
libbb/hash_md5prime.c (+460/-0)
libbb/herror_msg.c (+1/-1)
libbb/human_readable.c (+5/-5)
libbb/inet_common.c (+5/-5)
libbb/info_msg.c (+1/-1)
libbb/inode_hash.c (+3/-3)
libbb/isdirectory.c (+2/-2)
libbb/kernel_version.c (+1/-1)
libbb/last_char_is.c (+1/-1)
libbb/lineedit.c (+463/-428)
libbb/lineedit_ptr_hack.c (+1/-1)
libbb/llist.c (+1/-1)
libbb/login.c (+2/-2)
libbb/loop.c (+1/-1)
libbb/make_directory.c (+2/-2)
libbb/makedev.c (+1/-1)
libbb/match_fstype.c (+1/-1)
libbb/md5.c (+0/-427)
libbb/md5prime.c (+0/-460)
libbb/messages.c (+1/-10)
libbb/mode_string.c (+1/-1)
libbb/mtab.c (+1/-1)
libbb/mtab_file.c (+0/-15)
libbb/obscure.c (+46/-34)
libbb/parse_config.c (+3/-15)
libbb/parse_mode.c (+6/-6)
libbb/perror_msg.c (+1/-1)
libbb/perror_nomsg.c (+1/-1)
libbb/perror_nomsg_and_die.c (+1/-1)
libbb/pidfile.c (+1/-1)
libbb/platform.c (+1/-1)
libbb/print_flags.c (+1/-1)
libbb/printable.c (+1/-1)
libbb/printable_string.c (+1/-1)
libbb/process_escape_sequence.c (+48/-32)
libbb/procps.c (+113/-55)
libbb/progress.c (+36/-25)
libbb/ptr_to_globals.c (+1/-1)
libbb/pw_encrypt.c (+1/-1)
libbb/pw_encrypt_md5.c (+16/-16)
libbb/pw_encrypt_sha.c (+28/-28)
libbb/read.c (+1/-1)
libbb/read_key.c (+1/-1)
libbb/read_printf.c (+2/-2)
libbb/recursive_action.c (+1/-1)
libbb/remove_file.c (+1/-1)
libbb/rtc.c (+1/-8)
libbb/safe_gethostname.c (+1/-1)
libbb/safe_poll.c (+1/-1)
libbb/safe_strncpy.c (+9/-4)
libbb/safe_write.c (+1/-1)
libbb/selinux_common.c (+1/-2)
libbb/sha1.c (+0/-480)
libbb/signals.c (+1/-1)
libbb/simplify_path.c (+6/-6)
libbb/single_argv.c (+1/-1)
libbb/skip_whitespace.c (+1/-1)
libbb/speed_table.c (+3/-3)
libbb/str_tolower.c (+1/-1)
libbb/strrstr.c (+1/-1)
libbb/time.c (+1/-1)
libbb/trim.c (+1/-1)
libbb/u_signal_names.c (+1/-1)
libbb/udp_io.c (+1/-1)
libbb/unicode.c (+7/-4)
libbb/update_passwd.c (+4/-4)
libbb/utmp.c (+1/-1)
libbb/uuencode.c (+76/-2)
libbb/vdprintf.c (+1/-1)
libbb/verror_msg.c (+1/-1)
libbb/vfork_daemon_rexec.c (+2/-1)
libbb/warn_ignoring_args.c (+1/-1)
libbb/wfopen.c (+1/-1)
libbb/wfopen_input.c (+10/-2)
libbb/write.c (+1/-1)
libbb/xatonum.c (+2/-2)
libbb/xatonum_template.c (+2/-2)
libbb/xconnect.c (+1/-1)
libbb/xfunc_die.c (+1/-1)
libbb/xfuncs.c (+1/-1)
libbb/xfuncs_printf.c (+20/-2)
libbb/xgetcwd.c (+2/-2)
libbb/xgethostbyname.c (+1/-1)
libbb/xreadlink.c (+1/-1)
libbb/xrealloc_vector.c (+1/-1)
libbb/xregcomp.c (+1/-1)
libpwdgrp/Kbuild.src (+1/-1)
libpwdgrp/pwd_grp.c (+8/-9)
libpwdgrp/pwd_grp_internal.c (+7/-8)
loginutils/Config.src (+47/-51)
loginutils/Kbuild.src (+1/-1)
loginutils/add-remove-shell.c (+135/-0)
loginutils/addgroup.c (+1/-2)
loginutils/adduser.c (+1/-1)
loginutils/chpasswd.c (+3/-3)
loginutils/cryptpw.c (+3/-3)
loginutils/deluser.c (+81/-34)
loginutils/getty.c (+13/-27)
loginutils/login.c (+10/-3)
loginutils/passwd.c (+1/-1)
loginutils/su.c (+2/-2)
loginutils/sulogin.c (+1/-1)
loginutils/vlock.c (+1/-1)
mailutils/Kbuild.src (+1/-1)
mailutils/mail.c (+3/-71)
mailutils/mail.h (+0/-1)
mailutils/mime.c (+3/-3)
mailutils/popmaildir.c (+4/-4)
mailutils/sendmail.c (+5/-5)
miscutils/Config.src (+18/-6)
miscutils/Kbuild.src (+1/-1)
miscutils/adjtimex.c (+1/-1)
miscutils/bbconfig.c (+22/-0)
miscutils/beep.c (+1/-1)
miscutils/chat.c (+11/-10)
miscutils/chrt.c (+1/-1)
miscutils/conspy.c (+13/-10)
miscutils/crond.c (+504/-507)
miscutils/crontab.c (+1/-1)
miscutils/dc.c (+52/-15)
miscutils/devfsd.c (+2/-2)
miscutils/devmem.c (+1/-1)
miscutils/eject.c (+1/-1)
miscutils/fbsplash.c (+2/-2)
miscutils/flash_eraseall.c (+8/-16)
miscutils/flash_lock_unlock.c (+1/-1)
miscutils/flashcp.c (+1/-1)
miscutils/hdparm.c (+6/-6)
miscutils/inotifyd.c (+1/-1)
miscutils/ionice.c (+2/-2)
miscutils/last.c (+6/-6)
miscutils/last_fancy.c (+1/-1)
miscutils/less.c (+12/-10)
miscutils/makedevs.c (+6/-6)
miscutils/man.c (+8/-3)
miscutils/microcom.c (+1/-1)
miscutils/mountpoint.c (+1/-1)
miscutils/mt.c (+3/-3)
miscutils/nandwrite.c (+241/-0)
miscutils/raidautorun.c (+1/-1)
miscutils/readahead.c (+1/-1)
miscutils/rfkill.c (+2/-2)
miscutils/runlevel.c (+8/-8)
miscutils/rx.c (+1/-1)
miscutils/strings.c (+5/-5)
miscutils/taskset.c (+1/-1)
miscutils/time.c (+1/-1)
miscutils/ttysize.c (+1/-1)
miscutils/ubi_attach_detach.c (+5/-5)
miscutils/wall.c (+1/-1)
miscutils/watchdog.c (+3/-3)
modutils/Kbuild.src (+1/-1)
modutils/depmod.c (+15/-3)
modutils/insmod.c (+6/-2)
modutils/lsmod.c (+11/-1)
modutils/modinfo.c (+1/-1)
modutils/modprobe-small.c (+70/-16)
modutils/modprobe.c (+17/-14)
modutils/modutils-24.c (+28/-2)
modutils/modutils.c (+4/-1)
modutils/modutils.h (+1/-1)
modutils/rmmod.c (+18/-3)
networking/Config.src (+21/-1)
networking/Kbuild.src (+1/-1)
networking/arping.c (+3/-5)
networking/brctl.c (+3/-3)
networking/dnsd.c (+2/-2)
networking/ether-wake.c (+3/-3)
networking/ftpd.c (+2/-2)
networking/ftpgetput.c (+1/-1)
networking/hostname.c (+1/-1)
networking/httpd.c (+80/-38)
networking/httpd_indexcgi.c (+1/-1)
networking/httpd_ssi.c (+1/-1)
networking/ifconfig.c (+2/-2)
networking/ifplugd.c (+187/-217)
networking/ifupdown.c (+72/-59)
networking/inetd.c (+7/-1)
networking/interface.c (+1/-2)
networking/ip.c (+4/-6)
networking/ipcalc.c (+4/-4)
networking/isrv.c (+1/-1)
networking/isrv.h (+1/-1)
networking/isrv_identd.c (+1/-1)
networking/libiproute/Kbuild.src (+1/-1)
networking/libiproute/ip_common.h (+14/-15)
networking/libiproute/ip_parse_common_args.c (+8/-11)
networking/libiproute/ipaddress.c (+8/-10)
networking/libiproute/iplink.c (+11/-8)
networking/libiproute/iproute.c (+10/-13)
networking/libiproute/iprule.c (+11/-14)
networking/libiproute/iptunnel.c (+7/-9)
networking/libiproute/libnetlink.c (+20/-32)
networking/libiproute/libnetlink.h (+8/-8)
networking/libiproute/ll_addr.c (+6/-8)
networking/libiproute/ll_map.c (+7/-10)
networking/libiproute/ll_proto.c (+6/-9)
networking/libiproute/ll_types.c (+6/-8)
networking/libiproute/rt_names.c (+6/-8)
networking/libiproute/rtm_map.c (+6/-9)
networking/libiproute/utils.c (+6/-8)
networking/libiproute/utils.h (+3/-3)
networking/nameif.c (+3/-3)
networking/nbd-client.c (+155/-0)
networking/nc.c (+6/-6)
networking/nc_bloaty.c (+5/-4)
networking/netstat.c (+122/-82)
networking/nslookup.c (+1/-1)
networking/ntpd.c (+42/-16)
networking/ntpd_simple.c (+2/-2)
networking/ping.c (+7/-7)
networking/pscan.c (+1/-1)
networking/route.c (+3/-3)
networking/slattach.c (+3/-3)
networking/tc.c (+3/-5)
networking/tcpudp.c (+1/-1)
networking/tcpudp_perhost.c (+1/-1)
networking/tcpudp_perhost.h (+1/-1)
networking/telnet.c (+87/-94)
networking/telnetd.c (+4/-4)
networking/tftp.c (+14/-29)
networking/traceroute.c (+0/-1)
networking/tunctl.c (+1/-1)
networking/udhcp/Config.src (+1/-1)
networking/udhcp/Kbuild.src (+1/-1)
networking/udhcp/arpping.c (+1/-1)
networking/udhcp/common.c (+10/-5)
networking/udhcp/common.h (+6/-4)
networking/udhcp/dhcpc.c (+245/-66)
networking/udhcp/dhcpc.h (+1/-1)
networking/udhcp/dhcpd.c (+9/-5)
networking/udhcp/dhcpd.h (+1/-1)
networking/udhcp/dhcprelay.c (+119/-72)
networking/udhcp/domain_codec.c (+1/-1)
networking/udhcp/dumpleases.c (+5/-16)
networking/udhcp/files.c (+3/-13)
networking/udhcp/leases.c (+1/-1)
networking/udhcp/packet.c (+5/-5)
networking/udhcp/static_leases.c (+1/-1)
networking/vconfig.c (+3/-3)
networking/wget.c (+127/-65)
networking/zcip.c (+1/-1)
printutils/Kbuild.src (+1/-1)
printutils/lpd.c (+2/-2)
printutils/lpr.c (+2/-4)
procps/Kbuild.src (+1/-1)
procps/free.c (+74/-48)
procps/fuser.c (+1/-1)
procps/iostat.c (+594/-0)
procps/kill.c (+3/-3)
procps/mpstat.c (+979/-0)
procps/nmeter.c (+7/-6)
procps/pgrep.c (+1/-1)
procps/pidof.c (+1/-1)
procps/pmap.c (+111/-0)
procps/powertop.c (+859/-0)
procps/ps.c (+1/-9)
procps/renice.c (+5/-5)
procps/smemcap.c (+5/-2)
procps/sysctl.c (+2/-2)
procps/top.c (+11/-10)
procps/uptime.c (+1/-1)
procps/watch.c (+1/-1)
runit/Kbuild.src (+5/-5)
runit/chpst.c (+3/-4)
runit/runit_lib.c (+0/-273)
runit/runit_lib.h (+0/-53)
runit/runsv.c (+5/-4)
runit/runsvdir.c (+6/-3)
runit/sv.c (+7/-4)
runit/svlogd.c (+53/-6)
scripts/Makefile.IMA (+2/-2)
scripts/Makefile.host (+0/-1)
scripts/Makefile.lib (+0/-2)
scripts/basic/docproc.c (+0/-1)
scripts/bloat-o-meter (+2/-2)
scripts/cleanup_printf2puts (+1/-1)
scripts/echo.c (+1/-1)
scripts/find_stray_empty_lines (+19/-0)
scripts/gen_build_files.sh (+48/-53)
scripts/individual (+0/-129)
scripts/kconfig/check.sh (+0/-1)
scripts/kconfig/lex.zconf.c_shipped (+0/-1)
scripts/kconfig/mconf.c (+1/-1)
scripts/kconfig/menu.c (+0/-1)
scripts/kconfig/util.c (+0/-1)
scripts/kconfig/zconf.hash.c_shipped (+0/-1)
scripts/kconfig/zconf.tab.c_shipped (+0/-2)
scripts/kconfig/zconf.y (+1/-1)
scripts/mkconfigs (+34/-9)
scripts/mkdiff_obj (+17/-10)
scripts/mkmakefile (+4/-1)
scripts/randomtest.loop (+1/-1)
scripts/showasm (+1/-2)
selinux/Config.src (+0/-1)
selinux/Kbuild.src (+1/-1)
selinux/chcon.c (+1/-1)
selinux/getenforce.c (+1/-1)
selinux/getsebool.c (+1/-1)
selinux/load_policy.c (+1/-1)
selinux/matchpathcon.c (+1/-1)
selinux/runcon.c (+1/-1)
selinux/selinuxenabled.c (+1/-1)
selinux/sestatus.c (+5/-5)
selinux/setenforce.c (+1/-1)
selinux/setfiles.c (+0/-1)
selinux/setsebool.c (+1/-1)
shell/Config.src (+0/-263)
shell/Kbuild.src (+1/-7)
shell/ash.c (+446/-339)
shell/ash_ptr_hack.c (+1/-1)
shell/ash_test/ash-arith/arith.right (+28/-28)
shell/ash_test/ash-signals/signal7.right (+1/-0)
shell/ash_test/ash-signals/signal7.tests (+18/-0)
shell/ash_test/ash-signals/signal8.right (+3/-0)
shell/ash_test/ash-signals/signal8.tests (+18/-0)
shell/ash_test/ash-signals/signal9.right (+3/-0)
shell/ash_test/ash-signals/signal9.tests (+21/-0)
shell/ash_test/ash-vars/var_bash3.right (+20/-20)
shell/ash_test/ash-vars/var_bash3.tests (+20/-20)
shell/ash_test/ash-vars/var_bash4.right (+23/-0)
shell/ash_test/ash-vars/var_bash4.tests (+47/-0)
shell/ash_test/ash-vars/var_bash5.right (+4/-0)
shell/ash_test/ash-vars/var_bash5.tests (+11/-0)
shell/ash_test/recho.c (+4/-9)
shell/ash_test/zecho.c (+1/-4)
shell/bbsh.c (+0/-223)
shell/cttyhack.c (+55/-3)
shell/hush.c (+3303/-2762)
shell/hush_test/hush-arith/arith.right (+27/-27)
shell/hush_test/hush-bugs/export_exp.tests (+0/-19)
shell/hush_test/hush-bugs/export_exp.tests.disabled (+22/-0)
shell/hush_test/hush-glob/bash_brace1.right (+4/-0)
shell/hush_test/hush-glob/bash_brace1.tests (+10/-0)
shell/hush_test/hush-glob/glob2.right (+18/-0)
shell/hush_test/hush-glob/glob2.tests (+27/-0)
shell/hush_test/hush-misc/assignment3.right (+2/-0)
shell/hush_test/hush-misc/assignment3.tests (+5/-0)
shell/hush_test/hush-misc/break1.tests (+0/-1)
shell/hush_test/hush-misc/heredoc_backslash1.right (+43/-0)
shell/hush_test/hush-misc/heredoc_backslash1.tests (+70/-0)
shell/hush_test/hush-misc/pipefail.right (+40/-0)
shell/hush_test/hush-misc/pipefail.tests (+45/-0)
shell/hush_test/hush-parsing/comment1.right (+2/-0)
shell/hush_test/hush-parsing/comment1.tests (+2/-0)
shell/hush_test/hush-parsing/eol1.right (+1/-0)
shell/hush_test/hush-parsing/eol1.tests (+18/-0)
shell/hush_test/hush-psubst/tick3.right (+1/-1)
shell/hush_test/hush-psubst/tick3.tests (+4/-2)
shell/hush_test/hush-trap/exit.right (+10/-0)
shell/hush_test/hush-trap/exit.tests (+31/-0)
shell/hush_test/hush-trap/signal7.right (+1/-0)
shell/hush_test/hush-trap/signal7.tests (+18/-0)
shell/hush_test/hush-trap/subshell.tests (+5/-6)
shell/hush_test/hush-vars/var_bash1.right (+14/-0)
shell/hush_test/hush-vars/var_bash1.tests (+18/-0)
shell/hush_test/hush-vars/var_bash2.right (+10/-0)
shell/hush_test/hush-vars/var_bash2.tests (+24/-0)
shell/hush_test/hush-vars/var_bash3.right (+20/-0)
shell/hush_test/hush-vars/var_bash3.tests (+41/-0)
shell/hush_test/hush-vars/var_bash4.right (+40/-0)
shell/hush_test/hush-vars/var_bash4.tests (+81/-0)
shell/hush_test/hush-vars/var_bash5.right (+11/-0)
shell/hush_test/hush-vars/var_bash5.tests (+29/-0)
shell/hush_test/hush-vars/var_bash6.right (+5/-0)
shell/hush_test/hush-vars/var_bash6.tests (+9/-0)
shell/hush_test/hush-vars/var_serial.right (+5/-0)
shell/hush_test/hush-vars/var_serial.tests (+22/-0)
shell/hush_test/hush-vars/var_unbackslash.right (+11/-0)
shell/hush_test/hush-vars/var_unbackslash.tests (+23/-0)
shell/match.c (+81/-71)
shell/match.h (+17/-16)
shell/math.c (+412/-362)
shell/math.h (+57/-64)
shell/random.c (+1/-1)
shell/random.h (+1/-1)
shell/shell_common.c (+8/-3)
shell/shell_common.h (+1/-1)
sysklogd/Config.src (+0/-1)
sysklogd/Kbuild.src (+1/-1)
sysklogd/klogd.c (+41/-11)
sysklogd/logger.c (+4/-4)
sysklogd/logread.c (+1/-1)
sysklogd/syslogd.c (+21/-7)
sysklogd/syslogd_and_logger.c (+1/-1)
testsuite/all_sourcecode.tests (+1/-1)
testsuite/ar.tests (+1/-1)
testsuite/ash.tests (+1/-1)
testsuite/awk.tests (+13/-1)
testsuite/basename/basename-works (+0/-1)
testsuite/bunzip2.tests (+36/-3)
testsuite/busybox.tests (+1/-1)
testsuite/bzcat.tests (+5/-0)
testsuite/cal.tests (+1/-1)
testsuite/comm.tests (+1/-1)
testsuite/cp.tests (+1/-1)
testsuite/cpio.tests (+13/-1)
testsuite/cut.tests (+1/-1)
testsuite/date/date-works-1 (+3/-0)
testsuite/diff.tests (+1/-1)
testsuite/dirname/dirname-works (+0/-1)
testsuite/du/du-h-works (+1/-1)
testsuite/du/du-k-works (+3/-1)
testsuite/du/du-l-works (+3/-0)
testsuite/expand.tests (+1/-1)
testsuite/expr/expr-works (+0/-1)
testsuite/fold.tests (+1/-1)
testsuite/grep.tests (+2/-2)
testsuite/gunzip.tests (+1/-1)
testsuite/hostname/hostname-d-works (+2/-2)
testsuite/ln/ln-preserves-soft-links (+0/-1)
testsuite/ls.tests (+1/-1)
testsuite/makedevs.tests (+10/-1)
testsuite/md5sum.tests (+43/-0)
testsuite/mdev.tests (+11/-1)
testsuite/mkfs.minix.tests (+1/-1)
testsuite/mount.testroot (+1/-1)
testsuite/mount.tests (+1/-1)
testsuite/od.tests (+1/-1)
testsuite/parse.tests (+1/-1)
testsuite/patch.tests (+63/-11)
testsuite/pidof.tests (+1/-1)
testsuite/printf.tests (+4/-4)
testsuite/readlink.tests (+2/-1)
testsuite/runtest (+8/-2)
testsuite/rx.tests (+1/-1)
testsuite/sed.tests (+18/-5)
testsuite/seq.tests (+1/-1)
testsuite/sha1sum.tests (+3/-0)
testsuite/sha256sum.tests (+3/-0)
testsuite/sha512sum.tests (+3/-0)
testsuite/sort.tests (+1/-1)
testsuite/start-stop-daemon.tests (+1/-1)
testsuite/sum.tests (+1/-1)
testsuite/tail.tests (+1/-1)
testsuite/tar.tests (+47/-11)
testsuite/taskset.tests (+1/-1)
testsuite/test.tests (+1/-1)
testsuite/testing.sh (+3/-2)
testsuite/tr.tests (+4/-4)
testsuite/unexpand.tests (+1/-1)
testsuite/uniq.tests (+1/-1)
testsuite/unzip.tests (+1/-1)
testsuite/uptime/uptime-works (+0/-1)
testsuite/uuencode.tests (+2/-3)
testsuite/xargs.tests (+1/-1)
util-linux/Config.src (+9/-14)
util-linux/Kbuild.src (+1/-1)
util-linux/acpid.c (+223/-112)
util-linux/blkid.c (+1/-1)
util-linux/blockdev.c (+1/-1)
util-linux/dmesg.c (+13/-8)
util-linux/fbset.c (+4/-4)
util-linux/fdformat.c (+2/-2)
util-linux/fdisk.c (+59/-24)
util-linux/fdisk_aix.c (+1/-1)
util-linux/fdisk_gpt.c (+195/-0)
util-linux/fdisk_osf.c (+2/-1)
util-linux/fdisk_sgi.c (+1/-1)
util-linux/fdisk_sun.c (+2/-2)
util-linux/findfs.c (+1/-1)
util-linux/flock.c (+1/-1)
util-linux/freeramdisk.c (+1/-1)
util-linux/fsck_minix.c (+1/-1)
util-linux/getopt.c (+1/-1)
util-linux/hexdump.c (+8/-8)
util-linux/hwclock.c (+1/-1)
util-linux/ipcrm.c (+7/-9)
util-linux/ipcs.c (+1/-1)
util-linux/losetup.c (+1/-1)
util-linux/lspci.c (+1/-1)
util-linux/lsusb.c (+1/-1)
util-linux/mdev.c (+4/-3)
util-linux/mkfs_ext2.c (+4/-4)
util-linux/mkfs_minix.c (+2/-3)
util-linux/mkfs_reiser.c (+3/-3)
util-linux/mkfs_vfat.c (+3/-4)
util-linux/mkswap.c (+11/-5)
util-linux/more.c (+10/-6)
util-linux/mount.c (+40/-56)
util-linux/pivot_root.c (+1/-1)
util-linux/rdate.c (+1/-1)
util-linux/rdev.c (+1/-1)
util-linux/readprofile.c (+3/-3)
util-linux/rev.c (+1/-1)
util-linux/rtcwake.c (+2/-2)
util-linux/script.c (+2/-2)
util-linux/scriptreplay.c (+1/-1)
util-linux/setarch.c (+1/-1)
util-linux/swaponoff.c (+1/-1)
util-linux/switch_root.c (+1/-1)
util-linux/umount.c (+9/-14)
util-linux/volume_id/Kbuild.src (+1/-1)
util-linux/volume_id/get_devname.c (+1/-1)
util-linux/volume_id/volume_id.c (+0/-1)
util-linux/xmount.c (+1/-1)
To merge this branch: bzr merge lp:~smoser/ubuntu/oneiric/busybox/debian-merge-1.18.4
Reviewer Review Type Date Requested Status
Ubuntu branches Pending
Review via email: mp+62702@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Clint Byrum (clint-fewbar) wrote :

Scott, this looks great!

It would appear you used merge-changelog to do the changelog. Apparently there are some entries out out of order, so merge-changelog moved a giant block of changes above version 20040623-2 that used to be below it. It also removed the erroneous, duplicate 0.52-2 entry.

I went ahead and restored the changelogs below the new entries to their original state.

Otherwise it looks good for sponsorship. Uploaded.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file '.pc/applets-fallback.patch/Config.in'
--- .pc/applets-fallback.patch/Config.in 2010-08-03 06:42:39 +0000
+++ .pc/applets-fallback.patch/Config.in 2011-05-27 16:11:32 +0000
@@ -47,6 +47,17 @@
47 compiler other than gcc.47 compiler other than gcc.
48 If you do use gcc, this option may needlessly increase code size.48 If you do use gcc, this option may needlessly increase code size.
4949
50config PLATFORM_LINUX
51 bool "Enable Linux-specific applets and features"
52 default y
53 help
54 For the most part, busybox requires only POSIX compatibility
55 from the target system, but some applets and features use
56 Linux-specific interfaces.
57
58 Answering 'N' here will disable such applets and hide the
59 corresponding configuration options.
60
50choice61choice
51 prompt "Buffer allocation policy"62 prompt "Buffer allocation policy"
52 default FEATURE_BUFFERS_USE_MALLOC63 default FEATURE_BUFFERS_USE_MALLOC
@@ -112,6 +123,14 @@
112 busybox at runtime to create hard links or symlinks for all the123 busybox at runtime to create hard links or symlinks for all the
113 applets that are compiled into busybox.124 applets that are compiled into busybox.
114125
126config INSTALL_NO_USR
127 bool "Don't use /usr"
128 default n
129 help
130 Disable use of /usr. busybox --install and "make install"
131 will install applets only to /bin and /sbin,
132 never to /usr/bin or /usr/sbin.
133
115config LOCALE_SUPPORT134config LOCALE_SUPPORT
116 bool "Enable locale support (system needs locale for this to work)"135 bool "Enable locale support (system needs locale for this to work)"
117 default n136 default n
@@ -264,15 +283,6 @@
264 Don't enable this unless you have a really good reason to clean283 Don't enable this unless you have a really good reason to clean
265 things up manually.284 things up manually.
266285
267config FEATURE_UTMP
268 bool "Support utmp file"
269 default y
270 help
271 The file /var/run/utmp is used to track who is currently logged in.
272 With this option on, certain applets (getty, login, telnetd etc)
273 will create and delete entries there.
274 "who" applet requires this option.
275
276config FEATURE_WTMP286config FEATURE_WTMP
277 bool "Support wtmp file"287 bool "Support wtmp file"
278 default y288 default y
@@ -284,6 +294,15 @@
284 will append new entries there.294 will append new entries there.
285 "last" applet requires this option.295 "last" applet requires this option.
286296
297config FEATURE_UTMP
298 bool "Support utmp file"
299 default y
300 help
301 The file /var/run/utmp is used to track who is currently logged in.
302 With this option on, certain applets (getty, login, telnetd etc)
303 will create and delete entries there.
304 "who" applet requires this option.
305
287config FEATURE_PIDFILE306config FEATURE_PIDFILE
288 bool "Support writing pidfiles"307 bool "Support writing pidfiles"
289 default y308 default y
@@ -296,14 +315,19 @@
296 default y315 default y
297 help316 help
298 With this option you can install the busybox binary belonging317 With this option you can install the busybox binary belonging
299 to root with the suid bit set, and it will automatically drop318 to root with the suid bit set, enabling some applets to perform
300 priviledges for applets that don't need root access.319 root-level operations even when run by ordinary users
320 (for example, mounting of user mounts in fstab needs this).
321
322 Busybox will automatically drop priviledges for applets
323 that don't need root access.
301324
302 If you are really paranoid and don't want to do this, build two325 If you are really paranoid and don't want to do this, build two
303 busybox binaries with different applets in them (and the appropriate326 busybox binaries with different applets in them (and the appropriate
304 symlinks pointing to each binary), and only set the suid bit on the327 symlinks pointing to each binary), and only set the suid bit on the
305 one that needs it. The applets currently marked to need the suid bit328 one that needs it.
306 are:329
330 The applets currently marked to need the suid bit are:
307331
308 crontab, dnsd, findfs, ipcrm, ipcs, login, passwd, ping, su,332 crontab, dnsd, findfs, ipcrm, ipcs, login, passwd, ping, su,
309 traceroute, vlock.333 traceroute, vlock.
@@ -353,6 +377,7 @@
353config SELINUX377config SELINUX
354 bool "Support NSA Security Enhanced Linux"378 bool "Support NSA Security Enhanced Linux"
355 default n379 default n
380 depends on PLATFORM_LINUX
356 help381 help
357 Enable support for SELinux in applets ls, ps, and id. Also provide382 Enable support for SELinux in applets ls, ps, and id. Also provide
358 the option of compiling in SELinux applets.383 the option of compiling in SELinux applets.
@@ -639,20 +664,13 @@
639664
640endmenu665endmenu
641666
642menu 'Installation Options'667menu 'Installation Options ("make install" behavior)'
643
644config INSTALL_NO_USR
645 bool "Don't use /usr"
646 default n
647 help
648 Disable use of /usr. Don't activate this option if you don't know
649 that you really want this behaviour.
650668
651choice669choice
652 prompt "Applets links"670 prompt "What kind of applet links to install"
653 default INSTALL_APPLET_SYMLINKS671 default INSTALL_APPLET_SYMLINKS
654 help672 help
655 Choose how you install applets links.673 Choose what kind of links to applets are created by "make install".
656674
657config INSTALL_APPLET_SYMLINKS675config INSTALL_APPLET_SYMLINKS
658 bool "as soft-links"676 bool "as soft-links"
@@ -676,8 +694,9 @@
676 bool "not installed"694 bool "not installed"
677 depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE || FEATURE_PREFER_APPLETS695 depends on FEATURE_INSTALLER || FEATURE_SH_STANDALONE || FEATURE_PREFER_APPLETS
678 help696 help
679 Do not install applet links. Useful when using the -install feature697 Do not install applet links. Useful when you plan to use
680 or a standalone shell for rescue purposes.698 busybox --install for installing links, or plan to use
699 a standalone shell and thus don't need applet links.
681700
682endchoice701endchoice
683702
@@ -701,8 +720,8 @@
701config INSTALL_SH_APPLET_SCRIPT_WRAPPER720config INSTALL_SH_APPLET_SCRIPT_WRAPPER
702 bool "as script wrapper"721 bool "as script wrapper"
703 help722 help
704 Install /bin/sh applet as script wrapper that call the busybox723 Install /bin/sh applet as script wrapper that calls
705 binary.724 the busybox binary.
706725
707endchoice726endchoice
708727
709728
=== modified file '.pc/applets-fallback.patch/coreutils/chroot.c'
--- .pc/applets-fallback.patch/coreutils/chroot.c 2010-10-22 11:37:59 +0000
+++ .pc/applets-fallback.patch/coreutils/chroot.c 2011-05-27 16:11:32 +0000
@@ -4,7 +4,7 @@
4 *4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 */8 */
99
10/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */10/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */
1111
=== modified file '.pc/applets-fallback.patch/include/libbb.h'
--- .pc/applets-fallback.patch/include/libbb.h 2010-08-03 06:42:39 +0000
+++ .pc/applets-fallback.patch/include/libbb.h 2011-05-27 16:11:32 +0000
@@ -3,9 +3,9 @@
3 * Busybox main internal header file3 * Busybox main internal header file
4 *4 *
5 * Based in part on code from sash, Copyright (c) 1999 by David I. Bell5 * Based in part on code from sash, Copyright (c) 1999 by David I. Bell
6 * Permission has been granted to redistribute this code under the GPL.6 * Permission has been granted to redistribute this code under GPL.
7 *7 *
8 * Licensed under the GPL version 2, see the file LICENSE in this tarball.8 * Licensed under GPLv2, see file LICENSE in this source tree.
9 */9 */
10#ifndef LIBBB_H10#ifndef LIBBB_H
11#define LIBBB_H 111#define LIBBB_H 1
@@ -37,20 +37,18 @@
37#include <termios.h>37#include <termios.h>
38#include <time.h>38#include <time.h>
39#include <unistd.h>39#include <unistd.h>
40/* Try to pull in PATH_MAX */
41#include <limits.h>
42#include <sys/param.h>40#include <sys/param.h>
43#ifdef HAVE_MNTENT_H41#ifdef HAVE_MNTENT_H
44#include <mntent.h>42# include <mntent.h>
45#endif43#endif
46#ifdef HAVE_SYS_STATFS_H44#ifdef HAVE_SYS_STATFS_H
47#include <sys/statfs.h>45# include <sys/statfs.h>
48#endif46#endif
49#if ENABLE_SELINUX47#if ENABLE_SELINUX
50#include <selinux/selinux.h>48# include <selinux/selinux.h>
51#include <selinux/context.h>49# include <selinux/context.h>
52#include <selinux/flask.h>50# include <selinux/flask.h>
53#include <selinux/av_permissions.h>51# include <selinux/av_permissions.h>
54#endif52#endif
55#if ENABLE_LOCALE_SUPPORT53#if ENABLE_LOCALE_SUPPORT
56# include <locale.h>54# include <locale.h>
@@ -70,7 +68,7 @@
70# include <shadow.h>68# include <shadow.h>
71# endif69# endif
72#endif70#endif
73#if defined __FreeBSD__71#if defined __FreeBSD__ || defined __OpenBSD__
74# include <netinet/in.h>72# include <netinet/in.h>
75# include <arpa/inet.h>73# include <arpa/inet.h>
76#elif defined __APPLE__74#elif defined __APPLE__
@@ -190,7 +188,7 @@
190/* While sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway.188/* While sizeof(off_t) == sizeof(int), off_t is typedef'ed to long anyway.
191 * gcc will throw warnings on printf("%d", off_t). Crap... */189 * gcc will throw warnings on printf("%d", off_t). Crap... */
192typedef unsigned long uoff_t;190typedef unsigned long uoff_t;
193# define XATOOFF(a) xatoi_u(a)191# define XATOOFF(a) xatoi_positive(a)
194# define BB_STRTOOFF bb_strtou192# define BB_STRTOOFF bb_strtou
195# define STRTOOFF strtol193# define STRTOOFF strtol
196# define OFF_FMT "l"194# define OFF_FMT "l"
@@ -222,11 +220,11 @@
222220
223/* Macros for min/max. */221/* Macros for min/max. */
224#ifndef MIN222#ifndef MIN
225#define MIN(a,b) (((a)<(b))?(a):(b))223#define MIN(a,b) (((a)<(b))?(a):(b))
226#endif224#endif
227225
228#ifndef MAX226#ifndef MAX
229#define MAX(a,b) (((a)>(b))?(a):(b))227#define MAX(a,b) (((a)>(b))?(a):(b))
230#endif228#endif
231229
232/* buffer allocation schemes */230/* buffer allocation schemes */
@@ -254,6 +252,11 @@
254#define errno (*bb_errno)252#define errno (*bb_errno)
255#endif253#endif
256254
255#if !(ULONG_MAX > 0xffffffff)
256/* Only 32-bit CPUs need this, 64-bit ones use inlined version */
257uint64_t bb_bswap_64(uint64_t x) FAST_FUNC;
258#endif
259
257unsigned long long monotonic_ns(void) FAST_FUNC;260unsigned long long monotonic_ns(void) FAST_FUNC;
258unsigned long long monotonic_us(void) FAST_FUNC;261unsigned long long monotonic_us(void) FAST_FUNC;
259unsigned long long monotonic_ms(void) FAST_FUNC;262unsigned long long monotonic_ms(void) FAST_FUNC;
@@ -321,6 +324,7 @@
321/* this helper yells "short read!" if param is not -1 */324/* this helper yells "short read!" if param is not -1 */
322extern void complain_copyfd_and_die(off_t sz) NORETURN FAST_FUNC;325extern void complain_copyfd_and_die(off_t sz) NORETURN FAST_FUNC;
323extern char bb_process_escape_sequence(const char **ptr) FAST_FUNC;326extern char bb_process_escape_sequence(const char **ptr) FAST_FUNC;
327char* strcpy_and_process_escape_sequences(char *dst, const char *src) FAST_FUNC;
324/* xxxx_strip version can modify its parameter:328/* xxxx_strip version can modify its parameter:
325 * "/" -> "/"329 * "/" -> "/"
326 * "abc" -> "abc"330 * "abc" -> "abc"
@@ -411,15 +415,18 @@
411void bb_unsetenv_and_free(char *key) FAST_FUNC;415void bb_unsetenv_and_free(char *key) FAST_FUNC;
412void xunlink(const char *pathname) FAST_FUNC;416void xunlink(const char *pathname) FAST_FUNC;
413void xstat(const char *pathname, struct stat *buf) FAST_FUNC;417void xstat(const char *pathname, struct stat *buf) FAST_FUNC;
418void xfstat(int fd, struct stat *buf, const char *errmsg) FAST_FUNC;
414int xopen(const char *pathname, int flags) FAST_FUNC;419int xopen(const char *pathname, int flags) FAST_FUNC;
415int xopen_nonblocking(const char *pathname) FAST_FUNC;420int xopen_nonblocking(const char *pathname) FAST_FUNC;
416int xopen3(const char *pathname, int flags, int mode) FAST_FUNC;421int xopen3(const char *pathname, int flags, int mode) FAST_FUNC;
417int open_or_warn(const char *pathname, int flags) FAST_FUNC;422int open_or_warn(const char *pathname, int flags) FAST_FUNC;
418int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC;423int open3_or_warn(const char *pathname, int flags, int mode) FAST_FUNC;
419int open_or_warn_stdin(const char *pathname) FAST_FUNC;424int open_or_warn_stdin(const char *pathname) FAST_FUNC;
425int xopen_stdin(const char *pathname) FAST_FUNC;
420void xrename(const char *oldpath, const char *newpath) FAST_FUNC;426void xrename(const char *oldpath, const char *newpath) FAST_FUNC;
421int rename_or_warn(const char *oldpath, const char *newpath) FAST_FUNC;427int rename_or_warn(const char *oldpath, const char *newpath) FAST_FUNC;
422off_t xlseek(int fd, off_t offset, int whence) FAST_FUNC;428off_t xlseek(int fd, off_t offset, int whence) FAST_FUNC;
429int xmkstemp(char *template) FAST_FUNC;
423off_t fdlength(int fd) FAST_FUNC;430off_t fdlength(int fd) FAST_FUNC;
424431
425uoff_t FAST_FUNC get_volume_size_in_bytes(int fd,432uoff_t FAST_FUNC get_volume_size_in_bytes(int fd,
@@ -739,7 +746,7 @@
739char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) FAST_FUNC;746char *utoa_to_buf(unsigned n, char *buf, unsigned buflen) FAST_FUNC;
740char *itoa_to_buf(int n, char *buf, unsigned buflen) FAST_FUNC;747char *itoa_to_buf(int n, char *buf, unsigned buflen) FAST_FUNC;
741/* Intelligent formatters of bignums */748/* Intelligent formatters of bignums */
742void smart_ulltoa4(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;749void smart_ulltoa4(unsigned long long ul, char buf[4], const char *scale) FAST_FUNC;
743void smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;750void smart_ulltoa5(unsigned long long ul, char buf[5], const char *scale) FAST_FUNC;
744/* If block_size == 0, display size without fractional part,751/* If block_size == 0, display size without fractional part,
745 * else display (size * block_size) with one decimal digit.752 * else display (size * block_size) with one decimal digit.
@@ -765,11 +772,16 @@
765};772};
766#include "xatonum.h"773#include "xatonum.h"
767/* Specialized: */774/* Specialized: */
775
768/* Using xatoi() instead of naive atoi() is not always convenient -776/* Using xatoi() instead of naive atoi() is not always convenient -
769 * in many places people want *non-negative* values, but store them777 * in many places people want *non-negative* values, but store them
770 * in signed int. Therefore we need this one:778 * in signed int. Therefore we need this one:
771 * dies if input is not in [0, INT_MAX] range. Also will reject '-0' etc */779 * dies if input is not in [0, INT_MAX] range. Also will reject '-0' etc.
772int xatoi_u(const char *numstr) FAST_FUNC;780 * It should really be named xatoi_nonnegative (since it allows 0),
781 * but that would be too long.
782 */
783int xatoi_positive(const char *numstr) FAST_FUNC;
784
773/* Useful for reading port numbers */785/* Useful for reading port numbers */
774uint16_t xatou16(const char *numstr) FAST_FUNC;786uint16_t xatou16(const char *numstr) FAST_FUNC;
775787
@@ -874,9 +886,9 @@
874struct nofork_save_area {886struct nofork_save_area {
875 jmp_buf die_jmp;887 jmp_buf die_jmp;
876 const char *applet_name;888 const char *applet_name;
877 int xfunc_error_retval;
878 uint32_t option_mask32;889 uint32_t option_mask32;
879 int die_sleep;890 int die_sleep;
891 uint8_t xfunc_error_retval;
880 smallint saved;892 smallint saved;
881};893};
882void save_nofork_data(struct nofork_save_area *save) FAST_FUNC;894void save_nofork_data(struct nofork_save_area *save) FAST_FUNC;
@@ -987,7 +999,7 @@
987extern const char *msg_eol;999extern const char *msg_eol;
988extern smallint logmode;1000extern smallint logmode;
989extern int die_sleep;1001extern int die_sleep;
990extern int xfunc_error_retval;1002extern uint8_t xfunc_error_retval;
991extern jmp_buf die_jmp;1003extern jmp_buf die_jmp;
992extern void xfunc_die(void) NORETURN FAST_FUNC;1004extern void xfunc_die(void) NORETURN FAST_FUNC;
993extern void bb_show_usage(void) NORETURN FAST_FUNC;1005extern void bb_show_usage(void) NORETURN FAST_FUNC;
@@ -1381,6 +1393,29 @@
1381enum { COMM_LEN = 16 };1393enum { COMM_LEN = 16 };
1382# endif1394# endif
1383#endif1395#endif
1396
1397struct smaprec {
1398 unsigned long mapped_rw;
1399 unsigned long mapped_ro;
1400 unsigned long shared_clean;
1401 unsigned long shared_dirty;
1402 unsigned long private_clean;
1403 unsigned long private_dirty;
1404 unsigned long stack;
1405 unsigned long smap_pss, smap_swap;
1406 unsigned long smap_size;
1407 unsigned long smap_start;
1408 char smap_mode[5];
1409 char *smap_name;
1410};
1411
1412#if !ENABLE_PMAP
1413#define procps_read_smaps(pid, total, cb, data) \
1414 procps_read_smaps(pid, total)
1415#endif
1416int FAST_FUNC procps_read_smaps(pid_t pid, struct smaprec *total,
1417 void (*cb)(struct smaprec *, void *), void *data);
1418
1384typedef struct procps_status_t {1419typedef struct procps_status_t {
1385 DIR *dir;1420 DIR *dir;
1386 IF_FEATURE_SHOW_THREADS(DIR *task_dir;)1421 IF_FEATURE_SHOW_THREADS(DIR *task_dir;)
@@ -1409,13 +1444,7 @@
1409#endif1444#endif
1410 unsigned tty_major,tty_minor;1445 unsigned tty_major,tty_minor;
1411#if ENABLE_FEATURE_TOPMEM1446#if ENABLE_FEATURE_TOPMEM
1412 unsigned long mapped_rw;1447 struct smaprec smaps;
1413 unsigned long mapped_ro;
1414 unsigned long shared_clean;
1415 unsigned long shared_dirty;
1416 unsigned long private_clean;
1417 unsigned long private_dirty;
1418 unsigned long stack;
1419#endif1448#endif
1420 char state[4];1449 char state[4];
1421 /* basename of executable in exec(2), read from /proc/N/stat1450 /* basename of executable in exec(2), read from /proc/N/stat
@@ -1474,57 +1503,50 @@
1474void read_cmdline(char *buf, int size, unsigned pid, const char *comm) FAST_FUNC;1503void read_cmdline(char *buf, int size, unsigned pid, const char *comm) FAST_FUNC;
1475pid_t *find_pid_by_name(const char* procName) FAST_FUNC;1504pid_t *find_pid_by_name(const char* procName) FAST_FUNC;
1476pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC;1505pid_t *pidlist_reverse(pid_t *pidList) FAST_FUNC;
1506int starts_with_cpu(const char *str) FAST_FUNC;
1507unsigned get_cpu_count(void) FAST_FUNC;
14771508
14781509
1479extern const char bb_uuenc_tbl_base64[];1510extern const char bb_uuenc_tbl_base64[];
1480extern const char bb_uuenc_tbl_std[];1511extern const char bb_uuenc_tbl_std[];
1481void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;1512void bb_uuencode(char *store, const void *s, int length, const char *tbl) FAST_FUNC;
1513enum {
1514 BASE64_FLAG_UU_STOP = 0x100,
1515 /* Sign-extends to a value which never matches fgetc result: */
1516 BASE64_FLAG_NO_STOP_CHAR = 0x80,
1517};
1518void FAST_FUNC read_base64(FILE *src_stream, FILE *dst_stream, int flags);
14821519
1483typedef struct sha1_ctx_t {1520typedef struct md5_ctx_t {
1484 uint32_t hash[8]; /* 5, +3 elements for sha256 */1521 uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */
1485 uint64_t total64;1522 void (*process_block)(struct md5_ctx_t*) FAST_FUNC;
1486 uint8_t wbuffer[64]; /* NB: always correctly aligned for uint64_t */1523 uint64_t total64; /* must be directly before hash[] */
1487 void (*process_block)(struct sha1_ctx_t*) FAST_FUNC;1524 uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */
1488} sha1_ctx_t;1525} md5_ctx_t;
1489void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;1526typedef struct md5_ctx_t sha1_ctx_t;
1490void sha1_hash(const void *data, size_t length, sha1_ctx_t *ctx) FAST_FUNC;1527typedef struct md5_ctx_t sha256_ctx_t;
1491void sha1_end(void *resbuf, sha1_ctx_t *ctx) FAST_FUNC;
1492typedef struct sha1_ctx_t sha256_ctx_t;
1493void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
1494#define sha256_hash sha1_hash
1495#define sha256_end sha1_end
1496typedef struct sha512_ctx_t {1528typedef struct sha512_ctx_t {
1529 uint64_t total64[2]; /* must be directly before hash[] */
1497 uint64_t hash[8];1530 uint64_t hash[8];
1498 uint64_t total64[2];1531 uint8_t wbuffer[128]; /* always correctly aligned for uint64_t */
1499 uint8_t wbuffer[128]; /* NB: always correctly aligned for uint64_t */
1500} sha512_ctx_t;1532} sha512_ctx_t;
1533void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
1534void md5_hash(md5_ctx_t *ctx, const void *data, size_t length) FAST_FUNC;
1535void md5_end(md5_ctx_t *ctx, void *resbuf) FAST_FUNC;
1536void sha1_begin(sha1_ctx_t *ctx) FAST_FUNC;
1537#define sha1_hash md5_hash
1538void sha1_end(sha1_ctx_t *ctx, void *resbuf) FAST_FUNC;
1539void sha256_begin(sha256_ctx_t *ctx) FAST_FUNC;
1540#define sha256_hash md5_hash
1541#define sha256_end sha1_end
1501void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;1542void sha512_begin(sha512_ctx_t *ctx) FAST_FUNC;
1502void sha512_hash(const void *buffer, size_t len, sha512_ctx_t *ctx) FAST_FUNC;1543void sha512_hash(sha512_ctx_t *ctx, const void *buffer, size_t len) FAST_FUNC;
1503void sha512_end(void *resbuf, sha512_ctx_t *ctx) FAST_FUNC;1544void sha512_end(sha512_ctx_t *ctx, void *resbuf) FAST_FUNC;
1504#if 11545
1505typedef struct md5_ctx_t {1546extern uint32_t *global_crc32_table;
1506 uint32_t A;
1507 uint32_t B;
1508 uint32_t C;
1509 uint32_t D;
1510 uint64_t total;
1511 uint32_t buflen;
1512 char buffer[128];
1513} md5_ctx_t;
1514#else
1515/* libbb/md5prime.c uses a bit different one: */
1516typedef struct md5_ctx_t {
1517 uint32_t state[4]; /* state (ABCD) */
1518 uint32_t count[2]; /* number of bits, modulo 2^64 (lsb first) */
1519 unsigned char buffer[64]; /* input buffer */
1520} md5_ctx_t;
1521#endif
1522void md5_begin(md5_ctx_t *ctx) FAST_FUNC;
1523void md5_hash(const void *data, size_t length, md5_ctx_t *ctx) FAST_FUNC;
1524void md5_end(void *resbuf, md5_ctx_t *ctx) FAST_FUNC;
1525
1526
1527uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;1547uint32_t *crc32_filltable(uint32_t *tbl256, int endian) FAST_FUNC;
1548uint32_t crc32_block_endian1(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
1549uint32_t crc32_block_endian0(uint32_t val, const void *buf, unsigned len, uint32_t *crc_table) FAST_FUNC;
15281550
1529typedef struct masks_labels_t {1551typedef struct masks_labels_t {
1530 const char *labels;1552 const char *labels;
@@ -1547,12 +1569,22 @@
1547 off_t totalsize) FAST_FUNC;1569 off_t totalsize) FAST_FUNC;
15481570
1549extern const char *applet_name;1571extern const char *applet_name;
1572
1573/* Some older linkers don't perform string merging, we used to have common strings
1574 * as global arrays to do it by hand. But:
1575 * (1) newer linkers do it themselves,
1576 * (2) however, they DONT merge string constants with global arrays,
1577 * even if the value is the same (!). Thus global arrays actually
1578 * increased size a bit: for example, "/etc/passwd" string from libc
1579 * wasn't merged with bb_path_passwd_file[] array!
1580 * Therefore now we use #defines.
1581 */
1550/* "BusyBox vN.N.N (timestamp or extra_version)" */1582/* "BusyBox vN.N.N (timestamp or extra_version)" */
1551extern const char bb_banner[];1583extern const char bb_banner[];
1552extern const char bb_msg_memory_exhausted[];1584extern const char bb_msg_memory_exhausted[];
1553extern const char bb_msg_invalid_date[];1585extern const char bb_msg_invalid_date[];
1554extern const char bb_msg_read_error[];1586#define bb_msg_read_error "read error"
1555extern const char bb_msg_write_error[];1587#define bb_msg_write_error "write error"
1556extern const char bb_msg_unknown[];1588extern const char bb_msg_unknown[];
1557extern const char bb_msg_can_not_create_raw_socket[];1589extern const char bb_msg_can_not_create_raw_socket[];
1558extern const char bb_msg_perm_denied_are_you_root[];1590extern const char bb_msg_perm_denied_are_you_root[];
@@ -1562,18 +1594,23 @@
1562extern const char bb_msg_standard_input[];1594extern const char bb_msg_standard_input[];
1563extern const char bb_msg_standard_output[];1595extern const char bb_msg_standard_output[];
15641596
1565extern const char bb_str_default[];
1566/* NB: (bb_hexdigits_upcase[i] | 0x20) -> lowercase hex digit */1597/* NB: (bb_hexdigits_upcase[i] | 0x20) -> lowercase hex digit */
1567extern const char bb_hexdigits_upcase[];1598extern const char bb_hexdigits_upcase[];
15681599
1569extern const char bb_path_mtab_file[];
1570extern const char bb_path_passwd_file[];
1571extern const char bb_path_shadow_file[];
1572extern const char bb_path_gshadow_file[];
1573extern const char bb_path_group_file[];
1574extern const char bb_path_motd_file[];
1575extern const char bb_path_wtmp_file[];1600extern const char bb_path_wtmp_file[];
1576extern const char bb_dev_null[];1601
1602/* Busybox mount uses either /proc/mounts or /etc/mtab to
1603 * get the list of currently mounted filesystems */
1604#define bb_path_mtab_file IF_FEATURE_MTAB_SUPPORT("/etc/mtab")IF_NOT_FEATURE_MTAB_SUPPORT("/proc/mounts")
1605
1606#define bb_path_passwd_file "/etc/passwd"
1607#define bb_path_shadow_file "/etc/shadow"
1608#define bb_path_gshadow_file "/etc/gshadow"
1609#define bb_path_group_file "/etc/group"
1610
1611#define bb_path_motd_file "/etc/motd"
1612
1613#define bb_dev_null "/dev/null"
1577extern const char bb_busybox_exec_path[];1614extern const char bb_busybox_exec_path[];
1578/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,1615/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
1579 * but I want to save a few bytes here */1616 * but I want to save a few bytes here */
@@ -1613,46 +1650,47 @@
1613/* "sh" */1650/* "sh" */
1614#define DEFAULT_SHELL_SHORT_NAME (bb_default_login_shell+6)1651#define DEFAULT_SHELL_SHORT_NAME (bb_default_login_shell+6)
16151652
1616#if ENABLE_FEATURE_DEVFS1653/* The following devices are the same on all systems. */
1654#define CURRENT_TTY "/dev/tty"
1655#define DEV_CONSOLE "/dev/console"
1656
1657#if defined(__FreeBSD_kernel__)
1658# define CURRENT_VC CURRENT_TTY
1659# define VC_1 "/dev/ttyv0"
1660# define VC_2 "/dev/ttyv1"
1661# define VC_3 "/dev/ttyv2"
1662# define VC_4 "/dev/ttyv3"
1663# define VC_5 "/dev/ttyv4"
1664# define VC_FORMAT "/dev/ttyv%d"
1665#elif defined(__GNU__)
1666# define CURRENT_VC CURRENT_TTY
1667# define VC_1 "/dev/tty1"
1668# define VC_2 "/dev/tty2"
1669# define VC_3 "/dev/tty3"
1670# define VC_4 "/dev/tty4"
1671# define VC_5 "/dev/tty5"
1672# define VC_FORMAT "/dev/tty%d"
1673#elif ENABLE_FEATURE_DEVFS
1674/*Linux, obsolete devfs names */
1617# define CURRENT_VC "/dev/vc/0"1675# define CURRENT_VC "/dev/vc/0"
1618# define VC_1 "/dev/vc/1"1676# define VC_1 "/dev/vc/1"
1619# define VC_2 "/dev/vc/2"1677# define VC_2 "/dev/vc/2"
1620# define VC_3 "/dev/vc/3"1678# define VC_3 "/dev/vc/3"
1621# define VC_4 "/dev/vc/4"1679# define VC_4 "/dev/vc/4"
1622# define VC_5 "/dev/vc/5"1680# define VC_5 "/dev/vc/5"
1623# if defined(__sh__) || defined(__H8300H__) || defined(__H8300S__)
1624/* Yes, this sucks, but both SH (including sh64) and H8 have a SCI(F) for their
1625 respective serial ports .. as such, we can't use the common device paths for
1626 these. -- PFM */
1627# define SC_0 "/dev/ttsc/0"
1628# define SC_1 "/dev/ttsc/1"
1629# define SC_FORMAT "/dev/ttsc/%d"
1630# else
1631# define SC_0 "/dev/tts/0"
1632# define SC_1 "/dev/tts/1"
1633# define SC_FORMAT "/dev/tts/%d"
1634# endif
1635# define VC_FORMAT "/dev/vc/%d"1681# define VC_FORMAT "/dev/vc/%d"
1636# define LOOP_FORMAT "/dev/loop/%d"1682# define LOOP_FORMAT "/dev/loop/%d"
1637# define LOOP_NAMESIZE (sizeof("/dev/loop/") + sizeof(int)*3 + 1)1683# define LOOP_NAMESIZE (sizeof("/dev/loop/") + sizeof(int)*3 + 1)
1638# define LOOP_NAME "/dev/loop/"1684# define LOOP_NAME "/dev/loop/"
1639# define FB_0 "/dev/fb/0"1685# define FB_0 "/dev/fb/0"
1640#else1686#else
1687/*Linux, normal names */
1641# define CURRENT_VC "/dev/tty0"1688# define CURRENT_VC "/dev/tty0"
1642# define VC_1 "/dev/tty1"1689# define VC_1 "/dev/tty1"
1643# define VC_2 "/dev/tty2"1690# define VC_2 "/dev/tty2"
1644# define VC_3 "/dev/tty3"1691# define VC_3 "/dev/tty3"
1645# define VC_4 "/dev/tty4"1692# define VC_4 "/dev/tty4"
1646# define VC_5 "/dev/tty5"1693# define VC_5 "/dev/tty5"
1647# if defined(__sh__) || defined(__H8300H__) || defined(__H8300S__)
1648# define SC_0 "/dev/ttySC0"
1649# define SC_1 "/dev/ttySC1"
1650# define SC_FORMAT "/dev/ttySC%d"
1651# else
1652# define SC_0 "/dev/ttyS0"
1653# define SC_1 "/dev/ttyS1"
1654# define SC_FORMAT "/dev/ttyS%d"
1655# endif
1656# define VC_FORMAT "/dev/tty%d"1694# define VC_FORMAT "/dev/tty%d"
1657# define LOOP_FORMAT "/dev/loop%d"1695# define LOOP_FORMAT "/dev/loop%d"
1658# define LOOP_NAMESIZE (sizeof("/dev/loop") + sizeof(int)*3 + 1)1696# define LOOP_NAMESIZE (sizeof("/dev/loop") + sizeof(int)*3 + 1)
@@ -1660,10 +1698,6 @@
1660# define FB_0 "/dev/fb0"1698# define FB_0 "/dev/fb0"
1661#endif1699#endif
16621700
1663/* The following devices are the same on devfs and non-devfs systems. */
1664#define CURRENT_TTY "/dev/tty"
1665#define DEV_CONSOLE "/dev/console"
1666
16671701
1668#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))1702#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
16691703
16701704
=== modified file '.pc/applets-fallback.patch/libbb/execable.c'
--- .pc/applets-fallback.patch/libbb/execable.c 2010-08-03 06:42:39 +0000
+++ .pc/applets-fallback.patch/libbb/execable.c 2011-05-27 16:11:32 +0000
@@ -4,7 +4,7 @@
4 *4 *
5 * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu>5 * Copyright (C) 2006 Gabriel Somlo <somlo at cmu.edu>
6 *6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 */8 */
99
10#include "libbb.h"10#include "libbb.h"
1111
=== modified file '.pc/applets-fallback.patch/libbb/messages.c'
--- .pc/applets-fallback.patch/libbb/messages.c 2010-08-03 06:42:39 +0000
+++ .pc/applets-fallback.patch/libbb/messages.c 2011-05-27 16:11:32 +0000
@@ -2,7 +2,7 @@
2/*2/*
3 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>3 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
4 *4 *
5 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.5 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
6 */6 */
77
8#include "libbb.h"8#include "libbb.h"
@@ -24,8 +24,6 @@
2424
25const char bb_msg_memory_exhausted[] ALIGN1 = "memory exhausted";25const char bb_msg_memory_exhausted[] ALIGN1 = "memory exhausted";
26const char bb_msg_invalid_date[] ALIGN1 = "invalid date '%s'";26const char bb_msg_invalid_date[] ALIGN1 = "invalid date '%s'";
27const char bb_msg_write_error[] ALIGN1 = "write error";
28const char bb_msg_read_error[] ALIGN1 = "read error";
29const char bb_msg_unknown[] ALIGN1 = "(unknown)";27const char bb_msg_unknown[] ALIGN1 = "(unknown)";
30const char bb_msg_can_not_create_raw_socket[] ALIGN1 = "can't create raw socket";28const char bb_msg_can_not_create_raw_socket[] ALIGN1 = "can't create raw socket";
31const char bb_msg_perm_denied_are_you_root[] ALIGN1 = "permission denied (are you root?)";29const char bb_msg_perm_denied_are_you_root[] ALIGN1 = "permission denied (are you root?)";
@@ -35,15 +33,8 @@
35const char bb_msg_standard_input[] ALIGN1 = "standard input";33const char bb_msg_standard_input[] ALIGN1 = "standard input";
36const char bb_msg_standard_output[] ALIGN1 = "standard output";34const char bb_msg_standard_output[] ALIGN1 = "standard output";
3735
38const char bb_str_default[] ALIGN1 = "default";
39const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF";36const char bb_hexdigits_upcase[] ALIGN1 = "0123456789ABCDEF";
4037
41const char bb_path_passwd_file[] ALIGN1 = "/etc/passwd";
42const char bb_path_shadow_file[] ALIGN1 = "/etc/shadow";
43const char bb_path_group_file[] ALIGN1 = "/etc/group";
44const char bb_path_gshadow_file[] ALIGN1 = "/etc/gshadow";
45const char bb_path_motd_file[] ALIGN1 = "/etc/motd";
46const char bb_dev_null[] ALIGN1 = "/dev/null";
47const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;38const char bb_busybox_exec_path[] ALIGN1 = CONFIG_BUSYBOX_EXEC_PATH;
48const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;39const char bb_default_login_shell[] ALIGN1 = LIBBB_DEFAULT_LOGIN_SHELL;
49/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,40/* util-linux manpage says /sbin:/bin:/usr/sbin:/usr/bin,
5041
=== modified file '.pc/applets-fallback.patch/shell/ash.c'
--- .pc/applets-fallback.patch/shell/ash.c 2010-08-03 06:42:39 +0000
+++ .pc/applets-fallback.patch/shell/ash.c 2011-05-27 16:11:32 +0000
@@ -13,7 +13,7 @@
13 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>13 * Copyright (c) 1997-2005 Herbert Xu <herbert@gondor.apana.org.au>
14 * was re-ported from NetBSD and debianized.14 * was re-ported from NetBSD and debianized.
15 *15 *
16 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.16 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
17 */17 */
1818
19/*19/*
@@ -43,7 +43,9 @@
43#include <sys/times.h>43#include <sys/times.h>
4444
45#include "shell_common.h"45#include "shell_common.h"
46#include "math.h"46#if ENABLE_SH_MATH_SUPPORT
47# include "math.h"
48#endif
47#if ENABLE_ASH_RANDOM_SUPPORT49#if ENABLE_ASH_RANDOM_SUPPORT
48# include "random.h"50# include "random.h"
49#else51#else
@@ -70,6 +72,124 @@
70# error "Do not even bother, ash will not run on NOMMU machine"72# error "Do not even bother, ash will not run on NOMMU machine"
71#endif73#endif
7274
75//applet:IF_ASH(APPLET(ash, _BB_DIR_BIN, _BB_SUID_DROP))
76//applet:IF_FEATURE_SH_IS_ASH(APPLET_ODDNAME(sh, ash, _BB_DIR_BIN, _BB_SUID_DROP, sh))
77//applet:IF_FEATURE_BASH_IS_ASH(APPLET_ODDNAME(bash, ash, _BB_DIR_BIN, _BB_SUID_DROP, bash))
78
79//kbuild:lib-$(CONFIG_ASH) += ash.o ash_ptr_hack.o shell_common.o
80//kbuild:lib-$(CONFIG_ASH_RANDOM_SUPPORT) += random.o
81
82//config:config ASH
83//config: bool "ash"
84//config: default y
85//config: depends on !NOMMU
86//config: help
87//config: Tha 'ash' shell adds about 60k in the default configuration and is
88//config: the most complete and most pedantically correct shell included with
89//config: busybox. This shell is actually a derivative of the Debian 'dash'
90//config: shell (by Herbert Xu), which was created by porting the 'ash' shell
91//config: (written by Kenneth Almquist) from NetBSD.
92//config:
93//config:config ASH_BASH_COMPAT
94//config: bool "bash-compatible extensions"
95//config: default y
96//config: depends on ASH
97//config: help
98//config: Enable bash-compatible extensions.
99//config:
100//config:config ASH_JOB_CONTROL
101//config: bool "Job control"
102//config: default y
103//config: depends on ASH
104//config: help
105//config: Enable job control in the ash shell.
106//config:
107//config:config ASH_ALIAS
108//config: bool "alias support"
109//config: default y
110//config: depends on ASH
111//config: help
112//config: Enable alias support in the ash shell.
113//config:
114//config:config ASH_GETOPTS
115//config: bool "Builtin getopt to parse positional parameters"
116//config: default y
117//config: depends on ASH
118//config: help
119//config: Enable getopts builtin in the ash shell.
120//config:
121//config:config ASH_BUILTIN_ECHO
122//config: bool "Builtin version of 'echo'"
123//config: default y
124//config: depends on ASH
125//config: help
126//config: Enable support for echo, builtin to ash.
127//config:
128//config:config ASH_BUILTIN_PRINTF
129//config: bool "Builtin version of 'printf'"
130//config: default y
131//config: depends on ASH
132//config: help
133//config: Enable support for printf, builtin to ash.
134//config:
135//config:config ASH_BUILTIN_TEST
136//config: bool "Builtin version of 'test'"
137//config: default y
138//config: depends on ASH
139//config: help
140//config: Enable support for test, builtin to ash.
141//config:
142//config:config ASH_CMDCMD
143//config: bool "'command' command to override shell builtins"
144//config: default y
145//config: depends on ASH
146//config: help
147//config: Enable support for the ash 'command' builtin, which allows
148//config: you to run the specified command with the specified arguments,
149//config: even when there is an ash builtin command with the same name.
150//config:
151//config:config ASH_MAIL
152//config: bool "Check for new mail on interactive shells"
153//config: default n
154//config: depends on ASH
155//config: help
156//config: Enable "check for new mail" in the ash shell.
157//config:
158//config:config ASH_OPTIMIZE_FOR_SIZE
159//config: bool "Optimize for size instead of speed"
160//config: default y
161//config: depends on ASH
162//config: help
163//config: Compile ash for reduced size at the price of speed.
164//config:
165//config:config ASH_RANDOM_SUPPORT
166//config: bool "Pseudorandom generator and $RANDOM variable"
167//config: default y
168//config: depends on ASH
169//config: help
170//config: Enable pseudorandom generator and dynamic variable "$RANDOM".
171//config: Each read of "$RANDOM" will generate a new pseudorandom value.
172//config: You can reset the generator by using a specified start value.
173//config: After "unset RANDOM" the generator will switch off and this
174//config: variable will no longer have special treatment.
175//config:
176//config:config ASH_EXPAND_PRMT
177//config: bool "Expand prompt string"
178//config: default y
179//config: depends on ASH
180//config: help
181//config: "PS#" may contain volatile content, such as backquote commands.
182//config: This option recreates the prompt string from the environment
183//config: variable each time it is displayed.
184//config:
185
186//usage:#define ash_trivial_usage NOUSAGE_STR
187//usage:#define ash_full_usage ""
188//usage:#define sh_trivial_usage NOUSAGE_STR
189//usage:#define sh_full_usage ""
190//usage:#define bash_trivial_usage NOUSAGE_STR
191//usage:#define bash_full_usage ""
192
73193
74/* ============ Hash table sizes. Configurable. */194/* ============ Hash table sizes. Configurable. */
75195
@@ -835,7 +955,8 @@
835 for (p = arg->narg.text; *p; p++) {955 for (p = arg->narg.text; *p; p++) {
836 switch ((unsigned char)*p) {956 switch ((unsigned char)*p) {
837 case CTLESC:957 case CTLESC:
838 putc(*++p, fp);958 p++;
959 putc(*p, fp);
839 break;960 break;
840 case CTLVAR:961 case CTLVAR:
841 putc('$', fp);962 putc('$', fp);
@@ -844,8 +965,10 @@
844 if (subtype == VSLENGTH)965 if (subtype == VSLENGTH)
845 putc('#', fp);966 putc('#', fp);
846967
847 while (*p != '=')968 while (*p != '=') {
848 putc(*p++, fp);969 putc(*p, fp);
970 p++;
971 }
849972
850 if (subtype & VSNUL)973 if (subtype & VSNUL)
851 putc(':', fp);974 putc(':', fp);
@@ -1864,37 +1987,35 @@
1864# define optindval() (voptind.var_text + 7)1987# define optindval() (voptind.var_text + 7)
1865#endif1988#endif
18661989
1990#if ENABLE_ASH_GETOPTS
1991static void FAST_FUNC
1992getoptsreset(const char *value)
1993{
1994 shellparam.optind = number(value);
1995 shellparam.optoff = -1;
1996}
1997#endif
18671998
1999/* math.h has these, otherwise define our private copies */
2000#if !ENABLE_SH_MATH_SUPPORT
1868#define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))2001#define is_name(c) ((c) == '_' || isalpha((unsigned char)(c)))
1869#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))2002#define is_in_name(c) ((c) == '_' || isalnum((unsigned char)(c)))
1870
1871#if ENABLE_ASH_GETOPTS
1872static void FAST_FUNC
1873getoptsreset(const char *value)
1874{
1875 shellparam.optind = number(value);
1876 shellparam.optoff = -1;
1877}
1878#endif
1879
1880/*2003/*
1881 * Return of a legal variable name (a letter or underscore followed by zero or2004 * Return the pointer to the first char which is not part of a legal variable name
1882 * more letters, underscores, and digits).2005 * (a letter or underscore followed by letters, underscores, and digits).
1883 */2006 */
1884static char* FAST_FUNC2007static const char*
1885endofname(const char *name)2008endofname(const char *name)
1886{2009{
1887 char *p;2010 if (!is_name(*name))
18882011 return name;
1889 p = (char *) name;2012 while (*++name) {
1890 if (!is_name(*p))2013 if (!is_in_name(*name))
1891 return p;
1892 while (*++p) {
1893 if (!is_in_name(*p))
1894 break;2014 break;
1895 }2015 }
1896 return p;2016 return name;
1897}2017}
2018#endif
18982019
1899/*2020/*
1900 * Compares two strings up to the first = or '\0'. The first2021 * Compares two strings up to the first = or '\0'. The first
@@ -2077,9 +2198,10 @@
2077static void2198static void
2078setvar(const char *name, const char *val, int flags)2199setvar(const char *name, const char *val, int flags)
2079{2200{
2080 char *p, *q;2201 const char *q;
2202 char *p;
2203 char *nameeq;
2081 size_t namelen;2204 size_t namelen;
2082 char *nameeq;
2083 size_t vallen;2205 size_t vallen;
20842206
2085 q = endofname(name);2207 q = endofname(name);
@@ -2093,12 +2215,13 @@
2093 } else {2215 } else {
2094 vallen = strlen(val);2216 vallen = strlen(val);
2095 }2217 }
2218
2096 INT_OFF;2219 INT_OFF;
2097 nameeq = ckmalloc(namelen + vallen + 2);2220 nameeq = ckmalloc(namelen + vallen + 2);
2098 p = (char *)memcpy(nameeq, name, namelen) + namelen;2221 p = memcpy(nameeq, name, namelen) + namelen;
2099 if (val) {2222 if (val) {
2100 *p++ = '=';2223 *p++ = '=';
2101 p = (char *)memcpy(p, val, vallen) + vallen;2224 p = memcpy(p, val, vallen) + vallen;
2102 }2225 }
2103 *p = '\0';2226 *p = '\0';
2104 setvareq(nameeq, flags | VNOSAVE);2227 setvareq(nameeq, flags | VNOSAVE);
@@ -2312,12 +2435,13 @@
2312#endif2435#endif
23132436
2314static void2437static void
2315setprompt(int whichprompt)2438setprompt_if(smallint do_set, int whichprompt)
2316{2439{
2317 const char *prompt;2440 const char *prompt;
2318#if ENABLE_ASH_EXPAND_PRMT2441 IF_ASH_EXPAND_PRMT(struct stackmark smark;)
2319 struct stackmark smark;2442
2320#endif2443 if (!do_set)
2444 return;
23212445
2322 needprompt = 0;2446 needprompt = 0;
23232447
@@ -4515,6 +4639,7 @@
4515 INT_ON;4639 INT_ON;
4516 }4640 }
4517 }4641 }
4642 may_have_traps = 0;
4518}4643}
45194644
4520/* Lives far away from here, needed for forkchild */4645/* Lives far away from here, needed for forkchild */
@@ -4870,9 +4995,13 @@
4870 * revealed that it was a regular file, and the file has not been4995 * revealed that it was a regular file, and the file has not been
4871 * replaced, return the file descriptor.4996 * replaced, return the file descriptor.
4872 */4997 */
4873 if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode)4998 if (fstat(fd, &finfo2) == 0
4874 && finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino)4999 && !S_ISREG(finfo2.st_mode)
5000 && finfo.st_dev == finfo2.st_dev
5001 && finfo.st_ino == finfo2.st_ino
5002 ) {
4875 return fd;5003 return fd;
5004 }
48765005
4877 /* The file has been replaced. badness. */5006 /* The file has been replaced. badness. */
4878 close(fd);5007 close(fd);
@@ -5315,25 +5444,17 @@
5315static arith_t5444static arith_t
5316ash_arith(const char *s)5445ash_arith(const char *s)
5317{5446{
5318 arith_eval_hooks_t math_hooks;5447 arith_state_t math_state;
5319 arith_t result;5448 arith_t result;
5320 int errcode = 0;
53215449
5322 math_hooks.lookupvar = lookupvar;5450 math_state.lookupvar = lookupvar;
5323 math_hooks.setvar = setvar2;5451 math_state.setvar = setvar2;
5324 math_hooks.endofname = endofname;5452 //math_state.endofname = endofname;
53255453
5326 INT_OFF;5454 INT_OFF;
5327 result = arith(s, &errcode, &math_hooks);5455 result = arith(&math_state, s);
5328 if (errcode < 0) {5456 if (math_state.errmsg)
5329 if (errcode == -3)5457 ash_msg_and_raise_error(math_state.errmsg);
5330 ash_msg_and_raise_error("exponent less than 0");
5331 if (errcode == -2)
5332 ash_msg_and_raise_error("divide by zero");
5333 if (errcode == -5)
5334 ash_msg_and_raise_error("expression recursion loop detected");
5335 raise_error_syntax(s);
5336 }
5337 INT_ON;5458 INT_ON;
53385459
5339 return result;5460 return result;
@@ -5391,13 +5512,18 @@
5391/*5512/*
5392 * Our own itoa().5513 * Our own itoa().
5393 */5514 */
5515#if !ENABLE_SH_MATH_SUPPORT
5516/* cvtnum() is used even if math support is off (to prepare $? values and such) */
5517typedef long arith_t;
5518# define ARITH_FMT "%ld"
5519#endif
5394static int5520static int
5395cvtnum(arith_t num)5521cvtnum(arith_t num)
5396{5522{
5397 int len;5523 int len;
53985524
5399 expdest = makestrspace(32, expdest);5525 expdest = makestrspace(32, expdest);
5400 len = fmtstr(expdest, 32, arith_t_fmt, num);5526 len = fmtstr(expdest, 32, ARITH_FMT, num);
5401 STADJUST(len, expdest);5527 STADJUST(len, expdest);
5402 return len;5528 return len;
5403}5529}
@@ -5568,7 +5694,7 @@
5568 return;5694 return;
55695695
5570 if (ifsfirst.endoff > endoff) {5696 if (ifsfirst.endoff > endoff) {
5571 while (ifsfirst.next != NULL) {5697 while (ifsfirst.next) {
5572 struct ifsregion *ifsp;5698 struct ifsregion *ifsp;
5573 INT_OFF;5699 INT_OFF;
5574 ifsp = ifsfirst.next->next;5700 ifsp = ifsfirst.next->next;
@@ -5576,9 +5702,9 @@
5576 ifsfirst.next = ifsp;5702 ifsfirst.next = ifsp;
5577 INT_ON;5703 INT_ON;
5578 }5704 }
5579 if (ifsfirst.begoff > endoff)5705 if (ifsfirst.begoff > endoff) {
5580 ifslastp = NULL;5706 ifslastp = NULL;
5581 else {5707 } else {
5582 ifslastp = &ifsfirst;5708 ifslastp = &ifsfirst;
5583 ifsfirst.endoff = endoff;5709 ifsfirst.endoff = endoff;
5584 }5710 }
@@ -5587,8 +5713,8 @@
55875713
5588 ifslastp = &ifsfirst;5714 ifslastp = &ifsfirst;
5589 while (ifslastp->next && ifslastp->next->begoff < endoff)5715 while (ifslastp->next && ifslastp->next->begoff < endoff)
5590 ifslastp=ifslastp->next;5716 ifslastp = ifslastp->next;
5591 while (ifslastp->next != NULL) {5717 while (ifslastp->next) {
5592 struct ifsregion *ifsp;5718 struct ifsregion *ifsp;
5593 INT_OFF;5719 INT_OFF;
5594 ifsp = ifslastp->next->next;5720 ifsp = ifslastp->next->next;
@@ -5765,9 +5891,9 @@
57655891
5766 if (quoted == 0)5892 if (quoted == 0)
5767 recordregion(startloc, dest - (char *)stackblock(), 0);5893 recordregion(startloc, dest - (char *)stackblock(), 0);
5768 TRACE(("evalbackq: size=%d: \"%.*s\"\n",5894 TRACE(("evalbackq: size:%d:'%.*s'\n",
5769 (dest - (char *)stackblock()) - startloc,5895 (int)((dest - (char *)stackblock()) - startloc),
5770 (dest - (char *)stackblock()) - startloc,5896 (int)((dest - (char *)stackblock()) - startloc),
5771 stackblock() + startloc));5897 stackblock() + startloc));
5772}5898}
57735899
@@ -5882,7 +6008,7 @@
5882 flags &= ~EXP_TILDE;6008 flags &= ~EXP_TILDE;
5883 tilde:6009 tilde:
5884 q = p;6010 q = p;
5885 if (*q == CTLESC && (flags & EXP_QWORD))6011 if ((unsigned char)*q == CTLESC && (flags & EXP_QWORD))
5886 q++;6012 q++;
5887 if (*q == '~')6013 if (*q == '~')
5888 p = exptilde(p, q, flags);6014 p = exptilde(p, q, flags);
@@ -5896,9 +6022,7 @@
5896 c = p[length];6022 c = p[length];
5897 if (c) {6023 if (c) {
5898 if (!(c & 0x80)6024 if (!(c & 0x80)
5899#if ENABLE_SH_MATH_SUPPORT6025 IF_SH_MATH_SUPPORT(|| c == CTLENDARI)
5900 || c == CTLENDARI
5901#endif
5902 ) {6026 ) {
5903 /* c == '=' || c == ':' || c == CTLENDARI */6027 /* c == '=' || c == ':' || c == CTLENDARI */
5904 length++;6028 length++;
@@ -5945,8 +6069,8 @@
5945 /* "$@" syntax adherence hack */6069 /* "$@" syntax adherence hack */
5946 if (!inquotes6070 if (!inquotes
5947 && memcmp(p, dolatstr, 4) == 06071 && memcmp(p, dolatstr, 4) == 0
5948 && ( p[4] == CTLQUOTEMARK6072 && ( p[4] == (char)CTLQUOTEMARK
5949 || (p[4] == CTLENDVAR && p[5] == CTLQUOTEMARK)6073 || (p[4] == (char)CTLENDVAR && p[5] == (char)CTLQUOTEMARK)
5950 )6074 )
5951 ) {6075 ) {
5952 p = evalvar(p + 1, flags, /* var_str_list: */ NULL) + 1;6076 p = evalvar(p + 1, flags, /* var_str_list: */ NULL) + 1;
@@ -5981,47 +6105,20 @@
5981#endif6105#endif
5982 }6106 }
5983 }6107 }
5984 breakloop:6108 breakloop: ;
5985 ;
5986}6109}
59876110
5988static char *6111static char *
5989scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM, char *str, int quotes,6112scanleft(char *startp, char *rmesc, char *rmescend UNUSED_PARAM,
5990 int zero)6113 char *pattern, int quotes, int zero)
5991{6114{
5992// This commented out code was added by James Simmons <jsimmons@infradead.org>6115 char *loc, *loc2;
5993// as part of a larger change when he added support for ${var/a/b}.
5994// However, it broke # and % operators:
5995//
5996//var=ababcdcd
5997// ok bad
5998//echo ${var#ab} abcdcd abcdcd
5999//echo ${var##ab} abcdcd abcdcd
6000//echo ${var#a*b} abcdcd ababcdcd (!)
6001//echo ${var##a*b} cdcd cdcd
6002//echo ${var#?} babcdcd ababcdcd (!)
6003//echo ${var##?} babcdcd babcdcd
6004//echo ${var#*} ababcdcd babcdcd (!)
6005//echo ${var##*}
6006//echo ${var%cd} ababcd ababcd
6007//echo ${var%%cd} ababcd abab (!)
6008//echo ${var%c*d} ababcd ababcd
6009//echo ${var%%c*d} abab ababcdcd (!)
6010//echo ${var%?} ababcdc ababcdc
6011//echo ${var%%?} ababcdc ababcdcd (!)
6012//echo ${var%*} ababcdcd ababcdcd
6013//echo ${var%%*}
6014//
6015// Commenting it back out helped. Remove it completely if it really
6016// is not needed.
6017
6018 char *loc, *loc2; //, *full;
6019 char c;6116 char c;
60206117
6021 loc = startp;6118 loc = startp;
6022 loc2 = rmesc;6119 loc2 = rmesc;
6023 do {6120 do {
6024 int match; // = strlen(str);6121 int match;
6025 const char *s = loc2;6122 const char *s = loc2;
60266123
6027 c = *loc2;6124 c = *loc2;
@@ -6029,35 +6126,22 @@
6029 *loc2 = '\0';6126 *loc2 = '\0';
6030 s = rmesc;6127 s = rmesc;
6031 }6128 }
6032 match = pmatch(str, s); // this line was deleted6129 match = pmatch(pattern, s);
60336130
6034// // chop off end if its '*'
6035// full = strrchr(str, '*');
6036// if (full && full != str)
6037// match--;
6038//
6039// // If str starts with '*' replace with s.
6040// if ((*str == '*') && strlen(s) >= match) {
6041// full = xstrdup(s);
6042// strncpy(full+strlen(s)-match+1, str+1, match-1);
6043// } else
6044// full = xstrndup(str, match);
6045// match = strncmp(s, full, strlen(full));
6046// free(full);
6047//
6048 *loc2 = c;6131 *loc2 = c;
6049 if (match) // if (!match)6132 if (match)
6050 return loc;6133 return loc;
6051 if (quotes && (unsigned char)*loc == CTLESC)6134 if (quotes && (unsigned char)*loc == CTLESC)
6052 loc++;6135 loc++;
6053 loc++;6136 loc++;
6054 loc2++;6137 loc2++;
6055 } while (c);6138 } while (c);
6056 return 0;6139 return NULL;
6057}6140}
60586141
6059static char *6142static char *
6060scanright(char *startp, char *rmesc, char *rmescend, char *pattern, int quotes, int match_at_start)6143scanright(char *startp, char *rmesc, char *rmescend,
6144 char *pattern, int quotes, int match_at_start)
6061{6145{
6062#if !ENABLE_ASH_OPTIMIZE_FOR_SIZE6146#if !ENABLE_ASH_OPTIMIZE_FOR_SIZE
6063 int try2optimize = match_at_start;6147 int try2optimize = match_at_start;
@@ -6123,7 +6207,7 @@
6123 }6207 }
6124 }6208 }
6125 }6209 }
6126 return 0;6210 return NULL;
6127}6211}
61286212
6129static void varunset(const char *, const char *, const char *, int) NORETURN;6213static void varunset(const char *, const char *, const char *, int) NORETURN;
@@ -6143,16 +6227,18 @@
6143 msg = umsg;6227 msg = umsg;
6144 }6228 }
6145 }6229 }
6146 ash_msg_and_raise_error("%.*s: %s%s", end - var - 1, var, msg, tail);6230 ash_msg_and_raise_error("%.*s: %s%s", (int)(end - var - 1), var, msg, tail);
6147}6231}
61486232
6149#if ENABLE_ASH_BASH_COMPAT6233#if ENABLE_ASH_BASH_COMPAT
6150static char *6234static char *
6151parse_sub_pattern(char *arg, int inquotes)6235parse_sub_pattern(char *arg, int varflags)
6152{6236{
6153 char *idx, *repl = NULL;6237 char *idx, *repl = NULL;
6154 unsigned char c;6238 unsigned char c;
61556239
6240 //char *org_arg = arg;
6241 //bb_error_msg("arg:'%s' varflags:%x", arg, varflags);
6156 idx = arg;6242 idx = arg;
6157 while (1) {6243 while (1) {
6158 c = *arg;6244 c = *arg;
@@ -6166,24 +6252,37 @@
6166 }6252 }
6167 }6253 }
6168 *idx++ = c;6254 *idx++ = c;
6169 if (!inquotes && c == '\\' && arg[1] == '\\')
6170 arg++; /* skip both \\, not just first one */
6171 arg++;6255 arg++;
6256 /*
6257 * Example: v='ab\c'; echo ${v/\\b/_\\_\z_}
6258 * The result is a_\_z_c (not a\_\_z_c)!
6259 *
6260 * Enable debug prints in this function and you'll see:
6261 * ash: arg:'\\b/_\\_z_' varflags:d
6262 * ash: pattern:'\\b' repl:'_\_z_'
6263 * That is, \\b is interpreted as \\b, but \\_ as \_!
6264 * IOW: search pattern and replace string treat backslashes
6265 * differently! That is the reason why we check repl below:
6266 */
6267 if (c == '\\' && *arg == '\\' && repl && !(varflags & VSQUOTE))
6268 arg++; /* skip both '\', not just first one */
6172 }6269 }
6173 *idx = c; /* NUL */6270 *idx = c; /* NUL */
6271 //bb_error_msg("pattern:'%s' repl:'%s'", org_arg, repl);
61746272
6175 return repl;6273 return repl;
6176}6274}
6177#endif /* ENABLE_ASH_BASH_COMPAT */6275#endif /* ENABLE_ASH_BASH_COMPAT */
61786276
6179static const char *6277static const char *
6180subevalvar(char *p, char *str, int strloc, int subtype,6278subevalvar(char *p, char *varname, int strloc, int subtype,
6181 int startloc, int varflags, int quotes, struct strlist *var_str_list)6279 int startloc, int varflags, int quotes, struct strlist *var_str_list)
6182{6280{
6183 struct nodelist *saveargbackq = argbackq;6281 struct nodelist *saveargbackq = argbackq;
6184 char *startp;6282 char *startp;
6185 char *loc;6283 char *loc;
6186 char *rmesc, *rmescend;6284 char *rmesc, *rmescend;
6285 char *str;
6187 IF_ASH_BASH_COMPAT(const char *repl = NULL;)6286 IF_ASH_BASH_COMPAT(const char *repl = NULL;)
6188 IF_ASH_BASH_COMPAT(int pos, len, orig_len;)6287 IF_ASH_BASH_COMPAT(int pos, len, orig_len;)
6189 int saveherefd = herefd;6288 int saveherefd = herefd;
@@ -6191,6 +6290,9 @@
6191 int zero;6290 int zero;
6192 char *(*scan)(char*, char*, char*, char*, int, int);6291 char *(*scan)(char*, char*, char*, char*, int, int);
61936292
6293 //bb_error_msg("subevalvar(p:'%s',varname:'%s',strloc:%d,subtype:%d,startloc:%d,varflags:%x,quotes:%d)",
6294 // p, varname, strloc, subtype, startloc, varflags, quotes);
6295
6194 herefd = -1;6296 herefd = -1;
6195 argstr(p, (subtype != VSASSIGN && subtype != VSQUESTION) ? EXP_CASE : 0,6297 argstr(p, (subtype != VSASSIGN && subtype != VSQUESTION) ? EXP_CASE : 0,
6196 var_str_list);6298 var_str_list);
@@ -6201,11 +6303,15 @@
62016303
6202 switch (subtype) {6304 switch (subtype) {
6203 case VSASSIGN:6305 case VSASSIGN:
6204 setvar(str, startp, 0);6306 setvar(varname, startp, 0);
6205 amount = startp - expdest;6307 amount = startp - expdest;
6206 STADJUST(amount, expdest);6308 STADJUST(amount, expdest);
6207 return startp;6309 return startp;
62086310
6311 case VSQUESTION:
6312 varunset(p, varname, startp, varflags);
6313 /* NOTREACHED */
6314
6209#if ENABLE_ASH_BASH_COMPAT6315#if ENABLE_ASH_BASH_COMPAT
6210 case VSSUBSTR:6316 case VSSUBSTR:
6211 loc = str = stackblock() + strloc;6317 loc = str = stackblock() + strloc;
@@ -6266,11 +6372,8 @@
6266 STADJUST(amount, expdest);6372 STADJUST(amount, expdest);
6267 return loc;6373 return loc;
6268#endif6374#endif
6375 }
62696376
6270 case VSQUESTION:
6271 varunset(p, str, startp, varflags);
6272 /* NOTREACHED */
6273 }
6274 resetloc = expdest - (char *)stackblock();6377 resetloc = expdest - (char *)stackblock();
62756378
6276 /* We'll comeback here if we grow the stack while handling6379 /* We'll comeback here if we grow the stack while handling
@@ -6303,14 +6406,15 @@
6303 char *idx, *end;6406 char *idx, *end;
63046407
6305 if (!repl) {6408 if (!repl) {
6306 repl = parse_sub_pattern(str, varflags & VSQUOTE);6409 repl = parse_sub_pattern(str, varflags);
6410 //bb_error_msg("repl:'%s'", repl);
6307 if (!repl)6411 if (!repl)
6308 repl = nullstr;6412 repl = nullstr;
6309 }6413 }
63106414
6311 /* If there's no pattern to match, return the expansion unmolested */6415 /* If there's no pattern to match, return the expansion unmolested */
6312 if (str[0] == '\0')6416 if (str[0] == '\0')
6313 return 0;6417 return NULL;
63146418
6315 len = 0;6419 len = 0;
6316 idx = startp;6420 idx = startp;
@@ -6318,6 +6422,7 @@
6318 while (idx < end) {6422 while (idx < end) {
6319 try_to_match:6423 try_to_match:
6320 loc = scanright(idx, rmesc, rmescend, str, quotes, 1);6424 loc = scanright(idx, rmesc, rmescend, str, quotes, 1);
6425 //bb_error_msg("scanright('%s'):'%s'", str, loc);
6321 if (!loc) {6426 if (!loc) {
6322 /* No match, advance */6427 /* No match, advance */
6323 char *restart_detect = stackblock();6428 char *restart_detect = stackblock();
@@ -6356,6 +6461,7 @@
6356 idx = loc;6461 idx = loc;
6357 }6462 }
63586463
6464 //bb_error_msg("repl:'%s'", repl);
6359 for (loc = (char*)repl; *loc; loc++) {6465 for (loc = (char*)repl; *loc; loc++) {
6360 char *restart_detect = stackblock();6466 char *restart_detect = stackblock();
6361 if (quotes && *loc == '\\') {6467 if (quotes && *loc == '\\') {
@@ -6369,12 +6475,9 @@
6369 }6475 }
63706476
6371 if (subtype == VSREPLACE) {6477 if (subtype == VSREPLACE) {
6478 //bb_error_msg("tail:'%s', quotes:%x", idx, quotes);
6372 while (*idx) {6479 while (*idx) {
6373 char *restart_detect = stackblock();6480 char *restart_detect = stackblock();
6374 if (quotes && *idx == '\\') {
6375 STPUTC(CTLESC, expdest);
6376 len++;
6377 }
6378 STPUTC(*idx, expdest);6481 STPUTC(*idx, expdest);
6379 if (stackblock() != restart_detect)6482 if (stackblock() != restart_detect)
6380 goto restart;6483 goto restart;
@@ -6391,6 +6494,7 @@
6391 STPUTC('\0', expdest);6494 STPUTC('\0', expdest);
6392 startp = (char *)stackblock() + startloc;6495 startp = (char *)stackblock() + startloc;
6393 memmove(startp, (char *)stackblock() + workloc, len + 1);6496 memmove(startp, (char *)stackblock() + workloc, len + 1);
6497 //bb_error_msg("startp:'%s'", startp);
6394 amount = expdest - (startp + len);6498 amount = expdest - (startp + len);
6395 STADJUST(-amount, expdest);6499 STADJUST(-amount, expdest);
6396 return startp;6500 return startp;
@@ -6620,8 +6724,8 @@
6620 vsplus:6724 vsplus:
6621 if (varlen < 0) {6725 if (varlen < 0) {
6622 argstr(6726 argstr(
6623 p, flags | EXP_TILDE |6727 p,
6624 (quoted ? EXP_QWORD : EXP_WORD),6728 flags | (quoted ? EXP_TILDE|EXP_QWORD : EXP_TILDE|EXP_WORD),
6625 var_str_list6729 var_str_list
6626 );6730 );
6627 goto end;6731 goto end;
@@ -6691,7 +6795,7 @@
6691 */6795 */
6692 STPUTC('\0', expdest);6796 STPUTC('\0', expdest);
6693 patloc = expdest - (char *)stackblock();6797 patloc = expdest - (char *)stackblock();
6694 if (NULL == subevalvar(p, /* str: */ NULL, patloc, subtype,6798 if (NULL == subevalvar(p, /* varname: */ NULL, patloc, subtype,
6695 startloc, varflags,6799 startloc, varflags,
6696//TODO: | EXP_REDIR too? All other such places do it too6800//TODO: | EXP_REDIR too? All other such places do it too
6697 /* quotes: */ flags & (EXP_FULL | EXP_CASE),6801 /* quotes: */ flags & (EXP_FULL | EXP_CASE),
@@ -7526,7 +7630,7 @@
7526 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {7630 for (cmdp = *pp; cmdp; cmdp = cmdp->next) {
7527 if (cmdp->cmdtype == CMDNORMAL7631 if (cmdp->cmdtype == CMDNORMAL
7528 || (cmdp->cmdtype == CMDBUILTIN7632 || (cmdp->cmdtype == CMDBUILTIN
7529 && !IS_BUILTIN_REGULAR(cmdp->param.cmd)7633 && !IS_BUILTIN_REGULAR(cmdp->param.cmd)
7530 && builtinloc > 0)7634 && builtinloc > 0)
7531 ) {7635 ) {
7532 cmdp->rehash = 1;7636 cmdp->rehash = 1;
@@ -8117,7 +8221,7 @@
81178221
8118/* Called to execute a trap.8222/* Called to execute a trap.
8119 * Single callsite - at the end of evaltree().8223 * Single callsite - at the end of evaltree().
8120 * If we return non-zero, exaltree raises EXEXIT exception.8224 * If we return non-zero, evaltree raises EXEXIT exception.
8121 *8225 *
8122 * Perhaps we should avoid entering new trap handlers8226 * Perhaps we should avoid entering new trap handlers
8123 * while we are executing a trap handler. [is it a TODO?]8227 * while we are executing a trap handler. [is it a TODO?]
@@ -8307,11 +8411,15 @@
83078411
8308 out:8412 out:
8309 exception_handler = savehandler;8413 exception_handler = savehandler;
8414
8310 out1:8415 out1:
8416 /* Order of checks below is important:
8417 * signal handlers trigger before exit caused by "set -e".
8418 */
8419 if (pending_sig && dotrap())
8420 goto exexit;
8311 if (checkexit & exitstatus)8421 if (checkexit & exitstatus)
8312 evalskip |= SKIPEVAL;8422 evalskip |= SKIPEVAL;
8313 else if (pending_sig && dotrap())
8314 goto exexit;
83158423
8316 if (flags & EV_EXIT) {8424 if (flags & EV_EXIT) {
8317 exexit:8425 exexit:
@@ -8643,7 +8751,7 @@
8643 while ((lvp = localvars) != NULL) {8751 while ((lvp = localvars) != NULL) {
8644 localvars = lvp->next;8752 localvars = lvp->next;
8645 vp = lvp->vp;8753 vp = lvp->vp;
8646 TRACE(("poplocalvar %s\n", vp ? vp->text : "-"));8754 TRACE(("poplocalvar %s\n", vp ? vp->var_text : "-"));
8647 if (vp == NULL) { /* $- saved */8755 if (vp == NULL) { /* $- saved */
8648 memcpy(optlist, lvp->text, sizeof(optlist));8756 memcpy(optlist, lvp->text, sizeof(optlist));
8649 free((char*)lvp->text);8757 free((char*)lvp->text);
@@ -9301,7 +9409,7 @@
9301static int9409static int
9302goodname(const char *p)9410goodname(const char *p)
9303{9411{
9304 return !*endofname(p);9412 return endofname(p)[0] == '\0';
9305}9413}
93069414
93079415
@@ -10932,7 +11040,6 @@
10932 startlinno = g_parsefile->linno;11040 startlinno = g_parsefile->linno;
10933 bqlist = NULL;11041 bqlist = NULL;
10934 quotef = 0;11042 quotef = 0;
10935 oldstyle = 0;
10936 prevsyntax = 0;11043 prevsyntax = 0;
10937#if ENABLE_ASH_EXPAND_PRMT11044#if ENABLE_ASH_EXPAND_PRMT
10938 pssyntax = (syntax == PSSYNTAX);11045 pssyntax = (syntax == PSSYNTAX);
@@ -10948,160 +11055,156 @@
10948 STARTSTACKSTR(out);11055 STARTSTACKSTR(out);
10949 loop:11056 loop:
10950 /* For each line, until end of word */11057 /* For each line, until end of word */
10951 {11058 CHECKEND(); /* set c to PEOF if at end of here document */
10952 CHECKEND(); /* set c to PEOF if at end of here document */11059 for (;;) { /* until end of line or end of word */
10953 for (;;) { /* until end of line or end of word */11060 CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */
10954 CHECKSTRSPACE(4, out); /* permit 4 calls to USTPUTC */11061 switch (SIT(c, syntax)) {
10955 switch (SIT(c, syntax)) {11062 case CNL: /* '\n' */
10956 case CNL: /* '\n' */11063 if (syntax == BASESYNTAX)
10957 if (syntax == BASESYNTAX)11064 goto endword; /* exit outer loop */
10958 goto endword; /* exit outer loop */11065 USTPUTC(c, out);
10959 USTPUTC(c, out);11066 g_parsefile->linno++;
10960 g_parsefile->linno++;11067 setprompt_if(doprompt, 2);
10961 if (doprompt)11068 c = pgetc();
10962 setprompt(2);11069 goto loop; /* continue outer loop */
10963 c = pgetc();11070 case CWORD:
10964 goto loop; /* continue outer loop */11071 USTPUTC(c, out);
10965 case CWORD:11072 break;
10966 USTPUTC(c, out);11073 case CCTL:
10967 break;11074 if (eofmark == NULL || dblquote)
10968 case CCTL:11075 USTPUTC(CTLESC, out);
10969 if (eofmark == NULL || dblquote)
10970 USTPUTC(CTLESC, out);
10971#if ENABLE_ASH_BASH_COMPAT11076#if ENABLE_ASH_BASH_COMPAT
10972 if (c == '\\' && bash_dollar_squote) {11077 if (c == '\\' && bash_dollar_squote) {
10973 c = decode_dollar_squote();11078 c = decode_dollar_squote();
10974 if (c & 0x100) {11079 if (c & 0x100) {
10975 USTPUTC('\\', out);11080 USTPUTC('\\', out);
10976 c = (unsigned char)c;11081 c = (unsigned char)c;
10977 }
10978 }11082 }
11083 }
10979#endif11084#endif
10980 USTPUTC(c, out);11085 USTPUTC(c, out);
10981 break;11086 break;
10982 case CBACK: /* backslash */11087 case CBACK: /* backslash */
10983 c = pgetc_without_PEOA();11088 c = pgetc_without_PEOA();
10984 if (c == PEOF) {11089 if (c == PEOF) {
10985 USTPUTC(CTLESC, out);11090 USTPUTC(CTLESC, out);
10986 USTPUTC('\\', out);11091 USTPUTC('\\', out);
10987 pungetc();11092 pungetc();
10988 } else if (c == '\n') {11093 } else if (c == '\n') {
10989 if (doprompt)11094 setprompt_if(doprompt, 2);
10990 setprompt(2);11095 } else {
10991 } else {
10992#if ENABLE_ASH_EXPAND_PRMT11096#if ENABLE_ASH_EXPAND_PRMT
10993 if (c == '$' && pssyntax) {11097 if (c == '$' && pssyntax) {
10994 USTPUTC(CTLESC, out);11098 USTPUTC(CTLESC, out);
10995 USTPUTC('\\', out);11099 USTPUTC('\\', out);
10996 }11100 }
10997#endif11101#endif
10998 if (dblquote && c != '\\'11102 /* Backslash is retained if we are in "str" and next char isn't special */
10999 && c != '`' && c != '$'11103 if (dblquote
11000 && (c != '"' || eofmark != NULL)11104 && c != '\\'
11001 ) {11105 && c != '`'
11002 USTPUTC(CTLESC, out);11106 && c != '$'
11003 USTPUTC('\\', out);11107 && (c != '"' || eofmark != NULL)
11004 }11108 ) {
11005 if (SIT(c, SQSYNTAX) == CCTL)11109 USTPUTC(CTLESC, out);
11006 USTPUTC(CTLESC, out);11110 USTPUTC('\\', out);
11007 USTPUTC(c, out);
11008 quotef = 1;
11009 }11111 }
11010 break;11112 if (SIT(c, SQSYNTAX) == CCTL)
11011 case CSQUOTE:11113 USTPUTC(CTLESC, out);
11012 syntax = SQSYNTAX;11114 USTPUTC(c, out);
11115 quotef = 1;
11116 }
11117 break;
11118 case CSQUOTE:
11119 syntax = SQSYNTAX;
11013 quotemark:11120 quotemark:
11014 if (eofmark == NULL) {11121 if (eofmark == NULL) {
11015 USTPUTC(CTLQUOTEMARK, out);11122 USTPUTC(CTLQUOTEMARK, out);
11123 }
11124 break;
11125 case CDQUOTE:
11126 syntax = DQSYNTAX;
11127 dblquote = 1;
11128 goto quotemark;
11129 case CENDQUOTE:
11130 IF_ASH_BASH_COMPAT(bash_dollar_squote = 0;)
11131 if (eofmark != NULL && arinest == 0
11132 && varnest == 0
11133 ) {
11134 USTPUTC(c, out);
11135 } else {
11136 if (dqvarnest == 0) {
11137 syntax = BASESYNTAX;
11138 dblquote = 0;
11016 }11139 }
11017 break;11140 quotef = 1;
11018 case CDQUOTE:
11019 syntax = DQSYNTAX;
11020 dblquote = 1;
11021 goto quotemark;11141 goto quotemark;
11022 case CENDQUOTE:11142 }
11023 IF_ASH_BASH_COMPAT(bash_dollar_squote = 0;)11143 break;
11024 if (eofmark != NULL && arinest == 011144 case CVAR: /* '$' */
11025 && varnest == 011145 PARSESUB(); /* parse substitution */
11026 ) {11146 break;
11027 USTPUTC(c, out);11147 case CENDVAR: /* '}' */
11028 } else {11148 if (varnest > 0) {
11029 if (dqvarnest == 0) {11149 varnest--;
11030 syntax = BASESYNTAX;11150 if (dqvarnest > 0) {
11031 dblquote = 0;11151 dqvarnest--;
11032 }11152 }
11033 quotef = 1;11153 c = CTLENDVAR;
11034 goto quotemark;11154 }
11035 }11155 USTPUTC(c, out);
11036 break;11156 break;
11037 case CVAR: /* '$' */
11038 PARSESUB(); /* parse substitution */
11039 break;
11040 case CENDVAR: /* '}' */
11041 if (varnest > 0) {
11042 varnest--;
11043 if (dqvarnest > 0) {
11044 dqvarnest--;
11045 }
11046 USTPUTC(CTLENDVAR, out);
11047 } else {
11048 USTPUTC(c, out);
11049 }
11050 break;
11051#if ENABLE_SH_MATH_SUPPORT11157#if ENABLE_SH_MATH_SUPPORT
11052 case CLP: /* '(' in arithmetic */11158 case CLP: /* '(' in arithmetic */
11053 parenlevel++;11159 parenlevel++;
11160 USTPUTC(c, out);
11161 break;
11162 case CRP: /* ')' in arithmetic */
11163 if (parenlevel > 0) {
11164 parenlevel--;
11165 } else {
11166 if (pgetc() == ')') {
11167 if (--arinest == 0) {
11168 syntax = prevsyntax;
11169 dblquote = (syntax == DQSYNTAX);
11170 c = CTLENDARI;
11171 }
11172 } else {
11173 /*
11174 * unbalanced parens
11175 * (don't 2nd guess - no error)
11176 */
11177 pungetc();
11178 }
11179 }
11180 USTPUTC(c, out);
11181 break;
11182#endif
11183 case CBQUOTE: /* '`' */
11184 PARSEBACKQOLD();
11185 break;
11186 case CENDFILE:
11187 goto endword; /* exit outer loop */
11188 case CIGN:
11189 break;
11190 default:
11191 if (varnest == 0) {
11192#if ENABLE_ASH_BASH_COMPAT
11193 if (c == '&') {
11194 if (pgetc() == '>')
11195 c = 0x100 + '>'; /* flag &> */
11196 pungetc();
11197 }
11198#endif
11199 goto endword; /* exit outer loop */
11200 }
11201 IF_ASH_ALIAS(if (c != PEOA))
11054 USTPUTC(c, out);11202 USTPUTC(c, out);
11055 break;11203 }
11056 case CRP: /* ')' in arithmetic */11204 c = pgetc_fast();
11057 if (parenlevel > 0) {11205 } /* for (;;) */
11058 USTPUTC(c, out);
11059 --parenlevel;
11060 } else {
11061 if (pgetc() == ')') {
11062 if (--arinest == 0) {
11063 USTPUTC(CTLENDARI, out);
11064 syntax = prevsyntax;
11065 dblquote = (syntax == DQSYNTAX);
11066 } else
11067 USTPUTC(')', out);
11068 } else {
11069 /*
11070 * unbalanced parens
11071 * (don't 2nd guess - no error)
11072 */
11073 pungetc();
11074 USTPUTC(')', out);
11075 }
11076 }
11077 break;
11078#endif
11079 case CBQUOTE: /* '`' */
11080 PARSEBACKQOLD();
11081 break;
11082 case CENDFILE:
11083 goto endword; /* exit outer loop */
11084 case CIGN:
11085 break;
11086 default:
11087 if (varnest == 0) {
11088#if ENABLE_ASH_BASH_COMPAT
11089 if (c == '&') {
11090 if (pgetc() == '>')
11091 c = 0x100 + '>'; /* flag &> */
11092 pungetc();
11093 }
11094#endif
11095 goto endword; /* exit outer loop */
11096 }
11097 IF_ASH_ALIAS(if (c != PEOA))
11098 USTPUTC(c, out);
11099
11100 }
11101 c = pgetc_fast();
11102 } /* for (;;) */
11103 }
11104 endword:11206 endword:
11207
11105#if ENABLE_SH_MATH_SUPPORT11208#if ENABLE_SH_MATH_SUPPORT
11106 if (syntax == ARISYNTAX)11209 if (syntax == ARISYNTAX)
11107 raise_error_syntax("missing '))'");11210 raise_error_syntax("missing '))'");
@@ -11262,8 +11365,6 @@
11262 unsigned char subtype;11365 unsigned char subtype;
11263 int typeloc;11366 int typeloc;
11264 int flags;11367 int flags;
11265 char *p;
11266 static const char types[] ALIGN1 = "}-+?=";
1126711368
11268 c = pgetc();11369 c = pgetc();
11269 if (c > 255 /* PEOA or PEOF */11370 if (c > 255 /* PEOA or PEOF */
@@ -11276,7 +11377,8 @@
11276#endif11377#endif
11277 USTPUTC('$', out);11378 USTPUTC('$', out);
11278 pungetc();11379 pungetc();
11279 } else if (c == '(') { /* $(command) or $((arith)) */11380 } else if (c == '(') {
11381 /* $(command) or $((arith)) */
11280 if (pgetc() == '(') {11382 if (pgetc() == '(') {
11281#if ENABLE_SH_MATH_SUPPORT11383#if ENABLE_SH_MATH_SUPPORT
11282 PARSEARITH();11384 PARSEARITH();
@@ -11288,6 +11390,7 @@
11288 PARSEBACKQNEW();11390 PARSEBACKQNEW();
11289 }11391 }
11290 } else {11392 } else {
11393 /* $VAR, $<specialchar>, ${...}, or PEOA/PEOF */
11291 USTPUTC(CTLVAR, out);11394 USTPUTC(CTLVAR, out);
11292 typeloc = out - (char *)stackblock();11395 typeloc = out - (char *)stackblock();
11293 USTPUTC(VSNORMAL, out);11396 USTPUTC(VSNORMAL, out);
@@ -11297,76 +11400,90 @@
11297 if (c == '#') {11400 if (c == '#') {
11298 c = pgetc();11401 c = pgetc();
11299 if (c == '}')11402 if (c == '}')
11300 c = '#';11403 c = '#'; /* ${#} - same as $# */
11301 else11404 else
11302 subtype = VSLENGTH;11405 subtype = VSLENGTH; /* ${#VAR} */
11303 } else11406 } else {
11304 subtype = 0;11407 subtype = 0;
11408 }
11305 }11409 }
11306 if (c <= 255 /* not PEOA or PEOF */ && is_name(c)) {11410 if (c <= 255 /* not PEOA or PEOF */ && is_name(c)) {
11411 /* $[{[#]]NAME[}] */
11307 do {11412 do {
11308 STPUTC(c, out);11413 STPUTC(c, out);
11309 c = pgetc();11414 c = pgetc();
11310 } while (c <= 255 /* not PEOA or PEOF */ && is_in_name(c));11415 } while (c <= 255 /* not PEOA or PEOF */ && is_in_name(c));
11311 } else if (isdigit(c)) {11416 } else if (isdigit(c)) {
11417 /* $[{[#]]NUM[}] */
11312 do {11418 do {
11313 STPUTC(c, out);11419 STPUTC(c, out);
11314 c = pgetc();11420 c = pgetc();
11315 } while (isdigit(c));11421 } while (isdigit(c));
11316 } else if (is_special(c)) {11422 } else if (is_special(c)) {
11423 /* $[{[#]]<specialchar>[}] */
11317 USTPUTC(c, out);11424 USTPUTC(c, out);
11318 c = pgetc();11425 c = pgetc();
11319 } else {11426 } else {
11320 badsub:11427 badsub:
11321 raise_error_syntax("bad substitution");11428 raise_error_syntax("bad substitution");
11322 }11429 }
11323 if (c != '}' && subtype == VSLENGTH)11430 if (c != '}' && subtype == VSLENGTH) {
11431 /* ${#VAR didn't end with } */
11324 goto badsub;11432 goto badsub;
11433 }
1132511434
11326 STPUTC('=', out);11435 STPUTC('=', out);
11327 flags = 0;11436 flags = 0;
11328 if (subtype == 0) {11437 if (subtype == 0) {
11438 /* ${VAR...} but not $VAR or ${#VAR} */
11439 /* c == first char after VAR */
11329 switch (c) {11440 switch (c) {
11330 case ':':11441 case ':':
11331 c = pgetc();11442 c = pgetc();
11332#if ENABLE_ASH_BASH_COMPAT11443#if ENABLE_ASH_BASH_COMPAT
11333 if (c == ':' || c == '$' || isdigit(c)) {11444 if (c == ':' || c == '$' || isdigit(c)) {
11334 pungetc();11445//TODO: support more general format ${v:EXPR:EXPR},
11446// where EXPR follows $(()) rules
11335 subtype = VSSUBSTR;11447 subtype = VSSUBSTR;
11336 break;11448 pungetc();
11449 break; /* "goto do_pungetc" is bigger (!) */
11337 }11450 }
11338#endif11451#endif
11339 flags = VSNUL;11452 flags = VSNUL;
11340 /*FALLTHROUGH*/11453 /*FALLTHROUGH*/
11341 default:11454 default: {
11342 p = strchr(types, c);11455 static const char types[] ALIGN1 = "}-+?=";
11456 const char *p = strchr(types, c);
11343 if (p == NULL)11457 if (p == NULL)
11344 goto badsub;11458 goto badsub;
11345 subtype = p - types + VSNORMAL;11459 subtype = p - types + VSNORMAL;
11346 break;11460 break;
11461 }
11347 case '%':11462 case '%':
11348 case '#': {11463 case '#': {
11349 int cc = c;11464 int cc = c;
11350 subtype = c == '#' ? VSTRIMLEFT : VSTRIMRIGHT;11465 subtype = (c == '#' ? VSTRIMLEFT : VSTRIMRIGHT);
11351 c = pgetc();11466 c = pgetc();
11352 if (c == cc)11467 if (c != cc)
11353 subtype++;11468 goto do_pungetc;
11354 else11469 subtype++;
11355 pungetc();
11356 break;11470 break;
11357 }11471 }
11358#if ENABLE_ASH_BASH_COMPAT11472#if ENABLE_ASH_BASH_COMPAT
11359 case '/':11473 case '/':
11474 /* ${v/[/]pattern/repl} */
11475//TODO: encode pattern and repl separately.
11476// Currently ${v/$var_with_slash/repl} is horribly broken
11360 subtype = VSREPLACE;11477 subtype = VSREPLACE;
11361 c = pgetc();11478 c = pgetc();
11362 if (c == '/')11479 if (c != '/')
11363 subtype++; /* VSREPLACEALL */11480 goto do_pungetc;
11364 else11481 subtype++; /* VSREPLACEALL */
11365 pungetc();
11366 break;11482 break;
11367#endif11483#endif
11368 }11484 }
11369 } else {11485 } else {
11486 do_pungetc:
11370 pungetc();11487 pungetc();
11371 }11488 }
11372 if (dblquote || arinest)11489 if (dblquote || arinest)
@@ -11423,16 +11540,14 @@
11423 treatment to some slashes, and then push the string and11540 treatment to some slashes, and then push the string and
11424 reread it as input, interpreting it normally. */11541 reread it as input, interpreting it normally. */
11425 char *pout;11542 char *pout;
11426 int pc;
11427 size_t psavelen;11543 size_t psavelen;
11428 char *pstr;11544 char *pstr;
1142911545
11430
11431 STARTSTACKSTR(pout);11546 STARTSTACKSTR(pout);
11432 for (;;) {11547 for (;;) {
11433 if (needprompt) {11548 int pc;
11434 setprompt(2);11549
11435 }11550 setprompt_if(needprompt, 2);
11436 pc = pgetc();11551 pc = pgetc();
11437 switch (pc) {11552 switch (pc) {
11438 case '`':11553 case '`':
@@ -11442,8 +11557,7 @@
11442 pc = pgetc();11557 pc = pgetc();
11443 if (pc == '\n') {11558 if (pc == '\n') {
11444 g_parsefile->linno++;11559 g_parsefile->linno++;
11445 if (doprompt)11560 setprompt_if(doprompt, 2);
11446 setprompt(2);
11447 /*11561 /*
11448 * If eating a newline, avoid putting11562 * If eating a newline, avoid putting
11449 * the newline into the new character11563 * the newline into the new character
@@ -11606,9 +11720,7 @@
11606 tokpushback = 0;11720 tokpushback = 0;
11607 return lasttoken;11721 return lasttoken;
11608 }11722 }
11609 if (needprompt) {11723 setprompt_if(needprompt, 2);
11610 setprompt(2);
11611 }
11612 startlinno = g_parsefile->linno;11724 startlinno = g_parsefile->linno;
11613 for (;;) { /* until token or start of word found */11725 for (;;) { /* until token or start of word found */
11614 c = pgetc_fast();11726 c = pgetc_fast();
@@ -11625,8 +11737,7 @@
11625 break; /* return readtoken1(...) */11737 break; /* return readtoken1(...) */
11626 }11738 }
11627 startlinno = ++g_parsefile->linno;11739 startlinno = ++g_parsefile->linno;
11628 if (doprompt)11740 setprompt_if(doprompt, 2);
11629 setprompt(2);
11630 } else {11741 } else {
11631 const char *p;11742 const char *p;
1163211743
@@ -11672,9 +11783,7 @@
11672 tokpushback = 0;11783 tokpushback = 0;
11673 return lasttoken;11784 return lasttoken;
11674 }11785 }
11675 if (needprompt) {11786 setprompt_if(needprompt, 2);
11676 setprompt(2);
11677 }
11678 startlinno = g_parsefile->linno;11787 startlinno = g_parsefile->linno;
11679 for (;;) { /* until token or start of word found */11788 for (;;) { /* until token or start of word found */
11680 c = pgetc_fast();11789 c = pgetc_fast();
@@ -11690,8 +11799,7 @@
11690 case '\\':11799 case '\\':
11691 if (pgetc() == '\n') {11800 if (pgetc() == '\n') {
11692 startlinno = ++g_parsefile->linno;11801 startlinno = ++g_parsefile->linno;
11693 if (doprompt)11802 setprompt_if(doprompt, 2);
11694 setprompt(2);
11695 continue;11803 continue;
11696 }11804 }
11697 pungetc();11805 pungetc();
@@ -11817,8 +11925,7 @@
1181711925
11818 tokpushback = 0;11926 tokpushback = 0;
11819 doprompt = interact;11927 doprompt = interact;
11820 if (doprompt)11928 setprompt_if(doprompt, doprompt);
11821 setprompt(doprompt);
11822 needprompt = 0;11929 needprompt = 0;
11823 t = readtoken();11930 t = readtoken();
11824 if (t == TEOF)11931 if (t == TEOF)
@@ -11842,10 +11949,8 @@
11842 heredoclist = NULL;11949 heredoclist = NULL;
1184311950
11844 while (here) {11951 while (here) {
11845 if (needprompt) {11952 setprompt_if(needprompt, 2);
11846 setprompt(2);11953 readtoken1(pgetc(), here->here->type == NHERE ? SQSYNTAX : DQSYNTAX,
11847 }
11848 readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX,
11849 here->eofmark, here->striptabs);11954 here->eofmark, here->striptabs);
11850 n = stzalloc(sizeof(struct narg));11955 n = stzalloc(sizeof(struct narg));
11851 n->narg.type = NARG;11956 n->narg.type = NARG;
@@ -11936,7 +12041,6 @@
11936 p = grabstackstr(concat);12041 p = grabstackstr(concat);
11937 }12042 }
11938 evalstring(p, ~SKIPEVAL);12043 evalstring(p, ~SKIPEVAL);
11939
11940 }12044 }
11941 return exitstatus;12045 return exitstatus;
11942}12046}
@@ -12228,7 +12332,7 @@
12228 }12332 }
12229 if ((act & DO_NOFUNC)12333 if ((act & DO_NOFUNC)
12230 || !prefix(pathopt, "func")12334 || !prefix(pathopt, "func")
12231 ) { /* ignore unimplemented options */12335 ) { /* ignore unimplemented options */
12232 continue;12336 continue;
12233 }12337 }
12234 }12338 }
@@ -12743,7 +12847,7 @@
12743 /* bash re-enables SIGHUP which is SIG_IGNed on entry.12847 /* bash re-enables SIGHUP which is SIG_IGNed on entry.
12744 * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"12848 * Try: "trap '' HUP; bash; echo RET" and type "kill -HUP $$"
12745 */12849 */
12746 signal(SIGHUP, SIG_DFL);12850 signal(SIGHUP, SIG_DFL);
1274712851
12748 /* from var.c: */12852 /* from var.c: */
12749 {12853 {
@@ -12916,10 +13020,12 @@
12916 if (e == EXERROR)13020 if (e == EXERROR)
12917 exitstatus = 2;13021 exitstatus = 2;
12918 s = state;13022 s = state;
12919 if (e == EXEXIT || s == 0 || iflag == 0 || shlvl)13023 if (e == EXEXIT || s == 0 || iflag == 0 || shlvl) {
12920 exitshell();13024 exitshell();
12921 if (e == EXINT)13025 }
13026 if (e == EXINT) {
12922 outcslow('\n', stderr);13027 outcslow('\n', stderr);
13028 }
1292313029
12924 popstackmark(&smark);13030 popstackmark(&smark);
12925 FORCE_INT_ON; /* enable interrupts */13031 FORCE_INT_ON; /* enable interrupts */
@@ -13012,6 +13118,7 @@
13012 _mcleanup();13118 _mcleanup();
13013 }13119 }
13014#endif13120#endif
13121 TRACE(("End of main reached\n"));
13015 exitshell();13122 exitshell();
13016 /* NOTREACHED */13123 /* NOTREACHED */
13017}13124}
1301813125
=== modified file '.pc/applied-patches'
--- .pc/applied-patches 2011-02-23 03:14:46 +0000
+++ .pc/applied-patches 2011-05-27 16:11:32 +0000
@@ -1,31 +1,10 @@
1doc-man-name.patch
2shell-ash-export-HOME.patch1shell-ash-export-HOME.patch
3applets-fallback.patch2applets-fallback.patch
4version.patch3version.patch
5init-console.patch4init-console.patch
6strip.patch
7make_gen_build_files_skip_quilt.patch5make_gen_build_files_skip_quilt.patch
8readlink-use-xmalloc_realpath.patch
9mark-Linux-specific-configuration-options.patch
10init-loginutils-termios-portability-fixes.patch
11init-halt-portability-improvements.patch
12init-make-the-initial-TERM-value-configurable.patch
13libbb.h-add-device-names-for-Hurd-and-FreeBSD.patch
14mkdir-fix-p-on-FreeBSD.patch
15libbb-conditionalize-AF_-usage-in-error-reporting.patch
16tcpsvd-udpsvd-conditionalize-usage-of-SO_ORIGINAL_DS.patch
17less-remove-misguided-dependency-on-PLATFORM_LINUX.patch
18bootchartd-mounting-tmpfs-is-Linux-specific.patch
19vlock-disable-linux-console-calls-on-other-systems.patch
20cttyhack-serial-console-detection-is-Linux-specific.patch
21klogd-make-it-work-on-non-linux-systems.patch
22stty-sort-out-preprocessor-conditionals.patch
23update-scripts-kconfig-_shipped.patch
24blockdev.patch
25u-mount-FreeBSD-support.patch6u-mount-FreeBSD-support.patch
26swaponoff-FreeBSD-support.patch7swaponoff-FreeBSD-support.patch
27init-console-CRTSCTS.patch8dirname-basename-skip-doubledash.diff
28debian-changes-1:1.17.1-10
29test-bin.patch9test-bin.patch
30static-sh-alias.patch10static-sh-alias.patch
31grep-o-loop.patch
3211
=== removed directory '.pc/blockdev.patch'
=== removed directory '.pc/blockdev.patch/util-linux'
=== removed file '.pc/blockdev.patch/util-linux/blockdev.c'
=== removed directory '.pc/bootchartd-mounting-tmpfs-is-Linux-specific.patch'
=== removed directory '.pc/bootchartd-mounting-tmpfs-is-Linux-specific.patch/init'
=== removed file '.pc/bootchartd-mounting-tmpfs-is-Linux-specific.patch/init/bootchartd.c'
--- .pc/bootchartd-mounting-tmpfs-is-Linux-specific.patch/init/bootchartd.c 2010-08-03 06:42:39 +0000
+++ .pc/bootchartd-mounting-tmpfs-is-Linux-specific.patch/init/bootchartd.c 1970-01-01 00:00:00 +0000
@@ -1,443 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
4 */
5
6//config:config BOOTCHARTD
7//config: bool "bootchartd"
8//config: default y
9//config: depends on PLATFORM_LINUX
10//config: help
11//config: bootchartd is commonly used to profile the boot process
12//config: for the purpose of speeding it up. In this case, it is started
13//config: by the kernel as the init process. This is configured by adding
14//config: the init=/sbin/bootchartd option to the kernel command line.
15//config:
16//config: It can also be used to monitor the resource usage of a specific
17//config: application or the running system in general. In this case,
18//config: bootchartd is started interactively by running bootchartd start
19//config: and stopped using bootchartd stop.
20//config:
21//config:config FEATURE_BOOTCHARTD_BLOATED_HEADER
22//config: bool "Compatible, bloated header"
23//config: default y
24//config: depends on BOOTCHARTD
25//config: help
26//config: Create extended header file compatible with "big" bootchartd.
27//config: "Big" bootchartd is a shell script and it dumps some
28//config: "convenient" info int the header, such as:
29//config: title = Boot chart for `hostname` (`date`)
30//config: system.uname = `uname -srvm`
31//config: system.release = `cat /etc/DISTRO-release`
32//config: system.cpu = `grep '^model name' /proc/cpuinfo | head -1` ($cpucount)
33//config: system.kernel.options = `cat /proc/cmdline`
34//config: This data is not mandatory for bootchart graph generation,
35//config: and is considered bloat. Nevertheless, this option
36//config: makes bootchartd applet to dump a subset of it.
37//config:
38//config:config FEATURE_BOOTCHARTD_CONFIG_FILE
39//config: bool "Support bootchartd.conf"
40//config: default y
41//config: depends on BOOTCHARTD
42//config: help
43//config: Enable reading and parsing of $PWD/bootchartd.conf
44//config: and /etc/bootchartd.conf files.
45
46#include "libbb.h"
47/* After libbb.h, since it needs sys/types.h on some systems */
48#include <sys/utsname.h>
49#include <sys/mount.h>
50#ifndef MS_SILENT
51# define MS_SILENT (1 << 15)
52#endif
53#ifndef MNT_DETACH
54# define MNT_DETACH 0x00000002
55#endif
56
57#define BC_VERSION_STR "0.8"
58
59/* For debugging, set to 0:
60 * strace won't work with DO_SIGNAL_SYNC set to 1.
61 */
62#define DO_SIGNAL_SYNC 1
63
64
65//$PWD/bootchartd.conf and /etc/bootchartd.conf:
66//supported options:
67//# Sampling period (in seconds)
68//SAMPLE_PERIOD=0.2
69//
70//not yet supported:
71//# tmpfs size
72//# (32 MB should suffice for ~20 minutes worth of log data, but YMMV)
73//TMPFS_SIZE=32m
74//
75//# Whether to enable and store BSD process accounting information. The
76//# kernel needs to be configured to enable v3 accounting
77//# (CONFIG_BSD_PROCESS_ACCT_V3). accton from the GNU accounting utilities
78//# is also required.
79//PROCESS_ACCOUNTING="no"
80//
81//# Tarball for the various boot log files
82//BOOTLOG_DEST=/var/log/bootchart.tgz
83//
84//# Whether to automatically stop logging as the boot process completes.
85//# The logger will look for known processes that indicate bootup completion
86//# at a specific runlevel (e.g. gdm-binary, mingetty, etc.).
87//AUTO_STOP_LOGGER="yes"
88//
89//# Whether to automatically generate the boot chart once the boot logger
90//# completes. The boot chart will be generated in $AUTO_RENDER_DIR.
91//# Note that the bootchart package must be installed.
92//AUTO_RENDER="no"
93//
94//# Image format to use for the auto-generated boot chart
95//# (choose between png, svg and eps).
96//AUTO_RENDER_FORMAT="png"
97//
98//# Output directory for auto-generated boot charts
99//AUTO_RENDER_DIR="/var/log"
100
101
102/* Globals */
103struct globals {
104 char jiffy_line[COMMON_BUFSIZE];
105} FIX_ALIASING;
106#define G (*(struct globals*)&bb_common_bufsiz1)
107#define INIT_G() do { } while (0)
108
109static void dump_file(FILE *fp, const char *filename)
110{
111 int fd = open(filename, O_RDONLY);
112 if (fd >= 0) {
113 fputs(G.jiffy_line, fp);
114 fflush(fp);
115 bb_copyfd_eof(fd, fileno(fp));
116 close(fd);
117 fputc('\n', fp);
118 }
119}
120
121static int dump_procs(FILE *fp, int look_for_login_process)
122{
123 struct dirent *entry;
124 DIR *dir = opendir("/proc");
125 int found_login_process = 0;
126
127 fputs(G.jiffy_line, fp);
128 while ((entry = readdir(dir)) != NULL) {
129 char name[sizeof("/proc/%u/cmdline") + sizeof(int)*3];
130 int stat_fd;
131 unsigned pid = bb_strtou(entry->d_name, NULL, 10);
132 if (errno)
133 continue;
134
135 /* Android's version reads /proc/PID/cmdline and extracts
136 * non-truncated process name. Do we want to do that? */
137
138 sprintf(name, "/proc/%u/stat", pid);
139 stat_fd = open(name, O_RDONLY);
140 if (stat_fd >= 0) {
141 char *p;
142 char stat_line[4*1024];
143 int rd = safe_read(stat_fd, stat_line, sizeof(stat_line)-2);
144
145 close(stat_fd);
146 if (rd < 0)
147 continue;
148 stat_line[rd] = '\0';
149 p = strchrnul(stat_line, '\n');
150 *p++ = '\n';
151 *p = '\0';
152 fputs(stat_line, fp);
153 if (!look_for_login_process)
154 continue;
155 p = strchr(stat_line, '(');
156 if (!p)
157 continue;
158 p++;
159 strchrnul(p, ')')[0] = '\0';
160 /* Is it gdm, kdm or a getty? */
161 if (((p[0] == 'g' || p[0] == 'k' || p[0] == 'x') && p[1] == 'd' && p[2] == 'm')
162 || strstr(p, "getty")
163 ) {
164 found_login_process = 1;
165 }
166 }
167 }
168 closedir(dir);
169 fputc('\n', fp);
170 return found_login_process;
171}
172
173static char *make_tempdir(void)
174{
175 char template[] = "/tmp/bootchart.XXXXXX";
176 char *tempdir = xstrdup(mkdtemp(template));
177 if (!tempdir) {
178 /* /tmp is not writable (happens when we are used as init).
179 * Try to mount a tmpfs, them cd and lazily unmount it.
180 * Since we unmount it at once, we can mount it anywhere.
181 * Try a few locations which are likely ti exist.
182 */
183 static const char dirs[] = "/mnt\0""/tmp\0""/boot\0""/proc\0";
184 const char *try_dir = dirs;
185 while (mount("none", try_dir, "tmpfs", MS_SILENT, "size=16m") != 0) {
186 try_dir += strlen(try_dir) + 1;
187 if (!try_dir[0])
188 bb_perror_msg_and_die("can't %smount tmpfs", "");
189 }
190 //bb_error_msg("mounted tmpfs on %s", try_dir);
191 xchdir(try_dir);
192 if (umount2(try_dir, MNT_DETACH) != 0) {
193 bb_perror_msg_and_die("can't %smount tmpfs", "un");
194 }
195 } else {
196 xchdir(tempdir);
197 }
198 return tempdir;
199}
200
201static void do_logging(unsigned sample_period_us)
202{
203 //# Enable process accounting if configured
204 //if [ "$PROCESS_ACCOUNTING" = "yes" ]; then
205 // [ -e kernel_pacct ] || : > kernel_pacct
206 // accton kernel_pacct
207 //fi
208
209 FILE *proc_stat = xfopen("proc_stat.log", "w");
210 FILE *proc_diskstats = xfopen("proc_diskstats.log", "w");
211 //FILE *proc_netdev = xfopen("proc_netdev.log", "w");
212 FILE *proc_ps = xfopen("proc_ps.log", "w");
213 int look_for_login_process = (getppid() == 1);
214 unsigned count = 60*1000*1000 / sample_period_us; /* ~1 minute */
215
216 while (--count && !bb_got_signal) {
217 char *p;
218 int len = open_read_close("/proc/uptime", G.jiffy_line, sizeof(G.jiffy_line)-2);
219 if (len < 0)
220 goto wait_more;
221 /* /proc/uptime has format "NNNNNN.MM NNNNNNN.MM" */
222 /* we convert it to "NNNNNNMM\n" (using first value) */
223 G.jiffy_line[len] = '\0';
224 p = strchr(G.jiffy_line, '.');
225 if (!p)
226 goto wait_more;
227 while (isdigit(*++p))
228 p[-1] = *p;
229 p[-1] = '\n';
230 p[0] = '\0';
231
232 dump_file(proc_stat, "/proc/stat");
233 dump_file(proc_diskstats, "/proc/diskstats");
234 //dump_file(proc_netdev, "/proc/net/dev");
235 if (dump_procs(proc_ps, look_for_login_process)) {
236 /* dump_procs saw a getty or {g,k,x}dm
237 * stop logging in 2 seconds:
238 */
239 if (count > 2*1000*1000 / sample_period_us)
240 count = 2*1000*1000 / sample_period_us;
241 }
242 fflush_all();
243 wait_more:
244 usleep(sample_period_us);
245 }
246
247 // [ -e kernel_pacct ] && accton off
248}
249
250static void finalize(char *tempdir, const char *prog)
251{
252 //# Stop process accounting if configured
253 //local pacct=
254 //[ -e kernel_pacct ] && pacct=kernel_pacct
255
256 FILE *header_fp = xfopen("header", "w");
257
258 if (prog)
259 fprintf(header_fp, "profile.process = %s\n", prog);
260
261 fputs("version = "BC_VERSION_STR"\n", header_fp);
262 if (ENABLE_FEATURE_BOOTCHARTD_BLOATED_HEADER) {
263 char *hostname;
264 char *kcmdline;
265 time_t t;
266 struct tm tm_time;
267 /* x2 for possible localized weekday/month names */
268 char date_buf[sizeof("Mon Jun 21 05:29:03 CEST 2010") * 2];
269 struct utsname unamebuf;
270
271 hostname = safe_gethostname();
272 time(&t);
273 localtime_r(&t, &tm_time);
274 strftime(date_buf, sizeof(date_buf), "%a %b %e %H:%M:%S %Z %Y", &tm_time);
275 fprintf(header_fp, "title = Boot chart for %s (%s)\n", hostname, date_buf);
276 if (ENABLE_FEATURE_CLEAN_UP)
277 free(hostname);
278
279 uname(&unamebuf); /* never fails */
280 /* same as uname -srvm */
281 fprintf(header_fp, "system.uname = %s %s %s %s\n",
282 unamebuf.sysname,
283 unamebuf.release,
284 unamebuf.version,
285 unamebuf.machine
286 );
287
288 //system.release = `cat /etc/DISTRO-release`
289 //system.cpu = `grep '^model name' /proc/cpuinfo | head -1` ($cpucount)
290
291 kcmdline = xmalloc_open_read_close("/proc/cmdline", NULL);
292 /* kcmdline includes trailing "\n" */
293 fprintf(header_fp, "system.kernel.options = %s", kcmdline);
294 if (ENABLE_FEATURE_CLEAN_UP)
295 free(kcmdline);
296 }
297 fclose(header_fp);
298
299 /* Package log files */
300 system("tar -zcf /var/log/bootchart.tgz header *.log"); // + $pacct
301 /* Clean up (if we are not in detached tmpfs) */
302 if (tempdir) {
303 unlink("header");
304 unlink("proc_stat.log");
305 unlink("proc_diskstats.log");
306 //unlink("proc_netdev.log");
307 unlink("proc_ps.log");
308 rmdir(tempdir);
309 }
310
311 /* shell-based bootchartd tries to run /usr/bin/bootchart if $AUTO_RENDER=yes:
312 * /usr/bin/bootchart -o "$AUTO_RENDER_DIR" -f $AUTO_RENDER_FORMAT "$BOOTLOG_DEST"
313 */
314}
315
316//usage:#define bootchartd_trivial_usage
317//usage: "start [PROG ARGS]|stop|init"
318//usage:#define bootchartd_full_usage "\n\n"
319//usage: "Create /var/log/bootchart.tgz with boot chart data\n"
320//usage: "\nOptions:"
321//usage: "\nstart: start background logging; with PROG, run PROG, then kill logging with USR1"
322//usage: "\nstop: send USR1 to all bootchartd processes"
323//usage: "\ninit: start background logging; stop when getty/xdm is seen (for init scripts)"
324//usage: "\nUnder PID 1: as init, then exec $bootchart_init, /init, /sbin/init"
325
326int bootchartd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
327int bootchartd_main(int argc UNUSED_PARAM, char **argv)
328{
329 unsigned sample_period_us;
330 pid_t parent_pid, logger_pid;
331 smallint cmd;
332 enum {
333 CMD_STOP = 0,
334 CMD_START,
335 CMD_INIT,
336 CMD_PID1, /* used to mark pid 1 case */
337 };
338
339 INIT_G();
340
341 parent_pid = getpid();
342 if (argv[1]) {
343 cmd = index_in_strings("stop\0""start\0""init\0", argv[1]);
344 if (cmd < 0)
345 bb_show_usage();
346 if (cmd == CMD_STOP) {
347 pid_t *pidList = find_pid_by_name("bootchartd");
348 while (*pidList != 0) {
349 if (*pidList != parent_pid)
350 kill(*pidList, SIGUSR1);
351 pidList++;
352 }
353 return EXIT_SUCCESS;
354 }
355 } else {
356 if (parent_pid != 1)
357 bb_show_usage();
358 cmd = CMD_PID1;
359 }
360
361 /* Here we are in START, INIT or CMD_PID1 state */
362
363 /* Read config file: */
364 sample_period_us = 200 * 1000;
365 if (ENABLE_FEATURE_BOOTCHARTD_CONFIG_FILE) {
366 char* token[2];
367 parser_t *parser = config_open2("/etc/bootchartd.conf" + 5, fopen_for_read);
368 if (!parser)
369 parser = config_open2("/etc/bootchartd.conf", fopen_for_read);
370 while (config_read(parser, token, 2, 0, "#=", PARSE_NORMAL & ~PARSE_COLLAPSE)) {
371 if (strcmp(token[0], "SAMPLE_PERIOD") == 0 && token[1])
372 sample_period_us = atof(token[1]) * 1000000;
373 }
374 config_close(parser);
375 }
376 if ((int)sample_period_us <= 0)
377 sample_period_us = 1; /* prevent division by 0 */
378
379 /* Create logger child: */
380 logger_pid = fork_or_rexec(argv);
381
382 if (logger_pid == 0) { /* child */
383 char *tempdir;
384
385 bb_signals(0
386 + (1 << SIGUSR1)
387 + (1 << SIGUSR2)
388 + (1 << SIGTERM)
389 + (1 << SIGQUIT)
390 + (1 << SIGINT)
391 + (1 << SIGHUP)
392 , record_signo);
393
394 if (DO_SIGNAL_SYNC)
395 /* Inform parent that we are ready */
396 raise(SIGSTOP);
397
398 /* If we are started by kernel, PATH might be unset.
399 * In order to find "tar", let's set some sane PATH:
400 */
401 if (cmd == CMD_PID1 && !getenv("PATH"))
402 putenv((char*)bb_PATH_root_path);
403
404 tempdir = make_tempdir();
405 do_logging(sample_period_us);
406 finalize(tempdir, cmd == CMD_START ? argv[2] : NULL);
407 return EXIT_SUCCESS;
408 }
409
410 /* parent */
411
412 if (DO_SIGNAL_SYNC) {
413 /* Wait for logger child to set handlers, then unpause it.
414 * Otherwise with short-lived PROG (e.g. "bootchartd start true")
415 * we might send SIGUSR1 before logger sets its handler.
416 */
417 waitpid(logger_pid, NULL, WUNTRACED);
418 kill(logger_pid, SIGCONT);
419 }
420
421 if (cmd == CMD_PID1) {
422 char *bootchart_init = getenv("bootchart_init");
423 if (bootchart_init)
424 execl(bootchart_init, bootchart_init, NULL);
425 execl("/init", "init", NULL);
426 execl("/sbin/init", "init", NULL);
427 bb_perror_msg_and_die("can't execute '%s'", "/sbin/init");
428 }
429
430 if (cmd == CMD_START && argv[2]) { /* "start PROG ARGS" */
431 pid_t pid = xvfork();
432 if (pid == 0) { /* child */
433 argv += 2;
434 execvp(argv[0], argv);
435 bb_perror_msg_and_die("can't execute '%s'", argv[0]);
436 }
437 /* parent */
438 waitpid(pid, NULL, 0);
439 kill(logger_pid, SIGUSR1);
440 }
441
442 return EXIT_SUCCESS;
443}
4440
=== removed directory '.pc/cttyhack-serial-console-detection-is-Linux-specific.patch'
=== removed directory '.pc/cttyhack-serial-console-detection-is-Linux-specific.patch/shell'
=== removed file '.pc/cttyhack-serial-console-detection-is-Linux-specific.patch/shell/Config.src'
--- .pc/cttyhack-serial-console-detection-is-Linux-specific.patch/shell/Config.src 2010-08-03 06:42:39 +0000
+++ .pc/cttyhack-serial-console-detection-is-Linux-specific.patch/shell/Config.src 1970-01-01 00:00:00 +0000
@@ -1,402 +0,0 @@
1#
2# For a description of the syntax of this configuration file,
3# see scripts/kbuild/config-language.txt.
4#
5
6menu "Shells"
7
8INSERT
9
10config ASH
11 bool "ash"
12 default y
13 depends on !NOMMU
14 help
15 Tha 'ash' shell adds about 60k in the default configuration and is
16 the most complete and most pedantically correct shell included with
17 busybox. This shell is actually a derivative of the Debian 'dash'
18 shell (by Herbert Xu), which was created by porting the 'ash' shell
19 (written by Kenneth Almquist) from NetBSD.
20
21config ASH_BASH_COMPAT
22 bool "bash-compatible extensions"
23 default y
24 depends on ASH
25 help
26 Enable bash-compatible extensions.
27
28config ASH_JOB_CONTROL
29 bool "Job control"
30 default y
31 depends on ASH
32 help
33 Enable job control in the ash shell.
34
35config ASH_ALIAS
36 bool "alias support"
37 default y
38 depends on ASH
39 help
40 Enable alias support in the ash shell.
41
42config ASH_GETOPTS
43 bool "Builtin getopt to parse positional parameters"
44 default y
45 depends on ASH
46 help
47 Enable getopts builtin in the ash shell.
48
49config ASH_BUILTIN_ECHO
50 bool "Builtin version of 'echo'"
51 default y
52 depends on ASH
53 help
54 Enable support for echo, builtin to ash.
55
56config ASH_BUILTIN_PRINTF
57 bool "Builtin version of 'printf'"
58 default y
59 depends on ASH
60 help
61 Enable support for printf, builtin to ash.
62
63config ASH_BUILTIN_TEST
64 bool "Builtin version of 'test'"
65 default y
66 depends on ASH
67 help
68 Enable support for test, builtin to ash.
69
70config ASH_CMDCMD
71 bool "'command' command to override shell builtins"
72 default y
73 depends on ASH
74 help
75 Enable support for the ash 'command' builtin, which allows
76 you to run the specified command with the specified arguments,
77 even when there is an ash builtin command with the same name.
78
79config ASH_MAIL
80 bool "Check for new mail on interactive shells"
81 default n
82 depends on ASH
83 help
84 Enable "check for new mail" in the ash shell.
85
86config ASH_OPTIMIZE_FOR_SIZE
87 bool "Optimize for size instead of speed"
88 default y
89 depends on ASH
90 help
91 Compile ash for reduced size at the price of speed.
92
93config ASH_RANDOM_SUPPORT
94 bool "Pseudorandom generator and $RANDOM variable"
95 default y
96 depends on ASH
97 help
98 Enable pseudorandom generator and dynamic variable "$RANDOM".
99 Each read of "$RANDOM" will generate a new pseudorandom value.
100 You can reset the generator by using a specified start value.
101 After "unset RANDOM" the generator will switch off and this
102 variable will no longer have special treatment.
103
104config ASH_EXPAND_PRMT
105 bool "Expand prompt string"
106 default y
107 depends on ASH
108 help
109 "PS#" may contain volatile content, such as backquote commands.
110 This option recreates the prompt string from the environment
111 variable each time it is displayed.
112
113config HUSH
114 bool "hush"
115 default y
116 help
117 hush is a small shell (22k). It handles the normal flow control
118 constructs such as if/then/elif/else/fi, for/in/do/done, while loops,
119 case/esac. Redirections, here documents, $((arithmetic))
120 and functions are supported.
121
122 It will compile and work on no-mmu systems.
123
124 It does not handle select, aliases, brace expansion,
125 tilde expansion, &>file and >&file redirection of stdout+stderr.
126
127config HUSH_BASH_COMPAT
128 bool "bash-compatible extensions"
129 default y
130 depends on HUSH
131 help
132 Enable bash-compatible extensions.
133
134config HUSH_HELP
135 bool "help builtin"
136 default y
137 depends on HUSH
138 help
139 Enable help builtin in hush. Code size + ~1 kbyte.
140
141config HUSH_INTERACTIVE
142 bool "Interactive mode"
143 default y
144 depends on HUSH
145 help
146 Enable interactive mode (prompt and command editing).
147 Without this, hush simply reads and executes commands
148 from stdin just like a shell script from a file.
149 No prompt, no PS1/PS2 magic shell variables.
150
151config HUSH_JOB
152 bool "Job control"
153 default y
154 depends on HUSH_INTERACTIVE
155 help
156 Enable job control: Ctrl-Z backgrounds, Ctrl-C interrupts current
157 command (not entire shell), fg/bg builtins work. Without this option,
158 "cmd &" still works by simply spawning a process and immediately
159 prompting for next command (or executing next command in a script),
160 but no separate process group is formed.
161
162config HUSH_TICK
163 bool "Process substitution"
164 default y
165 depends on HUSH
166 help
167 Enable process substitution `command` and $(command) in hush.
168
169config HUSH_IF
170 bool "Support if/then/elif/else/fi"
171 default y
172 depends on HUSH
173 help
174 Enable if/then/elif/else/fi in hush.
175
176config HUSH_LOOPS
177 bool "Support for, while and until loops"
178 default y
179 depends on HUSH
180 help
181 Enable for, while and until loops in hush.
182
183config HUSH_CASE
184 bool "Support case ... esac statement"
185 default y
186 depends on HUSH
187 help
188 Enable case ... esac statement in hush. +400 bytes.
189
190config HUSH_FUNCTIONS
191 bool "Support funcname() { commands; } syntax"
192 default y
193 depends on HUSH
194 help
195 Enable support for shell functions in hush. +800 bytes.
196
197config HUSH_LOCAL
198 bool "Support local builtin"
199 default y
200 depends on HUSH_FUNCTIONS
201 help
202 Enable support for local variables in functions.
203
204config HUSH_EXPORT_N
205 bool "Support export '-n' option"
206 default y
207 depends on HUSH
208 help
209 Enable support for export '-n' option in hush. It is a bash extension.
210
211config HUSH_RANDOM_SUPPORT
212 bool "Pseudorandom generator and $RANDOM variable"
213 default y
214 depends on HUSH
215 help
216 Enable pseudorandom generator and dynamic variable "$RANDOM".
217 Each read of "$RANDOM" will generate a new pseudorandom value.
218
219
220choice
221 prompt "Choose which shell is aliased to 'sh' name"
222 default FEATURE_SH_IS_ASH
223 help
224 Choose which shell you want to be executed by 'sh' alias.
225 The ash shell is the most bash compatible and full featured one.
226
227# note: cannot use "select ASH" here, it breaks "make allnoconfig"
228config FEATURE_SH_IS_ASH
229 depends on ASH
230 bool "ash"
231 depends on !NOMMU
232
233config FEATURE_SH_IS_HUSH
234 depends on HUSH
235 bool "hush"
236
237config FEATURE_SH_IS_NONE
238 bool "none"
239
240endchoice
241
242choice
243 prompt "Choose which shell is aliased to 'bash' name"
244 default FEATURE_BASH_IS_NONE
245 help
246 Choose which shell you want to be executed by 'bash' alias.
247 The ash shell is the most bash compatible and full featured one.
248
249 Note that selecting this option does not switch on any bash
250 compatibility code. It merely makes it possible to install
251 /bin/bash (sym)link and run scripts which start with
252 #!/bin/bash line.
253
254 Many systems use it in scripts which use bash-specific features,
255 even simple ones like $RANDOM. Without this option, busybox
256 can't be used for running them because it won't recongnize
257 "bash" as a supported applet name.
258
259config FEATURE_BASH_IS_ASH
260 depends on ASH
261 bool "ash"
262 depends on !NOMMU
263
264config FEATURE_BASH_IS_HUSH
265 depends on HUSH
266 bool "hush"
267
268config FEATURE_BASH_IS_NONE
269 bool "none"
270
271endchoice
272
273
274config LASH
275 bool "lash (deprecated: aliased to hush)"
276 default n
277 select HUSH
278 help
279 lash is deprecated and will be removed, please migrate to hush.
280
281config MSH
282 bool "msh (deprecated: please use hush)"
283 default n
284 select HUSH
285 help
286 msh is deprecated and will be removed, please migrate to hush.
287 If there is a feature msh has but hush does not, please let us know.
288
289# The minix shell (adds just 30k) is quite complete and handles things
290# like for/do/done, case/esac and all the things you expect a Bourne
291# shell to do. It is not always pedantically correct about Bourne
292# shell grammar (try running the shell testscript "tests/sh.testcases"
293# on it and compare vs bash) but for most things it works quite well.
294# It uses only vfork, so it can be used on uClinux systems.
295
296
297config SH_MATH_SUPPORT
298 bool "POSIX math support"
299 default y
300 depends on ASH || HUSH
301 help
302 Enable math support in the shell via $((...)) syntax.
303
304config SH_MATH_SUPPORT_64
305 bool "Extend POSIX math support to 64 bit"
306 default y
307 depends on SH_MATH_SUPPORT
308 help
309 Enable 64-bit math support in the shell. This will make the shell
310 slightly larger, but will allow computation with very large numbers.
311 This is not in POSIX, so do not rely on this in portable code.
312
313config FEATURE_SH_EXTRA_QUIET
314 bool "Hide message on interactive shell startup"
315 default y
316 depends on HUSH || ASH
317 help
318 Remove the busybox introduction when starting a shell.
319
320config FEATURE_SH_STANDALONE
321 bool "Standalone shell"
322 default n
323 depends on (HUSH || ASH) && FEATURE_PREFER_APPLETS
324 help
325 This option causes busybox shells to use busybox applets
326 in preference to executables in the PATH whenever possible. For
327 example, entering the command 'ifconfig' into the shell would cause
328 busybox to use the ifconfig busybox applet. Specifying the fully
329 qualified executable name, such as '/sbin/ifconfig' will still
330 execute the /sbin/ifconfig executable on the filesystem. This option
331 is generally used when creating a statically linked version of busybox
332 for use as a rescue shell, in the event that you screw up your system.
333
334 This is implemented by re-execing /proc/self/exe (typically)
335 with right parameters. Some selected applets ("NOFORK" applets)
336 can even be executed without creating new process.
337 Instead, busybox will call <applet>_main() internally.
338
339 However, this causes problems in chroot jails without mounted /proc
340 and with ps/top (command name can be shown as 'exe' for applets
341 started this way).
342# untrue?
343# Note that this will *also* cause applets to take precedence
344# over shell builtins of the same name. So turning this on will
345# eliminate any performance gained by turning on the builtin "echo"
346# and "test" commands in ash.
347# untrue?
348# Note that when using this option, the shell will attempt to directly
349# run '/bin/busybox'. If you do not have the busybox binary sitting in
350# that exact location with that exact name, this option will not work at
351# all.
352
353config FEATURE_SH_NOFORK
354 bool "Run 'nofork' applets directly"
355 default n
356 depends on (HUSH || ASH) && FEATURE_PREFER_APPLETS
357 help
358 This option causes busybox shells [currently only ash]
359 to not execute typical fork/exec/wait sequence, but call <applet>_main
360 directly, if possible. (Sometimes it is not possible: for example,
361 this is not possible in pipes).
362
363 This will be done only for some applets (those which are marked
364 NOFORK in include/applets.h).
365
366 This may significantly speed up some shell scripts.
367
368 This feature is relatively new. Use with care.
369
370config CTTYHACK
371 bool "cttyhack"
372 default y
373 depends on PLATFORM_LINUX
374 help
375 One common problem reported on the mailing list is "can't access tty;
376 job control turned off" error message which typically appears when
377 one tries to use shell with stdin/stdout opened to /dev/console.
378 This device is special - it cannot be a controlling tty.
379
380 Proper solution is to use correct device instead of /dev/console.
381
382 cttyhack provides "quick and dirty" solution to this problem.
383 It analyzes stdin with various ioctls, trying to determine whether
384 it is a /dev/ttyN or /dev/ttySN (virtual terminal or serial line).
385 If it detects one, it closes stdin/out/err and reopens that device.
386 Then it executes given program. Opening the device will make
387 that device a controlling tty. This may require cttyhack
388 to be a session leader.
389
390 Example for /etc/inittab (for busybox init):
391
392 ::respawn:/bin/cttyhack /bin/sh
393
394 Giving controlling tty to shell running with PID 1:
395
396 $ exec cttyhack sh
397
398 Starting an interactive shell from boot shell script:
399
400 setsid cttyhack sh
401
402endmenu
4030
=== removed file '.pc/cttyhack-serial-console-detection-is-Linux-specific.patch/shell/cttyhack.c'
--- .pc/cttyhack-serial-console-detection-is-Linux-specific.patch/shell/cttyhack.c 2010-08-03 06:42:39 +0000
+++ .pc/cttyhack-serial-console-detection-is-Linux-specific.patch/shell/cttyhack.c 1970-01-01 00:00:00 +0000
@@ -1,85 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Licensed under GPLv2
4 *
5 * Copyright (c) 2007 Denys Vlasenko <vda.linux@googlemail.com>
6 */
7#include "libbb.h"
8
9/* From <linux/vt.h> */
10struct vt_stat {
11 unsigned short v_active; /* active vt */
12 unsigned short v_signal; /* signal to send */
13 unsigned short v_state; /* vt bitmask */
14};
15enum { VT_GETSTATE = 0x5603 }; /* get global vt state info */
16
17/* From <linux/serial.h> */
18struct serial_struct {
19 int type;
20 int line;
21 unsigned int port;
22 int irq;
23 int flags;
24 int xmit_fifo_size;
25 int custom_divisor;
26 int baud_base;
27 unsigned short close_delay;
28 char io_type;
29 char reserved_char[1];
30 int hub6;
31 unsigned short closing_wait; /* time to wait before closing */
32 unsigned short closing_wait2; /* no longer used... */
33 unsigned char *iomem_base;
34 unsigned short iomem_reg_shift;
35 unsigned int port_high;
36 unsigned long iomap_base; /* cookie passed into ioremap */
37 int reserved[1];
38};
39
40int cttyhack_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
41int cttyhack_main(int argc UNUSED_PARAM, char **argv)
42{
43 int fd;
44 char console[sizeof(int)*3 + 16];
45 union {
46 struct vt_stat vt;
47 struct serial_struct sr;
48 char paranoia[sizeof(struct serial_struct) * 3];
49 } u;
50
51 if (!*++argv) {
52 bb_show_usage();
53 }
54
55 strcpy(console, "/dev/tty");
56 fd = open(console, O_RDWR);
57 if (fd >= 0) {
58 /* We already have ctty, nothing to do */
59 close(fd);
60 } else {
61 /* We don't have ctty (or don't have "/dev/tty" node...) */
62 if (ioctl(0, TIOCGSERIAL, &u.sr) == 0) {
63 /* this is a serial console */
64 sprintf(console + 8, "S%d", u.sr.line);
65 } else if (ioctl(0, VT_GETSTATE, &u.vt) == 0) {
66 /* this is linux virtual tty */
67 sprintf(console + 8, "S%d" + 1, u.vt.v_active);
68 }
69 if (console[8]) {
70 fd = xopen(console, O_RDWR);
71 //bb_error_msg("switching to '%s'", console);
72 dup2(fd, 0);
73 dup2(fd, 1);
74 dup2(fd, 2);
75 while (fd > 2)
76 close(fd--);
77 /* Some other session may have it as ctty,
78 * steal it from them:
79 */
80 ioctl(0, TIOCSCTTY, 1);
81 }
82 }
83
84 BB_EXECVP_or_die(argv);
85}
860
=== removed directory '.pc/debian-changes-1:1.17.1-10'
=== removed directory '.pc/debian-changes-1:1.17.1-10/busybox-1.17.1'
=== removed file '.pc/debian-changes-1:1.17.1-10/busybox-1.17.1/.indent.pro'
=== added directory '.pc/dirname-basename-skip-doubledash.diff'
=== added directory '.pc/dirname-basename-skip-doubledash.diff/coreutils'
=== added file '.pc/dirname-basename-skip-doubledash.diff/coreutils/basename.c'
--- .pc/dirname-basename-skip-doubledash.diff/coreutils/basename.c 1970-01-01 00:00:00 +0000
+++ .pc/dirname-basename-skip-doubledash.diff/coreutils/basename.c 2011-05-27 16:11:32 +0000
@@ -0,0 +1,61 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini basename implementation for busybox
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 */
9
10/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org)
11 *
12 * Changes:
13 * 1) Now checks for too many args. Need at least one and at most two.
14 * 2) Don't check for options, as per SUSv3.
15 * 3) Save some space by using strcmp(). Calling strncmp() here was silly.
16 */
17
18/* BB_AUDIT SUSv3 compliant */
19/* http://www.opengroup.org/onlinepubs/007904975/utilities/basename.html */
20
21//kbuild:lib-$(CONFIG_BASENAME) += basename.o
22
23//config:config BASENAME
24//config: bool "basename"
25//config: default y
26//config: help
27//config: basename is used to strip the directory and suffix from filenames,
28//config: leaving just the filename itself. Enable this option if you wish
29//config: to enable the 'basename' utility.
30
31#include "libbb.h"
32
33/* This is a NOFORK applet. Be very careful! */
34
35int basename_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
36int basename_main(int argc, char **argv)
37{
38 size_t m, n;
39 char *s;
40
41 if ((unsigned)(argc-2) >= 2) {
42 bb_show_usage();
43 }
44
45 /* It should strip slash: /abc/def/ -> def */
46 s = bb_get_last_path_component_strip(*++argv);
47
48 m = strlen(s);
49 if (*++argv) {
50 n = strlen(*argv);
51 if ((m > n) && (strcmp(s+m-n, *argv) == 0)) {
52 m -= n;
53 /*s[m] = '\0'; - redundant */
54 }
55 }
56
57 /* puts(s) will do, but we can do without stdio this way: */
58 s[m++] = '\n';
59 /* NB: != is correct here: */
60 return full_write(STDOUT_FILENO, s, m) != (ssize_t)m;
61}
062
=== added file '.pc/dirname-basename-skip-doubledash.diff/coreutils/dirname.c'
--- .pc/dirname-basename-skip-doubledash.diff/coreutils/dirname.c 1970-01-01 00:00:00 +0000
+++ .pc/dirname-basename-skip-doubledash.diff/coreutils/dirname.c 2011-05-27 16:11:32 +0000
@@ -0,0 +1,22 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini dirname implementation for busybox
4 *
5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
6 *
7 * Licensed under GPLv2 or later, see file LICENSE in this source tree.
8 */
9
10/* BB_AUDIT SUSv3 compliant */
11/* http://www.opengroup.org/onlinepubs/007904975/utilities/dirname.html */
12
13#include "libbb.h"
14
15/* This is a NOFORK applet. Be very careful! */
16
17int dirname_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
18int dirname_main(int argc UNUSED_PARAM, char **argv)
19{
20 puts(dirname(single_argv(argv)));
21 return fflush_all();
22}
023
=== removed directory '.pc/doc-man-name.patch'
=== removed file '.pc/doc-man-name.patch/Makefile.custom'
--- .pc/doc-man-name.patch/Makefile.custom 2010-08-03 06:42:39 +0000
+++ .pc/doc-man-name.patch/Makefile.custom 1970-01-01 00:00:00 +0000
@@ -1,177 +0,0 @@
1# ==========================================================================
2# Build system
3# ==========================================================================
4
5busybox.links: $(srctree)/applets/busybox.mkll $(objtree)/include/autoconf.h include/applets.h
6 $(Q)-$(SHELL) $^ >$@
7
8.PHONY: install
9ifeq ($(CONFIG_INSTALL_APPLET_SYMLINKS),y)
10INSTALL_OPTS:= --symlinks
11endif
12ifeq ($(CONFIG_INSTALL_APPLET_HARDLINKS),y)
13INSTALL_OPTS:= --hardlinks
14endif
15ifeq ($(CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS),y)
16ifeq ($(CONFIG_INSTALL_SH_APPLET_SYMLINK),y)
17INSTALL_OPTS:= --sw-sh-sym
18endif
19ifeq ($(CONFIG_INSTALL_SH_APPLET_HARDLINK),y)
20INSTALL_OPTS:= --sw-sh-hard
21endif
22ifeq ($(CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER),y)
23INSTALL_OPTS:= --scriptwrapper
24endif
25endif
26install: $(srctree)/applets/install.sh busybox busybox.links
27 $(Q)DO_INSTALL_LIBS="$(strip $(LIBBUSYBOX_SONAME) $(DO_INSTALL_LIBS))" \
28 $(SHELL) $< $(CONFIG_PREFIX) $(INSTALL_OPTS)
29ifeq ($(strip $(CONFIG_FEATURE_SUID)),y)
30 @echo
31 @echo
32 @echo --------------------------------------------------
33 @echo You will probably need to make your busybox binary
34 @echo setuid root to ensure all configured applets will
35 @echo work properly.
36 @echo --------------------------------------------------
37 @echo
38endif
39
40uninstall: busybox.links
41 rm -f $(CONFIG_PREFIX)/bin/busybox
42 for i in `cat busybox.links` ; do rm -f $(CONFIG_PREFIX)$$i; done
43ifneq ($(strip $(DO_INSTALL_LIBS)),n)
44 for i in $(LIBBUSYBOX_SONAME) $(DO_INSTALL_LIBS); do \
45 rm -f $(CONFIG_PREFIX)$$i; \
46 done
47endif
48
49# Not very elegant: copies testsuite to objdir...
50# (cp -pPR is POSIX-compliant (cp -dpR or cp -a would not be))
51.PHONY: check
52.PHONY: test
53check test: busybox busybox.links
54 test -d $(objtree)/testsuite || cp -pPR $(srctree)/testsuite $(objtree)
55 bindir=$(objtree) srcdir=$(srctree)/testsuite \
56 $(SHELL) -c "cd $(objtree)/testsuite && $(srctree)/testsuite/runtest $(if $(KBUILD_VERBOSE:0=),-v)"
57
58.PHONY: release
59release: distclean
60 cd ..; \
61 rm -r -f busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION); \
62 cp -pPR busybox busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) && { \
63 find busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ -type d \
64 -name .svn \
65 -print \
66 -exec rm -r -f {} \; ; \
67 find busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ -type d \
68 -name .git \
69 -print \
70 -exec rm -r -f {} \; ; \
71 find busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ -type f \
72 -name .\#* \
73 -print \
74 -exec rm -f {} \; ; \
75 tar -czf busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION).tar.gz \
76 busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ ; }
77
78.PHONY: checkhelp
79checkhelp:
80 $(Q)$(srctree)/scripts/checkhelp.awk \
81 $(patsubst %,$(srctree)/%,$(wildcard $(patsubst %,%/Config.in,$(busybox-dirs) ./)))
82
83.PHONY: sizes
84sizes: busybox_unstripped
85 $(NM) --size-sort $(<)
86
87.PHONY: bloatcheck
88bloatcheck: busybox_old busybox_unstripped
89 @$(srctree)/scripts/bloat-o-meter busybox_old busybox_unstripped
90 @$(CROSS_COMPILE)size busybox_old busybox_unstripped
91
92.PHONY: baseline
93baseline: busybox_unstripped
94 @mv busybox_unstripped busybox_old
95
96.PHONY: objsizes
97objsizes: busybox_unstripped
98 $(srctree)/scripts/objsizes
99
100.PHONY: stksizes
101stksizes: busybox_unstripped
102 $(CROSS_COMPILE)objdump -d busybox_unstripped | $(srctree)/scripts/checkstack.pl $(ARCH) | uniq
103
104.PHONY: bigdata
105bigdata: busybox_unstripped
106 $(CROSS_COMPILE)nm --size-sort busybox_unstripped | grep -vi ' [trw] '
107
108# Documentation Targets
109.PHONY: doc
110doc: docs/busybox.pod docs/BusyBox.txt docs/BusyBox.1 docs/BusyBox.html
111
112# FIXME: Doesn't belong here
113 cmd_doc =
114 quiet_cmd_doc = $(Q)echo " DOC $(@F)"
115silent_cmd_doc =
116disp_doc = $($(quiet)cmd_doc)
117
118# sed adds newlines after "Options:" etc,
119# this is needed in order to get good BusyBox.{1,txt,html}
120docs/busybox.pod: $(srctree)/docs/busybox_header.pod \
121 include/usage.h \
122 $(srctree)/docs/busybox_footer.pod \
123 applets/usage_pod
124 $(disp_doc)
125 $(Q)-mkdir -p docs
126 $(Q)-( \
127 cat $(srctree)/docs/busybox_header.pod; \
128 applets/usage_pod | sed 's/^[A-Za-z][A-Za-z ]*[a-z]:$$/&\n/'; \
129 cat $(srctree)/docs/busybox_footer.pod; \
130 ) > docs/busybox.pod
131
132docs/BusyBox.txt: docs/busybox.pod
133 $(disp_doc)
134 $(Q)-mkdir -p docs
135 $(Q)-pod2text $< > $@
136
137docs/BusyBox.1: docs/busybox.pod
138 $(disp_doc)
139 $(Q)-mkdir -p docs
140 $(Q)-pod2man --center=BusyBox --release="version $(KERNELVERSION)" $< > $@
141
142docs/BusyBox.html: docs/busybox.net/BusyBox.html
143 $(disp_doc)
144 $(Q)-mkdir -p docs
145 $(Q)-rm -f docs/BusyBox.html
146 $(Q)-cp docs/busybox.net/BusyBox.html docs/BusyBox.html
147
148docs/busybox.net/BusyBox.html: docs/busybox.pod
149 $(Q)-mkdir -p docs/busybox.net
150 $(Q)-pod2html --noindex $< > $@
151 $(Q)-rm -f pod2htm*
152
153# documentation, cross-reference
154# Modern distributions already ship synopsis packages (e.g. debian)
155# If you have an old distribution go to http://synopsis.fresco.org/
156syn_tgt = $(wildcard $(patsubst %,%/*.c,$(busybox-alldirs)))
157syn = $(patsubst %.c, %.syn, $(syn_tgt))
158
159comma:= ,
160brace_open:= (
161brace_close:= )
162
163SYN_CPPFLAGS := $(strip $(CPPFLAGS) $(EXTRA_CPPFLAGS))
164SYN_CPPFLAGS := $(subst $(brace_open),\$(brace_open),$(SYN_CPPFLAGS))
165SYN_CPPFLAGS := $(subst $(brace_close),\$(brace_close),$(SYN_CPPFLAGS))
166#SYN_CPPFLAGS := $(subst ",\",$(SYN_CPPFLAGS))
167#")
168#SYN_CPPFLAGS := [$(patsubst %,'%'$(comma),$(SYN_CPPFLAGS))'']
169
170%.syn: %.c
171 synopsis -p C -l Comments.SSDFilter,Comments.Previous -Wp,preprocess=True,cppflags="'$(SYN_CPPFLAGS)'" -o $@ $<
172
173.PHONY: html
174html: $(syn)
175 synopsis -f HTML -Wf,title="'BusyBox Documentation'" -o $@ $^
176
177-include $(srctree)/Makefile.local
1780
=== removed directory '.pc/grep-o-loop.patch'
=== removed directory '.pc/grep-o-loop.patch/findutils'
=== removed file '.pc/grep-o-loop.patch/findutils/grep.c'
--- .pc/grep-o-loop.patch/findutils/grep.c 2010-10-13 11:03:32 +0000
+++ .pc/grep-o-loop.patch/findutils/grep.c 1970-01-01 00:00:00 +0000
@@ -1,771 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini grep implementation for busybox using libc regex.
4 *
5 * Copyright (C) 1999,2000,2001 by Lineo, inc. and Mark Whitley
6 * Copyright (C) 1999,2000,2001 by Mark Whitley <markw@codepoet.org>
7 *
8 * Licensed under the GPL v2 or later, see the file LICENSE in this tarball.
9 */
10/* BB_AUDIT SUSv3 defects - unsupported option -x "match whole line only". */
11/* BB_AUDIT GNU defects - always acts as -a. */
12/* http://www.opengroup.org/onlinepubs/007904975/utilities/grep.html */
13/*
14 * 2004,2006 (C) Vladimir Oleynik <dzo@simtreas.ru> -
15 * correction "-e pattern1 -e pattern2" logic and more optimizations.
16 * precompiled regex
17 *
18 * (C) 2006 Jac Goudsmit added -o option
19 */
20
21//applet:IF_GREP(APPLET(grep, _BB_DIR_BIN, _BB_SUID_DROP))
22//applet:IF_FEATURE_GREP_EGREP_ALIAS(APPLET_ODDNAME(egrep, grep, _BB_DIR_BIN, _BB_SUID_DROP, egrep))
23//applet:IF_FEATURE_GREP_FGREP_ALIAS(APPLET_ODDNAME(fgrep, grep, _BB_DIR_BIN, _BB_SUID_DROP, fgrep))
24
25//kbuild:lib-$(CONFIG_GREP) += grep.o
26
27//config:config GREP
28//config: bool "grep"
29//config: default y
30//config: help
31//config: grep is used to search files for a specified pattern.
32//config:
33//config:config FEATURE_GREP_EGREP_ALIAS
34//config: bool "Enable extended regular expressions (egrep & grep -E)"
35//config: default y
36//config: depends on GREP
37//config: help
38//config: Enabled support for extended regular expressions. Extended
39//config: regular expressions allow for alternation (foo|bar), grouping,
40//config: and various repetition operators.
41//config:
42//config:config FEATURE_GREP_FGREP_ALIAS
43//config: bool "Alias fgrep to grep -F"
44//config: default y
45//config: depends on GREP
46//config: help
47//config: fgrep sees the search pattern as a normal string rather than
48//config: regular expressions.
49//config: grep -F always works, this just creates the fgrep alias.
50//config:
51//config:config FEATURE_GREP_CONTEXT
52//config: bool "Enable before and after context flags (-A, -B and -C)"
53//config: default y
54//config: depends on GREP
55//config: help
56//config: Print the specified number of leading (-B) and/or trailing (-A)
57//config: context surrounding our matching lines.
58//config: Print the specified number of context lines (-C).
59
60#include "libbb.h"
61#include "xregex.h"
62
63
64/* options */
65//usage:#define grep_trivial_usage
66//usage: "[-HhnlLoqvsriw"
67//usage: "F"
68//usage: IF_FEATURE_GREP_EGREP_ALIAS("E")
69//usage: IF_EXTRA_COMPAT("z")
70//usage: "] [-m N] "
71//usage: IF_FEATURE_GREP_CONTEXT("[-A/B/C N] ")
72//usage: "PATTERN/-e PATTERN.../-f FILE [FILE]..."
73//usage:#define grep_full_usage "\n\n"
74//usage: "Search for PATTERN in FILEs (or stdin)\n"
75//usage: "\nOptions:"
76//usage: "\n -H Add 'filename:' prefix"
77//usage: "\n -h Do not add 'filename:' prefix"
78//usage: "\n -n Add 'line_no:' prefix"
79//usage: "\n -l Show only names of files that match"
80//usage: "\n -L Show only names of files that don't match"
81//usage: "\n -c Show only count of matching lines"
82//usage: "\n -o Show only the matching part of line"
83//usage: "\n -q Quiet. Return 0 if PATTERN is found, 1 otherwise"
84//usage: "\n -v Select non-matching lines"
85//usage: "\n -s Suppress open and read errors"
86//usage: "\n -r Recurse"
87//usage: "\n -i Ignore case"
88//usage: "\n -w Match whole words only"
89//usage: "\n -F PATTERN is a literal (not regexp)"
90//usage: IF_FEATURE_GREP_EGREP_ALIAS(
91//usage: "\n -E PATTERN is an extended regexp"
92//usage: )
93//usage: IF_EXTRA_COMPAT(
94//usage: "\n -z Input is NUL terminated"
95//usage: )
96//usage: "\n -m N Match up to N times per file"
97//usage: IF_FEATURE_GREP_CONTEXT(
98//usage: "\n -A N Print N lines of trailing context"
99//usage: "\n -B N Print N lines of leading context"
100//usage: "\n -C N Same as '-A N -B N'"
101//usage: )
102//usage: "\n -e PTRN Pattern to match"
103//usage: "\n -f FILE Read pattern from file"
104//usage:
105//usage:#define grep_example_usage
106//usage: "$ grep root /etc/passwd\n"
107//usage: "root:x:0:0:root:/root:/bin/bash\n"
108//usage: "$ grep ^[rR]oo. /etc/passwd\n"
109//usage: "root:x:0:0:root:/root:/bin/bash\n"
110//usage:
111//usage:#define egrep_trivial_usage NOUSAGE_STR
112//usage:#define egrep_full_usage ""
113//usage:#define fgrep_trivial_usage NOUSAGE_STR
114//usage:#define fgrep_full_usage ""
115
116#define OPTSTR_GREP \
117 "lnqvscFiHhe:f:Lorm:w" \
118 IF_FEATURE_GREP_CONTEXT("A:B:C:") \
119 IF_FEATURE_GREP_EGREP_ALIAS("E") \
120 IF_EXTRA_COMPAT("z") \
121 "aI"
122/* ignored: -a "assume all files to be text" */
123/* ignored: -I "assume binary files have no matches" */
124enum {
125 OPTBIT_l, /* list matched file names only */
126 OPTBIT_n, /* print line# */
127 OPTBIT_q, /* quiet - exit(EXIT_SUCCESS) of first match */
128 OPTBIT_v, /* invert the match, to select non-matching lines */
129 OPTBIT_s, /* suppress errors about file open errors */
130 OPTBIT_c, /* count matches per file (suppresses normal output) */
131 OPTBIT_F, /* literal match */
132 OPTBIT_i, /* case-insensitive */
133 OPTBIT_H, /* force filename display */
134 OPTBIT_h, /* inhibit filename display */
135 OPTBIT_e, /* -e PATTERN */
136 OPTBIT_f, /* -f FILE_WITH_PATTERNS */
137 OPTBIT_L, /* list unmatched file names only */
138 OPTBIT_o, /* show only matching parts of lines */
139 OPTBIT_r, /* recurse dirs */
140 OPTBIT_m, /* -m MAX_MATCHES */
141 OPTBIT_w, /* -w whole word match */
142 IF_FEATURE_GREP_CONTEXT( OPTBIT_A ,) /* -A NUM: after-match context */
143 IF_FEATURE_GREP_CONTEXT( OPTBIT_B ,) /* -B NUM: before-match context */
144 IF_FEATURE_GREP_CONTEXT( OPTBIT_C ,) /* -C NUM: -A and -B combined */
145 IF_FEATURE_GREP_EGREP_ALIAS(OPTBIT_E ,) /* extended regexp */
146 IF_EXTRA_COMPAT( OPTBIT_z ,) /* input is NUL terminated */
147 OPT_l = 1 << OPTBIT_l,
148 OPT_n = 1 << OPTBIT_n,
149 OPT_q = 1 << OPTBIT_q,
150 OPT_v = 1 << OPTBIT_v,
151 OPT_s = 1 << OPTBIT_s,
152 OPT_c = 1 << OPTBIT_c,
153 OPT_F = 1 << OPTBIT_F,
154 OPT_i = 1 << OPTBIT_i,
155 OPT_H = 1 << OPTBIT_H,
156 OPT_h = 1 << OPTBIT_h,
157 OPT_e = 1 << OPTBIT_e,
158 OPT_f = 1 << OPTBIT_f,
159 OPT_L = 1 << OPTBIT_L,
160 OPT_o = 1 << OPTBIT_o,
161 OPT_r = 1 << OPTBIT_r,
162 OPT_m = 1 << OPTBIT_m,
163 OPT_w = 1 << OPTBIT_w,
164 OPT_A = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_A)) + 0,
165 OPT_B = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_B)) + 0,
166 OPT_C = IF_FEATURE_GREP_CONTEXT( (1 << OPTBIT_C)) + 0,
167 OPT_E = IF_FEATURE_GREP_EGREP_ALIAS((1 << OPTBIT_E)) + 0,
168 OPT_z = IF_EXTRA_COMPAT( (1 << OPTBIT_z)) + 0,
169};
170
171#define PRINT_FILES_WITH_MATCHES (option_mask32 & OPT_l)
172#define PRINT_LINE_NUM (option_mask32 & OPT_n)
173#define BE_QUIET (option_mask32 & OPT_q)
174#define SUPPRESS_ERR_MSGS (option_mask32 & OPT_s)
175#define PRINT_MATCH_COUNTS (option_mask32 & OPT_c)
176#define FGREP_FLAG (option_mask32 & OPT_F)
177#define PRINT_FILES_WITHOUT_MATCHES (option_mask32 & OPT_L)
178#define NUL_DELIMITED (option_mask32 & OPT_z)
179
180struct globals {
181 int max_matches;
182#if !ENABLE_EXTRA_COMPAT
183 int reflags;
184#else
185 RE_TRANSLATE_TYPE case_fold; /* RE_TRANSLATE_TYPE is [[un]signed] char* */
186#endif
187 smalluint invert_search;
188 smalluint print_filename;
189 smalluint open_errors;
190#if ENABLE_FEATURE_GREP_CONTEXT
191 smalluint did_print_line;
192 int lines_before;
193 int lines_after;
194 char **before_buf;
195 IF_EXTRA_COMPAT(size_t *before_buf_size;)
196 int last_line_printed;
197#endif
198 /* globals used internally */
199 llist_t *pattern_head; /* growable list of patterns to match */
200 const char *cur_file; /* the current file we are reading */
201} FIX_ALIASING;
202#define G (*(struct globals*)&bb_common_bufsiz1)
203#define INIT_G() do { \
204 struct G_sizecheck { \
205 char G_sizecheck[sizeof(G) > COMMON_BUFSIZE ? -1 : 1]; \
206 }; \
207} while (0)
208#define max_matches (G.max_matches )
209#if !ENABLE_EXTRA_COMPAT
210# define reflags (G.reflags )
211#else
212# define case_fold (G.case_fold )
213/* http://www.delorie.com/gnu/docs/regex/regex_46.html */
214# define reflags re_syntax_options
215# undef REG_NOSUB
216# undef REG_EXTENDED
217# undef REG_ICASE
218# define REG_NOSUB bug:is:here /* should not be used */
219/* Just RE_SYNTAX_EGREP is not enough, need to enable {n[,[m]]} too */
220# define REG_EXTENDED (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES)
221# define REG_ICASE bug:is:here /* should not be used */
222#endif
223#define invert_search (G.invert_search )
224#define print_filename (G.print_filename )
225#define open_errors (G.open_errors )
226#define did_print_line (G.did_print_line )
227#define lines_before (G.lines_before )
228#define lines_after (G.lines_after )
229#define before_buf (G.before_buf )
230#define before_buf_size (G.before_buf_size )
231#define last_line_printed (G.last_line_printed )
232#define pattern_head (G.pattern_head )
233#define cur_file (G.cur_file )
234
235
236typedef struct grep_list_data_t {
237 char *pattern;
238/* for GNU regex, matched_range must be persistent across grep_file() calls */
239#if !ENABLE_EXTRA_COMPAT
240 regex_t compiled_regex;
241 regmatch_t matched_range;
242#else
243 struct re_pattern_buffer compiled_regex;
244 struct re_registers matched_range;
245#endif
246#define ALLOCATED 1
247#define COMPILED 2
248 int flg_mem_alocated_compiled;
249} grep_list_data_t;
250
251#if !ENABLE_EXTRA_COMPAT
252#define print_line(line, line_len, linenum, decoration) \
253 print_line(line, linenum, decoration)
254#endif
255static void print_line(const char *line, size_t line_len, int linenum, char decoration)
256{
257#if ENABLE_FEATURE_GREP_CONTEXT
258 /* Happens when we go to next file, immediately hit match
259 * and try to print prev context... from prev file! Don't do it */
260 if (linenum < 1)
261 return;
262 /* possibly print the little '--' separator */
263 if ((lines_before || lines_after) && did_print_line
264 && last_line_printed != linenum - 1
265 ) {
266 puts("--");
267 }
268 /* guard against printing "--" before first line of first file */
269 did_print_line = 1;
270 last_line_printed = linenum;
271#endif
272 if (print_filename)
273 printf("%s%c", cur_file, decoration);
274 if (PRINT_LINE_NUM)
275 printf("%i%c", linenum, decoration);
276 /* Emulate weird GNU grep behavior with -ov */
277 if ((option_mask32 & (OPT_v|OPT_o)) != (OPT_v|OPT_o)) {
278#if !ENABLE_EXTRA_COMPAT
279 puts(line);
280#else
281 fwrite(line, 1, line_len, stdout);
282 putchar(NUL_DELIMITED ? '\0' : '\n');
283#endif
284 }
285}
286
287#if ENABLE_EXTRA_COMPAT
288/* Unlike getline, this one removes trailing '\n' */
289static ssize_t FAST_FUNC bb_getline(char **line_ptr, size_t *line_alloc_len, FILE *file)
290{
291 ssize_t res_sz;
292 char *line;
293 int delim = (NUL_DELIMITED ? '\0' : '\n');
294
295 res_sz = getdelim(line_ptr, line_alloc_len, delim, file);
296 line = *line_ptr;
297
298 if (res_sz > 0) {
299 if (line[res_sz - 1] == delim)
300 line[--res_sz] = '\0';
301 } else {
302 free(line); /* uclibc allocates a buffer even on EOF. WTF? */
303 }
304 return res_sz;
305}
306#endif
307
308static int grep_file(FILE *file)
309{
310 smalluint found;
311 int linenum = 0;
312 int nmatches = 0;
313#if !ENABLE_EXTRA_COMPAT
314 char *line;
315#else
316 char *line = NULL;
317 ssize_t line_len;
318 size_t line_alloc_len;
319# define rm_so start[0]
320# define rm_eo end[0]
321#endif
322#if ENABLE_FEATURE_GREP_CONTEXT
323 int print_n_lines_after = 0;
324 int curpos = 0; /* track where we are in the circular 'before' buffer */
325 int idx = 0; /* used for iteration through the circular buffer */
326#else
327 enum { print_n_lines_after = 0 };
328#endif
329
330 while (
331#if !ENABLE_EXTRA_COMPAT
332 (line = xmalloc_fgetline(file)) != NULL
333#else
334 (line_len = bb_getline(&line, &line_alloc_len, file)) >= 0
335#endif
336 ) {
337 llist_t *pattern_ptr = pattern_head;
338 grep_list_data_t *gl = gl; /* for gcc */
339
340 linenum++;
341 found = 0;
342 while (pattern_ptr) {
343 gl = (grep_list_data_t *)pattern_ptr->data;
344 if (FGREP_FLAG) {
345 found |= (((option_mask32 & OPT_i)
346 ? strcasestr(line, gl->pattern)
347 : strstr(line, gl->pattern)
348 ) != NULL);
349 } else {
350 if (!(gl->flg_mem_alocated_compiled & COMPILED)) {
351 gl->flg_mem_alocated_compiled |= COMPILED;
352#if !ENABLE_EXTRA_COMPAT
353 xregcomp(&gl->compiled_regex, gl->pattern, reflags);
354#else
355 memset(&gl->compiled_regex, 0, sizeof(gl->compiled_regex));
356 gl->compiled_regex.translate = case_fold; /* for -i */
357 if (re_compile_pattern(gl->pattern, strlen(gl->pattern), &gl->compiled_regex))
358 bb_error_msg_and_die("bad regex '%s'", gl->pattern);
359#endif
360 }
361#if !ENABLE_EXTRA_COMPAT
362 gl->matched_range.rm_so = 0;
363 gl->matched_range.rm_eo = 0;
364#endif
365 if (
366#if !ENABLE_EXTRA_COMPAT
367 regexec(&gl->compiled_regex, line, 1, &gl->matched_range, 0) == 0
368#else
369 re_search(&gl->compiled_regex, line, line_len,
370 /*start:*/ 0, /*range:*/ line_len,
371 &gl->matched_range) >= 0
372#endif
373 ) {
374 if (!(option_mask32 & OPT_w))
375 found = 1;
376 else {
377 char c = ' ';
378 if (gl->matched_range.rm_so)
379 c = line[gl->matched_range.rm_so - 1];
380 if (!isalnum(c) && c != '_') {
381 c = line[gl->matched_range.rm_eo];
382 if (!c || (!isalnum(c) && c != '_'))
383 found = 1;
384 }
385 }
386 }
387 }
388 /* If it's non-inverted search, we can stop
389 * at first match */
390 if (found && !invert_search)
391 goto do_found;
392 pattern_ptr = pattern_ptr->link;
393 } /* while (pattern_ptr) */
394
395 if (found ^ invert_search) {
396 do_found:
397 /* keep track of matches */
398 nmatches++;
399
400 /* quiet/print (non)matching file names only? */
401 if (option_mask32 & (OPT_q|OPT_l|OPT_L)) {
402 free(line); /* we don't need line anymore */
403 if (BE_QUIET) {
404 /* manpage says about -q:
405 * "exit immediately with zero status
406 * if any match is found,
407 * even if errors were detected" */
408 exit(EXIT_SUCCESS);
409 }
410 /* if we're just printing filenames, we stop after the first match */
411 if (PRINT_FILES_WITH_MATCHES) {
412 puts(cur_file);
413 /* fall through to "return 1" */
414 }
415 /* OPT_L aka PRINT_FILES_WITHOUT_MATCHES: return early */
416 return 1; /* one match */
417 }
418
419#if ENABLE_FEATURE_GREP_CONTEXT
420 /* Were we printing context and saw next (unwanted) match? */
421 if ((option_mask32 & OPT_m) && nmatches > max_matches)
422 break;
423#endif
424
425 /* print the matched line */
426 if (PRINT_MATCH_COUNTS == 0) {
427#if ENABLE_FEATURE_GREP_CONTEXT
428 int prevpos = (curpos == 0) ? lines_before - 1 : curpos - 1;
429
430 /* if we were told to print 'before' lines and there is at least
431 * one line in the circular buffer, print them */
432 if (lines_before && before_buf[prevpos] != NULL) {
433 int first_buf_entry_line_num = linenum - lines_before;
434
435 /* advance to the first entry in the circular buffer, and
436 * figure out the line number is of the first line in the
437 * buffer */
438 idx = curpos;
439 while (before_buf[idx] == NULL) {
440 idx = (idx + 1) % lines_before;
441 first_buf_entry_line_num++;
442 }
443
444 /* now print each line in the buffer, clearing them as we go */
445 while (before_buf[idx] != NULL) {
446 print_line(before_buf[idx], before_buf_size[idx], first_buf_entry_line_num, '-');
447 free(before_buf[idx]);
448 before_buf[idx] = NULL;
449 idx = (idx + 1) % lines_before;
450 first_buf_entry_line_num++;
451 }
452 }
453
454 /* make a note that we need to print 'after' lines */
455 print_n_lines_after = lines_after;
456#endif
457 if (option_mask32 & OPT_o) {
458 if (FGREP_FLAG) {
459 /* -Fo just prints the pattern
460 * (unless -v: -Fov doesnt print anything at all) */
461 if (found)
462 print_line(gl->pattern, strlen(gl->pattern), linenum, ':');
463 } else while (1) {
464 unsigned end = gl->matched_range.rm_eo;
465 char old = line[end];
466 line[end] = '\0';
467 print_line(line + gl->matched_range.rm_so,
468 end - gl->matched_range.rm_so,
469 linenum, ':');
470 if (old == '\0')
471 break;
472 line[end] = old;
473#if !ENABLE_EXTRA_COMPAT
474 if (regexec(&gl->compiled_regex, line + end,
475 1, &gl->matched_range, REG_NOTBOL) != 0)
476 break;
477 gl->matched_range.rm_so += end;
478 gl->matched_range.rm_eo += end;
479#else
480 if (re_search(&gl->compiled_regex, line, line_len,
481 end, line_len - end,
482 &gl->matched_range) < 0)
483 break;
484#endif
485 }
486 } else {
487 print_line(line, line_len, linenum, ':');
488 }
489 }
490 }
491#if ENABLE_FEATURE_GREP_CONTEXT
492 else { /* no match */
493 /* if we need to print some context lines after the last match, do so */
494 if (print_n_lines_after) {
495 print_line(line, strlen(line), linenum, '-');
496 print_n_lines_after--;
497 } else if (lines_before) {
498 /* Add the line to the circular 'before' buffer */
499 free(before_buf[curpos]);
500 before_buf[curpos] = line;
501 IF_EXTRA_COMPAT(before_buf_size[curpos] = line_len;)
502 curpos = (curpos + 1) % lines_before;
503 /* avoid free(line) - we took the line */
504 line = NULL;
505 }
506 }
507
508#endif /* ENABLE_FEATURE_GREP_CONTEXT */
509#if !ENABLE_EXTRA_COMPAT
510 free(line);
511#endif
512 /* Did we print all context after last requested match? */
513 if ((option_mask32 & OPT_m)
514 && !print_n_lines_after
515 && nmatches == max_matches
516 ) {
517 break;
518 }
519 } /* while (read line) */
520
521 /* special-case file post-processing for options where we don't print line
522 * matches, just filenames and possibly match counts */
523
524 /* grep -c: print [filename:]count, even if count is zero */
525 if (PRINT_MATCH_COUNTS) {
526 if (print_filename)
527 printf("%s:", cur_file);
528 printf("%d\n", nmatches);
529 }
530
531 /* grep -L: print just the filename */
532 if (PRINT_FILES_WITHOUT_MATCHES) {
533 /* nmatches is zero, no need to check it:
534 * we return 1 early if we detected a match
535 * and PRINT_FILES_WITHOUT_MATCHES is set */
536 puts(cur_file);
537 }
538
539 return nmatches;
540}
541
542#if ENABLE_FEATURE_CLEAN_UP
543#define new_grep_list_data(p, m) add_grep_list_data(p, m)
544static char *add_grep_list_data(char *pattern, int flg_used_mem)
545#else
546#define new_grep_list_data(p, m) add_grep_list_data(p)
547static char *add_grep_list_data(char *pattern)
548#endif
549{
550 grep_list_data_t *gl = xzalloc(sizeof(*gl));
551 gl->pattern = pattern;
552#if ENABLE_FEATURE_CLEAN_UP
553 gl->flg_mem_alocated_compiled = flg_used_mem;
554#else
555 /*gl->flg_mem_alocated_compiled = 0;*/
556#endif
557 return (char *)gl;
558}
559
560static void load_regexes_from_file(llist_t *fopt)
561{
562 char *line;
563 FILE *f;
564
565 while (fopt) {
566 llist_t *cur = fopt;
567 char *ffile = cur->data;
568
569 fopt = cur->link;
570 free(cur);
571 f = xfopen_stdin(ffile);
572 while ((line = xmalloc_fgetline(f)) != NULL) {
573 llist_add_to(&pattern_head,
574 new_grep_list_data(line, ALLOCATED));
575 }
576 }
577}
578
579static int FAST_FUNC file_action_grep(const char *filename,
580 struct stat *statbuf UNUSED_PARAM,
581 void* matched,
582 int depth UNUSED_PARAM)
583{
584 FILE *file = fopen_for_read(filename);
585 if (file == NULL) {
586 if (!SUPPRESS_ERR_MSGS)
587 bb_simple_perror_msg(filename);
588 open_errors = 1;
589 return 0;
590 }
591 cur_file = filename;
592 *(int*)matched += grep_file(file);
593 fclose(file);
594 return 1;
595}
596
597static int grep_dir(const char *dir)
598{
599 int matched = 0;
600 recursive_action(dir,
601 /* recurse=yes */ ACTION_RECURSE |
602 /* followLinks=no */
603 /* depthFirst=yes */ ACTION_DEPTHFIRST,
604 /* fileAction= */ file_action_grep,
605 /* dirAction= */ NULL,
606 /* userData= */ &matched,
607 /* depth= */ 0);
608 return matched;
609}
610
611int grep_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
612int grep_main(int argc UNUSED_PARAM, char **argv)
613{
614 FILE *file;
615 int matched;
616 llist_t *fopt = NULL;
617
618 /* do normal option parsing */
619#if ENABLE_FEATURE_GREP_CONTEXT
620 int Copt;
621
622 /* -H unsets -h; -C unsets -A,-B; -e,-f are lists;
623 * -m,-A,-B,-C have numeric param */
624 opt_complementary = "H-h:C-AB:e::f::m+:A+:B+:C+";
625 getopt32(argv,
626 OPTSTR_GREP,
627 &pattern_head, &fopt, &max_matches,
628 &lines_after, &lines_before, &Copt);
629
630 if (option_mask32 & OPT_C) {
631 /* -C unsets prev -A and -B, but following -A or -B
632 may override it */
633 if (!(option_mask32 & OPT_A)) /* not overridden */
634 lines_after = Copt;
635 if (!(option_mask32 & OPT_B)) /* not overridden */
636 lines_before = Copt;
637 }
638 /* sanity checks */
639 if (option_mask32 & (OPT_c|OPT_q|OPT_l|OPT_L)) {
640 option_mask32 &= ~OPT_n;
641 lines_before = 0;
642 lines_after = 0;
643 } else if (lines_before > 0) {
644 before_buf = xzalloc(lines_before * sizeof(before_buf[0]));
645 IF_EXTRA_COMPAT(before_buf_size = xzalloc(lines_before * sizeof(before_buf_size[0]));)
646 }
647#else
648 /* with auto sanity checks */
649 /* -H unsets -h; -c,-q or -l unset -n; -e,-f are lists; -m N */
650 opt_complementary = "H-h:c-n:q-n:l-n:e::f::m+";
651 getopt32(argv, OPTSTR_GREP,
652 &pattern_head, &fopt, &max_matches);
653#endif
654 invert_search = ((option_mask32 & OPT_v) != 0); /* 0 | 1 */
655
656 if (pattern_head != NULL) {
657 /* convert char **argv to grep_list_data_t */
658 llist_t *cur;
659
660 for (cur = pattern_head; cur; cur = cur->link)
661 cur->data = new_grep_list_data(cur->data, 0);
662 }
663 if (option_mask32 & OPT_f)
664 load_regexes_from_file(fopt);
665
666 if (ENABLE_FEATURE_GREP_FGREP_ALIAS && applet_name[0] == 'f')
667 option_mask32 |= OPT_F;
668
669#if !ENABLE_EXTRA_COMPAT
670 if (!(option_mask32 & (OPT_o | OPT_w)))
671 reflags = REG_NOSUB;
672#endif
673
674 if (ENABLE_FEATURE_GREP_EGREP_ALIAS
675 && (applet_name[0] == 'e' || (option_mask32 & OPT_E))
676 ) {
677 reflags |= REG_EXTENDED;
678 }
679#if ENABLE_EXTRA_COMPAT
680 else {
681 reflags = RE_SYNTAX_GREP;
682 }
683#endif
684
685 if (option_mask32 & OPT_i) {
686#if !ENABLE_EXTRA_COMPAT
687 reflags |= REG_ICASE;
688#else
689 int i;
690 case_fold = xmalloc(256);
691 for (i = 0; i < 256; i++)
692 case_fold[i] = (unsigned char)i;
693 for (i = 'a'; i <= 'z'; i++)
694 case_fold[i] = (unsigned char)(i - ('a' - 'A'));
695#endif
696 }
697
698 argv += optind;
699
700 /* if we didn't get a pattern from -e and no command file was specified,
701 * first parameter should be the pattern. no pattern, no worky */
702 if (pattern_head == NULL) {
703 char *pattern;
704 if (*argv == NULL)
705 bb_show_usage();
706 pattern = new_grep_list_data(*argv++, 0);
707 llist_add_to(&pattern_head, pattern);
708 }
709
710 /* argv[0..(argc-1)] should be names of file to grep through. If
711 * there is more than one file to grep, we will print the filenames. */
712 if (argv[0] && argv[1])
713 print_filename = 1;
714 /* -H / -h of course override */
715 if (option_mask32 & OPT_H)
716 print_filename = 1;
717 if (option_mask32 & OPT_h)
718 print_filename = 0;
719
720 /* If no files were specified, or '-' was specified, take input from
721 * stdin. Otherwise, we grep through all the files specified. */
722 matched = 0;
723 do {
724 cur_file = *argv;
725 file = stdin;
726 if (!cur_file || LONE_DASH(cur_file)) {
727 cur_file = "(standard input)";
728 } else {
729 if (option_mask32 & OPT_r) {
730 struct stat st;
731 if (stat(cur_file, &st) == 0 && S_ISDIR(st.st_mode)) {
732 if (!(option_mask32 & OPT_h))
733 print_filename = 1;
734 matched += grep_dir(cur_file);
735 goto grep_done;
736 }
737 }
738 /* else: fopen(dir) will succeed, but reading won't */
739 file = fopen_for_read(cur_file);
740 if (file == NULL) {
741 if (!SUPPRESS_ERR_MSGS)
742 bb_simple_perror_msg(cur_file);
743 open_errors = 1;
744 continue;
745 }
746 }
747 matched += grep_file(file);
748 fclose_if_not_stdin(file);
749 grep_done: ;
750 } while (*argv && *++argv);
751
752 /* destroy all the elments in the pattern list */
753 if (ENABLE_FEATURE_CLEAN_UP) {
754 while (pattern_head) {
755 llist_t *pattern_head_ptr = pattern_head;
756 grep_list_data_t *gl = (grep_list_data_t *)pattern_head_ptr->data;
757
758 pattern_head = pattern_head->link;
759 if (gl->flg_mem_alocated_compiled & ALLOCATED)
760 free(gl->pattern);
761 if (gl->flg_mem_alocated_compiled & COMPILED)
762 regfree(&gl->compiled_regex);
763 free(gl);
764 free(pattern_head_ptr);
765 }
766 }
767 /* 0 = success, 1 = failed, 2 = error */
768 if (open_errors)
769 return 2;
770 return !matched; /* invert return value: 0 = success, 1 = failed */
771}
7720
=== removed directory '.pc/grep-o-loop.patch/testsuite'
=== removed file '.pc/grep-o-loop.patch/testsuite/grep.tests'
--- .pc/grep-o-loop.patch/testsuite/grep.tests 2010-10-13 11:03:32 +0000
+++ .pc/grep-o-loop.patch/testsuite/grep.tests 1970-01-01 00:00:00 +0000
@@ -1,102 +0,0 @@
1#!/bin/sh
2
3# Copyright 2005 by Rob Landley <rob@landley.net>
4# Licensed under GPL v2, see file LICENSE for details.
5
6# AUDIT:
7
8. ./testing.sh
9
10# testing "test name" "options" "expected result" "file input" "stdin"
11# file input will be file called "input"
12# test can create a file "actual" instead of writing to stdout
13
14# Test exit status
15
16testing "grep (exit with error)" "grep nonexistent 2> /dev/null ; echo \$?" \
17 "1\n" "" ""
18testing "grep (exit success)" "grep grep $0 > /dev/null 2>&1 ; echo \$?" "0\n" \
19 "" ""
20# Test various data sources and destinations
21
22testing "grep (default to stdin)" "grep two" "two\n" "" \
23 "one\ntwo\nthree\nthree\nthree\n"
24testing "grep - (specify stdin)" "grep two -" "two\n" "" \
25 "one\ntwo\nthree\nthree\nthree\n"
26testing "grep input (specify file)" "grep two input" "two\n" \
27 "one\ntwo\nthree\nthree\nthree\n" ""
28
29# GNU grep 2.5.3 outputs a new line character after the located string
30# even if there is no new line character in the input
31testing "grep (no newline at EOL)" "grep bug input" "bug\n" "bug" ""
32
33>empty
34testing "grep two files" "grep two input empty 2>/dev/null" \
35 "input:two\n" "one\ntwo\nthree\nthree\nthree\n" ""
36rm empty
37
38testing "grep - infile (specify stdin and file)" "grep two - input" \
39 "(standard input):two\ninput:two\n" "one\ntwo\nthree\n" \
40 "one\ntwo\ntoo\nthree\nthree\n"
41
42# Check if we see the correct return value if both stdin and non-existing file
43# are given.
44testing "grep - nofile (specify stdin and nonexisting file)" \
45 "grep two - nonexistent 2> /dev/null ; echo \$?" \
46 "(standard input):two\n(standard input):two\n2\n" \
47 "" "one\ntwo\ntwo\nthree\nthree\nthree\n"
48testing "grep -q - nofile (specify stdin and nonexisting file, no match)" \
49 "grep -q nomatch - nonexistent 2> /dev/null ; echo \$?" \
50 "2\n" "" "one\ntwo\ntwo\nthree\nthree\nthree\n"
51# SUSv3: If the -q option is specified, the exit status shall be zero
52# if an input line is selected, even if an error was detected.
53testing "grep -q - nofile (specify stdin and nonexisting file, match)" \
54 "grep -q two - nonexistent ; echo \$?" \
55 "0\n" "" "one\ntwo\ntwo\nthree\nthree\nthree\n"
56
57# Test various command line options
58# -s no error messages
59testing "grep -s nofile (nonexisting file, no match)" \
60 "grep -s nomatch nonexistent ; echo \$?" "2\n" "" ""
61testing "grep -s nofile - (stdin and nonexisting file, match)" \
62 "grep -s domatch nonexistent - ; echo \$?" \
63 "(standard input):domatch\n2\n" "" "nomatch\ndomatch\nend\n"
64
65optional EXTRA_COMPAT
66testing "grep handles NUL in files" "grep -a foo input" "\0foo\n" "\0foo\n\n" ""
67testing "grep handles NUL on stdin" "grep -a foo" "\0foo\n" "" "\0foo\n\n"
68
69testing "grep matches NUL" "grep . input > /dev/null 2>&1 ; echo \$?" \
70 "0\n" "\0\n" ""
71SKIP=
72
73# -e regex
74testing "grep handles multiple regexps" "grep -e one -e two input ; echo \$?" \
75 "one\ntwo\n0\n" "one\ntwo\n" ""
76testing "grep -F handles multiple expessions" "grep -F -e one -e two input ; echo \$?" \
77 "one\ntwo\n0\n" "one\ntwo\n" ""
78testing "grep -F handles -i" "grep -F -i foo input ; echo \$?" \
79 "FOO\n0\n" "FOO\n" ""
80
81# -f file/-
82testing "grep can read regexps from stdin" "grep -f - input ; echo \$?" \
83 "two\nthree\n0\n" "tw\ntwo\nthree\n" "tw.\nthr\n"
84
85optional FEATURE_GREP_EGREP_ALIAS
86testing "grep -E supports extended regexps" "grep -E fo+" "foo\n" "" \
87 "b\ar\nfoo\nbaz"
88testing "grep is also egrep" "egrep foo" "foo\n" "" "foo\nbar\n"
89testing "egrep is not case insensitive" \
90 "egrep foo ; [ \$? -ne 0 ] && echo yes" "yes\n" "" "FOO\n"
91testing "grep -E -o prints all matches" \
92 "grep -E -o '([[:xdigit:]]{2}[:-]){5}[[:xdigit:]]{2}'" \
93 "00:19:3E:00:AA:5E\n00:1D:60:3D:3A:FB\n00:22:43:49:FB:AA\n" \
94 "" "00:19:3E:00:AA:5E 00:1D:60:3D:3A:FB 00:22:43:49:FB:AA\n"
95SKIP=
96
97testing "grep -o does not loop forever" \
98 'grep -o "[^/]*$"' \
99 "test\n" \
100 "" "/var/test\n"
101
102exit $FAILCOUNT
1030
=== removed directory '.pc/init-console-CRTSCTS.patch'
=== removed directory '.pc/init-console-CRTSCTS.patch/init'
=== removed file '.pc/init-console-CRTSCTS.patch/init/init.c'
--- .pc/init-console-CRTSCTS.patch/init/init.c 2010-10-21 16:17:03 +0000
+++ .pc/init-console-CRTSCTS.patch/init/init.c 1970-01-01 00:00:00 +0000
@@ -1,1047 +0,0 @@
1/* vi: set sw=4 ts=4: */
2/*
3 * Mini init implementation for busybox
4 *
5 * Copyright (C) 1995, 1996 by Bruce Perens <bruce@pixar.com>.
6 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
7 * Adjusted by so many folks, it's impossible to keep track.
8 *
9 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
10 */
11
12#include "libbb.h"
13#include <syslog.h>
14#include <paths.h>
15#include <sys/resource.h>
16#ifdef __linux__
17#include <linux/vt.h>
18#endif
19#if ENABLE_FEATURE_UTMP
20# include <utmp.h> /* DEAD_PROCESS */
21#endif
22#include "reboot.h" /* reboot() constants */
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
30
31/* Was a CONFIG_xxx option. A lot of people were building
32 * not fully functional init by switching it on! */
33#define DEBUG_INIT 0
34
35#define COMMAND_SIZE 256
36#define CONSOLE_NAME_SIZE 32
37
38/* Default sysinit script. */
39#ifndef INIT_SCRIPT
40#define INIT_SCRIPT "/etc/init.d/rcS"
41#endif
42
43/* Each type of actions can appear many times. They will be
44 * handled in order. RESTART is an exception, only 1st is used.
45 */
46/* Start these actions first and wait for completion */
47#define SYSINIT 0x01
48/* Start these after SYSINIT and wait for completion */
49#define WAIT 0x02
50/* Start these after WAIT and *dont* wait for completion */
51#define ONCE 0x04
52/*
53 * NB: while SYSINIT/WAIT/ONCE are being processed,
54 * SIGHUP ("reread /etc/inittab") will be processed only after
55 * each group of actions. If new inittab adds, say, a SYSINIT action,
56 * it will not be run, since init is already "past SYSINIT stage".
57 */
58/* Start these after ONCE are started, restart on exit */
59#define RESPAWN 0x08
60/* Like RESPAWN, but wait for <Enter> to be pressed on tty */
61#define ASKFIRST 0x10
62/*
63 * Start these on SIGINT, and wait for completion.
64 * Then go back to respawning RESPAWN and ASKFIRST actions.
65 * NB: kernel sends SIGINT to us if Ctrl-Alt-Del was pressed.
66 */
67#define CTRLALTDEL 0x20
68/*
69 * Start these before killing all processes in preparation for
70 * running RESTART actions or doing low-level halt/reboot/poweroff
71 * (initiated by SIGUSR1/SIGTERM/SIGUSR2).
72 * Wait for completion before proceeding.
73 */
74#define SHUTDOWN 0x40
75/*
76 * exec() on SIGQUIT. SHUTDOWN actions are started and waited for,
77 * then all processes are killed, then init exec's 1st RESTART action,
78 * replacing itself by it. If no RESTART action specified,
79 * SIGQUIT has no effect.
80 */
81#define RESTART 0x80
82
83
84/* A linked list of init_actions, to be read from inittab */
85struct init_action {
86 struct init_action *next;
87 pid_t pid;
88 uint8_t action_type;
89 char terminal[CONSOLE_NAME_SIZE];
90 char command[COMMAND_SIZE];
91};
92
93static struct init_action *init_action_list = NULL;
94
95static const char *log_console = VC_5;
96
97enum {
98 L_LOG = 0x1,
99 L_CONSOLE = 0x2,
100};
101
102/* Print a message to the specified device.
103 * "where" may be bitwise-or'd from L_LOG | L_CONSOLE
104 * NB: careful, we can be called after vfork!
105 */
106#define dbg_message(...) do { if (DEBUG_INIT) message(__VA_ARGS__); } while (0)
107static void message(int where, const char *fmt, ...)
108 __attribute__ ((format(printf, 2, 3)));
109static void message(int where, const char *fmt, ...)
110{
111 va_list arguments;
112 unsigned l;
113 char msg[128];
114
115 msg[0] = '\r';
116 va_start(arguments, fmt);
117 l = 1 + vsnprintf(msg + 1, sizeof(msg) - 2, fmt, arguments);
118 if (l > sizeof(msg) - 1)
119 l = sizeof(msg) - 1;
120 va_end(arguments);
121
122#if ENABLE_FEATURE_INIT_SYSLOG
123 msg[l] = '\0';
124 if (where & L_LOG) {
125 /* Log the message to syslogd */
126 openlog(applet_name, 0, LOG_DAEMON);
127 /* don't print "\r" */
128 syslog(LOG_INFO, "%s", msg + 1);
129 closelog();
130 }
131 msg[l++] = '\n';
132 msg[l] = '\0';
133#else
134 {
135 static int log_fd = -1;
136
137 msg[l++] = '\n';
138 msg[l] = '\0';
139 /* Take full control of the log tty, and never close it.
140 * It's mine, all mine! Muhahahaha! */
141 if (log_fd < 0) {
142 if (!log_console) {
143 log_fd = STDERR_FILENO;
144 } else {
145 log_fd = device_open(log_console, O_WRONLY | O_NONBLOCK | O_NOCTTY);
146 if (log_fd < 0) {
147 bb_error_msg("can't log to %s", log_console);
148 where = L_CONSOLE;
149 } else {
150 close_on_exec_on(log_fd);
151 }
152 }
153 }
154 if (where & L_LOG) {
155 full_write(log_fd, msg, l);
156 if (log_fd == STDERR_FILENO)
157 return; /* don't print dup messages */
158 }
159 }
160#endif
161
162 if (where & L_CONSOLE) {
163 /* Send console messages to console so people will see them. */
164 full_write(STDERR_FILENO, msg, l);
165 }
166}
167
168static void console_init(void)
169{
170#ifdef VT_OPENQRY
171 int vtno;
172#endif
173 char *s;
174
175 s = getenv("CONSOLE");
176 if (!s)
177 s = getenv("console");
178 if (s) {
179 int fd = open(s, O_RDWR | O_NONBLOCK | O_NOCTTY);
180 if (fd >= 0) {
181 dup2(fd, STDIN_FILENO);
182 dup2(fd, STDOUT_FILENO);
183 xmove_fd(fd, STDERR_FILENO);
184 }
185 dbg_message(L_LOG, "console='%s'", s);
186 } else {
187 /* Make sure fd 0,1,2 are not closed
188 * (so that they won't be used by future opens) */
189 bb_sanitize_stdio();
190// Users report problems
191// /* Make sure init can't be blocked by writing to stderr */
192// fcntl(STDERR_FILENO, F_SETFL, fcntl(STDERR_FILENO, F_GETFL) | O_NONBLOCK);
193 }
194
195 s = getenv("TERM");
196#ifdef VT_OPENQRY
197 if (ioctl(STDIN_FILENO, VT_OPENQRY, &vtno) != 0) {
198 /* Not a linux terminal, probably serial console.
199 * Force the TERM setting to vt102
200 * if TERM is set to linux (the default) */
201 if (!s || strcmp(s, "linux") == 0)
202 putenv((char*)"TERM=vt102");
203 if (!ENABLE_FEATURE_INIT_SYSLOG)
204 log_console = NULL;
205 } else
206#endif
207 if (!s)
208 putenv((char*)"TERM=" CONFIG_INIT_TERMINAL_TYPE);
209}
210
211/* Set terminal settings to reasonable defaults.
212 * NB: careful, we can be called after vfork! */
213static void set_sane_term(void)
214{
215 struct termios tty;
216
217 tcgetattr(STDIN_FILENO, &tty);
218
219 /* set control chars */
220 tty.c_cc[VINTR] = 3; /* C-c */
221 tty.c_cc[VQUIT] = 28; /* C-\ */
222 tty.c_cc[VERASE] = 127; /* C-? */
223 tty.c_cc[VKILL] = 21; /* C-u */
224 tty.c_cc[VEOF] = 4; /* C-d */
225 tty.c_cc[VSTART] = 17; /* C-q */
226 tty.c_cc[VSTOP] = 19; /* C-s */
227 tty.c_cc[VSUSP] = 26; /* C-z */
228
229#ifdef __linux__
230 /* use line discipline 0 */
231 tty.c_line = 0;
232#endif
233
234 /* Make it be sane */
235 tty.c_cflag &= CBAUD | CBAUDEX | CSIZE | CSTOPB | PARENB | PARODD;
236 tty.c_cflag |= CREAD | HUPCL | CLOCAL;
237
238 /* input modes */
239 tty.c_iflag = ICRNL | IXON | IXOFF;
240
241 /* output modes */
242 tty.c_oflag = OPOST | ONLCR;
243
244 /* local modes */
245 tty.c_lflag =
246 ISIG | ICANON | ECHO | ECHOE | ECHOK | ECHOCTL | ECHOKE | IEXTEN;
247
248 tcsetattr_stdin_TCSANOW(&tty);
249}
250
251/* Open the new terminal device.
252 * NB: careful, we can be called after vfork! */
253static int open_stdio_to_tty(const char* tty_name)
254{
255 /* empty tty_name means "use init's tty", else... */
256 if (tty_name[0]) {
257 int fd;
258
259 close(STDIN_FILENO);
260 /* fd can be only < 0 or 0: */
261 fd = device_open(tty_name, O_RDWR);
262 if (fd) {
263 message(L_LOG | L_CONSOLE, "can't open %s: %s",
264 tty_name, strerror(errno));
265 return 0; /* failure */
266 }
267 dup2(STDIN_FILENO, STDOUT_FILENO);
268 dup2(STDIN_FILENO, STDERR_FILENO);
269 }
270 set_sane_term();
271 return 1; /* success */
272}
273
274static void reset_sighandlers_and_unblock_sigs(void)
275{
276 bb_signals(0
277 + (1 << SIGUSR1)
278 + (1 << SIGUSR2)
279 + (1 << SIGTERM)
280 + (1 << SIGQUIT)
281 + (1 << SIGINT)
282 + (1 << SIGHUP)
283 + (1 << SIGTSTP)
284 + (1 << SIGSTOP)
285 , SIG_DFL);
286 sigprocmask_allsigs(SIG_UNBLOCK);
287}
288
289/* Wrapper around exec:
290 * Takes string (max COMMAND_SIZE chars).
291 * If chars like '>' detected, execs '[-]/bin/sh -c "exec ......."'.
292 * Otherwise splits words on whitespace, deals with leading dash,
293 * and uses plain exec().
294 * NB: careful, we can be called after vfork!
295 */
296static void init_exec(const char *command)
297{
298 char *cmd[COMMAND_SIZE / 2];
299 char buf[COMMAND_SIZE + 6]; /* COMMAND_SIZE+strlen("exec ")+1 */
300 int dash = (command[0] == '-' /* maybe? && command[1] == '/' */);
301
302 /* See if any special /bin/sh requiring characters are present */
303 if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {
304 strcpy(buf, "exec ");
305 strcpy(buf + 5, command + dash); /* excluding "-" */
306 /* NB: LIBBB_DEFAULT_LOGIN_SHELL define has leading dash */
307 cmd[0] = (char*)(LIBBB_DEFAULT_LOGIN_SHELL + !dash);
308 cmd[1] = (char*)"-c";
309 cmd[2] = buf;
310 cmd[3] = NULL;
311 } else {
312 /* Convert command (char*) into cmd (char**, one word per string) */
313 char *word, *next;
314 int i = 0;
315 next = strcpy(buf, command); /* including "-" */
316 while ((word = strsep(&next, " \t")) != NULL) {
317 if (*word != '\0') { /* not two spaces/tabs together? */
318 cmd[i] = word;
319 i++;
320 }
321 }
322 cmd[i] = NULL;
323 }
324 /* If we saw leading "-", it is interactive shell.
325 * Try harder to give it a controlling tty.
326 * And skip "-" in actual exec call. */
327 if (dash) {
328 /* _Attempt_ to make stdin a controlling tty. */
329 if (ENABLE_FEATURE_INIT_SCTTY)
330 ioctl(STDIN_FILENO, TIOCSCTTY, 0 /*only try, don't steal*/);
331 }
332 BB_EXECVP(cmd[0] + dash, cmd);
333 message(L_LOG | L_CONSOLE, "can't run '%s': %s", cmd[0], strerror(errno));
334 /* returns if execvp fails */
335}
336
337/* Used only by run_actions */
338static pid_t run(const struct init_action *a)
339{
340 pid_t pid;
341
342 /* Careful: don't be affected by a signal in vforked child */
343 sigprocmask_allsigs(SIG_BLOCK);
344 if (BB_MMU && (a->action_type & ASKFIRST))
345 pid = fork();
346 else
347 pid = vfork();
348 if (pid < 0)
349 message(L_LOG | L_CONSOLE, "can't fork");
350 if (pid) {
351 sigprocmask_allsigs(SIG_UNBLOCK);
352 return pid; /* Parent or error */
353 }
354
355 /* Child */
356
357 /* Reset signal handlers that were set by the parent process */
358 reset_sighandlers_and_unblock_sigs();
359
360 /* Create a new session and make ourself the process group leader */
361 setsid();
362
363 /* Open the new terminal device */
364 if (!open_stdio_to_tty(a->terminal))
365 _exit(EXIT_FAILURE);
366
367 /* NB: on NOMMU we can't wait for input in child, so
368 * "askfirst" will work the same as "respawn". */
369 if (BB_MMU && (a->action_type & ASKFIRST)) {
370 static const char press_enter[] ALIGN1 =
371#ifdef CUSTOMIZED_BANNER
372#include CUSTOMIZED_BANNER
373#endif
374 "\nPlease press Enter to activate this console. ";
375 char c;
376 /*
377 * Save memory by not exec-ing anything large (like a shell)
378 * before the user wants it. This is critical if swap is not
379 * enabled and the system has low memory. Generally this will
380 * be run on the second virtual console, and the first will
381 * be allowed to start a shell or whatever an init script
382 * specifies.
383 */
384 dbg_message(L_LOG, "waiting for enter to start '%s'"
385 "(pid %d, tty '%s')\n",
386 a->command, getpid(), a->terminal);
387 full_write(STDOUT_FILENO, press_enter, sizeof(press_enter) - 1);
388 while (safe_read(STDIN_FILENO, &c, 1) == 1 && c != '\n')
389 continue;
390 }
391
392 /*
393 * When a file named /.init_enable_core exists, setrlimit is called
394 * before processes are spawned to set core file size as unlimited.
395 * This is for debugging only. Don't use this is production, unless
396 * you want core dumps lying about....
397 */
398 if (ENABLE_FEATURE_INIT_COREDUMPS) {
399 if (access("/.init_enable_core", F_OK) == 0) {
400 struct rlimit limit;
401 limit.rlim_cur = RLIM_INFINITY;
402 limit.rlim_max = RLIM_INFINITY;
403 setrlimit(RLIMIT_CORE, &limit);
404 }
405 }
406
407 /* Log the process name and args */
408 message(L_LOG, "starting pid %d, tty '%s': '%s'",
409 getpid(), a->terminal, a->command);
410
411 /* Now run it. The new program will take over this PID,
412 * so nothing further in init.c should be run. */
413 init_exec(a->command);
414 /* We're still here? Some error happened. */
415 _exit(-1);
416}
417
418static struct init_action *mark_terminated(pid_t pid)
419{
420 struct init_action *a;
421
422 if (pid > 0) {
423 for (a = init_action_list; a; a = a->next) {
424 if (a->pid == pid) {
425 a->pid = 0;
426 return a;
427 }
428 }
429 update_utmp(pid, DEAD_PROCESS, /*tty_name:*/ NULL, /*username:*/ NULL, /*hostname:*/ NULL);
430 }
431 return NULL;
432}
433
434static void waitfor(pid_t pid)
435{
436 /* waitfor(run(x)): protect against failed fork inside run() */
437 if (pid <= 0)
438 return;
439
440 /* Wait for any child (prevent zombies from exiting orphaned processes)
441 * but exit the loop only when specified one has exited. */
442 while (1) {
443 pid_t wpid = wait(NULL);
444 mark_terminated(wpid);
445 /* Unsafe. SIGTSTP handler might have wait'ed it already */
446 /*if (wpid == pid) break;*/
447 /* More reliable: */
448 if (kill(pid, 0))
449 break;
450 }
451}
452
453/* Run all commands of a particular type */
454static void run_actions(int action_type)
455{
456 struct init_action *a;
457
458 for (a = init_action_list; a; a = a->next) {
459 if (!(a->action_type & action_type))
460 continue;
461 if (a->terminal[0] && access(a->terminal, R_OK | W_OK))
462 continue;
463
464 if (a->action_type & (SYSINIT | WAIT | ONCE | CTRLALTDEL | SHUTDOWN)) {
465 pid_t pid = run(a);
466 if (a->action_type & (SYSINIT | WAIT | CTRLALTDEL | SHUTDOWN))
467 waitfor(pid);
468 }
469 if (a->action_type & (RESPAWN | ASKFIRST)) {
470 /* Only run stuff with pid == 0. If pid != 0,
471 * it is already running
472 */
473 if (a->pid == 0)
474 a->pid = run(a);
475 }
476 }
477}
478
479static void new_init_action(uint8_t action_type, const char *command, const char *cons)
480{
481 struct init_action *a, **nextp;
482
483 /* Scenario:
484 * old inittab:
485 * ::shutdown:umount -a -r
486 * ::shutdown:swapoff -a
487 * new inittab:
488 * ::shutdown:swapoff -a
489 * ::shutdown:umount -a -r
490 * On reload, we must ensure entries end up in correct order.
491 * To achieve that, if we find a matching entry, we move it
492 * to the end.
493 */
494 nextp = &init_action_list;
495 while ((a = *nextp) != NULL) {
496 /* Don't enter action if it's already in the list,
497 * This prevents losing running RESPAWNs.
498 */
499 if (strcmp(a->command, command) == 0
500 && strcmp(a->terminal, cons) == 0
501 ) {
502 /* Remove from list */
503 *nextp = a->next;
504 /* Find the end of the list */
505 while (*nextp != NULL)
506 nextp = &(*nextp)->next;
507 a->next = NULL;
508 break;
509 }
510 nextp = &a->next;
511 }
512
513 if (!a)
514 a = xzalloc(sizeof(*a));
515 /* Append to the end of the list */
516 *nextp = a;
517 a->action_type = action_type;
518 safe_strncpy(a->command, command, sizeof(a->command));
519 safe_strncpy(a->terminal, cons, sizeof(a->terminal));
520 dbg_message(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n",
521 a->command, a->action_type, a->terminal);
522}
523
524/* NOTE that if CONFIG_FEATURE_USE_INITTAB is NOT defined,
525 * then parse_inittab() simply adds in some default
526 * actions(i.e., runs INIT_SCRIPT and then starts a pair
527 * of "askfirst" shells). If CONFIG_FEATURE_USE_INITTAB
528 * _is_ defined, but /etc/inittab is missing, this
529 * results in the same set of default behaviors.
530 */
531static void parse_inittab(void)
532{
533#if ENABLE_FEATURE_USE_INITTAB
534 char *token[4];
535 parser_t *parser = config_open2("/etc/inittab", fopen_for_read);
536
537 if (parser == NULL)
538#endif
539 {
540 /* No inittab file - set up some default behavior */
541 /* Reboot on Ctrl-Alt-Del */
542 new_init_action(CTRLALTDEL, "reboot", "");
543 /* Umount all filesystems on halt/reboot */
544 new_init_action(SHUTDOWN, "umount -a -r", "");
545 /* Swapoff on halt/reboot */
546 if (ENABLE_SWAPONOFF)
547 new_init_action(SHUTDOWN, "swapoff -a", "");
548 /* Prepare to restart init when a QUIT is received */
549 new_init_action(RESTART, "init", "");
550 /* Askfirst shell on tty1-4 */
551 new_init_action(ASKFIRST, bb_default_login_shell, "");
552//TODO: VC_1 instead of ""? "" is console -> ctty problems -> angry users
553 new_init_action(ASKFIRST, bb_default_login_shell, VC_2);
554 new_init_action(ASKFIRST, bb_default_login_shell, VC_3);
555 new_init_action(ASKFIRST, bb_default_login_shell, VC_4);
556 /* sysinit */
557 new_init_action(SYSINIT, INIT_SCRIPT, "");
558 return;
559 }
560
561#if ENABLE_FEATURE_USE_INITTAB
562 /* optional_tty:ignored_runlevel:action:command
563 * Delims are not to be collapsed and need exactly 4 tokens
564 */
565 while (config_read(parser, token, 4, 0, "#:",
566 PARSE_NORMAL & ~(PARSE_TRIM | PARSE_COLLAPSE))) {
567 /* order must correspond to SYSINIT..RESTART constants */
568 static const char actions[] ALIGN1 =
569 "sysinit\0""wait\0""once\0""respawn\0""askfirst\0"
570 "ctrlaltdel\0""shutdown\0""restart\0";
571 int action;
572 char *tty = token[0];
573
574 if (!token[3]) /* less than 4 tokens */
575 goto bad_entry;
576 action = index_in_strings(actions, token[2]);
577 if (action < 0 || !token[3][0]) /* token[3]: command */
578 goto bad_entry;
579 /* turn .*TTY -> /dev/TTY */
580 if (tty[0]) {
581 tty = concat_path_file("/dev/", skip_dev_pfx(tty));
582 }
583 new_init_action(1 << action, token[3], tty);
584 if (tty[0])
585 free(tty);
586 continue;
587 bad_entry:
588 message(L_LOG | L_CONSOLE, "Bad inittab entry at line %d",
589 parser->lineno);
590 }
591 config_close(parser);
592#endif
593}
594
595static void pause_and_low_level_reboot(unsigned magic) NORETURN;
596static void pause_and_low_level_reboot(unsigned magic)
597{
598 pid_t pid;
599
600 /* Allow time for last message to reach serial console, etc */
601 sleep(1);
602
603 /* We have to fork here, since the kernel calls do_exit(EXIT_SUCCESS)
604 * in linux/kernel/sys.c, which can cause the machine to panic when
605 * the init process exits... */
606 pid = vfork();
607 if (pid == 0) { /* child */
608 reboot(magic);
609 _exit(EXIT_SUCCESS);
610 }
611 while (1)
612 sleep(1);
613}
614
615static void run_shutdown_and_kill_processes(void)
616{
617 /* Run everything to be run at "shutdown". This is done _prior_
618 * to killing everything, in case people wish to use scripts to
619 * shut things down gracefully... */
620 run_actions(SHUTDOWN);
621
622 message(L_CONSOLE | L_LOG, "The system is going down NOW!");
623
624 /* Send signals to every process _except_ pid 1 */
625 kill(-1, SIGTERM);
626 message(L_CONSOLE | L_LOG, "Sent SIG%s to all processes", "TERM");
627 sync();
628 sleep(1);
629
630 kill(-1, SIGKILL);
631 message(L_CONSOLE, "Sent SIG%s to all processes", "KILL");
632 sync();
633 /*sleep(1); - callers take care about making a pause */
634}
635
636/* Signal handling by init:
637 *
638 * For process with PID==1, on entry kernel sets all signals to SIG_DFL
639 * and unmasks all signals. However, for process with PID==1,
640 * default action (SIG_DFL) on any signal is to ignore it,
641 * even for special signals SIGKILL and SIGCONT.
642 * Also, any signal can be caught or blocked.
643 * (but SIGSTOP is still handled specially, at least in 2.6.20)
644 *
645 * We install two kinds of handlers, "immediate" and "delayed".
646 *
647 * Immediate handlers execute at any time, even while, say, sysinit
648 * is running.
649 *
650 * Delayed handlers just set a flag variable. The variable is checked
651 * in the main loop and acted upon.
652 *
653 * halt/poweroff/reboot and restart have immediate handlers.
654 * They only traverse linked list of struct action's, never modify it,
655 * this should be safe to do even in signal handler. Also they
656 * never return.
657 *
658 * SIGSTOP and SIGTSTP have immediate handlers. They just wait
659 * for SIGCONT to happen.
660 *
661 * SIGHUP has a delayed handler, because modifying linked list
662 * of struct action's from a signal handler while it is manipulated
663 * by the program may be disastrous.
664 *
665 * Ctrl-Alt-Del has a delayed handler. Not a must, but allowing
666 * it to happen even somewhere inside "sysinit" would be a bit awkward.
667 *
668 * There is a tiny probability that SIGHUP and Ctrl-Alt-Del will collide
669 * and only one will be remembered and acted upon.
670 */
671
672/* The SIGUSR[12]/SIGTERM handler */
673static void halt_reboot_pwoff(int sig) NORETURN;
674static void halt_reboot_pwoff(int sig)
675{
676 const char *m;
677 unsigned rb;
678
679 /* We may call run() and it unmasks signals,
680 * including the one masked inside this signal handler.
681 * Testcase which would start multiple reboot scripts:
682 * while true; do reboot; done
683 * Preventing it:
684 */
685 reset_sighandlers_and_unblock_sigs();
686
687 run_shutdown_and_kill_processes();
688
689 m = "halt";
690 rb = RB_HALT_SYSTEM;
691 if (sig == SIGTERM) {
692 m = "reboot";
693 rb = RB_AUTOBOOT;
694 } else if (sig == SIGUSR2) {
695 m = "poweroff";
696 rb = RB_POWER_OFF;
697 }
698 message(L_CONSOLE, "Requesting system %s", m);
699 pause_and_low_level_reboot(rb);
700 /* not reached */
701}
702
703/* Handler for QUIT - exec "restart" action,
704 * else (no such action defined) do nothing */
705static void restart_handler(int sig UNUSED_PARAM)
706{
707 struct init_action *a;
708
709 for (a = init_action_list; a; a = a->next) {
710 if (!(a->action_type & RESTART))
711 continue;
712
713 /* Starting from here, we won't return.
714 * Thus don't need to worry about preserving errno
715 * and such.
716 */
717
718 reset_sighandlers_and_unblock_sigs();
719
720 run_shutdown_and_kill_processes();
721
722#ifdef RB_ENABLE_CAD
723 /* Allow Ctrl-Alt-Del to reboot the system.
724 * This is how kernel sets it up for init, we follow suit.
725 */
726 reboot(RB_ENABLE_CAD); /* misnomer */
727#endif
728
729 if (open_stdio_to_tty(a->terminal)) {
730 dbg_message(L_CONSOLE, "Trying to re-exec %s", a->command);
731 /* Theoretically should be safe.
732 * But in practice, kernel bugs may leave
733 * unkillable processes, and wait() may block forever.
734 * Oh well. Hoping "new" init won't be too surprised
735 * by having children it didn't create.
736 */
737 //while (wait(NULL) > 0)
738 // continue;
739 init_exec(a->command);
740 }
741 /* Open or exec failed */
742 pause_and_low_level_reboot(RB_HALT_SYSTEM);
743 /* not reached */
744 }
745}
746
747/* The SIGSTOP/SIGTSTP handler
748 * NB: inside it, all signals except SIGCONT are masked
749 * via appropriate setup in sigaction().
750 */
751static void stop_handler(int sig UNUSED_PARAM)
752{
753 smallint saved_bb_got_signal;
754 int saved_errno;
755
756 saved_bb_got_signal = bb_got_signal;
757 saved_errno = errno;
758 signal(SIGCONT, record_signo);
759
760 while (1) {
761 pid_t wpid;
762
763 if (bb_got_signal == SIGCONT)
764 break;
765 /* NB: this can accidentally wait() for a process
766 * which we waitfor() elsewhere! waitfor() must have
767 * code which is resilient against this.
768 */
769 wpid = wait_any_nohang(NULL);
770 mark_terminated(wpid);
771 sleep(1);
772 }
773
774 signal(SIGCONT, SIG_DFL);
775 errno = saved_errno;
776 bb_got_signal = saved_bb_got_signal;
777}
778
779#if ENABLE_FEATURE_USE_INITTAB
780static void reload_inittab(void)
781{
782 struct init_action *a, **nextp;
783
784 message(L_LOG, "reloading /etc/inittab");
785
786 /* Disable old entries */
787 for (a = init_action_list; a; a = a->next)
788 a->action_type = 0;
789
790 /* Append new entries, or modify existing entries
791 * (incl. setting a->action_type) if cmd and device name
792 * match new ones. End result: only entries with
793 * a->action_type == 0 are stale.
794 */
795 parse_inittab();
796
797#if ENABLE_FEATURE_KILL_REMOVED
798 /* Kill stale entries */
799 /* Be nice and send SIGTERM first */
800 for (a = init_action_list; a; a = a->next)
801 if (a->action_type == 0 && a->pid != 0)
802 kill(a->pid, SIGTERM);
803 if (CONFIG_FEATURE_KILL_DELAY) {
804 /* NB: parent will wait in NOMMU case */
805 if ((BB_MMU ? fork() : vfork()) == 0) { /* child */
806 sleep(CONFIG_FEATURE_KILL_DELAY);
807 for (a = init_action_list; a; a = a->next)
808 if (a->action_type == 0 && a->pid != 0)
809 kill(a->pid, SIGKILL);
810 _exit(EXIT_SUCCESS);
811 }
812 }
813#endif
814
815 /* Remove stale entries and SYSINIT entries.
816 * We never rerun SYSINIT entries anyway,
817 * removing them too saves a few bytes */
818 nextp = &init_action_list;
819 while ((a = *nextp) != NULL) {
820 if ((a->action_type & ~SYSINIT) == 0) {
821 *nextp = a->next;
822 free(a);
823 } else {
824 nextp = &a->next;
825 }
826 }
827
828 /* Not needed: */
829 /* run_actions(RESPAWN | ASKFIRST); */
830 /* - we return to main loop, which does this automagically */
831}
832#endif
833
834static int check_delayed_sigs(void)
835{
836 int sigs_seen = 0;
837
838 while (1) {
839 smallint sig = bb_got_signal;
840
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: