From 98dc75f1908bebc805f01c4cf010aab53dd77536 Mon Sep 17 00:00:00 2001 From: Stephan Raue Date: Mon, 5 Oct 2009 20:50:47 +0200 Subject: [PATCH] busybox-system: - merge with package busybox - add patch to enhance fbsplash - add more patches from busybox.net --- .../busybox-system/config/device_table.conf | 177 -- .../sysutils/busybox-system/config/mdev.conf | 94 - .../{busybox-system => busybox}/build | 0 .../{busybox-system => busybox}/conf.d/home | 0 .../conf.d/language | 0 .../{busybox-system => busybox}/conf.d/path | 0 .../{busybox-system => busybox}/conf.d/shell | 0 .../config/busybox.conf} | 22 +- .../config/sysconfig | 0 .../init.d/02_time | 0 .../init.d/03_date | 0 .../init.d/13_syslogd | 0 .../init.d/25_acpid | 0 .../init.d/53_httpd | 0 .../init.d/54_crond | 0 .../init.d/80_debug | 0 .../init.d/99_shutdown | 0 .../{busybox-system => busybox}/install | 0 .../sysutils/busybox/patches/30_telnetd.diff | 12 - .../busybox/patches/busybox-1.15.1-ash.diff | 29 - .../patches/busybox-1.15.1-buildsys.diff | 34 + .../busybox/patches/busybox-1.15.1-dd.diff | 35 + .../busybox/patches/busybox-1.15.1-hush.diff | 413 ++++ .../patches/busybox-1.15.1-lineedit.diff | 156 ++ .../patches/busybox-1.15.1-pidof_killall.diff | 250 +++ .../busybox/patches/busybox-1.15.1-sed.diff | 15 + .../busybox/patches/busybox-1.15.1-uniq.diff | 11 + .../sysutils/busybox/patches/fbsplash.diff | 1849 +++++++++++++++++ .../scripts/acpi_powerbtn | 0 .../{busybox-system => busybox}/scripts/init | 0 .../scripts/udhcp.script | 0 31 files changed, 2776 insertions(+), 321 deletions(-) delete mode 100644 packages/sysutils/busybox-system/config/device_table.conf delete mode 100644 packages/sysutils/busybox-system/config/mdev.conf rename packages/sysutils/{busybox-system => busybox}/build (100%) rename packages/sysutils/{busybox-system => busybox}/conf.d/home (100%) rename packages/sysutils/{busybox-system => busybox}/conf.d/language (100%) rename packages/sysutils/{busybox-system => busybox}/conf.d/path (100%) rename packages/sysutils/{busybox-system => busybox}/conf.d/shell (100%) rename packages/sysutils/{busybox-system/config/busybox-system.conf => busybox/config/busybox.conf} (98%) rename packages/sysutils/{busybox-system => busybox}/config/sysconfig (100%) rename packages/sysutils/{busybox-system => busybox}/init.d/02_time (100%) rename packages/sysutils/{busybox-system => busybox}/init.d/03_date (100%) rename packages/sysutils/{busybox-system => busybox}/init.d/13_syslogd (100%) rename packages/sysutils/{busybox-system => busybox}/init.d/25_acpid (100%) rename packages/sysutils/{busybox-system => busybox}/init.d/53_httpd (100%) rename packages/sysutils/{busybox-system => busybox}/init.d/54_crond (100%) rename packages/sysutils/{busybox-system => busybox}/init.d/80_debug (100%) rename packages/sysutils/{busybox-system => busybox}/init.d/99_shutdown (100%) rename packages/sysutils/{busybox-system => busybox}/install (100%) delete mode 100644 packages/sysutils/busybox/patches/30_telnetd.diff delete mode 100644 packages/sysutils/busybox/patches/busybox-1.15.1-ash.diff create mode 100644 packages/sysutils/busybox/patches/busybox-1.15.1-buildsys.diff create mode 100644 packages/sysutils/busybox/patches/busybox-1.15.1-dd.diff create mode 100644 packages/sysutils/busybox/patches/busybox-1.15.1-hush.diff create mode 100644 packages/sysutils/busybox/patches/busybox-1.15.1-lineedit.diff create mode 100644 packages/sysutils/busybox/patches/busybox-1.15.1-pidof_killall.diff create mode 100644 packages/sysutils/busybox/patches/busybox-1.15.1-sed.diff create mode 100644 packages/sysutils/busybox/patches/busybox-1.15.1-uniq.diff create mode 100644 packages/sysutils/busybox/patches/fbsplash.diff rename packages/sysutils/{busybox-system => busybox}/scripts/acpi_powerbtn (100%) rename packages/sysutils/{busybox-system => busybox}/scripts/init (100%) rename packages/sysutils/{busybox-system => busybox}/scripts/udhcp.script (100%) diff --git a/packages/sysutils/busybox-system/config/device_table.conf b/packages/sysutils/busybox-system/config/device_table.conf deleted file mode 100644 index 3062f0ac6e..0000000000 --- a/packages/sysutils/busybox-system/config/device_table.conf +++ /dev/null @@ -1,177 +0,0 @@ -# When building a target filesystem, it is desirable to not have to -# become root and then run 'mknod' a thousand times. Using a device -# table you can create device nodes and directories "on the fly". -# -# This is a sample device table file for use with genext2fs. You can -# do all sorts of interesting things with a device table file. For -# example, if you want to adjust the permissions on a particular file -# you can just add an entry like: -# /sbin/foobar f 2755 0 0 - - - - - -# and (assuming the file /sbin/foobar exists) it will be made setuid -# root (regardless of what its permissions are on the host filesystem. -# Furthermore, you can use a single table entry to create a many device -# minors. For example, if I wanted to create /dev/hda and /dev/hda[0-15] -# I could just use the following two table entries: -# /dev/hda b 640 0 0 3 0 0 0 - -# /dev/hda b 640 0 0 3 1 1 1 15 -# -# Device table entries take the form of: -# -# where name is the file name, type can be one of: -# f A regular file -# d Directory -# c Character special device file -# b Block special device file -# p Fifo (named pipe) -# uid is the user id for the target file, gid is the group id for the -# target file. The rest of the entries (major, minor, etc) apply only -# to device special files. - -# Have fun -# -Erik Andersen -# - -# -/dev d 755 0 0 - - - - - -#/dev/pts d 755 0 0 - - - - - -#/dev/shm d 755 0 0 - - - - - -#/tmp d 1777 0 0 - - - - - -#/etc d 755 0 0 - - - - - -/sys d 755 0 0 - - - - - -#/config d 755 0 0 - - - - - -/proc d 755 0 0 - - - - - -#/home/default d 2755 1000 1000 - - - - - -#/root d 750 0 0 - - - - - -# -#/bin/busybox f 4755 0 0 - - - - - -#/etc/shadow f 600 0 0 - - - - - -#/etc/passwd f 644 0 0 - - - - - -#/etc/network/if-up.d d 755 0 0 - - - - - -#/etc/network/if-pre-up.d d 755 0 0 - - - - - -#/etc/network/if-down.d d 755 0 0 - - - - - -#/etc/network/if-post-down.d d 755 0 0 - - - - - -#/usr/share/udhcpc/default.script f 755 0 0 - - - - - -# uncomment this to allow starting x as non-root -#/usr/X11R6/bin/Xfbdev f 4755 0 0 - - - - - -# Normal system devices -# -#/dev/mem c 640 0 0 1 1 0 0 - -#/dev/kmem c 640 0 0 1 2 0 0 - -/dev/null c 666 0 0 1 3 0 0 - -#/dev/zero c 666 0 0 1 5 0 0 - -#/dev/random c 666 0 0 1 8 0 0 - -#/dev/urandom c 666 0 0 1 9 0 0 - -#/dev/ram b 640 0 0 1 1 0 0 - -#/dev/ram b 640 0 0 1 0 0 1 4 -/dev/loop b 640 0 0 7 0 0 1 2 -#/dev/rtc c 640 0 0 10 135 - - - -#/dev/console c 666 0 0 5 1 - - - -#/dev/tty c 666 0 0 5 0 - - - -#/dev/tty c 666 0 0 4 0 0 1 8 -#/dev/ttyAMA c 600 0 0 204 64 0 1 1 -#/dev/ttyp c 666 0 0 3 0 0 1 10 -#/dev/ptyp c 666 0 0 2 0 0 1 10 -#/dev/ptmx c 666 0 0 5 2 - - - -#/dev/ttyP c 666 0 0 57 0 0 1 4 -#/dev/ttyS c 666 0 0 4 64 0 1 4 -#/dev/fb c 640 0 5 29 0 0 32 4 -#/dev/ttySA c 666 0 0 204 5 0 1 3 -#/dev/psaux c 666 0 0 10 1 0 0 - -#/dev/ppp c 666 0 0 108 0 - - - - -# Input stuff -#/dev/input d 755 0 0 - - - - - -#/dev/input/mice c 640 0 0 13 63 0 0 - -#/dev/input/mouse c 660 0 0 13 32 0 1 4 -#/dev/input/event c 660 0 0 13 64 0 1 4 -#/dev/input/js c 660 0 0 13 0 0 1 4 - - -# MTD stuff -#/dev/mtd c 640 0 0 90 0 0 2 4 -#/dev/mtdblock b 640 0 0 31 0 0 1 4 - -#Tun/tap driver -#/dev/net d 755 0 0 - - - - - -#/dev/net/tun c 660 0 0 10 200 - - - - -# Audio stuff -#/dev/audio c 666 0 29 14 4 - - - -#/dev/audio1 c 666 0 29 14 20 - - - -#/dev/dsp c 666 0 29 14 3 - - - -#/dev/dsp1 c 666 0 29 14 19 - - - -#/dev/sndstat c 666 0 29 14 6 - - - - -# User-mode Linux stuff -#/dev/ubda b 640 0 0 98 0 0 0 - -#/dev/ubda b 640 0 0 98 1 1 1 15 - -# IDE Devices -#/dev/hda b 640 0 0 3 0 0 0 - -#/dev/hda b 640 0 0 3 1 1 1 15 -#/dev/hdb b 640 0 0 3 64 0 0 - -#/dev/hdb b 640 0 0 3 65 1 1 15 -#/dev/hdc b 640 0 0 22 0 0 0 - -#/dev/hdc b 640 0 0 22 1 1 1 15 -#/dev/hdd b 640 0 0 22 64 0 0 - -#/dev/hdd b 640 0 0 22 65 1 1 15 -#/dev/hde b 640 0 0 33 0 0 0 - -#/dev/hde b 640 0 0 33 1 1 1 15 -#/dev/hdf b 640 0 0 33 64 0 0 - -#/dev/hdf b 640 0 0 33 65 1 1 15 -#/dev/hdg b 640 0 0 34 0 0 0 - -#/dev/hdg b 640 0 0 34 1 1 1 15 -#/dev/hdh b 640 0 0 34 64 0 0 - -#/dev/hdh b 640 0 0 34 65 1 1 15 - -# SCSI Devices -/dev/sda b 640 0 0 8 0 0 0 - -/dev/sda b 640 0 0 8 1 1 1 15 -/dev/sdb b 640 0 0 8 16 0 0 - -/dev/sdb b 640 0 0 8 17 1 1 15 -#/dev/sdc b 640 0 0 8 32 0 0 - -#/dev/sdc b 640 0 0 8 33 1 1 15 -#/dev/sdd b 640 0 0 8 48 0 0 - -#/dev/sdd b 640 0 0 8 49 1 1 15 -#/dev/sde b 640 0 0 8 64 0 0 - -#/dev/sde b 640 0 0 8 65 1 1 15 -#/dev/sdf b 640 0 0 8 80 0 0 - -#/dev/sdf b 640 0 0 8 81 1 1 15 -#/dev/sdg b 640 0 0 8 96 0 0 - -#/dev/sdg b 640 0 0 8 97 1 1 15 -#/dev/sdh b 640 0 0 8 112 0 0 - -#/dev/sdh b 640 0 0 8 113 1 1 15 -#/dev/sg c 640 0 0 21 0 0 1 15 -#/dev/scd b 640 0 0 11 0 0 1 15 -#/dev/st c 640 0 0 9 0 0 1 8 -#/dev/nst c 640 0 0 9 128 0 1 8 -#/dev/st c 640 0 0 9 32 1 1 4 -#/dev/st c 640 0 0 9 64 1 1 4 -#/dev/st c 640 0 0 9 96 1 1 4 - -# Floppy disk devices -#/dev/fd b 640 0 0 2 0 0 1 2 -#/dev/fd0d360 b 640 0 0 2 4 0 0 - -#/dev/fd1d360 b 640 0 0 2 5 0 0 - -#/dev/fd0h1200 b 640 0 0 2 8 0 0 - -#/dev/fd1h1200 b 640 0 0 2 9 0 0 - -#/dev/fd0u1440 b 640 0 0 2 28 0 0 - -#/dev/fd1u1440 b 640 0 0 2 29 0 0 - -#/dev/fd0u2880 b 640 0 0 2 32 0 0 - -#/dev/fd1u2880 b 640 0 0 2 33 0 0 - - -# All the proprietary cdrom devices in the world -#/dev/aztcd b 640 0 0 29 0 0 0 - -#/dev/bpcd b 640 0 0 41 0 0 0 - -#/dev/capi20 c 640 0 0 68 0 0 1 2 -#/dev/cdu31a b 640 0 0 15 0 0 0 - -#/dev/cdu535 b 640 0 0 24 0 0 0 - -#/dev/cm206cd b 640 0 0 32 0 0 0 - -#/dev/sjcd b 640 0 0 18 0 0 0 - -#/dev/sonycd b 640 0 0 15 0 0 0 - -#/dev/gscd b 640 0 0 16 0 0 0 - -#/dev/sbpcd b 640 0 0 25 0 0 0 - -#/dev/sbpcd b 640 0 0 25 0 0 1 4 -#/dev/mcd b 640 0 0 23 0 0 0 - -#/dev/optcd b 640 0 0 17 0 0 0 - - diff --git a/packages/sysutils/busybox-system/config/mdev.conf b/packages/sysutils/busybox-system/config/mdev.conf deleted file mode 100644 index 647817dc0d..0000000000 --- a/packages/sysutils/busybox-system/config/mdev.conf +++ /dev/null @@ -1,94 +0,0 @@ -# -# This is a sample mdev.conf. -# - -SLEEP=10 - -# Symlinks: -# Syntax: %s -> %s -MAKEDEV -> ../sbin/MAKEDEV -/proc/core -> kcore -fd -> /proc/self/fd -mcdx -> mcdx0 -radio -> radio0 -ram -> ram1 -sbpcd -> sbpcd0 -sr0 -> scd0 -sr1 -> scd1 -sr10 -> scd10 -sr11 -> scd11 -sr12 -> scd12 -sr13 -> scd13 -sr14 -> scd14 -sr15 -> scd15 -sr16 -> scd16 -sr2 -> scd2 -sr3 -> scd3 -sr4 -> scd4 -sr5 -> scd5 -sr6 -> scd6 -sr7 -> scd7 -sr8 -> scd8 -sr9 -> scd9 -stderr -> fd/2 -stdin -> fd/0 -stdout -> fd/1 -vbi -> vbi0 -#vcs -> vcs0 -#vcsa -> vcsa0 -video -> video0 - -# Devices: -# Syntax: %s %d:%d %s -# devices user:group mode - -null root:root 777 -zero root:root 666 -grsec root:root 660 - -urandom root:root 444 - -console root:tty 0600 -fd0 root:floppy 0660 -kmem root:root 000 -mem root:root 0640 -port root:root 0640 -ptmx root:tty 0660 - -sd[a-z][0-9]* root:disk 0660 */lib/mdev/sd_links -hd[a-z][0-9]* root:disk 0660 */lib/mdev/ide_links -md[0-9] root:disk 0660 - -tty root:tty 0666 -tty[0-9] root:tty 0660 -tty[0-9][0-9] root:tty 0660 -ttyS[0-9]* root:tty 640 - -ttyLTM[0-9] root:dialout 0660 @ln -sf $MDEV modem -ttySHSF[0-9] root:dialout 0660 @ln -sf $MDEV modem -slamr root:dialout 0660 @ln -sf $MDEV slamr0 -slusb root:dialout 0660 @ln -sf $MDEV slusb0 -video.* root:video 0660 -fuse root:root 0666 - -# alsa sound devices -pcm.* root:audio 0660 */lib/mdev/subdir_dev snd -control.* root:audio 0660 */lib/mdev/subdir_dev snd -midi.* root:audio 0660 */lib/mdev/subdir_dev snd -seq root:audio 0660 */lib/mdev/subdir_dev snd -timer root:audio 0660 */lib/mdev/subdir_dev snd - -# load drivers for usb devices -usbdev[0-9].* root:root 0660 */lib/mdev/usbdev - -# net devices -tun[0-9]* root:root 0600 */lib/mdev/subdir_dev net -tap[0-9]* root:root 0600 */lib/mdev/subdir_dev net - -# zaptel devices -zapctl root:dialout 0660 */lib/mdev/subdir_dev zap ctl -zaptimer root:dialout 0660 */lib/mdev/subdir_dev zap timer -zapchannel root:dialout 0660 */lib/mdev/subdir_dev zap channel -zappseudo root:dialout 0660 */lib/mdev/subdir_dev zap pseudo -zap[0-9]* root:dialout 0660 */lib/mdev/subdir_dev zap - diff --git a/packages/sysutils/busybox-system/build b/packages/sysutils/busybox/build similarity index 100% rename from packages/sysutils/busybox-system/build rename to packages/sysutils/busybox/build diff --git a/packages/sysutils/busybox-system/conf.d/home b/packages/sysutils/busybox/conf.d/home similarity index 100% rename from packages/sysutils/busybox-system/conf.d/home rename to packages/sysutils/busybox/conf.d/home diff --git a/packages/sysutils/busybox-system/conf.d/language b/packages/sysutils/busybox/conf.d/language similarity index 100% rename from packages/sysutils/busybox-system/conf.d/language rename to packages/sysutils/busybox/conf.d/language diff --git a/packages/sysutils/busybox-system/conf.d/path b/packages/sysutils/busybox/conf.d/path similarity index 100% rename from packages/sysutils/busybox-system/conf.d/path rename to packages/sysutils/busybox/conf.d/path diff --git a/packages/sysutils/busybox-system/conf.d/shell b/packages/sysutils/busybox/conf.d/shell similarity index 100% rename from packages/sysutils/busybox-system/conf.d/shell rename to packages/sysutils/busybox/conf.d/shell diff --git a/packages/sysutils/busybox-system/config/busybox-system.conf b/packages/sysutils/busybox/config/busybox.conf similarity index 98% rename from packages/sysutils/busybox-system/config/busybox-system.conf rename to packages/sysutils/busybox/config/busybox.conf index 9ebe2380a3..5e621e2843 100644 --- a/packages/sysutils/busybox-system/config/busybox-system.conf +++ b/packages/sysutils/busybox/config/busybox.conf @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Busybox version: 1.15.1 -# Fri Sep 25 11:20:48 2009 +# Mon Oct 5 10:23:59 2009 # CONFIG_HAVE_DOT_CONFIG=y @@ -587,6 +587,10 @@ CONFIG_FEATURE_CROND_DIR="/var/spool/cron" CONFIG_EJECT=y CONFIG_FEATURE_EJECT_SCSI=y CONFIG_FBSPLASH=y +CONFIG_FEATURE_FBSPLASH_8BPP=y +CONFIG_FEATURE_FBSPLASH_SPRITES=y +CONFIG_FEATURE_FBSPLASH_TEXT=y +CONFIG_FEATURE_FBSPLASH_FONTLOAD=y # CONFIG_FLASH_LOCK is not set # CONFIG_FLASH_UNLOCK is not set # CONFIG_FLASH_ERASEALL is not set @@ -628,16 +632,16 @@ CONFIG_MOUNTPOINT=y # CONFIG_FEATURE_TASKSET_FANCY is not set # CONFIG_TIME is not set # CONFIG_TIMEOUT is not set -# CONFIG_TTYSIZE is not set +CONFIG_TTYSIZE=y # CONFIG_VOLNAME is not set # CONFIG_WATCHDOG is not set # # Networking Utilities # -CONFIG_FEATURE_IPV6=y -CONFIG_FEATURE_UNIX_LOCAL=y -CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y +# CONFIG_FEATURE_IPV6 is not set +# CONFIG_FEATURE_UNIX_LOCAL is not set +# CONFIG_FEATURE_PREFER_IPV4_ADDRESS is not set # CONFIG_VERBOSE_RESOLUTION_ERRORS is not set # CONFIG_ARP is not set # CONFIG_ARPING is not set @@ -670,7 +674,7 @@ CONFIG_FEATURE_IFCONFIG_STATUS=y # CONFIG_FEATURE_IFCONFIG_SLIP is not set # CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set CONFIG_FEATURE_IFCONFIG_HW=y -# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y # CONFIG_IFENSLAVE is not set # CONFIG_IFPLUGD is not set # CONFIG_IFUPDOWN is not set @@ -715,7 +719,7 @@ CONFIG_NETSTAT=y # CONFIG_FEATURE_NETSTAT_PRG is not set # CONFIG_NSLOOKUP is not set CONFIG_PING=y -CONFIG_PING6=y +# CONFIG_PING6 is not set CONFIG_FEATURE_FANCY_PING=y # CONFIG_PSCAN is not set CONFIG_ROUTE=y @@ -743,7 +747,7 @@ CONFIG_DHCPD_LEASES_FILE="" CONFIG_APP_UDHCPC=y CONFIG_FEATURE_UDHCPC_ARPING=y # CONFIG_FEATURE_UDHCP_PORT is not set -CONFIG_UDHCP_DEBUG=0 +CONFIG_UDHCP_DEBUG=9 CONFIG_FEATURE_UDHCP_RFC3397=y CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 @@ -815,7 +819,7 @@ CONFIG_RUNSV=y CONFIG_RUNSVDIR=y # CONFIG_FEATURE_RUNSVDIR_LOG is not set CONFIG_SV=y -CONFIG_SV_DEFAULT_SERVICE_DIR="/etc/service" +CONFIG_SV_DEFAULT_SERVICE_DIR="/usr/etc/service" # CONFIG_SVLOGD is not set # CONFIG_CHPST is not set # CONFIG_SETUIDGID is not set diff --git a/packages/sysutils/busybox-system/config/sysconfig b/packages/sysutils/busybox/config/sysconfig similarity index 100% rename from packages/sysutils/busybox-system/config/sysconfig rename to packages/sysutils/busybox/config/sysconfig diff --git a/packages/sysutils/busybox-system/init.d/02_time b/packages/sysutils/busybox/init.d/02_time similarity index 100% rename from packages/sysutils/busybox-system/init.d/02_time rename to packages/sysutils/busybox/init.d/02_time diff --git a/packages/sysutils/busybox-system/init.d/03_date b/packages/sysutils/busybox/init.d/03_date similarity index 100% rename from packages/sysutils/busybox-system/init.d/03_date rename to packages/sysutils/busybox/init.d/03_date diff --git a/packages/sysutils/busybox-system/init.d/13_syslogd b/packages/sysutils/busybox/init.d/13_syslogd similarity index 100% rename from packages/sysutils/busybox-system/init.d/13_syslogd rename to packages/sysutils/busybox/init.d/13_syslogd diff --git a/packages/sysutils/busybox-system/init.d/25_acpid b/packages/sysutils/busybox/init.d/25_acpid similarity index 100% rename from packages/sysutils/busybox-system/init.d/25_acpid rename to packages/sysutils/busybox/init.d/25_acpid diff --git a/packages/sysutils/busybox-system/init.d/53_httpd b/packages/sysutils/busybox/init.d/53_httpd similarity index 100% rename from packages/sysutils/busybox-system/init.d/53_httpd rename to packages/sysutils/busybox/init.d/53_httpd diff --git a/packages/sysutils/busybox-system/init.d/54_crond b/packages/sysutils/busybox/init.d/54_crond similarity index 100% rename from packages/sysutils/busybox-system/init.d/54_crond rename to packages/sysutils/busybox/init.d/54_crond diff --git a/packages/sysutils/busybox-system/init.d/80_debug b/packages/sysutils/busybox/init.d/80_debug similarity index 100% rename from packages/sysutils/busybox-system/init.d/80_debug rename to packages/sysutils/busybox/init.d/80_debug diff --git a/packages/sysutils/busybox-system/init.d/99_shutdown b/packages/sysutils/busybox/init.d/99_shutdown similarity index 100% rename from packages/sysutils/busybox-system/init.d/99_shutdown rename to packages/sysutils/busybox/init.d/99_shutdown diff --git a/packages/sysutils/busybox-system/install b/packages/sysutils/busybox/install similarity index 100% rename from packages/sysutils/busybox-system/install rename to packages/sysutils/busybox/install diff --git a/packages/sysutils/busybox/patches/30_telnetd.diff b/packages/sysutils/busybox/patches/30_telnetd.diff deleted file mode 100644 index e2c9fc5c93..0000000000 --- a/packages/sysutils/busybox/patches/30_telnetd.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff -Naur busybox-1.15.0/networking/telnetd.c busybox-1.15.0a/networking/telnetd.c ---- busybox-1.15.0/networking/telnetd.c 2009-08-21 00:26:14.000000000 +0200 -+++ busybox-1.15.0a/networking/telnetd.c 2009-08-30 11:38:57.000000000 +0200 -@@ -63,7 +63,7 @@ - }; - #define G (*(struct globals*)&bb_common_bufsiz1) - #define INIT_G() do { \ -- G.loginpath = "/bin/login"; \ -+ G.loginpath = "/bin/sh"; \ - G.issuefile = "/etc/issue.net"; \ - } while (0) - diff --git a/packages/sysutils/busybox/patches/busybox-1.15.1-ash.diff b/packages/sysutils/busybox/patches/busybox-1.15.1-ash.diff deleted file mode 100644 index b77e45fd89..0000000000 --- a/packages/sysutils/busybox/patches/busybox-1.15.1-ash.diff +++ /dev/null @@ -1,29 +0,0 @@ -diff -urpN busybox-1.15.1/shell/ash.c busybox-1.15.1-ash/shell/ash.c ---- busybox-1.15.1/shell/ash.c 2009-09-12 17:56:11.000000000 +0200 -+++ busybox-1.15.1-ash/shell/ash.c 2009-09-16 16:29:09.609276492 +0200 -@@ -5553,7 +5553,7 @@ exptilde(char *startp, char *p, int flag - char *name; - struct passwd *pw; - const char *home; -- int quotes = flag & (EXP_FULL | EXP_CASE); -+ int quotes = flag & (EXP_FULL | EXP_CASE | EXP_REDIR); - int startloc; - - name = p + 1; -@@ -6321,7 +6321,7 @@ varvalue(char *name, int varflags, int f - int syntax; - int quoted = varflags & VSQUOTE; - int subtype = varflags & VSTYPE; -- int quotes = flags & (EXP_FULL | EXP_CASE); -+ int quotes = flags & (EXP_FULL | EXP_CASE | EXP_REDIR); - - if (quoted && (flags & EXP_FULL)) - sep = 1 << CHAR_BIT; -@@ -6558,6 +6558,7 @@ evalvar(char *p, int flag, struct strlis - patloc = expdest - (char *)stackblock(); - if (0 == subevalvar(p, /* str: */ NULL, patloc, subtype, - startloc, varflags, -+//TODO: | EXP_REDIR too? All other such places do it too - /* quotes: */ flag & (EXP_FULL | EXP_CASE), - var_str_list) - ) { diff --git a/packages/sysutils/busybox/patches/busybox-1.15.1-buildsys.diff b/packages/sysutils/busybox/patches/busybox-1.15.1-buildsys.diff new file mode 100644 index 0000000000..e63f8f8447 --- /dev/null +++ b/packages/sysutils/busybox/patches/busybox-1.15.1-buildsys.diff @@ -0,0 +1,34 @@ +diff -urpN busybox-1.15.1/miscutils/hdparm.c busybox-1.15.1-buildsys/miscutils/hdparm.c +--- busybox-1.15.1/miscutils/hdparm.c 2009-09-12 17:55:36.000000000 +0200 ++++ busybox-1.15.1-buildsys/miscutils/hdparm.c 2009-09-22 23:13:25.000000000 +0200 +@@ -15,6 +15,9 @@ + /* must be _after_ libbb.h: */ + #include + #include ++#if !defined(BLKGETSIZE64) ++# define BLKGETSIZE64 _IOR(0x12,114,size_t) ++#endif + + /* device types */ + /* ------------ */ +diff -urpN busybox-1.15.1/util-linux/fdisk.c busybox-1.15.1-buildsys/util-linux/fdisk.c +--- busybox-1.15.1/util-linux/fdisk.c 2009-09-12 17:55:37.000000000 +0200 ++++ busybox-1.15.1-buildsys/util-linux/fdisk.c 2009-09-22 23:13:25.000000000 +0200 +@@ -9,13 +9,16 @@ + + #ifndef _LARGEFILE64_SOURCE + /* For lseek64 */ +-#define _LARGEFILE64_SOURCE ++# define _LARGEFILE64_SOURCE + #endif + #include /* assert */ + #include + #if !defined(BLKSSZGET) + # define BLKSSZGET _IO(0x12, 104) + #endif ++#if !defined(BLKGETSIZE64) ++# define BLKGETSIZE64 _IOR(0x12,114,size_t) ++#endif + #include "libbb.h" + + /* Looks like someone forgot to add this to config system */ diff --git a/packages/sysutils/busybox/patches/busybox-1.15.1-dd.diff b/packages/sysutils/busybox/patches/busybox-1.15.1-dd.diff new file mode 100644 index 0000000000..a3e2676257 --- /dev/null +++ b/packages/sysutils/busybox/patches/busybox-1.15.1-dd.diff @@ -0,0 +1,35 @@ +diff -urpN busybox-1.15.1/coreutils/dd.c busybox-1.15.1-dd/coreutils/dd.c +--- busybox-1.15.1/coreutils/dd.c 2009-09-12 17:55:58.000000000 +0200 ++++ busybox-1.15.1-dd/coreutils/dd.c 2009-09-18 20:48:22.000000000 +0200 +@@ -286,25 +286,26 @@ int dd_main(int argc UNUSED_PARAM, char + } + + while (!(flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) { +- if (flags & FLAG_NOERROR) /* Pre-zero the buffer if conv=noerror */ +- memset(ibuf, 0, ibs); + n = safe_read(ifd, ibuf, ibs); + if (n == 0) + break; + if (n < 0) { ++ /* "Bad block" */ + if (!(flags & FLAG_NOERROR)) + goto die_infile; +- n = ibs; + bb_simple_perror_msg(infile); +- /* GNU dd with conv=noerror skips over "bad blocks" */ ++ /* GNU dd with conv=noerror skips over bad blocks */ + xlseek(ifd, ibs, SEEK_CUR); ++ /* conv=noerror,sync writes NULs, ++ * conv=noerror just ignores input bad blocks */ ++ n = 0; + } + if ((size_t)n == ibs) + G.in_full++; + else { + G.in_part++; + if (flags & FLAG_SYNC) { +- memset(ibuf + n, '\0', ibs - n); ++ memset(ibuf + n, 0, ibs - n); + n = ibs; + } + } diff --git a/packages/sysutils/busybox/patches/busybox-1.15.1-hush.diff b/packages/sysutils/busybox/patches/busybox-1.15.1-hush.diff new file mode 100644 index 0000000000..3cd0a7dcd2 --- /dev/null +++ b/packages/sysutils/busybox/patches/busybox-1.15.1-hush.diff @@ -0,0 +1,413 @@ +diff -urpN busybox-1.15.1/shell/hush.c busybox-1.15.1-hush/shell/hush.c +--- busybox-1.15.1/shell/hush.c 2009-09-12 17:56:20.000000000 +0200 ++++ busybox-1.15.1-hush/shell/hush.c 2009-09-27 02:46:54.000000000 +0200 +@@ -78,6 +78,7 @@ + * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. + */ + #include "busybox.h" /* for APPLET_IS_NOFORK/NOEXEC */ ++#include /* for malloc_trim */ + #include + /* #include */ + #if ENABLE_HUSH_CASE +@@ -786,7 +787,7 @@ static void xxfree(void *ptr) + * HUSH_DEBUG >= 2 prints line number in this file where it was detected. + */ + #if HUSH_DEBUG < 2 +-# define die_if_script(lineno, fmt...) die_if_script(fmt) ++# define die_if_script(lineno, ...) die_if_script(__VA_ARGS__) + # define syntax_error(lineno, msg) syntax_error(msg) + # define syntax_error_at(lineno, msg) syntax_error_at(msg) + # define syntax_error_unterm_ch(lineno, ch) syntax_error_unterm_ch(ch) +@@ -855,7 +856,7 @@ static void syntax_error_unexpected_ch(u + # undef syntax_error_unterm_str + # undef syntax_error_unexpected_ch + #else +-# define die_if_script(fmt...) die_if_script(__LINE__, fmt) ++# define die_if_script(...) die_if_script(__LINE__, __VA_ARGS__) + # define syntax_error(msg) syntax_error(__LINE__, msg) + # define syntax_error_at(msg) syntax_error_at(__LINE__, msg) + # define syntax_error_unterm_ch(ch) syntax_error_unterm_ch(__LINE__, ch) +@@ -898,7 +899,7 @@ static int is_well_formed_var_name(const + /* Replace each \x with x in place, return ptr past NUL. */ + static char *unbackslash(char *src) + { +- char *dst = src; ++ char *dst = src = strchrnul(src, '\\'); + while (1) { + if (*src == '\\') + src++; +@@ -1037,7 +1038,7 @@ static void restore_G_args(save_arg_t *s + * is finished or backgrounded. It is the same in interactive and + * non-interactive shells, and is the same regardless of whether + * a user trap handler is installed or a shell special one is in effect. +- * ^C or ^Z from keyboard seem to execute "at once" because it usually ++ * ^C or ^Z from keyboard seems to execute "at once" because it usually + * backgrounds (i.e. stops) or kills all members of currently running + * pipe. + * +@@ -1104,12 +1105,17 @@ static void restore_G_args(save_arg_t *s + * (child shell is not interactive), + * unset all traps (note: regardless of child shell's type - {}, (), etc) + * after [v]fork, if we plan to exec: +- * POSIX says pending signal mask is cleared in child - no need to clear it. ++ * POSIX says fork clears pending signal mask in child - no need to clear it. + * Restore blocked signal set to one inherited by shell just prior to exec. + * + * Note: as a result, we do not use signal handlers much. The only uses + * are to count SIGCHLDs + * and to restore tty pgrp on signal-induced exit. ++ * ++ * Note 2 (compat): ++ * Standard says "When a subshell is entered, traps that are not being ignored ++ * are set to the default actions". bash interprets it so that traps which ++ * are set to "" (ignore) are NOT reset to defaults. We do the same. + */ + enum { + SPECIAL_INTERACTIVE_SIGS = 0 +@@ -2596,43 +2602,51 @@ static void reset_traps_to_defaults(void + { + /* This function is always called in a child shell + * after fork (not vfork, NOMMU doesn't use this function). +- * Child shells are not interactive. +- * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling. +- * Testcase: (while :; do :; done) + ^Z should background. +- * Same goes for SIGTERM, SIGHUP, SIGINT. + */ + unsigned sig; + unsigned mask; + ++ /* Child shells are not interactive. ++ * SIGTTIN/SIGTTOU/SIGTSTP should not have special handling. ++ * Testcase: (while :; do :; done) + ^Z should background. ++ * Same goes for SIGTERM, SIGHUP, SIGINT. ++ */ + if (!G.traps && !(G.non_DFL_mask & SPECIAL_INTERACTIVE_SIGS)) +- return; ++ return; /* already no traps and no SPECIAL_INTERACTIVE_SIGS */ + +- /* Stupid. It can be done with *single* &= op, but we can't use +- * the fact that G.blocked_set is implemented as a bitmask... */ ++ /* Switching off SPECIAL_INTERACTIVE_SIGS. ++ * Stupid. It can be done with *single* &= op, but we can't use ++ * the fact that G.blocked_set is implemented as a bitmask ++ * in libc... */ + mask = (SPECIAL_INTERACTIVE_SIGS >> 1); + sig = 1; + while (1) { +- if (mask & 1) +- sigdelset(&G.blocked_set, sig); ++ if (mask & 1) { ++ /* Careful. Only if no trap or trap is not "" */ ++ if (!G.traps || !G.traps[sig] || G.traps[sig][0]) ++ sigdelset(&G.blocked_set, sig); ++ } + mask >>= 1; + if (!mask) + break; + sig++; + } +- ++ /* Our homegrown sig mask is saner to work with :) */ + G.non_DFL_mask &= ~SPECIAL_INTERACTIVE_SIGS; ++ ++ /* Resetting all traps to default except empty ones */ + mask = G.non_DFL_mask; + if (G.traps) for (sig = 0; sig < NSIG; sig++, mask >>= 1) { +- if (!G.traps[sig]) ++ if (!G.traps[sig] || !G.traps[sig][0]) + continue; + free(G.traps[sig]); + G.traps[sig] = NULL; + /* There is no signal for 0 (EXIT) */ + if (sig == 0) + continue; +- /* There was a trap handler, we are removing it. ++ /* There was a trap handler, we just removed it. + * But if sig still has non-DFL handling, +- * we should not unblock it. */ ++ * we should not unblock the sig. */ + if (mask & 1) + continue; + sigdelset(&G.blocked_set, sig); +@@ -3079,15 +3093,21 @@ static const struct built_in_command* fi + } + + #if ENABLE_HUSH_FUNCTIONS +-static const struct function *find_function(const char *name) ++static struct function **find_function_slot(const char *name) + { +- const struct function *funcp = G.top_func; +- while (funcp) { +- if (strcmp(name, funcp->name) == 0) { ++ struct function **funcpp = &G.top_func; ++ while (*funcpp) { ++ if (strcmp(name, (*funcpp)->name) == 0) { + break; + } +- funcp = funcp->next; ++ funcpp = &(*funcpp)->next; + } ++ return funcpp; ++} ++ ++static const struct function *find_function(const char *name) ++{ ++ const struct function *funcp = *find_function_slot(name); + if (funcp) + debug_printf_exec("found function '%s'\n", name); + return funcp; +@@ -3096,18 +3116,11 @@ static const struct function *find_funct + /* Note: takes ownership on name ptr */ + static struct function *new_function(char *name) + { +- struct function *funcp; +- struct function **funcpp = &G.top_func; +- +- while ((funcp = *funcpp) != NULL) { +- struct command *cmd; +- +- if (strcmp(funcp->name, name) != 0) { +- funcpp = &funcp->next; +- continue; +- } ++ struct function **funcpp = find_function_slot(name); ++ struct function *funcp = *funcpp; + +- cmd = funcp->parent_cmd; ++ if (funcp != NULL) { ++ struct command *cmd = funcp->parent_cmd; + debug_printf_exec("func %p parent_cmd %p\n", funcp, cmd); + if (!cmd) { + debug_printf_exec("freeing & replacing function '%s'\n", funcp->name); +@@ -3129,39 +3142,36 @@ static struct function *new_function(cha + cmd->group_as_string = funcp->body_as_string; + # endif + } +- goto skip; ++ } else { ++ debug_printf_exec("remembering new function '%s'\n", name); ++ funcp = *funcpp = xzalloc(sizeof(*funcp)); ++ /*funcp->next = NULL;*/ + } +- debug_printf_exec("remembering new function '%s'\n", name); +- funcp = *funcpp = xzalloc(sizeof(*funcp)); +- /*funcp->next = NULL;*/ +- skip: ++ + funcp->name = name; + return funcp; + } + + static void unset_func(const char *name) + { +- struct function *funcp; +- struct function **funcpp = &G.top_func; ++ struct function **funcpp = find_function_slot(name); ++ struct function *funcp = *funcpp; + +- while ((funcp = *funcpp) != NULL) { +- if (strcmp(funcp->name, name) == 0) { +- *funcpp = funcp->next; +- /* funcp is unlinked now, deleting it. +- * Note: if !funcp->body, the function was created by +- * "-F name body", do not free ->body_as_string +- * and ->name as they were not malloced. */ +- if (funcp->body) { +- free_pipe_list(funcp->body); +- free(funcp->name); ++ if (funcp != NULL) { ++ debug_printf_exec("freeing function '%s'\n", funcp->name); ++ *funcpp = funcp->next; ++ /* funcp is unlinked now, deleting it. ++ * Note: if !funcp->body, the function was created by ++ * "-F name body", do not free ->body_as_string ++ * and ->name as they were not malloced. */ ++ if (funcp->body) { ++ free_pipe_list(funcp->body); ++ free(funcp->name); + # if !BB_MMU +- free(funcp->body_as_string); ++ free(funcp->body_as_string); + # endif +- } +- free(funcp); +- break; + } +- funcpp = &funcp->next; ++ free(funcp); + } + } + +@@ -3628,9 +3638,9 @@ static int checkjobs(struct pipe* fg_pip + /* Note: is WIFSIGNALED, WEXITSTATUS = sig + 128 */ + rcode = WEXITSTATUS(status); + IF_HAS_KEYWORDS(if (fg_pipe->pi_inverted) rcode = !rcode;) +- /* bash prints killing signal's name for *last* ++ /* bash prints killer signal's name for *last* + * process in pipe (prints just newline for SIGINT). +- * Mimic this. Example: "sleep 5" + ^\ ++ * Mimic this. Example: "sleep 5" + (^\ or kill -QUIT) + */ + if (WIFSIGNALED(status)) { + int sig = WTERMSIG(status); +@@ -5183,6 +5193,47 @@ static FILE *generate_stream_from_string + xmove_fd(channel[1], 1); + /* Prevent it from trying to handle ctrl-z etc */ + IF_HUSH_JOB(G.run_list_level = 1;) ++ /* Awful hack for `trap` or $(trap). ++ * ++ * http://www.opengroup.org/onlinepubs/009695399/utilities/trap.html ++ * contains an example where "trap" is executed in a subshell: ++ * ++ * save_traps=$(trap) ++ * ... ++ * eval "$save_traps" ++ * ++ * Standard does not say that "trap" in subshell shall print ++ * parent shell's traps. It only says that its output ++ * must have suitable form, but then, in the above example ++ * (which is not supposed to be normative), it implies that. ++ * ++ * bash (and probably other shell) does implement it ++ * (traps are reset to defaults, but "trap" still shows them), ++ * but as a result, "trap" logic is hopelessly messed up: ++ * ++ * # trap ++ * trap -- 'echo Ho' SIGWINCH <--- we have a handler ++ * # (trap) <--- trap is in subshell - no output (correct, traps are reset) ++ * # true | trap <--- trap is in subshell - no output (ditto) ++ * # echo `true | trap` <--- in subshell - output (but traps are reset!) ++ * trap -- 'echo Ho' SIGWINCH ++ * # echo `(trap)` <--- in subshell in subshell - output ++ * trap -- 'echo Ho' SIGWINCH ++ * # echo `true | (trap)` <--- in subshell in subshell in subshell - output! ++ * trap -- 'echo Ho' SIGWINCH ++ * ++ * The rules when to forget and when to not forget traps ++ * get really complex and nonsensical. ++ * ++ * Our solution: ONLY bare $(trap) or `trap` is special. ++ */ ++ s = skip_whitespace(s); ++ if (strncmp(s, "trap", 4) == 0 && (*skip_whitespace(s + 4) == '\0')) ++ { ++ static const char *const argv[] = { NULL, NULL }; ++ builtin_trap((char**)argv); ++ exit(0); /* not _exit() - we need to fflush */ ++ } + #if BB_MMU + reset_traps_to_defaults(); + parse_and_run_string(s); +@@ -5676,8 +5727,10 @@ static int handle_dollar(o_string *as_st + goto make_var; + } + /* else: it's $_ */ +- /* TODO: */ +- /* $_ Shell or shell script name; or last cmd name */ ++ /* TODO: $_ and $-: */ ++ /* $_ Shell or shell script name; or last argument of last command ++ * (if last command wasn't a pipe; if it was, bash sets $_ to ""); ++ * but in command's env, set to full pathname used to invoke it */ + /* $- Option flags set by set builtin or shell options (-i etc) */ + default: + o_addQchr(dest, '$'); +@@ -5794,7 +5847,7 @@ static struct pipe *parse_stream(char ** + * found. When recursing, quote state is passed in via dest->o_escape. + */ + debug_printf_parse("parse_stream entered, end_trigger='%c'\n", +- end_trigger ? : 'X'); ++ end_trigger ? end_trigger : 'X'); + debug_enter(); + + G.ifs = get_local_var_value("IFS"); +@@ -6860,7 +6913,8 @@ static int FAST_FUNC builtin_cd(char **a + * bash says "bash: cd: HOME not set" and does nothing + * (exitcode 1) + */ +- newdir = get_local_var_value("HOME") ? : "/"; ++ const char *home = get_local_var_value("HOME"); ++ newdir = home ? home : "/"; + } + if (chdir(newdir)) { + /* Mimic bash message exactly */ +@@ -7057,6 +7111,10 @@ static int FAST_FUNC builtin_trap(char * + if (G.traps[i]) { + printf("trap -- "); + print_escaped(G.traps[i]); ++ /* note: bash adds "SIG", but only if invoked ++ * as "bash". If called as "sh", or if set -o posix, ++ * then it prints short signal names. ++ * We are printing short names: */ + printf(" %s\n", get_signame(i)); + } + } +@@ -7268,6 +7326,10 @@ static int FAST_FUNC builtin_memleak(cha + void *p; + unsigned long l; + ++#ifdef M_TRIM_THRESHOLD ++ /* Optional. Reduces probability of false positives */ ++ malloc_trim(0); ++#endif + /* Crude attempt to find where "free memory" starts, + * sans fragmentation. */ + p = malloc(240); +diff -urpN busybox-1.15.1/shell/hush_test/hush-trap/savetrap.right busybox-1.15.1-hush/shell/hush_test/hush-trap/savetrap.right +--- busybox-1.15.1/shell/hush_test/hush-trap/savetrap.right 1970-01-01 01:00:00.000000000 +0100 ++++ busybox-1.15.1-hush/shell/hush_test/hush-trap/savetrap.right 2009-09-27 02:03:53.000000000 +0200 +@@ -0,0 +1,8 @@ ++trap -- 'echo Exiting' EXIT ++trap -- 'echo WINCH!' WINCH ++trap -- 'echo Exiting' EXIT ++trap -- 'echo WINCH!' WINCH ++trap -- 'echo Exiting' EXIT ++trap -- 'echo WINCH!' WINCH ++Done ++Exiting +diff -urpN busybox-1.15.1/shell/hush_test/hush-trap/savetrap.tests busybox-1.15.1-hush/shell/hush_test/hush-trap/savetrap.tests +--- busybox-1.15.1/shell/hush_test/hush-trap/savetrap.tests 1970-01-01 01:00:00.000000000 +0100 ++++ busybox-1.15.1-hush/shell/hush_test/hush-trap/savetrap.tests 2009-09-27 02:04:02.000000000 +0200 +@@ -0,0 +1,9 @@ ++trap 'echo Exiting' EXIT ++trap 'echo WINCH!' SIGWINCH ++v=` trap ` ++echo "$v" ++v=$( trap ) ++echo "$v" ++v=`trap` ++echo "$v" ++echo Done +diff -urpN busybox-1.15.1/shell/hush_test/hush-trap/subshell.right busybox-1.15.1-hush/shell/hush_test/hush-trap/subshell.right +--- busybox-1.15.1/shell/hush_test/hush-trap/subshell.right 1970-01-01 01:00:00.000000000 +0100 ++++ busybox-1.15.1-hush/shell/hush_test/hush-trap/subshell.right 2009-09-26 15:14:57.000000000 +0200 +@@ -0,0 +1,6 @@ ++Ok ++Ok ++Ok ++Ok ++TERM ++Done +diff -urpN busybox-1.15.1/shell/hush_test/hush-trap/subshell.tests busybox-1.15.1-hush/shell/hush_test/hush-trap/subshell.tests +--- busybox-1.15.1/shell/hush_test/hush-trap/subshell.tests 1970-01-01 01:00:00.000000000 +0100 ++++ busybox-1.15.1-hush/shell/hush_test/hush-trap/subshell.tests 2009-09-26 15:14:57.000000000 +0200 +@@ -0,0 +1,20 @@ ++# Non-empty traps should be reset in subshell ++ ++# HUP is special in interactive shells ++trap '' HUP ++# QUIT is always special ++trap '' QUIT ++# SYS is not special ++trap '' SYS ++# WINCH is harmless ++trap 'bad: caught WINCH' WINCH ++# With TERM we'll check whether it is reset ++trap 'bad: caught TERM' TERM ++ ++# using bash, becuase we don't have $PPID (yet) ++(bash -c 'kill -HUP $PPID'; echo Ok) ++(bash -c 'kill -QUIT $PPID'; echo Ok) ++(bash -c 'kill -SYS $PPID'; echo Ok) ++(bash -c 'kill -WINCH $PPID'; echo Ok) ++(bash -c 'kill -TERM $PPID'; echo Bad: TERM is not reset) ++echo Done diff --git a/packages/sysutils/busybox/patches/busybox-1.15.1-lineedit.diff b/packages/sysutils/busybox/patches/busybox-1.15.1-lineedit.diff new file mode 100644 index 0000000000..20a7a8f37c --- /dev/null +++ b/packages/sysutils/busybox/patches/busybox-1.15.1-lineedit.diff @@ -0,0 +1,156 @@ +diff -urpN busybox-1.15.1/libbb/lineedit.c busybox-1.15.1-lineedit/libbb/lineedit.c +--- busybox-1.15.1/libbb/lineedit.c 2009-09-12 17:55:58.000000000 +0200 ++++ busybox-1.15.1-lineedit/libbb/lineedit.c 2009-09-28 23:56:03.000000000 +0200 +@@ -114,8 +114,8 @@ struct lineedit_statics { + unsigned cmdedit_prmt_len; /* length of prompt (without colors etc) */ + + unsigned cursor; +- unsigned command_len; +- /* *int* maxsize: we want x in "if (x > S.maxsize)" ++ int command_len; /* must be signed (^D returns -1 len) */ ++ /* signed maxsize: we want x in "if (x > S.maxsize)" + * to _not_ be promoted to unsigned */ + int maxsize; + CHAR_T *command_ps; +@@ -1095,15 +1095,15 @@ static void save_command_ps_at_cur_histo + int cur = state->cur_history; + free(state->history[cur]); + +-#if ENABLE_FEATURE_ASSUME_UNICODE ++# if ENABLE_FEATURE_ASSUME_UNICODE + { + char tbuf[MAX_LINELEN]; + save_string(tbuf, sizeof(tbuf)); + state->history[cur] = xstrdup(tbuf); + } +-#else ++# else + state->history[cur] = xstrdup(command_ps); +-#endif ++# endif + } + } + +@@ -1131,7 +1131,7 @@ static int get_next_history(void) + return 0; + } + +-#if ENABLE_FEATURE_EDITING_SAVEHISTORY ++# if ENABLE_FEATURE_EDITING_SAVEHISTORY + /* We try to ensure that concurrent additions to the history + * do not overwrite each other. + * Otherwise shell users get unhappy. +@@ -1256,10 +1256,10 @@ static void save_history(char *str) + free_line_input_t(st_temp); + } + } +-#else +-#define load_history(a) ((void)0) +-#define save_history(a) ((void)0) +-#endif /* FEATURE_COMMAND_SAVEHISTORY */ ++# else ++# define load_history(a) ((void)0) ++# define save_history(a) ((void)0) ++# endif /* FEATURE_COMMAND_SAVEHISTORY */ + + static void remember_in_history(char *str) + { +@@ -1290,15 +1290,15 @@ static void remember_in_history(char *st + /* i <= MAX_HISTORY */ + state->cur_history = i; + state->cnt_history = i; +-#if ENABLE_FEATURE_EDITING_SAVEHISTORY ++# if MAX_HISTORY > 0 && ENABLE_FEATURE_EDITING_SAVEHISTORY + if ((state->flags & SAVE_HISTORY) && state->hist_file) + save_history(str); +-#endif ++# endif + IF_FEATURE_EDITING_FANCY_PROMPT(num_ok_lines++;) + } + + #else /* MAX_HISTORY == 0 */ +-#define remember_in_history(a) ((void)0) ++# define remember_in_history(a) ((void)0) + #endif /* MAX_HISTORY */ + + +@@ -1476,11 +1476,11 @@ static void parse_and_put_prompt(const c + c = *prmt_ptr++; + + switch (c) { +-#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR ++# if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR + case 'u': + pbuf = user_buf ? user_buf : (char*)""; + break; +-#endif ++# endif + case 'h': + pbuf = free_me = safe_gethostname(); + *strchrnul(pbuf, '.') = '\0'; +@@ -1488,7 +1488,7 @@ static void parse_and_put_prompt(const c + case '$': + c = (geteuid() == 0 ? '#' : '$'); + break; +-#if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR ++# if ENABLE_FEATURE_GETUSERNAME_AND_HOMEDIR + case 'w': + /* /home/user[/something] -> ~[/something] */ + pbuf = cwd_buf; +@@ -1501,7 +1501,7 @@ static void parse_and_put_prompt(const c + pbuf = free_me = xasprintf("~%s", cwd_buf + l); + } + break; +-#endif ++# endif + case 'W': + pbuf = cwd_buf; + cp = strrchr(pbuf, '/'); +@@ -1688,13 +1688,15 @@ int FAST_FUNC read_line_input(const char + + /* With null flags, no other fields are ever used */ + state = st ? st : (line_input_t*) &const_int_0; +-#if ENABLE_FEATURE_EDITING_SAVEHISTORY ++#if MAX_HISTORY > 0 ++# if ENABLE_FEATURE_EDITING_SAVEHISTORY + if ((state->flags & SAVE_HISTORY) && state->hist_file) + if (state->cnt_history == 0) + load_history(state); +-#endif ++# endif + if (state->flags & DO_HISTORY) + state->cur_history = state->cnt_history; ++#endif + + /* prepare before init handlers */ + cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ +@@ -1716,7 +1718,7 @@ int FAST_FUNC read_line_input(const char + new_settings.c_cc[VTIME] = 0; + /* Turn off CTRL-C, so we can trap it */ + #ifndef _POSIX_VDISABLE +-#define _POSIX_VDISABLE '\0' ++# define _POSIX_VDISABLE '\0' + #endif + new_settings.c_cc[VINTR] = _POSIX_VDISABLE; + tcsetattr_stdin_TCSANOW(&new_settings); +@@ -2037,7 +2039,8 @@ int FAST_FUNC read_line_input(const char + rewrite_line: + /* Rewrite the line with the selected history item */ + /* change command */ +- command_len = load_string(state->history[state->cur_history] ? : "", maxsize); ++ command_len = load_string(state->history[state->cur_history] ? ++ state->history[state->cur_history] : "", maxsize); + /* redraw and go to eol (bol, in vi) */ + redraw(cmdedit_y, (state->flags & VI_MODE) ? 9999 : 0); + break; +@@ -2121,7 +2124,9 @@ int FAST_FUNC read_line_input(const char + #undef command + + #if ENABLE_FEATURE_ASSUME_UNICODE +- command_len = save_string(command, maxsize - 1); ++ command[0] = '\0'; ++ if (command_len > 0) ++ command_len = save_string(command, maxsize - 1); + free(command_ps); + #endif + diff --git a/packages/sysutils/busybox/patches/busybox-1.15.1-pidof_killall.diff b/packages/sysutils/busybox/patches/busybox-1.15.1-pidof_killall.diff new file mode 100644 index 0000000000..43c0c80636 --- /dev/null +++ b/packages/sysutils/busybox/patches/busybox-1.15.1-pidof_killall.diff @@ -0,0 +1,250 @@ +diff -urpN busybox-1.15.1/libbb/procps.c busybox-1.15.1-pidof_killall/libbb/procps.c +--- busybox-1.15.1/libbb/procps.c 2009-09-12 17:55:58.000000000 +0200 ++++ busybox-1.15.1-pidof_killall/libbb/procps.c 2009-09-22 23:03:59.000000000 +0200 +@@ -134,8 +134,8 @@ static unsigned long fast_strtoul_16(cha + return n; + } + /* TOPMEM uses fast_strtoul_10, so... */ +-#undef ENABLE_FEATURE_FAST_TOP +-#define ENABLE_FEATURE_FAST_TOP 1 ++# undef ENABLE_FEATURE_FAST_TOP ++# define ENABLE_FEATURE_FAST_TOP 1 + #endif + + #if ENABLE_FEATURE_FAST_TOP +@@ -198,14 +198,16 @@ procps_status_t* FAST_FUNC procps_scan(p + if (errno) + continue; + +- /* After this point we have to break, not continue +- * ("continue" would mean that current /proc/NNN +- * is not a valid process info) */ ++ /* After this point we can: ++ * "break": stop parsing, return the data ++ * "continue": try next /proc/XXX ++ */ + + memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz)); + + sp->pid = pid; +- if (!(flags & ~PSSCAN_PID)) break; ++ if (!(flags & ~PSSCAN_PID)) ++ break; /* we needed only pid, we got it */ + + #if ENABLE_SELINUX + if (flags & PSSCAN_CONTEXT) { +@@ -218,7 +220,7 @@ procps_status_t* FAST_FUNC procps_scan(p + + if (flags & PSSCAN_UIDGID) { + if (stat(filename, &sb)) +- break; ++ continue; /* process probably exited */ + /* Effective UID/GID, not real */ + sp->uid = sb.st_uid; + sp->gid = sb.st_gid; +@@ -234,10 +236,10 @@ procps_status_t* FAST_FUNC procps_scan(p + strcpy(filename_tail, "stat"); + n = read_to_buf(filename, buf); + if (n < 0) +- break; ++ continue; /* process probably exited */ + cp = strrchr(buf, ')'); /* split into "PID (cmd" and "" */ + /*if (!cp || cp[1] != ' ') +- break;*/ ++ continue;*/ + cp[0] = '\0'; + if (sizeof(sp->comm) < 16) + BUG_comm_size(); +@@ -257,12 +259,12 @@ procps_status_t* FAST_FUNC procps_scan(p + "%lu " /* start_time */ + "%lu " /* vsize */ + "%lu " /* rss */ +-#if ENABLE_FEATURE_TOP_SMP_PROCESS ++# if ENABLE_FEATURE_TOP_SMP_PROCESS + "%*s %*s %*s %*s %*s %*s " /*rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */ + "%*s %*s %*s %*s " /*signal, blocked, sigignore, sigcatch */ + "%*s %*s %*s %*s " /*wchan, nswap, cnswap, exit_signal */ + "%d" /*cpu last seen on*/ +-#endif ++# endif + , + sp->state, &sp->ppid, + &sp->pgid, &sp->sid, &tty, +@@ -271,17 +273,17 @@ procps_status_t* FAST_FUNC procps_scan(p + &sp->start_time, + &vsz, + &rss +-#if ENABLE_FEATURE_TOP_SMP_PROCESS ++# if ENABLE_FEATURE_TOP_SMP_PROCESS + , &sp->last_seen_on_cpu +-#endif ++# endif + ); + + if (n < 11) +- break; +-#if ENABLE_FEATURE_TOP_SMP_PROCESS ++ continue; /* bogus data, get next /proc/XXX */ ++# if ENABLE_FEATURE_TOP_SMP_PROCESS + if (n < 11+15) + sp->last_seen_on_cpu = 0; +-#endif ++# endif + + /* vsz is in bytes and we want kb */ + sp->vsz = vsz >> 10; +@@ -311,14 +313,14 @@ procps_status_t* FAST_FUNC procps_scan(p + sp->vsz = fast_strtoul_10(&cp) >> 10; + /* vsz is in bytes but rss is in *PAGES*! Can you believe that? */ + sp->rss = fast_strtoul_10(&cp) << sp->shift_pages_to_kb; +-#if ENABLE_FEATURE_TOP_SMP_PROCESS ++# if ENABLE_FEATURE_TOP_SMP_PROCESS + /* (6): rss_rlim, start_code, end_code, start_stack, kstk_esp, kstk_eip */ + /* (4): signal, blocked, sigignore, sigcatch */ + /* (4): wchan, nswap, cnswap, exit_signal */ + cp = skip_fields(cp, 14); + //FIXME: is it safe to assume this field exists? + sp->last_seen_on_cpu = fast_strtoul_10(&cp); +-#endif ++# endif + #endif /* end of !ENABLE_FEATURE_TOP_SMP_PROCESS */ + + #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS +@@ -343,48 +345,48 @@ procps_status_t* FAST_FUNC procps_scan(p + + strcpy(filename_tail, "smaps"); + file = fopen_for_read(filename); +- if (!file) +- break; +- while (fgets(buf, sizeof(buf), file)) { +- unsigned long sz; +- char *tp; +- char w; ++ if (file) { ++ while (fgets(buf, sizeof(buf), file)) { ++ unsigned long sz; ++ char *tp; ++ char w; + #define SCAN(str, name) \ + if (strncmp(buf, str, sizeof(str)-1) == 0) { \ + tp = skip_whitespace(buf + sizeof(str)-1); \ + sp->name += fast_strtoul_10(&tp); \ + continue; \ + } +- SCAN("Shared_Clean:" , shared_clean ); +- SCAN("Shared_Dirty:" , shared_dirty ); +- SCAN("Private_Clean:", private_clean); +- SCAN("Private_Dirty:", private_dirty); ++ SCAN("Shared_Clean:" , shared_clean ); ++ SCAN("Shared_Dirty:" , shared_dirty ); ++ SCAN("Private_Clean:", private_clean); ++ SCAN("Private_Dirty:", private_dirty); + #undef SCAN +- // f7d29000-f7d39000 rw-s ADR M:m OFS FILE +- tp = strchr(buf, '-'); +- if (tp) { +- *tp = ' '; +- tp = buf; +- sz = fast_strtoul_16(&tp); /* start */ +- sz = (fast_strtoul_16(&tp) - sz) >> 10; /* end - start */ +- // tp -> "rw-s" string +- w = tp[1]; +- // skipping "rw-s ADR M:m OFS " +- tp = skip_whitespace(skip_fields(tp, 4)); +- // filter out /dev/something (something != zero) +- if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) { +- if (w == 'w') { +- sp->mapped_rw += sz; +- } else if (w == '-') { +- sp->mapped_ro += sz; ++ // f7d29000-f7d39000 rw-s ADR M:m OFS FILE ++ tp = strchr(buf, '-'); ++ if (tp) { ++ *tp = ' '; ++ tp = buf; ++ sz = fast_strtoul_16(&tp); /* start */ ++ sz = (fast_strtoul_16(&tp) - sz) >> 10; /* end - start */ ++ // tp -> "rw-s" string ++ w = tp[1]; ++ // skipping "rw-s ADR M:m OFS " ++ tp = skip_whitespace(skip_fields(tp, 4)); ++ // filter out /dev/something (something != zero) ++ if (strncmp(tp, "/dev/", 5) != 0 || strcmp(tp, "/dev/zero\n") == 0) { ++ if (w == 'w') { ++ sp->mapped_rw += sz; ++ } else if (w == '-') { ++ sp->mapped_ro += sz; ++ } + } +- } + //else printf("DROPPING %s (%s)\n", buf, tp); +- if (strcmp(tp, "[stack]\n") == 0) +- sp->stack += sz; ++ if (strcmp(tp, "[stack]\n") == 0) ++ sp->stack += sz; ++ } + } ++ fclose(file); + } +- fclose(file); + } + #endif /* TOPMEM */ + #if ENABLE_FEATURE_PS_ADDITIONAL_COLUMNS +@@ -393,23 +395,34 @@ procps_status_t* FAST_FUNC procps_scan(p + + strcpy(filename_tail, "status"); + file = fopen_for_read(filename); +- if (!file) +- break; +- while (fgets(buf, sizeof(buf), file)) { +- char *tp; ++ if (file) { ++ while (fgets(buf, sizeof(buf), file)) { ++ char *tp; + #define SCAN_TWO(str, name, statement) \ + if (strncmp(buf, str, sizeof(str)-1) == 0) { \ + tp = skip_whitespace(buf + sizeof(str)-1); \ + sscanf(tp, "%u", &sp->name); \ + statement; \ + } +- SCAN_TWO("Uid:", ruid, continue); +- SCAN_TWO("Gid:", rgid, break); ++ SCAN_TWO("Uid:", ruid, continue); ++ SCAN_TWO("Gid:", rgid, break); + #undef SCAN_TWO ++ } ++ fclose(file); + } +- fclose(file); + } + #endif /* PS_ADDITIONAL_COLUMNS */ ++ if (flags & PSSCAN_EXE) { ++ strcpy(filename_tail, "exe"); ++ free(sp->exe); ++ sp->exe = xmalloc_readlink(filename); ++ } ++ /* Note: if /proc/PID/cmdline is empty, ++ * code below "breaks". Therefore it must be ++ * the last code to parse /proc/PID/xxx data ++ * (we used to have /proc/PID/exe parsing after it ++ * and were getting stale sp->exe). ++ */ + #if 0 /* PSSCAN_CMD is not used */ + if (flags & (PSSCAN_CMD|PSSCAN_ARGV0)) { + free(sp->argv0); +@@ -452,13 +465,9 @@ procps_status_t* FAST_FUNC procps_scan(p + } + } + #endif +- if (flags & PSSCAN_EXE) { +- strcpy(filename_tail, "exe"); +- free(sp->exe); +- sp->exe = xmalloc_readlink(filename); +- } + break; +- } ++ } /* for (;;) */ ++ + return sp; + } + diff --git a/packages/sysutils/busybox/patches/busybox-1.15.1-sed.diff b/packages/sysutils/busybox/patches/busybox-1.15.1-sed.diff new file mode 100644 index 0000000000..7042bf0ebe --- /dev/null +++ b/packages/sysutils/busybox/patches/busybox-1.15.1-sed.diff @@ -0,0 +1,15 @@ +diff -urpN busybox-1.15.1/editors/sed.c busybox-1.15.1-sed/editors/sed.c +--- busybox-1.15.1/editors/sed.c 2009-09-12 17:55:58.000000000 +0200 ++++ busybox-1.15.1-sed/editors/sed.c 2009-09-22 03:01:59.000000000 +0200 +@@ -690,10 +690,8 @@ static int do_subst_command(sed_cmd_t *s + if (sed_cmd->which_match) + break; + +- if (*line == '\0') +- break; + //maybe (G.regmatch[0].rm_eo ? REG_NOTBOL : 0) instead of unconditional REG_NOTBOL? +- } while (regexec(current_regex, line, 10, G.regmatch, REG_NOTBOL) != REG_NOMATCH); ++ } while (*line && regexec(current_regex, line, 10, G.regmatch, REG_NOTBOL) != REG_NOMATCH); + + /* Copy rest of string into output pipeline */ + while (1) { diff --git a/packages/sysutils/busybox/patches/busybox-1.15.1-uniq.diff b/packages/sysutils/busybox/patches/busybox-1.15.1-uniq.diff new file mode 100644 index 0000000000..0055544b07 --- /dev/null +++ b/packages/sysutils/busybox/patches/busybox-1.15.1-uniq.diff @@ -0,0 +1,11 @@ +diff -urpN busybox-1.15.1/coreutils/uniq.c busybox-1.15.1-uniq/coreutils/uniq.c +--- busybox-1.15.1/coreutils/uniq.c 2009-09-12 17:55:58.000000000 +0200 ++++ busybox-1.15.1-uniq/coreutils/uniq.c 2009-09-23 12:56:09.132695142 +0200 +@@ -84,6 +84,7 @@ int uniq_main(int argc UNUSED_PARAM, cha + break; + } + ++ free(s1); + ++dups; /* note: testing for overflow seems excessive. */ + } + diff --git a/packages/sysutils/busybox/patches/fbsplash.diff b/packages/sysutils/busybox/patches/fbsplash.diff new file mode 100644 index 0000000000..f8b056729d --- /dev/null +++ b/packages/sysutils/busybox/patches/fbsplash.diff @@ -0,0 +1,1849 @@ +*** busybox-1.15.0/include/usage.h.orig 2009-08-22 14:52:14.000000000 +0200 +--- busybox-1.15.0/include/usage.h 2009-09-01 08:42:18.000000000 +0200 +*************** +*** 156,162 **** + "\n -n Start new tone" \ + + #define fbsplash_trivial_usage \ +! "-s IMGFILE [-c] [-d DEV] [-i INIFILE] [-f CMD]" + #define fbsplash_full_usage "\n\n" \ + "Options:\n" \ + "\n -s Image" \ +--- 156,163 ---- + "\n -n Start new tone" \ + + #define fbsplash_trivial_usage \ +! "-s IMGFILE [-c] [-d DEV] [-i INIFILE] [-f CMD] " \ +! IF_FEATURE_FBSPLASH_FONTLOAD( "[-m FONTMAPFILE]" ) + #define fbsplash_full_usage "\n\n" \ + "Options:\n" \ + "\n -s Image" \ +*************** +*** 165,172 **** +--- 166,178 ---- + "\n -i Config file (var=value):" \ + "\n BAR_LEFT,BAR_TOP,BAR_WIDTH,BAR_HEIGHT" \ + "\n BAR_R,BAR_G,BAR_B" \ ++ "\n TEXT_LEFT,TEXT_TOP,TEXT_R,TEXT_G,TEXT_B,TEXT_SIZE" \ + "\n -f Control pipe (else exit after drawing image)" \ + "\n commands: 'NN' (% for progress bar) or 'exit'" \ ++ IF_FEATURE_FBSPLASH_FONTLOAD( \ ++ "\n -m Font map file" \ ++ "\n commands: 'NN' (% for progress bar), 'write:string to print' or 'exit'" \ ++ ) + + #define brctl_trivial_usage \ + "COMMAND [BRIDGE [INTERFACE]]" +*** busybox-1.15.0/miscutils/Config.in.orig 2009-08-22 17:59:16.000000000 +0200 +--- busybox-1.15.0/miscutils/Config.in 2009-09-01 08:44:41.000000000 +0200 +*************** +*** 256,262 **** + default n + help + Shows splash image and progress bar on framebuffer device. +! Can be used during boot phase of an embedded device. ~2kb. + Usage: + - use kernel option 'vga=xxx' or otherwise enable fb device. + - put somewhere fbsplash.cfg file and an image in .ppm format. +--- 256,263 ---- + default n + help + Shows splash image and progress bar on framebuffer device. +! Can be used during boot phase of an embedded device. +! Code size is 2..7kb depends on enabled features. + Usage: + - use kernel option 'vga=xxx' or otherwise enable fb device. + - put somewhere fbsplash.cfg file and an image in .ppm format. +*************** +*** 272,277 **** +--- 273,316 ---- + "NN" (ASCII decimal number) - percentage to show on progress bar + "exit" - well you guessed it + ++ config FEATURE_FBSPLASH_8BPP ++ bool "support 8bit depth with color mapping" ++ depends on FBSPLASH ++ help ++ support for low color framebuffer that's need color mapping ~350 b ++ ++ config FEATURE_FBSPLASH_SPRITES ++ bool "Render icons and animations" ++ default n ++ depends on FBSPLASH ++ help ++ This option adds the ability to display icons on the ++ image displayed by the fbsplash applet. ~1.5kb. ++ - command for fifo: ++ "load:x:y:filename" - load images from file ++ each sprite is one square area when image is wider than higher ++ before load new sprite set, old area is cleared. ++ "sprite:n" - show one sprite - sprite 0 is background. ++ "anime:n:m:t" - anime from sprite n up/down to sprite m ++ time between sprites is in t * 100 msec. ++ ++ config FEATURE_FBSPLASH_TEXT ++ bool "text rendering" ++ default n ++ depends on FBSPLASH ++ help ++ This option adds the ability to print text messages on the ++ image displayed by the fbsplash applet. ~2kb. ++ - command for fifo: ++ "write:string to print" - print the string after the word "write:" ++ ++ config FEATURE_FBSPLASH_FONTLOAD ++ bool "font loading" ++ depends on FEATURE_FBSPLASH_TEXT ++ help ++ The font is loaded from a standard console font file. ++ Supported are psf v1.x and psf v2.0 files including mapping ~1kb. ++ + config FLASH_LOCK + bool "flash_lock" + default n +*** busybox-1.15.0/miscutils/fbsplash.c.orig 2009-08-21 00:26:14.000000000 +0200 +--- busybox-1.15.0/miscutils/fbsplash.c 2009-09-01 08:42:18.000000000 +0200 +*************** +*** 1,6 **** +--- 1,7 ---- + /* vi: set sw=4 ts=4: */ + /* + * Copyright (C) 2008 Michele Sanges ++ * Copyright (C) 2009 Jiri Gabriel + * + * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. + * +*************** +*** 10,51 **** + * - run applet: $ setsid fbsplash [params] & + * -c: hide cursor + * -d /dev/fbN: framebuffer device (if not /dev/fb0) +! * -s path_to_image_file (can be "-" for stdin) + * -i path_to_cfg_file + * -f path_to_fifo (can be "-" for stdin) + * - if you want to run it only in presence of a kernel parameter + * (for example fbsplash=on), use: + * grep -q "fbsplash=on" + + /* If you want logging messages on /tmp/fbsplash.log... */ + #define DEBUG 0 + +! #define BYTES_PER_PIXEL 2 + +! typedef unsigned short DATA; + + struct globals { + #if DEBUG + bool bdebug_messages; // enable/disable logging + FILE *logfile_fd; // log file + #endif +! unsigned char *addr; // pointer to framebuffer memory +! unsigned ns[7]; // n-parameters + const char *image_filename; + struct fb_var_screeninfo scr_var; + struct fb_fix_screeninfo scr_fix; + }; + #define G (*ptr_to_globals) + #define INIT_G() do { \ + SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ + } while (0) + + #define nbar_width ns[0] // progress bar width + #define nbar_height ns[1] // progress bar height +--- 11,198 ---- + * - run applet: $ setsid fbsplash [params] & + * -c: hide cursor + * -d /dev/fbN: framebuffer device (if not /dev/fb0) +! * -s path_to_image_file - ppm or ppm.gz or ppm.bz2 + * -i path_to_cfg_file + * -f path_to_fifo (can be "-" for stdin) ++ * -m font map file - standard psf file (v1 and v2) can be with unumap + * - if you want to run it only in presence of a kernel parameter + * (for example fbsplash=on), use: + * grep -q "fbsplash=on" ++ #if ENABLE_FEATURE_FBSPLASH_TEXT ++ #include ++ ++ /* if you have fonts with sequences can turn this to 1 i not find any font with this feature ++ ~510 bytes of code */ ++ #define ENABLE_FEATURE_FBSPLASH_PSFSEQS 0 ++ ++ /* if you not use text colors and need optimize size - disable text colors ++ ~250 bytes of code */ ++ #define ENABLE_FEATURE_FBSPLASH_TEXT_COLORS 1 ++ ++ #if !defined(GIO_UNIMAP) ++ struct unipair { ++ unsigned short unicode; ++ unsigned short fontpos; ++ } __atribute__ ((packed)); ++ ++ struct unimapdesc { ++ unsigned short entry_ct; ++ struct unipair *entries; ++ } __atribute__ ((packed)); ++ #endif ++ ++ #if ENABLE_FEATURE_FBSPLASH_FONTLOAD ++ ++ enum { // uint16 ++ PSF1_MAGIC = 0x0436, ++ PSF1_SEPARATOR = 0xFFFF, ++ PSF1_STARTSEQ = 0xFFFE ++ }; ++ ++ enum { // uint32 ++ PSF2_MAGIC = 0x864ab572, ++ PSF2_HAS_UNICODE_TABLE = 0x01, /* bits used in flags */ ++ PSF2_MAXVERSION = 0 /* max version recognized so far */ ++ }; ++ ++ enum { // uint8 ++ PSF1_MODE512 = 0x01, ++ PSF1_MODEHASTAB = 0x02, ++ PSF1_MODEHASSEQ = 0x04, ++ PSF1_MAXMODE = 0x05, ++ PSF2_STARTSEQ = 0xFE, ++ PSF2_SEPARATOR = 0xFF ++ }; ++ ++ struct psf1_header { ++ uint16_t magic; /* Magic number */ ++ uint8_t mode; /* PSF font mode */ ++ uint8_t charsize; /* Character size */ ++ } __attribute__ ((packed)); ++ ++ struct psf2_header { ++ uint32_t magic; ++ uint32_t version; ++ uint32_t headersize; /* offset of bitmaps in file */ ++ uint32_t flags; ++ uint32_t length; /* number of glyphs */ ++ uint32_t charsize; /* number of bytes for each character */ ++ uint32_t height, width; /* max dimensions of glyphs */ ++ /* charsize = height * ((width + 7) / 8) */ ++ } __attribute__ ((packed)); ++ ++ #endif // FONTLOAD ++ struct fbfont { ++ uint8_t *mem1; ++ uint8_t *glyphs; ++ struct unimapdesc ud; ++ int height; ++ int width; ++ int glyphcount; ++ int charsize; ++ int rowbytes; ++ }; ++ ++ #endif + + /* If you want logging messages on /tmp/fbsplash.log... */ + #define DEBUG 0 + +! typedef uint32_t RGB; + +! struct sprite { +! int w,h,bw; // width height in pixels, width in bytes +! uint8_t pixbuf[0]; +! }; +! +! struct ppmfile { +! int fd; +! int sizx,sizy; +! int bufhead,buftail; +! uint8_t buf[0]; // buf for entire pixels row +! }; + + struct globals { + #if DEBUG + bool bdebug_messages; // enable/disable logging + FILE *logfile_fd; // log file + #endif +! unsigned char *addr; // pointer to visible framebuffer memory +! unsigned char *mapaddr; // pointer to framebuffer memory +! #if ENABLE_FEATURE_FBSPLASH_TEXT +! #define FBCFGVALS 13 +! #else +! #define FBCFGVALS 7 +! #endif +! unsigned ns[FBCFGVALS]; // n-parameters + const char *image_filename; + struct fb_var_screeninfo scr_var; + struct fb_fix_screeninfo scr_fix; ++ int bytes_per_pixel,x0,y0; // offset for centering ++ struct sprite *spb1,*spb2; ++ #if ENABLE_FEATURE_FBSPLASH_TEXT ++ struct fbfont *font; ++ struct sprite *spt; ++ uint8_t *unknown_glyph; ++ #if ENABLE_FEATURE_FBSPLASH_PSFSEQS ++ uint8_t combglyph[4*32]; /* max width=32 max height=32 */ ++ #endif ++ #endif + }; ++ + #define G (*ptr_to_globals) + #define INIT_G() do { \ + SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \ + } while (0) ++ #if ENABLE_FEATURE_FBSPLASH_TEXT ++ #define GF (*(ptr_to_globals->font)) ++ #endif + + #define nbar_width ns[0] // progress bar width + #define nbar_height ns[1] // progress bar height +*************** +*** 54,59 **** +--- 201,275 ---- + #define nbar_colr ns[4] // progress bar color red component + #define nbar_colg ns[5] // progress bar color green component + #define nbar_colb ns[6] // progress bar color blue component ++ #define text_posx ns[7] // text horizontal position ++ #define text_posy ns[8] // text vertical position ++ #define text_colr ns[9] // text color red component ++ #define text_colg ns[10] // text color green component ++ #define text_colb ns[11] // text color blue component ++ #define text_size ns[12] // text size (1 to 4) ++ ++ /** ++ * A function to compute pixel value ++ */ ++ static RGB FAST_FUNC makecol(uint16_t r, uint16_t g, uint16_t b) { ++ if (r > 255) r = 255; ++ if (g > 255) g = 255; ++ if (b > 255) b = 255; ++ #if ENABLE_FEATURE_FBSPLASH_8BPP ++ if (G.bytes_per_pixel == 1) { ++ // mymap is 6*8*5 = 240 values on offset 16 ++ // (r/42.6666) + (g/32) + (b/51.2) ++ return 16 + (((r << 8) + r) / 13107) * 40 + ++ (((g << 8) + g) / 9362) * 5 + ++ (((b << 8) + b) / 16383); ++ } ++ #endif ++ return ((r >> (8 - G.scr_var.red.length )) << G.scr_var.red.offset) | ++ ((g >> (8 - G.scr_var.green.length)) << G.scr_var.green.offset) | ++ ((b >> (8 - G.scr_var.blue.length )) << G.scr_var.blue.offset); ++ } ++ ++ /* ++ * A function to put the pixel row ++ */ ++ static void fb_putpixrow(int x, int y, int w, uint8_t *rgb) { ++ uint8_t *a; ++ int realw; ++ if (x < 0 || y < 0 || x > G.scr_var.xres || y > G.scr_var.yres) return; ++ a = G.addr + G.scr_fix.line_length * y + G.bytes_per_pixel * x; ++ realw = ((x + w) < G.scr_var.xres ? w : G.scr_var.xres - x) * G.bytes_per_pixel; ++ memcpy(a,rgb,realw); ++ return; ++ } ++ ++ /* ++ * A function to put the sprite to position or fill sprite from videoram ++ */ ++ static void fb_sprite(int x, int y, int x0, int width, struct sprite *s, int direction) { ++ uint8_t *a,*p; ++ int realw,iy; ++ ++ if (x < 0 || y < 0 || x > G.scr_var.xres || y > G.scr_var.yres || ++ x0 >= s->w || x0 < 0 || width > (s->w - x0)) { ++ return; ++ } ++ realw = ((x + width) < G.scr_var.xres ? width : (G.scr_var.xres - x)) * G.bytes_per_pixel; ++ a = G.addr + G.scr_fix.line_length * y + G.bytes_per_pixel * x; ++ p = &(s->pixbuf[x0 * G.bytes_per_pixel]); ++ for (iy = 0; iy < s->h; iy++) { ++ if ((iy + y) > G.scr_var.yres) break; ++ if (direction == 1) { ++ memcpy(p,a,realw); ++ } else { ++ memcpy(a,p,realw); ++ } ++ a += G.scr_fix.line_length; ++ p += s->bw; ++ } ++ return; ++ } ++ #define fb_putsprite(x,y,s) fb_sprite(x,y,0,s->w,s,0) ++ #define fb_getsprite(x,y,s) fb_sprite(x,y,0,s->w,s,1) + + #if DEBUG + #define DEBUG_MESSAGE(strMessage, args...) \ +*************** +*** 78,231 **** + xioctl(fbfd, FBIOGET_VSCREENINFO, &G.scr_var); + xioctl(fbfd, FBIOGET_FSCREENINFO, &G.scr_fix); + +! if (G.scr_var.bits_per_pixel != 16) +! bb_error_msg_and_die("only 16 bpp is supported"); + + // map the device in memory +! G.addr = mmap(NULL, +! G.scr_var.xres * G.scr_var.yres +! * BYTES_PER_PIXEL /*(G.scr_var.bits_per_pixel / 8)*/ , + PROT_WRITE, MAP_SHARED, fbfd, 0); +! if (G.addr == MAP_FAILED) + bb_perror_msg_and_die("mmap"); + close(fbfd); + } + + + /** +- * Draw hollow rectangle on framebuffer +- */ +- static void fb_drawrectangle(void) +- { +- int cnt; +- DATA thispix; +- DATA *ptr1, *ptr2; +- unsigned char nred = G.nbar_colr/2; +- unsigned char ngreen = G.nbar_colg/2; +- unsigned char nblue = G.nbar_colb/2; +- +- nred >>= 3; // 5-bit red +- ngreen >>= 2; // 6-bit green +- nblue >>= 3; // 5-bit blue +- thispix = nblue + (ngreen << 5) + (nred << (5+6)); +- +- // horizontal lines +- ptr1 = (DATA*)(G.addr + (G.nbar_posy * G.scr_var.xres + G.nbar_posx) * BYTES_PER_PIXEL); +- ptr2 = (DATA*)(G.addr + ((G.nbar_posy + G.nbar_height - 1) * G.scr_var.xres + G.nbar_posx) * BYTES_PER_PIXEL); +- cnt = G.nbar_width - 1; +- do { +- *ptr1++ = thispix; +- *ptr2++ = thispix; +- } while (--cnt >= 0); +- +- // vertical lines +- ptr1 = (DATA*)(G.addr + (G.nbar_posy * G.scr_var.xres + G.nbar_posx) * BYTES_PER_PIXEL); +- ptr2 = (DATA*)(G.addr + (G.nbar_posy * G.scr_var.xres + G.nbar_posx + G.nbar_width - 1) * BYTES_PER_PIXEL); +- cnt = G.nbar_height - 1 /* HUH?! G.nbar_posy + G.nbar_height - 1 - G.nbar_posy*/; +- do { +- *ptr1 = thispix; ptr1 += G.scr_var.xres; +- *ptr2 = thispix; ptr2 += G.scr_var.xres; +- } while (--cnt >= 0); +- } +- +- +- /** +- * Draw filled rectangle on framebuffer +- * \param nx1pos,ny1pos upper left position +- * \param nx2pos,ny2pos down right position +- * \param nred,ngreen,nblue rgb color +- */ +- static void fb_drawfullrectangle(int nx1pos, int ny1pos, int nx2pos, int ny2pos, +- unsigned char nred, unsigned char ngreen, unsigned char nblue) +- { +- int cnt1, cnt2, nypos; +- DATA thispix; +- DATA *ptr; +- +- nred >>= 3; // 5-bit red +- ngreen >>= 2; // 6-bit green +- nblue >>= 3; // 5-bit blue +- thispix = nblue + (ngreen << 5) + (nred << (5+6)); +- +- cnt1 = ny2pos - ny1pos; +- nypos = ny1pos; +- do { +- ptr = (DATA*)(G.addr + (nypos * G.scr_var.xres + nx1pos) * BYTES_PER_PIXEL); +- cnt2 = nx2pos - nx1pos; +- do { +- *ptr++ = thispix; +- } while (--cnt2 >= 0); +- +- nypos++; +- } while (--cnt1 >= 0); +- } +- +- +- /** + * Draw a progress bar on framebuffer +! * \param percent percentage of loading + */ +! static void fb_drawprogressbar(unsigned percent) + { +! int i, left_x, top_y, width, height; + +! // outer box +! left_x = G.nbar_posx; +! top_y = G.nbar_posy; +! width = G.nbar_width - 1; +! height = G.nbar_height - 1; +! if ((height | width) < 0) + return; +! // NB: "width" of 1 actually makes rect with width of 2! +! fb_drawrectangle(); +! +! // inner "empty" rectangle +! left_x++; +! top_y++; +! width -= 2; +! height -= 2; +! if ((height | width) < 0) + return; +! fb_drawfullrectangle( +! left_x, top_y, +! left_x + width, top_y + height, +! G.nbar_colr, G.nbar_colg, G.nbar_colb); +! +! if (percent > 0) { +! // actual progress bar +! width = width * percent / 100; +! i = height; +! if (height == 0) +! height++; // divide by 0 is bad +! while (i >= 0) { +! // draw one-line thick "rectangle" +! // top line will have gray lvl 200, bottom one 100 +! unsigned gray_level = 100 + i*100/height; +! fb_drawfullrectangle( +! left_x, top_y, left_x + width, top_y, +! gray_level, gray_level, gray_level); +! top_y++; +! i--; +! } +! } + } + + + /** +! * Draw image from PPM file + */ +! static void fb_drawimage(void) +! { +! char *head, *ptr; +! FILE *theme_file; +! unsigned char *pixline; +! unsigned i, j, width, height, line_size; +! +! theme_file = xfopen_stdin(G.image_filename); +! head = xmalloc(256); +! + /* parse ppm header +! * - A ppm image’s magic number is the two characters "P6". + * - Whitespace (blanks, TABs, CRs, LFs). + * - A width, formatted as ASCII characters in decimal. + * - Whitespace. +--- 294,411 ---- + xioctl(fbfd, FBIOGET_VSCREENINFO, &G.scr_var); + xioctl(fbfd, FBIOGET_FSCREENINFO, &G.scr_fix); + +! #if ENABLE_FEATURE_FBSPLASH_8BPP +! if ((G.scr_var.bits_per_pixel < 8) || +! (G.scr_fix.type != FB_TYPE_PACKED_PIXELS)) { +! bb_error_msg_and_die("only 8,15,16,24 and 32 bpp is supported"); +! } +! #else +! if ((G.scr_var.bits_per_pixel < 15) || +! (G.scr_fix.type != FB_TYPE_PACKED_PIXELS)) { +! bb_error_msg_and_die("only 15,16,24 and 32 bpp is supported"); +! } +! #endif +! switch (G.scr_fix.visual) { +! #if ENABLE_FEATURE_FBSPLASH_8BPP +! case FB_VISUAL_PSEUDOCOLOR: do { +! uint8_t *cmem; +! struct fb_cmap *cmap; +! int r,g,b,i; +! cmem = xzalloc(sizeof(struct fb_cmap) + sizeof(uint16_t) * 3 * 256); +! cmap = (struct fb_cmap *)cmem; +! cmap->len = 256; +! cmap->red = (uint16_t *)&(cmem[sizeof(struct fb_cmap)]); +! cmap->green = &(cmap->red[256]); +! cmap->blue = &(cmap->green[256]); +! xioctl(fbfd, FBIOGETCMAP, cmem); // read original palette +! // fill cmap with my 6x8x5 pallette +! for (r = 0,i = 16; r < 6; r++) { +! for (g = 0; g < 8; g++) { +! for (b = 0; b < 5; b++, i++) { +! cmap->red[i] = r * 13107; +! cmap->green[i] = g * 9362; +! cmap->blue[i] = b * 16383; +! } +! } +! } +! xioctl(fbfd, FBIOPUTCMAP, cmem); +! free(cmem); +! } while(0); +! #endif +! case FB_VISUAL_TRUECOLOR: +! break; +! default: +! bb_error_msg_and_die("only TrueColor modes is supported"); +! } + ++ G.bytes_per_pixel = (G.scr_var.bits_per_pixel + 7) / 8; + // map the device in memory +! G.mapaddr = mmap(NULL, +! G.scr_var.yres_virtual * G.scr_fix.line_length , + PROT_WRITE, MAP_SHARED, fbfd, 0); +! if (G.mapaddr == MAP_FAILED) + bb_perror_msg_and_die("mmap"); ++ G.addr = G.mapaddr + G.scr_var.yoffset * G.scr_fix.line_length; + close(fbfd); + } + + + /** + * Draw a progress bar on framebuffer +! * \param frompct percentage on which bar starting +! * \param topct percentage where bar end + */ +! static void fb_drawnbar(int frompct, int topct) + { +! int w0,w1,w2; + +! if (G.spb1 == NULL || G.spb2 == NULL) + return; +! if (frompct < 0 || frompct > 100 || +! topct < 0 || topct > 100 || +! frompct > topct) { + return; +! } +! w0 = G.spb1->w * frompct / 100; +! w0 = (w0 > G.spb1->w ? G.spb1->w : w0); +! w2 = G.spb1->w * (100 - topct) / 100; +! w2 = ((w0 + w2) > G.spb1->w ? G.spb1->w - w0 : w2); +! w1 = G.spb1->w - w0 - w2; +! if (w0 > 0) +! fb_sprite(G.nbar_posx, G.nbar_posy, 0, w0, G.spb1, 0); // left "empty" area +! if (w1 > 0) +! fb_sprite(G.nbar_posx + w0, G.nbar_posy, w0, w1, G.spb2, 0); // filled area +! if (w2 > 0) +! fb_sprite(G.nbar_posx + w0 + w1, G.nbar_posy, w0 + w1, w2, G.spb1, 0); // right "empty" area + } + ++ static struct sprite *fb_newsprite(int pw, int ph, int scrx, int scry) { ++ struct sprite *s; ++ s=xmalloc(sizeof(struct sprite) + ++ ph * pw * G.bytes_per_pixel); ++ s->w = pw; ++ s->h = ph; ++ s->bw = pw * G.bytes_per_pixel; ++ if (scrx >= 0) fb_getsprite(scrx, scry, s); // read ++ return s; ++ } + + /** +! * Open PPM file - must be binary, color maxval 255 + */ +! static struct ppmfile *ppm_open(const char *filename) { +! int i,k,l,val; +! struct ppmfile *p; +! uint8_t *s; +! char *e; +! +! i = open_zipped(filename); +! if (i == -1) return NULL; +! p = (struct ppmfile *) xmalloc(sizeof(struct ppmfile) + 600); +! // initial buf 600 bytes header cannot be larger +! p->fd = i; + /* parse ppm header +! * - A ppm images magic number is the two characters "P6". + * - Whitespace (blanks, TABs, CRs, LFs). + * - A width, formatted as ASCII characters in decimal. + * - Whitespace. +*************** +*** 237,292 **** + * - A raster of Width * Height pixels in triplets of rgb + * in pure binary by 1 (or not implemented 2) bytes. + */ +! while (1) { +! if (fgets(head, 256, theme_file) == NULL +! /* do not overrun the buffer */ +! || strlen(bb_common_bufsiz1) >= sizeof(bb_common_bufsiz1) - 256) +! bb_error_msg_and_die("bad PPM file '%s'", G.image_filename); +! +! ptr = memchr(skip_whitespace(head), '#', 256); +! if (ptr != NULL) +! *ptr = 0; /* ignore comments */ +! strcat(bb_common_bufsiz1, head); +! // width, height, max_color_val +! if (sscanf(bb_common_bufsiz1, "P6 %u %u %u", &width, &height, &i) == 3 +! && i <= 255) +! break; +! /* If we do not find a signature throughout the whole file then +! we will diagnose this via EOF on read in the head of the loop. */ + } + +! if (ENABLE_FEATURE_CLEAN_UP) +! free(head); +! if (width != G.scr_var.xres || height != G.scr_var.yres) + bb_error_msg_and_die("PPM %dx%d does not match screen %dx%d", +! width, height, G.scr_var.xres, G.scr_var.yres); +! line_size = width*3; + if (width > G.scr_var.xres) + width = G.scr_var.xres; + if (height > G.scr_var.yres) + height = G.scr_var.yres; + +! pixline = xmalloc(line_size); +! for (j = 0; j < height; j++) { +! unsigned char *pixel = pixline; +! DATA *src = (DATA *)(G.addr + j * G.scr_fix.line_length); + +! if (fread(pixline, 1, line_size, theme_file) != line_size) +! bb_error_msg_and_die("bad PPM file '%s'", G.image_filename); + for (i = 0; i < width; i++) { +! unsigned thispix; +! thispix = (((unsigned)pixel[0] << 8) & 0xf800) +! | (((unsigned)pixel[1] << 3) & 0x07e0) +! | (((unsigned)pixel[2] >> 3)); +! *src++ = thispix; + pixel += 3; + } + } +! if (ENABLE_FEATURE_CLEAN_UP) +! free(pixline); +! fclose(theme_file); + } + + + /** + * Parse configuration file +--- 417,1159 ---- + * - A raster of Width * Height pixels in triplets of rgb + * in pure binary by 1 (or not implemented 2) bytes. + */ +! l=read(p->fd,&(p->buf[0]),600); +! if ((l < 0) || (p->buf[0] != 'P') || (p->buf[1] != '6')) { +! goto ppmopen_end; +! } +! for (s = &(p->buf[2]), i = 0, k = 0; s < &(p->buf[l]) && (k < 3); ) { +! switch (i) { +! case 0: +! if (*s <= ' ') { +! s++; // skip whitespaces +! } else { +! i++; // next state +! } +! break; +! case 1: // num or rmks +! if (*s == '#') { +! i = 2; +! } else { +! val=bb_strtoi((char *)s,&e,10); +! if (s == (uint8_t *)e) goto ppmopen_end; // no number - error +! s=(uint8_t *)e; +! i=0; // skip whitespaces +! switch (++k) { +! case 1: p->sizx = val; break; +! case 2: p->sizy = val; break; +! case 3: +! if (val > 255) +! goto ppmopen_end; // only 1 byte per color +! s++; +! p->bufhead = s - &(p->buf[0]); +! p->buftail = l; +! break; +! } +! } +! break; +! case 2: // skip to eol +! if (*s == 10) i=0; +! s++; +! break; +! } +! } +! if (p->sizx < 1 || p->sizy < 1) goto ppmopen_end; +! if (p->sizx > 200) { +! // buf is only 600 bytes = 200 pix prealocated - need more. +! p = xrealloc(p,sizeof(struct ppmfile) + 3 * p->sizx); + } ++ return p; + +! ppmopen_end: +! close(p->fd); +! free(p); +! return NULL; +! } +! +! /** +! * Read pixelline from ppm to internal buffer and return pointer +! */ +! static uint8_t *ppm_readline(struct ppmfile *p) { +! int i; +! if (p==NULL) return NULL; +! if (p->bufhead < p->buftail) { +! // pack buffer +! for (i = 0; p->bufhead < p->buftail; i++) { +! p->buf[i]=p->buf[p->bufhead++]; +! } +! p->buftail = i; +! } else { +! p->buftail = 0; +! } +! while (p->buftail < (p->sizx * 3)) { +! i=read(p->fd, &(p->buf[p->buftail]), (p->sizx * 3) - p->buftail); +! if (i < 0) return NULL; +! p->buftail += i; +! } +! p->bufhead = p->sizx * 3; +! return &(p->buf[0]); +! } +! +! /** +! * Close ppmfile +! */ +! +! static void ppm_close(struct ppmfile *p) { +! if (p == NULL) return; +! close(p->fd); +! free(p); +! } +! +! /** +! * Draws a PPM image. +! */ +! static void fb_drawimage(void) +! { +! struct ppmfile *ppm; +! unsigned char *pixel; +! unsigned char *rgbline,*rgbpix,*sprpix; +! RGB thispix; +! unsigned i, j, width, height; +! +! ppm = ppm_open(G.image_filename); +! if (ppm == NULL) +! bb_error_msg_and_die("PPM file %s cannot be opened",G.image_filename); +! width = ppm->sizx; +! height = ppm->sizy; +! if (width > G.scr_var.xres || height > G.scr_var.yres) + bb_error_msg_and_die("PPM %dx%d does not match screen %dx%d", +! width, height, G.scr_var.xres, G.scr_var.yres); + if (width > G.scr_var.xres) + width = G.scr_var.xres; + if (height > G.scr_var.yres) + height = G.scr_var.yres; + +! G.x0 = (width == G.scr_var.xres ? 0 : (G.scr_var.xres - width) / 2); +! G.y0 = (height == G.scr_var.yres ? 0 : (G.scr_var.yres - height) / 2); +! rgbline = xmalloc((width * G.bytes_per_pixel) + sizeof(RGB)); + +! for (j = 0; j < height; j++) { +! pixel = ppm_readline(ppm); +! rgbpix = rgbline; +! if (pixel == NULL) +! bb_error_msg_and_die("bad PPM file '%s' line %d", G.image_filename,j); +! if (G.spb2 != NULL && j >= G.nbar_posy && j < (G.nbar_posy + G.spb2->h)) { +! sprpix = &(G.spb2->pixbuf[(j - G.nbar_posy) * G.spb2->bw]); +! } else { +! sprpix = NULL; +! } + for (i = 0; i < width; i++) { +! thispix = makecol(pixel[0],pixel[1],pixel[2]); +! *((RGB*)rgbpix) = thispix; +! if ((sprpix != NULL) && (i >= G.nbar_posx)) { +! if (G.nbar_colr >= 256) { // Multiple not add +! thispix = makecol((G.nbar_colr & 255) * pixel[0], (G.nbar_colg & 255) * pixel[1], (G.nbar_colb & 255) * pixel[2]); +! } else { +! thispix = makecol(G.nbar_colr + pixel[0], G.nbar_colg + pixel[1], G.nbar_colb + pixel[2]); +! } +! memcpy(sprpix,&thispix,G.bytes_per_pixel); +! if (i >= (G.nbar_posx + G.spb2->w - 1)) { +! sprpix = NULL; +! } else { +! sprpix += G.bytes_per_pixel; +! } +! } + pixel += 3; ++ rgbpix += G.bytes_per_pixel; ++ } ++ fb_putpixrow(G.x0,j + G.y0,width,rgbline); ++ } ++ free(rgbline); ++ ppm_close(ppm); ++ // recalc cfg if centered image ++ G.nbar_posx += G.x0; ++ G.nbar_posy += G.y0; ++ #if ENABLE_FEATURE_FBSPLASH_TEXT ++ G.text_posx += G.x0; ++ G.text_posy += G.y0; ++ #endif ++ } ++ ++ #if ENABLE_FEATURE_FBSPLASH_SPRITES ++ /** ++ * Read rectangle sprites from ppm file ++ * \return pointer to array of sprites ++ * \return number of sprites loaded ++ */ ++ static struct sprite *fb_loadsprites(char *filename, int sx, int sy) { ++ struct ppmfile *ppm; ++ uint8_t *pixel, *rgbpix; ++ struct sprite *s=NULL; ++ int y,i; ++ RGB thispix; ++ ++ if ((ppm = ppm_open(filename)) == NULL) goto readsprites_out; ++ s = fb_newsprite(ppm->sizx + ppm->sizy, ppm->sizy, -1, -1); ++ fb_sprite(sx + G.x0, sy + G.y0, 0, s->h, s, 1); // load square 0 - background ++ rgbpix = &(s->pixbuf[0]); ++ for (y = 0; y < ppm->sizy; y++) { ++ // skip square 0 ++ rgbpix += s->h * G.bytes_per_pixel; ++ // read from file ++ pixel = ppm_readline(ppm); ++ for (i = 0; (pixel != NULL) && (i < ppm->sizx); i++) { ++ if (pixel[0]==0xFF && pixel[1]==0 && pixel[2]==0xFF) { ++ // transparent color => get pixel from square 0 ++ memcpy(&thispix, ++ &(s->pixbuf[y * s->bw + (i % s->h) * G.bytes_per_pixel]), ++ G.bytes_per_pixel); ++ } else { ++ thispix = makecol(pixel[0],pixel[1],pixel[2]); ++ } ++ memcpy(rgbpix,&thispix,G.bytes_per_pixel); ++ pixel += 3; ++ rgbpix += G.bytes_per_pixel; ++ } ++ } ++ ppm_close(ppm); ++ return s; ++ readsprites_out: ++ if (s != NULL) free(s); ++ return NULL; ++ } ++ ++ #define fb_putanim(x,y,n,s) fb_sprite(x + G.x0,y + G.y0,s->h * n,s->h,s,0) ++ #endif ++ ++ #if ENABLE_FEATURE_FBSPLASH_TEXT ++ ++ /* ++ * A function to put the pixel ++ */ ++ static void fb_putpixel(int x, int y, RGB rgb) { ++ uint8_t *a; ++ if (x < 0 || y < 0 || x > G.scr_var.xres || y > G.scr_var.yres) return; ++ a=G.addr + G.scr_fix.line_length * y + G.bytes_per_pixel * x; ++ memcpy(a,&rgb,G.bytes_per_pixel); ++ /* ++ switch (G.scr_var.bits_per_pixel) { ++ case 8: ++ *a = rgb & 0xFF; ++ break; ++ case 15: ++ case 16: ++ *((uint16_t *)a) = rgb & 0xFFFF; ++ break; ++ case 24: ++ a[0] = rgb & 0xFF; ++ a[1] = (rgb >> 8) & 0xFF; ++ a[2] = (rgb >> 16) & 0xFF; ++ break; ++ case 32: ++ *((uint32_t *)a) = rgb; ++ break; ++ } ++ */ ++ return; ++ } ++ ++ /** ++ * UTF-8 - get one charcter and advance to next ++ * ??? this function may be in libbb ??? ++ * \return UCS4 value ++ */ ++ static uint32_t ucs4value(uint8_t **s) { ++ uint8_t *c; ++ uint32_t ucs,w; ++ int count; ++ ++ if (s==NULL || *s==NULL || **s==0) return 0; ++ c = *s; ++ ucs = *c++; ++ if (ucs >= 0xC0) { /* 0x80..0xBF is error in utf8 but i use as-is */ ++ for (w = ucs & 0x7F, count = 0;(w & 0x40) == 0x40; count++) { ++ w <<= 1; ++ } ++ ucs=ucs & (0x7E >> count); ++ for(; count > 0; count--) { ++ if ((*c & 0xC0) != 0x80) { /* error in utf8 */ ++ ucs=0; ++ break; ++ } ++ ucs = (ucs << 6) + (*c++ & 0x3F); ++ } ++ } ++ *s=c; ++ return ucs; ++ } ++ ++ /** ++ * Find in GF.ud.entries desired UTF-8 char and advance to next char ++ * can combine glyphs in own memory ++ * \param s pointer to utf8 char pointer ++ * \return pinter to glyph ++ */ ++ static uint8_t *getglyph(uint8_t **s) { ++ uint32_t ucs; ++ uint8_t *c,*g; ++ int utflen,i; ++ ++ if (s == NULL || *s == NULL || **s == 0) ++ return G.unknown_glyph; /* end of string - no advance */ ++ c = *s; ++ ucs = ucs4value(&c); ++ utflen = c - *s; ++ g = G.unknown_glyph; ++ if (GF.ud.entries == NULL) { ++ if (ucs < GF.glyphcount) { ++ g = GF.glyphs + GF.charsize * ucs; ++ } ++ } else if (ucs <= 0xFFFF) { // only ucs2 ++ #if ENABLE_FEATURE_FBSPLASH_PSFSEQS ++ int j,compose; ++ memset(G.combglyph,0,sizeof(G.combglyph)); ++ for (i = 0, compose=0; i < GF.ud.entry_ct; i++) { ++ if (GF.ud.entries[i].unicode == ucs) { ++ g=GF.glyphs + ++ GF.ud.entries[i].fontpos * GF.charsize; ++ for (j = 0; j < GF.charsize; j++) { ++ G.combglyph[j] |= g[j]; ++ } ++ compose++; ++ } ++ } ++ if (compose > 1) { // found more than one ++ g = &(G.combglyph[0]); ++ } ++ #else ++ // no sequences - first found win ++ for (i = 0; i < GF.ud.entry_ct ; i++) { ++ if (GF.ud.entries[i].unicode == ucs) { ++ g = GF.glyphs + GF.ud.entries[i].fontpos * GF.charsize; ++ break; ++ } ++ } ++ #endif ++ } ++ *s=c; ++ return g; ++ } ++ ++ /** ++ * Draws a single character on framebuffer. ++ * \param nXPos horizontal position from which draw the character. ++ * \param nYPos vertical position from which draw the character. ++ * \param nCharSize character scale factor [1..4]. ++ * \param pointer to *nChar character to draw - auto advance by utf8. ++ * \param RGB color ++ */ ++ static void fb_drawchar(int nXPos, int nYPos, int nCharSize, ++ uint8_t **nChar, RGB thispix) ++ { ++ int x,y,px; ++ uint8_t *glyph; ++ ++ if (G.font==NULL || GF.height==0 || GF.glyphs==NULL) return; ++ if (G.unknown_glyph == NULL) { ++ uint8_t *unknown; ++ const uint8_t unconst[]="?"; ++ unknown=(uint8_t *)unconst; ++ G.unknown_glyph = getglyph(&unknown); ++ } ++ ++ glyph=getglyph(nChar); ++ if (glyph==NULL) return; ++ glyph-=GF.rowbytes; ++ for (y = 0; y < (GF.height * nCharSize); y++) { ++ if ((y % nCharSize) == 0) glyph+=GF.rowbytes; ++ for (x = 0,px = -1; x < (GF.width * nCharSize); x++) { ++ if ((x % nCharSize) == 0) px++; ++ if ((glyph[px / 8] & (0x80 >> (px % 8))) != 0) { ++ fb_putpixel(nXPos + x, nYPos + y,thispix); ++ } ++ } ++ } ++ } ++ ++ ++ /** ++ * Draws a string on framebuffer. ++ * \param *strString pointer to the string. ++ */ ++ static void fb_drawstring(char *strString) ++ { ++ RGB thispix; ++ int nCharSize; ++ int x; ++ uint8_t *c; ++ ++ // size check ++ nCharSize = G.text_size; ++ if (nCharSize < 1) ++ nCharSize = 1; ++ else if (nCharSize > 4) ++ nCharSize = 4; ++ ++ if (G.font==NULL || GF.height==0 || GF.glyphs==NULL) return; ++ ++ // redraws the portion of image interested to the old write operation ++ fb_putsprite(G.text_posx, G.text_posy, G.spt); ++ ++ // new write operation ++ thispix=makecol(G.text_colr,G.text_colg,G.text_colb); ++ for (x = G.text_posx, c = (uint8_t *)strString; *c != 0;) { ++ #if ENABLE_FEATURE_FBSPLASH_TEXT_COLORS ++ if (*c==0x1b && c[1]=='[') { ++ long newcol=0,first; ++ char *e; ++ e=(char *)&(c[1]); ++ do { ++ first=newcol; ++ ++e; ++ newcol = strtol(e,&e,10); ++ } while (*e == ';'); ++ if (*e == 'm' && ((newcol == 0) || (newcol >= 30 && newcol <= 37))) { ++ if (newcol >= 30 && newcol <= 37) { ++ if (newcol == 0 && first == 1) { ++ thispix=makecol(0x33,0x33,0x33); ++ } else { ++ newcol -= 30; ++ first = (first == 1 ? 0xFF : 0xCC); ++ thispix=makecol((newcol & 1) ? first : 0, ++ (newcol & 2) ? first : 0, ++ (newcol & 4) ? first : 0); ++ } ++ } else { ++ thispix=makecol(G.text_colr,G.text_colg,G.text_colb); ++ } ++ c=(uint8_t *)(++e); ++ continue; ++ } ++ } ++ #endif ++ fb_drawchar(x, G.text_posy, nCharSize, &c, thispix); ++ x += GF.width * nCharSize; ++ if (x >= G.scr_var.xres) break; // too long string ++ } ++ } ++ ++ /** ++ * Free readed font structure with all allocated memory ++ */ ++ static void fb_freefont(void) { ++ if (G.font != NULL) { ++ if (GF.mem1 != NULL) free(GF.mem1); ++ if (GF.ud.entries != NULL) free(GF.ud.entries); ++ free(G.font); ++ G.font=NULL; ++ } ++ } ++ ++ /** ++ * Read font and mapping from console using ioctl GIO_FONT and GIO_UNIMAP ++ */ ++ static void fb_readvgafont(void) { ++ int fd,i; ++ #if (defined(KDFONTOP) && defined(KD_FONT_OP_GET)) || defined(GIO_FONTX) ++ #if defined(KDFONTOP) && defined(KD_FONT_OP_GET) ++ struct console_font_op fo; ++ fd = open(CURRENT_TTY,O_NONBLOCK); ++ // if (fd == -1) fd = open("/dev/tty0",O_NOCTTY); ++ // if (fd == -1) fd = open("/dev/tty1",O_NOCTTY); ++ if (fd == -1) return; ++ ++ fo.data = NULL; ++ fo.charcount = 0; ++ fo.height = 32; fo.width = 32; // max usable font size ++ fo.flags = 0; ++ fo.op = KD_FONT_OP_GET; ++ if (ioctl(fd, KDFONTOP, &fo) == 0) { ++ i = (fo.width + 7) / 8; ++ fo.data = xmalloc(fo.charcount * 32 * i); ++ if (ioctl(fd, KDFONTOP, &fo) == -1) { ++ free(fo.data); ++ goto fb_vgafontout; ++ } ++ } ++ if (G.font != NULL) fb_freefont(); ++ G.font = (struct fbfont *) xzalloc(sizeof(struct fbfont)); ++ GF.height = fo.height; ++ GF.glyphcount = fo.charcount; ++ GF.width = fo.width; ++ GF.rowbytes = (fo.width + 7) / 8; ++ GF.charsize = GF.height * GF.rowbytes; ++ GF.mem1 = (uint8_t *) xmalloc(GF.height * GF.glyphcount * GF.rowbytes); ++ GF.glyphs = GF.mem1; ++ for (i = 0; i < GF.glyphcount; i++) { ++ memcpy(&(GF.glyphs[i * GF.height * GF.rowbytes]), ++ &(fo.data[i * 32 * GF.rowbytes]), ++ GF.height * GF.rowbytes); ++ } ++ if (fo.data) free(fo.data); ++ #else // KDFONTOP / GIO_FONTX ++ struct consolefontdesc cfd; ++ int j; ++ fd = open(CURRENT_TTY,O_NONBLOCK); ++ // if (fd == -1) fd = open("/dev/tty0",O_NOCTTY); ++ // if (fd == -1) fd = open("/dev/tty1",O_NOCTTY); ++ if (fd == -1) return; ++ ++ cfd.chardata = NULL; ++ cfd.charcount = 0; ++ cfd.charheight = 0; ++ if (ioctl(fd, GIO_FONTX, &cfd) == 0) { ++ cfd.chardata = xmalloc(cfd.charcount * 32); ++ if (ioctl(fd, GIO_FONTX, &cfd) == -1) { ++ free(cfd.chardata); ++ goto fb_vgafontout; ++ } ++ } else { ++ cfd.charcount=256; ++ cfd.chardata = xmalloc(256 * 32); ++ if (ioctl(fd, GIO_FONT, cfd.chardata) != 0) { ++ free(cfd.chardata); ++ goto fb_vgafontout; ++ } ++ // compute real height ++ cfd.charheight=0; ++ for (j = 31; (j > 0) && (cfd.charheight == 0); j--) { ++ for (i = 0; (i < 256) && (cfd.charheight == 0); i++) { ++ if (cfd.chardata[i*32+j] != 0) ++ cfd.charheight=j; ++ } ++ } ++ } ++ if (cfd.charheight != 0) { ++ if (G.font != NULL) fb_freefont(); ++ G.font = (struct fbfont *) xzalloc(sizeof(struct fbfont)); ++ GF.charsize = cfd.charheight; ++ GF.height = GF.charsize; ++ GF.glyphcount = cfd.charcount; ++ GF.width = 8; ++ GF.rowbytes = 1; ++ GF.mem1 = (uint8_t *) xmalloc(GF.height * GF.glyphcount); ++ GF.glyphs = GF.mem1; ++ // pack font ++ for (i = 0; i < GF.glyphcount; i++) { ++ memcpy(&(GF.glyphs[i * GF.height]), ++ &(cfd.chardata[i * 32]), ++ GF.height); + } + } +! free(cfd.chardata); +! #endif // FONTOP / FONTX +! #if defined(GIO_UNIMAP) +! GF.ud.entry_ct = 0; +! ioctl(fd, GIO_UNIMAP, &(GF.ud)); +! if (errno != ENOMEM) { +! goto fb_vgafontout; +! } +! if (GF.ud.entry_ct > 0) { +! GF.ud.entries = xmalloc(GF.ud.entry_ct * sizeof(struct unipair)); +! if (ioctl(fd, GIO_UNIMAP, &(GF.ud)) == -1) { +! // error no unimap +! free(GF.ud.entries); +! GF.ud.entry_ct = 0; +! } +! } +! #endif // GIO_UNIMAP +! fb_vgafontout: +! close(fd); +! #endif // GIO_FONTX or KDFONTOP available +! return; +! } +! +! #if ENABLE_FEATURE_FBSPLASH_FONTLOAD +! +! static uint16_t nextuni(int ver, uint8_t *map, int *pos) { +! uint16_t rv; +! int i; +! i=*pos; +! if (ver==1) { +! rv = map[i + 1]; +! rv = (rv << 8) + map[i]; +! i += 2; +! } else { // ver 2 +! if (map[i] == 0xFF) rv = 0xFFFF; +! else if (map[i] == 0xFE) rv = 0xFFFE; +! else if (map[i] < 0xC0) rv = map[i]; +! else if (map[i] < 0xE0) { +! rv = map[i] & 0x1F; +! if ((map[i + 1] & 0xC0) == 0x80) +! rv = (rv << 6) + (map[++i] & 0x3F); +! } else if (map[i] < 0xF0) { +! rv = map[i] & 0x0F; +! if ((map[i + 1] & 0xC0) == 0x80) +! rv = (rv << 6) + (map[++i] & 0x3F); +! if ((map[i + 1] & 0xC0) == 0x80) +! rv = (rv << 6) + (map[++i] & 0x3F); +! } else rv = map[i]; +! i++; +! } +! *pos=i; +! return rv; + } + ++ /** ++ * Convert unimap from psf v1 and psf v2 to unimapdesc ++ */ ++ static void convertmap(int ver, uint8_t *map, int mapsize, struct unimapdesc *ud) { ++ int i,j,k,glyph,glycodes; ++ #if ENABLE_FEATURE_FBSPLASH_PSFSEQS ++ int l, seqlen=0, *seq=NULL; ++ #endif ++ uint16_t e; ++ ud->entry_ct=0; ++ for (i = 0, glycodes=0; i < mapsize; ) { ++ e = nextuni(ver, map, &i); ++ if (e == PSF1_STARTSEQ) { ++ #if ENABLE_FEATURE_FBSPLASH_PSFSEQS ++ seqlen++; ++ #endif ++ e = nextuni(ver, map, &i); ++ while ((e != PSF1_SEPARATOR) && (i < mapsize)) { ++ #if ENABLE_FEATURE_FBSPLASH_PSFSEQS ++ ud->entry_ct += glycodes; ++ #endif ++ e = nextuni(ver, map, &i); ++ } ++ glycodes=0; ++ } else if (e == PSF1_SEPARATOR) { ++ ud->entry_ct += glycodes; ++ glycodes=0; ++ } else { ++ glycodes++; ++ } ++ } ++ ud->entries = (struct unipair *) ++ xmalloc(sizeof(struct unimapdesc) * ud->entry_ct); ++ #if ENABLE_FEATURE_FBSPLASH_PSFSEQS ++ if (seqlen > 0) { ++ seq = xzalloc(sizeof(int) * (seqlen + 1)); ++ } ++ #endif ++ for (i = 0, glyph = 0, j = 0, k = 0; i < mapsize; ) { ++ e = nextuni(ver, map, &i); ++ if (e == PSF1_STARTSEQ) { ++ e = nextuni(ver, map, &i); ++ k++; // this is seqence - position saved ++ // remove sequence - this is not glyph ++ while (ud->entries[j-1].fontpos == glyph && j > 0) { ++ j--; ++ } ++ // skip chars in seq ++ while ((e != PSF1_SEPARATOR) && (i < mapsize)) { ++ e = nextuni(ver, map, &i); ++ } ++ #if ENABLE_FEATURE_FBSPLASH_PSFSEQS ++ if (k < seqlen) seq[k] = i; ++ #endif ++ } else if (e == PSF1_SEPARATOR) { ++ glyph++; ++ #if ENABLE_FEATURE_FBSPLASH_PSFSEQS ++ // next may be sequence ++ if (k < seqlen) seq[k] = i; ++ #endif ++ } else if (j < ud->entry_ct) { ++ ud->entries[j].unicode=e; ++ ud->entries[j++].fontpos=glyph; ++ } ++ } ++ #if ENABLE_FEATURE_FBSPLASH_PSFSEQS ++ i = 0; ++ while (i < seqlen) { ++ k = seq[i]; ++ do { ++ e = nextuni(ver, map, &k); ++ } while (e != PSF1_STARTSEQ && e != PSF1_SEPARATOR && k < mapsize); ++ if (e == PSF1_STARTSEQ) { ++ e = nextuni(ver, map, &k); ++ while ((e != PSF1_SEPARATOR) && (k < mapsize)) { ++ // find glyph in table ++ glyph = 0; ++ while ((glyph < j) && (ud->entries[glyph].unicode != e)) { ++ glyph++; ++ } ++ // write glyph to table for all chars ++ if (glyph < j) { // found ++ l = seq[i]; // code pointer ++ e = nextuni(ver, map, &l); ++ while(e != PSF1_STARTSEQ && l < mapsize) { ++ ud->entries[j].unicode=e; ++ ud->entries[j++].fontpos=ud->entries[glyph].fontpos; ++ e = nextuni(ver, map, &l); ++ } ++ } ++ e = nextuni(ver, map, &k); ++ } ++ } ++ i++; ++ } ++ if (seqlen > 0) { ++ // remove unfound glyphs if any ++ ud->entry_ct = j; ++ free(seq); ++ } ++ #endif ++ } ++ ++ /** ++ * Read PSF v1 and PSF v2 fonts to own font structure ++ */ ++ static void fb_readpsf(const char *filename) { ++ unsigned int len; ++ int maplen; ++ uint8_t *buf; ++ struct psf1_header *psf1; ++ struct psf2_header *psf2; ++ ++ if (G.font != NULL) fb_freefont(); ++ len = 48*1024; // can't be larger ++ buf = xmalloc_open_zipped_read_close(filename, &len); ++ if (buf == NULL) { ++ bb_simple_perror_msg_and_die(filename); ++ } ++ if (len < 1024) { ++ goto badfmt; ++ } ++ G.font = (struct fbfont *) xzalloc(sizeof(struct fbfont)); ++ GF.mem1 = buf; ++ psf1 = (struct psf1_header *)buf; ++ psf2 = (struct psf2_header *)buf; ++ if ((psf1->magic == PSF1_MAGIC) && (psf1->mode <= PSF1_MAXMODE)) { ++ GF.glyphs = &(buf[sizeof(struct psf1_header)]); ++ GF.charsize = psf1->charsize; ++ GF.height = GF.charsize; ++ GF.glyphcount = ((psf1->mode & PSF1_MODE512) ? 512 : 256); ++ GF.width = 8; ++ maplen = len - sizeof(struct psf1_header) - ++ (GF.charsize * GF.glyphcount); ++ if ((maplen > 0) && ((psf1->mode & PSF1_MODEHASTAB) != 0)) { ++ convertmap(1,&(buf[len - maplen]),maplen,&(GF.ud)); ++ } else { ++ if (maplen < 0) goto badfmt; ++ } ++ } else if ((psf2->magic == PSF2_MAGIC) && ++ (psf2->version <= PSF2_MAXVERSION)) { ++ GF.glyphs=&(buf[psf2->headersize]); ++ GF.height = psf2->height; ++ GF.width = psf2->width; ++ GF.glyphcount = psf2->length; ++ GF.charsize = psf2->charsize; ++ maplen = len - psf2->headersize - ++ (GF.charsize * GF.glyphcount); ++ if ((maplen > 0) && ((psf2->flags & PSF2_HAS_UNICODE_TABLE) != 0)) { ++ convertmap(2,&(buf[len - maplen]),maplen,&(GF.ud)); ++ } else { ++ if (maplen < 0) goto badfmt; ++ } ++ } else { ++ goto badfmt; ++ } ++ GF.rowbytes = GF.charsize / GF.height; ++ ++ return; ++ badfmt: ++ if (G.font) fb_freefont(); ++ bb_error_msg_and_die("Cannot read file %s - unrecognized format\n",filename); ++ } ++ #endif // FONTLOAD ++ #endif // TEXT + + /** + * Parse configuration file +*************** +*** 298,303 **** +--- 1165,1173 ---- + "BAR_WIDTH\0" "BAR_HEIGHT\0" + "BAR_LEFT\0" "BAR_TOP\0" + "BAR_R\0" "BAR_G\0" "BAR_B\0" ++ #if ENABLE_FEATURE_FBSPLASH_TEXT ++ "TEXT_LEFT\0" "TEXT_TOP\0" "TEXT_R\0" "TEXT_G\0" "TEXT_B\0" "TEXT_SIZE\0" ++ #endif + #if DEBUG + "DEBUG\0" + #endif +*************** +*** 305,319 **** + char *token[2]; + parser_t *parser = config_open2(cfg_filename, xfopen_stdin); + while (config_read(parser, token, 2, 2, "#=", +! (PARSE_NORMAL | PARSE_MIN_DIE) & ~(PARSE_TRIM | PARSE_COLLAPSE))) { + unsigned val = xatoi_u(token[1]); + int i = index_in_strings(param_names, token[0]); + if (i < 0) + bb_error_msg_and_die("syntax error: %s", token[0]); +! if (i >= 0 && i < 7) + G.ns[i] = val; + #if DEBUG +! if (i == 7) { + G.bdebug_messages = val; + if (G.bdebug_messages) + G.logfile_fd = xfopen_for_write("/tmp/fbsplash.log"); +--- 1175,1189 ---- + char *token[2]; + parser_t *parser = config_open2(cfg_filename, xfopen_stdin); + while (config_read(parser, token, 2, 2, "#=", +! (PARSE_NORMAL | PARSE_MIN_DIE) & ~(PARSE_TRIM | PARSE_COLLAPSE))) { + unsigned val = xatoi_u(token[1]); + int i = index_in_strings(param_names, token[0]); + if (i < 0) + bb_error_msg_and_die("syntax error: %s", token[0]); +! if (i >= 0 && i < FBCFGVALS) + G.ns[i] = val; + #if DEBUG +! if (i == FBCFGVALS) { + G.bdebug_messages = val; + if (G.bdebug_messages) + G.logfile_fd = xfopen_for_write("/tmp/fbsplash.log"); +*************** +*** 327,337 **** + int fbsplash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; + int fbsplash_main(int argc UNUSED_PARAM, char **argv) + { + const char *fb_device, *cfg_filename, *fifo_filename; +! FILE *fp = fp; // for compiler +! char *num_buf; +! unsigned num; + bool bCursorOff; + + INIT_G(); + +--- 1197,1220 ---- + int fbsplash_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; + int fbsplash_main(int argc UNUSED_PARAM, char **argv) + { ++ #if ENABLE_FEATURE_FBSPLASH_FONTLOAD ++ const char *fontmap_filename = NULL; ++ #endif + const char *fb_device, *cfg_filename, *fifo_filename; +! char num_buf[512]; +! int num; + bool bCursorOff; ++ struct timeval tim; ++ fd_set rdfds; ++ FILE *fp=fp; ++ int bounce_x=0; ++ #if ENABLE_FEATURE_FBSPLASH_SPRITES ++ int anim_x,anim_y, /* position of sprite or animation */ ++ anim_n,anim_m, /* min sprite, max sprite for animation */ ++ anim_p=0, /* actual sprite */ ++ anim_t=0,anim_now=0; /* time between steps */ ++ struct sprite *spa=NULL; ++ #endif + + INIT_G(); + +*************** +*** 339,347 **** + fb_device = "/dev/fb0"; + cfg_filename = NULL; + fifo_filename = NULL; + bCursorOff = 1 & getopt32(argv, "cs:d:i:f:", + &G.image_filename, &fb_device, &cfg_filename, &fifo_filename); +! + // parse configuration file + if (cfg_filename) + init(cfg_filename); +--- 1222,1240 ---- + fb_device = "/dev/fb0"; + cfg_filename = NULL; + fifo_filename = NULL; ++ ++ #if ENABLE_FEATURE_FBSPLASH_FONTLOAD ++ bCursorOff = 1 & getopt32(argv, "cs:d:i:f:m:", ++ &G.image_filename, &fb_device, &cfg_filename, &fifo_filename, &fontmap_filename); ++ ++ if (fontmap_filename) fb_readpsf(fontmap_filename); ++ #else + bCursorOff = 1 & getopt32(argv, "cs:d:i:f:", + &G.image_filename, &fb_device, &cfg_filename, &fifo_filename); +! #endif +! #if ENABLE_FEATURE_FBSPLASH_TEXT +! if (G.font==NULL) fb_readvgafont(); +! #endif + // parse configuration file + if (cfg_filename) + init(cfg_filename); +*************** +*** 357,369 **** + full_write(STDOUT_FILENO, "\x1b" "[?25l", 6); + } + + fb_drawimage(); + + if (!fifo_filename) + return EXIT_SUCCESS; + + fp = xfopen_stdin(fifo_filename); +! if (fp != stdin) { + // For named pipes, we want to support this: + // mkfifo cmd_pipe + // fbsplash -f cmd_pipe .... & +--- 1250,1274 ---- + full_write(STDOUT_FILENO, "\x1b" "[?25l", 6); + } + ++ if (fifo_filename != NULL) { ++ G.spb2 = fb_newsprite(G.nbar_width, G.nbar_height, -1, -1); ++ } ++ + fb_drawimage(); + ++ G.spb1 = fb_newsprite(G.nbar_width, G.nbar_height, G.nbar_posx, G.nbar_posy); ++ #if ENABLE_FEATURE_FBSPLASH_TEXT ++ if (G.font != NULL) ++ G.spt = fb_newsprite(G.scr_var.xres - G.text_posx, ++ GF.height * G.text_size, ++ G.text_posx, G.text_posy); ++ #endif ++ + if (!fifo_filename) + return EXIT_SUCCESS; + + fp = xfopen_stdin(fifo_filename); +! if (fp != stdin) { + // For named pipes, we want to support this: + // mkfifo cmd_pipe + // fbsplash -f cmd_pipe .... & +*************** +*** 375,407 **** + // when last writer closes input end. + // The simplest way is to open fifo for writing too + // and become an additional writer :) +! open(fifo_filename, O_WRONLY); // errors are ignored +! } + +- fb_drawprogressbar(0); + // Block on read, waiting for some input. + // Use of style I/O allows to correctly + // handle a case when we have many buffered lines + // already in the pipe +! while ((num_buf = xmalloc_fgetline(fp)) != NULL) { +! if (strncmp(num_buf, "exit", 4) == 0) { +! DEBUG_MESSAGE("exit"); +! break; +! } +! num = atoi(num_buf); +! if (isdigit(num_buf[0]) && (num <= 100)) { + #if DEBUG +! char strVal[10]; +! sprintf(strVal, "%d", num); +! DEBUG_MESSAGE(strVal); + #endif +- fb_drawprogressbar(num); + } +- free(num_buf); + } +! + if (bCursorOff) // restore cursor + full_write(STDOUT_FILENO, "\x1b" "[?25h", 6); + + return EXIT_SUCCESS; + } +--- 1280,1416 ---- + // when last writer closes input end. + // The simplest way is to open fifo for writing too + // and become an additional writer :) +! open(fifo_filename, O_WRONLY | O_NDELAY); // errors are ignored +! } + + // Block on read, waiting for some input. + // Use of style I/O allows to correctly + // handle a case when we have many buffered lines + // already in the pipe +! // select and fgets work just in time only in nobuf mode +! setvbuf(fp, NULL, _IONBF, 0); +! tim.tv_sec = 0; +! tim.tv_usec = 100000; +! while (1) { +! FD_ZERO(&rdfds); +! FD_SET(fileno(fp),&rdfds); +! if ((num=select(fileno(fp) + 1,&rdfds,NULL,NULL,&tim))==-1) +! break; // select error +! if (num != 0 && fgets(num_buf,sizeof(num_buf) - 1,fp) != NULL) { +! num_buf[sizeof(num_buf) - 1]=0; +! num=strlen(num_buf) - 1; +! if (num >= 0 && num_buf[num]==10) num_buf[num]=0; +! if (strncmp(num_buf, "exit", 4) == 0) { +! DEBUG_MESSAGE("exit"); +! break; +! } else if (strncmp(num_buf, "bounce", 6) == 0) { +! bounce_x = 0; +! #if ENABLE_FEATURE_FBSPLASH_TEXT +! } else if (strncmp(num_buf, "write:", 6) == 0) { +! if (G.font!=NULL) fb_drawstring(num_buf + 6); +! DEBUG_MESSAGE(num_buf); +! #endif +! #if ENABLE_FEATURE_FBSPLASH_SPRITES +! } else if (strncmp(num_buf, "load:", 5) == 0) { +! if (spa) { +! fb_putanim(anim_x,anim_y,0,spa); // hide old +! free(spa); +! spa=NULL; +! } +! if (sscanf(&(num_buf[5]),"%d:%d:", +! &anim_x,&anim_y) == 2) { +! // skip x:y +! for (num=5;num_buf[num] != ':';) num++; +! for (num++;num_buf[num] != ':';) num++; +! spa=fb_loadsprites(&(num_buf[num + 1]),anim_x,anim_y); +! anim_t = anim_now = 0; // stop animation +! } +! } else if (strncmp(num_buf, "sprite:", 7) == 0) { +! if (spa != NULL) { +! // "sprite:n" +! anim_t = anim_now = 0; // stop animation +! anim_p = atoi(&(num_buf[7])); +! if (anim_p >= 0) { +! fb_putanim(anim_x,anim_y,anim_p,spa); +! } +! } +! } else if (strncmp(num_buf, "anime:", 6) == 0) { +! if (spa != NULL) { +! // "anime:n:m:t" +! if ((sscanf(&(num_buf[6]),"%d:%d:%d", +! &anim_n,&anim_m,&anim_t) == 3) && +! (anim_n >= 0) && (anim_m >= 0)) { +! anim_p = anim_n; // first frame +! fb_putanim(anim_x,anim_y,anim_p,spa); +! anim_now = anim_t; // next sprite after time t +! } else { +! anim_now = anim_t = 0; // stop animation +! } +! } +! #endif +! } else { +! num = atoi(num_buf); +! if ((isdigit(num_buf[0]) || (num_buf[0]=='-')) && +! (num >= -100 && num <= 100)) { + #if DEBUG +! char strVal[10]; +! sprintf(strVal, "%d", num); +! DEBUG_MESSAGE(strVal); +! #endif +! if (num < 0) { +! fb_drawnbar(-1 * num,100); +! } else { +! fb_drawnbar(0,num); +! } +! bounce_x = -1; // stop bounce +! } +! } +! } else { +! if (fp == stdin && feof(fp)) break; // stdin closed END +! } +! if (tim.tv_usec == 0) { // timeout - anime +! tim.tv_usec = 100000; +! if (bounce_x >= 0) { +! bounce_x += 5; +! if (bounce_x > 160) bounce_x = 0; +! if (bounce_x > 80) +! fb_drawnbar(160 - bounce_x,180 - bounce_x); +! else +! fb_drawnbar(bounce_x, bounce_x + 20); +! } +! #if ENABLE_FEATURE_FBSPLASH_SPRITES +! if (spa != NULL && anim_t != 0) { +! --anim_now; +! if (anim_now <= 0) { +! anim_now = anim_t; // wait +! if (anim_n < anim_m) { +! anim_p++; +! if (anim_p > anim_m) anim_p = anim_n; +! } else { +! anim_p--; +! if (anim_p < anim_m) anim_p = anim_n; +! } +! fb_putanim(anim_x,anim_y,anim_p,spa); +! } +! } + #endif + } + } +! if (G.spb1 != NULL) free(G.spb1); +! G.spb1 = NULL; +! if (G.spb2 != NULL) free(G.spb2); +! G.spb2 = NULL; +! #if ENABLE_FEATURE_FBSPLASH_TEXT +! if (G.font != NULL) fb_freefont(); +! if (G.spt != NULL) free(G.spt); +! G.spt = NULL; +! #endif +! #if ENABLE_FEATURE_FBSPLASH_SPRITES +! if (spa != NULL) free(spa); +! #endif + if (bCursorOff) // restore cursor + full_write(STDOUT_FILENO, "\x1b" "[?25h", 6); + + return EXIT_SUCCESS; + } ++ #endif +*** busybox-1.15.0/miscutils/fbsplash.cfg.orig 2009-08-21 00:26:14.000000000 +0200 +--- busybox-1.15.0/miscutils/fbsplash.cfg 2009-09-01 08:42:18.000000000 +0200 +*************** +*** 7,9 **** +--- 7,19 ---- + BAR_R=80 + BAR_G=80 + BAR_B=130 ++ # the below settings are active only if you enable the option FBSPLASH_TEXT_RENDERING ++ # text position ++ #TEXT_LEFT=100 ++ #TEXT_TOP=350 ++ ## text color ++ #TEXT_R=80 ++ #TEXT_G=80 ++ #TEXT_B=130 ++ ## text size (1 to 4) ++ #TEXT_SIZE=2 diff --git a/packages/sysutils/busybox-system/scripts/acpi_powerbtn b/packages/sysutils/busybox/scripts/acpi_powerbtn similarity index 100% rename from packages/sysutils/busybox-system/scripts/acpi_powerbtn rename to packages/sysutils/busybox/scripts/acpi_powerbtn diff --git a/packages/sysutils/busybox-system/scripts/init b/packages/sysutils/busybox/scripts/init similarity index 100% rename from packages/sysutils/busybox-system/scripts/init rename to packages/sysutils/busybox/scripts/init diff --git a/packages/sysutils/busybox-system/scripts/udhcp.script b/packages/sysutils/busybox/scripts/udhcp.script similarity index 100% rename from packages/sysutils/busybox-system/scripts/udhcp.script rename to packages/sysutils/busybox/scripts/udhcp.script