xref: /OK3568_Linux_fs/yocto/poky/meta/recipes-core/busybox/busybox.inc (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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 = "GPL-2.0-only & 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_system_unitdir}/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	export KCONFIG_NOTIMESTAMP=1
114
115	sed -e '/CONFIG_STATIC/d' \
116		< ${WORKDIR}/defconfig > ${S}/.config
117	echo "# CONFIG_STATIC is not set" >> .config
118	for i in 'CROSS' 'DISTRO FEATURES'; do echo "### $i"; done >> \
119		${S}/.config
120	sed -i -e '${configmangle}' ${S}/.config
121	if test ${DO_IPv4} -eq 0 && test ${DO_IPv6} -eq 0; then
122		# disable networking applets
123		mv ${S}/.config ${S}/.config.oe-tmp
124		awk 'BEGIN{net=0}
125		/^# Networking Utilities/{net=1}
126		/^#$/{if(net){net=net+1}}
127		{if(net==2&&$0 !~ /^#/&&$1){print("# "$1" is not set")}else{print}}' \
128		${S}/.config.oe-tmp > ${S}/.config
129	fi
130	sed -i 's/CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n"/CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -b"/' ${S}/.config
131	if [ -n "${DEBUG_PREFIX_MAP}" ]; then
132		sed -i 's|${DEBUG_PREFIX_MAP}||g' ${S}/.config
133	fi
134}
135
136do_configure () {
137	set -x
138	do_prepare_config
139	merge_config.sh -m .config ${@" ".join(find_cfgs(d))}
140	cml1_do_configure
141
142	# Save a copy of .config and autoconf.h.
143	cp .config .config.orig
144	cp include/autoconf.h include/autoconf.h.orig
145}
146
147do_compile() {
148	unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS
149	export KCONFIG_NOTIMESTAMP=1
150
151	# Ensure we start do_compile with the original .config and autoconf.h.
152	# These files should always have matching timestamps.
153	cp .config.orig .config
154	cp include/autoconf.h.orig include/autoconf.h
155
156	if [ "${BUSYBOX_SPLIT_SUID}" = "1" -a x`grep "CONFIG_FEATURE_INDIVIDUAL=y" .config` = x ]; then
157		# Guard againt interrupted do_compile: clean temporary files.
158		rm -f .config.app.suid .config.app.nosuid .config.disable.apps .config.nonapps
159
160		# split the .config into two parts, and make two busybox binaries
161		oe_runmake busybox.cfg.suid
162		oe_runmake busybox.cfg.nosuid
163
164		# workaround for suid bug 10346
165		if ! grep -q "CONFIG_SH_IS_NONE" busybox.cfg.nosuid; then
166			echo "CONFIG_SH_IS_NONE" >> busybox.cfg.suid
167		fi
168
169		for i in `cat busybox.cfg.suid busybox.cfg.nosuid`; do
170			echo "# $i is not set" >> .config.disable.apps
171		done
172		merge_config.sh -m .config.orig .config.disable.apps
173		cp .config .config.nonapps
174		for s in suid nosuid; do
175			cat busybox.cfg.$s | while read item; do
176				grep -w "$item" .config.orig
177			done > .config.app.$s
178
179			# workaround for suid bug 10346
180			if [ "$s" = "suid" ] ; then
181				sed "s/.*CONFIG_SH_IS_NONE.*$/CONFIG_SH_IS_NONE=y/" -i .config.app.suid
182			fi
183
184			merge_config.sh -m .config.nonapps .config.app.$s
185			oe_runmake busybox_unstripped
186			mv busybox_unstripped busybox.$s
187			oe_runmake busybox.links
188			sort busybox.links > busybox.links.$s
189			rm busybox.links
190		done
191
192		# hard fail if sh is being linked to the suid busybox (detects bug 10346)
193		if grep -q -x "/bin/sh" busybox.links.suid; then
194			bbfatal "busybox suid binary incorrectly provides /bin/sh"
195		fi
196
197		# cleanup
198		rm .config.app.suid .config.app.nosuid .config.disable.apps .config.nonapps
199	else
200		oe_runmake busybox_unstripped
201		cp busybox_unstripped busybox
202		oe_runmake busybox.links
203	fi
204
205	# restore original .config and autoconf.h, because the install process
206	# may check these files
207	cp .config.orig .config
208	cp include/autoconf.h.orig include/autoconf.h
209}
210
211do_install () {
212	sed -i "s:^/bin/:BASE_BINDIR/:" busybox.links*
213	sed -i "s:^/sbin/:BASE_SBINDIR/:" busybox.links*
214	sed -i "s:^/usr/bin/:BINDIR/:" busybox.links*
215	sed -i "s:^/usr/sbin/:SBINDIR/:" busybox.links*
216
217	# Move arch/link to BINDIR to match coreutils
218	sed -i "s:^BASE_BINDIR/arch:BINDIR/arch:" busybox.links*
219	sed -i "s:^BASE_BINDIR/link:BINDIR/link:" busybox.links*
220
221	sed -i "s:^BASE_BINDIR/:${base_bindir}/:" busybox.links*
222	sed -i "s:^BASE_SBINDIR/:${base_sbindir}/:" busybox.links*
223	sed -i "s:^BINDIR/:${bindir}/:" busybox.links*
224	sed -i "s:^SBINDIR/:${sbindir}/:" busybox.links*
225
226	install -d ${D}${sysconfdir}/init.d
227
228	if ! grep -q "CONFIG_FEATURE_INDIVIDUAL=y" ${B}/.config; then
229		# Install ${base_bindir}/busybox, and the ${base_bindir}/sh link so the postinst script
230		# can run. Let update-alternatives handle the rest.
231		install -d ${D}${base_bindir}
232		if [ "${BUSYBOX_SPLIT_SUID}" = "1" ]; then
233			install -m 4755 ${B}/busybox.suid ${D}${base_bindir}
234			install -m 0755 ${B}/busybox.nosuid ${D}${base_bindir}
235			install -m 0644 ${S}/busybox.links.suid ${D}${sysconfdir}
236			install -m 0644 ${S}/busybox.links.nosuid ${D}${sysconfdir}
237			if grep -q "CONFIG_SH_IS_ASH=y" ${B}/.config; then
238				ln -sf busybox.nosuid ${D}${base_bindir}/sh
239			fi
240			# Keep a default busybox for people who want to invoke busybox directly.
241			# This is also useful for the on device upgrade. Because we want
242			# to use the busybox command in postinst.
243			ln -sf busybox.nosuid ${D}${base_bindir}/busybox
244		else
245			if grep -q "CONFIG_FEATURE_SUID=y" ${B}/.config; then
246				install -m 4755 ${B}/busybox ${D}${base_bindir}
247			else
248				install -m 0755 ${B}/busybox ${D}${base_bindir}
249			fi
250			install -m 0644 ${S}/busybox.links ${D}${sysconfdir}
251			if grep -q "CONFIG_SH_IS_ASH=y" ${B}/.config; then
252				ln -sf busybox ${D}${base_bindir}/sh
253			fi
254			# We make this symlink here to eliminate the error when upgrading together
255			# with busybox-syslog. Without this symlink, the opkg may think of the
256			# busybox.nosuid as obsolete and remove it, resulting in dead links like
257			# ${base_bindir}/sed -> ${base_bindir}/busybox.nosuid. This will make upgrading busybox-syslog fail.
258			# This symlink will be safely deleted in postinst, thus no negative effect.
259			ln -sf busybox ${D}${base_bindir}/busybox.nosuid
260		fi
261	else
262		install -d ${D}${base_bindir} ${D}${bindir} ${D}${libdir}
263		cat busybox.links | while read FILE; do
264			NAME=`basename "$FILE"`
265			install -m 0755 "0_lib/$NAME" "${D}$FILE.${BPN}"
266		done
267		# add suid bit where needed
268		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
269			find ${D} -name $i.${BPN} -exec chmod a+s {} \;
270		done
271		install -m 0755 0_lib/libbusybox.so.${PV} ${D}${libdir}/libbusybox.so.${PV}
272		ln -sf sh.${BPN} ${D}${base_bindir}/sh
273		ln -sf ln.${BPN} ${D}${base_bindir}/ln
274		ln -sf test.${BPN} ${D}${bindir}/test
275		if [ -f ${D}/linuxrc.${BPN} ]; then
276			mv ${D}/linuxrc.${BPN} ${D}/linuxrc
277		fi
278		install -m 0644 ${S}/busybox.links ${D}${sysconfdir}
279	fi
280
281	if grep -q "CONFIG_SYSLOGD=y" ${B}/.config; then
282		install -m 0755 ${WORKDIR}/syslog ${D}${sysconfdir}/init.d/syslog
283		install -m 644 ${WORKDIR}/syslog-startup.conf ${D}${sysconfdir}/syslog-startup.conf
284		install -m 644 ${WORKDIR}/syslog.conf ${D}${sysconfdir}/syslog.conf
285	fi
286	if grep -q "CONFIG_CROND=y" ${B}/.config; then
287		install -m 0755 ${WORKDIR}/busybox-cron ${D}${sysconfdir}/init.d/
288	fi
289	if grep -q "CONFIG_HTTPD=y" ${B}/.config; then
290		install -m 0755 ${WORKDIR}/busybox-httpd ${D}${sysconfdir}/init.d/
291		install -d ${D}/srv/www
292	fi
293	if grep -q "CONFIG_UDHCPD=y" ${B}/.config; then
294		install -m 0755 ${WORKDIR}/busybox-udhcpd ${D}${sysconfdir}/init.d/
295	fi
296	if grep -q "CONFIG_HWCLOCK=y" ${B}/.config; then
297		install -m 0755 ${WORKDIR}/hwclock.sh ${D}${sysconfdir}/init.d/
298	fi
299	if grep -q "CONFIG_UDHCPC=y" ${B}/.config; then
300		install -d ${D}${sysconfdir}/udhcpc.d
301		install -d ${D}${datadir}/udhcpc
302		install -m 0755 ${WORKDIR}/simple.script ${D}${sysconfdir}/udhcpc.d/50default
303		sed -i "s:/SBIN_DIR/:${base_sbindir}/:" ${D}${sysconfdir}/udhcpc.d/50default
304		install -m 0755 ${WORKDIR}/default.script ${D}${datadir}/udhcpc/default.script
305	fi
306	if grep -q "CONFIG_INETD=y" ${B}/.config; then
307		install -m 0755 ${WORKDIR}/inetd ${D}${sysconfdir}/init.d/inetd.${BPN}
308		sed -i "s:/usr/sbin/:${sbindir}/:" ${D}${sysconfdir}/init.d/inetd.${BPN}
309		install -m 0644 ${WORKDIR}/inetd.conf ${D}${sysconfdir}/
310	fi
311	if grep -q "CONFIG_MDEV=y" ${B}/.config; then
312		install -m 0755 ${WORKDIR}/mdev ${D}${sysconfdir}/init.d/mdev
313		if grep "CONFIG_FEATURE_MDEV_CONF=y" ${B}/.config; then
314			install -m 644 ${WORKDIR}/mdev.conf ${D}${sysconfdir}/mdev.conf
315			install -d ${D}${sysconfdir}/mdev
316			install -m 0755 ${WORKDIR}/find-touchscreen.sh ${D}${sysconfdir}/mdev
317			install -m 0755 ${WORKDIR}/mdev-mount.sh ${D}${sysconfdir}/mdev
318		fi
319	fi
320	if grep -q "CONFIG_INIT=y" ${B}/.config && ${@bb.utils.contains('VIRTUAL-RUNTIME_init_manager','busybox','true','false',d)}; then
321		install -D -m 0755 ${WORKDIR}/rcS ${D}${sysconfdir}/init.d/rcS
322		install -D -m 0755 ${WORKDIR}/rcK ${D}${sysconfdir}/init.d/rcK
323		install -D -m 0755 ${WORKDIR}/rcS.default ${D}${sysconfdir}/default/rcS
324	fi
325
326	if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
327		if grep -q "CONFIG_KLOGD=y" ${B}/.config; then
328			install -d ${D}${systemd_system_unitdir}
329			sed 's,@base_sbindir@,${base_sbindir},g' < ${WORKDIR}/busybox-klogd.service.in \
330			> ${D}${systemd_system_unitdir}/busybox-klogd.service
331		fi
332
333		if grep -q "CONFIG_SYSLOGD=y" ${B}/.config; then
334			install -d ${D}${systemd_system_unitdir}
335			sed 's,@base_sbindir@,${base_sbindir},g' < ${WORKDIR}/busybox-syslog.service.in \
336			> ${D}${systemd_system_unitdir}/busybox-syslog.service
337			if  [ ! -e ${D}${systemd_system_unitdir}/busybox-klogd.service ] ; then
338				sed -i '/klog/d' ${D}${systemd_system_unitdir}/busybox-syslog.service
339			fi
340			if [ -f ${WORKDIR}/busybox-syslog.default ] ; then
341				install -d ${D}${sysconfdir}/default
342				install -m 0644 ${WORKDIR}/busybox-syslog.default ${D}${sysconfdir}/default/busybox-syslog
343			fi
344		fi
345	fi
346
347	# Remove the sysvinit specific configuration file for systemd systems to avoid confusion
348	if ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', 'false', 'true', d)}; then
349		rm -f ${D}${sysconfdir}/syslog-startup.conf
350	fi
351}
352
353PTEST_BINDIR = "1"
354
355do_install_ptest () {
356	cp -r ${B}/testsuite ${D}${PTEST_PATH}/
357        # These access the internet which is not guaranteed to work on machines running the tests
358        rm -rf ${D}${PTEST_PATH}/testsuite/wget
359	sort ${B}/.config > ${D}${PTEST_PATH}/.config
360	ln -s ${base_bindir}/busybox   ${D}${PTEST_PATH}/busybox
361}
362
363inherit update-alternatives
364
365ALTERNATIVE_PRIORITY = "50"
366
367python do_package:prepend () {
368    # We need to load the full set of busybox provides from the /etc/busybox.links
369    # Use this to see the update-alternatives with the right information
370
371    dvar = d.getVar('D')
372    pn = d.getVar('PN')
373    def set_alternative_vars(links, target):
374        links = d.expand(links)
375        target = d.expand(target)
376        f = open('%s%s' % (dvar, links), 'r')
377        for alt_link_name in f:
378            alt_link_name = alt_link_name.strip()
379            alt_name = os.path.basename(alt_link_name)
380            # Match coreutils
381            if alt_name == '[':
382                alt_name = 'lbracket'
383            if alt_name == 'klogd' or alt_name == 'syslogd':
384                d.appendVar('ALTERNATIVE:%s-syslog' % (pn), ' ' + alt_name)
385            else:
386                d.appendVar('ALTERNATIVE:%s' % (pn), ' ' + alt_name)
387            d.setVarFlag('ALTERNATIVE_LINK_NAME', alt_name, alt_link_name)
388            if os.path.exists('%s%s' % (dvar, target)):
389                d.setVarFlag('ALTERNATIVE_TARGET', alt_name, target)
390        f.close()
391        return
392
393    if os.path.exists('%s/etc/busybox.links' % (dvar)):
394        set_alternative_vars("${sysconfdir}/busybox.links", "${base_bindir}/busybox")
395    else:
396        set_alternative_vars("${sysconfdir}/busybox.links.nosuid", "${base_bindir}/busybox.nosuid")
397        set_alternative_vars("${sysconfdir}/busybox.links.suid", "${base_bindir}/busybox.suid")
398}
399
400# This part of code is dedicated to the on target upgrade problem.  It's known
401# that if we don't make appropriate symlinks before update-alternatives calls,
402# there will be errors indicating missing commands such as 'sed'.
403# These symlinks will later be updated by update-alternatives calls.
404# The update-alternatives.bbclass' postinst script runs firstly before other
405# postinst, but this part of code needs run firstly, so add this funtion.
406python populate_packages_updatealternatives:append() {
407    postinst = """
408test -n 2 > /dev/null || alias test='busybox test'
409if test "x$D" = "x"; then
410    # Remove busybox.nosuid if it's a symlink, because this situation indicates
411    # that we're installing or upgrading to a one-binary busybox.
412    if test -h ${base_bindir}/busybox.nosuid; then
413        rm -f ${base_bindir}/busybox.nosuid
414    fi
415    for suffix in "" ".nosuid" ".suid"; do
416        if test -e ${sysconfdir}/busybox.links$suffix; then
417            while read link; do
418                if test ! -e "$link"; then
419                    # we can use busybox here because even if we are using splitted busybox
420                    # we've made a symlink from /bin/busybox to /bin/busybox.nosuid.
421                    busybox rm -f $link
422                    busybox ln -s "${base_bindir}/busybox$suffix" $link
423                fi
424            done < ${sysconfdir}/busybox.links$suffix
425        fi
426    done
427fi
428if grep -q "^${base_bindir}/bash$" $D${sysconfdir}/busybox.links*; then
429    grep -q "^${base_bindir}/bash$" $D${sysconfdir}/shells || echo ${base_bindir}/bash >> $D${sysconfdir}/shells
430fi
431
432"""
433    d.prependVar('pkg_postinst:%s' % pkg, postinst)
434}
435
436pkg_postinst:${PN}:prepend () {
437        # Need path to saved utils, but they may have be removed on upgrade of busybox
438        # Only use shell to get paths. Also capture if busybox was saved.
439        BUSYBOX=""
440        if [ "x$D" = "x" ] ; then
441           for busybox_rmdir in /tmp/busyboxrm-*; do
442               if [ "$busybox_rmdir" != '/tmp/busyboxrm-*' ] ; then
443                  export PATH=$busybox_rmdir:$PATH
444                  if [ -e $busybox_rmdir/busybox* ] ; then
445                    BUSYBOX="$busybox_rmdir/busybox*"
446                  fi
447               fi
448           done
449        fi
450}
451
452pkg_postinst:${PN}:append () {
453        # If busybox exists in the remove directory it is because it was the only shell left.
454        if [ "x$D" = "x" ] ; then
455           if [ "x$BUSYBOX" != "x" ] ; then
456              update-alternatives --remove sh $BUSYBOX
457              rm -f $BUSYBOX
458           fi
459        fi
460}
461
462pkg_prerm:${PN} () {
463	# This is so you can make busybox commit suicide - removing busybox with no other packages
464	# providing its files, this will make update-alternatives work, but the update-rc.d part
465	# for syslog, httpd and/or udhcpd will fail if there is no other package providing sh
466	tmpdir=`mktemp -d /tmp/busyboxrm-XXXXXX`
467	ln -s ${base_bindir}/busybox $tmpdir/[
468	ln -s ${base_bindir}/busybox $tmpdir/test
469	ln -s ${base_bindir}/busybox $tmpdir/head
470	ln -s ${base_bindir}/busybox $tmpdir/sh
471	ln -s ${base_bindir}/busybox $tmpdir/basename
472	ln -s ${base_bindir}/busybox $tmpdir/echo
473	ln -s ${base_bindir}/busybox $tmpdir/mv
474	ln -s ${base_bindir}/busybox $tmpdir/ln
475	ln -s ${base_bindir}/busybox $tmpdir/dirname
476	ln -s ${base_bindir}/busybox $tmpdir/rm
477	ln -s ${base_bindir}/busybox $tmpdir/sed
478	ln -s ${base_bindir}/busybox $tmpdir/sort
479	ln -s ${base_bindir}/busybox $tmpdir/grep
480	ln -s ${base_bindir}/busybox $tmpdir/tail
481	export PATH=$PATH:$tmpdir
482
483        # If busybox is the shell, we need to save it since its the lowest priority shell
484        # Register saved bitbake as the lowest priority shell possible as back up.
485        if [ -n "$(readlink -f /bin/sh | grep busybox)" ] ; then
486           BUSYBOX=$(readlink -f /bin/sh)
487           cp $BUSYBOX $tmpdir/$(basename $BUSYBOX)
488           update-alternatives --install /bin/sh sh $tmpdir/$(basename $BUSYBOX) 1
489        fi
490}
491
492pkg_postrm:${PN} () {
493        # Add path to remove dir in case we removed our only grep
494        if [ "x$D" = "x" ] ; then
495           for busybox_rmdir in /tmp/busyboxrm-*; do
496               if [ "$busybox_rmdir" != '/tmp/busyboxrm-*' ] ; then
497                  export PATH=$busybox_rmdir:$PATH
498               fi
499           done
500        fi
501
502	if grep -q "^${base_bindir}/bash$" $D${sysconfdir}/busybox.links* && [ ! -e $D${base_bindir}/bash ]; then
503		printf "$(grep -v "^${base_bindir}/bash$" $D${sysconfdir}/shells)\n" > $D${sysconfdir}/shells
504	fi
505}
506
507pkg_prerm:${PN}-syslog () {
508	# remove syslog
509	if test "x$D" = "x"; then
510		if test "$1" = "upgrade" -o "$1" = "remove"; then
511			${sysconfdir}/init.d/syslog stop || :
512		fi
513	fi
514}
515
516RPROVIDES:${PN} += "${@bb.utils.contains('DISTRO_FEATURES', 'usrmerge', '/bin/sh /bin/ash', '', d)}"
517