1SUMMARY = "Tiny versions of many common UNIX utilities in a single small executable"
2DESCRIPTION = "BusyBox combines tiny versions of many common UNIX utilities into a single small executable. It provides minimalist replacements for most of the utilities you usually find in GNU fileutils, shellutils, etc. The utilities in BusyBox generally have fewer options than their full-featured GNU cousins; however, the options that are included provide the expected functionality and behave very much like their GNU counterparts. BusyBox provides a fairly complete POSIX environment for any small or embedded system."
3HOMEPAGE = "https://www.busybox.net"
4BUGTRACKER = "https://bugs.busybox.net/"
5
6DEPENDS += "kern-tools-native virtual/crypt"
7
8# bzip2 applet in busybox is based on lightly-modified bzip2-1.0.4 source
9# the GPL is version 2 only
10LICENSE = "GPLv2 & bzip2-1.0.4"
11LIC_FILES_CHKSUM = "file://LICENSE;md5=de10de48642ab74318e893a61105afbb \
12                    file://archival/libarchive/bz/LICENSE;md5=28e3301eae987e8cfe19988e98383dae"
13
14SECTION = "base"
15
16# Whether to split the suid apps into a seperate binary
17BUSYBOX_SPLIT_SUID ?= "1"
18
19export EXTRA_CFLAGS = "${CFLAGS}"
20export EXTRA_LDFLAGS = "${LDFLAGS}"
21
22EXTRA_OEMAKE = "CC='${CC}' LD='${CCLD}' V=1 ARCH=${TARGET_ARCH} CROSS_COMPILE=${TARGET_PREFIX} SKIP_STRIP=y HOSTCC='${BUILD_CC}' HOSTCPP='${BUILD_CPP}'"
23
24PACKAGES =+ "${PN}-httpd ${PN}-udhcpd ${PN}-udhcpc ${PN}-syslog ${PN}-mdev ${PN}-hwclock"
25
26FILES_${PN}-httpd = "${sysconfdir}/init.d/busybox-httpd /srv/www"
27FILES_${PN}-syslog = "${sysconfdir}/init.d/syslog* ${sysconfdir}/syslog-startup.conf* ${sysconfdir}/syslog.conf* ${systemd_unitdir}/system/syslog.service ${sysconfdir}/default/busybox-syslog"
28FILES_${PN}-mdev = "${sysconfdir}/init.d/mdev ${sysconfdir}/mdev.conf ${sysconfdir}/mdev/*"
29FILES_${PN}-udhcpd = "${sysconfdir}/init.d/busybox-udhcpd"
30FILES_${PN}-udhcpc = "${sysconfdir}/udhcpc.d ${datadir}/udhcpc"
31FILES_${PN}-hwclock = "${sysconfdir}/init.d/hwclock.sh"
32
33INITSCRIPT_PACKAGES = "${PN}-httpd ${PN}-syslog ${PN}-udhcpd ${PN}-mdev ${PN}-hwclock"
34
35INITSCRIPT_NAME_${PN}-httpd = "busybox-httpd"
36INITSCRIPT_NAME_${PN}-hwclock = "hwclock.sh"
37INITSCRIPT_NAME_${PN}-mdev = "mdev"
38INITSCRIPT_PARAMS_${PN}-mdev = "start 04 S ."
39INITSCRIPT_NAME_${PN}-syslog = "syslog"
40INITSCRIPT_NAME_${PN}-udhcpd = "busybox-udhcpd"
41
42SYSTEMD_PACKAGES = "${PN}-syslog"
43SYSTEMD_SERVICE_${PN}-syslog = "${@bb.utils.contains('SRC_URI', 'file://syslog.cfg', 'busybox-syslog.service', '', d)}"
44
45RDEPENDS_${PN}-syslog = "busybox"
46CONFFILES_${PN}-syslog = "${sysconfdir}/syslog-startup.conf"
47RCONFLICTS_${PN}-syslog = "rsyslog sysklogd syslog-ng"
48
49CONFFILES_${PN}-mdev = "${sysconfdir}/mdev.conf"
50
51RRECOMMENDS_${PN} = "${PN}-udhcpc"
52
53RDEPENDS_${PN} = "${@["", "busybox-inittab"][(d.getVar('VIRTUAL-RUNTIME_init_manager') == 'busybox')]}"
54
55inherit cml1 systemd update-rc.d ptest
56
57# busybox's unzip test case needs zip command, which busybox itself does not provide
58RDEPENDS_${PN}-ptest = "zip"
59
60# internal helper
61def busybox_cfg(feature, tokens, cnf, rem):
62    if type(tokens) == type(""):
63        tokens = [tokens]
64    rem.extend(['/^[# ]*' + token + '[ =]/d' for token in tokens])
65    if feature:
66        cnf.extend([token + '=y' for token in tokens])
67    else:
68        cnf.extend(['# ' + token + ' is not set' for token in tokens])
69
70# Map distro features to config settings
71def features_to_busybox_settings(d):
72    cnf, rem = ([], [])
73    busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'ipv6', True, False, d), 'CONFIG_FEATURE_IPV6', cnf, rem)
74    busybox_cfg(True, 'CONFIG_LFS', cnf, rem)
75    busybox_cfg(True, 'CONFIG_FDISK_SUPPORT_LARGE_DISKS', cnf, rem)
76    busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'nls', True, False, d), 'CONFIG_LOCALE_SUPPORT', cnf, rem)
77    busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'ipv4', True, False, d), 'CONFIG_FEATURE_IFUPDOWN_IPV4', cnf, rem)
78    busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'ipv6', True, False, d), 'CONFIG_FEATURE_IFUPDOWN_IPV6', cnf, rem)
79    busybox_cfg(bb.utils.contains_any('DISTRO_FEATURES', 'bluetooth wifi', True, False, d), 'CONFIG_RFKILL', cnf, rem)
80    return "\n".join(cnf), "\n".join(rem)
81
82# X, Y = ${@features_to_busybox_settings(d)}
83# unfortunately doesn't seem to work with bitbake, workaround:
84def features_to_busybox_conf(d):
85    cnf, rem = features_to_busybox_settings(d)
86    return cnf
87def features_to_busybox_del(d):
88    cnf, rem = features_to_busybox_settings(d)
89    return rem
90
91configmangle = '/CONFIG_EXTRA_CFLAGS/d; \
92		'
93OE_FEATURES := "${@features_to_busybox_conf(d)}"
94OE_DEL      := "${@features_to_busybox_del(d)}"
95DO_IPv4 := "${@bb.utils.contains('DISTRO_FEATURES', 'ipv4', 1, 0, d)}"
96DO_IPv6 := "${@bb.utils.contains('DISTRO_FEATURES', 'ipv6', 1, 0, d)}"
97
98python () {
99  if "${OE_DEL}":
100    d.setVar('configmangle_append', "${OE_DEL}" + "\n")
101  if "${OE_FEATURES}":
102    d.setVar('configmangle_append',
103                   "/^### DISTRO FEATURES$/a\\\n%s\n\n" %
104                   ("\\n".join((d.expand("${OE_FEATURES}").split("\n")))))
105  d.setVar('configmangle_append',
106                 "/^### CROSS$/a\\\n%s\n" %
107                  ("\\n".join(["CONFIG_EXTRA_CFLAGS=\"${CFLAGS} ${HOST_CC_ARCH}\""
108                        ])
109                  ))
110}
111
112do_prepare_config () {
113	if [ "${BUILD_REPRODUCIBLE_BINARIES}" = "1" ]; then
114		export KCONFIG_NOTIMESTAMP=1
115	fi
116	sed -e '/CONFIG_STATIC/d' \
117		< ${WORKDIR}/defconfig > ${S}/.config
118	echo "# CONFIG_STATIC is not set" >> .config
119	for i in 'CROSS' 'DISTRO FEATURES'; do echo "### $i"; done >> \
120		${S}/.config
121	sed -i -e '${configmangle}' ${S}/.config
122	if test ${DO_IPv4} -eq 0 && test ${DO_IPv6} -eq 0; then
123		# disable networking applets
124		mv ${S}/.config ${S}/.config.oe-tmp
125		awk 'BEGIN{net=0}
126		/^# Networking Utilities/{net=1}
127		/^#$/{if(net){net=net+1}}
128		{if(net==2&&$0 !~ /^#/&&$1){print("# "$1" is not set")}else{print}}' \
129		${S}/.config.oe-tmp > ${S}/.config
130	fi
131	sed -i 's/CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n"/CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -b"/' ${S}/.config
132	if [ -n "${DEBUG_PREFIX_MAP}" ]; then
133		sed -i 's|${DEBUG_PREFIX_MAP}||g' ${S}/.config
134	fi
135}
136
137do_configure () {
138	set -x
139	do_prepare_config
140	merge_config.sh -m .config ${@" ".join(find_cfgs(d))}
141	cml1_do_configure
142}
143
144do_compile() {
145	unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS
146	if [ "${BUILD_REPRODUCIBLE_BINARIES}" = "1" ]; then
147		export KCONFIG_NOTIMESTAMP=1
148	fi
149	if [ "${BUSYBOX_SPLIT_SUID}" = "1" -a x`grep "CONFIG_FEATURE_INDIVIDUAL=y" .config` = x ]; then
150		# split the .config into two parts, and make two busybox binaries
151		if [ -e .config.orig ]; then
152			# Need to guard again an interrupted do_compile - restore any backup
153			cp .config.orig .config
154		fi
155		cp .config .config.orig
156		oe_runmake busybox.cfg.suid
157		oe_runmake busybox.cfg.nosuid
158
159		# workaround for suid bug 10346
160		if ! grep -q "CONFIG_SH_IS_NONE" busybox.cfg.nosuid; then
161			echo "CONFIG_SH_IS_NONE" >> busybox.cfg.suid
162		fi
163
164		for i in `cat busybox.cfg.suid busybox.cfg.nosuid`; do
165			echo "# $i is not set" >> .config.disable.apps
166		done
167		merge_config.sh -m .config.orig .config.disable.apps
168		cp .config .config.nonapps
169		for s in suid nosuid; do
170			cat busybox.cfg.$s | while read item; do
171				grep -w "$item" .config.orig
172			done > .config.app.$s
173
174			# workaround for suid bug 10346
175			if [ "$s" = "suid" ] ; then
176				sed "s/.*CONFIG_SH_IS_NONE.*$/CONFIG_SH_IS_NONE=y/" -i .config.app.suid
177			fi
178
179			merge_config.sh -m .config.nonapps .config.app.$s
180			oe_runmake busybox_unstripped
181			mv busybox_unstripped busybox.$s
182			oe_runmake busybox.links
183			sort busybox.links > busybox.links.$s
184			rm busybox.links
185		done
186
187		# hard fail if sh is being linked to the suid busybox (detects bug 10346)
188		if grep -q -x "/bin/sh" busybox.links.suid; then
189			bbfatal "busybox suid binary incorrectly provides /bin/sh"
190		fi
191
192		# copy .config.orig back to .config, because the install process may check this file
193		cp .config.orig .config
194		# cleanup
195		rm .config.orig .config.app.suid .config.app.nosuid .config.disable.apps .config.nonapps
196	else
197		oe_runmake busybox_unstripped
198		cp busybox_unstripped busybox
199		oe_runmake busybox.links
200	fi
201}
202
203do_install () {
204	sed -i "s:^/bin/:BASE_BINDIR/:" busybox.links*
205	sed -i "s:^/sbin/:BASE_SBINDIR/:" busybox.links*
206	sed -i "s:^/usr/bin/:BINDIR/:" busybox.links*
207	sed -i "s:^/usr/sbin/:SBINDIR/:" busybox.links*
208
209	# Move arch/link to BINDIR to match coreutils
210	sed -i "s:^BASE_BINDIR/arch:BINDIR/arch:" busybox.links*
211	sed -i "s:^BASE_BINDIR/link:BINDIR/link:" busybox.links*
212
213	sed -i "s:^BASE_BINDIR/:${base_bindir}/:" busybox.links*
214	sed -i "s:^BASE_SBINDIR/:${base_sbindir}/:" busybox.links*
215	sed -i "s:^BINDIR/:${bindir}/:" busybox.links*
216	sed -i "s:^SBINDIR/:${sbindir}/:" busybox.links*
217
218	install -d ${D}${sysconfdir}/init.d
219
220	if ! grep -q "CONFIG_FEATURE_INDIVIDUAL=y" ${B}/.config; then
221		# Install ${base_bindir}/busybox, and the ${base_bindir}/sh link so the postinst script
222		# can run. Let update-alternatives handle the rest.
223		install -d ${D}${base_bindir}
224		if [ "${BUSYBOX_SPLIT_SUID}" = "1" ]; then
225			install -m 4755 ${B}/busybox.suid ${D}${base_bindir}
226			install -m 0755 ${B}/busybox.nosuid ${D}${base_bindir}
227			install -m 0644 ${S}/busybox.links.suid ${D}${sysconfdir}
228			install -m 0644 ${S}/busybox.links.nosuid ${D}${sysconfdir}
229			if grep -q "CONFIG_SH_IS_ASH=y" ${B}/.config; then
230				ln -sf busybox.nosuid ${D}${base_bindir}/sh
231			fi
232			# Keep a default busybox for people who want to invoke busybox directly.
233			# This is also useful for the on device upgrade. Because we want
234			# to use the busybox command in postinst.
235			ln -sf busybox.nosuid ${D}${base_bindir}/busybox
236		else
237			if grep -q "CONFIG_FEATURE_SUID=y" ${B}/.config; then
238				install -m 4755 ${B}/busybox ${D}${base_bindir}
239			else
240				install -m 0755 ${B}/busybox ${D}${base_bindir}
241			fi
242			install -m 0644 ${S}/busybox.links ${D}${sysconfdir}
243			if grep -q "CONFIG_SH_IS_ASH=y" ${B}/.config; then
244				ln -sf busybox ${D}${base_bindir}/sh
245			fi
246			# We make this symlink here to eliminate the error when upgrading together
247			# with busybox-syslog. Without this symlink, the opkg may think of the
248			# busybox.nosuid as obsolete and remove it, resulting in dead links like
249			# ${base_bindir}/sed -> ${base_bindir}/busybox.nosuid. This will make upgrading busybox-syslog fail.
250			# This symlink will be safely deleted in postinst, thus no negative effect.
251			ln -sf busybox ${D}${base_bindir}/busybox.nosuid
252		fi
253	else
254		install -d ${D}${base_bindir} ${D}${bindir} ${D}${libdir}
255		cat busybox.links | while read FILE; do
256			NAME=`basename "$FILE"`
257			install -m 0755 "0_lib/$NAME" "${D}$FILE.${BPN}"
258		done
259		# add suid bit where needed
260		for i in `grep -E "APPLET.*BB_SUID_((MAYBE|REQUIRE))" include/applets.h | grep -v _BB_SUID_DROP | cut -f 3 -d '(' | cut -f 1 -d ','`; do
261			find ${D} -name $i.${BPN} -exec chmod a+s {} \;
262		done
263		install -m 0755 0_lib/libbusybox.so.${PV} ${D}${libdir}/libbusybox.so.${PV}
264		ln -sf sh.${BPN} ${D}${base_bindir}/sh
265		ln -sf ln.${BPN} ${D}${base_bindir}/ln
266		ln -sf test.${BPN} ${D}${bindir}/test
267		if [ -f ${D}/linuxrc.${BPN} ]; then
268			mv ${D}/linuxrc.${BPN} ${D}/linuxrc
269		fi
270		install -m 0644 ${S}/busybox.links ${D}${sysconfdir}
271	fi
272
273	if grep -q "CONFIG_SYSLOGD=y" ${B}/.config; then
274		install -m 0755 ${WORKDIR}/syslog ${D}${sysconfdir}/init.d/syslog
275		install -m 644 ${WORKDIR}/syslog-startup.conf ${D}${sysconfdir}/syslog-startup.conf
276		install -m 644 ${WORKDIR}/syslog.conf ${D}${sysconfdir}/syslog.conf
277	fi
278	if grep -q "CONFIG_CROND=y" ${B}/.config; then
279		install -m 0755 ${WORKDIR}/busybox-cron ${D}${sysconfdir}/init.d/
280	fi
281	if grep -q "CONFIG_HTTPD=y" ${B}/.config; then
282		install -m 0755 ${WORKDIR}/busybox-httpd ${D}${sysconfdir}/init.d/
283		install -d ${D}/srv/www
284	fi
285	if grep -q "CONFIG_UDHCPD=y" ${B}/.config; then
286		install -m 0755 ${WORKDIR}/busybox-udhcpd ${D}${sysconfdir}/init.d/
287	fi
288	if grep -q "CONFIG_HWCLOCK=y" ${B}/.config; then
289		install -m 0755 ${WORKDIR}/hwclock.sh ${D}${sysconfdir}/init.d/
290	fi
291	if grep -q "CONFIG_UDHCPC=y" ${B}/.config; then
292		install -d ${D}${sysconfdir}/udhcpc.d
293		install -d ${D}${datadir}/udhcpc
294		install -m 0755 ${WORKDIR}/simple.script ${D}${sysconfdir}/udhcpc.d/50default
295		sed -i "s:/SBIN_DIR/:${base_sbindir}/:" ${D}${sysconfdir}/udhcpc.d/50default
296		install -m 0755 ${WORKDIR}/default.script ${D}${datadir}/udhcpc/default.script
297	fi
298	if grep -q "CONFIG_INETD=y" ${B}/.config; then
299		install -m 0755 ${WORKDIR}/inetd ${D}${sysconfdir}/init.d/inetd.${BPN}
300		sed -i "s:/usr/sbin/:${sbindir}/:" ${D}${sysconfdir}/init.d/inetd.${BPN}
301		install -m 0644 ${WORKDIR}/inetd.conf ${D}${sysconfdir}/
302	fi
303	if grep -q "CONFIG_MDEV=y" ${B}/.config; then
304		install -m 0755 ${WORKDIR}/mdev ${D}${sysconfdir}/init.d/mdev
305		if grep "CONFIG_FEATURE_MDEV_CONF=y" ${B}/.config; then
306			install -m 644 ${WORKDIR}/mdev.conf ${D}${sysconfdir}/mdev.conf
307			install -d ${D}${sysconfdir}/mdev
308			install -m 0755 ${WORKDIR}/find-touchscreen.sh ${D}${sysconfdir}/mdev
309			install -m 0755 ${WORKDIR}/mdev-mount.sh ${D}${sysconfdir}/mdev
310		fi
311	fi
312	if grep -q "CONFIG_INIT=y" ${B}/.config && ${@bb.utils.contains('VIRTUAL-RUNTIME_init_manager','busybox','true','false',d)}; then
313		install -D -m 0755 ${WORKDIR}/rcS ${D}${sysconfdir}/init.d/rcS
314		install -D -m 0755 ${WORKDIR}/rcK ${D}${sysconfdir}/init.d/rcK
315		install -D -m 0755 ${WORKDIR}/rcS.default ${D}${sysconfdir}/default/rcS
316	fi
317
318	if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
319		if grep -q "CONFIG_KLOGD=y" ${B}/.config; then
320			install -d ${D}${systemd_unitdir}/system
321			sed 's,@base_sbindir@,${base_sbindir},g' < ${WORKDIR}/busybox-klogd.service.in \
322			> ${D}${systemd_unitdir}/system/busybox-klogd.service
323		fi
324
325		if grep -q "CONFIG_SYSLOGD=y" ${B}/.config; then
326			install -d ${D}${systemd_unitdir}/system
327			sed 's,@base_sbindir@,${base_sbindir},g' < ${WORKDIR}/busybox-syslog.service.in \
328			> ${D}${systemd_unitdir}/system/busybox-syslog.service
329			if  [ ! -e ${D}${systemd_unitdir}/system/busybox-klogd.service ] ; then
330				sed -i '/klog/d' ${D}${systemd_unitdir}/system/busybox-syslog.service
331			fi
332			if [ -f ${WORKDIR}/busybox-syslog.default ] ; then
333				install -d ${D}${sysconfdir}/default
334				install -m 0644 ${WORKDIR}/busybox-syslog.default ${D}${sysconfdir}/default/busybox-syslog
335			fi
336		fi
337	fi
338
339	# Remove the sysvinit specific configuration file for systemd systems to avoid confusion
340	if ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', 'false', 'true', d)}; then
341		rm -f ${D}${sysconfdir}/syslog-startup.conf
342	fi
343}
344
345PTEST_BINDIR = "1"
346
347do_install_ptest () {
348	cp -r ${B}/testsuite ${D}${PTEST_PATH}/
349        # These access the internet which is not guaranteed to work on machines running the tests
350        rm -rf ${D}${PTEST_PATH}/testsuite/wget
351	sort ${B}/.config > ${D}${PTEST_PATH}/.config
352	ln -s /bin/busybox   ${D}${PTEST_PATH}/busybox
353}
354
355inherit update-alternatives
356
357ALTERNATIVE_PRIORITY = "50"
358
359python do_package_prepend () {
360    # We need to load the full set of busybox provides from the /etc/busybox.links
361    # Use this to see the update-alternatives with the right information
362
363    dvar = d.getVar('D')
364    pn = d.getVar('PN')
365    def set_alternative_vars(links, target):
366        links = d.expand(links)
367        target = d.expand(target)
368        f = open('%s%s' % (dvar, links), 'r')
369        for alt_link_name in f:
370            alt_link_name = alt_link_name.strip()
371            alt_name = os.path.basename(alt_link_name)
372            # Match coreutils
373            if alt_name == '[':
374                alt_name = 'lbracket'
375            if alt_name == 'klogd' or alt_name == 'syslogd':
376                d.appendVar('ALTERNATIVE_%s-syslog' % (pn), ' ' + alt_name)
377            else:
378                d.appendVar('ALTERNATIVE_%s' % (pn), ' ' + alt_name)
379            d.setVarFlag('ALTERNATIVE_LINK_NAME', alt_name, alt_link_name)
380            if os.path.exists('%s%s' % (dvar, target)):
381                d.setVarFlag('ALTERNATIVE_TARGET', alt_name, target)
382        f.close()
383        return
384
385    if os.path.exists('%s/etc/busybox.links' % (dvar)):
386        set_alternative_vars("${sysconfdir}/busybox.links", "${base_bindir}/busybox")
387    else:
388        set_alternative_vars("${sysconfdir}/busybox.links.nosuid", "${base_bindir}/busybox.nosuid")
389        set_alternative_vars("${sysconfdir}/busybox.links.suid", "${base_bindir}/busybox.suid")
390}
391
392# This part of code is dedicated to the on target upgrade problem.  It's known
393# that if we don't make appropriate symlinks before update-alternatives calls,
394# there will be errors indicating missing commands such as 'sed'.
395# These symlinks will later be updated by update-alternatives calls.
396# The update-alternatives.bbclass' postinst script runs firstly before other
397# postinst, but this part of code needs run firstly, so add this funtion.
398python populate_packages_updatealternatives_append() {
399    postinst = """
400test -n 2 > /dev/null || alias test='busybox test'
401if test "x$D" = "x"; then
402    # Remove busybox.nosuid if it's a symlink, because this situation indicates
403    # that we're installing or upgrading to a one-binary busybox.
404    if test -h ${base_bindir}/busybox.nosuid; then
405        rm -f ${base_bindir}/busybox.nosuid
406    fi
407    for suffix in "" ".nosuid" ".suid"; do
408        if test -e ${sysconfdir}/busybox.links$suffix; then
409            while read link; do
410                if test ! -e "$link"; then
411                    # we can use busybox here because even if we are using splitted busybox
412                    # we've made a symlink from /bin/busybox to /bin/busybox.nosuid.
413                    busybox rm -f $link
414                    busybox ln -s "${base_bindir}/busybox$suffix" $link
415                fi
416            done < ${sysconfdir}/busybox.links$suffix
417        fi
418    done
419fi
420if grep -q "^${base_bindir}/bash$" $D${sysconfdir}/busybox.links*; then
421    grep -q "^${base_bindir}/bash$" $D${sysconfdir}/shells || echo ${base_bindir}/bash >> $D${sysconfdir}/shells
422fi
423
424"""
425    d.prependVar('pkg_postinst_%s' % pkg, postinst)
426}
427
428pkg_postinst_${PN}_prepend () {
429        # Need path to saved utils, but they may have be removed on upgrade of busybox
430        # Only use shell to get paths. Also capture if busybox was saved.
431        BUSYBOX=""
432        if [ "x$D" = "x" ] ; then
433           for busybox_rmdir in /tmp/busyboxrm-*; do
434               if [ "$busybox_rmdir" != '/tmp/busyboxrm-*' ] ; then
435                  export PATH=$busybox_rmdir:$PATH
436                  if [ -e $busybox_rmdir/busybox* ] ; then
437                    BUSYBOX="$busybox_rmdir/busybox*"
438                  fi
439               fi
440           done
441        fi
442}
443
444pkg_postinst_${PN}_append () {
445        # If busybox exists in the remove directory it is because it was the only shell left.
446        if [ "x$D" = "x" ] ; then
447           if [ "x$BUSYBOX" != "x" ] ; then
448              update-alternatives --remove sh $BUSYBOX
449              rm -f $BUSYBOX
450           fi
451        fi
452}
453
454pkg_prerm_${PN} () {
455	# This is so you can make busybox commit suicide - removing busybox with no other packages
456	# providing its files, this will make update-alternatives work, but the update-rc.d part
457	# for syslog, httpd and/or udhcpd will fail if there is no other package providing sh
458	tmpdir=`mktemp -d /tmp/busyboxrm-XXXXXX`
459	ln -s ${base_bindir}/busybox $tmpdir/[
460	ln -s ${base_bindir}/busybox $tmpdir/test
461	ln -s ${base_bindir}/busybox $tmpdir/head
462	ln -s ${base_bindir}/busybox $tmpdir/sh
463	ln -s ${base_bindir}/busybox $tmpdir/basename
464	ln -s ${base_bindir}/busybox $tmpdir/echo
465	ln -s ${base_bindir}/busybox $tmpdir/mv
466	ln -s ${base_bindir}/busybox $tmpdir/ln
467	ln -s ${base_bindir}/busybox $tmpdir/dirname
468	ln -s ${base_bindir}/busybox $tmpdir/rm
469	ln -s ${base_bindir}/busybox $tmpdir/sed
470	ln -s ${base_bindir}/busybox $tmpdir/sort
471	ln -s ${base_bindir}/busybox $tmpdir/grep
472	ln -s ${base_bindir}/busybox $tmpdir/tail
473	export PATH=$PATH:$tmpdir
474
475        # If busybox is the shell, we need to save it since its the lowest priority shell
476        # Register saved bitbake as the lowest priority shell possible as back up.
477        if [ -n "$(readlink -f /bin/sh | grep busybox)" ] ; then
478           BUSYBOX=$(readlink -f /bin/sh)
479           cp $BUSYBOX $tmpdir/$(basename $BUSYBOX)
480           update-alternatives --install /bin/sh sh $tmpdir/$(basename $BUSYBOX) 1
481        fi
482}
483
484pkg_postrm_${PN} () {
485        # Add path to remove dir in case we removed our only grep
486        if [ "x$D" = "x" ] ; then
487           for busybox_rmdir in /tmp/busyboxrm-*; do
488               if [ "$busybox_rmdir" != '/tmp/busyboxrm-*' ] ; then
489                  export PATH=$busybox_rmdir:$PATH
490               fi
491           done
492        fi
493
494	if grep -q "^${base_bindir}/bash$" $D${sysconfdir}/busybox.links* && [ ! -e $D${base_bindir}/bash ]; then
495		printf "$(grep -v "^${base_bindir}/bash$" $D${sysconfdir}/shells)\n" > $D${sysconfdir}/shells
496	fi
497}
498
499pkg_prerm_${PN}-syslog () {
500	# remove syslog
501	if test "x$D" = "x"; then
502		if test "$1" = "upgrade" -o "$1" = "remove"; then
503			${sysconfdir}/init.d/syslog stop || :
504		fi
505	fi
506}
507
508RPROVIDES_${PN} += "${@bb.utils.contains('DISTRO_FEATURES', 'usrmerge', '/bin/sh /bin/ash', '', d)}"
509