blob: ed8f9fe7665bacef48d15234043cd38140aed72e [file] [log] [blame]
Patrick Williamsc124f4f2015-09-15 14:41:29 -05001SUMMARY = "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 = "http://www.busybox.net"
4BUGTRACKER = "https://bugs.busybox.net/"
5
6DEPENDS += "kern-tools-native"
7
8# bzip2 applet in busybox is based on lightly-modified bzip2 source
9# the GPL is version 2 only
10LICENSE = "GPLv2 & bzip2"
11LIC_FILES_CHKSUM = "file://LICENSE;md5=de10de48642ab74318e893a61105afbb"
12
13SECTION = "base"
14
15# Whether to split the suid apps into a seperate binary
16BUSYBOX_SPLIT_SUID ?= "1"
17
18export EXTRA_CFLAGS = "${CFLAGS}"
19export EXTRA_LDFLAGS = "${LDFLAGS}"
20export EXTRA_OEMAKE += "'LD=${CCLD}'"
21
22PACKAGES =+ "${PN}-httpd ${PN}-udhcpd ${PN}-udhcpc ${PN}-syslog ${PN}-mdev ${PN}-hwclock"
23
24FILES_${PN}-httpd = "${sysconfdir}/init.d/busybox-httpd /srv/www"
25FILES_${PN}-syslog = "${sysconfdir}/init.d/syslog* ${sysconfdir}/syslog-startup.conf* ${sysconfdir}/syslog.conf* ${systemd_unitdir}/system/syslog.service ${sysconfdir}/default/busybox-syslog"
26FILES_${PN}-mdev = "${sysconfdir}/init.d/mdev ${sysconfdir}/mdev.conf ${sysconfdir}/mdev/*"
27FILES_${PN}-udhcpd = "${sysconfdir}/init.d/busybox-udhcpd"
28FILES_${PN}-udhcpc = "${sysconfdir}/udhcpc.d ${datadir}/udhcpc"
29FILES_${PN}-hwclock = "${sysconfdir}/init.d/hwclock.sh"
30
31INITSCRIPT_PACKAGES = "${PN}-httpd ${PN}-syslog ${PN}-udhcpd ${PN}-mdev ${PN}-hwclock"
32
33INITSCRIPT_NAME_${PN}-httpd = "busybox-httpd"
34INITSCRIPT_NAME_${PN}-hwclock = "hwclock.sh"
35INITSCRIPT_NAME_${PN}-mdev = "mdev"
36INITSCRIPT_PARAMS_${PN}-mdev = "start 03 S ."
37INITSCRIPT_NAME_${PN}-syslog = "syslog"
38INITSCRIPT_NAME_${PN}-udhcpd = "busybox-udhcpd"
39
40SYSTEMD_PACKAGES = "${PN}-syslog"
41SYSTEMD_SERVICE_${PN}-syslog = "busybox-syslog.service"
42
43CONFFILES_${PN}-syslog = "${sysconfdir}/syslog-startup.conf.${BPN}"
44CONFFILES_${PN}-mdev = "${sysconfdir}/mdev.conf"
45
46RRECOMMENDS_${PN} = "${PN}-syslog ${PN}-udhcpc"
47
48inherit cml1 systemd update-rc.d ptest
49
50# internal helper
51def busybox_cfg(feature, tokens, cnf, rem):
52 if type(tokens) == type(""):
53 tokens = [tokens]
54 rem.extend(['/^[# ]*' + token + '[ =]/d' for token in tokens])
55 if feature:
56 cnf.extend([token + '=y' for token in tokens])
57 else:
58 cnf.extend(['# ' + token + ' is not set' for token in tokens])
59
60# Map distro features to config settings
61def features_to_busybox_settings(d):
62 cnf, rem = ([], [])
63 busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'ipv6', True, False, d), 'CONFIG_FEATURE_IPV6', cnf, rem)
64 busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'largefile', True, False, d), 'CONFIG_LFS', cnf, rem)
65 busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'largefile', True, False, d), 'CONFIG_FDISK_SUPPORT_LARGE_DISKS', cnf, rem)
66 busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'nls', True, False, d), 'CONFIG_LOCALE_SUPPORT', cnf, rem)
67 busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'ipv4', True, False, d), 'CONFIG_FEATURE_IFUPDOWN_IPV4', cnf, rem)
68 busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'ipv6', True, False, d), 'CONFIG_FEATURE_IFUPDOWN_IPV6', cnf, rem)
69 busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'wifi', True, False, d), 'CONFIG_RFKILL', cnf, rem)
70 busybox_cfg(bb.utils.contains('DISTRO_FEATURES', 'bluetooth', True, False, d), 'CONFIG_RFKILL', cnf, rem)
71 return "\n".join(cnf), "\n".join(rem)
72
73# X, Y = ${@features_to_uclibc_settings(d)}
74# unfortunately doesn't seem to work with bitbake, workaround:
75def features_to_busybox_conf(d):
76 cnf, rem = features_to_busybox_settings(d)
77 return cnf
78def features_to_busybox_del(d):
79 cnf, rem = features_to_busybox_settings(d)
80 return rem
81
82configmangle = '/CROSS_COMPILER_PREFIX/d; \
83 /CONFIG_EXTRA_CFLAGS/d; \
84 '
85OE_FEATURES := "${@features_to_busybox_conf(d)}"
86OE_DEL := "${@features_to_busybox_del(d)}"
87DO_IPv4 := "${@bb.utils.contains('DISTRO_FEATURES', 'ipv4', 1, 0, d)}"
88DO_IPv6 := "${@bb.utils.contains('DISTRO_FEATURES', 'ipv6', 1, 0, d)}"
89
90python () {
91 if "${OE_DEL}":
92 d.setVar('configmangle_append', "${OE_DEL}" + "\n")
93 if "${OE_FEATURES}":
94 d.setVar('configmangle_append',
95 "/^### DISTRO FEATURES$/a\\\n%s\n\n" %
96 ("\\n".join((d.expand("${OE_FEATURES}").split("\n")))))
97 d.setVar('configmangle_append',
98 "/^### CROSS$/a\\\n%s\n" %
99 ("\\n".join(["CONFIG_CROSS_COMPILER_PREFIX=\"${TARGET_PREFIX}\"",
100 "CONFIG_EXTRA_CFLAGS=\"${CFLAGS}\" \"${HOST_CC_ARCH}\""
101 ])
102 ))
103}
104
105do_prepare_config () {
106 sed -e 's#@DATADIR@#${datadir}#g' \
107 < ${WORKDIR}/defconfig > ${S}/.config
108 sed -i -e '/CONFIG_STATIC/d' .config
109 echo "# CONFIG_STATIC is not set" >> .config
110 for i in 'CROSS' 'DISTRO FEATURES'; do echo "### $i"; done >> \
111 ${S}/.config
112 sed -i -e '${configmangle}' ${S}/.config
113 if test ${DO_IPv4} -eq 0 && test ${DO_IPv6} -eq 0; then
114 # disable networking applets
115 mv ${S}/.config ${S}/.config.oe-tmp
116 awk 'BEGIN{net=0}
117 /^# Networking Utilities/{net=1}
118 /^#$/{if(net){net=net+1}}
119 {if(net==2&&$0 !~ /^#/&&$1){print("# "$1" is not set")}else{print}}' \
120 ${S}/.config.oe-tmp > ${S}/.config
121 fi
122 sed -i 's/CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n"/CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -b"/' ${S}/.config
123}
124
125# returns all the elements from the src uri that are .cfg files
126def find_cfgs(d):
127 sources=src_patches(d, True)
128 sources_list=[]
129 for s in sources:
130 if s.endswith('.cfg'):
131 sources_list.append(s)
132
133 return sources_list
134
135do_configure () {
136 do_prepare_config
137 merge_config.sh -m .config ${@" ".join(find_cfgs(d))}
138 cml1_do_configure
139}
140
141do_compile() {
142 unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS
143 if [ "${BUSYBOX_SPLIT_SUID}" = "1" -a x`grep "CONFIG_FEATURE_INDIVIDUAL=y" .config` = x ]; then
144 # split the .config into two parts, and make two busybox binaries
145 cp .config .config.orig
146 oe_runmake busybox.cfg.suid
147 oe_runmake busybox.cfg.nosuid
148 for i in `cat busybox.cfg.suid busybox.cfg.nosuid`; do
149 echo "# $i is not set" >> .config.disable.apps
150 done
151 merge_config.sh -m .config.orig .config.disable.apps
152 cp .config .config.nonapps
153 for s in suid nosuid; do
154 cat busybox.cfg.$s | while read item; do
155 grep -w "$item" .config.orig
156 done > .config.app.$s
157 merge_config.sh -m .config.nonapps .config.app.$s
158 oe_runmake busybox_unstripped
159 mv busybox_unstripped busybox.$s
160 oe_runmake busybox.links
161 mv busybox.links busybox.links.$s
162 done
163 # copy .config.orig back to .config, because the install process may check this file
164 cp .config.orig .config
165 # cleanup
166 rm .config.orig .config.app.suid .config.app.nosuid .config.disable.apps .config.nonapps
167 else
168 oe_runmake busybox_unstripped
169 cp busybox_unstripped busybox
170 oe_runmake busybox.links
171 fi
172}
173
174do_install () {
175 if [ "${prefix}" != "/usr" ]; then
176 sed -i "s:^/usr/:${prefix}/:" busybox.links*
177 fi
178 if [ "${base_sbindir}" != "/sbin" ]; then
179 sed -i "s:^/sbin/:${base_sbindir}/:" busybox.links*
180 fi
181 if [ "${base_bindir}" != "/bin" ]; then
182 sed -i "s:^/bin/:${base_bindir}/:" busybox.links*
183 fi
184
185 install -d ${D}${sysconfdir}/init.d
186
187 if ! grep -q "CONFIG_FEATURE_INDIVIDUAL=y" ${B}/.config; then
188 # Install /bin/busybox, and the /bin/sh link so the postinst script
189 # can run. Let update-alternatives handle the rest.
190 install -d ${D}${base_bindir}
191 if [ "${BUSYBOX_SPLIT_SUID}" = "1" ]; then
192 install -m 4755 ${B}/busybox.suid ${D}${base_bindir}
193 install -m 0755 ${B}/busybox.nosuid ${D}${base_bindir}
194 install -m 0644 ${S}/busybox.links.suid ${D}${sysconfdir}
195 install -m 0644 ${S}/busybox.links.nosuid ${D}${sysconfdir}
196 if grep -q "CONFIG_FEATURE_SH_IS_ASH=y" ${B}/.config; then
197 ln -sf busybox.nosuid ${D}${base_bindir}/sh
198 fi
199 # Keep a default busybox for people who want to invoke busybox directly.
200 # This is also useful for the on device upgrade. Because we want
201 # to use the busybox command in postinst.
202 ln -sf busybox.nosuid ${D}${base_bindir}/busybox
203 else
204 if grep -q "CONFIG_FEATURE_SUID=y" ${B}/.config; then
205 install -m 4755 ${B}/busybox ${D}${base_bindir}
206 else
207 install -m 0755 ${B}/busybox ${D}${base_bindir}
208 fi
209 install -m 0644 ${S}/busybox.links ${D}${sysconfdir}
210 if grep -q "CONFIG_FEATURE_SH_IS_ASH=y" ${B}/.config; then
211 ln -sf busybox ${D}${base_bindir}/sh
212 fi
213 # We make this symlink here to eliminate the error when upgrading together
214 # with busybox-syslog. Without this symlink, the opkg may think of the
215 # busybox.nosuid as obsolete and remove it, resulting in dead links like
216 # /bin/sed -> /bin/busybox.nosuid. This will make upgrading busybox-syslog fail.
217 # This symlink will be safely deleted in postinst, thus no negative effect.
218 ln -sf busybox ${D}${base_bindir}/busybox.nosuid
219 fi
220 else
221 install -d ${D}${base_bindir} ${D}${base_sbindir}
222 install -d ${D}${libdir} ${D}${bindir} ${D}${sbindir}
223 cat busybox.links | while read FILE; do
224 NAME=`basename "$FILE"`
225 install -m 0755 "0_lib/$NAME" "${D}$FILE.${BPN}"
226 done
227 # add suid bit where needed
228 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
229 find ${D} -name $i.${BPN} -exec chmod a+s {} \;
230 done
231 install -m 0755 0_lib/libbusybox.so.${PV} ${D}${libdir}/libbusybox.so.${PV}
232 ln -sf sh.${BPN} ${D}${base_bindir}/sh
233 ln -sf ln.${BPN} ${D}${base_bindir}/ln
234 ln -sf test.${BPN} ${D}${bindir}/test
235 if [ -f ${D}/linuxrc.${BPN} ]; then
236 mv ${D}/linuxrc.${BPN} ${D}/linuxrc
237 fi
238 install -m 0644 ${S}/busybox.links ${D}${sysconfdir}
239 fi
240
241 if grep -q "CONFIG_SYSLOGD=y" ${B}/.config; then
242 install -m 0755 ${WORKDIR}/syslog ${D}${sysconfdir}/init.d/syslog.${BPN}
243 install -m 644 ${WORKDIR}/syslog-startup.conf ${D}${sysconfdir}/syslog-startup.conf.${BPN}
244 install -m 644 ${WORKDIR}/syslog.conf ${D}${sysconfdir}/syslog.conf.${BPN}
245 fi
246 if grep "CONFIG_CROND=y" ${B}/.config; then
247 install -m 0755 ${WORKDIR}/busybox-cron ${D}${sysconfdir}/init.d/
248 fi
249 if grep "CONFIG_HTTPD=y" ${B}/.config; then
250 install -m 0755 ${WORKDIR}/busybox-httpd ${D}${sysconfdir}/init.d/
251 install -d ${D}/srv/www
252 fi
253 if grep "CONFIG_UDHCPD=y" ${B}/.config; then
254 install -m 0755 ${WORKDIR}/busybox-udhcpd ${D}${sysconfdir}/init.d/
255 fi
256 if grep "CONFIG_HWCLOCK=y" ${B}/.config; then
257 install -m 0755 ${WORKDIR}/hwclock.sh ${D}${sysconfdir}/init.d/
258 fi
259 if grep "CONFIG_UDHCPC=y" ${B}/.config; then
260 install -d ${D}${sysconfdir}/udhcpc.d
261 install -d ${D}${datadir}/udhcpc
262 install -m 0755 ${WORKDIR}/simple.script ${D}${sysconfdir}/udhcpc.d/50default
263 install -m 0755 ${WORKDIR}/default.script ${D}${datadir}/udhcpc/default.script
264 fi
265 if grep "CONFIG_INETD=y" ${B}/.config; then
266 install -m 0755 ${WORKDIR}/inetd ${D}${sysconfdir}/init.d/inetd.${BPN}
267 sed -i "s:/usr/sbin/:${sbindir}/:" ${D}${sysconfdir}/init.d/inetd.${BPN}
268 install -m 0644 ${WORKDIR}/inetd.conf ${D}${sysconfdir}/
269 fi
270 if grep "CONFIG_MDEV=y" ${B}/.config; then
271 install -m 0755 ${WORKDIR}/mdev ${D}${sysconfdir}/init.d/mdev
272 if grep "CONFIG_FEATURE_MDEV_CONF=y" ${B}/.config; then
273 install -m 644 ${WORKDIR}/mdev.conf ${D}${sysconfdir}/mdev.conf
274 install -d ${D}${sysconfdir}/mdev
275 install -m 0755 ${WORKDIR}/find-touchscreen.sh ${D}${sysconfdir}/mdev
276 install -m 0755 ${WORKDIR}/mdev-mount.sh ${D}${sysconfdir}/mdev
277 fi
278 fi
279
280 if ${@bb.utils.contains('DISTRO_FEATURES','systemd','true','false',d)}; then
281 if grep -q "CONFIG_SYSLOGD=y" ${B}/.config; then
282 install -d ${D}${systemd_unitdir}/system
283 sed 's,@base_sbindir@,${base_sbindir},g' < ${WORKDIR}/busybox-syslog.service.in \
284 > ${D}${systemd_unitdir}/system/busybox-syslog.service
285 if [ -f ${WORKDIR}/busybox-syslog.default ] ; then
286 install -d ${D}${sysconfdir}/default
287 install -m 0644 ${WORKDIR}/busybox-syslog.default ${D}${sysconfdir}/default/busybox-syslog
288 fi
289 ln -sf /dev/null ${D}${systemd_unitdir}/system/syslog.service
290 fi
291 if grep -q "CONFIG_KLOGD=y" ${B}/.config; then
292 install -d ${D}${systemd_unitdir}/system
293 sed 's,@base_sbindir@,${base_sbindir},g' < ${WORKDIR}/busybox-klogd.service.in \
294 > ${D}${systemd_unitdir}/system/busybox-klogd.service
295 fi
296 fi
297
298 # Remove the sysvinit specific configuration file for systemd systems to avoid confusion
299 if ${@bb.utils.contains('DISTRO_FEATURES', 'sysvinit', 'false', 'true', d)}; then
300 rm -f ${D}${sysconfdir}/syslog-startup.conf.${BPN}
301 fi
302}
303
304inherit update-alternatives
305
306ALTERNATIVE_PRIORITY = "50"
307
308ALTERNATIVE_${PN}-syslog += "syslog-conf"
309ALTERNATIVE_LINK_NAME[syslog-conf] = "${sysconfdir}/syslog.conf"
310
311python () {
312 if bb.utils.contains('DISTRO_FEATURES', 'sysvinit', True, False, d):
313 pn = d.getVar('PN', True)
314 d.appendVar('ALTERNATIVE_%s-syslog' % (pn), ' syslog-init')
315 d.setVarFlag('ALTERNATIVE_LINK_NAME', 'syslog-init', '%s/init.d/syslog' % (d.getVar('sysconfdir', True)))
316 d.setVarFlag('ALTERNATIVE_TARGET', 'syslog-init', '%s/init.d/syslog.%s' % (d.getVar('sysconfdir', True), d.getVar('BPN', True)))
317 d.appendVar('ALTERNATIVE_%s-syslog' % (pn), ' syslog-startup-conf')
318 d.setVarFlag('ALTERNATIVE_LINK_NAME', 'syslog-startup-conf', '%s/syslog-startup.conf' % (d.getVar('sysconfdir', True)))
319 d.setVarFlag('ALTERNATIVE_TARGET', 'syslog-startup-conf', '%s/syslog-startup.conf.%s' % (d.getVar('sysconfdir', True), d.getVar('BPN', True)))
320}
321
322python do_package_prepend () {
323 # We need to load the full set of busybox provides from the /etc/busybox.links
324 # Use this to see the update-alternatives with the right information
325
326 dvar = d.getVar('D', True)
327 pn = d.getVar('PN', True)
328 def set_alternative_vars(links, target):
329 f = open('%s%s' % (dvar, links), 'r')
330 for alt_link_name in f:
331 alt_link_name = alt_link_name.strip()
332 alt_name = os.path.basename(alt_link_name)
333 # Match coreutils
334 if alt_name == '[':
335 alt_name = 'lbracket'
336 d.appendVar('ALTERNATIVE_%s' % (pn), ' ' + alt_name)
337 d.setVarFlag('ALTERNATIVE_LINK_NAME', alt_name, alt_link_name)
338 if os.path.exists('%s%s' % (dvar, target)):
339 d.setVarFlag('ALTERNATIVE_TARGET', alt_name, target)
340 f.close()
341 return
342
343 if os.path.exists('%s/etc/busybox.links' % (dvar)):
344 set_alternative_vars("${sysconfdir}/busybox.links", "${base_bindir}/busybox")
345 else:
346 set_alternative_vars("${sysconfdir}/busybox.links.nosuid", "${base_bindir}/busybox.nosuid")
347 set_alternative_vars("${sysconfdir}/busybox.links.suid", "${base_bindir}/busybox.suid")
348}
349
350pkg_postinst_${PN} () {
351 # This part of code is dedicated to the on target upgrade problem.
352 # It's known that if we don't make appropriate symlinks before update-alternatives calls,
353 # there will be errors indicating missing commands such as 'sed'.
354 # These symlinks will later be updated by update-alternatives calls.
355 test -n 2 > /dev/null || alias test='busybox test'
356 if test "x$D" = "x"; then
357 # Remove busybox.nosuid if it's a symlink, because this situation indicates
358 # that we're installing or upgrading to a one-binary busybox.
359 if test -h ${base_bindir}/busybox.nosuid; then
360 rm -f ${base_bindir}/busybox.nosuid
361 fi
362 for suffix in "" ".nosuid" ".suid"; do
363 if test -e ${sysconfdir}/busybox.links$suffix; then
364 while read link; do
365 if test ! -e "$link"; then
366 case "$link" in
367 /*/*/*)
368 to="../..${base_bindir}/busybox$suffix"
369 ;;
370 /bin/*)
371 to="busybox$suffix"
372 ;;
373 /*/*)
374 to="..${base_bindir}/busybox$suffix"
375 ;;
376 esac
377 # we can use busybox here because even if we are using splitted busybox
378 # we've made a symlink from /bin/busybox to /bin/busybox.nosuid.
379 busybox rm -f $link
380 busybox ln -s $to $link
381 fi
382 done < ${sysconfdir}/busybox.links$suffix
383 fi
384 done
385 fi
386}
387
388pkg_prerm_${PN} () {
389 # This is so you can make busybox commit suicide - removing busybox with no other packages
390 # providing its files, this will make update-alternatives work, but the update-rc.d part
391 # for syslog, httpd and/or udhcpd will fail if there is no other package providing sh
392 tmpdir=`mktemp -d /tmp/busyboxrm-XXXXXX`
393 ln -s ${base_bindir}/busybox $tmpdir/[
394 ln -s ${base_bindir}/busybox $tmpdir/test
395 ln -s ${base_bindir}/busybox $tmpdir/head
396 ln -s ${base_bindir}/busybox $tmpdir/sh
397 ln -s ${base_bindir}/busybox $tmpdir/basename
398 ln -s ${base_bindir}/busybox $tmpdir/echo
399 ln -s ${base_bindir}/busybox $tmpdir/mv
400 ln -s ${base_bindir}/busybox $tmpdir/ln
401 ln -s ${base_bindir}/busybox $tmpdir/dirname
402 ln -s ${base_bindir}/busybox $tmpdir/rm
403 ln -s ${base_bindir}/busybox $tmpdir/sed
404 ln -s ${base_bindir}/busybox $tmpdir/sort
405 ln -s ${base_bindir}/busybox $tmpdir/grep
406 export PATH=$PATH:$tmpdir
407}
408
409pkg_prerm_${PN}-syslog () {
410 # remove syslog
411 if test "x$D" = "x"; then
412 if test "$1" = "upgrade" -o "$1" = "remove"; then
413 ${sysconfdir}/init.d/syslog stop
414 fi
415 fi
416}