aboutsummaryrefslogtreecommitdiffstats
path: root/package/utils
diff options
context:
space:
mode:
Diffstat (limited to 'package/utils')
-rw-r--r--package/utils/admswconfig/Makefile52
-rw-r--r--package/utils/admswconfig/files/admswconfig68
-rw-r--r--package/utils/admswconfig/files/admswswitch.sh28
-rw-r--r--package/utils/admswconfig/patches/001-matrix.patch15
-rw-r--r--package/utils/admswconfig/patches/002-fix-musl.patch11
-rw-r--r--package/utils/busybox/Config-defaults.in2721
-rw-r--r--package/utils/busybox/Config.in26
-rw-r--r--package/utils/busybox/Makefile118
-rw-r--r--package/utils/busybox/config/Config.in843
-rw-r--r--package/utils/busybox/config/archival/Config.in372
-rw-r--r--package/utils/busybox/config/console-tools/Config.in176
-rw-r--r--package/utils/busybox/config/coreutils/Config.in954
-rw-r--r--package/utils/busybox/config/debianutils/Config.in85
-rw-r--r--package/utils/busybox/config/e2fsprogs/Config.in71
-rw-r--r--package/utils/busybox/config/e2fsprogs/old_e2fsprogs/Config.in69
-rw-r--r--package/utils/busybox/config/editors/Config.in234
-rw-r--r--package/utils/busybox/config/findutils/Config.in269
-rw-r--r--package/utils/busybox/config/init/Config.in184
-rw-r--r--package/utils/busybox/config/libbb/Config.in249
-rw-r--r--package/utils/busybox/config/loginutils/Config.in342
-rw-r--r--package/utils/busybox/config/mailutils/Config.in55
-rw-r--r--package/utils/busybox/config/miscutils/Config.in760
-rw-r--r--package/utils/busybox/config/modutils/Config.in269
-rw-r--r--package/utils/busybox/config/networking/Config.in1105
-rw-r--r--package/utils/busybox/config/networking/udhcp/Config.in171
-rw-r--r--package/utils/busybox/config/printutils/Config.in28
-rw-r--r--package/utils/busybox/config/procps/Config.in273
-rw-r--r--package/utils/busybox/config/runit/Config.in89
-rw-r--r--package/utils/busybox/config/selinux/Config.in124
-rw-r--r--package/utils/busybox/config/shell/Config.in444
-rw-r--r--package/utils/busybox/config/sysklogd/Config.in169
-rw-r--r--package/utils/busybox/config/util-linux/Config.in792
-rw-r--r--package/utils/busybox/config/util-linux/volume_id/Config.in304
-rwxr-xr-xpackage/utils/busybox/convert_defaults.pl13
-rwxr-xr-xpackage/utils/busybox/convert_menuconfig.pl75
-rwxr-xr-xpackage/utils/busybox/files/cron38
-rwxr-xr-xpackage/utils/busybox/files/ntpd-hotplug3
-rwxr-xr-xpackage/utils/busybox/files/sysntpd42
-rw-r--r--package/utils/busybox/patches/001-resource_h_include.patch10
-rw-r--r--package/utils/busybox/patches/100-trylink_bash.patch8
-rw-r--r--package/utils/busybox/patches/101-gen_build_files_bash.patch8
-rw-r--r--package/utils/busybox/patches/102-trylink_mktemp_fix.patch20
-rw-r--r--package/utils/busybox/patches/110-no_static_libgcc.patch11
-rw-r--r--package/utils/busybox/patches/120-remove_uclibc_rpc_check.patch12
-rw-r--r--package/utils/busybox/patches/130-mconf_missing_sigwinch.patch13
-rw-r--r--package/utils/busybox/patches/200-udhcpc_reduce_msgs.patch18
-rw-r--r--package/utils/busybox/patches/201-udhcpc_changed_ifindex.patch15
-rw-r--r--package/utils/busybox/patches/203-udhcpc_renew_no_deconfig.patch10
-rw-r--r--package/utils/busybox/patches/204-udhcpc_src_ip_rebind.patch51
-rw-r--r--package/utils/busybox/patches/210-add_netmsg_util.patch103
-rw-r--r--package/utils/busybox/patches/220-add_lock_util.patch182
-rw-r--r--package/utils/busybox/patches/230-ntpd_delayed_resolve.patch48
-rw-r--r--package/utils/busybox/patches/240-telnetd_intr.patch10
-rw-r--r--package/utils/busybox/patches/250-date-k-flag.patch87
-rw-r--r--package/utils/busybox/patches/260-arping_missing_includes.patch11
-rw-r--r--package/utils/busybox/patches/270-libbb_make_unicode_printable.patch20
-rw-r--r--package/utils/busybox/patches/301-ip-link-fix-netlink-msg-size.patch11
-rw-r--r--package/utils/bzip2/Makefile109
-rw-r--r--package/utils/e2fsprogs/Makefile230
-rw-r--r--package/utils/e2fsprogs/files/e2fsck.conf3
-rw-r--r--package/utils/e2fsprogs/files/e2fsck.sh38
-rw-r--r--package/utils/e2fsprogs/patches/001-com_err_version.patch13
-rw-r--r--package/utils/fbtest/Makefile44
-rw-r--r--package/utils/fbtest/src/Makefile14
-rw-r--r--package/utils/fbtest/src/fbtest.c446
-rw-r--r--package/utils/fuse/Makefile101
-rw-r--r--package/utils/fuse/patches/001-fix_exec_environment_for_mount_and_umount.patch59
-rw-r--r--package/utils/fuse/patches/100-missing_includes.patch20
-rw-r--r--package/utils/fuse/patches/112-no_break_on_mknod.patch11
-rw-r--r--package/utils/fuse/patches/200-backport_arm64_fuse_kernel_h_clean_includes.patch30
-rw-r--r--package/utils/hostap-utils/Makefile44
-rw-r--r--package/utils/jsonfilter/Makefile33
-rw-r--r--package/utils/lua/Makefile183
-rw-r--r--package/utils/lua/patches-host/010-lua-5.1.3-lnum-full-260308.patch3736
-rw-r--r--package/utils/lua/patches-host/011-lnum-use-double.patch11
-rw-r--r--package/utils/lua/patches-host/015-lnum-ppc-compat.patch11
-rw-r--r--package/utils/lua/patches-host/030-archindependent-bytecode.patch111
-rw-r--r--package/utils/lua/patches-host/100-no_readline.patch49
-rw-r--r--package/utils/lua/patches/010-lua-5.1.3-lnum-full-260308.patch3736
-rw-r--r--package/utils/lua/patches/011-lnum-use-double.patch11
-rw-r--r--package/utils/lua/patches/015-lnum-ppc-compat.patch11
-rw-r--r--package/utils/lua/patches/020-shared_liblua.patch140
-rw-r--r--package/utils/lua/patches/030-archindependent-bytecode.patch111
-rw-r--r--package/utils/lua/patches/040-use-symbolic-functions.patch11
-rw-r--r--package/utils/lua/patches/050-honor-cflags.patch11
-rw-r--r--package/utils/lua/patches/100-no_readline.patch49
-rw-r--r--package/utils/lua/patches/200-lua-path.patch15
-rw-r--r--package/utils/lua/patches/300-opcode_performance.patch363
-rw-r--r--package/utils/mdadm/Makefile52
-rw-r--r--package/utils/mdadm/patches/000-compile.patch11
-rw-r--r--package/utils/mdadm/patches/100-cross_compile.patch19
-rw-r--r--package/utils/mdadm/patches/200-reduce_size.patch25
-rw-r--r--package/utils/mkelfimage/Makefile35
-rw-r--r--package/utils/mkelfimage/patches/no-stack-protector.patch11
-rw-r--r--package/utils/nvram/Makefile52
-rwxr-xr-xpackage/utils/nvram/files/nvram.init98
-rw-r--r--package/utils/nvram/src/Makefile7
-rw-r--r--package/utils/nvram/src/cli.c246
-rw-r--r--package/utils/nvram/src/crc.c69
-rw-r--r--package/utils/nvram/src/nvram.c540
-rw-r--r--package/utils/nvram/src/nvram.h123
-rw-r--r--package/utils/nvram/src/sdinitvals.h30
-rw-r--r--package/utils/otrx/Makefile43
-rw-r--r--package/utils/otrx/src/Makefile7
-rw-r--r--package/utils/otrx/src/otrx.c577
-rw-r--r--package/utils/px5g-standalone/Makefile41
-rw-r--r--package/utils/px5g-standalone/src/Makefile14
-rw-r--r--package/utils/px5g-standalone/src/library/base64.c264
-rw-r--r--package/utils/px5g-standalone/src/library/bignum.c2010
-rw-r--r--package/utils/px5g-standalone/src/library/rsa.c750
-rw-r--r--package/utils/px5g-standalone/src/library/sha1.c622
-rw-r--r--package/utils/px5g-standalone/src/library/timing.c265
-rw-r--r--package/utils/px5g-standalone/src/library/x509write.c1162
-rw-r--r--package/utils/px5g-standalone/src/polarssl/base64.h93
-rw-r--r--package/utils/px5g-standalone/src/polarssl/bignum.h437
-rw-r--r--package/utils/px5g-standalone/src/polarssl/bn_mul.h731
-rw-r--r--package/utils/px5g-standalone/src/polarssl/config.h329
-rw-r--r--package/utils/px5g-standalone/src/polarssl/rsa.h309
-rw-r--r--package/utils/px5g-standalone/src/polarssl/sha1.h150
-rw-r--r--package/utils/px5g-standalone/src/polarssl/timing.h81
-rw-r--r--package/utils/px5g-standalone/src/polarssl/x509.h549
-rw-r--r--package/utils/px5g-standalone/src/px5g.c213
-rw-r--r--package/utils/px5g/Makefile44
-rw-r--r--package/utils/px5g/px5g.c273
-rw-r--r--package/utils/spidev_test/Makefile43
-rw-r--r--package/utils/ubi-utils/Makefile61
-rw-r--r--package/utils/ubi-utils/patches/010-fix-rpmatch.patch19
-rw-r--r--package/utils/ubi-utils/patches/100-fix_includes.patch30
-rw-r--r--package/utils/ubi-utils/patches/110-gcc5-fix.patch41
-rw-r--r--package/utils/ubi-utils/patches/130-lzma_jffs2.patch5029
-rw-r--r--package/utils/ugps/Makefile50
-rw-r--r--package/utils/ugps/files/gps.config2
-rw-r--r--package/utils/ugps/files/ugps.init22
-rw-r--r--package/utils/usbmode/Makefile59
-rw-r--r--package/utils/usbmode/data/12d1:1f162
-rw-r--r--package/utils/usbmode/files/usbmode.hotplug1
-rwxr-xr-xpackage/utils/usbmode/files/usbmode.init12
-rw-r--r--package/utils/usbreset/Makefile44
-rw-r--r--package/utils/usbreset/src/usbreset.c235
-rw-r--r--package/utils/usbutils/Makefile57
-rw-r--r--package/utils/util-linux/Makefile644
-rw-r--r--package/utils/util-linux/patches/0001-switch_root-improve-statfs-f_type-portability.patch49
-rw-r--r--package/utils/util-linux/patches/0002-lib-colors-use-static-buffers-when-parse-scheme.patch126
-rw-r--r--package/utils/util-linux/patches/001-no-printf-alloc.patch104
-rw-r--r--package/utils/util-linux/patches/002-mkostemp.patch46
-rw-r--r--package/utils/util-linux/patches/003-fix_pkgconfig_files.patch62
-rw-r--r--package/utils/xfsprogs/Makefile90
-rw-r--r--package/utils/xfsprogs/patches/001-automake-compat.patch84
-rw-r--r--package/utils/xfsprogs/patches/100-no_aio.patch21
-rw-r--r--package/utils/xfsprogs/patches/110-uclibc_no_ustat.patch34
-rw-r--r--package/utils/xfsprogs/patches/120-portability.patch47
-rw-r--r--package/utils/xfsprogs/patches/130-uclibc_no_xattr.patch34
-rw-r--r--package/utils/xfsprogs/patches/140-no_po.patch20
-rw-r--r--package/utils/xfsprogs/patches/150-include_fixes.patch72
154 files changed, 39465 insertions, 0 deletions
diff --git a/package/utils/admswconfig/Makefile b/package/utils/admswconfig/Makefile
new file mode 100644
index 0000000..820f854
--- /dev/null
+++ b/package/utils/admswconfig/Makefile
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2007 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=admswconfig
+PKG_VERSION:=0.1
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://downloads.openwrt.org/sources
+PKG_MD5SUM:=faafd4618f970119a665b11b21ac6a26
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/admswconfig
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=ADM5120 Switch configuration tool
+ DEPENDS:=@TARGET_adm5120
+ URL:=http://sharon.esrac.ele.tue.nl/users/pe1rxq/linux-adm/admswconfig/
+ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+endef
+
+define Package/admswconfig/description
+ A program to configure the internal ethernet switch of an ADM5120 processor.
+ You need the corresponding driver for the switch in the kernel.
+ With this program you can configure which ports of the switch belong
+ to the different ethernet devices.
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(TARGET_CC) $(TARGET_CFLAGS) -Os $(PKG_BUILD_DIR)/admswconfig.c -o $(PKG_BUILD_DIR)/$(PKG_NAME)
+endef
+
+define Package/admswconfig/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/admswconfig $(1)/sbin/
+ $(INSTALL_DIR) $(1)/lib/network/
+ $(INSTALL_DATA) ./files/admswswitch.sh $(1)/lib/network/admswswitch.sh
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/admswconfig $(1)/etc/init.d/admswconfig
+endef
+
+$(eval $(call BuildPackage,admswconfig))
diff --git a/package/utils/admswconfig/files/admswconfig b/package/utils/admswconfig/files/admswconfig
new file mode 100644
index 0000000..7231030
--- /dev/null
+++ b/package/utils/admswconfig/files/admswconfig
@@ -0,0 +1,68 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006 OpenWrt.org
+
+START=05
+
+start() {
+ [ -e /etc/config/network ] && exit 0
+
+ mkdir -p /etc/config
+
+ board_name=$(awk 'BEGIN{FS="[ \t]+:[ \t]"} /system type/ {print $2}' /proc/cpuinfo)
+
+ case "$board_name" in
+ "Compex WP54"*)
+ board="Compex WP54";;
+ esac
+
+ echo "$board" |awk '
+ function p(cfgname, name) {
+ if (c[name] != "") print " option " cfgname " \"" c[name] "\""
+ }
+
+ BEGIN {
+ FS="="
+ c["lan_ifname"]="eth0"
+ c["wan_ifname"]="eth1"
+ c["eth0ports"]="1 2 3 4"
+ c["eth1ports"]="0"
+ }
+ END {
+ board=$1
+ if (board == "Compex WP54") {
+ c["eth0ports"]="0"
+ c["eth1ports"]="1"
+ }
+
+ print "#### VLAN configuration "
+ print "config switch"
+ p("eth0", "eth0ports")
+ p("eth1", "eth1ports")
+ print ""
+ print ""
+ print "#### Loopback configuration"
+ print "config interface loopback"
+ print " option ifname \"lo\""
+ print " option proto static"
+ print " option ipaddr 127.0.0.1"
+ print " option netmask 255.0.0.0"
+ print ""
+ print ""
+ print "#### LAN configuration"
+ print "config interface lan"
+ print " option type bridge"
+ p("ifname", "lan_ifname")
+ p("macaddr", "lan_macaddr")
+ print " option proto static"
+ print " option ipaddr 192.168.1.1"
+ print " option netmask 255.255.255.0"
+ print ""
+ print ""
+ print "#### WAN configuration"
+ print "config interface wan"
+ p("ifname", "wan_ifname")
+ p("macaddr", "wan_macaddr")
+ print " option proto dhcp"
+ }' > /etc/config/network
+}
+
diff --git a/package/utils/admswconfig/files/admswswitch.sh b/package/utils/admswconfig/files/admswswitch.sh
new file mode 100644
index 0000000..3b8aabf
--- /dev/null
+++ b/package/utils/admswconfig/files/admswswitch.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Copyright (C) 2006 OpenWrt.org
+
+setup_switch_vlan() {
+ config_get ports "$CONFIG_SECTION" "eth$1"
+ ports=`echo "$ports"| sed s/" "/""/g`
+ ip link set dev eth$1 down
+ admswconfig eth$1 ${ports}c
+ ip link set dev eth$1 up
+}
+
+setup_switch() {
+ config_cb() {
+ case "$1" in
+ switch)
+ option_cb() {
+ case "$1" in
+ eth*) setup_switch_vlan "${1##eth}";;
+ esac
+ }
+ ;;
+ *)
+ option_cb() { return 0; }
+ ;;
+ esac
+ }
+ config_load network
+}
diff --git a/package/utils/admswconfig/patches/001-matrix.patch b/package/utils/admswconfig/patches/001-matrix.patch
new file mode 100644
index 0000000..e50d515
--- /dev/null
+++ b/package/utils/admswconfig/patches/001-matrix.patch
@@ -0,0 +1,15 @@
+--- a/admswconfig.c
++++ b/admswconfig.c
+@@ -111,9 +111,9 @@ int main(int argc, char **argv)
+ }
+ } else {
+ /* display matrix */
+- printf("ethX\tport0\tport1\tport2\tport3\tport4");
+- if (info.ports == 6)
+- printf("\tport5");
++ printf("ethX");
++ for (i = 0; i < info.ports; i++)
++ printf("\tport%d", i);
+ printf("\tCPU\n");
+ for (i = 0; i < info.ports; i++) {
+ printf("%d", i);
diff --git a/package/utils/admswconfig/patches/002-fix-musl.patch b/package/utils/admswconfig/patches/002-fix-musl.patch
new file mode 100644
index 0000000..3dad1f9
--- /dev/null
+++ b/package/utils/admswconfig/patches/002-fix-musl.patch
@@ -0,0 +1,11 @@
+--- a/admswconfig.c
++++ b/admswconfig.c
+@@ -68,7 +68,7 @@ int main(int argc, char **argv)
+ return 1;
+ }
+ strcpy(ifr.ifr_name, device);
+- ifr.ifr_data = (caddr_t)&info;
++ ifr.ifr_data = (void *)&info;
+ if (ioctl(fd, SIOCGADMINFO, &ifr) < 0) {
+ perror("SIOCGADMINFO");
+ return 1;
diff --git a/package/utils/busybox/Config-defaults.in b/package/utils/busybox/Config-defaults.in
new file mode 100644
index 0000000..5b77f93
--- /dev/null
+++ b/package/utils/busybox/Config-defaults.in
@@ -0,0 +1,2721 @@
+config BUSYBOX_DEFAULT_HAVE_DOT_CONFIG
+ bool
+ default y
+config BUSYBOX_DEFAULT_DESKTOP
+ bool
+ default n
+config BUSYBOX_DEFAULT_EXTRA_COMPAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_INCLUDE_SUSv2
+ bool
+ default y
+config BUSYBOX_DEFAULT_USE_PORTABLE_CODE
+ bool
+ default n
+config BUSYBOX_DEFAULT_PLATFORM_LINUX
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_BUFFERS_USE_MALLOC
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_BUFFERS_GO_ON_STACK
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_BUFFERS_GO_IN_BSS
+ bool
+ default n
+config BUSYBOX_DEFAULT_SHOW_USAGE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VERBOSE_USAGE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_COMPRESS_USAGE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_INSTALLER
+ bool
+ default n
+config BUSYBOX_DEFAULT_INSTALL_NO_USR
+ bool
+ default n
+config BUSYBOX_DEFAULT_LOCALE_SUPPORT
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNICODE_SUPPORT
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNICODE_USING_LOCALE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHECK_UNICODE_IN_ENV
+ bool
+ default n
+config BUSYBOX_DEFAULT_SUBST_WCHAR
+ int
+ default 0
+config BUSYBOX_DEFAULT_LAST_SUPPORTED_WCHAR
+ int
+ default 0
+config BUSYBOX_DEFAULT_UNICODE_COMBINING_WCHARS
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNICODE_WIDE_WCHARS
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNICODE_BIDI_SUPPORT
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNICODE_NEUTRAL_TABLE
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNICODE_PRESERVE_BROKEN
+ bool
+ default n
+config BUSYBOX_DEFAULT_PAM
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_USE_SENDFILE
+ bool
+ default n
+config BUSYBOX_DEFAULT_LONG_OPTS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_DEVPTS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_CLEAN_UP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_UTMP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_WTMP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_PIDFILE
+ bool
+ default y
+config BUSYBOX_DEFAULT_PID_FILE_PATH
+ string
+ default "/var/run"
+config BUSYBOX_DEFAULT_FEATURE_SUID
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_SUID_CONFIG
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SUID_CONFIG_QUIET
+ bool
+ default n
+config BUSYBOX_DEFAULT_SELINUX
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_PREFER_APPLETS
+ bool
+ default y
+config BUSYBOX_DEFAULT_BUSYBOX_EXEC_PATH
+ string
+ default "/proc/self/exe"
+config BUSYBOX_DEFAULT_FEATURE_SYSLOG
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_HAVE_RPC
+ bool
+ default n
+config BUSYBOX_DEFAULT_STATIC
+ bool
+ default n
+config BUSYBOX_DEFAULT_PIE
+ bool
+ default n
+config BUSYBOX_DEFAULT_NOMMU
+ bool
+ default n
+config BUSYBOX_DEFAULT_BUILD_LIBBUSYBOX
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INDIVIDUAL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SHARED_BUSYBOX
+ bool
+ default n
+config BUSYBOX_DEFAULT_LFS
+ bool
+ default y
+config BUSYBOX_DEFAULT_CROSS_COMPILER_PREFIX
+ string
+ default ""
+config BUSYBOX_DEFAULT_SYSROOT
+ string
+ default ""
+config BUSYBOX_DEFAULT_EXTRA_CFLAGS
+ string
+ default ""
+config BUSYBOX_DEFAULT_EXTRA_LDFLAGS
+ string
+ default ""
+config BUSYBOX_DEFAULT_EXTRA_LDLIBS
+ string
+ default ""
+config BUSYBOX_DEFAULT_DEBUG
+ bool
+ default n
+config BUSYBOX_DEFAULT_DEBUG_PESSIMIZE
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNIT_TEST
+ bool
+ default n
+config BUSYBOX_DEFAULT_WERROR
+ bool
+ default n
+config BUSYBOX_DEFAULT_NO_DEBUG_LIB
+ bool
+ default y
+config BUSYBOX_DEFAULT_DMALLOC
+ bool
+ default n
+config BUSYBOX_DEFAULT_EFENCE
+ bool
+ default n
+config BUSYBOX_DEFAULT_INSTALL_APPLET_SYMLINKS
+ bool
+ default y
+config BUSYBOX_DEFAULT_INSTALL_APPLET_HARDLINKS
+ bool
+ default n
+config BUSYBOX_DEFAULT_INSTALL_APPLET_SCRIPT_WRAPPERS
+ bool
+ default n
+config BUSYBOX_DEFAULT_INSTALL_APPLET_DONT
+ bool
+ default n
+config BUSYBOX_DEFAULT_INSTALL_SH_APPLET_SYMLINK
+ bool
+ default n
+config BUSYBOX_DEFAULT_INSTALL_SH_APPLET_HARDLINK
+ bool
+ default n
+config BUSYBOX_DEFAULT_INSTALL_SH_APPLET_SCRIPT_WRAPPER
+ bool
+ default n
+config BUSYBOX_DEFAULT_PREFIX
+ string
+ default "./_install"
+config BUSYBOX_DEFAULT_FEATURE_SYSTEMD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_RTMINMAX
+ bool
+ default n
+config BUSYBOX_DEFAULT_PASSWORD_MINLEN
+ int
+ default 6
+config BUSYBOX_DEFAULT_MD5_SMALL
+ int
+ default 1
+config BUSYBOX_DEFAULT_SHA3_SMALL
+ int
+ default 1
+config BUSYBOX_DEFAULT_FEATURE_FAST_TOP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_ETC_NETWORKS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_USE_TERMIOS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_EDITING
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_EDITING_MAX_LEN
+ int
+ default 512
+config BUSYBOX_DEFAULT_FEATURE_EDITING_VI
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_EDITING_HISTORY
+ int
+ default 256
+config BUSYBOX_DEFAULT_FEATURE_EDITING_SAVEHISTORY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_EDITING_SAVE_ON_EXIT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_REVERSE_SEARCH
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TAB_COMPLETION
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_USERNAME_COMPLETION
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_EDITING_FANCY_PROMPT
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_EDITING_ASK_TERMINAL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_NON_POSIX_CP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VERBOSE_CP_MESSAGE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_COPYBUF_KB
+ int
+ default 4
+config BUSYBOX_DEFAULT_FEATURE_SKIP_ROOTFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_MONOTONIC_SYSCALL
+ bool
+ default n
+config BUSYBOX_DEFAULT_IOCTL_HEX2STR_ERROR
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_HWIB
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SEAMLESS_XZ
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SEAMLESS_LZMA
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SEAMLESS_BZ2
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SEAMLESS_GZ
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_SEAMLESS_Z
+ bool
+ default n
+config BUSYBOX_DEFAULT_AR
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_AR_LONG_FILENAMES
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_AR_CREATE
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNCOMPRESS
+ bool
+ default n
+config BUSYBOX_DEFAULT_GUNZIP
+ bool
+ default y
+config BUSYBOX_DEFAULT_BUNZIP2
+ bool
+ default y
+config BUSYBOX_DEFAULT_UNLZMA
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LZMA_FAST
+ bool
+ default n
+config BUSYBOX_DEFAULT_LZMA
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNXZ
+ bool
+ default n
+config BUSYBOX_DEFAULT_XZ
+ bool
+ default n
+config BUSYBOX_DEFAULT_BZIP2
+ bool
+ default n
+config BUSYBOX_DEFAULT_CPIO
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CPIO_O
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CPIO_P
+ bool
+ default n
+config BUSYBOX_DEFAULT_DPKG
+ bool
+ default n
+config BUSYBOX_DEFAULT_DPKG_DEB
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_DPKG_DEB_EXTRACT_ONLY
+ bool
+ default n
+config BUSYBOX_DEFAULT_GZIP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_GZIP_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_GZIP_FAST
+ int
+ default 0
+config BUSYBOX_DEFAULT_LZOP
+ bool
+ default n
+config BUSYBOX_DEFAULT_LZOP_COMPR_HIGH
+ bool
+ default n
+config BUSYBOX_DEFAULT_RPM
+ bool
+ default n
+config BUSYBOX_DEFAULT_RPM2CPIO
+ bool
+ default n
+config BUSYBOX_DEFAULT_TAR
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TAR_CREATE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TAR_AUTODETECT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TAR_FROM
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TAR_OLDGNU_COMPATIBILITY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TAR_OLDSUN_COMPATIBILITY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TAR_GNU_EXTENSIONS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TAR_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TAR_TO_COMMAND
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TAR_UNAME_GNAME
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TAR_NOPRESERVE_TIME
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TAR_SELINUX
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNZIP
+ bool
+ default n
+config BUSYBOX_DEFAULT_BASENAME
+ bool
+ default y
+config BUSYBOX_DEFAULT_CAT
+ bool
+ default y
+config BUSYBOX_DEFAULT_DATE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_DATE_ISOFMT
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_DATE_NANO
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_DATE_COMPAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_HOSTID
+ bool
+ default n
+config BUSYBOX_DEFAULT_ID
+ bool
+ default y
+config BUSYBOX_DEFAULT_GROUPS
+ bool
+ default n
+config BUSYBOX_DEFAULT_SHUF
+ bool
+ default n
+config BUSYBOX_DEFAULT_TEST
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TEST_64
+ bool
+ default y
+config BUSYBOX_DEFAULT_TOUCH
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TOUCH_NODEREF
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TOUCH_SUSV3
+ bool
+ default y
+config BUSYBOX_DEFAULT_TR
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TR_CLASSES
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TR_EQUIV
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNLINK
+ bool
+ default n
+config BUSYBOX_DEFAULT_BASE64
+ bool
+ default n
+config BUSYBOX_DEFAULT_WHO
+ bool
+ default n
+config BUSYBOX_DEFAULT_USERS
+ bool
+ default n
+config BUSYBOX_DEFAULT_CAL
+ bool
+ default n
+config BUSYBOX_DEFAULT_CATV
+ bool
+ default n
+config BUSYBOX_DEFAULT_CHGRP
+ bool
+ default y
+config BUSYBOX_DEFAULT_CHMOD
+ bool
+ default y
+config BUSYBOX_DEFAULT_CHOWN
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_CHOWN_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_CHROOT
+ bool
+ default y
+config BUSYBOX_DEFAULT_CKSUM
+ bool
+ default n
+config BUSYBOX_DEFAULT_COMM
+ bool
+ default n
+config BUSYBOX_DEFAULT_CP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_CP_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_CUT
+ bool
+ default y
+config BUSYBOX_DEFAULT_DD
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_DD_SIGNAL_HANDLING
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_DD_THIRD_STATUS_LINE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_DD_IBS_OBS
+ bool
+ default y
+config BUSYBOX_DEFAULT_DF
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_DF_FANCY
+ bool
+ default n
+config BUSYBOX_DEFAULT_DIRNAME
+ bool
+ default y
+config BUSYBOX_DEFAULT_DOS2UNIX
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNIX2DOS
+ bool
+ default n
+config BUSYBOX_DEFAULT_DU
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
+ bool
+ default y
+config BUSYBOX_DEFAULT_ECHO
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FANCY_ECHO
+ bool
+ default y
+config BUSYBOX_DEFAULT_ENV
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_ENV_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_EXPAND
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_EXPAND_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_EXPR
+ bool
+ default y
+config BUSYBOX_DEFAULT_EXPR_MATH_SUPPORT_64
+ bool
+ default y
+config BUSYBOX_DEFAULT_FALSE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FOLD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FSYNC
+ bool
+ default y
+config BUSYBOX_DEFAULT_HEAD
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FANCY_HEAD
+ bool
+ default y
+config BUSYBOX_DEFAULT_INSTALL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INSTALL_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_LN
+ bool
+ default y
+config BUSYBOX_DEFAULT_LOGNAME
+ bool
+ default n
+config BUSYBOX_DEFAULT_LS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_LS_FILETYPES
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_LS_FOLLOWLINKS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_LS_RECURSIVE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_LS_SORTFILES
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_LS_TIMESTAMPS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_LS_USERNAME
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_LS_COLOR
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_LS_COLOR_IS_DEFAULT
+ bool
+ default y
+config BUSYBOX_DEFAULT_MD5SUM
+ bool
+ default y
+config BUSYBOX_DEFAULT_MKDIR
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_MKDIR_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_MKFIFO
+ bool
+ default y
+config BUSYBOX_DEFAULT_MKNOD
+ bool
+ default y
+config BUSYBOX_DEFAULT_MV
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_MV_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_NICE
+ bool
+ default y
+config BUSYBOX_DEFAULT_NOHUP
+ bool
+ default n
+config BUSYBOX_DEFAULT_OD
+ bool
+ default n
+config BUSYBOX_DEFAULT_PRINTENV
+ bool
+ default n
+config BUSYBOX_DEFAULT_PRINTF
+ bool
+ default y
+config BUSYBOX_DEFAULT_PWD
+ bool
+ default y
+config BUSYBOX_DEFAULT_READLINK
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_READLINK_FOLLOW
+ bool
+ default y
+config BUSYBOX_DEFAULT_REALPATH
+ bool
+ default n
+config BUSYBOX_DEFAULT_RM
+ bool
+ default y
+config BUSYBOX_DEFAULT_RMDIR
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_RMDIR_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_SEQ
+ bool
+ default y
+config BUSYBOX_DEFAULT_SHA1SUM
+ bool
+ default n
+config BUSYBOX_DEFAULT_SHA256SUM
+ bool
+ default n
+config BUSYBOX_DEFAULT_SHA512SUM
+ bool
+ default n
+config BUSYBOX_DEFAULT_SHA3SUM
+ bool
+ default n
+config BUSYBOX_DEFAULT_SLEEP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FANCY_SLEEP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FLOAT_SLEEP
+ bool
+ default n
+config BUSYBOX_DEFAULT_SORT
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_SORT_BIG
+ bool
+ default n
+config BUSYBOX_DEFAULT_SPLIT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SPLIT_FANCY
+ bool
+ default n
+config BUSYBOX_DEFAULT_STAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_STAT_FORMAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_STTY
+ bool
+ default n
+config BUSYBOX_DEFAULT_SUM
+ bool
+ default n
+config BUSYBOX_DEFAULT_SYNC
+ bool
+ default y
+config BUSYBOX_DEFAULT_TAC
+ bool
+ default n
+config BUSYBOX_DEFAULT_TAIL
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FANCY_TAIL
+ bool
+ default y
+config BUSYBOX_DEFAULT_TEE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TEE_USE_BLOCK_IO
+ bool
+ default y
+config BUSYBOX_DEFAULT_TRUE
+ bool
+ default y
+config BUSYBOX_DEFAULT_TTY
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNAME
+ bool
+ default y
+config BUSYBOX_DEFAULT_UNEXPAND
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_UNEXPAND_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_UNIQ
+ bool
+ default y
+config BUSYBOX_DEFAULT_USLEEP
+ bool
+ default n
+config BUSYBOX_DEFAULT_UUDECODE
+ bool
+ default n
+config BUSYBOX_DEFAULT_UUENCODE
+ bool
+ default n
+config BUSYBOX_DEFAULT_WC
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_WC_LARGE
+ bool
+ default n
+config BUSYBOX_DEFAULT_WHOAMI
+ bool
+ default n
+config BUSYBOX_DEFAULT_YES
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VERBOSE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_PRESERVE_HARDLINKS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_AUTOWIDTH
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_HUMAN_READABLE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_MD5_SHA1_SUM_CHECK
+ bool
+ default y
+config BUSYBOX_DEFAULT_CHVT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FGCONSOLE
+ bool
+ default n
+config BUSYBOX_DEFAULT_CLEAR
+ bool
+ default y
+config BUSYBOX_DEFAULT_DEALLOCVT
+ bool
+ default n
+config BUSYBOX_DEFAULT_DUMPKMAP
+ bool
+ default n
+config BUSYBOX_DEFAULT_KBD_MODE
+ bool
+ default n
+config BUSYBOX_DEFAULT_LOADFONT
+ bool
+ default n
+config BUSYBOX_DEFAULT_LOADKMAP
+ bool
+ default n
+config BUSYBOX_DEFAULT_OPENVT
+ bool
+ default n
+config BUSYBOX_DEFAULT_RESET
+ bool
+ default y
+config BUSYBOX_DEFAULT_RESIZE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_RESIZE_PRINT
+ bool
+ default n
+config BUSYBOX_DEFAULT_SETCONSOLE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SETCONSOLE_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_SETFONT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SETFONT_TEXTUAL_MAP
+ bool
+ default n
+config BUSYBOX_DEFAULT_DEFAULT_SETFONT_DIR
+ string
+ default ""
+config BUSYBOX_DEFAULT_SETKEYCODES
+ bool
+ default n
+config BUSYBOX_DEFAULT_SETLOGCONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_SHOWKEY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LOADFONT_PSF2
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LOADFONT_RAW
+ bool
+ default n
+config BUSYBOX_DEFAULT_MKTEMP
+ bool
+ default y
+config BUSYBOX_DEFAULT_PIPE_PROGRESS
+ bool
+ default n
+config BUSYBOX_DEFAULT_RUN_PARTS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_RUN_PARTS_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_RUN_PARTS_FANCY
+ bool
+ default n
+config BUSYBOX_DEFAULT_START_STOP_DAEMON
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_START_STOP_DAEMON_FANCY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_WHICH
+ bool
+ default y
+config BUSYBOX_DEFAULT_AWK
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_AWK_LIBM
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_AWK_GNU_EXTENSIONS
+ bool
+ default y
+config BUSYBOX_DEFAULT_CMP
+ bool
+ default y
+config BUSYBOX_DEFAULT_DIFF
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_DIFF_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_DIFF_DIR
+ bool
+ default n
+config BUSYBOX_DEFAULT_ED
+ bool
+ default n
+config BUSYBOX_DEFAULT_PATCH
+ bool
+ default n
+config BUSYBOX_DEFAULT_SED
+ bool
+ default y
+config BUSYBOX_DEFAULT_VI
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_MAX_LEN
+ int
+ default 1024
+config BUSYBOX_DEFAULT_FEATURE_VI_8BIT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VI_COLON
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_YANKMARK
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_SEARCH
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_REGEX_SEARCH
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VI_USE_SIGNALS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_DOT_CMD
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_READONLY
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_SETOPTS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_SET
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_WIN_RESIZE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_ASK_TERMINAL
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_VI_UNDO
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VI_UNDO_QUEUE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VI_UNDO_QUEUE_MAX
+ int
+ default 0
+config BUSYBOX_DEFAULT_FEATURE_ALLOW_EXEC
+ bool
+ default y
+config BUSYBOX_DEFAULT_FIND
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_PRINT0
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_MTIME
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_MMIN
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FIND_PERM
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_TYPE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_XDEV
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_MAXDEPTH
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_NEWER
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FIND_INUM
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FIND_EXEC
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_EXEC_PLUS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FIND_USER
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_GROUP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_NOT
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_DEPTH
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_PAREN
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_SIZE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_PRUNE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_DELETE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FIND_PATH
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_REGEX
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FIND_CONTEXT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FIND_LINKS
+ bool
+ default n
+config BUSYBOX_DEFAULT_GREP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_GREP_EGREP_ALIAS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_GREP_FGREP_ALIAS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_GREP_CONTEXT
+ bool
+ default y
+config BUSYBOX_DEFAULT_XARGS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_XARGS_SUPPORT_CONFIRMATION
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_XARGS_SUPPORT_QUOTES
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_XARGS_SUPPORT_TERMOPT
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_XARGS_SUPPORT_ZERO_TERM
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_XARGS_SUPPORT_REPL_STR
+ bool
+ default n
+config BUSYBOX_DEFAULT_BOOTCHARTD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_BOOTCHARTD_BLOATED_HEADER
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_BOOTCHARTD_CONFIG_FILE
+ bool
+ default n
+config BUSYBOX_DEFAULT_HALT
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_CALL_TELINIT
+ bool
+ default n
+config BUSYBOX_DEFAULT_TELINIT_PATH
+ string
+ default ""
+config BUSYBOX_DEFAULT_INIT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_USE_INITTAB
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_KILL_REMOVED
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_KILL_DELAY
+ int
+ default 0
+config BUSYBOX_DEFAULT_FEATURE_INIT_SCTTY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INIT_SYSLOG
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_EXTRA_QUIET
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INIT_COREDUMPS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INITRD
+ bool
+ default n
+config BUSYBOX_DEFAULT_INIT_TERMINAL_TYPE
+ string
+ default ""
+config BUSYBOX_DEFAULT_MESG
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MESG_ENABLE_ONLY_GROUP
+ bool
+ default n
+config BUSYBOX_DEFAULT_ADD_SHELL
+ bool
+ default n
+config BUSYBOX_DEFAULT_REMOVE_SHELL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SHADOWPASSWDS
+ bool
+ default y
+config BUSYBOX_DEFAULT_USE_BB_PWD_GRP
+ bool
+ default n
+config BUSYBOX_DEFAULT_USE_BB_SHADOW
+ bool
+ default n
+config BUSYBOX_DEFAULT_USE_BB_CRYPT
+ bool
+ default n
+config BUSYBOX_DEFAULT_USE_BB_CRYPT_SHA
+ bool
+ default n
+config BUSYBOX_DEFAULT_ADDUSER
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_ADDUSER_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHECK_NAMES
+ bool
+ default n
+config BUSYBOX_DEFAULT_LAST_ID
+ int
+ default 0
+config BUSYBOX_DEFAULT_FIRST_SYSTEM_ID
+ int
+ default 0
+config BUSYBOX_DEFAULT_LAST_SYSTEM_ID
+ int
+ default 0
+config BUSYBOX_DEFAULT_ADDGROUP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_ADDGROUP_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_ADDUSER_TO_GROUP
+ bool
+ default n
+config BUSYBOX_DEFAULT_DELUSER
+ bool
+ default n
+config BUSYBOX_DEFAULT_DELGROUP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_DEL_USER_FROM_GROUP
+ bool
+ default n
+config BUSYBOX_DEFAULT_GETTY
+ bool
+ default n
+config BUSYBOX_DEFAULT_LOGIN
+ bool
+ default n
+config BUSYBOX_DEFAULT_LOGIN_SESSION_AS_CHILD
+ bool
+ default n
+config BUSYBOX_DEFAULT_LOGIN_SCRIPTS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_NOLOGIN
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SECURETTY
+ bool
+ default n
+config BUSYBOX_DEFAULT_PASSWD
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_PASSWD_WEAK_CHECK
+ bool
+ default y
+config BUSYBOX_DEFAULT_CRYPTPW
+ bool
+ default n
+config BUSYBOX_DEFAULT_CHPASSWD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_DEFAULT_PASSWD_ALGO
+ string
+ default "md5"
+config BUSYBOX_DEFAULT_SU
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SU_SYSLOG
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SU_CHECKS_SHELLS
+ bool
+ default n
+config BUSYBOX_DEFAULT_SULOGIN
+ bool
+ default n
+config BUSYBOX_DEFAULT_VLOCK
+ bool
+ default n
+config BUSYBOX_DEFAULT_CHATTR
+ bool
+ default n
+config BUSYBOX_DEFAULT_FSCK
+ bool
+ default n
+config BUSYBOX_DEFAULT_LSATTR
+ bool
+ default n
+config BUSYBOX_DEFAULT_TUNE2FS
+ bool
+ default n
+config BUSYBOX_DEFAULT_MODINFO
+ bool
+ default n
+config BUSYBOX_DEFAULT_MODPROBE_SMALL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED
+ bool
+ default n
+config BUSYBOX_DEFAULT_INSMOD
+ bool
+ default n
+config BUSYBOX_DEFAULT_RMMOD
+ bool
+ default n
+config BUSYBOX_DEFAULT_LSMOD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LSMOD_PRETTY_2_6_OUTPUT
+ bool
+ default n
+config BUSYBOX_DEFAULT_MODPROBE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MODPROBE_BLACKLIST
+ bool
+ default n
+config BUSYBOX_DEFAULT_DEPMOD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_2_4_MODULES
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INSMOD_TRY_MMAP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INSMOD_VERSION_CHECKING
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INSMOD_LOADINKMEM
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INSMOD_LOAD_MAP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INSMOD_LOAD_MAP_FULL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHECK_TAINTED_MODULE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MODUTILS_ALIAS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MODUTILS_SYMBOLS
+ bool
+ default n
+config BUSYBOX_DEFAULT_DEFAULT_MODULES_DIR
+ string
+ default ""
+config BUSYBOX_DEFAULT_DEFAULT_DEPMOD_FILE
+ string
+ default ""
+config BUSYBOX_DEFAULT_BLOCKDEV
+ bool
+ default n
+config BUSYBOX_DEFAULT_FATATTR
+ bool
+ default n
+config BUSYBOX_DEFAULT_FSTRIM
+ bool
+ default n
+config BUSYBOX_DEFAULT_MDEV
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MDEV_CONF
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MDEV_RENAME
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MDEV_RENAME_REGEXP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MDEV_EXEC
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MDEV_LOAD_FIRMWARE
+ bool
+ default n
+config BUSYBOX_DEFAULT_REV
+ bool
+ default n
+config BUSYBOX_DEFAULT_ACPID
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_ACPID_COMPAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_BLKID
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_BLKID_TYPE
+ bool
+ default n
+config BUSYBOX_DEFAULT_DMESG
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_DMESG_PRETTY
+ bool
+ default y
+config BUSYBOX_DEFAULT_FBSET
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FBSET_FANCY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FBSET_READMODE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FDFLUSH
+ bool
+ default n
+config BUSYBOX_DEFAULT_FDFORMAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FDISK
+ bool
+ default n
+config BUSYBOX_DEFAULT_FDISK_SUPPORT_LARGE_DISKS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FDISK_WRITABLE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_AIX_LABEL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SGI_LABEL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SUN_LABEL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_OSF_LABEL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_GPT_LABEL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FDISK_ADVANCED
+ bool
+ default n
+config BUSYBOX_DEFAULT_FINDFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FLOCK
+ bool
+ default n
+config BUSYBOX_DEFAULT_FREERAMDISK
+ bool
+ default n
+config BUSYBOX_DEFAULT_FSCK_MINIX
+ bool
+ default n
+config BUSYBOX_DEFAULT_MKFS_EXT2
+ bool
+ default n
+config BUSYBOX_DEFAULT_MKFS_MINIX
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MINIX2
+ bool
+ default n
+config BUSYBOX_DEFAULT_MKFS_REISER
+ bool
+ default n
+config BUSYBOX_DEFAULT_MKFS_VFAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_GETOPT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_GETOPT_LONG
+ bool
+ default n
+config BUSYBOX_DEFAULT_HEXDUMP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_HEXDUMP_REVERSE
+ bool
+ default n
+config BUSYBOX_DEFAULT_HD
+ bool
+ default n
+config BUSYBOX_DEFAULT_HWCLOCK
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_HWCLOCK_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HWCLOCK_ADJTIME_FHS
+ bool
+ default n
+config BUSYBOX_DEFAULT_IPCRM
+ bool
+ default n
+config BUSYBOX_DEFAULT_IPCS
+ bool
+ default n
+config BUSYBOX_DEFAULT_LOSETUP
+ bool
+ default n
+config BUSYBOX_DEFAULT_LSPCI
+ bool
+ default n
+config BUSYBOX_DEFAULT_LSUSB
+ bool
+ default n
+config BUSYBOX_DEFAULT_MKSWAP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_MKSWAP_UUID
+ bool
+ default n
+config BUSYBOX_DEFAULT_MORE
+ bool
+ default n
+config BUSYBOX_DEFAULT_MOUNT
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_MOUNT_FAKE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MOUNT_VERBOSE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MOUNT_HELPERS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_MOUNT_LABEL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MOUNT_NFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MOUNT_CIFS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_MOUNT_FLAGS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_MOUNT_FSTAB
+ bool
+ default y
+config BUSYBOX_DEFAULT_PIVOT_ROOT
+ bool
+ default y
+config BUSYBOX_DEFAULT_RDATE
+ bool
+ default n
+config BUSYBOX_DEFAULT_RDEV
+ bool
+ default n
+config BUSYBOX_DEFAULT_READPROFILE
+ bool
+ default n
+config BUSYBOX_DEFAULT_RTCWAKE
+ bool
+ default n
+config BUSYBOX_DEFAULT_SCRIPT
+ bool
+ default n
+config BUSYBOX_DEFAULT_SCRIPTREPLAY
+ bool
+ default n
+config BUSYBOX_DEFAULT_SETARCH
+ bool
+ default n
+config BUSYBOX_DEFAULT_SWAPONOFF
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SWAPON_DISCARD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SWAPON_PRI
+ bool
+ default n
+config BUSYBOX_DEFAULT_SWITCH_ROOT
+ bool
+ default y
+config BUSYBOX_DEFAULT_UMOUNT
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_UMOUNT_ALL
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_MOUNT_LOOP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_MOUNT_LOOP_CREATE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MTAB_SUPPORT
+ bool
+ default n
+config BUSYBOX_DEFAULT_VOLUMEID
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_BTRFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_CRAMFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_EXFAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_EXT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_F2FS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_FAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_HFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_ISO9660
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_JFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_LINUXRAID
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_LINUXSWAP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_LUKS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_NILFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_NTFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_OCFS2
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_REISERFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_ROMFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_SQUASHFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_SYSV
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_UDF
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_VOLUMEID_XFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_CONSPY
+ bool
+ default n
+config BUSYBOX_DEFAULT_CROND
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_CROND_D
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CROND_CALL_SENDMAIL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CROND_DIR
+ string
+ default "/etc"
+config BUSYBOX_DEFAULT_LESS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_LESS_MAXLINES
+ int
+ default 9999999
+config BUSYBOX_DEFAULT_FEATURE_LESS_BRACKETS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LESS_FLAGS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LESS_MARKS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LESS_REGEXP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LESS_WINCH
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LESS_ASK_TERMINAL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LESS_DASHCMD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LESS_LINENUMS
+ bool
+ default n
+config BUSYBOX_DEFAULT_NANDWRITE
+ bool
+ default n
+config BUSYBOX_DEFAULT_NANDDUMP
+ bool
+ default n
+config BUSYBOX_DEFAULT_RFKILL
+ bool
+ default n
+config BUSYBOX_DEFAULT_SETSERIAL
+ bool
+ default n
+config BUSYBOX_DEFAULT_TASKSET
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TASKSET_FANCY
+ bool
+ default n
+config BUSYBOX_DEFAULT_UBIATTACH
+ bool
+ default n
+config BUSYBOX_DEFAULT_UBIDETACH
+ bool
+ default n
+config BUSYBOX_DEFAULT_UBIMKVOL
+ bool
+ default n
+config BUSYBOX_DEFAULT_UBIRMVOL
+ bool
+ default n
+config BUSYBOX_DEFAULT_UBIRSVOL
+ bool
+ default n
+config BUSYBOX_DEFAULT_UBIUPDATEVOL
+ bool
+ default n
+config BUSYBOX_DEFAULT_WALL
+ bool
+ default n
+config BUSYBOX_DEFAULT_ADJTIMEX
+ bool
+ default n
+config BUSYBOX_DEFAULT_BBCONFIG
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_COMPRESS_BBCONFIG
+ bool
+ default n
+config BUSYBOX_DEFAULT_BEEP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_BEEP_FREQ
+ int
+ default 0
+config BUSYBOX_DEFAULT_FEATURE_BEEP_LENGTH_MS
+ int
+ default 0
+config BUSYBOX_DEFAULT_CHAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHAT_NOFAIL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHAT_TTY_HIFI
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHAT_IMPLICIT_CR
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHAT_SWALLOW_OPTS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHAT_SEND_ESCAPES
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHAT_VAR_ABORT_LEN
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHAT_CLR_ABORT
+ bool
+ default n
+config BUSYBOX_DEFAULT_CHRT
+ bool
+ default n
+config BUSYBOX_DEFAULT_CRONTAB
+ bool
+ default y
+config BUSYBOX_DEFAULT_DC
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_DC_LIBM
+ bool
+ default n
+config BUSYBOX_DEFAULT_DEVFSD
+ bool
+ default n
+config BUSYBOX_DEFAULT_DEVFSD_MODLOAD
+ bool
+ default n
+config BUSYBOX_DEFAULT_DEVFSD_FG_NP
+ bool
+ default n
+config BUSYBOX_DEFAULT_DEVFSD_VERBOSE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_DEVFS
+ bool
+ default n
+config BUSYBOX_DEFAULT_DEVMEM
+ bool
+ default n
+config BUSYBOX_DEFAULT_EJECT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_EJECT_SCSI
+ bool
+ default n
+config BUSYBOX_DEFAULT_FBSPLASH
+ bool
+ default n
+config BUSYBOX_DEFAULT_FLASHCP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FLASH_LOCK
+ bool
+ default n
+config BUSYBOX_DEFAULT_FLASH_UNLOCK
+ bool
+ default n
+config BUSYBOX_DEFAULT_FLASH_ERASEALL
+ bool
+ default n
+config BUSYBOX_DEFAULT_IONICE
+ bool
+ default n
+config BUSYBOX_DEFAULT_INOTIFYD
+ bool
+ default n
+config BUSYBOX_DEFAULT_LAST
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LAST_SMALL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LAST_FANCY
+ bool
+ default n
+config BUSYBOX_DEFAULT_HDPARM
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HDPARM_GET_IDENTITY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HDPARM_HDIO_SCAN_HWIF
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HDPARM_HDIO_DRIVE_RESET
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HDPARM_HDIO_GETSET_DMA
+ bool
+ default n
+config BUSYBOX_DEFAULT_LOCK
+ bool
+ default y
+config BUSYBOX_DEFAULT_MAKEDEVS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MAKEDEVS_LEAF
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MAKEDEVS_TABLE
+ bool
+ default n
+config BUSYBOX_DEFAULT_MAN
+ bool
+ default n
+config BUSYBOX_DEFAULT_MICROCOM
+ bool
+ default n
+config BUSYBOX_DEFAULT_MOUNTPOINT
+ bool
+ default n
+config BUSYBOX_DEFAULT_MT
+ bool
+ default n
+config BUSYBOX_DEFAULT_RAIDAUTORUN
+ bool
+ default n
+config BUSYBOX_DEFAULT_READAHEAD
+ bool
+ default n
+config BUSYBOX_DEFAULT_RUNLEVEL
+ bool
+ default n
+config BUSYBOX_DEFAULT_RX
+ bool
+ default n
+config BUSYBOX_DEFAULT_SETSID
+ bool
+ default n
+config BUSYBOX_DEFAULT_STRINGS
+ bool
+ default y
+config BUSYBOX_DEFAULT_TIME
+ bool
+ default y
+config BUSYBOX_DEFAULT_TIMEOUT
+ bool
+ default n
+config BUSYBOX_DEFAULT_TTYSIZE
+ bool
+ default n
+config BUSYBOX_DEFAULT_VOLNAME
+ bool
+ default n
+config BUSYBOX_DEFAULT_WATCHDOG
+ bool
+ default n
+config BUSYBOX_DEFAULT_NAMEIF
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_NAMEIF_EXTENDED
+ bool
+ default n
+config BUSYBOX_DEFAULT_NBDCLIENT
+ bool
+ default n
+config BUSYBOX_DEFAULT_NC
+ bool
+ default y
+config BUSYBOX_DEFAULT_NC_SERVER
+ bool
+ default n
+config BUSYBOX_DEFAULT_NC_EXTRA
+ bool
+ default n
+config BUSYBOX_DEFAULT_NC_110_COMPAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_PING
+ bool
+ default y
+config BUSYBOX_DEFAULT_PING6
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_FANCY_PING
+ bool
+ default y
+config BUSYBOX_DEFAULT_WHOIS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IPV6
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_UNIX_LOCAL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_PREFER_IPV4_ADDRESS
+ bool
+ default y
+config BUSYBOX_DEFAULT_VERBOSE_RESOLUTION_ERRORS
+ bool
+ default y
+config BUSYBOX_DEFAULT_ARP
+ bool
+ default n
+config BUSYBOX_DEFAULT_ARPING
+ bool
+ default n
+config BUSYBOX_DEFAULT_BRCTL
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_BRCTL_FANCY
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_BRCTL_SHOW
+ bool
+ default y
+config BUSYBOX_DEFAULT_DNSD
+ bool
+ default n
+config BUSYBOX_DEFAULT_ETHER_WAKE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FAKEIDENTD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FTPD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FTP_WRITE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FTPD_ACCEPT_BROKEN_LIST
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FTP_AUTHENTICATION
+ bool
+ default n
+config BUSYBOX_DEFAULT_FTPGET
+ bool
+ default n
+config BUSYBOX_DEFAULT_FTPPUT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_FTPGETPUT_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_HOSTNAME
+ bool
+ default n
+config BUSYBOX_DEFAULT_HTTPD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_RANGES
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_SETUID
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_BASIC_AUTH
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_AUTH_MD5
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_CGI
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_ENCODE_URL_STR
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_ERROR_PAGES
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_PROXY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_HTTPD_GZIP
+ bool
+ default n
+config BUSYBOX_DEFAULT_IFCONFIG
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_IFCONFIG_STATUS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_IFCONFIG_SLIP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IFCONFIG_HW
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_IFCONFIG_BROADCAST_PLUS
+ bool
+ default y
+config BUSYBOX_DEFAULT_IFENSLAVE
+ bool
+ default n
+config BUSYBOX_DEFAULT_IFPLUGD
+ bool
+ default n
+config BUSYBOX_DEFAULT_IFUPDOWN
+ bool
+ default n
+config BUSYBOX_DEFAULT_IFUPDOWN_IFSTATE_PATH
+ string
+ default ""
+config BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_IP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_IP_BUILTIN
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_IPV4
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_IPV6
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_MAPPING
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_EXTERNAL_DHCP
+ bool
+ default n
+config BUSYBOX_DEFAULT_INETD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INETD_SUPPORT_BUILTIN_ECHO
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INETD_SUPPORT_BUILTIN_TIME
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_INETD_RPC
+ bool
+ default n
+config BUSYBOX_DEFAULT_IP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_IP_ADDRESS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_IP_LINK
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_IP_ROUTE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_IP_TUNNEL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IP_RULE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IP_SHORT_FORMS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IP_RARE_PROTOCOLS
+ bool
+ default n
+config BUSYBOX_DEFAULT_IPADDR
+ bool
+ default n
+config BUSYBOX_DEFAULT_IPLINK
+ bool
+ default n
+config BUSYBOX_DEFAULT_IPROUTE
+ bool
+ default n
+config BUSYBOX_DEFAULT_IPTUNNEL
+ bool
+ default n
+config BUSYBOX_DEFAULT_IPRULE
+ bool
+ default n
+config BUSYBOX_DEFAULT_IPCALC
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IPCALC_FANCY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IPCALC_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_NETMSG
+ bool
+ default y
+config BUSYBOX_DEFAULT_NETSTAT
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_NETSTAT_WIDE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_NETSTAT_PRG
+ bool
+ default y
+config BUSYBOX_DEFAULT_NSLOOKUP
+ bool
+ default y
+config BUSYBOX_DEFAULT_NTPD
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_NTPD_SERVER
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_NTPD_CONF
+ bool
+ default n
+config BUSYBOX_DEFAULT_PSCAN
+ bool
+ default n
+config BUSYBOX_DEFAULT_ROUTE
+ bool
+ default y
+config BUSYBOX_DEFAULT_SLATTACH
+ bool
+ default n
+config BUSYBOX_DEFAULT_TCPSVD
+ bool
+ default n
+config BUSYBOX_DEFAULT_TELNET
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TELNET_TTYPE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TELNET_AUTOLOGIN
+ bool
+ default n
+config BUSYBOX_DEFAULT_TELNETD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TELNETD_STANDALONE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TELNETD_INETD_WAIT
+ bool
+ default n
+config BUSYBOX_DEFAULT_TFTP
+ bool
+ default n
+config BUSYBOX_DEFAULT_TFTPD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TFTP_GET
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TFTP_PUT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TFTP_BLOCKSIZE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TFTP_PROGRESS_BAR
+ bool
+ default n
+config BUSYBOX_DEFAULT_TFTP_DEBUG
+ bool
+ default n
+config BUSYBOX_DEFAULT_TRACEROUTE
+ bool
+ default y
+config BUSYBOX_DEFAULT_TRACEROUTE6
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TRACEROUTE_VERBOSE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TRACEROUTE_SOURCE_ROUTE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TRACEROUTE_USE_ICMP
+ bool
+ default n
+config BUSYBOX_DEFAULT_TUNCTL
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TUNCTL_UG
+ bool
+ default n
+config BUSYBOX_DEFAULT_UDHCPC6
+ bool
+ default n
+config BUSYBOX_DEFAULT_UDHCPD
+ bool
+ default n
+config BUSYBOX_DEFAULT_DHCPRELAY
+ bool
+ default n
+config BUSYBOX_DEFAULT_DUMPLEASES
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_UDHCPD_WRITE_LEASES_EARLY
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_UDHCPD_BASE_IP_ON_MAC
+ bool
+ default n
+config BUSYBOX_DEFAULT_DHCPD_LEASES_FILE
+ string
+ default ""
+config BUSYBOX_DEFAULT_UDHCPC
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_UDHCPC_ARPING
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_UDHCPC_SANITIZEOPT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_UDHCP_PORT
+ bool
+ default n
+config BUSYBOX_DEFAULT_UDHCP_DEBUG
+ int
+ default 0
+config BUSYBOX_DEFAULT_FEATURE_UDHCP_RFC3397
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_UDHCP_8021Q
+ bool
+ default n
+config BUSYBOX_DEFAULT_UDHCPC_DEFAULT_SCRIPT
+ string
+ default "/usr/share/udhcpc/default.script"
+config BUSYBOX_DEFAULT_UDHCPC_SLACK_FOR_BUGGY_SERVERS
+ int
+ default 80
+config BUSYBOX_DEFAULT_IFUPDOWN_UDHCPC_CMD_OPTIONS
+ string
+ default ""
+config BUSYBOX_DEFAULT_UDPSVD
+ bool
+ default n
+config BUSYBOX_DEFAULT_VCONFIG
+ bool
+ default n
+config BUSYBOX_DEFAULT_WGET
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_WGET_STATUSBAR
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_WGET_AUTHENTICATION
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_WGET_LONG_OPTIONS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_WGET_TIMEOUT
+ bool
+ default n
+config BUSYBOX_DEFAULT_ZCIP
+ bool
+ default n
+config BUSYBOX_DEFAULT_LPD
+ bool
+ default n
+config BUSYBOX_DEFAULT_LPR
+ bool
+ default n
+config BUSYBOX_DEFAULT_LPQ
+ bool
+ default n
+config BUSYBOX_DEFAULT_MAKEMIME
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_MIME_CHARSET
+ string
+ default ""
+config BUSYBOX_DEFAULT_POPMAILDIR
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_POPMAILDIR_DELIVERY
+ bool
+ default n
+config BUSYBOX_DEFAULT_REFORMIME
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_REFORMIME_COMPAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_SENDMAIL
+ bool
+ default n
+config BUSYBOX_DEFAULT_IOSTAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_LSOF
+ bool
+ default n
+config BUSYBOX_DEFAULT_MPSTAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_NMETER
+ bool
+ default n
+config BUSYBOX_DEFAULT_PMAP
+ bool
+ default n
+config BUSYBOX_DEFAULT_POWERTOP
+ bool
+ default n
+config BUSYBOX_DEFAULT_PSTREE
+ bool
+ default n
+config BUSYBOX_DEFAULT_PWDX
+ bool
+ default n
+config BUSYBOX_DEFAULT_SMEMCAP
+ bool
+ default n
+config BUSYBOX_DEFAULT_TOP
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TOP_CPU_USAGE_PERCENTAGE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TOP_CPU_GLOBAL_PERCENTS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_TOP_SMP_CPU
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TOP_DECIMALS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TOP_SMP_PROCESS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_TOPMEM
+ bool
+ default n
+config BUSYBOX_DEFAULT_UPTIME
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_UPTIME_UTMP_SUPPORT
+ bool
+ default n
+config BUSYBOX_DEFAULT_FREE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FUSER
+ bool
+ default n
+config BUSYBOX_DEFAULT_KILL
+ bool
+ default y
+config BUSYBOX_DEFAULT_KILLALL
+ bool
+ default y
+config BUSYBOX_DEFAULT_KILLALL5
+ bool
+ default n
+config BUSYBOX_DEFAULT_PGREP
+ bool
+ default y
+config BUSYBOX_DEFAULT_PIDOF
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_PIDOF_SINGLE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_PIDOF_OMIT
+ bool
+ default n
+config BUSYBOX_DEFAULT_PKILL
+ bool
+ default n
+config BUSYBOX_DEFAULT_PS
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_PS_WIDE
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_PS_LONG
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_PS_TIME
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_PS_ADDITIONAL_COLUMNS
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_PS_UNUSUAL_SYSTEMS
+ bool
+ default n
+config BUSYBOX_DEFAULT_RENICE
+ bool
+ default n
+config BUSYBOX_DEFAULT_BB_SYSCTL
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_SHOW_THREADS
+ bool
+ default n
+config BUSYBOX_DEFAULT_WATCH
+ bool
+ default n
+config BUSYBOX_DEFAULT_RUNSV
+ bool
+ default n
+config BUSYBOX_DEFAULT_RUNSVDIR
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_RUNSVDIR_LOG
+ bool
+ default n
+config BUSYBOX_DEFAULT_SV
+ bool
+ default n
+config BUSYBOX_DEFAULT_SV_DEFAULT_SERVICE_DIR
+ string
+ default ""
+config BUSYBOX_DEFAULT_SVLOGD
+ bool
+ default n
+config BUSYBOX_DEFAULT_CHPST
+ bool
+ default n
+config BUSYBOX_DEFAULT_SETUIDGID
+ bool
+ default n
+config BUSYBOX_DEFAULT_ENVUIDGID
+ bool
+ default n
+config BUSYBOX_DEFAULT_ENVDIR
+ bool
+ default n
+config BUSYBOX_DEFAULT_SOFTLIMIT
+ bool
+ default n
+config BUSYBOX_DEFAULT_CHCON
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_CHCON_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_GETENFORCE
+ bool
+ default n
+config BUSYBOX_DEFAULT_GETSEBOOL
+ bool
+ default n
+config BUSYBOX_DEFAULT_LOAD_POLICY
+ bool
+ default n
+config BUSYBOX_DEFAULT_MATCHPATHCON
+ bool
+ default n
+config BUSYBOX_DEFAULT_RESTORECON
+ bool
+ default n
+config BUSYBOX_DEFAULT_RUNCON
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_RUNCON_LONG_OPTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_SELINUXENABLED
+ bool
+ default n
+config BUSYBOX_DEFAULT_SETENFORCE
+ bool
+ default n
+config BUSYBOX_DEFAULT_SETFILES
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SETFILES_CHECK_OPTION
+ bool
+ default n
+config BUSYBOX_DEFAULT_SETSEBOOL
+ bool
+ default n
+config BUSYBOX_DEFAULT_SESTATUS
+ bool
+ default n
+config BUSYBOX_DEFAULT_ASH
+ bool
+ default y
+config BUSYBOX_DEFAULT_ASH_BASH_COMPAT
+ bool
+ default y
+config BUSYBOX_DEFAULT_ASH_IDLE_TIMEOUT
+ bool
+ default n
+config BUSYBOX_DEFAULT_ASH_JOB_CONTROL
+ bool
+ default y
+config BUSYBOX_DEFAULT_ASH_ALIAS
+ bool
+ default y
+config BUSYBOX_DEFAULT_ASH_GETOPTS
+ bool
+ default y
+config BUSYBOX_DEFAULT_ASH_BUILTIN_ECHO
+ bool
+ default y
+config BUSYBOX_DEFAULT_ASH_BUILTIN_PRINTF
+ bool
+ default y
+config BUSYBOX_DEFAULT_ASH_BUILTIN_TEST
+ bool
+ default y
+config BUSYBOX_DEFAULT_ASH_HELP
+ bool
+ default n
+config BUSYBOX_DEFAULT_ASH_CMDCMD
+ bool
+ default y
+config BUSYBOX_DEFAULT_ASH_MAIL
+ bool
+ default n
+config BUSYBOX_DEFAULT_ASH_OPTIMIZE_FOR_SIZE
+ bool
+ default n
+config BUSYBOX_DEFAULT_ASH_RANDOM_SUPPORT
+ bool
+ default n
+config BUSYBOX_DEFAULT_ASH_EXPAND_PRMT
+ bool
+ default y
+config BUSYBOX_DEFAULT_CTTYHACK
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_BASH_COMPAT
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_BRACE_EXPANSION
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_HELP
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_INTERACTIVE
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_SAVEHISTORY
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_JOB
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_TICK
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_IF
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_LOOPS
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_CASE
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_FUNCTIONS
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_LOCAL
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_RANDOM_SUPPORT
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_EXPORT_N
+ bool
+ default n
+config BUSYBOX_DEFAULT_HUSH_MODE_X
+ bool
+ default n
+config BUSYBOX_DEFAULT_MSH
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SH_IS_ASH
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_SH_IS_HUSH
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SH_IS_NONE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_BASH_IS_ASH
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_BASH_IS_HUSH
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_BASH_IS_NONE
+ bool
+ default y
+config BUSYBOX_DEFAULT_SH_MATH_SUPPORT
+ bool
+ default y
+config BUSYBOX_DEFAULT_SH_MATH_SUPPORT_64
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_SH_EXTRA_QUIET
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SH_STANDALONE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SH_NOFORK
+ bool
+ default y
+config BUSYBOX_DEFAULT_FEATURE_SH_HISTFILESIZE
+ bool
+ default n
+config BUSYBOX_DEFAULT_SYSLOGD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_ROTATE_LOGFILE
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_REMOTE_LOG
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SYSLOGD_DUP
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SYSLOGD_CFG
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_SYSLOGD_READ_BUFFER_SIZE
+ int
+ default 0
+config BUSYBOX_DEFAULT_FEATURE_IPC_SYSLOG
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_IPC_SYSLOG_BUFFER_SIZE
+ int
+ default 0
+config BUSYBOX_DEFAULT_LOGREAD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_LOGREAD_REDUCED_LOCKING
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_KMSG_SYSLOG
+ bool
+ default n
+config BUSYBOX_DEFAULT_KLOGD
+ bool
+ default n
+config BUSYBOX_DEFAULT_FEATURE_KLOGD_KLOGCTL
+ bool
+ default n
+config BUSYBOX_DEFAULT_LOGGER
+ bool
+ default y
diff --git a/package/utils/busybox/Config.in b/package/utils/busybox/Config.in
new file mode 100644
index 0000000..917e714
--- /dev/null
+++ b/package/utils/busybox/Config.in
@@ -0,0 +1,26 @@
+if PACKAGE_busybox
+
+config BUSYBOX_CUSTOM
+ bool "Customize busybox options"
+ default n
+ help
+ Enabling this allows full customization of busybox settings.
+ Note that there are many options here that can result in a build
+ that doesn't work properly. Enabling customization will mark your
+ build as "tainted" for the purpose of bug reports.
+ See the variables written to /etc/openwrt_release
+
+ Unless you know what you are doing, you should leave this as 'n'
+
+ source "Config-defaults.in"
+
+ if BUSYBOX_CUSTOM
+ source "config/Config.in"
+ endif
+
+config BUSYBOX_USE_LIBRPC
+ bool
+ default y if BUSYBOX_CUSTOM && BUSYBOX_CONFIG_FEATURE_HAVE_RPC
+ default y if !BUSYBOX_CUSTOM && BUSYBOX_DEFAULT_FEATURE_HAVE_RPC
+
+endif
diff --git a/package/utils/busybox/Makefile b/package/utils/busybox/Makefile
new file mode 100644
index 0000000..5ca4363
--- /dev/null
+++ b/package/utils/busybox/Makefile
@@ -0,0 +1,118 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=busybox
+PKG_VERSION:=1.24.1
+PKG_RELEASE:=1
+PKG_FLAGS:=essential
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=http://www.busybox.net/downloads \
+ http://distfiles.gentoo.org/distfiles/
+PKG_MD5SUM:=be98a40cadf84ce2d6b05fa41a275c6a
+
+PKG_BUILD_DEPENDS:=BUSYBOX_USE_LIBRPC:librpc BUSYBOX_CONFIG_PAM:libpam
+PKG_BUILD_PARALLEL:=1
+PKG_CHECK_FORMAT_SECURITY:=0
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=LICENSE archival/libarchive/bz/LICENSE
+
+include $(INCLUDE_DIR)/package.mk
+
+ifeq ($(DUMP),)
+ STAMP_CONFIGURED:=$(strip $(STAMP_CONFIGURED))_$(shell $(SH_FUNC) grep '^CONFIG_BUSYBOX_' $(TOPDIR)/.config | md5s)
+endif
+
+ifneq ($(findstring c,$(OPENWRT_VERBOSE)),)
+ BB_MAKE_VERBOSE := V=1
+else
+ BB_MAKE_VERBOSE :=
+endif
+
+define Package/busybox
+ SECTION:=base
+ CATEGORY:=Base system
+ MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+ TITLE:=Core utilities for embedded Linux
+ URL:=http://busybox.net/
+ DEPENDS:=+BUSYBOX_USE_LIBRPC:librpc +BUSYBOX_CONFIG_PAM:libpam
+ MENU:=1
+endef
+
+define Package/busybox/description
+ The Swiss Army Knife of embedded Linux.
+ It slices, it dices, it makes Julian Fries.
+endef
+
+define Package/busybox/config
+ source "$(SOURCE)/Config.in"
+endef
+
+BUSYBOX_SYM=$(if $(CONFIG_BUSYBOX_CUSTOM),CONFIG,DEFAULT)
+
+define Build/Configure
+ rm -f $(PKG_BUILD_DIR)/.configured*
+ grep 'CONFIG_BUSYBOX_$(BUSYBOX_SYM)' $(TOPDIR)/.config | sed -e "s,\\(# \)\\?CONFIG_BUSYBOX_$(BUSYBOX_SYM)_\\(.*\\),\\1CONFIG_\\2,g" > $(PKG_BUILD_DIR)/.config
+ yes 'n' | $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ KBUILD_HAVE_NLS=no \
+ ARCH="$(ARCH)" \
+ $(BB_MAKE_VERBOSE) \
+ oldconfig
+endef
+
+LDLIBS:=m crypt
+ifdef CONFIG_BUSYBOX_USE_LIBRPC
+ TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
+ export LDFLAGS=$(TARGET_LDFLAGS)
+ LDLIBS += rpc
+endif
+
+ifdef CONFIG_BUSYBOX_CONFIG_PAM
+ TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
+ export LDFLAGS=$(TARGET_LDFLAGS)
+ LDLIBS += pam pam_misc pthread
+endif
+
+define Build/Compile
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ KBUILD_HAVE_NLS=no \
+ EXTRA_CFLAGS="$(TARGET_CFLAGS)" \
+ ARCH="$(ARCH)" \
+ SKIP_STRIP=y \
+ LDLIBS="$(LDLIBS)" \
+ $(BB_MAKE_VERBOSE) \
+ all
+ rm -rf $(PKG_INSTALL_DIR)
+ $(FIND) $(PKG_BUILD_DIR) -lname "*busybox" -exec rm \{\} \;
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CROSS_COMPILE="$(TARGET_CROSS)" \
+ EXTRA_CFLAGS="$(TARGET_CFLAGS)" \
+ ARCH="$(ARCH)" \
+ CONFIG_PREFIX="$(PKG_INSTALL_DIR)" \
+ LDLIBS="$(LDLIBS)" \
+ $(BB_MAKE_VERBOSE) \
+ install
+endef
+
+define Package/busybox/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(CP) $(PKG_INSTALL_DIR)/* $(1)/
+ $(INSTALL_BIN) ./files/cron $(1)/etc/init.d/cron
+ $(INSTALL_BIN) ./files/sysntpd $(1)/etc/init.d/sysntpd
+ $(INSTALL_BIN) ./files/ntpd-hotplug $(1)/usr/sbin/ntpd-hotplug
+ -rm -rf $(1)/lib64
+endef
+
+$(eval $(call BuildPackage,busybox))
diff --git a/package/utils/busybox/config/Config.in b/package/utils/busybox/config/Config.in
new file mode 100644
index 0000000..6a205f6
--- /dev/null
+++ b/package/utils/busybox/config/Config.in
@@ -0,0 +1,843 @@
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+
+config BUSYBOX_CONFIG_HAVE_DOT_CONFIG
+ bool
+ default BUSYBOX_DEFAULT_HAVE_DOT_CONFIG
+
+menu "Busybox Settings"
+
+menu "General Configuration"
+
+config BUSYBOX_CONFIG_DESKTOP
+ bool "Enable options for full-blown desktop systems"
+ default BUSYBOX_DEFAULT_DESKTOP
+ help
+ Enable options and features which are not essential.
+ Select this only if you plan to use busybox on full-blown
+ desktop machine with common Linux distro, not on an embedded box.
+
+config BUSYBOX_CONFIG_EXTRA_COMPAT
+ bool "Provide compatible behavior for rare corner cases (bigger code)"
+ default BUSYBOX_DEFAULT_EXTRA_COMPAT
+ help
+ This option makes grep, sed etc handle rare corner cases
+ (embedded NUL bytes and such). This makes code bigger and uses
+ some GNU extensions in libc. You probably only need this option
+ if you plan to run busybox on desktop.
+
+config BUSYBOX_CONFIG_INCLUDE_SUSv2
+ bool "Enable obsolete features removed before SUSv3"
+ default BUSYBOX_DEFAULT_INCLUDE_SUSv2
+ help
+ This option will enable backwards compatibility with SuSv2,
+ specifically, old-style numeric options ('command -1 <file>')
+ will be supported in head, tail, and fold. (Note: should
+ affect renice too.)
+
+config BUSYBOX_CONFIG_USE_PORTABLE_CODE
+ bool "Avoid using GCC-specific code constructs"
+ default BUSYBOX_DEFAULT_USE_PORTABLE_CODE
+ help
+ Use this option if you are trying to compile busybox with
+ compiler other than gcc.
+ If you do use gcc, this option may needlessly increase code size.
+
+config BUSYBOX_CONFIG_PLATFORM_LINUX
+ bool "Enable Linux-specific applets and features"
+ default BUSYBOX_DEFAULT_PLATFORM_LINUX
+ help
+ For the most part, busybox requires only POSIX compatibility
+ from the target system, but some applets and features use
+ Linux-specific interfaces.
+
+ Answering 'N' here will disable such applets and hide the
+ corresponding configuration options.
+
+choice
+ prompt "Buffer allocation policy"
+ default BUSYBOX_CONFIG_FEATURE_BUFFERS_GO_ON_STACK
+ help
+ There are 3 ways BusyBox can handle buffer allocations:
+ - Use malloc. This costs code size for the call to xmalloc.
+ - Put them on stack. For some very small machines with limited stack
+ space, this can be deadly. For most folks, this works just fine.
+ - Put them in BSS. This works beautifully for computers with a real
+ MMU (and OS support), but wastes runtime RAM for uCLinux. This
+ behavior was the only one available for BusyBox versions 0.48 and
+ earlier.
+
+config BUSYBOX_CONFIG_FEATURE_BUFFERS_USE_MALLOC
+ bool "Allocate with Malloc"
+
+config BUSYBOX_CONFIG_FEATURE_BUFFERS_GO_ON_STACK
+ bool "Allocate on the Stack"
+
+config BUSYBOX_CONFIG_FEATURE_BUFFERS_GO_IN_BSS
+ bool "Allocate in the .bss section"
+
+endchoice
+
+config BUSYBOX_CONFIG_SHOW_USAGE
+ bool "Show applet usage messages"
+ default BUSYBOX_DEFAULT_SHOW_USAGE
+ help
+ Enabling this option, BusyBox applets will show terse help messages
+ when invoked with wrong arguments.
+ If you do not want to show any (helpful) usage message when
+ issuing wrong command syntax, you can say 'N' here,
+ saving approximately 7k.
+
+config BUSYBOX_CONFIG_FEATURE_VERBOSE_USAGE
+ bool "Show verbose applet usage messages"
+ default BUSYBOX_DEFAULT_FEATURE_VERBOSE_USAGE
+ depends on BUSYBOX_CONFIG_SHOW_USAGE
+ help
+ All BusyBox applets will show verbose help messages when
+ busybox is invoked with --help. This will add a lot of text to the
+ busybox binary. In the default configuration, this will add about
+ 13k, but it can add much more depending on your configuration.
+
+config BUSYBOX_CONFIG_FEATURE_COMPRESS_USAGE
+ bool "Store applet usage messages in compressed form"
+ default BUSYBOX_DEFAULT_FEATURE_COMPRESS_USAGE
+ depends on BUSYBOX_CONFIG_SHOW_USAGE
+ help
+ Store usage messages in .bz compressed form, uncompress them
+ on-the-fly when <applet> --help is called.
+
+ If you have a really tiny busybox with few applets enabled (and
+ bunzip2 isn't one of them), the overhead of the decompressor might
+ be noticeable. Also, if you run executables directly from ROM
+ and have very little memory, this might not be a win. Otherwise,
+ you probably want this.
+
+config BUSYBOX_CONFIG_FEATURE_INSTALLER
+ bool "Support --install [-s] to install applet links at runtime"
+ default BUSYBOX_DEFAULT_FEATURE_INSTALLER
+ help
+ Enable 'busybox --install [-s]' support. This will allow you to use
+ busybox at runtime to create hard links or symlinks for all the
+ applets that are compiled into busybox.
+
+config BUSYBOX_CONFIG_INSTALL_NO_USR
+ bool "Don't use /usr"
+ default BUSYBOX_DEFAULT_INSTALL_NO_USR
+ help
+ Disable use of /usr. busybox --install and "make install"
+ will install applets only to /bin and /sbin,
+ never to /usr/bin or /usr/sbin.
+
+config BUSYBOX_CONFIG_LOCALE_SUPPORT
+ bool "Enable locale support (system needs locale for this to work)"
+ default BUSYBOX_DEFAULT_LOCALE_SUPPORT
+ help
+ Enable this if your system has locale support and you would like
+ busybox to support locale settings.
+
+config BUSYBOX_CONFIG_UNICODE_SUPPORT
+ bool "Support Unicode"
+ default BUSYBOX_DEFAULT_UNICODE_SUPPORT
+ help
+ This makes various applets aware that one byte is not
+ one character on screen.
+
+ Busybox aims to eventually work correctly with Unicode displays.
+ Any older encodings are not guaranteed to work.
+ Probably by the time when busybox will be fully Unicode-clean,
+ other encodings will be mainly of historic interest.
+
+config BUSYBOX_CONFIG_UNICODE_USING_LOCALE
+ bool "Use libc routines for Unicode (else uses internal ones)"
+ default BUSYBOX_DEFAULT_UNICODE_USING_LOCALE
+ depends on BUSYBOX_CONFIG_UNICODE_SUPPORT && BUSYBOX_CONFIG_LOCALE_SUPPORT
+ help
+ With this option on, Unicode support is implemented using libc
+ routines. Otherwise, internal implementation is used.
+ Internal implementation is smaller.
+
+config BUSYBOX_CONFIG_FEATURE_CHECK_UNICODE_IN_ENV
+ bool "Check $LC_ALL, $LC_CTYPE and $LANG environment variables"
+ default BUSYBOX_DEFAULT_FEATURE_CHECK_UNICODE_IN_ENV
+ depends on BUSYBOX_CONFIG_UNICODE_SUPPORT && !BUSYBOX_CONFIG_UNICODE_USING_LOCALE
+ help
+ With this option on, Unicode support is activated
+ only if locale-related variables have the value of the form
+ "xxxx.utf8"
+
+ Otherwise, Unicode support will be always enabled and active.
+
+config BUSYBOX_CONFIG_SUBST_WCHAR
+ int "Character code to substitute unprintable characters with"
+ depends on BUSYBOX_CONFIG_UNICODE_SUPPORT
+ default BUSYBOX_DEFAULT_SUBST_WCHAR
+ help
+ Typical values are 63 for '?' (works with any output device),
+ 30 for ASCII substitute control code,
+ 65533 (0xfffd) for Unicode replacement character.
+
+config BUSYBOX_CONFIG_LAST_SUPPORTED_WCHAR
+ int "Range of supported Unicode characters"
+ depends on BUSYBOX_CONFIG_UNICODE_SUPPORT
+ default BUSYBOX_DEFAULT_LAST_SUPPORTED_WCHAR
+ help
+ Any character with Unicode value bigger than this is assumed
+ to be non-printable on output device. Many applets replace
+ such chars with substitution character.
+
+ The idea is that many valid printable Unicode chars are
+ nevertheless are not displayed correctly. Think about
+ combining charachers, double-wide hieroglyphs, obscure
+ characters in dozens of ancient scripts...
+ Many terminals, terminal emulators, xterms etc will fail
+ to handle them correctly. Choose the smallest value
+ which suits your needs.
+
+ Typical values are:
+ 126 - ASCII only
+ 767 (0x2ff) - there are no combining chars in [0..767] range
+ (the range includes Latin 1, Latin Ext. A and B),
+ code is ~700 bytes smaller for this case.
+ 4351 (0x10ff) - there are no double-wide chars in [0..4351] range,
+ code is ~300 bytes smaller for this case.
+ 12799 (0x31ff) - nearly all non-ideographic characters are
+ available in [0..12799] range, including
+ East Asian scripts like katakana, hiragana, hangul,
+ bopomofo...
+ 0 - off, any valid printable Unicode character will be printed.
+
+config BUSYBOX_CONFIG_UNICODE_COMBINING_WCHARS
+ bool "Allow zero-width Unicode characters on output"
+ default BUSYBOX_DEFAULT_UNICODE_COMBINING_WCHARS
+ depends on BUSYBOX_CONFIG_UNICODE_SUPPORT
+ help
+ With this option off, any Unicode char with width of 0
+ is substituted on output.
+
+config BUSYBOX_CONFIG_UNICODE_WIDE_WCHARS
+ bool "Allow wide Unicode characters on output"
+ default BUSYBOX_DEFAULT_UNICODE_WIDE_WCHARS
+ depends on BUSYBOX_CONFIG_UNICODE_SUPPORT
+ help
+ With this option off, any Unicode char with width > 1
+ is substituted on output.
+
+config BUSYBOX_CONFIG_UNICODE_BIDI_SUPPORT
+ bool "Bidirectional character-aware line input"
+ default BUSYBOX_DEFAULT_UNICODE_BIDI_SUPPORT
+ depends on BUSYBOX_CONFIG_UNICODE_SUPPORT && !BUSYBOX_CONFIG_UNICODE_USING_LOCALE
+ help
+ With this option on, right-to-left Unicode characters
+ are treated differently on input (e.g. cursor movement).
+
+config BUSYBOX_CONFIG_UNICODE_NEUTRAL_TABLE
+ bool "In bidi input, support non-ASCII neutral chars too"
+ default BUSYBOX_DEFAULT_UNICODE_NEUTRAL_TABLE
+ depends on BUSYBOX_CONFIG_UNICODE_BIDI_SUPPORT
+ help
+ In most cases it's enough to treat only ASCII non-letters
+ (i.e. punctuation, numbers and space) as characters
+ with neutral directionality.
+ With this option on, more extensive (and bigger) table
+ of neutral chars will be used.
+
+config BUSYBOX_CONFIG_UNICODE_PRESERVE_BROKEN
+ bool "Make it possible to enter sequences of chars which are not Unicode"
+ default BUSYBOX_DEFAULT_UNICODE_PRESERVE_BROKEN
+ depends on BUSYBOX_CONFIG_UNICODE_SUPPORT
+ help
+ With this option on, on line-editing input (such as used by shells)
+ invalid UTF-8 bytes are not substituted with the selected
+ substitution character.
+ For example, this means that entering 'l', 's', ' ', 0xff, [Enter]
+ at shell prompt will list file named 0xff (single char name
+ with char value 255), not file named '?'.
+
+config BUSYBOX_CONFIG_PAM
+ bool "Support for PAM (Pluggable Authentication Modules)"
+ default BUSYBOX_DEFAULT_PAM
+ help
+ Use PAM in some busybox applets (currently login and httpd) instead
+ of direct access to password database.
+
+config BUSYBOX_CONFIG_FEATURE_USE_SENDFILE
+ bool "Use sendfile system call"
+ default BUSYBOX_DEFAULT_FEATURE_USE_SENDFILE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ When enabled, busybox will use the kernel sendfile() function
+ instead of read/write loops to copy data between file descriptors
+ (for example, cp command does this a lot).
+ If sendfile() doesn't work, copying code falls back to read/write
+ loop. sendfile() was originally implemented for faster I/O
+ from files to sockets, but since Linux 2.6.33 it was extended
+ to work for many more file types.
+
+config BUSYBOX_CONFIG_LONG_OPTS
+ bool "Support for --long-options"
+ default BUSYBOX_DEFAULT_LONG_OPTS
+ help
+ Enable this if you want busybox applets to use the gnu --long-option
+ style, in addition to single character -a -b -c style options.
+
+config BUSYBOX_CONFIG_FEATURE_DEVPTS
+ bool "Use the devpts filesystem for Unix98 PTYs"
+ default BUSYBOX_DEFAULT_FEATURE_DEVPTS
+ help
+ Enable if you want BusyBox to use Unix98 PTY support. If enabled,
+ busybox will use /dev/ptmx for the master side of the pseudoterminal
+ and /dev/pts/<number> for the slave side. Otherwise, BSD style
+ /dev/ttyp<number> will be used. To use this option, you should have
+ devpts mounted.
+
+config BUSYBOX_CONFIG_FEATURE_CLEAN_UP
+ bool "Clean up all memory before exiting (usually not needed)"
+ default BUSYBOX_DEFAULT_FEATURE_CLEAN_UP
+ help
+ As a size optimization, busybox normally exits without explicitly
+ freeing dynamically allocated memory or closing files. This saves
+ space since the OS will clean up for us, but it can confuse debuggers
+ like valgrind, which report tons of memory and resource leaks.
+
+ Don't enable this unless you have a really good reason to clean
+ things up manually.
+
+config BUSYBOX_CONFIG_FEATURE_UTMP
+ bool "Support utmp file"
+ default BUSYBOX_DEFAULT_FEATURE_UTMP
+ help
+ The file /var/run/utmp is used to track who is currently logged in.
+ With this option on, certain applets (getty, login, telnetd etc)
+ will create and delete entries there.
+ "who" applet requires this option.
+
+config BUSYBOX_CONFIG_FEATURE_WTMP
+ bool "Support wtmp file"
+ default BUSYBOX_DEFAULT_FEATURE_WTMP
+ depends on BUSYBOX_CONFIG_FEATURE_UTMP
+ help
+ The file /var/run/wtmp is used to track when users have logged into
+ and logged out of the system.
+ With this option on, certain applets (getty, login, telnetd etc)
+ will append new entries there.
+ "last" applet requires this option.
+
+config BUSYBOX_CONFIG_FEATURE_PIDFILE
+ bool "Support writing pidfiles"
+ default BUSYBOX_DEFAULT_FEATURE_PIDFILE
+ help
+ This option makes some applets (e.g. crond, syslogd, inetd) write
+ a pidfile at the configured PID_FILE_PATH. It has no effect
+ on applets which require pidfiles to run.
+
+config BUSYBOX_CONFIG_PID_FILE_PATH
+ string "Path to directory for pidfile"
+ default BUSYBOX_DEFAULT_PID_FILE_PATH
+ depends on BUSYBOX_CONFIG_FEATURE_PIDFILE
+ help
+ This is the default path where pidfiles are created. Applets which
+ allow you to set the pidfile path on the command line will override
+ this value. The option has no effect on applets that require you to
+ specify a pidfile path.
+
+config BUSYBOX_CONFIG_FEATURE_SUID
+ bool "Support for SUID/SGID handling"
+ default BUSYBOX_DEFAULT_FEATURE_SUID
+ help
+ With this option you can install the busybox binary belonging
+ to root with the suid bit set, enabling some applets to perform
+ root-level operations even when run by ordinary users
+ (for example, mounting of user mounts in fstab needs this).
+
+ Busybox will automatically drop privileges for applets
+ that don't need root access.
+
+ If you are really paranoid and don't want to do this, build two
+ busybox binaries with different applets in them (and the appropriate
+ symlinks pointing to each binary), and only set the suid bit on the
+ one that needs it.
+
+ The applets which require root rights (need suid bit or
+ to be run by root) and will refuse to execute otherwise:
+ crontab, login, passwd, su, vlock, wall.
+
+ The applets which will use root rights if they have them
+ (via suid bit, or because run by root), but would try to work
+ without root right nevertheless:
+ findfs, ping[6], traceroute[6], mount.
+
+ Note that if you DONT select this option, but DO make busybox
+ suid root, ALL applets will run under root, which is a huge
+ security hole (think "cp /some/file /etc/passwd").
+
+config BUSYBOX_CONFIG_FEATURE_SUID_CONFIG
+ bool "Runtime SUID/SGID configuration via /etc/busybox.conf"
+ default BUSYBOX_DEFAULT_FEATURE_SUID_CONFIG
+ depends on BUSYBOX_CONFIG_FEATURE_SUID
+ help
+ Allow the SUID / SGID state of an applet to be determined at runtime
+ by checking /etc/busybox.conf. (This is sort of a poor man's sudo.)
+ The format of this file is as follows:
+
+ APPLET = [Ssx-][Ssx-][x-] [USER.GROUP]
+
+ s: USER or GROUP is allowed to execute APPLET.
+ APPLET will run under USER or GROUP
+ (reagardless of who's running it).
+ S: USER or GROUP is NOT allowed to execute APPLET.
+ APPLET will run under USER or GROUP.
+ This option is not very sensical.
+ x: USER/GROUP/others are allowed to execute APPLET.
+ No UID/GID change will be done when it is run.
+ -: USER/GROUP/others are not allowed to execute APPLET.
+
+ An example might help:
+
+ [SUID]
+ su = ssx root.0 # applet su can be run by anyone and runs with
+ # euid=0/egid=0
+ su = ssx # exactly the same
+
+ mount = sx- root.disk # applet mount can be run by root and members
+ # of group disk (but not anyone else)
+ # and runs with euid=0 (egid is not changed)
+
+ cp = --- # disable applet cp for everyone
+
+ The file has to be owned by user root, group root and has to be
+ writeable only by root:
+ (chown 0.0 /etc/busybox.conf; chmod 600 /etc/busybox.conf)
+ The busybox executable has to be owned by user root, group
+ root and has to be setuid root for this to work:
+ (chown 0.0 /bin/busybox; chmod 4755 /bin/busybox)
+
+ Robert 'sandman' Griebl has more information here:
+ <url: http://www.softforge.de/bb/suid.html >.
+
+config BUSYBOX_CONFIG_FEATURE_SUID_CONFIG_QUIET
+ bool "Suppress warning message if /etc/busybox.conf is not readable"
+ default BUSYBOX_DEFAULT_FEATURE_SUID_CONFIG_QUIET
+ depends on BUSYBOX_CONFIG_FEATURE_SUID_CONFIG
+ help
+ /etc/busybox.conf should be readable by the user needing the SUID,
+ check this option to avoid users to be notified about missing
+ permissions.
+
+config BUSYBOX_CONFIG_SELINUX
+ bool "Support NSA Security Enhanced Linux"
+ default BUSYBOX_DEFAULT_SELINUX
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Enable support for SELinux in applets ls, ps, and id. Also provide
+ the option of compiling in SELinux applets.
+
+ If you do not have a complete SELinux userland installed, this stuff
+ will not compile. Specifially, libselinux 1.28 or better is
+ directly required by busybox. If the installation is located in a
+ non-standard directory, provide it by invoking make as follows:
+ CFLAGS=-I<libselinux-include-path> \
+ LDFLAGS=-L<libselinux-lib-path> \
+ make
+
+ Most people will leave this set to 'N'.
+
+config BUSYBOX_CONFIG_FEATURE_PREFER_APPLETS
+ bool "exec prefers applets"
+ default BUSYBOX_DEFAULT_FEATURE_PREFER_APPLETS
+ help
+ This is an experimental option which directs applets about to
+ call 'exec' to try and find an applicable busybox applet before
+ searching the PATH. This is typically done by exec'ing
+ /proc/self/exe.
+ This may affect shell, find -exec, xargs and similar applets.
+ They will use applets even if /bin/<applet> -> busybox link
+ is missing (or is not a link to busybox). However, this causes
+ problems in chroot jails without mounted /proc and with ps/top
+ (command name can be shown as 'exe' for applets started this way).
+
+config BUSYBOX_CONFIG_BUSYBOX_EXEC_PATH
+ string "Path to BusyBox executable"
+ default BUSYBOX_DEFAULT_BUSYBOX_EXEC_PATH
+ help
+ When Busybox applets need to run other busybox applets, BusyBox
+ sometimes needs to exec() itself. When the /proc filesystem is
+ mounted, /proc/self/exe always points to the currently running
+ executable. If you haven't got /proc, set this to wherever you
+ want to run BusyBox from.
+
+# These are auto-selected by other options
+
+config BUSYBOX_CONFIG_FEATURE_SYSLOG
+ bool #No description makes it a hidden option
+ default BUSYBOX_DEFAULT_FEATURE_SYSLOG
+ #help
+ # This option is auto-selected when you select any applet which may
+ # send its output to syslog. You do not need to select it manually.
+
+config BUSYBOX_CONFIG_FEATURE_HAVE_RPC
+ bool #No description makes it a hidden option
+ default BUSYBOX_DEFAULT_FEATURE_HAVE_RPC
+ #help
+ # This is automatically selected if any of enabled applets need it.
+ # You do not need to select it manually.
+
+endmenu
+
+menu 'Build Options'
+
+config BUSYBOX_CONFIG_STATIC
+ bool "Build BusyBox as a static binary (no shared libs)"
+ default BUSYBOX_DEFAULT_STATIC
+ help
+ If you want to build a static BusyBox binary, which does not
+ use or require any shared libraries, then enable this option.
+ This can cause BusyBox to be considerably larger, so you should
+ leave this option false unless you have a good reason (i.e.
+ your target platform does not support shared libraries, or
+ you are building an initrd which doesn't need anything but
+ BusyBox, etc).
+
+ Most people will leave this set to 'N'.
+
+config BUSYBOX_CONFIG_PIE
+ bool "Build BusyBox as a position independent executable"
+ default BUSYBOX_DEFAULT_PIE
+ depends on !BUSYBOX_CONFIG_STATIC
+ help
+ Hardened code option. PIE binaries are loaded at a different
+ address at each invocation. This has some overhead,
+ particularly on x86-32 which is short on registers.
+
+ Most people will leave this set to 'N'.
+
+config BUSYBOX_CONFIG_NOMMU
+ bool "Force NOMMU build"
+ default BUSYBOX_DEFAULT_NOMMU
+ help
+ Busybox tries to detect whether architecture it is being
+ built against supports MMU or not. If this detection fails,
+ or if you want to build NOMMU version of busybox for testing,
+ you may force NOMMU build here.
+
+ Most people will leave this set to 'N'.
+
+# PIE can be made to work with BUILD_LIBBUSYBOX, but currently
+# build system does not support that
+config BUSYBOX_CONFIG_BUILD_LIBBUSYBOX
+ bool "Build shared libbusybox"
+ default BUSYBOX_DEFAULT_BUILD_LIBBUSYBOX
+ depends on !BUSYBOX_CONFIG_FEATURE_PREFER_APPLETS && !BUSYBOX_CONFIG_PIE && !BUSYBOX_CONFIG_STATIC
+ help
+ Build a shared library libbusybox.so.N.N.N which contains all
+ busybox code.
+
+ This feature allows every applet to be built as a tiny
+ separate executable. Enabling it for "one big busybox binary"
+ approach serves no purpose and increases code size.
+ You should almost certainly say "no" to this.
+
+### config FEATURE_FULL_LIBBUSYBOX
+### bool "Feature-complete libbusybox"
+### default n if !FEATURE_SHARED_BUSYBOX
+### depends on BUILD_LIBBUSYBOX
+### help
+### Build a libbusybox with the complete feature-set, disregarding
+### the actually selected config.
+###
+### Normally, libbusybox will only contain the features which are
+### used by busybox itself. If you plan to write a separate
+### standalone application which uses libbusybox say 'Y'.
+###
+### Note: libbusybox is GPL, not LGPL, and exports no stable API that
+### might act as a copyright barrier. We can and will modify the
+### exported function set between releases (even minor version number
+### changes), and happily break out-of-tree features.
+###
+### Say 'N' if in doubt.
+
+config BUSYBOX_CONFIG_FEATURE_INDIVIDUAL
+ bool "Produce a binary for each applet, linked against libbusybox"
+ default BUSYBOX_DEFAULT_FEATURE_INDIVIDUAL
+ depends on BUSYBOX_CONFIG_BUILD_LIBBUSYBOX
+ help
+ If your CPU architecture doesn't allow for sharing text/rodata
+ sections of running binaries, but allows for runtime dynamic
+ libraries, this option will allow you to reduce memory footprint
+ when you have many different applets running at once.
+
+ If your CPU architecture allows for sharing text/rodata,
+ having single binary is more optimal.
+
+ Each applet will be a tiny program, dynamically linked
+ against libbusybox.so.N.N.N.
+
+ You need to have a working dynamic linker.
+
+config BUSYBOX_CONFIG_FEATURE_SHARED_BUSYBOX
+ bool "Produce additional busybox binary linked against libbusybox"
+ default BUSYBOX_DEFAULT_FEATURE_SHARED_BUSYBOX
+ depends on BUSYBOX_CONFIG_BUILD_LIBBUSYBOX
+ help
+ Build busybox, dynamically linked against libbusybox.so.N.N.N.
+
+ You need to have a working dynamic linker.
+
+### config BUILD_AT_ONCE
+### bool "Compile all sources at once"
+### default n
+### help
+### Normally each source-file is compiled with one invocation of
+### the compiler.
+### If you set this option, all sources are compiled at once.
+### This gives the compiler more opportunities to optimize which can
+### result in smaller and/or faster binaries.
+###
+### Setting this option will consume alot of memory, e.g. if you
+### enable all applets with all features, gcc uses more than 300MB
+### RAM during compilation of busybox.
+###
+### This option is most likely only beneficial for newer compilers
+### such as gcc-4.1 and above.
+###
+### Say 'N' unless you know what you are doing.
+
+config BUSYBOX_CONFIG_LFS
+ bool
+ default BUSYBOX_DEFAULT_LFS
+ help
+ If you want to build BusyBox with large file support, then enable
+ this option. This will have no effect if your kernel or your C
+ library lacks large file support for large files. Some of the
+ programs that can benefit from large file support include dd, gzip,
+ cp, mount, tar, and many others. If you want to access files larger
+ than 2 Gigabytes, enable this option. Otherwise, leave it set to 'N'.
+
+config BUSYBOX_CONFIG_CROSS_COMPILER_PREFIX
+ string "Cross Compiler prefix"
+ default BUSYBOX_DEFAULT_CROSS_COMPILER_PREFIX
+ help
+ If you want to build BusyBox with a cross compiler, then you
+ will need to set this to the cross-compiler prefix, for example,
+ "i386-uclibc-".
+
+ Note that CROSS_COMPILE environment variable or
+ "make CROSS_COMPILE=xxx ..." will override this selection.
+
+ Native builds leave this empty.
+
+config BUSYBOX_CONFIG_SYSROOT
+ string "Path to sysroot"
+ default BUSYBOX_DEFAULT_SYSROOT
+ help
+ If you want to build BusyBox with a cross compiler, then you
+ might also need to specify where /usr/include and /usr/lib
+ will be found.
+
+ For example, BusyBox can be built against an installed
+ Android NDK, platform version 9, for ARM ABI with
+
+ CONFIG_SYSROOT=/opt/android-ndk/platforms/android-9/arch-arm
+
+ Native builds leave this empty.
+
+config BUSYBOX_CONFIG_EXTRA_CFLAGS
+ string "Additional CFLAGS"
+ default BUSYBOX_DEFAULT_EXTRA_CFLAGS
+ help
+ Additional CFLAGS to pass to the compiler verbatim.
+
+config BUSYBOX_CONFIG_EXTRA_LDFLAGS
+ string "Additional LDFLAGS"
+ default BUSYBOX_DEFAULT_EXTRA_LDFLAGS
+ help
+ Additional LDFLAGS to pass to the linker verbatim.
+
+config BUSYBOX_CONFIG_EXTRA_LDLIBS
+ string "Additional LDLIBS"
+ default BUSYBOX_DEFAULT_EXTRA_LDLIBS
+ help
+ Additional LDLIBS to pass to the linker with -l.
+
+endmenu
+
+menu 'Debugging Options'
+
+config BUSYBOX_CONFIG_DEBUG
+ bool "Build BusyBox with extra Debugging symbols"
+ default BUSYBOX_DEFAULT_DEBUG
+ help
+ Say Y here if you wish to examine BusyBox internals while applets are
+ running. This increases the size of the binary considerably, and
+ should only be used when doing development. If you are doing
+ development and want to debug BusyBox, answer Y.
+
+ Most people should answer N.
+
+config BUSYBOX_CONFIG_DEBUG_PESSIMIZE
+ bool "Disable compiler optimizations"
+ default BUSYBOX_DEFAULT_DEBUG_PESSIMIZE
+ depends on BUSYBOX_CONFIG_DEBUG
+ help
+ The compiler's optimization of source code can eliminate and reorder
+ code, resulting in an executable that's hard to understand when
+ stepping through it with a debugger. This switches it off, resulting
+ in a much bigger executable that more closely matches the source
+ code.
+
+config BUSYBOX_CONFIG_UNIT_TEST
+ bool "Build unit tests"
+ default BUSYBOX_DEFAULT_UNIT_TEST
+ help
+ Say Y here if you want to build unit tests (both the framework and
+ test cases) as a Busybox applet. This results in bigger code, so you
+ probably don't want this option in production builds.
+
+config BUSYBOX_CONFIG_WERROR
+ bool "Abort compilation on any warning"
+ default BUSYBOX_DEFAULT_WERROR
+ help
+ Selecting this will add -Werror to gcc command line.
+
+ Most people should answer N.
+
+choice
+ prompt "Additional debugging library"
+ default BUSYBOX_CONFIG_NO_DEBUG_LIB
+ help
+ Using an additional debugging library will make BusyBox become
+ considerable larger and will cause it to run more slowly. You
+ should always leave this option disabled for production use.
+
+ dmalloc support:
+ ----------------
+ This enables compiling with dmalloc ( http://dmalloc.com/ )
+ which is an excellent public domain mem leak and malloc problem
+ detector. To enable dmalloc, before running busybox you will
+ want to properly set your environment, for example:
+ export DMALLOC_OPTIONS=debug=0x34f47d83,inter=100,log=logfile
+ The 'debug=' value is generated using the following command
+ dmalloc -p log-stats -p log-non-free -p log-bad-space \
+ -p log-elapsed-time -p check-fence -p check-heap \
+ -p check-lists -p check-blank -p check-funcs -p realloc-copy \
+ -p allow-free-null
+
+ Electric-fence support:
+ -----------------------
+ This enables compiling with Electric-fence support. Electric
+ fence is another very useful malloc debugging library which uses
+ your computer's virtual memory hardware to detect illegal memory
+ accesses. This support will make BusyBox be considerable larger
+ and run slower, so you should leave this option disabled unless
+ you are hunting a hard to find memory problem.
+
+
+config BUSYBOX_CONFIG_NO_DEBUG_LIB
+ bool "None"
+
+config BUSYBOX_CONFIG_DMALLOC
+ bool "Dmalloc"
+
+config BUSYBOX_CONFIG_EFENCE
+ bool "Electric-fence"
+
+endchoice
+
+endmenu
+
+menu 'Installation Options ("make install" behavior)'
+
+choice
+ prompt "What kind of applet links to install"
+ default BUSYBOX_CONFIG_INSTALL_APPLET_SYMLINKS
+ help
+ Choose what kind of links to applets are created by "make install".
+
+config BUSYBOX_CONFIG_INSTALL_APPLET_SYMLINKS
+ bool "as soft-links"
+ help
+ Install applets as soft-links to the busybox binary. This needs some
+ free inodes on the filesystem, but might help with filesystem
+ generators that can't cope with hard-links.
+
+config BUSYBOX_CONFIG_INSTALL_APPLET_HARDLINKS
+ bool "as hard-links"
+ help
+ Install applets as hard-links to the busybox binary. This might
+ count on a filesystem with few inodes.
+
+config BUSYBOX_CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS
+ bool "as script wrappers"
+ help
+ Install applets as script wrappers that call the busybox binary.
+
+config BUSYBOX_CONFIG_INSTALL_APPLET_DONT
+ bool "not installed"
+ help
+ Do not install applet links. Useful when you plan to use
+ busybox --install for installing links, or plan to use
+ a standalone shell and thus don't need applet links.
+
+endchoice
+
+choice
+ prompt "/bin/sh applet link"
+ default BUSYBOX_CONFIG_INSTALL_SH_APPLET_SYMLINK
+ depends on BUSYBOX_CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS
+ help
+ Choose how you install /bin/sh applet link.
+
+config BUSYBOX_CONFIG_INSTALL_SH_APPLET_SYMLINK
+ bool "as soft-link"
+ help
+ Install /bin/sh applet as soft-link to the busybox binary.
+
+config BUSYBOX_CONFIG_INSTALL_SH_APPLET_HARDLINK
+ bool "as hard-link"
+ help
+ Install /bin/sh applet as hard-link to the busybox binary.
+
+config BUSYBOX_CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER
+ bool "as script wrapper"
+ help
+ Install /bin/sh applet as script wrapper that calls
+ the busybox binary.
+
+endchoice
+
+config BUSYBOX_CONFIG_PREFIX
+ string "BusyBox installation prefix"
+ default BUSYBOX_DEFAULT_PREFIX
+ help
+ Define your directory to install BusyBox files/subdirs in.
+
+endmenu
+
+source package/utils/busybox/config/libbb/Config.in
+
+endmenu
+
+comment "Applets"
+
+source package/utils/busybox/config/archival/Config.in
+source package/utils/busybox/config/coreutils/Config.in
+source package/utils/busybox/config/console-tools/Config.in
+source package/utils/busybox/config/debianutils/Config.in
+source package/utils/busybox/config/editors/Config.in
+source package/utils/busybox/config/findutils/Config.in
+source package/utils/busybox/config/init/Config.in
+source package/utils/busybox/config/loginutils/Config.in
+source package/utils/busybox/config/e2fsprogs/Config.in
+source package/utils/busybox/config/modutils/Config.in
+source package/utils/busybox/config/util-linux/Config.in
+source package/utils/busybox/config/miscutils/Config.in
+source package/utils/busybox/config/networking/Config.in
+source package/utils/busybox/config/printutils/Config.in
+source package/utils/busybox/config/mailutils/Config.in
+source package/utils/busybox/config/procps/Config.in
+source package/utils/busybox/config/runit/Config.in
+source package/utils/busybox/config/selinux/Config.in
+source package/utils/busybox/config/shell/Config.in
+source package/utils/busybox/config/sysklogd/Config.in
diff --git a/package/utils/busybox/config/archival/Config.in b/package/utils/busybox/config/archival/Config.in
new file mode 100644
index 0000000..e977bb4
--- /dev/null
+++ b/package/utils/busybox/config/archival/Config.in
@@ -0,0 +1,372 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Archival Utilities"
+
+config BUSYBOX_CONFIG_FEATURE_SEAMLESS_XZ
+ bool "Make tar, rpm, modprobe etc understand .xz data"
+ default BUSYBOX_DEFAULT_FEATURE_SEAMLESS_XZ
+ help
+ Make tar, rpm, modprobe etc understand .xz data.
+
+config BUSYBOX_CONFIG_FEATURE_SEAMLESS_LZMA
+ bool "Make tar, rpm, modprobe etc understand .lzma data"
+ default BUSYBOX_DEFAULT_FEATURE_SEAMLESS_LZMA
+ help
+ Make tar, rpm, modprobe etc understand .lzma data.
+
+config BUSYBOX_CONFIG_FEATURE_SEAMLESS_BZ2
+ bool "Make tar, rpm, modprobe etc understand .bz2 data"
+ default BUSYBOX_DEFAULT_FEATURE_SEAMLESS_BZ2
+ help
+ Make tar, rpm, modprobe etc understand .bz2 data.
+
+config BUSYBOX_CONFIG_FEATURE_SEAMLESS_GZ
+ bool "Make tar, rpm, modprobe etc understand .gz data"
+ default BUSYBOX_DEFAULT_FEATURE_SEAMLESS_GZ
+ help
+ Make tar, rpm, modprobe etc understand .gz data.
+
+config BUSYBOX_CONFIG_FEATURE_SEAMLESS_Z
+ bool "tar, rpm, modprobe etc understand .Z data"
+ default BUSYBOX_DEFAULT_FEATURE_SEAMLESS_Z
+ help
+ Make tar, rpm, modprobe etc understand .Z data.
+
+config BUSYBOX_CONFIG_AR
+ bool "ar"
+ default BUSYBOX_DEFAULT_AR # needs to be improved to be able to replace binutils ar
+ help
+ ar is an archival utility program used to create, modify, and
+ extract contents from archives. An archive is a single file holding
+ a collection of other files in a structure that makes it possible to
+ retrieve the original individual files (called archive members).
+ The original files' contents, mode (permissions), timestamp, owner,
+ and group are preserved in the archive, and can be restored on
+ extraction.
+
+ The stored filename is limited to 15 characters. (for more information
+ see long filename support).
+ ar has 60 bytes of overheads for every stored file.
+
+ This implementation of ar can extract archives, it cannot create or
+ modify them.
+ On an x86 system, the ar applet adds about 1K.
+
+ Unless you have a specific application which requires ar, you should
+ probably say N here.
+
+config BUSYBOX_CONFIG_FEATURE_AR_LONG_FILENAMES
+ bool "Support for long filenames (not needed for debs)"
+ default BUSYBOX_DEFAULT_FEATURE_AR_LONG_FILENAMES
+ depends on BUSYBOX_CONFIG_AR
+ help
+ By default the ar format can only store the first 15 characters
+ of the filename, this option removes that limitation.
+ It supports the GNU ar long filename method which moves multiple long
+ filenames into a the data section of a new ar entry.
+
+config BUSYBOX_CONFIG_FEATURE_AR_CREATE
+ bool "Support archive creation"
+ default BUSYBOX_DEFAULT_FEATURE_AR_CREATE
+ depends on BUSYBOX_CONFIG_AR
+ help
+ This enables archive creation (-c and -r) with busybox ar.
+config BUSYBOX_CONFIG_UNCOMPRESS
+ bool "uncompress"
+ default BUSYBOX_DEFAULT_UNCOMPRESS
+ help
+ uncompress is used to decompress archives created by compress.
+ Not much used anymore, replaced by gzip/gunzip.
+config BUSYBOX_CONFIG_GUNZIP
+ bool "gunzip"
+ default BUSYBOX_DEFAULT_GUNZIP
+ help
+ gunzip is used to decompress archives created by gzip.
+ You can use the `-t' option to test the integrity of
+ an archive, without decompressing it.
+config BUSYBOX_CONFIG_BUNZIP2
+ bool "bunzip2"
+ default BUSYBOX_DEFAULT_BUNZIP2
+ help
+ bunzip2 is a compression utility using the Burrows-Wheeler block
+ sorting text compression algorithm, and Huffman coding. Compression
+ is generally considerably better than that achieved by more
+ conventional LZ77/LZ78-based compressors, and approaches the
+ performance of the PPM family of statistical compressors.
+
+ Unless you have a specific application which requires bunzip2, you
+ should probably say N here.
+config BUSYBOX_CONFIG_UNLZMA
+ bool "unlzma"
+ default BUSYBOX_DEFAULT_UNLZMA
+ help
+ unlzma is a compression utility using the Lempel-Ziv-Markov chain
+ compression algorithm, and range coding. Compression
+ is generally considerably better than that achieved by the bzip2
+ compressors.
+
+ The BusyBox unlzma applet is limited to decompression only.
+ On an x86 system, this applet adds about 4K.
+
+config BUSYBOX_CONFIG_FEATURE_LZMA_FAST
+ bool "Optimize unlzma for speed"
+ default BUSYBOX_DEFAULT_FEATURE_LZMA_FAST
+ depends on BUSYBOX_CONFIG_UNLZMA
+ help
+ This option reduces decompression time by about 25% at the cost of
+ a 1K bigger binary.
+
+config BUSYBOX_CONFIG_LZMA
+ bool "Provide lzma alias which supports only unpacking"
+ default BUSYBOX_DEFAULT_LZMA
+ depends on BUSYBOX_CONFIG_UNLZMA
+ help
+ Enable this option if you want commands like "lzma -d" to work.
+ IOW: you'll get lzma applet, but it will always require -d option.
+config BUSYBOX_CONFIG_UNXZ
+ bool "unxz"
+ default BUSYBOX_DEFAULT_UNXZ
+ help
+ unxz is a unlzma successor.
+
+config BUSYBOX_CONFIG_XZ
+ bool "Provide xz alias which supports only unpacking"
+ default BUSYBOX_DEFAULT_XZ
+ depends on BUSYBOX_CONFIG_UNXZ
+ help
+ Enable this option if you want commands like "xz -d" to work.
+ IOW: you'll get xz applet, but it will always require -d option.
+config BUSYBOX_CONFIG_BZIP2
+ bool "bzip2"
+ default BUSYBOX_DEFAULT_BZIP2
+ help
+ bzip2 is a compression utility using the Burrows-Wheeler block
+ sorting text compression algorithm, and Huffman coding. Compression
+ is generally considerably better than that achieved by more
+ conventional LZ77/LZ78-based compressors, and approaches the
+ performance of the PPM family of statistical compressors.
+
+ Unless you have a specific application which requires bzip2, you
+ should probably say N here.
+config BUSYBOX_CONFIG_CPIO
+ bool "cpio"
+ default BUSYBOX_DEFAULT_CPIO
+ help
+ cpio is an archival utility program used to create, modify, and
+ extract contents from archives.
+ cpio has 110 bytes of overheads for every stored file.
+
+ This implementation of cpio can extract cpio archives created in the
+ "newc" or "crc" format, it cannot create or modify them.
+
+ Unless you have a specific application which requires cpio, you
+ should probably say N here.
+
+config BUSYBOX_CONFIG_FEATURE_CPIO_O
+ bool "Support for archive creation"
+ default BUSYBOX_DEFAULT_FEATURE_CPIO_O
+ depends on BUSYBOX_CONFIG_CPIO
+ help
+ This implementation of cpio can create cpio archives in the "newc"
+ format only.
+
+config BUSYBOX_CONFIG_FEATURE_CPIO_P
+ bool "Support for passthrough mode"
+ default BUSYBOX_DEFAULT_FEATURE_CPIO_P
+ depends on BUSYBOX_CONFIG_FEATURE_CPIO_O
+ help
+ Passthrough mode. Rarely used.
+config BUSYBOX_CONFIG_DPKG
+ bool "dpkg"
+ default BUSYBOX_DEFAULT_DPKG
+ select BUSYBOX_CONFIG_FEATURE_SEAMLESS_GZ
+ help
+ dpkg is a medium-level tool to install, build, remove and manage
+ Debian packages.
+
+ This implementation of dpkg has a number of limitations,
+ you should use the official dpkg if possible.
+config BUSYBOX_CONFIG_DPKG_DEB
+ bool "dpkg_deb"
+ default BUSYBOX_DEFAULT_DPKG_DEB
+ select BUSYBOX_CONFIG_FEATURE_SEAMLESS_GZ
+ help
+ dpkg-deb unpacks and provides information about Debian archives.
+
+ This implementation of dpkg-deb cannot pack archives.
+
+ Unless you have a specific application which requires dpkg-deb,
+ say N here.
+
+config BUSYBOX_CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY
+ bool "Extract only (-x)"
+ default BUSYBOX_DEFAULT_FEATURE_DPKG_DEB_EXTRACT_ONLY
+ depends on BUSYBOX_CONFIG_DPKG_DEB
+ help
+ This reduces dpkg-deb to the equivalent of
+ "ar -p <deb> data.tar.gz | tar -zx". However it saves space as none
+ of the extra dpkg-deb, ar or tar options are needed, they are linked
+ to internally.
+config BUSYBOX_CONFIG_GZIP
+ bool "gzip"
+ default BUSYBOX_DEFAULT_GZIP
+ help
+ gzip is used to compress files.
+ It's probably the most widely used UNIX compression program.
+
+config BUSYBOX_CONFIG_FEATURE_GZIP_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_GZIP_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_GZIP && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Enable use of long options, increases size by about 106 Bytes
+
+config BUSYBOX_CONFIG_GZIP_FAST
+ int "Trade memory for gzip speed (0:small,slow - 2:fast,big)"
+ default BUSYBOX_DEFAULT_GZIP_FAST
+ range 0 2
+ depends on BUSYBOX_CONFIG_GZIP
+ help
+ Enable big memory options for gzip.
+ 0: small buffers, small hash-tables
+ 1: larger buffers, larger hash-tables
+ 2: larger buffers, largest hash-tables
+ Larger models may give slightly better compression
+config BUSYBOX_CONFIG_LZOP
+ bool "lzop"
+ default BUSYBOX_DEFAULT_LZOP
+ help
+ Lzop compression/decompresion.
+
+config BUSYBOX_CONFIG_LZOP_COMPR_HIGH
+ bool "lzop compression levels 7,8,9 (not very useful)"
+ default BUSYBOX_DEFAULT_LZOP_COMPR_HIGH
+ depends on BUSYBOX_CONFIG_LZOP
+ help
+ High levels (7,8,9) of lzop compression. These levels
+ are actually slower than gzip at equivalent compression ratios
+ and take up 3.2K of code.
+config BUSYBOX_CONFIG_RPM
+ bool "rpm"
+ default BUSYBOX_DEFAULT_RPM
+ help
+ Mini RPM applet - queries and extracts RPM packages.
+config BUSYBOX_CONFIG_RPM2CPIO
+ bool "rpm2cpio"
+ default BUSYBOX_DEFAULT_RPM2CPIO
+ help
+ Converts a RPM file into a CPIO archive.
+config BUSYBOX_CONFIG_TAR
+ bool "tar"
+ default BUSYBOX_DEFAULT_TAR
+ help
+ tar is an archiving program. It's commonly used with gzip to
+ create compressed archives. It's probably the most widely used
+ UNIX archive program.
+
+config BUSYBOX_CONFIG_FEATURE_TAR_CREATE
+ bool "Enable archive creation"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_CREATE
+ depends on BUSYBOX_CONFIG_TAR
+ help
+ If you enable this option you'll be able to create
+ tar archives using the `-c' option.
+
+config BUSYBOX_CONFIG_FEATURE_TAR_AUTODETECT
+ bool "Autodetect compressed tarballs"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_AUTODETECT
+ depends on BUSYBOX_CONFIG_TAR && (BUSYBOX_CONFIG_FEATURE_SEAMLESS_Z || BUSYBOX_CONFIG_FEATURE_SEAMLESS_GZ || BUSYBOX_CONFIG_FEATURE_SEAMLESS_BZ2 || BUSYBOX_CONFIG_FEATURE_SEAMLESS_LZMA || BUSYBOX_CONFIG_FEATURE_SEAMLESS_XZ)
+ help
+ With this option tar can automatically detect compressed
+ tarballs. Currently it works only on files (not pipes etc).
+
+config BUSYBOX_CONFIG_FEATURE_TAR_FROM
+ bool "Enable -X (exclude from) and -T (include from) options)"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_FROM
+ depends on BUSYBOX_CONFIG_TAR
+ help
+ If you enable this option you'll be able to specify
+ a list of files to include or exclude from an archive.
+
+config BUSYBOX_CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY
+ bool "Support for old tar header format"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_OLDGNU_COMPATIBILITY
+ depends on BUSYBOX_CONFIG_TAR || BUSYBOX_CONFIG_DPKG
+ help
+ This option is required to unpack archives created in
+ the old GNU format; help to kill this old format by
+ repacking your ancient archives with the new format.
+
+config BUSYBOX_CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY
+ bool "Enable untarring of tarballs with checksums produced by buggy Sun tar"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_OLDSUN_COMPATIBILITY
+ depends on BUSYBOX_CONFIG_TAR || BUSYBOX_CONFIG_DPKG
+ help
+ This option is required to unpack archives created by some old
+ version of Sun's tar (it was calculating checksum using signed
+ arithmetic). It is said to be fixed in newer Sun tar, but "old"
+ tarballs still exist.
+
+config BUSYBOX_CONFIG_FEATURE_TAR_GNU_EXTENSIONS
+ bool "Support for GNU tar extensions (long filenames)"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_GNU_EXTENSIONS
+ depends on BUSYBOX_CONFIG_TAR || BUSYBOX_CONFIG_DPKG
+ help
+ With this option busybox supports GNU long filenames and
+ linknames.
+
+config BUSYBOX_CONFIG_FEATURE_TAR_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_TAR && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Enable use of long options, increases size by about 400 Bytes
+
+config BUSYBOX_CONFIG_FEATURE_TAR_TO_COMMAND
+ bool "Support for writing to an external program"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_TO_COMMAND
+ depends on BUSYBOX_CONFIG_TAR && BUSYBOX_CONFIG_FEATURE_TAR_LONG_OPTIONS
+ help
+ If you enable this option you'll be able to instruct tar to send
+ the contents of each extracted file to the standard input of an
+ external program.
+
+config BUSYBOX_CONFIG_FEATURE_TAR_UNAME_GNAME
+ bool "Enable use of user and group names"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_UNAME_GNAME
+ depends on BUSYBOX_CONFIG_TAR
+ help
+ Enables use of user and group names in tar. This affects contents
+ listings (-t) and preserving permissions when unpacking (-p).
+ +200 bytes.
+
+config BUSYBOX_CONFIG_FEATURE_TAR_NOPRESERVE_TIME
+ bool "Enable -m (do not preserve time) option"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_NOPRESERVE_TIME
+ depends on BUSYBOX_CONFIG_TAR
+ help
+ With this option busybox supports GNU tar -m
+ (do not preserve time) option.
+
+config BUSYBOX_CONFIG_FEATURE_TAR_SELINUX
+ bool "Support for extracting SELinux labels"
+ default BUSYBOX_DEFAULT_FEATURE_TAR_SELINUX
+ depends on BUSYBOX_CONFIG_TAR && BUSYBOX_CONFIG_SELINUX
+ help
+ With this option busybox supports restoring SELinux labels
+ when extracting files from tar archives.
+config BUSYBOX_CONFIG_UNZIP
+ bool "unzip"
+ default BUSYBOX_DEFAULT_UNZIP
+ help
+ unzip will list or extract files from a ZIP archive,
+ commonly found on DOS/WIN systems. The default behavior
+ (with no options) is to extract the archive into the
+ current directory. Use the `-d' option to extract to a
+ directory of your choice.
+
+endmenu
diff --git a/package/utils/busybox/config/console-tools/Config.in b/package/utils/busybox/config/console-tools/Config.in
new file mode 100644
index 0000000..53937d2
--- /dev/null
+++ b/package/utils/busybox/config/console-tools/Config.in
@@ -0,0 +1,176 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Console Utilities"
+
+
+config BUSYBOX_CONFIG_CHVT
+ bool "chvt"
+ default BUSYBOX_DEFAULT_CHVT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program is used to change to another terminal.
+ Example: chvt 4 (change to terminal /dev/tty4)
+
+config BUSYBOX_CONFIG_FGCONSOLE
+ bool "fgconsole"
+ default BUSYBOX_DEFAULT_FGCONSOLE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program prints active (foreground) console number.
+
+config BUSYBOX_CONFIG_CLEAR
+ bool "clear"
+ default BUSYBOX_DEFAULT_CLEAR
+ help
+ This program clears the terminal screen.
+
+config BUSYBOX_CONFIG_DEALLOCVT
+ bool "deallocvt"
+ default BUSYBOX_DEFAULT_DEALLOCVT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program deallocates unused virtual consoles.
+
+config BUSYBOX_CONFIG_DUMPKMAP
+ bool "dumpkmap"
+ default BUSYBOX_DEFAULT_DUMPKMAP
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program dumps the kernel's keyboard translation table to
+ stdout, in binary format. You can then use loadkmap to load it.
+
+config BUSYBOX_CONFIG_KBD_MODE
+ bool "kbd_mode"
+ default BUSYBOX_DEFAULT_KBD_MODE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program reports and sets keyboard mode.
+
+config BUSYBOX_CONFIG_LOADFONT
+ bool "loadfont"
+ default BUSYBOX_DEFAULT_LOADFONT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program loads a console font from standard input.
+
+config BUSYBOX_CONFIG_LOADKMAP
+ bool "loadkmap"
+ default BUSYBOX_DEFAULT_LOADKMAP
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program loads a keyboard translation table from
+ standard input.
+
+config BUSYBOX_CONFIG_OPENVT
+ bool "openvt"
+ default BUSYBOX_DEFAULT_OPENVT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program is used to start a command on an unused
+ virtual terminal.
+
+config BUSYBOX_CONFIG_RESET
+ bool "reset"
+ default BUSYBOX_DEFAULT_RESET
+ help
+ This program is used to reset the terminal screen, if it
+ gets messed up.
+
+config BUSYBOX_CONFIG_RESIZE
+ bool "resize"
+ default BUSYBOX_DEFAULT_RESIZE
+ help
+ This program is used to (re)set the width and height of your current
+ terminal.
+
+config BUSYBOX_CONFIG_FEATURE_RESIZE_PRINT
+ bool "Print environment variables"
+ default BUSYBOX_DEFAULT_FEATURE_RESIZE_PRINT
+ depends on BUSYBOX_CONFIG_RESIZE
+ help
+ Prints the newly set size (number of columns and rows) of
+ the terminal.
+ E.g.:
+ COLUMNS=80;LINES=44;export COLUMNS LINES;
+
+config BUSYBOX_CONFIG_SETCONSOLE
+ bool "setconsole"
+ default BUSYBOX_DEFAULT_SETCONSOLE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program redirects the system console to another device,
+ like the current tty while logged in via telnet.
+
+config BUSYBOX_CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_SETCONSOLE_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_SETCONSOLE && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the setconsole applet.
+
+config BUSYBOX_CONFIG_SETFONT
+ bool "setfont"
+ default BUSYBOX_DEFAULT_SETFONT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Allows to load console screen map. Useful for i18n.
+
+config BUSYBOX_CONFIG_FEATURE_SETFONT_TEXTUAL_MAP
+ bool "Support reading textual screen maps"
+ default BUSYBOX_DEFAULT_FEATURE_SETFONT_TEXTUAL_MAP
+ depends on BUSYBOX_CONFIG_SETFONT
+ help
+ Support reading textual screen maps.
+
+config BUSYBOX_CONFIG_DEFAULT_SETFONT_DIR
+ string "Default directory for console-tools files"
+ default BUSYBOX_DEFAULT_DEFAULT_SETFONT_DIR
+ depends on BUSYBOX_CONFIG_SETFONT
+ help
+ Directory to use if setfont's params are simple filenames
+ (not /path/to/file or ./file). Default is "" (no default directory).
+
+config BUSYBOX_CONFIG_SETKEYCODES
+ bool "setkeycodes"
+ default BUSYBOX_DEFAULT_SETKEYCODES
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program loads entries into the kernel's scancode-to-keycode
+ map, allowing unusual keyboards to generate usable keycodes.
+
+config BUSYBOX_CONFIG_SETLOGCONS
+ bool "setlogcons"
+ default BUSYBOX_DEFAULT_SETLOGCONS
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This program redirects the output console of kernel messages.
+
+config BUSYBOX_CONFIG_SHOWKEY
+ bool "showkey"
+ default BUSYBOX_DEFAULT_SHOWKEY
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Shows keys pressed.
+
+comment "Common options for loadfont and setfont"
+ depends on BUSYBOX_CONFIG_LOADFONT || BUSYBOX_CONFIG_SETFONT
+
+config BUSYBOX_CONFIG_FEATURE_LOADFONT_PSF2
+ bool "Support for PSF2 console fonts"
+ default BUSYBOX_DEFAULT_FEATURE_LOADFONT_PSF2
+ depends on BUSYBOX_CONFIG_LOADFONT || BUSYBOX_CONFIG_SETFONT
+ help
+ Support PSF2 console fonts.
+
+config BUSYBOX_CONFIG_FEATURE_LOADFONT_RAW
+ bool "Support for old (raw) console fonts"
+ default BUSYBOX_DEFAULT_FEATURE_LOADFONT_RAW
+ depends on BUSYBOX_CONFIG_LOADFONT || BUSYBOX_CONFIG_SETFONT
+ help
+ Support old (raw) console fonts.
+
+endmenu
diff --git a/package/utils/busybox/config/coreutils/Config.in b/package/utils/busybox/config/coreutils/Config.in
new file mode 100644
index 0000000..f50823f
--- /dev/null
+++ b/package/utils/busybox/config/coreutils/Config.in
@@ -0,0 +1,954 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Coreutils"
+
+config BUSYBOX_CONFIG_BASENAME
+ bool "basename"
+ default BUSYBOX_DEFAULT_BASENAME
+ help
+ basename is used to strip the directory and suffix from filenames,
+ leaving just the filename itself. Enable this option if you wish
+ to enable the 'basename' utility.
+config BUSYBOX_CONFIG_CAT
+ bool "cat"
+ default BUSYBOX_DEFAULT_CAT
+ help
+ cat is used to concatenate files and print them to the standard
+ output. Enable this option if you wish to enable the 'cat' utility.
+config BUSYBOX_CONFIG_DATE
+ bool "date"
+ default BUSYBOX_DEFAULT_DATE
+ help
+ date is used to set the system date or display the
+ current time in the given format.
+
+config BUSYBOX_CONFIG_FEATURE_DATE_ISOFMT
+ bool "Enable ISO date format output (-I)"
+ default BUSYBOX_DEFAULT_FEATURE_DATE_ISOFMT
+ depends on BUSYBOX_CONFIG_DATE
+ help
+ Enable option (-I) to output an ISO-8601 compliant
+ date/time string.
+
+# defaults to "no": stat's nanosecond field is a bit non-portable
+config BUSYBOX_CONFIG_FEATURE_DATE_NANO
+ bool "Support %[num]N nanosecond format specifier"
+ default BUSYBOX_DEFAULT_FEATURE_DATE_NANO
+ depends on BUSYBOX_CONFIG_DATE # syscall(__NR_clock_gettime)
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Support %[num]N format specifier. Adds ~250 bytes of code.
+
+config BUSYBOX_CONFIG_FEATURE_DATE_COMPAT
+ bool "Support weird 'date MMDDhhmm[[YY]YY][.ss]' format"
+ default BUSYBOX_DEFAULT_FEATURE_DATE_COMPAT
+ depends on BUSYBOX_CONFIG_DATE
+ help
+ System time can be set by 'date -s DATE' and simply 'date DATE',
+ but formats of DATE string are different. 'date DATE' accepts
+ a rather weird MMDDhhmm[[YY]YY][.ss] format with completely
+ unnatural placement of year between minutes and seconds.
+ date -s (and other commands like touch -d) use more sensible
+ formats (for one, ISO format YYYY-MM-DD hh:mm:ss.ssssss).
+
+ With this option off, 'date DATE' is 'date -s DATE' support
+ the same format. With it on, 'date DATE' additionally supports
+ MMDDhhmm[[YY]YY][.ss] format.
+config BUSYBOX_CONFIG_HOSTID
+ bool "hostid"
+ default BUSYBOX_DEFAULT_HOSTID
+ help
+ hostid prints the numeric identifier (in hexadecimal) for
+ the current host.
+config BUSYBOX_CONFIG_ID
+ bool "id"
+ default BUSYBOX_DEFAULT_ID
+ help
+ id displays the current user and group ID names.
+config BUSYBOX_CONFIG_GROUPS
+ bool "groups"
+ default BUSYBOX_DEFAULT_GROUPS
+ help
+ Print the group names associated with current user id.
+config BUSYBOX_CONFIG_SHUF
+ bool "shuf"
+ default BUSYBOX_DEFAULT_SHUF
+ help
+ Generate random permutations
+config BUSYBOX_CONFIG_TEST
+ bool "test"
+ default BUSYBOX_DEFAULT_TEST
+ help
+ test is used to check file types and compare values,
+ returning an appropriate exit code. The bash shell
+ has test built in, ash can build it in optionally.
+
+config BUSYBOX_CONFIG_FEATURE_TEST_64
+ bool "Extend test to 64 bit"
+ default BUSYBOX_DEFAULT_FEATURE_TEST_64
+ depends on BUSYBOX_CONFIG_TEST || BUSYBOX_CONFIG_ASH_BUILTIN_TEST || BUSYBOX_CONFIG_HUSH
+ help
+ Enable 64-bit support in test.
+config BUSYBOX_CONFIG_TOUCH
+ bool "touch"
+ default BUSYBOX_DEFAULT_TOUCH
+ help
+ touch is used to create or change the access and/or
+ modification timestamp of specified files.
+
+config BUSYBOX_CONFIG_FEATURE_TOUCH_NODEREF
+ bool "Add support for -h"
+ default BUSYBOX_DEFAULT_FEATURE_TOUCH_NODEREF
+ depends on BUSYBOX_CONFIG_TOUCH
+ help
+ Enable touch to have the -h option.
+ This requires libc support for lutimes() function.
+
+config BUSYBOX_CONFIG_FEATURE_TOUCH_SUSV3
+ bool "Add support for SUSV3 features (-d -t -r)"
+ default BUSYBOX_DEFAULT_FEATURE_TOUCH_SUSV3
+ depends on BUSYBOX_CONFIG_TOUCH
+ help
+ Enable touch to use a reference file or a given date/time argument.
+config BUSYBOX_CONFIG_TR
+ bool "tr"
+ default BUSYBOX_DEFAULT_TR
+ help
+ tr is used to squeeze, and/or delete characters from standard
+ input, writing to standard output.
+
+config BUSYBOX_CONFIG_FEATURE_TR_CLASSES
+ bool "Enable character classes (such as [:upper:])"
+ default BUSYBOX_DEFAULT_FEATURE_TR_CLASSES
+ depends on BUSYBOX_CONFIG_TR
+ help
+ Enable character classes, enabling commands such as:
+ tr [:upper:] [:lower:] to convert input into lowercase.
+
+config BUSYBOX_CONFIG_FEATURE_TR_EQUIV
+ bool "Enable equivalence classes"
+ default BUSYBOX_DEFAULT_FEATURE_TR_EQUIV
+ depends on BUSYBOX_CONFIG_TR
+ help
+ Enable equivalence classes, which essentially add the enclosed
+ character to the current set. For instance, tr [=a=] xyz would
+ replace all instances of 'a' with 'xyz'. This option is mainly
+ useful for cases when no other way of expressing a character
+ is possible.
+config BUSYBOX_CONFIG_UNLINK
+ bool "unlink"
+ default BUSYBOX_DEFAULT_UNLINK
+ help
+ unlink deletes a file by calling unlink()
+config BUSYBOX_CONFIG_BASE64
+ bool "base64"
+ default BUSYBOX_DEFAULT_BASE64
+ help
+ Base64 encode and decode
+config BUSYBOX_CONFIG_WHO
+ bool "who"
+ default BUSYBOX_DEFAULT_WHO
+ depends on BUSYBOX_CONFIG_FEATURE_UTMP
+ help
+ who is used to show who is logged on.
+config BUSYBOX_CONFIG_USERS
+ bool "users"
+ default BUSYBOX_DEFAULT_USERS
+ depends on BUSYBOX_CONFIG_FEATURE_UTMP
+ help
+ Print users currently logged on.
+
+config BUSYBOX_CONFIG_CAL
+ bool "cal"
+ default BUSYBOX_DEFAULT_CAL
+ help
+ cal is used to display a monthly calender.
+
+config BUSYBOX_CONFIG_CATV
+ bool "catv"
+ default BUSYBOX_DEFAULT_CATV
+ help
+ Display nonprinting characters as escape sequences (like some
+ implementations' cat -v option).
+
+config BUSYBOX_CONFIG_CHGRP
+ bool "chgrp"
+ default BUSYBOX_DEFAULT_CHGRP
+ help
+ chgrp is used to change the group ownership of files.
+
+config BUSYBOX_CONFIG_CHMOD
+ bool "chmod"
+ default BUSYBOX_DEFAULT_CHMOD
+ help
+ chmod is used to change the access permission of files.
+
+config BUSYBOX_CONFIG_CHOWN
+ bool "chown"
+ default BUSYBOX_DEFAULT_CHOWN
+ help
+ chown is used to change the user and/or group ownership
+ of files.
+
+config BUSYBOX_CONFIG_FEATURE_CHOWN_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_CHOWN_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_CHOWN && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Enable use of long options
+
+config BUSYBOX_CONFIG_CHROOT
+ bool "chroot"
+ default BUSYBOX_DEFAULT_CHROOT
+ help
+ chroot is used to change the root directory and run a command.
+ The default command is `/bin/sh'.
+
+config BUSYBOX_CONFIG_CKSUM
+ bool "cksum"
+ default BUSYBOX_DEFAULT_CKSUM
+ help
+ cksum is used to calculate the CRC32 checksum of a file.
+
+config BUSYBOX_CONFIG_COMM
+ bool "comm"
+ default BUSYBOX_DEFAULT_COMM
+ help
+ comm is used to compare two files line by line and return
+ a three-column output.
+
+config BUSYBOX_CONFIG_CP
+ bool "cp"
+ default BUSYBOX_DEFAULT_CP
+ help
+ cp is used to copy files and directories.
+
+config BUSYBOX_CONFIG_FEATURE_CP_LONG_OPTIONS
+ bool "Enable long options for cp"
+ default BUSYBOX_DEFAULT_FEATURE_CP_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_CP && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Enable long options for cp.
+ Also add support for --parents option.
+
+config BUSYBOX_CONFIG_CUT
+ bool "cut"
+ default BUSYBOX_DEFAULT_CUT
+ help
+ cut is used to print selected parts of lines from
+ each file to stdout.
+
+config BUSYBOX_CONFIG_DD
+ bool "dd"
+ default BUSYBOX_DEFAULT_DD
+ help
+ dd copies a file (from standard input to standard output,
+ by default) using specific input and output blocksizes,
+ while optionally performing conversions on it.
+
+config BUSYBOX_CONFIG_FEATURE_DD_SIGNAL_HANDLING
+ bool "Enable DD signal handling for status reporting"
+ default BUSYBOX_DEFAULT_FEATURE_DD_SIGNAL_HANDLING
+ depends on BUSYBOX_CONFIG_DD
+ help
+ Sending a SIGUSR1 signal to a running `dd' process makes it
+ print to standard error the number of records read and written
+ so far, then to resume copying.
+
+ $ dd if=/dev/zero of=/dev/null&
+ $ pid=$! kill -USR1 $pid; sleep 1; kill $pid
+ 10899206+0 records in
+ 10899206+0 records out
+
+config BUSYBOX_CONFIG_FEATURE_DD_THIRD_STATUS_LINE
+ bool "Enable the third status line upon signal"
+ default BUSYBOX_DEFAULT_FEATURE_DD_THIRD_STATUS_LINE
+ depends on BUSYBOX_CONFIG_DD && BUSYBOX_CONFIG_FEATURE_DD_SIGNAL_HANDLING
+ help
+ Displays a coreutils-like third status line with transferred bytes,
+ elapsed time and speed.
+
+config BUSYBOX_CONFIG_FEATURE_DD_IBS_OBS
+ bool "Enable ibs, obs and conv options"
+ default BUSYBOX_DEFAULT_FEATURE_DD_IBS_OBS
+ depends on BUSYBOX_CONFIG_DD
+ help
+ Enables support for writing a certain number of bytes in and out,
+ at a time, and performing conversions on the data stream.
+
+config BUSYBOX_CONFIG_DF
+ bool "df"
+ default BUSYBOX_DEFAULT_DF
+ help
+ df reports the amount of disk space used and available
+ on filesystems.
+
+config BUSYBOX_CONFIG_FEATURE_DF_FANCY
+ bool "Enable -a, -i, -B"
+ default BUSYBOX_DEFAULT_FEATURE_DF_FANCY
+ depends on BUSYBOX_CONFIG_DF
+ help
+ This option enables -a, -i and -B.
+
+ -a Show all filesystems
+ -i Inodes
+ -B <SIZE> Blocksize
+
+config BUSYBOX_CONFIG_DIRNAME
+ bool "dirname"
+ default BUSYBOX_DEFAULT_DIRNAME
+ help
+ dirname is used to strip a non-directory suffix from
+ a file name.
+
+config BUSYBOX_CONFIG_DOS2UNIX
+ bool "dos2unix/unix2dos"
+ default BUSYBOX_DEFAULT_DOS2UNIX
+ help
+ dos2unix is used to convert a text file from DOS format to
+ UNIX format, and vice versa.
+
+config BUSYBOX_CONFIG_UNIX2DOS
+ bool
+ default BUSYBOX_DEFAULT_UNIX2DOS
+ depends on BUSYBOX_CONFIG_DOS2UNIX
+ help
+ unix2dos is used to convert a text file from UNIX format to
+ DOS format, and vice versa.
+
+config BUSYBOX_CONFIG_DU
+ bool "du (default blocksize of 512 bytes)"
+ default BUSYBOX_DEFAULT_DU
+ help
+ du is used to report the amount of disk space used
+ for specified files.
+
+config BUSYBOX_CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
+ bool "Use a default blocksize of 1024 bytes (1K)"
+ default BUSYBOX_DEFAULT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K
+ depends on BUSYBOX_CONFIG_DU
+ help
+ Use a blocksize of (1K) instead of the default 512b.
+
+config BUSYBOX_CONFIG_ECHO
+ bool "echo (basic SuSv3 version taking no options)"
+ default BUSYBOX_DEFAULT_ECHO
+ help
+ echo is used to print a specified string to stdout.
+
+# this entry also appears in shell/Config.in, next to the echo builtin
+config BUSYBOX_CONFIG_FEATURE_FANCY_ECHO
+ bool "Enable echo options (-n and -e)"
+ default BUSYBOX_DEFAULT_FEATURE_FANCY_ECHO
+ depends on BUSYBOX_CONFIG_ECHO || BUSYBOX_CONFIG_ASH_BUILTIN_ECHO || BUSYBOX_CONFIG_HUSH
+ help
+ This adds options (-n and -e) to echo.
+
+config BUSYBOX_CONFIG_ENV
+ bool "env"
+ default BUSYBOX_DEFAULT_ENV
+ help
+ env is used to set an environment variable and run
+ a command; without options it displays the current
+ environment.
+
+config BUSYBOX_CONFIG_FEATURE_ENV_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_ENV_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_ENV && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the env applet.
+
+config BUSYBOX_CONFIG_EXPAND
+ bool "expand"
+ default BUSYBOX_DEFAULT_EXPAND
+ help
+ By default, convert all tabs to spaces.
+
+config BUSYBOX_CONFIG_FEATURE_EXPAND_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_EXPAND_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_EXPAND && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the expand applet.
+
+config BUSYBOX_CONFIG_EXPR
+ bool "expr"
+ default BUSYBOX_DEFAULT_EXPR
+ help
+ expr is used to calculate numbers and print the result
+ to standard output.
+
+config BUSYBOX_CONFIG_EXPR_MATH_SUPPORT_64
+ bool "Extend Posix numbers support to 64 bit"
+ default BUSYBOX_DEFAULT_EXPR_MATH_SUPPORT_64
+ depends on BUSYBOX_CONFIG_EXPR
+ help
+ Enable 64-bit math support in the expr applet. This will make
+ the applet slightly larger, but will allow computation with very
+ large numbers.
+
+config BUSYBOX_CONFIG_FALSE
+ bool "false"
+ default BUSYBOX_DEFAULT_FALSE
+ help
+ false returns an exit code of FALSE (1).
+
+config BUSYBOX_CONFIG_FOLD
+ bool "fold"
+ default BUSYBOX_DEFAULT_FOLD
+ help
+ Wrap text to fit a specific width.
+
+config BUSYBOX_CONFIG_FSYNC
+ bool "fsync"
+ default BUSYBOX_DEFAULT_FSYNC
+ help
+ fsync is used to flush file-related cached blocks to disk.
+
+config BUSYBOX_CONFIG_HEAD
+ bool "head"
+ default BUSYBOX_DEFAULT_HEAD
+ help
+ head is used to print the first specified number of lines
+ from files.
+
+config BUSYBOX_CONFIG_FEATURE_FANCY_HEAD
+ bool "Enable head options (-c, -q, and -v)"
+ default BUSYBOX_DEFAULT_FEATURE_FANCY_HEAD
+ depends on BUSYBOX_CONFIG_HEAD
+ help
+ This enables the head options (-c, -q, and -v).
+
+config BUSYBOX_CONFIG_INSTALL
+ bool "install"
+ default BUSYBOX_DEFAULT_INSTALL
+ help
+ Copy files and set attributes.
+
+config BUSYBOX_CONFIG_FEATURE_INSTALL_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_INSTALL_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_INSTALL && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the install applet.
+
+####config LENGTH
+#### bool "length"
+#### default y
+#### help
+#### length is used to print out the length of a specified string.
+
+config BUSYBOX_CONFIG_LN
+ bool "ln"
+ default BUSYBOX_DEFAULT_LN
+ help
+ ln is used to create hard or soft links between files.
+
+config BUSYBOX_CONFIG_LOGNAME
+ bool "logname"
+ default BUSYBOX_DEFAULT_LOGNAME
+ help
+ logname is used to print the current user's login name.
+
+config BUSYBOX_CONFIG_LS
+ bool "ls"
+ default BUSYBOX_DEFAULT_LS
+ help
+ ls is used to list the contents of directories.
+
+config BUSYBOX_CONFIG_FEATURE_LS_FILETYPES
+ bool "Enable filetyping options (-p and -F)"
+ default BUSYBOX_DEFAULT_FEATURE_LS_FILETYPES
+ depends on BUSYBOX_CONFIG_LS
+ help
+ Enable the ls options (-p and -F).
+
+config BUSYBOX_CONFIG_FEATURE_LS_FOLLOWLINKS
+ bool "Enable symlinks dereferencing (-L)"
+ default BUSYBOX_DEFAULT_FEATURE_LS_FOLLOWLINKS
+ depends on BUSYBOX_CONFIG_LS
+ help
+ Enable the ls option (-L).
+
+config BUSYBOX_CONFIG_FEATURE_LS_RECURSIVE
+ bool "Enable recursion (-R)"
+ default BUSYBOX_DEFAULT_FEATURE_LS_RECURSIVE
+ depends on BUSYBOX_CONFIG_LS
+ help
+ Enable the ls option (-R).
+
+config BUSYBOX_CONFIG_FEATURE_LS_SORTFILES
+ bool "Sort the file names"
+ default BUSYBOX_DEFAULT_FEATURE_LS_SORTFILES
+ depends on BUSYBOX_CONFIG_LS
+ help
+ Allow ls to sort file names alphabetically.
+
+config BUSYBOX_CONFIG_FEATURE_LS_TIMESTAMPS
+ bool "Show file timestamps"
+ default BUSYBOX_DEFAULT_FEATURE_LS_TIMESTAMPS
+ depends on BUSYBOX_CONFIG_LS
+ help
+ Allow ls to display timestamps for files.
+
+config BUSYBOX_CONFIG_FEATURE_LS_USERNAME
+ bool "Show username/groupnames"
+ default BUSYBOX_DEFAULT_FEATURE_LS_USERNAME
+ depends on BUSYBOX_CONFIG_LS
+ help
+ Allow ls to display username/groupname for files.
+
+config BUSYBOX_CONFIG_FEATURE_LS_COLOR
+ bool "Allow use of color to identify file types"
+ default BUSYBOX_DEFAULT_FEATURE_LS_COLOR
+ depends on BUSYBOX_CONFIG_LS && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ This enables the --color option to ls.
+
+config BUSYBOX_CONFIG_FEATURE_LS_COLOR_IS_DEFAULT
+ bool "Produce colored ls output by default"
+ default BUSYBOX_DEFAULT_FEATURE_LS_COLOR_IS_DEFAULT
+ depends on BUSYBOX_CONFIG_FEATURE_LS_COLOR
+ help
+ Saying yes here will turn coloring on by default,
+ even if no "--color" option is given to the ls command.
+ This is not recommended, since the colors are not
+ configurable, and the output may not be legible on
+ many output screens.
+
+config BUSYBOX_CONFIG_MD5SUM
+ bool "md5sum"
+ default BUSYBOX_DEFAULT_MD5SUM
+ help
+ md5sum is used to print or check MD5 checksums.
+
+config BUSYBOX_CONFIG_MKDIR
+ bool "mkdir"
+ default BUSYBOX_DEFAULT_MKDIR
+ help
+ mkdir is used to create directories with the specified names.
+
+config BUSYBOX_CONFIG_FEATURE_MKDIR_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_MKDIR_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_MKDIR && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the mkdir applet.
+
+config BUSYBOX_CONFIG_MKFIFO
+ bool "mkfifo"
+ default BUSYBOX_DEFAULT_MKFIFO
+ help
+ mkfifo is used to create FIFOs (named pipes).
+ The `mknod' program can also create FIFOs.
+
+config BUSYBOX_CONFIG_MKNOD
+ bool "mknod"
+ default BUSYBOX_DEFAULT_MKNOD
+ help
+ mknod is used to create FIFOs or block/character special
+ files with the specified names.
+
+config BUSYBOX_CONFIG_MV
+ bool "mv"
+ default BUSYBOX_DEFAULT_MV
+ help
+ mv is used to move or rename files or directories.
+
+config BUSYBOX_CONFIG_FEATURE_MV_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_MV_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_MV && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the mv applet.
+
+config BUSYBOX_CONFIG_NICE
+ bool "nice"
+ default BUSYBOX_DEFAULT_NICE
+ help
+ nice runs a program with modified scheduling priority.
+
+config BUSYBOX_CONFIG_NOHUP
+ bool "nohup"
+ default BUSYBOX_DEFAULT_NOHUP
+ help
+ run a command immune to hangups, with output to a non-tty.
+
+config BUSYBOX_CONFIG_OD
+ bool "od"
+ default BUSYBOX_DEFAULT_OD
+ help
+ od is used to dump binary files in octal and other formats.
+
+config BUSYBOX_CONFIG_PRINTENV
+ bool "printenv"
+ default BUSYBOX_DEFAULT_PRINTENV
+ help
+ printenv is used to print all or part of environment.
+
+config BUSYBOX_CONFIG_PRINTF
+ bool "printf"
+ default BUSYBOX_DEFAULT_PRINTF
+ help
+ printf is used to format and print specified strings.
+ It's similar to `echo' except it has more options.
+
+config BUSYBOX_CONFIG_PWD
+ bool "pwd"
+ default BUSYBOX_DEFAULT_PWD
+ help
+ pwd is used to print the current directory.
+
+config BUSYBOX_CONFIG_READLINK
+ bool "readlink"
+ default BUSYBOX_DEFAULT_READLINK
+ help
+ This program reads a symbolic link and returns the name
+ of the file it points to
+
+config BUSYBOX_CONFIG_FEATURE_READLINK_FOLLOW
+ bool "Enable canonicalization by following all symlinks (-f)"
+ default BUSYBOX_DEFAULT_FEATURE_READLINK_FOLLOW
+ depends on BUSYBOX_CONFIG_READLINK
+ help
+ Enable the readlink option (-f).
+
+config BUSYBOX_CONFIG_REALPATH
+ bool "realpath"
+ default BUSYBOX_DEFAULT_REALPATH
+ help
+ Return the canonicalized absolute pathname.
+ This isn't provided by GNU shellutils, but where else does it belong.
+
+config BUSYBOX_CONFIG_RM
+ bool "rm"
+ default BUSYBOX_DEFAULT_RM
+ help
+ rm is used to remove files or directories.
+
+config BUSYBOX_CONFIG_RMDIR
+ bool "rmdir"
+ default BUSYBOX_DEFAULT_RMDIR
+ help
+ rmdir is used to remove empty directories.
+
+config BUSYBOX_CONFIG_FEATURE_RMDIR_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_RMDIR_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_RMDIR && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the rmdir applet, including
+ --ignore-fail-on-non-empty for compatibility with GNU rmdir.
+
+config BUSYBOX_CONFIG_SEQ
+ bool "seq"
+ default BUSYBOX_DEFAULT_SEQ
+ help
+ print a sequence of numbers
+
+config BUSYBOX_CONFIG_SHA1SUM
+ bool "sha1sum"
+ default BUSYBOX_DEFAULT_SHA1SUM
+ help
+ Compute and check SHA1 message digest
+
+config BUSYBOX_CONFIG_SHA256SUM
+ bool "sha256sum"
+ default BUSYBOX_DEFAULT_SHA256SUM
+ help
+ Compute and check SHA256 message digest
+
+config BUSYBOX_CONFIG_SHA512SUM
+ bool "sha512sum"
+ default BUSYBOX_DEFAULT_SHA512SUM
+ help
+ Compute and check SHA512 message digest
+
+config BUSYBOX_CONFIG_SHA3SUM
+ bool "sha3sum"
+ default BUSYBOX_DEFAULT_SHA3SUM
+ help
+ Compute and check SHA3 (512-bit) message digest
+
+config BUSYBOX_CONFIG_SLEEP
+ bool "sleep"
+ default BUSYBOX_DEFAULT_SLEEP
+ help
+ sleep is used to pause for a specified number of seconds.
+ It comes in 3 versions:
+ - small: takes one integer parameter
+ - fancy: takes multiple integer arguments with suffixes:
+ sleep 1d 2h 3m 15s
+ - fancy with fractional numbers:
+ sleep 2.3s 4.5h sleeps for 16202.3 seconds
+ Last one is "the most compatible" with coreutils sleep,
+ but it adds around 1k of code.
+
+config BUSYBOX_CONFIG_FEATURE_FANCY_SLEEP
+ bool "Enable multiple arguments and s/m/h/d suffixes"
+ default BUSYBOX_DEFAULT_FEATURE_FANCY_SLEEP
+ depends on BUSYBOX_CONFIG_SLEEP
+ help
+ Allow sleep to pause for specified minutes, hours, and days.
+
+config BUSYBOX_CONFIG_FEATURE_FLOAT_SLEEP
+ bool "Enable fractional arguments"
+ default BUSYBOX_DEFAULT_FEATURE_FLOAT_SLEEP
+ depends on BUSYBOX_CONFIG_FEATURE_FANCY_SLEEP
+ help
+ Allow for fractional numeric parameters.
+
+config BUSYBOX_CONFIG_SORT
+ bool "sort"
+ default BUSYBOX_DEFAULT_SORT
+ help
+ sort is used to sort lines of text in specified files.
+
+config BUSYBOX_CONFIG_FEATURE_SORT_BIG
+ bool "Full SuSv3 compliant sort (support -ktcsbdfiozgM)"
+ default BUSYBOX_DEFAULT_FEATURE_SORT_BIG
+ depends on BUSYBOX_CONFIG_SORT
+ help
+ Without this, sort only supports -r, -u, and an integer version
+ of -n. Selecting this adds sort keys, floating point support, and
+ more. This adds a little over 3k to a nonstatic build on x86.
+
+ The SuSv3 sort standard is available at:
+ http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html
+
+config BUSYBOX_CONFIG_SPLIT
+ bool "split"
+ default BUSYBOX_DEFAULT_SPLIT
+ help
+ split a file into pieces.
+
+config BUSYBOX_CONFIG_FEATURE_SPLIT_FANCY
+ bool "Fancy extensions"
+ default BUSYBOX_DEFAULT_FEATURE_SPLIT_FANCY
+ depends on BUSYBOX_CONFIG_SPLIT
+ help
+ Add support for features not required by SUSv3.
+ Supports additional suffixes 'b' for 512 bytes,
+ 'g' for 1GiB for the -b option.
+
+config BUSYBOX_CONFIG_STAT
+ bool "stat"
+ default BUSYBOX_DEFAULT_STAT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX # statfs()
+ help
+ display file or filesystem status.
+
+config BUSYBOX_CONFIG_FEATURE_STAT_FORMAT
+ bool "Enable custom formats (-c)"
+ default BUSYBOX_DEFAULT_FEATURE_STAT_FORMAT
+ depends on BUSYBOX_CONFIG_STAT
+ help
+ Without this, stat will not support the '-c format' option where
+ users can pass a custom format string for output. This adds about
+ 7k to a nonstatic build on amd64.
+
+config BUSYBOX_CONFIG_STTY
+ bool "stty"
+ default BUSYBOX_DEFAULT_STTY
+ help
+ stty is used to change and print terminal line settings.
+
+config BUSYBOX_CONFIG_SUM
+ bool "sum"
+ default BUSYBOX_DEFAULT_SUM
+ help
+ checksum and count the blocks in a file
+
+config BUSYBOX_CONFIG_SYNC
+ bool "sync"
+ default BUSYBOX_DEFAULT_SYNC
+ help
+ sync is used to flush filesystem buffers.
+
+config BUSYBOX_CONFIG_TAC
+ bool "tac"
+ default BUSYBOX_DEFAULT_TAC
+ help
+ tac is used to concatenate and print files in reverse.
+
+config BUSYBOX_CONFIG_TAIL
+ bool "tail"
+ default BUSYBOX_DEFAULT_TAIL
+ help
+ tail is used to print the last specified number of lines
+ from files.
+
+config BUSYBOX_CONFIG_FEATURE_FANCY_TAIL
+ bool "Enable extra tail options (-q, -s, -v, and -F)"
+ default BUSYBOX_DEFAULT_FEATURE_FANCY_TAIL
+ depends on BUSYBOX_CONFIG_TAIL
+ help
+ The options (-q, -s, -v and -F) are provided by GNU tail, but
+ are not specific in the SUSv3 standard.
+
+ -q Never output headers giving file names
+ -s SEC Wait SEC seconds between reads with -f
+ -v Always output headers giving file names
+ -F Same as -f, but keep retrying
+
+config BUSYBOX_CONFIG_TEE
+ bool "tee"
+ default BUSYBOX_DEFAULT_TEE
+ help
+ tee is used to read from standard input and write
+ to standard output and files.
+
+config BUSYBOX_CONFIG_FEATURE_TEE_USE_BLOCK_IO
+ bool "Enable block I/O (larger/faster) instead of byte I/O"
+ default BUSYBOX_DEFAULT_FEATURE_TEE_USE_BLOCK_IO
+ depends on BUSYBOX_CONFIG_TEE
+ help
+ Enable this option for a faster tee, at expense of size.
+
+config BUSYBOX_CONFIG_TRUE
+ bool "true"
+ default BUSYBOX_DEFAULT_TRUE
+ help
+ true returns an exit code of TRUE (0).
+
+config BUSYBOX_CONFIG_TTY
+ bool "tty"
+ default BUSYBOX_DEFAULT_TTY
+ help
+ tty is used to print the name of the current terminal to
+ standard output.
+
+config BUSYBOX_CONFIG_UNAME
+ bool "uname"
+ default BUSYBOX_DEFAULT_UNAME
+ help
+ uname is used to print system information.
+
+config BUSYBOX_CONFIG_UNEXPAND
+ bool "unexpand"
+ default BUSYBOX_DEFAULT_UNEXPAND
+ help
+ By default, convert only leading sequences of blanks to tabs.
+
+config BUSYBOX_CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_UNEXPAND_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_UNEXPAND && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the unexpand applet.
+
+config BUSYBOX_CONFIG_UNIQ
+ bool "uniq"
+ default BUSYBOX_DEFAULT_UNIQ
+ help
+ uniq is used to remove duplicate lines from a sorted file.
+
+config BUSYBOX_CONFIG_USLEEP
+ bool "usleep"
+ default BUSYBOX_DEFAULT_USLEEP
+ help
+ usleep is used to pause for a specified number of microseconds.
+
+config BUSYBOX_CONFIG_UUDECODE
+ bool "uudecode"
+ default BUSYBOX_DEFAULT_UUDECODE
+ help
+ uudecode is used to decode a uuencoded file.
+
+config BUSYBOX_CONFIG_UUENCODE
+ bool "uuencode"
+ default BUSYBOX_DEFAULT_UUENCODE
+ help
+ uuencode is used to uuencode a file.
+
+config BUSYBOX_CONFIG_WC
+ bool "wc"
+ default BUSYBOX_DEFAULT_WC
+ help
+ wc is used to print the number of bytes, words, and lines,
+ in specified files.
+
+config BUSYBOX_CONFIG_FEATURE_WC_LARGE
+ bool "Support very large files in wc"
+ default BUSYBOX_DEFAULT_FEATURE_WC_LARGE
+ depends on BUSYBOX_CONFIG_WC
+ help
+ Use "unsigned long long" in wc for counter variables.
+
+config BUSYBOX_CONFIG_WHOAMI
+ bool "whoami"
+ default BUSYBOX_DEFAULT_WHOAMI
+ help
+ whoami is used to print the username of the current
+ user id (same as id -un).
+
+config BUSYBOX_CONFIG_YES
+ bool "yes"
+ default BUSYBOX_DEFAULT_YES
+ help
+ yes is used to repeatedly output a specific string, or
+ the default string `y'.
+
+comment "Common options"
+
+config BUSYBOX_CONFIG_FEATURE_VERBOSE
+ bool "Support verbose options (usually -v) for various applets"
+ default BUSYBOX_DEFAULT_FEATURE_VERBOSE
+ help
+ Enable cp -v, rm -v and similar messages.
+ Also enables long option (--verbose) if it exists.
+ Without this option, -v is accepted but ignored.
+
+comment "Common options for cp and mv"
+ depends on BUSYBOX_CONFIG_CP || BUSYBOX_CONFIG_MV
+
+config BUSYBOX_CONFIG_FEATURE_PRESERVE_HARDLINKS
+ bool "Preserve hard links"
+ default BUSYBOX_DEFAULT_FEATURE_PRESERVE_HARDLINKS
+ depends on BUSYBOX_CONFIG_CP || BUSYBOX_CONFIG_MV
+ help
+ Allow cp and mv to preserve hard links.
+
+comment "Common options for ls, more and telnet"
+ depends on BUSYBOX_CONFIG_LS || BUSYBOX_CONFIG_MORE || BUSYBOX_CONFIG_TELNET
+
+config BUSYBOX_CONFIG_FEATURE_AUTOWIDTH
+ bool "Calculate terminal & column widths"
+ default BUSYBOX_DEFAULT_FEATURE_AUTOWIDTH
+ depends on BUSYBOX_CONFIG_LS || BUSYBOX_CONFIG_MORE || BUSYBOX_CONFIG_TELNET
+ help
+ This option allows utilities such as 'ls', 'more' and 'telnet'
+ to determine the width of the screen, which can allow them to
+ display additional text or avoid wrapping text onto the next line.
+ If you leave this disabled, your utilities will be especially
+ primitive and will be unable to determine the current screen width.
+
+comment "Common options for df, du, ls"
+ depends on BUSYBOX_CONFIG_DF || BUSYBOX_CONFIG_DU || BUSYBOX_CONFIG_LS
+
+config BUSYBOX_CONFIG_FEATURE_HUMAN_READABLE
+ bool "Support for human readable output (example 13k, 23M, 235G)"
+ default BUSYBOX_DEFAULT_FEATURE_HUMAN_READABLE
+ depends on BUSYBOX_CONFIG_DF || BUSYBOX_CONFIG_DU || BUSYBOX_CONFIG_LS
+ help
+ Allow df, du, and ls to have human readable output.
+
+comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum"
+ depends on BUSYBOX_CONFIG_MD5SUM || BUSYBOX_CONFIG_SHA1SUM || BUSYBOX_CONFIG_SHA256SUM || BUSYBOX_CONFIG_SHA512SUM || BUSYBOX_CONFIG_SHA3SUM
+
+config BUSYBOX_CONFIG_FEATURE_MD5_SHA1_SUM_CHECK
+ bool "Enable -c, -s and -w options"
+ default BUSYBOX_DEFAULT_FEATURE_MD5_SHA1_SUM_CHECK
+ depends on BUSYBOX_CONFIG_MD5SUM || BUSYBOX_CONFIG_SHA1SUM || BUSYBOX_CONFIG_SHA256SUM || BUSYBOX_CONFIG_SHA512SUM || BUSYBOX_CONFIG_SHA3SUM
+ help
+ Enabling the -c options allows files to be checked
+ against pre-calculated hash values.
+
+ -s and -w are useful options when verifying checksums.
+
+endmenu
diff --git a/package/utils/busybox/config/debianutils/Config.in b/package/utils/busybox/config/debianutils/Config.in
new file mode 100644
index 0000000..533ad47
--- /dev/null
+++ b/package/utils/busybox/config/debianutils/Config.in
@@ -0,0 +1,85 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Debian Utilities"
+
+
+config BUSYBOX_CONFIG_MKTEMP
+ bool "mktemp"
+ default BUSYBOX_DEFAULT_MKTEMP
+ help
+ mktemp is used to create unique temporary files
+
+config BUSYBOX_CONFIG_PIPE_PROGRESS
+ bool "pipe_progress"
+ default BUSYBOX_DEFAULT_PIPE_PROGRESS
+ help
+ Display a dot to indicate pipe activity.
+
+config BUSYBOX_CONFIG_RUN_PARTS
+ bool "run-parts"
+ default BUSYBOX_DEFAULT_RUN_PARTS
+ help
+ run-parts is a utility designed to run all the scripts in a directory.
+
+ It is useful to set up a directory like cron.daily, where you need to
+ execute all the scripts in that directory.
+
+ In this implementation of run-parts some features (such as report
+ mode) are not implemented.
+
+ Unless you know that run-parts is used in some of your scripts
+ you can safely say N here.
+
+config BUSYBOX_CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_RUN_PARTS_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_RUN_PARTS && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the run-parts applet.
+
+config BUSYBOX_CONFIG_FEATURE_RUN_PARTS_FANCY
+ bool "Support additional arguments"
+ default BUSYBOX_DEFAULT_FEATURE_RUN_PARTS_FANCY
+ depends on BUSYBOX_CONFIG_RUN_PARTS
+ help
+ Support additional options:
+ -l --list print the names of the all matching files (not
+ limited to executables), but don't actually run them.
+
+config BUSYBOX_CONFIG_START_STOP_DAEMON
+ bool "start-stop-daemon"
+ default BUSYBOX_DEFAULT_START_STOP_DAEMON
+ help
+ start-stop-daemon is used to control the creation and
+ termination of system-level processes, usually the ones
+ started during the startup of the system.
+
+config BUSYBOX_CONFIG_FEATURE_START_STOP_DAEMON_FANCY
+ bool "Support additional arguments"
+ default BUSYBOX_DEFAULT_FEATURE_START_STOP_DAEMON_FANCY
+ depends on BUSYBOX_CONFIG_START_STOP_DAEMON
+ help
+ Support additional arguments.
+ -o|--oknodo ignored since we exit with 0 anyway
+ -v|--verbose
+ -N|--nicelevel N
+
+config BUSYBOX_CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_START_STOP_DAEMON_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_START_STOP_DAEMON && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the start-stop-daemon applet.
+
+config BUSYBOX_CONFIG_WHICH
+ bool "which"
+ default BUSYBOX_DEFAULT_WHICH
+ help
+ which is used to find programs in your PATH and
+ print out their pathnames.
+
+endmenu
diff --git a/package/utils/busybox/config/e2fsprogs/Config.in b/package/utils/busybox/config/e2fsprogs/Config.in
new file mode 100644
index 0000000..f826240
--- /dev/null
+++ b/package/utils/busybox/config/e2fsprogs/Config.in
@@ -0,0 +1,71 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Linux Ext2 FS Progs"
+
+
+config BUSYBOX_CONFIG_CHATTR
+ bool "chattr"
+ default BUSYBOX_DEFAULT_CHATTR
+ help
+ chattr changes the file attributes on a second extended file system.
+
+### config E2FSCK
+### bool "e2fsck"
+### default y
+### help
+### e2fsck is used to check Linux second extended file systems (ext2fs).
+### e2fsck also supports ext2 filesystems countaining a journal (ext3).
+### The normal compat symlinks 'fsck.ext2' and 'fsck.ext3' are also
+### provided.
+
+config BUSYBOX_CONFIG_FSCK
+ bool "fsck"
+ default BUSYBOX_DEFAULT_FSCK
+ help
+ fsck is used to check and optionally repair one or more filesystems.
+ In actuality, fsck is simply a front-end for the various file system
+ checkers (fsck.fstype) available under Linux.
+
+config BUSYBOX_CONFIG_LSATTR
+ bool "lsattr"
+ default BUSYBOX_DEFAULT_LSATTR
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ lsattr lists the file attributes on a second extended file system.
+
+### config MKE2FS
+### bool "mke2fs"
+### default y
+### help
+### mke2fs is used to create an ext2/ext3 filesystem. The normal compat
+### symlinks 'mkfs.ext2' and 'mkfs.ext3' are also provided.
+
+config BUSYBOX_CONFIG_TUNE2FS
+ bool "tune2fs"
+ default BUSYBOX_DEFAULT_TUNE2FS # off: it is too limited compared to upstream version
+ help
+ tune2fs allows the system administrator to adjust various tunable
+ filesystem parameters on Linux ext2/ext3 filesystems.
+
+### config E2LABEL
+### bool "e2label"
+### default y
+### depends on TUNE2FS
+### help
+### e2label will display or change the filesystem label on the ext2
+### filesystem located on device.
+
+### NB: this one is now provided by util-linux/volume_id/*
+### config FINDFS
+### bool "findfs"
+### default y
+### depends on TUNE2FS
+### help
+### findfs will search the disks in the system looking for a filesystem
+### which has a label matching label or a UUID equal to uuid.
+
+endmenu
diff --git a/package/utils/busybox/config/e2fsprogs/old_e2fsprogs/Config.in b/package/utils/busybox/config/e2fsprogs/old_e2fsprogs/Config.in
new file mode 100644
index 0000000..d7a5396
--- /dev/null
+++ b/package/utils/busybox/config/e2fsprogs/old_e2fsprogs/Config.in
@@ -0,0 +1,69 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Linux Ext2 FS Progs"
+
+
+config BUSYBOX_CONFIG_CHATTR
+ bool "chattr"
+ default BUSYBOX_DEFAULT_CHATTR
+ help
+ chattr changes the file attributes on a second extended file system.
+
+config BUSYBOX_CONFIG_E2FSCK
+ bool "e2fsck"
+ default BUSYBOX_DEFAULT_E2FSCK
+ help
+ e2fsck is used to check Linux second extended file systems (ext2fs).
+ e2fsck also supports ext2 filesystems countaining a journal (ext3).
+ The normal compat symlinks 'fsck.ext2' and 'fsck.ext3' are also
+ provided.
+
+config BUSYBOX_CONFIG_FSCK
+ bool "fsck"
+ default BUSYBOX_DEFAULT_FSCK
+ help
+ fsck is used to check and optionally repair one or more filesystems.
+ In actuality, fsck is simply a front-end for the various file system
+ checkers (fsck.fstype) available under Linux.
+
+config BUSYBOX_CONFIG_LSATTR
+ bool "lsattr"
+ default BUSYBOX_DEFAULT_LSATTR
+ help
+ lsattr lists the file attributes on a second extended file system.
+
+config BUSYBOX_CONFIG_MKE2FS
+ bool "mke2fs"
+ default BUSYBOX_DEFAULT_MKE2FS
+ help
+ mke2fs is used to create an ext2/ext3 filesystem. The normal compat
+ symlinks 'mkfs.ext2' and 'mkfs.ext3' are also provided.
+
+config BUSYBOX_CONFIG_TUNE2FS
+ bool "tune2fs"
+ default BUSYBOX_DEFAULT_TUNE2FS
+ help
+ tune2fs allows the system administrator to adjust various tunable
+ filesystem parameters on Linux ext2/ext3 filesystems.
+
+config BUSYBOX_CONFIG_E2LABEL
+ bool "e2label"
+ default BUSYBOX_DEFAULT_E2LABEL
+ depends on BUSYBOX_CONFIG_TUNE2FS
+ help
+ e2label will display or change the filesystem label on the ext2
+ filesystem located on device.
+
+config BUSYBOX_CONFIG_FINDFS
+ bool "findfs"
+ default BUSYBOX_DEFAULT_FINDFS
+ depends on BUSYBOX_CONFIG_TUNE2FS
+ help
+ findfs will search the disks in the system looking for a filesystem
+ which has a label matching label or a UUID equal to uuid.
+
+endmenu
diff --git a/package/utils/busybox/config/editors/Config.in b/package/utils/busybox/config/editors/Config.in
new file mode 100644
index 0000000..6ae361f
--- /dev/null
+++ b/package/utils/busybox/config/editors/Config.in
@@ -0,0 +1,234 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Editors"
+
+config BUSYBOX_CONFIG_AWK
+ bool "awk"
+ default BUSYBOX_DEFAULT_AWK
+ help
+ Awk is used as a pattern scanning and processing language. This is
+ the BusyBox implementation of that programming language.
+
+config BUSYBOX_CONFIG_FEATURE_AWK_LIBM
+ bool "Enable math functions (requires libm)"
+ default BUSYBOX_DEFAULT_FEATURE_AWK_LIBM
+ depends on BUSYBOX_CONFIG_AWK
+ help
+ Enable math functions of the Awk programming language.
+ NOTE: This will require libm to be present for linking.
+
+config BUSYBOX_CONFIG_FEATURE_AWK_GNU_EXTENSIONS
+ bool "Enable a few GNU extensions"
+ default BUSYBOX_DEFAULT_FEATURE_AWK_GNU_EXTENSIONS
+ depends on BUSYBOX_CONFIG_AWK
+ help
+ Enable a few features from gawk:
+ * command line option -e AWK_PROGRAM
+ * simultaneous use of -f and -e on the command line.
+ This enables the use of awk library files.
+ Ex: awk -f mylib.awk -e '{print myfunction($1);}' ...
+config BUSYBOX_CONFIG_CMP
+ bool "cmp"
+ default BUSYBOX_DEFAULT_CMP
+ help
+ cmp is used to compare two files and returns the result
+ to standard output.
+config BUSYBOX_CONFIG_DIFF
+ bool "diff"
+ default BUSYBOX_DEFAULT_DIFF
+ help
+ diff compares two files or directories and outputs the
+ differences between them in a form that can be given to
+ the patch command.
+
+config BUSYBOX_CONFIG_FEATURE_DIFF_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_DIFF_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_DIFF && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Enable use of long options.
+
+config BUSYBOX_CONFIG_FEATURE_DIFF_DIR
+ bool "Enable directory support"
+ default BUSYBOX_DEFAULT_FEATURE_DIFF_DIR
+ depends on BUSYBOX_CONFIG_DIFF
+ help
+ This option enables support for directory and subdirectory
+ comparison.
+config BUSYBOX_CONFIG_ED
+ bool "ed"
+ default BUSYBOX_DEFAULT_ED
+ help
+ The original 1970's Unix text editor, from the days of teletypes.
+ Small, simple, evil. Part of SUSv3. If you're not already using
+ this, you don't need it.
+config BUSYBOX_CONFIG_PATCH
+ bool "patch"
+ default BUSYBOX_DEFAULT_PATCH
+ help
+ Apply a unified diff formatted patch.
+config BUSYBOX_CONFIG_SED
+ bool "sed"
+ default BUSYBOX_DEFAULT_SED
+ help
+ sed is used to perform text transformations on a file
+ or input from a pipeline.
+config BUSYBOX_CONFIG_VI
+ bool "vi"
+ default BUSYBOX_DEFAULT_VI
+ help
+ 'vi' is a text editor. More specifically, it is the One True
+ text editor <grin>. It does, however, have a rather steep
+ learning curve. If you are not already comfortable with 'vi'
+ you may wish to use something else.
+
+config BUSYBOX_CONFIG_FEATURE_VI_MAX_LEN
+ int "Maximum screen width in vi"
+ range 256 16384
+ default BUSYBOX_DEFAULT_FEATURE_VI_MAX_LEN
+ depends on BUSYBOX_CONFIG_VI
+ help
+ Contrary to what you may think, this is not eating much.
+ Make it smaller than 4k only if you are very limited on memory.
+
+config BUSYBOX_CONFIG_FEATURE_VI_8BIT
+ bool "Allow vi to display 8-bit chars (otherwise shows dots)"
+ default BUSYBOX_DEFAULT_FEATURE_VI_8BIT
+ depends on BUSYBOX_CONFIG_VI
+ help
+ If your terminal can display characters with high bit set,
+ you may want to enable this. Note: vi is not Unicode-capable.
+ If your terminal combines several 8-bit bytes into one character
+ (as in Unicode mode), this will not work properly.
+
+config BUSYBOX_CONFIG_FEATURE_VI_COLON
+ bool "Enable \":\" colon commands (no \"ex\" mode)"
+ default BUSYBOX_DEFAULT_FEATURE_VI_COLON
+ depends on BUSYBOX_CONFIG_VI
+ help
+ Enable a limited set of colon commands for vi. This does not
+ provide an "ex" mode.
+
+config BUSYBOX_CONFIG_FEATURE_VI_YANKMARK
+ bool "Enable yank/put commands and mark cmds"
+ default BUSYBOX_DEFAULT_FEATURE_VI_YANKMARK
+ depends on BUSYBOX_CONFIG_VI
+ help
+ This will enable you to use yank and put, as well as mark in
+ busybox vi.
+
+config BUSYBOX_CONFIG_FEATURE_VI_SEARCH
+ bool "Enable search and replace cmds"
+ default BUSYBOX_DEFAULT_FEATURE_VI_SEARCH
+ depends on BUSYBOX_CONFIG_VI
+ help
+ Select this if you wish to be able to do search and replace in
+ busybox vi.
+
+config BUSYBOX_CONFIG_FEATURE_VI_REGEX_SEARCH
+ bool "Enable regex in search and replace"
+ default BUSYBOX_DEFAULT_FEATURE_VI_REGEX_SEARCH # Uses GNU regex, which may be unavailable. FIXME
+ depends on BUSYBOX_CONFIG_FEATURE_VI_SEARCH
+ help
+ Use extended regex search.
+
+config BUSYBOX_CONFIG_FEATURE_VI_USE_SIGNALS
+ bool "Catch signals"
+ default BUSYBOX_DEFAULT_FEATURE_VI_USE_SIGNALS
+ depends on BUSYBOX_CONFIG_VI
+ help
+ Selecting this option will make busybox vi signal aware. This will
+ make busybox vi support SIGWINCH to deal with Window Changes, catch
+ Ctrl-Z and Ctrl-C and alarms.
+
+config BUSYBOX_CONFIG_FEATURE_VI_DOT_CMD
+ bool "Remember previous cmd and \".\" cmd"
+ default BUSYBOX_DEFAULT_FEATURE_VI_DOT_CMD
+ depends on BUSYBOX_CONFIG_VI
+ help
+ Make busybox vi remember the last command and be able to repeat it.
+
+config BUSYBOX_CONFIG_FEATURE_VI_READONLY
+ bool "Enable -R option and \"view\" mode"
+ default BUSYBOX_DEFAULT_FEATURE_VI_READONLY
+ depends on BUSYBOX_CONFIG_VI
+ help
+ Enable the read-only command line option, which allows the user to
+ open a file in read-only mode.
+
+config BUSYBOX_CONFIG_FEATURE_VI_SETOPTS
+ bool "Enable set-able options, ai ic showmatch"
+ default BUSYBOX_DEFAULT_FEATURE_VI_SETOPTS
+ depends on BUSYBOX_CONFIG_VI
+ help
+ Enable the editor to set some (ai, ic, showmatch) options.
+
+config BUSYBOX_CONFIG_FEATURE_VI_SET
+ bool "Support for :set"
+ default BUSYBOX_DEFAULT_FEATURE_VI_SET
+ depends on BUSYBOX_CONFIG_VI
+ help
+ Support for ":set".
+
+config BUSYBOX_CONFIG_FEATURE_VI_WIN_RESIZE
+ bool "Handle window resize"
+ default BUSYBOX_DEFAULT_FEATURE_VI_WIN_RESIZE
+ depends on BUSYBOX_CONFIG_VI
+ help
+ Make busybox vi behave nicely with terminals that get resized.
+
+config BUSYBOX_CONFIG_FEATURE_VI_ASK_TERMINAL
+ bool "Use 'tell me cursor position' ESC sequence to measure window"
+ default BUSYBOX_DEFAULT_FEATURE_VI_ASK_TERMINAL
+ depends on BUSYBOX_CONFIG_VI
+ help
+ If terminal size can't be retrieved and $LINES/$COLUMNS are not set,
+ this option makes vi perform a last-ditch effort to find it:
+ position cursor to 999,999 and ask terminal to report real
+ cursor position using "ESC [ 6 n" escape sequence, then read stdin.
+
+ This is not clean but helps a lot on serial lines and such.
+config BUSYBOX_CONFIG_FEATURE_VI_UNDO
+ bool "Support undo command 'u'"
+ default BUSYBOX_DEFAULT_FEATURE_VI_UNDO
+ depends on BUSYBOX_CONFIG_VI
+ help
+ Support the 'u' command to undo insertion, deletion, and replacement
+ of text.
+config BUSYBOX_CONFIG_FEATURE_VI_UNDO_QUEUE
+ bool "Enable undo operation queuing"
+ default BUSYBOX_DEFAULT_FEATURE_VI_UNDO_QUEUE
+ depends on BUSYBOX_CONFIG_FEATURE_VI_UNDO
+ help
+ The vi undo functions can use an intermediate queue to greatly lower
+ malloc() calls and overhead. When the maximum size of this queue is
+ reached, the contents of the queue are committed to the undo stack.
+ This increases the size of the undo code and allows some undo
+ operations (especially un-typing/backspacing) to be far more useful.
+config BUSYBOX_CONFIG_FEATURE_VI_UNDO_QUEUE_MAX
+ int "Maximum undo character queue size"
+ default BUSYBOX_DEFAULT_FEATURE_VI_UNDO_QUEUE_MAX
+ range 32 65536
+ depends on BUSYBOX_CONFIG_FEATURE_VI_UNDO_QUEUE
+ help
+ This option sets the number of bytes used at runtime for the queue.
+ Smaller values will create more undo objects and reduce the amount
+ of typed or backspaced characters that are grouped into one undo
+ operation; larger values increase the potential size of each undo
+ and will generally malloc() larger objects and less frequently.
+ Unless you want more (or less) frequent "undo points" while typing,
+ you should probably leave this unchanged.
+
+config BUSYBOX_CONFIG_FEATURE_ALLOW_EXEC
+ bool "Allow vi and awk to execute shell commands"
+ default BUSYBOX_DEFAULT_FEATURE_ALLOW_EXEC
+ depends on BUSYBOX_CONFIG_VI || BUSYBOX_CONFIG_AWK
+ help
+ Enables vi and awk features which allows user to execute
+ shell commands (using system() C call).
+
+endmenu
diff --git a/package/utils/busybox/config/findutils/Config.in b/package/utils/busybox/config/findutils/Config.in
new file mode 100644
index 0000000..85ee1db
--- /dev/null
+++ b/package/utils/busybox/config/findutils/Config.in
@@ -0,0 +1,269 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Finding Utilities"
+
+config BUSYBOX_CONFIG_FIND
+ bool "find"
+ default BUSYBOX_DEFAULT_FIND
+ help
+ find is used to search your system to find specified files.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_PRINT0
+ bool "Enable -print0: NUL-terminated output"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_PRINT0
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Causes output names to be separated by a NUL character
+ rather than a newline. This allows names that contain
+ newlines and other whitespace to be more easily
+ interpreted by other programs.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_MTIME
+ bool "Enable -mtime: modified time matching"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_MTIME
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Allow searching based on the modification time of
+ files, in days.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_MMIN
+ bool "Enable -mmin: modified time matching by minutes"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_MMIN
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Allow searching based on the modification time of
+ files, in minutes.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_PERM
+ bool "Enable -perm: permissions matching"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_PERM
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Enable searching based on file permissions.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_TYPE
+ bool "Enable -type: file type matching (file/dir/link/...)"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_TYPE
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Enable searching based on file type (file,
+ directory, socket, device, etc.).
+
+config BUSYBOX_CONFIG_FEATURE_FIND_XDEV
+ bool "Enable -xdev: 'stay in filesystem'"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_XDEV
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ This option allows find to restrict searches to a single filesystem.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_MAXDEPTH
+ bool "Enable -mindepth N and -maxdepth N"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_MAXDEPTH
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ This option enables -mindepth N and -maxdepth N option.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_NEWER
+ bool "Enable -newer: compare file modification times"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_NEWER
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Support the 'find -newer' option for finding any files which have
+ modification time that is more recent than the specified FILE.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_INUM
+ bool "Enable -inum: inode number matching"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_INUM
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Support the 'find -inum' option for searching by inode number.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_EXEC
+ bool "Enable -exec: execute commands"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_EXEC
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Support the 'find -exec' option for executing commands based upon
+ the files matched.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_EXEC_PLUS
+ bool "Enable -exec ... {} +"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_EXEC_PLUS
+ depends on BUSYBOX_CONFIG_FEATURE_FIND_EXEC
+ help
+ Support the 'find -exec ... {} +' option for executing commands
+ for all matched files at once.
+ Without this option, -exec + is a synonym for -exec ;
+ (IOW: it works correctly, but without expected speedup)
+
+config BUSYBOX_CONFIG_FEATURE_FIND_USER
+ bool "Enable -user: username/uid matching"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_USER
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Support the 'find -user' option for searching by username or uid.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_GROUP
+ bool "Enable -group: group/gid matching"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_GROUP
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Support the 'find -group' option for searching by group name or gid.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_NOT
+ bool "Enable the 'not' (!) operator"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_NOT
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Support the '!' operator to invert the test results.
+ If 'Enable full-blown desktop' is enabled, then will also support
+ the non-POSIX notation '-not'.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_DEPTH
+ bool "Enable -depth"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_DEPTH
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Process each directory's contents before the directory itself.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_PAREN
+ bool "Enable parens in options"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_PAREN
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Enable usage of parens '(' to specify logical order of arguments.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_SIZE
+ bool "Enable -size: file size matching"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_SIZE
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Support the 'find -size' option for searching by file size.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_PRUNE
+ bool "Enable -prune: exclude subdirectories"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_PRUNE
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ If the file is a directory, dont descend into it. Useful for
+ exclusion .svn and CVS directories.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_DELETE
+ bool "Enable -delete: delete files/dirs"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_DELETE
+ depends on BUSYBOX_CONFIG_FIND && BUSYBOX_CONFIG_FEATURE_FIND_DEPTH
+ help
+ Support the 'find -delete' option for deleting files and directories.
+ WARNING: This option can do much harm if used wrong. Busybox will not
+ try to protect the user from doing stupid things. Use with care.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_PATH
+ bool "Enable -path: match pathname with shell pattern"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_PATH
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ The -path option matches whole pathname instead of just filename.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_REGEX
+ bool "Enable -regex: match pathname with regex"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_REGEX
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ The -regex option matches whole pathname against regular expression.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_CONTEXT
+ bool "Enable -context: security context matching"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_CONTEXT
+ depends on BUSYBOX_CONFIG_FIND && BUSYBOX_CONFIG_SELINUX
+ help
+ Support the 'find -context' option for matching security context.
+
+config BUSYBOX_CONFIG_FEATURE_FIND_LINKS
+ bool "Enable -links: link count matching"
+ default BUSYBOX_DEFAULT_FEATURE_FIND_LINKS
+ depends on BUSYBOX_CONFIG_FIND
+ help
+ Support the 'find -links' option for matching number of links.
+config BUSYBOX_CONFIG_GREP
+ bool "grep"
+ default BUSYBOX_DEFAULT_GREP
+ help
+ grep is used to search files for a specified pattern.
+
+config BUSYBOX_CONFIG_FEATURE_GREP_EGREP_ALIAS
+ bool "Enable extended regular expressions (egrep & grep -E)"
+ default BUSYBOX_DEFAULT_FEATURE_GREP_EGREP_ALIAS
+ depends on BUSYBOX_CONFIG_GREP
+ help
+ Enabled support for extended regular expressions. Extended
+ regular expressions allow for alternation (foo|bar), grouping,
+ and various repetition operators.
+
+config BUSYBOX_CONFIG_FEATURE_GREP_FGREP_ALIAS
+ bool "Alias fgrep to grep -F"
+ default BUSYBOX_DEFAULT_FEATURE_GREP_FGREP_ALIAS
+ depends on BUSYBOX_CONFIG_GREP
+ help
+ fgrep sees the search pattern as a normal string rather than
+ regular expressions.
+ grep -F always works, this just creates the fgrep alias.
+
+config BUSYBOX_CONFIG_FEATURE_GREP_CONTEXT
+ bool "Enable before and after context flags (-A, -B and -C)"
+ default BUSYBOX_DEFAULT_FEATURE_GREP_CONTEXT
+ depends on BUSYBOX_CONFIG_GREP
+ help
+ Print the specified number of leading (-B) and/or trailing (-A)
+ context surrounding our matching lines.
+ Print the specified number of context lines (-C).
+config BUSYBOX_CONFIG_XARGS
+ bool "xargs"
+ default BUSYBOX_DEFAULT_XARGS
+ help
+ xargs is used to execute a specified command for
+ every item from standard input.
+
+config BUSYBOX_CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION
+ bool "Enable -p: prompt and confirmation"
+ default BUSYBOX_DEFAULT_FEATURE_XARGS_SUPPORT_CONFIRMATION
+ depends on BUSYBOX_CONFIG_XARGS
+ help
+ Support -p: prompt the user whether to run each command
+ line and read a line from the terminal.
+
+config BUSYBOX_CONFIG_FEATURE_XARGS_SUPPORT_QUOTES
+ bool "Enable single and double quotes and backslash"
+ default BUSYBOX_DEFAULT_FEATURE_XARGS_SUPPORT_QUOTES
+ depends on BUSYBOX_CONFIG_XARGS
+ help
+ Support quoting in the input.
+
+config BUSYBOX_CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT
+ bool "Enable -x: exit if -s or -n is exceeded"
+ default BUSYBOX_DEFAULT_FEATURE_XARGS_SUPPORT_TERMOPT
+ depends on BUSYBOX_CONFIG_XARGS
+ help
+ Support -x: exit if the command size (see the -s or -n option)
+ is exceeded.
+
+config BUSYBOX_CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM
+ bool "Enable -0: NUL-terminated input"
+ default BUSYBOX_DEFAULT_FEATURE_XARGS_SUPPORT_ZERO_TERM
+ depends on BUSYBOX_CONFIG_XARGS
+ help
+ Support -0: input items are terminated by a NUL character
+ instead of whitespace, and the quotes and backslash
+ are not special.
+
+config BUSYBOX_CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR
+ bool "Enable -I STR: string to replace"
+ default BUSYBOX_DEFAULT_FEATURE_XARGS_SUPPORT_REPL_STR
+ depends on BUSYBOX_CONFIG_XARGS
+ help
+ Support -I STR and -i[STR] options.
+
+endmenu
diff --git a/package/utils/busybox/config/init/Config.in b/package/utils/busybox/config/init/Config.in
new file mode 100644
index 0000000..634207f
--- /dev/null
+++ b/package/utils/busybox/config/init/Config.in
@@ -0,0 +1,184 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Init Utilities"
+
+config BUSYBOX_CONFIG_BOOTCHARTD
+ bool "bootchartd"
+ default BUSYBOX_DEFAULT_BOOTCHARTD
+ help
+ bootchartd is commonly used to profile the boot process
+ for the purpose of speeding it up. In this case, it is started
+ by the kernel as the init process. This is configured by adding
+ the init=/sbin/bootchartd option to the kernel command line.
+
+ It can also be used to monitor the resource usage of a specific
+ application or the running system in general. In this case,
+ bootchartd is started interactively by running bootchartd start
+ and stopped using bootchartd stop.
+
+config BUSYBOX_CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER
+ bool "Compatible, bloated header"
+ default BUSYBOX_DEFAULT_FEATURE_BOOTCHARTD_BLOATED_HEADER
+ depends on BUSYBOX_CONFIG_BOOTCHARTD
+ help
+ Create extended header file compatible with "big" bootchartd.
+ "Big" bootchartd is a shell script and it dumps some
+ "convenient" info int the header, such as:
+ title = Boot chart for `hostname` (`date`)
+ system.uname = `uname -srvm`
+ system.release = `cat /etc/DISTRO-release`
+ system.cpu = `grep '^model name' /proc/cpuinfo | head -1` ($cpucount)
+ system.kernel.options = `cat /proc/cmdline`
+ This data is not mandatory for bootchart graph generation,
+ and is considered bloat. Nevertheless, this option
+ makes bootchartd applet to dump a subset of it.
+
+config BUSYBOX_CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE
+ bool "Support bootchartd.conf"
+ default BUSYBOX_DEFAULT_FEATURE_BOOTCHARTD_CONFIG_FILE
+ depends on BUSYBOX_CONFIG_BOOTCHARTD
+ help
+ Enable reading and parsing of $PWD/bootchartd.conf
+ and /etc/bootchartd.conf files.
+config BUSYBOX_CONFIG_HALT
+ bool "poweroff, halt, and reboot"
+ default BUSYBOX_DEFAULT_HALT
+ help
+ Stop all processes and either halt, reboot, or power off the system.
+
+config BUSYBOX_CONFIG_FEATURE_CALL_TELINIT
+ bool "Call telinit on shutdown and reboot"
+ default BUSYBOX_DEFAULT_FEATURE_CALL_TELINIT
+ depends on BUSYBOX_CONFIG_HALT && !BUSYBOX_CONFIG_INIT
+ help
+ Call an external program (normally telinit) to facilitate
+ a switch to a proper runlevel.
+
+ This option is only available if you selected halt and friends,
+ but did not select init.
+
+config BUSYBOX_CONFIG_TELINIT_PATH
+ string "Path to telinit executable"
+ default BUSYBOX_DEFAULT_TELINIT_PATH
+ depends on BUSYBOX_CONFIG_FEATURE_CALL_TELINIT
+ help
+ When busybox halt and friends have to call external telinit
+ to facilitate proper shutdown, this path is to be used when
+ locating telinit executable.
+config BUSYBOX_CONFIG_INIT
+ bool "init"
+ default BUSYBOX_DEFAULT_INIT
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ init is the first program run when the system boots.
+
+config BUSYBOX_CONFIG_FEATURE_USE_INITTAB
+ bool "Support reading an inittab file"
+ default BUSYBOX_DEFAULT_FEATURE_USE_INITTAB
+ depends on BUSYBOX_CONFIG_INIT
+ help
+ Allow init to read an inittab file when the system boot.
+
+config BUSYBOX_CONFIG_FEATURE_KILL_REMOVED
+ bool "Support killing processes that have been removed from inittab"
+ default BUSYBOX_DEFAULT_FEATURE_KILL_REMOVED
+ depends on BUSYBOX_CONFIG_FEATURE_USE_INITTAB
+ help
+ When respawn entries are removed from inittab and a SIGHUP is
+ sent to init, this option will make init kill the processes
+ that have been removed.
+
+config BUSYBOX_CONFIG_FEATURE_KILL_DELAY
+ int "How long to wait between TERM and KILL (0 - send TERM only)" if FEATURE_KILL_REMOVED
+ range 0 1024
+ default BUSYBOX_DEFAULT_FEATURE_KILL_DELAY
+ depends on BUSYBOX_CONFIG_FEATURE_KILL_REMOVED
+ help
+ With nonzero setting, init sends TERM, forks, child waits N
+ seconds, sends KILL and exits. Setting it too high is unwise
+ (child will hang around for too long and could actually kill
+ the wrong process!)
+
+config BUSYBOX_CONFIG_FEATURE_INIT_SCTTY
+ bool "Run commands with leading dash with controlling tty"
+ default BUSYBOX_DEFAULT_FEATURE_INIT_SCTTY
+ depends on BUSYBOX_CONFIG_INIT
+ help
+ If this option is enabled, init will try to give a controlling
+ tty to any command which has leading hyphen (often it's "-/bin/sh").
+ More precisely, init will do "ioctl(STDIN_FILENO, TIOCSCTTY, 0)".
+ If device attached to STDIN_FILENO can be a ctty but is not yet
+ a ctty for other session, it will become this process' ctty.
+ This is not the traditional init behavour, but is often what you want
+ in an embedded system where the console is only accessed during
+ development or for maintenance.
+ NB: using cttyhack applet may work better.
+
+config BUSYBOX_CONFIG_FEATURE_INIT_SYSLOG
+ bool "Enable init to write to syslog"
+ default BUSYBOX_DEFAULT_FEATURE_INIT_SYSLOG
+ depends on BUSYBOX_CONFIG_INIT
+
+config BUSYBOX_CONFIG_FEATURE_EXTRA_QUIET
+ bool "Be _extra_ quiet on boot"
+ default BUSYBOX_DEFAULT_FEATURE_EXTRA_QUIET
+ depends on BUSYBOX_CONFIG_INIT
+ help
+ Prevent init from logging some messages to the console during boot.
+
+config BUSYBOX_CONFIG_FEATURE_INIT_COREDUMPS
+ bool "Support dumping core for child processes (debugging only)"
+ default BUSYBOX_DEFAULT_FEATURE_INIT_COREDUMPS
+ depends on BUSYBOX_CONFIG_INIT
+ help
+ If this option is enabled and the file /.init_enable_core
+ exists, then init will call setrlimit() to allow unlimited
+ core file sizes. If this option is disabled, processes
+ will not generate any core files.
+
+config BUSYBOX_CONFIG_FEATURE_INITRD
+ bool "Support running init from within an initrd (not initramfs)"
+ default BUSYBOX_DEFAULT_FEATURE_INITRD
+ depends on BUSYBOX_CONFIG_INIT
+ help
+ Legacy support for running init under the old-style initrd. Allows
+ the name linuxrc to act as init, and it doesn't assume init is PID 1.
+
+ This does not apply to initramfs, which runs /init as PID 1 and
+ requires no special support.
+
+config BUSYBOX_CONFIG_INIT_TERMINAL_TYPE
+ string "Initial terminal type"
+ default BUSYBOX_DEFAULT_INIT_TERMINAL_TYPE
+ depends on BUSYBOX_CONFIG_INIT
+ help
+ This is the initial value set by init for the TERM environment
+ variable. This variable is used by programs which make use of
+ extended terminal capabilities.
+
+ Note that on Linux, init attempts to detect serial terminal and
+ sets TERM to "vt102" if one is found.
+config BUSYBOX_CONFIG_MESG
+ bool "mesg"
+ default BUSYBOX_DEFAULT_MESG
+ help
+ Mesg controls access to your terminal by others. It is typically
+ used to allow or disallow other users to write to your terminal
+
+config BUSYBOX_CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP
+ bool "Enable writing to tty only by group, not by everybody"
+ default BUSYBOX_DEFAULT_FEATURE_MESG_ENABLE_ONLY_GROUP
+ depends on BUSYBOX_CONFIG_MESG
+ help
+ Usually, ttys are owned by group "tty", and "write" tool is
+ setgid to this group. This way, "mesg y" only needs to enable
+ "write by owning group" bit in tty mode.
+
+ If you set this option to N, "mesg y" will enable writing
+ by anybody at all. This is not recommended.
+
+endmenu
diff --git a/package/utils/busybox/config/libbb/Config.in b/package/utils/busybox/config/libbb/Config.in
new file mode 100644
index 0000000..e66a15b
--- /dev/null
+++ b/package/utils/busybox/config/libbb/Config.in
@@ -0,0 +1,249 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Busybox Library Tuning"
+
+config BUSYBOX_CONFIG_FEATURE_SYSTEMD
+ bool "Enable systemd support"
+ default BUSYBOX_DEFAULT_FEATURE_SYSTEMD
+ help
+ If you plan to use busybox daemons on a system where daemons
+ are controlled by systemd, enable this option.
+ If you don't use systemd, it is still safe to enable it,
+ but the downside is increased code size.
+config BUSYBOX_CONFIG_FEATURE_RTMINMAX
+ bool "Support RTMIN[+n] and RTMAX[-n] signal names"
+ default BUSYBOX_DEFAULT_FEATURE_RTMINMAX
+ help
+ Support RTMIN[+n] and RTMAX[-n] signal names
+ in kill, killall etc. This costs ~250 bytes.
+
+config BUSYBOX_CONFIG_PASSWORD_MINLEN
+ int "Minimum password length"
+ default BUSYBOX_DEFAULT_PASSWORD_MINLEN
+ range 5 32
+ help
+ Minimum allowable password length.
+
+config BUSYBOX_CONFIG_MD5_SMALL
+ int "MD5: Trade bytes for speed (0:fast, 3:slow)"
+ default BUSYBOX_DEFAULT_MD5_SMALL
+ range 0 3
+ help
+ Trade binary size versus speed for the md5sum algorithm.
+ Approximate values running uClibc and hashing
+ linux-2.4.4.tar.bz2 were:
+ user times (sec) text size (386)
+ 0 (fastest) 1.1 6144
+ 1 1.4 5392
+ 2 3.0 5088
+ 3 (smallest) 5.1 4912
+
+config BUSYBOX_CONFIG_SHA3_SMALL
+ int "SHA3: Trade bytes for speed (0:fast, 1:slow)"
+ default BUSYBOX_DEFAULT_SHA3_SMALL
+ range 0 1
+ help
+ Trade binary size versus speed for the sha3sum algorithm.
+ SHA3_SMALL=0 compared to SHA3_SMALL=1 (approximate):
+ 64-bit x86: +270 bytes of code, 45% faster
+ 32-bit x86: +450 bytes of code, 75% faster
+
+config BUSYBOX_CONFIG_FEATURE_FAST_TOP
+ bool "Faster /proc scanning code (+100 bytes)"
+ default BUSYBOX_DEFAULT_FEATURE_FAST_TOP
+ help
+ This option makes top (and ps) ~20% faster (or 20% less CPU hungry),
+ but code size is slightly bigger.
+
+config BUSYBOX_CONFIG_FEATURE_ETC_NETWORKS
+ bool "Support for /etc/networks"
+ default BUSYBOX_DEFAULT_FEATURE_ETC_NETWORKS
+ help
+ Enable support for network names in /etc/networks. This is
+ a rarely used feature which allows you to use names
+ instead of IP/mask pairs in route command.
+
+config BUSYBOX_CONFIG_FEATURE_USE_TERMIOS
+ bool "Use termios to manipulate the screen"
+ default BUSYBOX_DEFAULT_FEATURE_USE_TERMIOS
+ depends on BUSYBOX_CONFIG_MORE || BUSYBOX_CONFIG_TOP || BUSYBOX_CONFIG_POWERTOP
+ help
+ This option allows utilities such as 'more' and 'top' to determine
+ the size of the screen. If you leave this disabled, your utilities
+ that display things on the screen will be especially primitive and
+ will be unable to determine the current screen size, and will be
+ unable to move the cursor.
+
+config BUSYBOX_CONFIG_FEATURE_EDITING
+ bool "Command line editing"
+ default BUSYBOX_DEFAULT_FEATURE_EDITING
+ help
+ Enable line editing (mainly for shell command line).
+
+config BUSYBOX_CONFIG_FEATURE_EDITING_MAX_LEN
+ int "Maximum length of input"
+ range 128 8192
+ default BUSYBOX_DEFAULT_FEATURE_EDITING_MAX_LEN
+ depends on BUSYBOX_CONFIG_FEATURE_EDITING
+ help
+ Line editing code uses on-stack buffers for storage.
+ You may want to decrease this parameter if your target machine
+ benefits from smaller stack usage.
+
+config BUSYBOX_CONFIG_FEATURE_EDITING_VI
+ bool "vi-style line editing commands"
+ default BUSYBOX_DEFAULT_FEATURE_EDITING_VI
+ depends on BUSYBOX_CONFIG_FEATURE_EDITING
+ help
+ Enable vi-style line editing. In shells, this mode can be
+ turned on and off with "set -o vi" and "set +o vi".
+
+config BUSYBOX_CONFIG_FEATURE_EDITING_HISTORY
+ int "History size"
+ # Don't allow way too big values here, code uses fixed "char *history[N]" struct member
+ range 0 9999
+ default BUSYBOX_DEFAULT_FEATURE_EDITING_HISTORY
+ depends on BUSYBOX_CONFIG_FEATURE_EDITING
+ help
+ Specify command history size (0 - disable).
+
+config BUSYBOX_CONFIG_FEATURE_EDITING_SAVEHISTORY
+ bool "History saving"
+ default BUSYBOX_DEFAULT_FEATURE_EDITING_SAVEHISTORY
+ depends on BUSYBOX_CONFIG_FEATURE_EDITING
+ help
+ Enable history saving in shells.
+
+config BUSYBOX_CONFIG_FEATURE_EDITING_SAVE_ON_EXIT
+ bool "Save history on shell exit, not after every command"
+ default BUSYBOX_DEFAULT_FEATURE_EDITING_SAVE_ON_EXIT
+ depends on BUSYBOX_CONFIG_FEATURE_EDITING_SAVEHISTORY
+ help
+ Save history on shell exit, not after every command.
+
+config BUSYBOX_CONFIG_FEATURE_REVERSE_SEARCH
+ bool "Reverse history search"
+ default BUSYBOX_DEFAULT_FEATURE_REVERSE_SEARCH
+ depends on BUSYBOX_CONFIG_FEATURE_EDITING_SAVEHISTORY
+ help
+ Enable readline-like Ctrl-R combination for reverse history search.
+ Increases code by about 0.5k.
+
+config BUSYBOX_CONFIG_FEATURE_TAB_COMPLETION
+ bool "Tab completion"
+ default BUSYBOX_DEFAULT_FEATURE_TAB_COMPLETION
+ depends on BUSYBOX_CONFIG_FEATURE_EDITING
+ help
+ Enable tab completion.
+
+config BUSYBOX_CONFIG_FEATURE_USERNAME_COMPLETION
+ bool "Username completion"
+ default BUSYBOX_DEFAULT_FEATURE_USERNAME_COMPLETION
+ depends on BUSYBOX_CONFIG_FEATURE_TAB_COMPLETION
+ help
+ Enable username completion.
+
+config BUSYBOX_CONFIG_FEATURE_EDITING_FANCY_PROMPT
+ bool "Fancy shell prompts"
+ default BUSYBOX_DEFAULT_FEATURE_EDITING_FANCY_PROMPT
+ depends on BUSYBOX_CONFIG_FEATURE_EDITING
+ help
+ Setting this option allows for prompts to use things like \w and
+ \$ and escape codes.
+
+config BUSYBOX_CONFIG_FEATURE_EDITING_ASK_TERMINAL
+ bool "Query cursor position from terminal"
+ default BUSYBOX_DEFAULT_FEATURE_EDITING_ASK_TERMINAL
+ depends on BUSYBOX_CONFIG_FEATURE_EDITING
+ help
+ Allow usage of "ESC [ 6 n" sequence. Terminal answers back with
+ current cursor position. This information is used to make line
+ editing more robust in some cases.
+ If you are not sure whether your terminals respond to this code
+ correctly, or want to save on code size (about 400 bytes),
+ then do not turn this option on.
+
+config BUSYBOX_CONFIG_FEATURE_NON_POSIX_CP
+ bool "Non-POSIX, but safer, copying to special nodes"
+ default BUSYBOX_DEFAULT_FEATURE_NON_POSIX_CP
+ help
+ With this option, "cp file symlink" will delete symlink
+ and create a regular file. This does not conform to POSIX,
+ but prevents a symlink attack.
+ Similarly, "cp file device" will not send file's data
+ to the device. (To do that, use "cat file >device")
+
+config BUSYBOX_CONFIG_FEATURE_VERBOSE_CP_MESSAGE
+ bool "Give more precise messages when copy fails (cp, mv etc)"
+ default BUSYBOX_DEFAULT_FEATURE_VERBOSE_CP_MESSAGE
+ help
+ Error messages with this feature enabled:
+ $ cp file /does_not_exist/file
+ cp: cannot create '/does_not_exist/file': Path does not exist
+ $ cp file /vmlinuz/file
+ cp: cannot stat '/vmlinuz/file': Path has non-directory component
+ If this feature is not enabled, they will be, respectively:
+ cp: cannot create '/does_not_exist/file': No such file or directory
+ cp: cannot stat '/vmlinuz/file': Not a directory
+ This will cost you ~60 bytes.
+
+config BUSYBOX_CONFIG_FEATURE_COPYBUF_KB
+ int "Copy buffer size, in kilobytes"
+ range 1 1024
+ default BUSYBOX_DEFAULT_FEATURE_COPYBUF_KB
+ help
+ Size of buffer used by cp, mv, install, wget etc.
+ Buffers which are 4 kb or less will be allocated on stack.
+ Bigger buffers will be allocated with mmap, with fallback to 4 kb
+ stack buffer if mmap fails.
+
+config BUSYBOX_CONFIG_FEATURE_SKIP_ROOTFS
+ bool "Skip rootfs in mount table"
+ default BUSYBOX_DEFAULT_FEATURE_SKIP_ROOTFS
+ help
+ Ignore rootfs entry in mount table.
+
+ In Linux, kernel has a special filesystem, rootfs, which is initially
+ mounted on /. It contains initramfs data, if kernel is configured
+ to have one. Usually, another file system is mounted over / early
+ in boot process, and therefore most tools which manipulate
+ mount table, such as df, will skip rootfs entry.
+
+ However, some systems do not mount anything on /.
+ If you need to configure busybox for one of these systems,
+ you may find it useful to turn this option off to make df show
+ initramfs statistics.
+
+ Otherwise, choose Y.
+
+config BUSYBOX_CONFIG_MONOTONIC_SYSCALL
+ bool "Use clock_gettime(CLOCK_MONOTONIC) syscall"
+ default BUSYBOX_DEFAULT_MONOTONIC_SYSCALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring
+ time intervals (time, ping, traceroute etc need this).
+ Probably requires Linux 2.6+. If not selected, gettimeofday
+ will be used instead (which gives wrong results if date/time
+ is reset).
+
+config BUSYBOX_CONFIG_IOCTL_HEX2STR_ERROR
+ bool "Use ioctl names rather than hex values in error messages"
+ default BUSYBOX_DEFAULT_IOCTL_HEX2STR_ERROR
+ help
+ Use ioctl names rather than hex values in error messages
+ (e.g. VT_DISALLOCATE rather than 0x5608). If disabled this
+ saves about 1400 bytes.
+
+config BUSYBOX_CONFIG_FEATURE_HWIB
+ bool "Support infiniband HW"
+ default BUSYBOX_DEFAULT_FEATURE_HWIB
+ help
+ Support for printing infiniband addresses in
+ network applets.
+
+endmenu
diff --git a/package/utils/busybox/config/loginutils/Config.in b/package/utils/busybox/config/loginutils/Config.in
new file mode 100644
index 0000000..f5ecf6f
--- /dev/null
+++ b/package/utils/busybox/config/loginutils/Config.in
@@ -0,0 +1,342 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Login/Password Management Utilities"
+
+config BUSYBOX_CONFIG_ADD_SHELL
+ bool "add-shell"
+ default BUSYBOX_DEFAULT_ADD_SHELL if BUSYBOX_CONFIG_DESKTOP
+ help
+ Add shells to /etc/shells.
+
+config BUSYBOX_CONFIG_REMOVE_SHELL
+ bool "remove-shell"
+ default BUSYBOX_DEFAULT_REMOVE_SHELL if BUSYBOX_CONFIG_DESKTOP
+ help
+ Remove shells from /etc/shells.
+
+config BUSYBOX_CONFIG_FEATURE_SHADOWPASSWDS
+ bool "Support for shadow passwords"
+ default BUSYBOX_DEFAULT_FEATURE_SHADOWPASSWDS
+ help
+ Build support for shadow password in /etc/shadow. This file is only
+ readable by root and thus the encrypted passwords are no longer
+ publicly readable.
+
+config BUSYBOX_CONFIG_USE_BB_PWD_GRP
+ bool "Use internal password and group functions rather than system functions"
+ default BUSYBOX_DEFAULT_USE_BB_PWD_GRP
+ help
+ If you leave this disabled, busybox will use the system's password
+ and group functions. And if you are using the GNU C library
+ (glibc), you will then need to install the /etc/nsswitch.conf
+ configuration file and the required /lib/libnss_* libraries in
+ order for the password and group functions to work. This generally
+ makes your embedded system quite a bit larger.
+
+ Enabling this option will cause busybox to directly access the
+ system's /etc/password, /etc/group files (and your system will be
+ smaller, and I will get fewer emails asking about how glibc NSS
+ works). When this option is enabled, you will not be able to use
+ PAM to access remote LDAP password servers and whatnot. And if you
+ want hostname resolution to work with glibc, you still need the
+ /lib/libnss_* libraries.
+
+ If you need to use glibc's nsswitch.conf mechanism
+ (e.g. if user/group database is NOT stored in /etc/passwd etc),
+ you must NOT use this option.
+
+ If you enable this option, it will add about 1.5k.
+
+config BUSYBOX_CONFIG_USE_BB_SHADOW
+ bool "Use internal shadow password functions"
+ default BUSYBOX_DEFAULT_USE_BB_SHADOW
+ depends on BUSYBOX_CONFIG_USE_BB_PWD_GRP && BUSYBOX_CONFIG_FEATURE_SHADOWPASSWDS
+ help
+ If you leave this disabled, busybox will use the system's shadow
+ password handling functions. And if you are using the GNU C library
+ (glibc), you will then need to install the /etc/nsswitch.conf
+ configuration file and the required /lib/libnss_* libraries in
+ order for the shadow password functions to work. This generally
+ makes your embedded system quite a bit larger.
+
+ Enabling this option will cause busybox to directly access the
+ system's /etc/shadow file when handling shadow passwords. This
+ makes your system smaller (and I will get fewer emails asking about
+ how glibc NSS works). When this option is enabled, you will not be
+ able to use PAM to access shadow passwords from remote LDAP
+ password servers and whatnot.
+
+config BUSYBOX_CONFIG_USE_BB_CRYPT
+ bool "Use internal crypt functions"
+ default BUSYBOX_DEFAULT_USE_BB_CRYPT
+ help
+ Busybox has internal DES and MD5 crypt functions.
+ They produce results which are identical to corresponding
+ standard C library functions.
+
+ If you leave this disabled, busybox will use the system's
+ crypt functions. Most C libraries use large (~70k)
+ static buffers there, and also combine them with more general
+ DES encryption/decryption.
+
+ For busybox, having large static buffers is undesirable,
+ especially on NOMMU machines. Busybox also doesn't need
+ DES encryption/decryption and can do with smaller code.
+
+ If you enable this option, it will add about 4.8k of code
+ if you are building dynamically linked executable.
+ In static build, it makes code _smaller_ by about 1.2k,
+ and likely many kilobytes less of bss.
+
+config BUSYBOX_CONFIG_USE_BB_CRYPT_SHA
+ bool "Enable SHA256/512 crypt functions"
+ default BUSYBOX_DEFAULT_USE_BB_CRYPT_SHA
+ depends on BUSYBOX_CONFIG_USE_BB_CRYPT
+ help
+ Enable this if you have passwords starting with "$5$" or "$6$"
+ in your /etc/passwd or /etc/shadow files. These passwords
+ are hashed using SHA256 and SHA512 algorithms. Support for them
+ was added to glibc in 2008.
+ With this option off, login will fail password check for any
+ user which has password encrypted with these algorithms.
+
+config BUSYBOX_CONFIG_ADDUSER
+ bool "adduser"
+ default BUSYBOX_DEFAULT_ADDUSER
+ help
+ Utility for creating a new user account.
+
+config BUSYBOX_CONFIG_FEATURE_ADDUSER_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_ADDUSER_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_ADDUSER && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the adduser applet.
+
+config BUSYBOX_CONFIG_FEATURE_CHECK_NAMES
+ bool "Enable sanity check on user/group names in adduser and addgroup"
+ default BUSYBOX_DEFAULT_FEATURE_CHECK_NAMES
+ depends on BUSYBOX_CONFIG_ADDUSER || BUSYBOX_CONFIG_ADDGROUP
+ help
+ Enable sanity check on user and group names in adduser and addgroup.
+ To avoid problems, the user or group name should consist only of
+ letters, digits, underscores, periods, at signs and dashes,
+ and not start with a dash (as defined by IEEE Std 1003.1-2001).
+ For compatibility with Samba machine accounts "$" is also supported
+ at the end of the user or group name.
+
+config BUSYBOX_CONFIG_LAST_ID
+ int "Last valid uid or gid for adduser and addgroup"
+ depends on BUSYBOX_CONFIG_ADDUSER || BUSYBOX_CONFIG_ADDGROUP
+ default BUSYBOX_DEFAULT_LAST_ID
+ help
+ Last valid uid or gid for adduser and addgroup
+
+config BUSYBOX_CONFIG_FIRST_SYSTEM_ID
+ int "First valid system uid or gid for adduser and addgroup"
+ depends on BUSYBOX_CONFIG_ADDUSER || BUSYBOX_CONFIG_ADDGROUP
+ range 0 BUSYBOX_CONFIG_LAST_ID
+ default BUSYBOX_DEFAULT_FIRST_SYSTEM_ID
+ help
+ First valid system uid or gid for adduser and addgroup
+
+config BUSYBOX_CONFIG_LAST_SYSTEM_ID
+ int "Last valid system uid or gid for adduser and addgroup"
+ depends on BUSYBOX_CONFIG_ADDUSER || BUSYBOX_CONFIG_ADDGROUP
+ range BUSYBOX_CONFIG_FIRST_SYSTEM_ID BUSYBOX_CONFIG_LAST_ID
+ default BUSYBOX_DEFAULT_LAST_SYSTEM_ID
+ help
+ Last valid system uid or gid for adduser and addgroup
+
+config BUSYBOX_CONFIG_ADDGROUP
+ bool "addgroup"
+ default BUSYBOX_DEFAULT_ADDGROUP
+ help
+ Utility for creating a new group account.
+
+config BUSYBOX_CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_ADDGROUP_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_ADDGROUP && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the addgroup applet.
+
+config BUSYBOX_CONFIG_FEATURE_ADDUSER_TO_GROUP
+ bool "Support for adding users to groups"
+ default BUSYBOX_DEFAULT_FEATURE_ADDUSER_TO_GROUP
+ depends on BUSYBOX_CONFIG_ADDGROUP
+ help
+ If called with two non-option arguments,
+ addgroup will add an existing user to an
+ existing group.
+
+config BUSYBOX_CONFIG_DELUSER
+ bool "deluser"
+ default BUSYBOX_DEFAULT_DELUSER
+ help
+ Utility for deleting a user account.
+
+config BUSYBOX_CONFIG_DELGROUP
+ bool "delgroup"
+ default BUSYBOX_DEFAULT_DELGROUP
+ help
+ Utility for deleting a group account.
+
+config BUSYBOX_CONFIG_FEATURE_DEL_USER_FROM_GROUP
+ bool "Support for removing users from groups"
+ default BUSYBOX_DEFAULT_FEATURE_DEL_USER_FROM_GROUP
+ depends on BUSYBOX_CONFIG_DELGROUP
+ help
+ If called with two non-option arguments, deluser
+ or delgroup will remove an user from a specified group.
+
+config BUSYBOX_CONFIG_GETTY
+ bool "getty"
+ default BUSYBOX_DEFAULT_GETTY
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ getty lets you log in on a tty. It is normally invoked by init.
+
+ Note that you can save a few bytes by disabling it and
+ using login applet directly.
+ If you need to reset tty attributes before calling login,
+ this script approximates getty:
+
+ exec </dev/$1 >/dev/$1 2>&1 || exit 1
+ reset
+ stty sane; stty ispeed 38400; stty ospeed 38400
+ printf "%s login: " "`hostname`"
+ read -r login
+ exec /bin/login "$login"
+
+config BUSYBOX_CONFIG_LOGIN
+ bool "login"
+ default BUSYBOX_DEFAULT_LOGIN
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ login is used when signing onto a system.
+
+ Note that Busybox binary must be setuid root for this applet to
+ work properly.
+
+config BUSYBOX_CONFIG_LOGIN_SESSION_AS_CHILD
+ bool "Run logged in session in a child process"
+ default BUSYBOX_DEFAULT_LOGIN_SESSION_AS_CHILD if BUSYBOX_CONFIG_PAM
+ depends on BUSYBOX_CONFIG_LOGIN
+ help
+ Run the logged in session in a child process. This allows
+ login to clean up things such as utmp entries or PAM sessions
+ when the login session is complete. If you use PAM, you
+ almost always would want this to be set to Y, else PAM session
+ will not be cleaned up.
+
+config BUSYBOX_CONFIG_LOGIN_SCRIPTS
+ bool "Support for login scripts"
+ depends on BUSYBOX_CONFIG_LOGIN
+ default BUSYBOX_DEFAULT_LOGIN_SCRIPTS
+ help
+ Enable this if you want login to execute $LOGIN_PRE_SUID_SCRIPT
+ just prior to switching from root to logged-in user.
+
+config BUSYBOX_CONFIG_FEATURE_NOLOGIN
+ bool "Support for /etc/nologin"
+ default BUSYBOX_DEFAULT_FEATURE_NOLOGIN
+ depends on BUSYBOX_CONFIG_LOGIN
+ help
+ The file /etc/nologin is used by (some versions of) login(1).
+ If it exists, non-root logins are prohibited.
+
+config BUSYBOX_CONFIG_FEATURE_SECURETTY
+ bool "Support for /etc/securetty"
+ default BUSYBOX_DEFAULT_FEATURE_SECURETTY
+ depends on BUSYBOX_CONFIG_LOGIN
+ help
+ The file /etc/securetty is used by (some versions of) login(1).
+ The file contains the device names of tty lines (one per line,
+ without leading /dev/) on which root is allowed to login.
+
+config BUSYBOX_CONFIG_PASSWD
+ bool "passwd"
+ default BUSYBOX_DEFAULT_PASSWD
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ passwd changes passwords for user and group accounts. A normal user
+ may only change the password for his/her own account, the super user
+ may change the password for any account. The administrator of a group
+ may change the password for the group.
+
+ Note that Busybox binary must be setuid root for this applet to
+ work properly.
+
+config BUSYBOX_CONFIG_FEATURE_PASSWD_WEAK_CHECK
+ bool "Check new passwords for weakness"
+ default BUSYBOX_DEFAULT_FEATURE_PASSWD_WEAK_CHECK
+ depends on BUSYBOX_CONFIG_PASSWD
+ help
+ With this option passwd will refuse new passwords which are "weak".
+
+config BUSYBOX_CONFIG_CRYPTPW
+ bool "cryptpw"
+ default BUSYBOX_DEFAULT_CRYPTPW
+ help
+ Encrypts the given password with the crypt(3) libc function
+ using the given salt. Debian has this utility under mkpasswd
+ name. Busybox provides mkpasswd as an alias for cryptpw.
+
+config BUSYBOX_CONFIG_CHPASSWD
+ bool "chpasswd"
+ default BUSYBOX_DEFAULT_CHPASSWD
+ help
+ Reads a file of user name and password pairs from standard input
+ and uses this information to update a group of existing users.
+
+config BUSYBOX_CONFIG_FEATURE_DEFAULT_PASSWD_ALGO
+ string "Default password encryption method (passwd -a, cryptpw -m parameter)"
+ default BUSYBOX_DEFAULT_FEATURE_DEFAULT_PASSWD_ALGO
+ depends on BUSYBOX_CONFIG_PASSWD || BUSYBOX_CONFIG_CRYPTPW
+ help
+ Possible choices are "d[es]", "m[d5]", "s[ha256]" or "sha512".
+
+config BUSYBOX_CONFIG_SU
+ bool "su"
+ default BUSYBOX_DEFAULT_SU
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ su is used to become another user during a login session.
+ Invoked without a username, su defaults to becoming the super user.
+
+ Note that Busybox binary must be setuid root for this applet to
+ work properly.
+
+config BUSYBOX_CONFIG_FEATURE_SU_SYSLOG
+ bool "Enable su to write to syslog"
+ default BUSYBOX_DEFAULT_FEATURE_SU_SYSLOG
+ depends on BUSYBOX_CONFIG_SU
+
+config BUSYBOX_CONFIG_FEATURE_SU_CHECKS_SHELLS
+ bool "Enable su to check user's shell to be listed in /etc/shells"
+ depends on BUSYBOX_CONFIG_SU
+ default BUSYBOX_DEFAULT_FEATURE_SU_CHECKS_SHELLS
+
+config BUSYBOX_CONFIG_SULOGIN
+ bool "sulogin"
+ default BUSYBOX_DEFAULT_SULOGIN
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ sulogin is invoked when the system goes into single user
+ mode (this is done through an entry in inittab).
+
+config BUSYBOX_CONFIG_VLOCK
+ bool "vlock"
+ default BUSYBOX_DEFAULT_VLOCK
+ help
+ Build the "vlock" applet which allows you to lock (virtual) terminals.
+
+ Note that Busybox binary must be setuid root for this applet to
+ work properly.
+
+endmenu
diff --git a/package/utils/busybox/config/mailutils/Config.in b/package/utils/busybox/config/mailutils/Config.in
new file mode 100644
index 0000000..64b9a2b
--- /dev/null
+++ b/package/utils/busybox/config/mailutils/Config.in
@@ -0,0 +1,55 @@
+# DO NOT EDIT. This file is generated from Config.src
+menu "Mail Utilities"
+
+
+config BUSYBOX_CONFIG_MAKEMIME
+ bool "makemime"
+ default BUSYBOX_DEFAULT_MAKEMIME
+ help
+ Create MIME-formatted messages.
+
+config BUSYBOX_CONFIG_FEATURE_MIME_CHARSET
+ string "Default charset"
+ default BUSYBOX_DEFAULT_FEATURE_MIME_CHARSET
+ depends on BUSYBOX_CONFIG_MAKEMIME || BUSYBOX_CONFIG_REFORMIME || BUSYBOX_CONFIG_SENDMAIL
+ help
+ Default charset of the message.
+
+config BUSYBOX_CONFIG_POPMAILDIR
+ bool "popmaildir"
+ default BUSYBOX_DEFAULT_POPMAILDIR
+ help
+ Simple yet powerful POP3 mail popper. Delivers content
+ of remote mailboxes to local Maildir.
+
+config BUSYBOX_CONFIG_FEATURE_POPMAILDIR_DELIVERY
+ bool "Allow message filters and custom delivery program"
+ default BUSYBOX_DEFAULT_FEATURE_POPMAILDIR_DELIVERY
+ depends on BUSYBOX_CONFIG_POPMAILDIR
+ help
+ Allow to use a custom program to filter the content
+ of the message before actual delivery (-F "prog [args...]").
+ Allow to use a custom program for message actual delivery
+ (-M "prog [args...]").
+
+config BUSYBOX_CONFIG_REFORMIME
+ bool "reformime"
+ default BUSYBOX_DEFAULT_REFORMIME
+ help
+ Parse MIME-formatted messages.
+
+config BUSYBOX_CONFIG_FEATURE_REFORMIME_COMPAT
+ bool "Accept and ignore options other than -x and -X"
+ default BUSYBOX_DEFAULT_FEATURE_REFORMIME_COMPAT
+ depends on BUSYBOX_CONFIG_REFORMIME
+ help
+ Accept (for compatibility only) and ignore options
+ other than -x and -X.
+
+config BUSYBOX_CONFIG_SENDMAIL
+ bool "sendmail"
+ default BUSYBOX_DEFAULT_SENDMAIL
+ help
+ Barebones sendmail.
+
+endmenu
diff --git a/package/utils/busybox/config/miscutils/Config.in b/package/utils/busybox/config/miscutils/Config.in
new file mode 100644
index 0000000..7819e30
--- /dev/null
+++ b/package/utils/busybox/config/miscutils/Config.in
@@ -0,0 +1,760 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Miscellaneous Utilities"
+
+config BUSYBOX_CONFIG_CONSPY
+ bool "conspy"
+ default BUSYBOX_DEFAULT_CONSPY
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ A text-mode VNC like program for Linux virtual terminals.
+ example: conspy NUM shared access to console num
+ or conspy -nd NUM screenshot of console num
+ or conspy -cs NUM poor man's GNU screen like
+config BUSYBOX_CONFIG_CROND
+ bool "crond"
+ default BUSYBOX_DEFAULT_CROND
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ Crond is a background daemon that parses individual crontab
+ files and executes commands on behalf of the users in question.
+ This is a port of dcron from slackware. It uses files of the
+ format /var/spool/cron/crontabs/<username> files, for example:
+ $ cat /var/spool/cron/crontabs/root
+ # Run daily cron jobs at 4:40 every day:
+ 40 4 * * * /etc/cron/daily > /dev/null 2>&1
+
+config BUSYBOX_CONFIG_FEATURE_CROND_D
+ bool "Support option -d to redirect output to stderr"
+ depends on BUSYBOX_CONFIG_CROND
+ default BUSYBOX_DEFAULT_FEATURE_CROND_D
+ help
+ -d N sets loglevel (0:most verbose) and directs all output to stderr.
+
+config BUSYBOX_CONFIG_FEATURE_CROND_CALL_SENDMAIL
+ bool "Report command output via email (using sendmail)"
+ default BUSYBOX_DEFAULT_FEATURE_CROND_CALL_SENDMAIL
+ depends on BUSYBOX_CONFIG_CROND
+ help
+ Command output will be sent to corresponding user via email.
+
+config BUSYBOX_CONFIG_FEATURE_CROND_DIR
+ string "crond spool directory"
+ default BUSYBOX_DEFAULT_FEATURE_CROND_DIR
+ depends on BUSYBOX_CONFIG_CROND || BUSYBOX_CONFIG_CRONTAB
+ help
+ Location of crond spool.
+config BUSYBOX_CONFIG_LESS
+ bool "less"
+ default BUSYBOX_DEFAULT_LESS
+ help
+ 'less' is a pager, meaning that it displays text files. It possesses
+ a wide array of features, and is an improvement over 'more'.
+
+config BUSYBOX_CONFIG_FEATURE_LESS_MAXLINES
+ int "Max number of input lines less will try to eat"
+ default BUSYBOX_DEFAULT_FEATURE_LESS_MAXLINES
+ depends on BUSYBOX_CONFIG_LESS
+
+config BUSYBOX_CONFIG_FEATURE_LESS_BRACKETS
+ bool "Enable bracket searching"
+ default BUSYBOX_DEFAULT_FEATURE_LESS_BRACKETS
+ depends on BUSYBOX_CONFIG_LESS
+ help
+ This option adds the capability to search for matching left and right
+ brackets, facilitating programming.
+
+config BUSYBOX_CONFIG_FEATURE_LESS_FLAGS
+ bool "Enable -m/-M"
+ default BUSYBOX_DEFAULT_FEATURE_LESS_FLAGS
+ depends on BUSYBOX_CONFIG_LESS
+ help
+ The -M/-m flag enables a more sophisticated status line.
+
+config BUSYBOX_CONFIG_FEATURE_LESS_MARKS
+ bool "Enable marks"
+ default BUSYBOX_DEFAULT_FEATURE_LESS_MARKS
+ depends on BUSYBOX_CONFIG_LESS
+ help
+ Marks enable positions in a file to be stored for easy reference.
+
+config BUSYBOX_CONFIG_FEATURE_LESS_REGEXP
+ bool "Enable regular expressions"
+ default BUSYBOX_DEFAULT_FEATURE_LESS_REGEXP
+ depends on BUSYBOX_CONFIG_LESS
+ help
+ Enable regular expressions, allowing complex file searches.
+
+config BUSYBOX_CONFIG_FEATURE_LESS_WINCH
+ bool "Enable automatic resizing on window size changes"
+ default BUSYBOX_DEFAULT_FEATURE_LESS_WINCH
+ depends on BUSYBOX_CONFIG_LESS
+ help
+ Makes less track window size changes.
+
+config BUSYBOX_CONFIG_FEATURE_LESS_ASK_TERMINAL
+ bool "Use 'tell me cursor position' ESC sequence to measure window"
+ default BUSYBOX_DEFAULT_FEATURE_LESS_ASK_TERMINAL
+ depends on BUSYBOX_CONFIG_FEATURE_LESS_WINCH
+ help
+ Makes less track window size changes.
+ If terminal size can't be retrieved and $LINES/$COLUMNS are not set,
+ this option makes less perform a last-ditch effort to find it:
+ position cursor to 999,999 and ask terminal to report real
+ cursor position using "ESC [ 6 n" escape sequence, then read stdin.
+
+ This is not clean but helps a lot on serial lines and such.
+
+config BUSYBOX_CONFIG_FEATURE_LESS_DASHCMD
+ bool "Enable flag changes ('-' command)"
+ default BUSYBOX_DEFAULT_FEATURE_LESS_DASHCMD
+ depends on BUSYBOX_CONFIG_LESS
+ help
+ This enables the ability to change command-line flags within
+ less itself ('-' keyboard command).
+
+config BUSYBOX_CONFIG_FEATURE_LESS_LINENUMS
+ bool "Enable dynamic switching of line numbers"
+ default BUSYBOX_DEFAULT_FEATURE_LESS_LINENUMS
+ depends on BUSYBOX_CONFIG_FEATURE_LESS_DASHCMD
+ help
+ Enables "-N" command.
+config BUSYBOX_CONFIG_NANDWRITE
+ bool "nandwrite"
+ default BUSYBOX_DEFAULT_NANDWRITE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Write to the specified MTD device, with bad blocks awareness
+
+config BUSYBOX_CONFIG_NANDDUMP
+ bool "nanddump"
+ default BUSYBOX_DEFAULT_NANDDUMP
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Dump the content of raw NAND chip
+config BUSYBOX_CONFIG_RFKILL
+ bool "rfkill"
+ default BUSYBOX_DEFAULT_RFKILL # doesn't build on Ubuntu 9.04
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Enable/disable wireless devices.
+
+ rfkill list : list all wireless devices
+ rfkill list bluetooth : list all bluetooth devices
+ rfkill list 1 : list device corresponding to the given index
+ rfkill block|unblock wlan : block/unblock all wlan(wifi) devices
+
+config BUSYBOX_CONFIG_SETSERIAL
+ bool "setserial"
+ default BUSYBOX_DEFAULT_SETSERIAL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Retrieve or set Linux serial port.
+config BUSYBOX_CONFIG_TASKSET
+ bool "taskset"
+ default BUSYBOX_DEFAULT_TASKSET # doesn't build on some non-x86 targets (m68k)
+ help
+ Retrieve or set a processes's CPU affinity.
+ This requires sched_{g,s}etaffinity support in your libc.
+
+config BUSYBOX_CONFIG_FEATURE_TASKSET_FANCY
+ bool "Fancy output"
+ default BUSYBOX_DEFAULT_FEATURE_TASKSET_FANCY
+ depends on BUSYBOX_CONFIG_TASKSET
+ help
+ Add code for fancy output. This merely silences a compiler-warning
+ and adds about 135 Bytes. May be needed for machines with alot
+ of CPUs.
+config BUSYBOX_CONFIG_UBIATTACH
+ bool "ubiattach"
+ default BUSYBOX_DEFAULT_UBIATTACH
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Attach MTD device to an UBI device.
+
+config BUSYBOX_CONFIG_UBIDETACH
+ bool "ubidetach"
+ default BUSYBOX_DEFAULT_UBIDETACH
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Detach MTD device from an UBI device.
+
+config BUSYBOX_CONFIG_UBIMKVOL
+ bool "ubimkvol"
+ default BUSYBOX_DEFAULT_UBIMKVOL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Create a UBI volume.
+
+config BUSYBOX_CONFIG_UBIRMVOL
+ bool "ubirmvol"
+ default BUSYBOX_DEFAULT_UBIRMVOL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Delete a UBI volume.
+
+config BUSYBOX_CONFIG_UBIRSVOL
+ bool "ubirsvol"
+ default BUSYBOX_DEFAULT_UBIRSVOL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Resize a UBI volume.
+
+config BUSYBOX_CONFIG_UBIUPDATEVOL
+ bool "ubiupdatevol"
+ default BUSYBOX_DEFAULT_UBIUPDATEVOL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Update a UBI volume.
+config BUSYBOX_CONFIG_WALL
+ bool "wall"
+ default BUSYBOX_DEFAULT_WALL
+ depends on BUSYBOX_CONFIG_FEATURE_UTMP
+ help
+ Write a message to all users that are logged in.
+
+config BUSYBOX_CONFIG_ADJTIMEX
+ bool "adjtimex"
+ default BUSYBOX_DEFAULT_ADJTIMEX
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Adjtimex reads and optionally sets adjustment parameters for
+ the Linux clock adjustment algorithm.
+
+config BUSYBOX_CONFIG_BBCONFIG
+ bool "bbconfig"
+ default BUSYBOX_DEFAULT_BBCONFIG
+ help
+ The bbconfig applet will print the config file with which
+ busybox was built.
+
+config BUSYBOX_CONFIG_FEATURE_COMPRESS_BBCONFIG
+ bool "Compress bbconfig data"
+ default BUSYBOX_DEFAULT_FEATURE_COMPRESS_BBCONFIG
+ depends on BUSYBOX_CONFIG_BBCONFIG
+ help
+ Store bbconfig data in compressed form, uncompress them on-the-fly
+ before output.
+
+ If you have a really tiny busybox with few applets enabled (and
+ bunzip2 isn't one of them), the overhead of the decompressor might
+ be noticeable. Also, if you run executables directly from ROM
+ and have very little memory, this might not be a win. Otherwise,
+ you probably want this.
+
+config BUSYBOX_CONFIG_BEEP
+ bool "beep"
+ default BUSYBOX_DEFAULT_BEEP
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The beep applets beeps in a given freq/Hz.
+
+config BUSYBOX_CONFIG_FEATURE_BEEP_FREQ
+ int "default frequency"
+ range 0 2147483647
+ default BUSYBOX_DEFAULT_FEATURE_BEEP_FREQ
+ depends on BUSYBOX_CONFIG_BEEP
+ help
+ Frequency for default beep.
+
+config BUSYBOX_CONFIG_FEATURE_BEEP_LENGTH_MS
+ int "default length"
+ range 0 2147483647
+ default BUSYBOX_DEFAULT_FEATURE_BEEP_LENGTH_MS
+ depends on BUSYBOX_CONFIG_BEEP
+ help
+ Length in ms for default beep.
+
+config BUSYBOX_CONFIG_CHAT
+ bool "chat"
+ default BUSYBOX_DEFAULT_CHAT
+ help
+ Simple chat utility.
+
+config BUSYBOX_CONFIG_FEATURE_CHAT_NOFAIL
+ bool "Enable NOFAIL expect strings"
+ depends on BUSYBOX_CONFIG_CHAT
+ default BUSYBOX_DEFAULT_FEATURE_CHAT_NOFAIL
+ help
+ When enabled expect strings which are started with a dash trigger
+ no-fail mode. That is when expectation is not met within timeout
+ the script is not terminated but sends next SEND string and waits
+ for next EXPECT string. This allows to compose far more flexible
+ scripts.
+
+config BUSYBOX_CONFIG_FEATURE_CHAT_TTY_HIFI
+ bool "Force STDIN to be a TTY"
+ depends on BUSYBOX_CONFIG_CHAT
+ default BUSYBOX_DEFAULT_FEATURE_CHAT_TTY_HIFI
+ help
+ Original chat always treats STDIN as a TTY device and sets for it
+ so-called raw mode. This option turns on such behaviour.
+
+config BUSYBOX_CONFIG_FEATURE_CHAT_IMPLICIT_CR
+ bool "Enable implicit Carriage Return"
+ depends on BUSYBOX_CONFIG_CHAT
+ default BUSYBOX_DEFAULT_FEATURE_CHAT_IMPLICIT_CR
+ help
+ When enabled make chat to terminate all SEND strings with a "\r"
+ unless "\c" is met anywhere in the string.
+
+config BUSYBOX_CONFIG_FEATURE_CHAT_SWALLOW_OPTS
+ bool "Swallow options"
+ depends on BUSYBOX_CONFIG_CHAT
+ default BUSYBOX_DEFAULT_FEATURE_CHAT_SWALLOW_OPTS
+ help
+ Busybox chat require no options. To make it not fail when used
+ in place of original chat (which has a bunch of options) turn
+ this on.
+
+config BUSYBOX_CONFIG_FEATURE_CHAT_SEND_ESCAPES
+ bool "Support weird SEND escapes"
+ depends on BUSYBOX_CONFIG_CHAT
+ default BUSYBOX_DEFAULT_FEATURE_CHAT_SEND_ESCAPES
+ help
+ Original chat uses some escape sequences in SEND arguments which
+ are not sent to device but rather performs special actions.
+ E.g. "\K" means to send a break sequence to device.
+ "\d" delays execution for a second, "\p" -- for a 1/100 of second.
+ Before turning this option on think twice: do you really need them?
+
+config BUSYBOX_CONFIG_FEATURE_CHAT_VAR_ABORT_LEN
+ bool "Support variable-length ABORT conditions"
+ depends on BUSYBOX_CONFIG_CHAT
+ default BUSYBOX_DEFAULT_FEATURE_CHAT_VAR_ABORT_LEN
+ help
+ Original chat uses fixed 50-bytes length ABORT conditions. Say N here.
+
+config BUSYBOX_CONFIG_FEATURE_CHAT_CLR_ABORT
+ bool "Support revoking of ABORT conditions"
+ depends on BUSYBOX_CONFIG_CHAT
+ default BUSYBOX_DEFAULT_FEATURE_CHAT_CLR_ABORT
+ help
+ Support CLR_ABORT directive.
+
+config BUSYBOX_CONFIG_CHRT
+ bool "chrt"
+ default BUSYBOX_DEFAULT_CHRT
+ help
+ manipulate real-time attributes of a process.
+ This requires sched_{g,s}etparam support in your libc.
+
+config BUSYBOX_CONFIG_CRONTAB
+ bool "crontab"
+ default BUSYBOX_DEFAULT_CRONTAB
+ help
+ Crontab manipulates the crontab for a particular user. Only
+ the superuser may specify a different user and/or crontab directory.
+ Note that Busybox binary must be setuid root for this applet to
+ work properly.
+
+config BUSYBOX_CONFIG_DC
+ bool "dc"
+ default BUSYBOX_DEFAULT_DC
+ help
+ Dc is a reverse-polish desk calculator which supports unlimited
+ precision arithmetic.
+
+config BUSYBOX_CONFIG_FEATURE_DC_LIBM
+ bool "Enable power and exp functions (requires libm)"
+ default BUSYBOX_DEFAULT_FEATURE_DC_LIBM
+ depends on BUSYBOX_CONFIG_DC
+ help
+ Enable power and exp functions.
+ NOTE: This will require libm to be present for linking.
+
+config BUSYBOX_CONFIG_DEVFSD
+ bool "devfsd (obsolete)"
+ default BUSYBOX_DEFAULT_DEVFSD
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ This is deprecated and should NOT be used anymore.
+ Use linux >= 2.6 (optionally with hotplug) and mdev instead!
+ See docs/mdev.txt for detailed instructions on how to use mdev
+ instead.
+
+ Provides compatibility with old device names on a devfs systems.
+ You should set it to true if you have devfs enabled.
+ The following keywords in devsfd.conf are supported:
+ "CLEAR_CONFIG", "INCLUDE", "OPTIONAL_INCLUDE", "RESTORE",
+ "PERMISSIONS", "EXECUTE", "COPY", "IGNORE",
+ "MKOLDCOMPAT", "MKNEWCOMPAT","RMOLDCOMPAT", "RMNEWCOMPAT".
+
+ But only if they are written UPPERCASE!!!!!!!!
+
+config BUSYBOX_CONFIG_DEVFSD_MODLOAD
+ bool "Adds support for MODLOAD keyword in devsfd.conf"
+ default BUSYBOX_DEFAULT_DEVFSD_MODLOAD
+ depends on BUSYBOX_CONFIG_DEVFSD
+ help
+ This actually doesn't work with busybox modutils but needs
+ the external modutils.
+
+config BUSYBOX_CONFIG_DEVFSD_FG_NP
+ bool "Enables the -fg and -np options"
+ default BUSYBOX_DEFAULT_DEVFSD_FG_NP
+ depends on BUSYBOX_CONFIG_DEVFSD
+ help
+ -fg Run the daemon in the foreground.
+ -np Exit after parsing the configuration file.
+ Do not poll for events.
+
+config BUSYBOX_CONFIG_DEVFSD_VERBOSE
+ bool "Increases logging (and size)"
+ default BUSYBOX_DEFAULT_DEVFSD_VERBOSE
+ depends on BUSYBOX_CONFIG_DEVFSD
+ help
+ Increases logging to stderr or syslog.
+
+config BUSYBOX_CONFIG_FEATURE_DEVFS
+ bool "Use devfs names for all devices (obsolete)"
+ default BUSYBOX_DEFAULT_FEATURE_DEVFS
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This is obsolete and should NOT be used anymore.
+ Use linux >= 2.6 (optionally with hotplug) and mdev instead!
+
+ For legacy systems -- if there is no way around devfsd -- this
+ tells busybox to look for names like /dev/loop/0 instead of
+ /dev/loop0. If your /dev directory has normal names instead of
+ devfs names, you don't want this.
+
+config BUSYBOX_CONFIG_DEVMEM
+ bool "devmem"
+ default BUSYBOX_DEFAULT_DEVMEM
+ help
+ devmem is a small program that reads and writes from physical
+ memory using /dev/mem.
+
+config BUSYBOX_CONFIG_EJECT
+ bool "eject"
+ default BUSYBOX_DEFAULT_EJECT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Used to eject cdroms. (defaults to /dev/cdrom)
+
+config BUSYBOX_CONFIG_FEATURE_EJECT_SCSI
+ bool "SCSI support"
+ default BUSYBOX_DEFAULT_FEATURE_EJECT_SCSI
+ depends on BUSYBOX_CONFIG_EJECT
+ help
+ Add the -s option to eject, this allows to eject SCSI-Devices and
+ usb-storage devices.
+
+config BUSYBOX_CONFIG_FBSPLASH
+ bool "fbsplash"
+ default BUSYBOX_DEFAULT_FBSPLASH
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ 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.
+ - $ 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 (can be "-" for stdin)
+ -f path_to_fifo (can be "-" for stdin)
+ - if you want to run it only in presence of kernel parameter:
+ grep -q "fbsplash=on" </proc/cmdline && setsid fbsplash [params] &
+ - commands for fifo:
+ "NN" (ASCII decimal number) - percentage to show on progress bar
+ "exit" - well you guessed it
+
+config BUSYBOX_CONFIG_FLASHCP
+ bool "flashcp"
+ default BUSYBOX_DEFAULT_FLASHCP # doesn't build on Ubuntu 8.04
+ help
+ The flashcp binary, inspired by mtd-utils as of git head 5eceb74f7.
+ This utility is used to copy images into a MTD device.
+
+config BUSYBOX_CONFIG_FLASH_LOCK
+ bool "flash_lock"
+ default BUSYBOX_DEFAULT_FLASH_LOCK # doesn't build on Ubuntu 8.04
+ help
+ The flash_lock binary from mtd-utils as of git head 5ec0c10d0. This
+ utility locks part or all of the flash device.
+
+config BUSYBOX_CONFIG_FLASH_UNLOCK
+ bool "flash_unlock"
+ default BUSYBOX_DEFAULT_FLASH_UNLOCK # doesn't build on Ubuntu 8.04
+ help
+ The flash_unlock binary from mtd-utils as of git head 5ec0c10d0. This
+ utility unlocks part or all of the flash device.
+
+config BUSYBOX_CONFIG_FLASH_ERASEALL
+ bool "flash_eraseall"
+ default BUSYBOX_DEFAULT_FLASH_ERASEALL # doesn't build on Ubuntu 8.04
+ help
+ The flash_eraseall binary from mtd-utils as of git head c4c6a59eb.
+ This utility is used to erase the whole MTD device.
+
+config BUSYBOX_CONFIG_IONICE
+ bool "ionice"
+ default BUSYBOX_DEFAULT_IONICE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Set/set program io scheduling class and priority
+ Requires kernel >= 2.6.13
+
+config BUSYBOX_CONFIG_INOTIFYD
+ bool "inotifyd"
+ default BUSYBOX_DEFAULT_INOTIFYD # doesn't build on Knoppix 5
+ help
+ Simple inotify daemon. Reports filesystem changes. Requires
+ kernel >= 2.6.13
+
+config BUSYBOX_CONFIG_LAST
+ bool "last"
+ default BUSYBOX_DEFAULT_LAST
+ depends on BUSYBOX_CONFIG_FEATURE_WTMP
+ help
+ 'last' displays a list of the last users that logged into the system.
+
+choice
+ prompt "Choose last implementation"
+ depends on BUSYBOX_CONFIG_LAST
+ default BUSYBOX_CONFIG_FEATURE_LAST_FANCY
+
+config BUSYBOX_CONFIG_FEATURE_LAST_SMALL
+ bool "small"
+ help
+ This is a small version of last with just the basic set of
+ features.
+
+config BUSYBOX_CONFIG_FEATURE_LAST_FANCY
+ bool "huge"
+ help
+ 'last' displays detailed information about the last users that
+ logged into the system (mimics sysvinit last). +900 bytes.
+endchoice
+
+config BUSYBOX_CONFIG_HDPARM
+ bool "hdparm"
+ default BUSYBOX_DEFAULT_HDPARM
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Get/Set hard drive parameters. Primarily intended for ATA
+ drives. Adds about 13k (or around 30k if you enable the
+ FEATURE_HDPARM_GET_IDENTITY option)....
+
+config BUSYBOX_CONFIG_FEATURE_HDPARM_GET_IDENTITY
+ bool "Support obtaining detailed information directly from drives"
+ default BUSYBOX_DEFAULT_FEATURE_HDPARM_GET_IDENTITY
+ depends on BUSYBOX_CONFIG_HDPARM
+ help
+ Enables the -I and -i options to obtain detailed information
+ directly from drives about their capabilities and supported ATA
+ feature set. If no device name is specified, hdparm will read
+ identify data from stdin. Enabling this option will add about 16k...
+
+config BUSYBOX_CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF
+ bool "Register an IDE interface (DANGEROUS)"
+ default BUSYBOX_DEFAULT_FEATURE_HDPARM_HDIO_SCAN_HWIF
+ depends on BUSYBOX_CONFIG_HDPARM
+ help
+ Enables the 'hdparm -R' option to register an IDE interface.
+ This is dangerous stuff, so you should probably say N.
+
+config BUSYBOX_CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
+ bool "Un-register an IDE interface (DANGEROUS)"
+ default BUSYBOX_DEFAULT_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF
+ depends on BUSYBOX_CONFIG_HDPARM
+ help
+ Enables the 'hdparm -U' option to un-register an IDE interface.
+ This is dangerous stuff, so you should probably say N.
+
+config BUSYBOX_CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET
+ bool "Perform device reset (DANGEROUS)"
+ default BUSYBOX_DEFAULT_FEATURE_HDPARM_HDIO_DRIVE_RESET
+ depends on BUSYBOX_CONFIG_HDPARM
+ help
+ Enables the 'hdparm -w' option to perform a device reset.
+ This is dangerous stuff, so you should probably say N.
+
+config BUSYBOX_CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
+ bool "Tristate device for hotswap (DANGEROUS)"
+ default BUSYBOX_DEFAULT_FEATURE_HDPARM_HDIO_TRISTATE_HWIF
+ depends on BUSYBOX_CONFIG_HDPARM
+ help
+ Enables the 'hdparm -x' option to tristate device for hotswap,
+ and the '-b' option to get/set bus state. This is dangerous
+ stuff, so you should probably say N.
+
+config BUSYBOX_CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA
+ bool "Get/set using_dma flag"
+ default BUSYBOX_DEFAULT_FEATURE_HDPARM_HDIO_GETSET_DMA
+ depends on BUSYBOX_CONFIG_HDPARM
+ help
+ Enables the 'hdparm -d' option to get/set using_dma flag.
+
+config BUSYBOX_CONFIG_LOCK
+ bool "lock"
+ default BUSYBOX_DEFAULT_LOCK
+ help
+ Small utility for using locks in scripts
+
+config BUSYBOX_CONFIG_MAKEDEVS
+ bool "makedevs"
+ default BUSYBOX_DEFAULT_MAKEDEVS
+ help
+ 'makedevs' is a utility used to create a batch of devices with
+ one command.
+
+ There are two choices for command line behaviour, the interface
+ as used by LEAF/Linux Router Project, or a device table file.
+
+ 'leaf' is traditionally what busybox follows, it allows multiple
+ devices of a particluar type to be created per command.
+ e.g. /dev/hda[0-9]
+ Device properties are passed as command line arguments.
+
+ 'table' reads device properties from a file or stdin, allowing
+ a batch of unrelated devices to be made with one command.
+ User/group names are allowed as an alternative to uid/gid.
+
+choice
+ prompt "Choose makedevs behaviour"
+ depends on BUSYBOX_CONFIG_MAKEDEVS
+ default BUSYBOX_CONFIG_FEATURE_MAKEDEVS_TABLE
+
+config BUSYBOX_CONFIG_FEATURE_MAKEDEVS_LEAF
+ bool "leaf"
+
+config BUSYBOX_CONFIG_FEATURE_MAKEDEVS_TABLE
+ bool "table"
+
+endchoice
+
+config BUSYBOX_CONFIG_MAN
+ bool "man"
+ default BUSYBOX_DEFAULT_MAN
+ help
+ Format and display manual pages.
+
+config BUSYBOX_CONFIG_MICROCOM
+ bool "microcom"
+ default BUSYBOX_DEFAULT_MICROCOM
+ help
+ The poor man's minicom utility for chatting with serial port devices.
+
+config BUSYBOX_CONFIG_MOUNTPOINT
+ bool "mountpoint"
+ default BUSYBOX_DEFAULT_MOUNTPOINT
+ help
+ mountpoint checks if the directory is a mountpoint.
+
+config BUSYBOX_CONFIG_MT
+ bool "mt"
+ default BUSYBOX_DEFAULT_MT
+ help
+ mt is used to control tape devices. You can use the mt utility
+ to advance or rewind a tape past a specified number of archive
+ files on the tape.
+
+config BUSYBOX_CONFIG_RAIDAUTORUN
+ bool "raidautorun"
+ default BUSYBOX_DEFAULT_RAIDAUTORUN
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ raidautorun tells the kernel md driver to
+ search and start RAID arrays.
+
+config BUSYBOX_CONFIG_READAHEAD
+ bool "readahead"
+ default BUSYBOX_DEFAULT_READAHEAD
+ depends on BUSYBOX_CONFIG_LFS
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Preload the files listed on the command line into RAM cache so that
+ subsequent reads on these files will not block on disk I/O.
+
+ This applet just calls the readahead(2) system call on each file.
+ It is mainly useful in system startup scripts to preload files
+ or executables before they are used. When used at the right time
+ (in particular when a CPU bound process is running) it can
+ significantly speed up system startup.
+
+ As readahead(2) blocks until each file has been read, it is best to
+ run this applet as a background job.
+
+config BUSYBOX_CONFIG_RUNLEVEL
+ bool "runlevel"
+ default BUSYBOX_DEFAULT_RUNLEVEL
+ depends on BUSYBOX_CONFIG_FEATURE_UTMP
+ help
+ find the current and previous system runlevel.
+
+ This applet uses utmp but does not rely on busybox supporing
+ utmp on purpose. It is used by e.g. emdebian via /etc/init.d/rc.
+
+config BUSYBOX_CONFIG_RX
+ bool "rx"
+ default BUSYBOX_DEFAULT_RX
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Receive files using the Xmodem protocol.
+
+config BUSYBOX_CONFIG_SETSID
+ bool "setsid"
+ default BUSYBOX_DEFAULT_SETSID
+ help
+ setsid runs a program in a new session
+
+config BUSYBOX_CONFIG_STRINGS
+ bool "strings"
+ default BUSYBOX_DEFAULT_STRINGS
+ help
+ strings prints the printable character sequences for each file
+ specified.
+
+config BUSYBOX_CONFIG_TIME
+ bool "time"
+ default BUSYBOX_DEFAULT_TIME
+ help
+ The time command runs the specified program with the given arguments.
+ When the command finishes, time writes a message to standard output
+ giving timing statistics about this program run.
+
+config BUSYBOX_CONFIG_TIMEOUT
+ bool "timeout"
+ default BUSYBOX_DEFAULT_TIMEOUT
+ help
+ Runs a program and watches it. If it does not terminate in
+ specified number of seconds, it is sent a signal.
+
+config BUSYBOX_CONFIG_TTYSIZE
+ bool "ttysize"
+ default BUSYBOX_DEFAULT_TTYSIZE
+ help
+ A replacement for "stty size". Unlike stty, can report only width,
+ only height, or both, in any order. It also does not complain on
+ error, but returns default 80x24.
+ Usage in shell scripts: width=`ttysize w`.
+
+config BUSYBOX_CONFIG_VOLNAME
+ bool "volname"
+ default BUSYBOX_DEFAULT_VOLNAME
+ help
+ Prints a CD-ROM volume name.
+
+config BUSYBOX_CONFIG_WATCHDOG
+ bool "watchdog"
+ default BUSYBOX_DEFAULT_WATCHDOG
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The watchdog utility is used with hardware or software watchdog
+ device drivers. It opens the specified watchdog device special file
+ and periodically writes a magic character to the device. If the
+ watchdog applet ever fails to write the magic character within a
+ certain amount of time, the watchdog device assumes the system has
+ hung, and will cause the hardware to reboot.
+
+endmenu
diff --git a/package/utils/busybox/config/modutils/Config.in b/package/utils/busybox/config/modutils/Config.in
new file mode 100644
index 0000000..9add56e
--- /dev/null
+++ b/package/utils/busybox/config/modutils/Config.in
@@ -0,0 +1,269 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Linux Module Utilities"
+
+config BUSYBOX_CONFIG_MODINFO
+ bool "modinfo"
+ default BUSYBOX_DEFAULT_MODINFO
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Show information about a Linux Kernel module
+
+config BUSYBOX_CONFIG_MODPROBE_SMALL
+ bool "Simplified modutils"
+ default BUSYBOX_DEFAULT_MODPROBE_SMALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Simplified modutils.
+
+ With this option modprobe does not require modules.dep file
+ and does not use /etc/modules.conf file.
+ It scans module files in /lib/modules/`uname -r` and
+ determines dependencies and module alias names on the fly.
+ This may make module loading slower, most notably
+ when one needs to load module by alias (this requires
+ scanning through module _bodies_).
+
+ At the first attempt to load a module by alias modprobe
+ will try to generate modules.dep.bb file in order to speed up
+ future loads by alias. Failure to do so (read-only /lib/modules,
+ etc) is not reported, and future modprobes will be slow too.
+
+ NB: modules.dep.bb file format is not compatible
+ with modules.dep file as created/used by standard module tools.
+
+ Additional module parameters can be stored in
+ /etc/modules/$module_name files.
+
+ Apart from modprobe, other utilities are also provided:
+ - insmod is an alias to modprobe
+ - rmmod is an alias to modprobe -r
+ - depmod generates modules.dep.bb
+
+ As of 2008-07, this code is experimental. It is 14kb smaller
+ than "non-small" modutils.
+
+config BUSYBOX_CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE
+ bool "Accept module options on modprobe command line"
+ default BUSYBOX_DEFAULT_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE
+ depends on BUSYBOX_CONFIG_MODPROBE_SMALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Allow insmod and modprobe take module options from command line.
+
+config BUSYBOX_CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED
+ bool "Skip loading of already loaded modules"
+ default BUSYBOX_DEFAULT_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED
+ depends on BUSYBOX_CONFIG_MODPROBE_SMALL
+ help
+ Check if the module is already loaded.
+
+config BUSYBOX_CONFIG_INSMOD
+ bool "insmod"
+ default BUSYBOX_DEFAULT_INSMOD
+ depends on !BUSYBOX_CONFIG_MODPROBE_SMALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ insmod is used to load specified modules in the running kernel.
+
+config BUSYBOX_CONFIG_RMMOD
+ bool "rmmod"
+ default BUSYBOX_DEFAULT_RMMOD
+ depends on !BUSYBOX_CONFIG_MODPROBE_SMALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ rmmod is used to unload specified modules from the kernel.
+
+config BUSYBOX_CONFIG_LSMOD
+ bool "lsmod"
+ default BUSYBOX_DEFAULT_LSMOD
+ depends on !BUSYBOX_CONFIG_MODPROBE_SMALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ lsmod is used to display a list of loaded modules.
+
+config BUSYBOX_CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT
+ bool "Pretty output"
+ default BUSYBOX_DEFAULT_FEATURE_LSMOD_PRETTY_2_6_OUTPUT
+ depends on BUSYBOX_CONFIG_LSMOD
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This option makes output format of lsmod adjusted to
+ the format of module-init-tools for Linux kernel 2.6.
+ Increases size somewhat.
+
+config BUSYBOX_CONFIG_MODPROBE
+ bool "modprobe"
+ default BUSYBOX_DEFAULT_MODPROBE
+ depends on !BUSYBOX_CONFIG_MODPROBE_SMALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Handle the loading of modules, and their dependencies on a high
+ level.
+
+config BUSYBOX_CONFIG_FEATURE_MODPROBE_BLACKLIST
+ bool "Blacklist support"
+ default BUSYBOX_DEFAULT_FEATURE_MODPROBE_BLACKLIST
+ depends on BUSYBOX_CONFIG_MODPROBE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Say 'y' here to enable support for the 'blacklist' command in
+ modprobe.conf. This prevents the alias resolver to resolve
+ blacklisted modules. This is useful if you want to prevent your
+ hardware autodetection scripts to load modules like evdev, frame
+ buffer drivers etc.
+
+config BUSYBOX_CONFIG_DEPMOD
+ bool "depmod"
+ default BUSYBOX_DEFAULT_DEPMOD
+ depends on !BUSYBOX_CONFIG_MODPROBE_SMALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ depmod generates modules.dep (and potentially modules.alias
+ and modules.symbols) that contain dependency information
+ for modprobe.
+
+comment "Options common to multiple modutils"
+
+config BUSYBOX_CONFIG_FEATURE_2_4_MODULES
+ bool "Support version 2.2/2.4 Linux kernels"
+ default BUSYBOX_DEFAULT_FEATURE_2_4_MODULES
+ depends on BUSYBOX_CONFIG_INSMOD || BUSYBOX_CONFIG_RMMOD || BUSYBOX_CONFIG_LSMOD
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Support module loading for 2.2.x and 2.4.x Linux kernels.
+ This increases size considerably. Say N unless you plan
+ to run ancient kernels.
+
+config BUSYBOX_CONFIG_FEATURE_INSMOD_TRY_MMAP
+ bool "Try to load module from a mmap'ed area"
+ default BUSYBOX_DEFAULT_FEATURE_INSMOD_TRY_MMAP
+ depends on BUSYBOX_CONFIG_INSMOD || BUSYBOX_CONFIG_MODPROBE_SMALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This option causes module loading code to try to mmap
+ module first. If it does not work (for example,
+ it does not work for compressed modules), module will be read
+ (and unpacked if needed) into a memory block allocated by malloc.
+
+ The only case when mmap works but malloc does not is when
+ you are trying to load a big module on a very memory-constrained
+ machine. Malloc will momentarily need 2x as much memory as mmap.
+
+ Choosing N saves about 250 bytes of code (on 32-bit x86).
+
+config BUSYBOX_CONFIG_FEATURE_INSMOD_VERSION_CHECKING
+ bool "Enable module version checking"
+ default BUSYBOX_DEFAULT_FEATURE_INSMOD_VERSION_CHECKING
+ depends on BUSYBOX_CONFIG_FEATURE_2_4_MODULES && (BUSYBOX_CONFIG_INSMOD || BUSYBOX_CONFIG_MODPROBE)
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Support checking of versions for modules. This is used to
+ ensure that the kernel and module are made for each other.
+
+config BUSYBOX_CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
+ bool "Add module symbols to kernel symbol table"
+ default BUSYBOX_DEFAULT_FEATURE_INSMOD_KSYMOOPS_SYMBOLS
+ depends on BUSYBOX_CONFIG_FEATURE_2_4_MODULES && (BUSYBOX_CONFIG_INSMOD || BUSYBOX_CONFIG_MODPROBE)
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ By adding module symbols to the kernel symbol table, Oops messages
+ occuring within kernel modules can be properly debugged. By enabling
+ this feature, module symbols will always be added to the kernel symbol
+ table for proper debugging support. If you are not interested in
+ Oops messages from kernel modules, say N.
+
+config BUSYBOX_CONFIG_FEATURE_INSMOD_LOADINKMEM
+ bool "In kernel memory optimization (uClinux only)"
+ default BUSYBOX_DEFAULT_FEATURE_INSMOD_LOADINKMEM
+ depends on BUSYBOX_CONFIG_FEATURE_2_4_MODULES && (BUSYBOX_CONFIG_INSMOD || BUSYBOX_CONFIG_MODPROBE)
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This is a special uClinux only memory optimization that lets insmod
+ load the specified kernel module directly into kernel space, reducing
+ memory usage by preventing the need for two copies of the module
+ being loaded into memory.
+
+config BUSYBOX_CONFIG_FEATURE_INSMOD_LOAD_MAP
+ bool "Enable insmod load map (-m) option"
+ default BUSYBOX_DEFAULT_FEATURE_INSMOD_LOAD_MAP
+ depends on BUSYBOX_CONFIG_FEATURE_2_4_MODULES && BUSYBOX_CONFIG_INSMOD
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Enabling this, one would be able to get a load map
+ output on stdout. This makes kernel module debugging
+ easier.
+ If you don't plan to debug kernel modules, you
+ don't need this option.
+
+config BUSYBOX_CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL
+ bool "Symbols in load map"
+ default BUSYBOX_DEFAULT_FEATURE_INSMOD_LOAD_MAP_FULL
+ depends on BUSYBOX_CONFIG_FEATURE_INSMOD_LOAD_MAP && !BUSYBOX_CONFIG_MODPROBE_SMALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Without this option, -m will only output section
+ load map. With this option, -m will also output
+ symbols load map.
+
+config BUSYBOX_CONFIG_FEATURE_CHECK_TAINTED_MODULE
+ bool "Support tainted module checking with new kernels"
+ default BUSYBOX_DEFAULT_FEATURE_CHECK_TAINTED_MODULE
+ depends on (BUSYBOX_CONFIG_LSMOD || BUSYBOX_CONFIG_FEATURE_2_4_MODULES) && !BUSYBOX_CONFIG_MODPROBE_SMALL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Support checking for tainted modules. These are usually binary
+ only modules that will make the linux-kernel list ignore your
+ support request.
+ This option is required to support GPLONLY modules.
+
+config BUSYBOX_CONFIG_FEATURE_MODUTILS_ALIAS
+ bool "Support for module.aliases file"
+ default BUSYBOX_DEFAULT_FEATURE_MODUTILS_ALIAS
+ depends on BUSYBOX_CONFIG_DEPMOD || BUSYBOX_CONFIG_MODPROBE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Generate and parse modules.alias containing aliases for bus
+ identifiers:
+ alias pcmcia:m*c*f03fn*pfn*pa*pb*pc*pd* parport_cs
+
+ and aliases for logical modules names e.g.:
+ alias padlock_aes aes
+ alias aes_i586 aes
+ alias aes_generic aes
+
+ Say Y if unsure.
+
+config BUSYBOX_CONFIG_FEATURE_MODUTILS_SYMBOLS
+ bool "Support for module.symbols file"
+ default BUSYBOX_DEFAULT_FEATURE_MODUTILS_SYMBOLS
+ depends on BUSYBOX_CONFIG_DEPMOD || BUSYBOX_CONFIG_MODPROBE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Generate and parse modules.symbols containing aliases for
+ symbol_request() kernel calls, such as:
+ alias symbol:usb_sg_init usbcore
+
+ Say Y if unsure.
+
+config BUSYBOX_CONFIG_DEFAULT_MODULES_DIR
+ string "Default directory containing modules"
+ default BUSYBOX_DEFAULT_DEFAULT_MODULES_DIR
+ depends on BUSYBOX_CONFIG_DEPMOD || BUSYBOX_CONFIG_MODPROBE || BUSYBOX_CONFIG_MODPROBE_SMALL || BUSYBOX_CONFIG_MODINFO
+ help
+ Directory that contains kernel modules.
+ Defaults to "/lib/modules"
+
+config BUSYBOX_CONFIG_DEFAULT_DEPMOD_FILE
+ string "Default name of modules.dep"
+ default BUSYBOX_DEFAULT_DEFAULT_DEPMOD_FILE
+ depends on BUSYBOX_CONFIG_DEPMOD || BUSYBOX_CONFIG_MODPROBE || BUSYBOX_CONFIG_MODPROBE_SMALL || BUSYBOX_CONFIG_MODINFO
+ help
+ Filename that contains kernel modules dependencies.
+ Defaults to "modules.dep"
+
+endmenu
diff --git a/package/utils/busybox/config/networking/Config.in b/package/utils/busybox/config/networking/Config.in
new file mode 100644
index 0000000..b3dd8c8
--- /dev/null
+++ b/package/utils/busybox/config/networking/Config.in
@@ -0,0 +1,1105 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Networking Utilities"
+
+config BUSYBOX_CONFIG_NAMEIF
+ bool "nameif"
+ default BUSYBOX_DEFAULT_NAMEIF
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ nameif is used to rename network interface by its MAC address.
+ Renamed interfaces MUST be in the down state.
+ It is possible to use a file (default: /etc/mactab)
+ with list of new interface names and MACs.
+ Maximum interface name length: IFNAMSIZ = 16
+ File fields are separated by space or tab.
+ File format:
+ # Comment
+ new_interface_name XX:XX:XX:XX:XX:XX
+
+config BUSYBOX_CONFIG_FEATURE_NAMEIF_EXTENDED
+ bool "Extended nameif"
+ default BUSYBOX_DEFAULT_FEATURE_NAMEIF_EXTENDED
+ depends on BUSYBOX_CONFIG_NAMEIF
+ help
+ This extends the nameif syntax to support the bus_info, driver,
+ phyaddr selectors. The syntax is compatible to the normal nameif.
+ File format:
+ new_interface_name driver=asix bus=usb-0000:00:08.2-3
+ new_interface_name bus=usb-0000:00:08.2-3 00:80:C8:38:91:B5
+ new_interface_name phy_address=2 00:80:C8:38:91:B5
+ new_interface_name mac=00:80:C8:38:91:B5
+ new_interface_name 00:80:C8:38:91:B5
+config BUSYBOX_CONFIG_NBDCLIENT
+ bool "nbd-client"
+ default BUSYBOX_DEFAULT_NBDCLIENT
+ help
+ Network block device client
+config BUSYBOX_CONFIG_NC
+ bool "nc"
+ default BUSYBOX_DEFAULT_NC
+ help
+ A simple Unix utility which reads and writes data across network
+ connections.
+
+config BUSYBOX_CONFIG_NC_SERVER
+ bool "Netcat server options (-l)"
+ default BUSYBOX_DEFAULT_NC_SERVER
+ depends on BUSYBOX_CONFIG_NC
+ help
+ Allow netcat to act as a server.
+
+config BUSYBOX_CONFIG_NC_EXTRA
+ bool "Netcat extensions (-eiw and -f FILE)"
+ default BUSYBOX_DEFAULT_NC_EXTRA
+ depends on BUSYBOX_CONFIG_NC
+ help
+ Add -e (support for executing the rest of the command line after
+ making or receiving a successful connection), -i (delay interval for
+ lines sent), -w (timeout for initial connection).
+
+config BUSYBOX_CONFIG_NC_110_COMPAT
+ bool "Netcat 1.10 compatibility (+2.5k)"
+ default BUSYBOX_DEFAULT_NC_110_COMPAT # off specially for Rob
+ depends on BUSYBOX_CONFIG_NC
+ help
+ This option makes nc closely follow original nc-1.10.
+ The code is about 2.5k bigger. It enables
+ -s ADDR, -n, -u, -v, -o FILE, -z options, but loses
+ busybox-specific extensions: -f FILE.
+config BUSYBOX_CONFIG_PING
+ bool "ping"
+ default BUSYBOX_DEFAULT_PING
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ ping uses the ICMP protocol's mandatory ECHO_REQUEST datagram to
+ elicit an ICMP ECHO_RESPONSE from a host or gateway.
+
+config BUSYBOX_CONFIG_PING6
+ bool "ping6"
+ default BUSYBOX_DEFAULT_PING6
+ depends on BUSYBOX_CONFIG_FEATURE_IPV6 && BUSYBOX_CONFIG_PING
+ help
+ This will give you a ping that can talk IPv6.
+
+config BUSYBOX_CONFIG_FEATURE_FANCY_PING
+ bool "Enable fancy ping output"
+ default BUSYBOX_DEFAULT_FEATURE_FANCY_PING
+ depends on BUSYBOX_CONFIG_PING
+ help
+ Make the output from the ping applet include statistics, and at the
+ same time provide full support for ICMP packets.
+config BUSYBOX_CONFIG_WHOIS
+ bool "whois"
+ default BUSYBOX_DEFAULT_WHOIS
+ help
+ whois is a client for the whois directory service
+
+config BUSYBOX_CONFIG_FEATURE_IPV6
+ bool "Enable IPv6 support"
+ default BUSYBOX_DEFAULT_FEATURE_IPV6
+ help
+ Enable IPv6 support in busybox.
+ This adds IPv6 support in the networking applets.
+
+config BUSYBOX_CONFIG_FEATURE_UNIX_LOCAL
+ bool "Enable Unix domain socket support (usually not needed)"
+ default BUSYBOX_DEFAULT_FEATURE_UNIX_LOCAL
+ help
+ Enable Unix domain socket support in all busybox networking
+ applets. Address of the form local:/path/to/unix/socket
+ will be recognized.
+
+ This extension is almost never used in real world usage.
+ You most likely want to say N.
+
+config BUSYBOX_CONFIG_FEATURE_PREFER_IPV4_ADDRESS
+ bool "Prefer IPv4 addresses from DNS queries"
+ default BUSYBOX_DEFAULT_FEATURE_PREFER_IPV4_ADDRESS
+ depends on BUSYBOX_CONFIG_FEATURE_IPV6
+ help
+ Use IPv4 address of network host if it has one.
+
+ If this option is off, the first returned address will be used.
+ This may cause problems when your DNS server is IPv6-capable and
+ is returning IPv6 host addresses too. If IPv6 address
+ precedes IPv4 one in DNS reply, busybox network applets
+ (e.g. wget) will use IPv6 address. On an IPv6-incapable host
+ or network applets will fail to connect to the host
+ using IPv6 address.
+
+config BUSYBOX_CONFIG_VERBOSE_RESOLUTION_ERRORS
+ bool "Verbose resolution errors"
+ default BUSYBOX_DEFAULT_VERBOSE_RESOLUTION_ERRORS
+ help
+ Enable if you are not satisfied with simplistic
+ "can't resolve 'hostname.com'" and want to know more.
+ This may increase size of your executable a bit.
+
+config BUSYBOX_CONFIG_ARP
+ bool "arp"
+ default BUSYBOX_DEFAULT_ARP
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Manipulate the system ARP cache.
+
+config BUSYBOX_CONFIG_ARPING
+ bool "arping"
+ default BUSYBOX_DEFAULT_ARPING
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Ping hosts by ARP packets.
+
+config BUSYBOX_CONFIG_BRCTL
+ bool "brctl"
+ default BUSYBOX_DEFAULT_BRCTL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Manage ethernet bridges.
+ Supports addbr/delbr and addif/delif.
+
+config BUSYBOX_CONFIG_FEATURE_BRCTL_FANCY
+ bool "Fancy options"
+ default BUSYBOX_DEFAULT_FEATURE_BRCTL_FANCY
+ depends on BUSYBOX_CONFIG_BRCTL
+ help
+ Add support for extended option like:
+ setageing, setfd, sethello, setmaxage,
+ setpathcost, setportprio, setbridgeprio,
+ stp
+ This adds about 600 bytes.
+
+config BUSYBOX_CONFIG_FEATURE_BRCTL_SHOW
+ bool "Support show"
+ default BUSYBOX_DEFAULT_FEATURE_BRCTL_SHOW
+ depends on BUSYBOX_CONFIG_BRCTL && BUSYBOX_CONFIG_FEATURE_BRCTL_FANCY
+ help
+ Add support for option which prints the current config:
+ show
+
+config BUSYBOX_CONFIG_DNSD
+ bool "dnsd"
+ default BUSYBOX_DEFAULT_DNSD
+ help
+ Small and static DNS server daemon.
+
+config BUSYBOX_CONFIG_ETHER_WAKE
+ bool "ether-wake"
+ default BUSYBOX_DEFAULT_ETHER_WAKE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Send a magic packet to wake up sleeping machines.
+
+config BUSYBOX_CONFIG_FAKEIDENTD
+ bool "fakeidentd"
+ default BUSYBOX_DEFAULT_FAKEIDENTD
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ fakeidentd listens on the ident port and returns a predefined
+ fake value on any query.
+
+config BUSYBOX_CONFIG_FTPD
+ bool "ftpd"
+ default BUSYBOX_DEFAULT_FTPD
+ help
+ simple FTP daemon. You have to run it via inetd.
+
+config BUSYBOX_CONFIG_FEATURE_FTP_WRITE
+ bool "Enable upload commands"
+ default BUSYBOX_DEFAULT_FEATURE_FTP_WRITE
+ depends on BUSYBOX_CONFIG_FTPD
+ help
+ Enable all kinds of FTP upload commands (-w option)
+
+config BUSYBOX_CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST
+ bool "Enable workaround for RFC-violating clients"
+ default BUSYBOX_DEFAULT_FEATURE_FTPD_ACCEPT_BROKEN_LIST
+ depends on BUSYBOX_CONFIG_FTPD
+ help
+ Some ftp clients (among them KDE's Konqueror) issue illegal
+ "LIST -l" requests. This option works around such problems.
+ It might prevent you from listing files starting with "-" and
+ it increases the code size by ~40 bytes.
+ Most other ftp servers seem to behave similar to this.
+
+config BUSYBOX_CONFIG_FEATURE_FTP_AUTHENTICATION
+ bool "Enable authentication"
+ default BUSYBOX_DEFAULT_FEATURE_FTP_AUTHENTICATION
+ depends on BUSYBOX_CONFIG_FTPD
+ help
+ Enable basic system login as seen in telnet etc.
+
+config BUSYBOX_CONFIG_FTPGET
+ bool "ftpget"
+ default BUSYBOX_DEFAULT_FTPGET
+ help
+ Retrieve a remote file via FTP.
+
+config BUSYBOX_CONFIG_FTPPUT
+ bool "ftpput"
+ default BUSYBOX_DEFAULT_FTPPUT
+ help
+ Store a remote file via FTP.
+
+config BUSYBOX_CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS
+ bool "Enable long options in ftpget/ftpput"
+ default BUSYBOX_DEFAULT_FEATURE_FTPGETPUT_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_LONG_OPTS && (BUSYBOX_CONFIG_FTPGET || BUSYBOX_CONFIG_FTPPUT)
+ help
+ Support long options for the ftpget/ftpput applet.
+
+config BUSYBOX_CONFIG_HOSTNAME
+ bool "hostname"
+ default BUSYBOX_DEFAULT_HOSTNAME
+ help
+ Show or set the system's host name.
+
+config BUSYBOX_CONFIG_HTTPD
+ bool "httpd"
+ default BUSYBOX_DEFAULT_HTTPD
+ help
+ Serve web pages via an HTTP server.
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_RANGES
+ bool "Support 'Ranges:' header"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_RANGES
+ depends on BUSYBOX_CONFIG_HTTPD
+ help
+ Makes httpd emit "Accept-Ranges: bytes" header and understand
+ "Range: bytes=NNN-[MMM]" header. Allows for resuming interrupted
+ downloads, seeking in multimedia players etc.
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_SETUID
+ bool "Enable -u <user> option"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_SETUID
+ depends on BUSYBOX_CONFIG_HTTPD
+ help
+ This option allows the server to run as a specific user
+ rather than defaulting to the user that starts the server.
+ Use of this option requires special privileges to change to a
+ different user.
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_BASIC_AUTH
+ bool "Enable Basic http Authentication"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_BASIC_AUTH
+ depends on BUSYBOX_CONFIG_HTTPD
+ help
+ Utilizes password settings from /etc/httpd.conf for basic
+ authentication on a per url basis.
+ Example for httpd.conf file:
+ /adm:toor:PaSsWd
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_AUTH_MD5
+ bool "Support MD5 crypted passwords for http Authentication"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_AUTH_MD5
+ depends on BUSYBOX_CONFIG_FEATURE_HTTPD_BASIC_AUTH
+ help
+ Enables encrypted passwords, and wildcard user/passwords
+ in httpd.conf file.
+ User '*' means 'any system user name is ok',
+ password of '*' means 'use system password for this user'
+ Examples:
+ /adm:toor:$1$P/eKnWXS$aI1aPGxT.dJD5SzqAKWrF0
+ /adm:root:*
+ /wiki:*:*
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_CGI
+ bool "Support Common Gateway Interface (CGI)"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_CGI
+ depends on BUSYBOX_CONFIG_HTTPD
+ help
+ This option allows scripts and executables to be invoked
+ when specific URLs are requested.
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
+ bool "Support for running scripts through an interpreter"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
+ depends on BUSYBOX_CONFIG_FEATURE_HTTPD_CGI
+ help
+ This option enables support for running scripts through an
+ interpreter. Turn this on if you want PHP scripts to work
+ properly. You need to supply an additional line in your
+ httpd.conf file:
+ *.php:/path/to/your/php
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
+ bool "Set REMOTE_PORT environment variable for CGI"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
+ depends on BUSYBOX_CONFIG_FEATURE_HTTPD_CGI
+ help
+ Use of this option can assist scripts in generating
+ references that contain a unique port number.
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_ENCODE_URL_STR
+ bool "Enable -e option (useful for CGIs written as shell scripts)"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_ENCODE_URL_STR
+ depends on BUSYBOX_CONFIG_HTTPD
+ help
+ This option allows html encoding of arbitrary strings for display
+ by the browser. Output goes to stdout.
+ For example, httpd -e "<Hello World>" produces
+ "&#60Hello&#32World&#62".
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_ERROR_PAGES
+ bool "Support for custom error pages"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_ERROR_PAGES
+ depends on BUSYBOX_CONFIG_HTTPD
+ help
+ This option allows you to define custom error pages in
+ the configuration file instead of the default HTTP status
+ error pages. For instance, if you add the line:
+ E404:/path/e404.html
+ in the config file, the server will respond the specified
+ '/path/e404.html' file instead of the terse '404 NOT FOUND'
+ message.
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_PROXY
+ bool "Support for reverse proxy"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_PROXY
+ depends on BUSYBOX_CONFIG_HTTPD
+ help
+ This option allows you to define URLs that will be forwarded
+ to another HTTP server. To setup add the following line to the
+ configuration file
+ P:/url/:http://hostname[:port]/new/path/
+ Then a request to /url/myfile will be forwarded to
+ http://hostname[:port]/new/path/myfile.
+
+config BUSYBOX_CONFIG_FEATURE_HTTPD_GZIP
+ bool "Support for GZIP content encoding"
+ default BUSYBOX_DEFAULT_FEATURE_HTTPD_GZIP
+ depends on BUSYBOX_CONFIG_HTTPD
+ help
+ Makes httpd send files using GZIP content encoding if the
+ client supports it and a pre-compressed <file>.gz exists.
+
+config BUSYBOX_CONFIG_IFCONFIG
+ bool "ifconfig"
+ default BUSYBOX_DEFAULT_IFCONFIG
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Ifconfig is used to configure the kernel-resident network interfaces.
+
+config BUSYBOX_CONFIG_FEATURE_IFCONFIG_STATUS
+ bool "Enable status reporting output (+7k)"
+ default BUSYBOX_DEFAULT_FEATURE_IFCONFIG_STATUS
+ depends on BUSYBOX_CONFIG_IFCONFIG
+ help
+ If ifconfig is called with no arguments it will display the status
+ of the currently active interfaces.
+
+config BUSYBOX_CONFIG_FEATURE_IFCONFIG_SLIP
+ bool "Enable slip-specific options \"keepalive\" and \"outfill\""
+ default BUSYBOX_DEFAULT_FEATURE_IFCONFIG_SLIP
+ depends on BUSYBOX_CONFIG_IFCONFIG
+ help
+ Allow "keepalive" and "outfill" support for SLIP. If you're not
+ planning on using serial lines, leave this unchecked.
+
+config BUSYBOX_CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
+ bool "Enable options \"mem_start\", \"io_addr\", and \"irq\""
+ default BUSYBOX_DEFAULT_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
+ depends on BUSYBOX_CONFIG_IFCONFIG
+ help
+ Allow the start address for shared memory, start address for I/O,
+ and/or the interrupt line used by the specified device.
+
+config BUSYBOX_CONFIG_FEATURE_IFCONFIG_HW
+ bool "Enable option \"hw\" (ether only)"
+ default BUSYBOX_DEFAULT_FEATURE_IFCONFIG_HW
+ depends on BUSYBOX_CONFIG_IFCONFIG
+ help
+ Set the hardware address of this interface, if the device driver
+ supports this operation. Currently, we only support the 'ether'
+ class.
+
+config BUSYBOX_CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS
+ bool "Set the broadcast automatically"
+ default BUSYBOX_DEFAULT_FEATURE_IFCONFIG_BROADCAST_PLUS
+ depends on BUSYBOX_CONFIG_IFCONFIG
+ help
+ Setting this will make ifconfig attempt to find the broadcast
+ automatically if the value '+' is used.
+
+config BUSYBOX_CONFIG_IFENSLAVE
+ bool "ifenslave"
+ default BUSYBOX_DEFAULT_IFENSLAVE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Userspace application to bind several interfaces
+ to a logical interface (use with kernel bonding driver).
+
+config BUSYBOX_CONFIG_IFPLUGD
+ bool "ifplugd"
+ default BUSYBOX_DEFAULT_IFPLUGD
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Network interface plug detection daemon.
+
+config BUSYBOX_CONFIG_IFUPDOWN
+ bool "ifupdown"
+ default BUSYBOX_DEFAULT_IFUPDOWN
+ help
+ Activate or deactivate the specified interfaces. This applet makes
+ use of either "ifconfig" and "route" or the "ip" command to actually
+ configure network interfaces. Therefore, you will probably also want
+ to enable either IFCONFIG and ROUTE, or enable
+ FEATURE_IFUPDOWN_IP and the various IP options. Of
+ course you could use non-busybox versions of these programs, so
+ against my better judgement (since this will surely result in plenty
+ of support questions on the mailing list), I do not force you to
+ enable these additional options. It is up to you to supply either
+ "ifconfig", "route" and "run-parts" or the "ip" command, either
+ via busybox or via standalone utilities.
+
+config BUSYBOX_CONFIG_IFUPDOWN_IFSTATE_PATH
+ string "Absolute path to ifstate file"
+ default BUSYBOX_DEFAULT_IFUPDOWN_IFSTATE_PATH
+ depends on BUSYBOX_CONFIG_IFUPDOWN
+ help
+ ifupdown keeps state information in a file called ifstate.
+ Typically it is located in /var/run/ifstate, however
+ some distributions tend to put it in other places
+ (debian, for example, uses /etc/network/run/ifstate).
+ This config option defines location of ifstate.
+
+config BUSYBOX_CONFIG_FEATURE_IFUPDOWN_IP
+ bool "Use ip applet"
+ default BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_IP
+ depends on BUSYBOX_CONFIG_IFUPDOWN
+ help
+ Use the iproute "ip" command to implement "ifup" and "ifdown", rather
+ than the default of using the older 'ifconfig' and 'route' utilities.
+
+config BUSYBOX_CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN
+ bool "Use busybox ip applet"
+ default BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_IP_BUILTIN
+ depends on BUSYBOX_CONFIG_FEATURE_IFUPDOWN_IP
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ select BUSYBOX_CONFIG_IP
+ select BUSYBOX_CONFIG_FEATURE_IP_ADDRESS
+ select BUSYBOX_CONFIG_FEATURE_IP_LINK
+ select BUSYBOX_CONFIG_FEATURE_IP_ROUTE
+ help
+ Use the busybox iproute "ip" applet to implement "ifupdown".
+
+ If left disabled, you must install the full-blown iproute2
+ utility or the "ifup" and "ifdown" applets will not work.
+
+config BUSYBOX_CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN
+ bool "Use busybox ifconfig and route applets"
+ default BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN
+ depends on BUSYBOX_CONFIG_IFUPDOWN && !BUSYBOX_CONFIG_FEATURE_IFUPDOWN_IP
+ select BUSYBOX_CONFIG_IFCONFIG
+ select BUSYBOX_CONFIG_ROUTE
+ help
+ Use the busybox iproute "ifconfig" and "route" applets to
+ implement the "ifup" and "ifdown" utilities.
+
+ If left disabled, you must install the full-blown ifconfig
+ and route utilities, or the "ifup" and "ifdown" applets will not
+ work.
+
+config BUSYBOX_CONFIG_FEATURE_IFUPDOWN_IPV4
+ bool "Support for IPv4"
+ default BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_IPV4
+ depends on BUSYBOX_CONFIG_IFUPDOWN
+ help
+ If you want ifup/ifdown to talk IPv4, leave this on.
+
+config BUSYBOX_CONFIG_FEATURE_IFUPDOWN_IPV6
+ bool "Support for IPv6"
+ default BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_IPV6
+ depends on BUSYBOX_CONFIG_IFUPDOWN && BUSYBOX_CONFIG_FEATURE_IPV6
+ help
+ If you need support for IPv6, turn this option on.
+
+### UNUSED
+###config FEATURE_IFUPDOWN_IPX
+### bool "Support for IPX"
+### default y
+### depends on IFUPDOWN
+### help
+### If this option is selected you can use busybox to work with IPX
+### networks.
+
+config BUSYBOX_CONFIG_FEATURE_IFUPDOWN_MAPPING
+ bool "Enable mapping support"
+ default BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_MAPPING
+ depends on BUSYBOX_CONFIG_IFUPDOWN
+ help
+ This enables support for the "mapping" stanza, unless you have
+ a weird network setup you don't need it.
+
+config BUSYBOX_CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP
+ bool "Support for external dhcp clients"
+ default BUSYBOX_DEFAULT_FEATURE_IFUPDOWN_EXTERNAL_DHCP
+ depends on BUSYBOX_CONFIG_IFUPDOWN
+ help
+ This enables support for the external dhcp clients. Clients are
+ tried in the following order: dhcpcd, dhclient, pump and udhcpc.
+ Otherwise, if udhcpc applet is enabled, it is used.
+ Otherwise, ifup/ifdown will have no support for DHCP.
+
+config BUSYBOX_CONFIG_INETD
+ bool "inetd"
+ default BUSYBOX_DEFAULT_INETD
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ Internet superserver daemon
+
+config BUSYBOX_CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO
+ bool "Support echo service"
+ default BUSYBOX_DEFAULT_FEATURE_INETD_SUPPORT_BUILTIN_ECHO
+ depends on BUSYBOX_CONFIG_INETD
+ help
+ Echo received data internal inetd service
+
+config BUSYBOX_CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD
+ bool "Support discard service"
+ default BUSYBOX_DEFAULT_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD
+ depends on BUSYBOX_CONFIG_INETD
+ help
+ Internet /dev/null internal inetd service
+
+config BUSYBOX_CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME
+ bool "Support time service"
+ default BUSYBOX_DEFAULT_FEATURE_INETD_SUPPORT_BUILTIN_TIME
+ depends on BUSYBOX_CONFIG_INETD
+ help
+ Return 32 bit time since 1900 internal inetd service
+
+config BUSYBOX_CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME
+ bool "Support daytime service"
+ default BUSYBOX_DEFAULT_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME
+ depends on BUSYBOX_CONFIG_INETD
+ help
+ Return human-readable time internal inetd service
+
+config BUSYBOX_CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN
+ bool "Support chargen service"
+ default BUSYBOX_DEFAULT_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN
+ depends on BUSYBOX_CONFIG_INETD
+ help
+ Familiar character generator internal inetd service
+
+config BUSYBOX_CONFIG_FEATURE_INETD_RPC
+ bool "Support RPC services"
+ default BUSYBOX_DEFAULT_FEATURE_INETD_RPC
+ depends on BUSYBOX_CONFIG_INETD
+ select BUSYBOX_CONFIG_FEATURE_HAVE_RPC
+ help
+ Support Sun-RPC based services
+
+config BUSYBOX_CONFIG_IP
+ bool "ip"
+ default BUSYBOX_DEFAULT_IP
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The "ip" applet is a TCP/IP interface configuration and routing
+ utility. You generally don't need "ip" to use busybox with
+ TCP/IP.
+
+config BUSYBOX_CONFIG_FEATURE_IP_ADDRESS
+ bool "ip address"
+ default BUSYBOX_DEFAULT_FEATURE_IP_ADDRESS
+ depends on BUSYBOX_CONFIG_IP
+ help
+ Address manipulation support for the "ip" applet.
+
+config BUSYBOX_CONFIG_FEATURE_IP_LINK
+ bool "ip link"
+ default BUSYBOX_DEFAULT_FEATURE_IP_LINK
+ depends on BUSYBOX_CONFIG_IP
+ help
+ Configure network devices with "ip".
+
+config BUSYBOX_CONFIG_FEATURE_IP_ROUTE
+ bool "ip route"
+ default BUSYBOX_DEFAULT_FEATURE_IP_ROUTE
+ depends on BUSYBOX_CONFIG_IP
+ help
+ Add support for routing table management to "ip".
+
+config BUSYBOX_CONFIG_FEATURE_IP_TUNNEL
+ bool "ip tunnel"
+ default BUSYBOX_DEFAULT_FEATURE_IP_TUNNEL
+ depends on BUSYBOX_CONFIG_IP
+ help
+ Add support for tunneling commands to "ip".
+
+config BUSYBOX_CONFIG_FEATURE_IP_RULE
+ bool "ip rule"
+ default BUSYBOX_DEFAULT_FEATURE_IP_RULE
+ depends on BUSYBOX_CONFIG_IP
+ help
+ Add support for rule commands to "ip".
+
+config BUSYBOX_CONFIG_FEATURE_IP_SHORT_FORMS
+ bool "Support short forms of ip commands"
+ default BUSYBOX_DEFAULT_FEATURE_IP_SHORT_FORMS
+ depends on BUSYBOX_CONFIG_IP
+ help
+ Also support short-form of ip <OBJECT> commands:
+ ip addr -> ipaddr
+ ip link -> iplink
+ ip route -> iproute
+ ip tunnel -> iptunnel
+ ip rule -> iprule
+
+ Say N unless you desparately need the short form of the ip
+ object commands.
+
+config BUSYBOX_CONFIG_FEATURE_IP_RARE_PROTOCOLS
+ bool "Support displaying rarely used link types"
+ default BUSYBOX_DEFAULT_FEATURE_IP_RARE_PROTOCOLS
+ depends on BUSYBOX_CONFIG_IP
+ help
+ If you are not going to use links of type "frad", "econet",
+ "bif" etc, you probably don't need to enable this.
+ Ethernet, wireless, infrared, ppp/slip, ip tunnelling
+ link types are supported without this option selected.
+
+config BUSYBOX_CONFIG_IPADDR
+ bool
+ default BUSYBOX_DEFAULT_IPADDR
+ depends on BUSYBOX_CONFIG_FEATURE_IP_SHORT_FORMS && BUSYBOX_CONFIG_FEATURE_IP_ADDRESS
+
+config BUSYBOX_CONFIG_IPLINK
+ bool
+ default BUSYBOX_DEFAULT_IPLINK
+ depends on BUSYBOX_CONFIG_FEATURE_IP_SHORT_FORMS && BUSYBOX_CONFIG_FEATURE_IP_LINK
+
+config BUSYBOX_CONFIG_IPROUTE
+ bool
+ default BUSYBOX_DEFAULT_IPROUTE
+ depends on BUSYBOX_CONFIG_FEATURE_IP_SHORT_FORMS && BUSYBOX_CONFIG_FEATURE_IP_ROUTE
+
+config BUSYBOX_CONFIG_IPTUNNEL
+ bool
+ default BUSYBOX_DEFAULT_IPTUNNEL
+ depends on BUSYBOX_CONFIG_FEATURE_IP_SHORT_FORMS && BUSYBOX_CONFIG_FEATURE_IP_TUNNEL
+
+config BUSYBOX_CONFIG_IPRULE
+ bool
+ default BUSYBOX_DEFAULT_IPRULE
+ depends on BUSYBOX_CONFIG_FEATURE_IP_SHORT_FORMS && BUSYBOX_CONFIG_FEATURE_IP_RULE
+
+config BUSYBOX_CONFIG_IPCALC
+ bool "ipcalc"
+ default BUSYBOX_DEFAULT_IPCALC
+ help
+ ipcalc takes an IP address and netmask and calculates the
+ resulting broadcast, network, and host range.
+
+config BUSYBOX_CONFIG_FEATURE_IPCALC_FANCY
+ bool "Fancy IPCALC, more options, adds 1 kbyte"
+ default BUSYBOX_DEFAULT_FEATURE_IPCALC_FANCY
+ depends on BUSYBOX_CONFIG_IPCALC
+ help
+ Adds the options hostname, prefix and silent to the output of
+ "ipcalc".
+
+config BUSYBOX_CONFIG_FEATURE_IPCALC_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_IPCALC_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_IPCALC && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the ipcalc applet.
+
+config BUSYBOX_CONFIG_NETMSG
+ bool "netmsg"
+ default BUSYBOX_DEFAULT_NETMSG
+ help
+ simple program for sending udp broadcast messages
+
+config BUSYBOX_CONFIG_NETSTAT
+ bool "netstat"
+ default BUSYBOX_DEFAULT_NETSTAT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ netstat prints information about the Linux networking subsystem.
+
+config BUSYBOX_CONFIG_FEATURE_NETSTAT_WIDE
+ bool "Enable wide netstat output"
+ default BUSYBOX_DEFAULT_FEATURE_NETSTAT_WIDE
+ depends on BUSYBOX_CONFIG_NETSTAT
+ help
+ Add support for wide columns. Useful when displaying IPv6 addresses
+ (-W option).
+
+config BUSYBOX_CONFIG_FEATURE_NETSTAT_PRG
+ bool "Enable PID/Program name output"
+ default BUSYBOX_DEFAULT_FEATURE_NETSTAT_PRG
+ depends on BUSYBOX_CONFIG_NETSTAT
+ help
+ Add support for -p flag to print out PID and program name.
+ +700 bytes of code.
+
+config BUSYBOX_CONFIG_NSLOOKUP
+ bool "nslookup"
+ default BUSYBOX_DEFAULT_NSLOOKUP
+ help
+ nslookup is a tool to query Internet name servers.
+
+config BUSYBOX_CONFIG_NTPD
+ bool "ntpd"
+ default BUSYBOX_DEFAULT_NTPD
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The NTP client/server daemon.
+
+config BUSYBOX_CONFIG_FEATURE_NTPD_SERVER
+ bool "Make ntpd usable as a NTP server"
+ default BUSYBOX_DEFAULT_FEATURE_NTPD_SERVER
+ depends on BUSYBOX_CONFIG_NTPD
+ help
+ Make ntpd usable as a NTP server. If you disable this option
+ ntpd will be usable only as a NTP client.
+
+config BUSYBOX_CONFIG_FEATURE_NTPD_CONF
+ bool "Make ntpd understand /etc/ntp.conf"
+ default BUSYBOX_DEFAULT_FEATURE_NTPD_CONF
+ depends on BUSYBOX_CONFIG_NTPD
+ help
+ Make ntpd look in /etc/ntp.conf for peers. Only "server address"
+ is supported.
+
+config BUSYBOX_CONFIG_PSCAN
+ bool "pscan"
+ default BUSYBOX_DEFAULT_PSCAN
+ help
+ Simple network port scanner.
+
+config BUSYBOX_CONFIG_ROUTE
+ bool "route"
+ default BUSYBOX_DEFAULT_ROUTE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Route displays or manipulates the kernel's IP routing tables.
+
+config BUSYBOX_CONFIG_SLATTACH
+ bool "slattach"
+ default BUSYBOX_DEFAULT_SLATTACH
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ slattach is a small utility to attach network interfaces to serial
+ lines.
+
+#config TC
+# bool "tc"
+# default y
+# help
+# show / manipulate traffic control settings
+#
+#config FEATURE_TC_INGRESS
+# def_bool n
+# depends on TC
+
+config BUSYBOX_CONFIG_TCPSVD
+ bool "tcpsvd"
+ default BUSYBOX_DEFAULT_TCPSVD
+ help
+ tcpsvd listens on a TCP port and runs a program for each new
+ connection.
+
+config BUSYBOX_CONFIG_TELNET
+ bool "telnet"
+ default BUSYBOX_DEFAULT_TELNET
+ help
+ Telnet is an interface to the TELNET protocol, but is also commonly
+ used to test other simple protocols.
+
+config BUSYBOX_CONFIG_FEATURE_TELNET_TTYPE
+ bool "Pass TERM type to remote host"
+ default BUSYBOX_DEFAULT_FEATURE_TELNET_TTYPE
+ depends on BUSYBOX_CONFIG_TELNET
+ help
+ Setting this option will forward the TERM environment variable to the
+ remote host you are connecting to. This is useful to make sure that
+ things like ANSI colors and other control sequences behave.
+
+config BUSYBOX_CONFIG_FEATURE_TELNET_AUTOLOGIN
+ bool "Pass USER type to remote host"
+ default BUSYBOX_DEFAULT_FEATURE_TELNET_AUTOLOGIN
+ depends on BUSYBOX_CONFIG_TELNET
+ help
+ Setting this option will forward the USER environment variable to the
+ remote host you are connecting to. This is useful when you need to
+ log into a machine without telling the username (autologin). This
+ option enables `-a' and `-l USER' arguments.
+
+config BUSYBOX_CONFIG_TELNETD
+ bool "telnetd"
+ default BUSYBOX_DEFAULT_TELNETD
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ A daemon for the TELNET protocol, allowing you to log onto the host
+ running the daemon. Please keep in mind that the TELNET protocol
+ sends passwords in plain text. If you can't afford the space for an
+ SSH daemon and you trust your network, you may say 'y' here. As a
+ more secure alternative, you should seriously consider installing the
+ very small Dropbear SSH daemon instead:
+ http://matt.ucc.asn.au/dropbear/dropbear.html
+
+ Note that for busybox telnetd to work you need several things:
+ First of all, your kernel needs:
+ UNIX98_PTYS=y
+ DEVPTS_FS=y
+
+ Next, you need a /dev/pts directory on your root filesystem:
+
+ $ ls -ld /dev/pts
+ drwxr-xr-x 2 root root 0 Sep 23 13:21 /dev/pts/
+
+ Next you need the pseudo terminal master multiplexer /dev/ptmx:
+
+ $ ls -la /dev/ptmx
+ crw-rw-rw- 1 root tty 5, 2 Sep 23 13:55 /dev/ptmx
+
+ Any /dev/ttyp[0-9]* files you may have can be removed.
+ Next, you need to mount the devpts filesystem on /dev/pts using:
+
+ mount -t devpts devpts /dev/pts
+
+ You need to be sure that busybox has LOGIN and
+ FEATURE_SUID enabled. And finally, you should make
+ certain that Busybox has been installed setuid root:
+
+ chown root.root /bin/busybox
+ chmod 4755 /bin/busybox
+
+ with all that done, telnetd _should_ work....
+
+
+config BUSYBOX_CONFIG_FEATURE_TELNETD_STANDALONE
+ bool "Support standalone telnetd (not inetd only)"
+ default BUSYBOX_DEFAULT_FEATURE_TELNETD_STANDALONE
+ depends on BUSYBOX_CONFIG_TELNETD
+ help
+ Selecting this will make telnetd able to run standalone.
+
+config BUSYBOX_CONFIG_FEATURE_TELNETD_INETD_WAIT
+ bool "Support -w SEC option (inetd wait mode)"
+ default BUSYBOX_DEFAULT_FEATURE_TELNETD_INETD_WAIT
+ depends on BUSYBOX_CONFIG_FEATURE_TELNETD_STANDALONE
+ help
+ This option allows you to run telnetd in "inet wait" mode.
+ Example inetd.conf line (note "wait", not usual "nowait"):
+
+ telnet stream tcp wait root /bin/telnetd telnetd -w10
+
+ In this example, inetd passes _listening_ socket_ as fd 0
+ to telnetd when connection appears.
+ telnetd will wait for connections until all existing
+ connections are closed, and no new connections
+ appear during 10 seconds. Then it exits, and inetd continues
+ to listen for new connections.
+
+ This option is rarely used. "tcp nowait" is much more usual
+ way of running tcp services, including telnetd.
+ You most probably want to say N here.
+
+config BUSYBOX_CONFIG_TFTP
+ bool "tftp"
+ default BUSYBOX_DEFAULT_TFTP
+ help
+ This enables the Trivial File Transfer Protocol client program. TFTP
+ is usually used for simple, small transfers such as a root image
+ for a network-enabled bootloader.
+
+config BUSYBOX_CONFIG_TFTPD
+ bool "tftpd"
+ default BUSYBOX_DEFAULT_TFTPD
+ help
+ This enables the Trivial File Transfer Protocol server program.
+ It expects that stdin is a datagram socket and a packet
+ is already pending on it. It will exit after one transfer.
+ In other words: it should be run from inetd in nowait mode,
+ or from udpsvd. Example: "udpsvd -E 0 69 tftpd DIR"
+
+comment "Common options for tftp/tftpd"
+ depends on BUSYBOX_CONFIG_TFTP || BUSYBOX_CONFIG_TFTPD
+
+config BUSYBOX_CONFIG_FEATURE_TFTP_GET
+ bool "Enable 'tftp get' and/or tftpd upload code"
+ default BUSYBOX_DEFAULT_FEATURE_TFTP_GET
+ depends on BUSYBOX_CONFIG_TFTP || BUSYBOX_CONFIG_TFTPD
+ help
+ Add support for the GET command within the TFTP client. This allows
+ a client to retrieve a file from a TFTP server.
+ Also enable upload support in tftpd, if tftpd is selected.
+
+ Note: this option does _not_ make tftpd capable of download
+ (the usual operation people need from it)!
+
+config BUSYBOX_CONFIG_FEATURE_TFTP_PUT
+ bool "Enable 'tftp put' and/or tftpd download code"
+ default BUSYBOX_DEFAULT_FEATURE_TFTP_PUT
+ depends on BUSYBOX_CONFIG_TFTP || BUSYBOX_CONFIG_TFTPD
+ help
+ Add support for the PUT command within the TFTP client. This allows
+ a client to transfer a file to a TFTP server.
+ Also enable download support in tftpd, if tftpd is selected.
+
+config BUSYBOX_CONFIG_FEATURE_TFTP_BLOCKSIZE
+ bool "Enable 'blksize' and 'tsize' protocol options"
+ default BUSYBOX_DEFAULT_FEATURE_TFTP_BLOCKSIZE
+ depends on BUSYBOX_CONFIG_TFTP || BUSYBOX_CONFIG_TFTPD
+ help
+ Allow tftp to specify block size, and tftpd to understand
+ "blksize" and "tsize" options.
+
+config BUSYBOX_CONFIG_FEATURE_TFTP_PROGRESS_BAR
+ bool "Enable tftp progress meter"
+ default BUSYBOX_DEFAULT_FEATURE_TFTP_PROGRESS_BAR
+ depends on BUSYBOX_CONFIG_TFTP && BUSYBOX_CONFIG_FEATURE_TFTP_BLOCKSIZE
+ help
+ Show progress bar.
+
+config BUSYBOX_CONFIG_TFTP_DEBUG
+ bool "Enable debug"
+ default BUSYBOX_DEFAULT_TFTP_DEBUG
+ depends on BUSYBOX_CONFIG_TFTP || BUSYBOX_CONFIG_TFTPD
+ help
+ Make tftp[d] print debugging messages on stderr.
+ This is useful if you are diagnosing a bug in tftp[d].
+
+config BUSYBOX_CONFIG_TRACEROUTE
+ bool "traceroute"
+ default BUSYBOX_DEFAULT_TRACEROUTE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Utility to trace the route of IP packets.
+
+config BUSYBOX_CONFIG_TRACEROUTE6
+ bool "traceroute6"
+ default BUSYBOX_DEFAULT_TRACEROUTE6
+ depends on BUSYBOX_CONFIG_FEATURE_IPV6 && BUSYBOX_CONFIG_TRACEROUTE
+ help
+ Utility to trace the route of IPv6 packets.
+
+config BUSYBOX_CONFIG_FEATURE_TRACEROUTE_VERBOSE
+ bool "Enable verbose output"
+ default BUSYBOX_DEFAULT_FEATURE_TRACEROUTE_VERBOSE
+ depends on BUSYBOX_CONFIG_TRACEROUTE
+ help
+ Add some verbosity to traceroute. This includes among other things
+ hostnames and ICMP response types.
+
+config BUSYBOX_CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE
+ bool "Enable loose source route"
+ default BUSYBOX_DEFAULT_FEATURE_TRACEROUTE_SOURCE_ROUTE
+ depends on BUSYBOX_CONFIG_TRACEROUTE
+ help
+ Add option to specify a loose source route gateway
+ (8 maximum).
+
+config BUSYBOX_CONFIG_FEATURE_TRACEROUTE_USE_ICMP
+ bool "Use ICMP instead of UDP"
+ default BUSYBOX_DEFAULT_FEATURE_TRACEROUTE_USE_ICMP
+ depends on BUSYBOX_CONFIG_TRACEROUTE
+ help
+ Add option -I to use ICMP ECHO instead of UDP datagrams.
+
+config BUSYBOX_CONFIG_TUNCTL
+ bool "tunctl"
+ default BUSYBOX_DEFAULT_TUNCTL
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ tunctl creates or deletes tun devices.
+
+config BUSYBOX_CONFIG_FEATURE_TUNCTL_UG
+ bool "Support owner:group assignment"
+ default BUSYBOX_DEFAULT_FEATURE_TUNCTL_UG
+ depends on BUSYBOX_CONFIG_TUNCTL
+ help
+ Allow to specify owner and group of newly created interface.
+ 340 bytes of pure bloat. Say no here.
+
+source package/utils/busybox/config/networking/udhcp/Config.in
+
+config BUSYBOX_CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS
+ string "ifup udhcpc command line options"
+ default BUSYBOX_DEFAULT_IFUPDOWN_UDHCPC_CMD_OPTIONS
+ depends on BUSYBOX_CONFIG_IFUPDOWN && BUSYBOX_CONFIG_UDHCPC
+ help
+ Command line options to pass to udhcpc from ifup.
+ Intended to alter options not available in /etc/network/interfaces.
+ (IE: --syslog --background etc...)
+
+config BUSYBOX_CONFIG_UDPSVD
+ bool "udpsvd"
+ default BUSYBOX_DEFAULT_UDPSVD
+ help
+ udpsvd listens on an UDP port and runs a program for each new
+ connection.
+
+config BUSYBOX_CONFIG_VCONFIG
+ bool "vconfig"
+ default BUSYBOX_DEFAULT_VCONFIG
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Creates, removes, and configures VLAN interfaces
+
+config BUSYBOX_CONFIG_WGET
+ bool "wget"
+ default BUSYBOX_DEFAULT_WGET
+ help
+ wget is a utility for non-interactive download of files from HTTP
+ and FTP servers.
+
+config BUSYBOX_CONFIG_FEATURE_WGET_STATUSBAR
+ bool "Enable a nifty process meter (+2k)"
+ default BUSYBOX_DEFAULT_FEATURE_WGET_STATUSBAR
+ depends on BUSYBOX_CONFIG_WGET
+ help
+ Enable the transfer progress bar for wget transfers.
+
+config BUSYBOX_CONFIG_FEATURE_WGET_AUTHENTICATION
+ bool "Enable HTTP authentication"
+ default BUSYBOX_DEFAULT_FEATURE_WGET_AUTHENTICATION
+ depends on BUSYBOX_CONFIG_WGET
+ help
+ Support authenticated HTTP transfers.
+
+config BUSYBOX_CONFIG_FEATURE_WGET_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_WGET_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_WGET && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the wget applet.
+
+config BUSYBOX_CONFIG_FEATURE_WGET_TIMEOUT
+ bool "Enable timeout option -T SEC"
+ default BUSYBOX_DEFAULT_FEATURE_WGET_TIMEOUT
+ depends on BUSYBOX_CONFIG_WGET
+ help
+ Supports network read and connect timeouts for wget,
+ so that wget will give up and timeout, through the -T
+ command line option.
+
+ Currently only connect and network data read timeout are
+ supported (i.e., timeout is not applied to the DNS query). When
+ FEATURE_WGET_LONG_OPTIONS is also enabled, the --timeout option
+ will work in addition to -T.
+
+config BUSYBOX_CONFIG_ZCIP
+ bool "zcip"
+ default BUSYBOX_DEFAULT_ZCIP
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927.
+ It's a daemon that allocates and defends a dynamically assigned
+ address on the 169.254/16 network, requiring no system administrator.
+
+ See http://www.zeroconf.org for further details, and "zcip.script"
+ in the busybox examples.
+
+endmenu
diff --git a/package/utils/busybox/config/networking/udhcp/Config.in b/package/utils/busybox/config/networking/udhcp/Config.in
new file mode 100644
index 0000000..4f48400
--- /dev/null
+++ b/package/utils/busybox/config/networking/udhcp/Config.in
@@ -0,0 +1,171 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+config BUSYBOX_CONFIG_UDHCPC6
+ bool "udhcp client for DHCPv6 (udhcpc6)"
+ default BUSYBOX_DEFAULT_UDHCPC6 # not yet ready
+ depends on BUSYBOX_CONFIG_FEATURE_IPV6
+ help
+ udhcpc6 is a DHCPv6 client
+
+config BUSYBOX_CONFIG_UDHCPD
+ bool "udhcp server (udhcpd)"
+ default BUSYBOX_DEFAULT_UDHCPD
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ udhcpd is a DHCP server geared primarily toward embedded systems,
+ while striving to be fully functional and RFC compliant.
+
+config BUSYBOX_CONFIG_DHCPRELAY
+ bool "dhcprelay"
+ default BUSYBOX_DEFAULT_DHCPRELAY
+ depends on BUSYBOX_CONFIG_UDHCPD
+ help
+ dhcprelay listens for dhcp requests on one or more interfaces
+ and forwards these requests to a different interface or dhcp
+ server.
+
+config BUSYBOX_CONFIG_DUMPLEASES
+ bool "Lease display utility (dumpleases)"
+ default BUSYBOX_DEFAULT_DUMPLEASES
+ depends on BUSYBOX_CONFIG_UDHCPD
+ help
+ dumpleases displays the leases written out by the udhcpd server.
+ Lease times are stored in the file by time remaining in lease, or
+ by the absolute time that it expires in seconds from epoch.
+
+config BUSYBOX_CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY
+ bool "Rewrite the lease file at every new acknowledge"
+ default BUSYBOX_DEFAULT_FEATURE_UDHCPD_WRITE_LEASES_EARLY
+ depends on BUSYBOX_CONFIG_UDHCPD
+ help
+ If selected, udhcpd will write a new file with leases every
+ time a new lease has been accepted, thus eliminating the need
+ to send SIGUSR1 for the initial writing or updating. Any timed
+ rewriting remains undisturbed.
+
+config BUSYBOX_CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC
+ bool "Select IP address based on client MAC"
+ default BUSYBOX_DEFAULT_FEATURE_UDHCPD_BASE_IP_ON_MAC
+ depends on BUSYBOX_CONFIG_UDHCPD
+ help
+ If selected, udhcpd will base its selection of IP address to offer
+ on the client's hardware address. Otherwise udhcpd uses the next
+ consecutive free address.
+
+ This reduces the frequency of IP address changes for clients
+ which let their lease expire, and makes consecutive DHCPOFFERS
+ for the same client to (almost always) contain the same
+ IP address.
+
+config BUSYBOX_CONFIG_DHCPD_LEASES_FILE
+ string "Absolute path to lease file"
+ default BUSYBOX_DEFAULT_DHCPD_LEASES_FILE
+ depends on BUSYBOX_CONFIG_UDHCPD
+ help
+ udhcpd stores addresses in a lease file. This is the absolute path
+ of the file. Normally it is safe to leave it untouched.
+
+config BUSYBOX_CONFIG_UDHCPC
+ bool "udhcp client (udhcpc)"
+ default BUSYBOX_DEFAULT_UDHCPC
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ udhcpc is a DHCP client geared primarily toward embedded systems,
+ while striving to be fully functional and RFC compliant.
+
+ The udhcp client negotiates a lease with the DHCP server and
+ runs a script when a lease is obtained or lost.
+
+config BUSYBOX_CONFIG_FEATURE_UDHCPC_ARPING
+ bool "Verify that the offered address is free, using ARP ping"
+ default BUSYBOX_DEFAULT_FEATURE_UDHCPC_ARPING
+ depends on BUSYBOX_CONFIG_UDHCPC
+ help
+ If selected, udhcpc will send ARP probes and make sure
+ the offered address is really not in use by anyone. The client
+ will DHCPDECLINE the offer if the address is in use,
+ and restart the discover process.
+
+config BUSYBOX_CONFIG_FEATURE_UDHCPC_SANITIZEOPT
+ bool "Do not pass malformed host and domain names"
+ default BUSYBOX_DEFAULT_FEATURE_UDHCPC_SANITIZEOPT
+ depends on BUSYBOX_CONFIG_UDHCPC
+ help
+ If selected, udhcpc will check some options (such as option 12 -
+ hostname) and if they don't look like valid hostnames
+ (for example, if they start with dash or contain spaces),
+ they will be replaced with string "bad" when exporting
+ to the environment.
+
+config BUSYBOX_CONFIG_FEATURE_UDHCP_PORT
+ bool "Enable '-P port' option for udhcpd and udhcpc"
+ default BUSYBOX_DEFAULT_FEATURE_UDHCP_PORT
+ depends on BUSYBOX_CONFIG_UDHCPD || BUSYBOX_CONFIG_UDHCPC
+ help
+ At the cost of ~300 bytes, enables -P port option.
+ This feature is typically not needed.
+
+config BUSYBOX_CONFIG_UDHCP_DEBUG
+ int "Maximum verbosity level for udhcp applets (0..9)"
+ default BUSYBOX_DEFAULT_UDHCP_DEBUG
+ range 0 9
+ depends on BUSYBOX_CONFIG_UDHCPD || BUSYBOX_CONFIG_UDHCPC || BUSYBOX_CONFIG_DHCPRELAY
+ help
+ Verbosity can be increased with multiple -v options.
+ This option controls how high it can be cranked up.
+
+ Bigger values result in bigger code. Levels above 1
+ are very verbose and useful for debugging only.
+
+config BUSYBOX_CONFIG_FEATURE_UDHCP_RFC3397
+ bool "Support for RFC3397 domain search (experimental)"
+ default BUSYBOX_DEFAULT_FEATURE_UDHCP_RFC3397
+ depends on BUSYBOX_CONFIG_UDHCPD || BUSYBOX_CONFIG_UDHCPC
+ help
+ If selected, both client and server will support passing of domain
+ search lists via option 119, specified in RFC 3397,
+ and SIP servers option 120, specified in RFC 3361.
+
+config BUSYBOX_CONFIG_FEATURE_UDHCP_8021Q
+ bool "Support for 802.1Q VLAN parameters"
+ default BUSYBOX_DEFAULT_FEATURE_UDHCP_8021Q
+ depends on BUSYBOX_CONFIG_UDHCPD || BUSYBOX_CONFIG_UDHCPC
+ help
+ If selected, both client and server will support passing of VLAN
+ ID and priority via options 132 and 133 as per 802.1Q.
+
+config BUSYBOX_CONFIG_UDHCPC_DEFAULT_SCRIPT
+ string "Absolute path to config script"
+ default BUSYBOX_DEFAULT_UDHCPC_DEFAULT_SCRIPT
+ depends on BUSYBOX_CONFIG_UDHCPC
+ help
+ This script is called after udhcpc receives an answer. See
+ examples/udhcp for a working example. Normally it is safe
+ to leave this untouched.
+
+config BUSYBOX_CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS
+ int "DHCP options slack buffer size"
+ default BUSYBOX_DEFAULT_UDHCPC_SLACK_FOR_BUGGY_SERVERS
+ range 0 924
+ depends on BUSYBOX_CONFIG_UDHCPD || BUSYBOX_CONFIG_UDHCPC
+ help
+ Some buggy DHCP servers send DHCP offer packets with option
+ field larger than we expect (which might also be considered a
+ buffer overflow attempt). These packets are normally discarded.
+ If circumstances beyond your control force you to support such
+ servers, this may help. The upper limit (924) makes dhcpc accept
+ even 1500 byte packets (maximum-sized ethernet packets).
+
+ This option does not make dhcp[cd] emit non-standard
+ sized packets.
+
+ Known buggy DHCP servers:
+ 3Com OfficeConnect Remote 812 ADSL Router:
+ seems to confuse maximum allowed UDP packet size with
+ maximum size of entire IP packet, and sends packets which are
+ 28 bytes too large.
+ Seednet (ISP) VDSL: sends packets 2 bytes too large.
diff --git a/package/utils/busybox/config/printutils/Config.in b/package/utils/busybox/config/printutils/Config.in
new file mode 100644
index 0000000..cccc4a5
--- /dev/null
+++ b/package/utils/busybox/config/printutils/Config.in
@@ -0,0 +1,28 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Print Utilities"
+
+
+config BUSYBOX_CONFIG_LPD
+ bool "lpd"
+ default BUSYBOX_DEFAULT_LPD
+ help
+ lpd is a print spooling daemon.
+
+config BUSYBOX_CONFIG_LPR
+ bool "lpr"
+ default BUSYBOX_DEFAULT_LPR
+ help
+ lpr sends files (or standard input) to a print spooling daemon.
+
+config BUSYBOX_CONFIG_LPQ
+ bool "lpq"
+ default BUSYBOX_DEFAULT_LPQ
+ help
+ lpq is a print spool queue examination and manipulation program.
+
+endmenu
diff --git a/package/utils/busybox/config/procps/Config.in b/package/utils/busybox/config/procps/Config.in
new file mode 100644
index 0000000..6eafbda
--- /dev/null
+++ b/package/utils/busybox/config/procps/Config.in
@@ -0,0 +1,273 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Process Utilities"
+
+config BUSYBOX_CONFIG_IOSTAT
+ bool "iostat"
+ default BUSYBOX_DEFAULT_IOSTAT
+ help
+ Report CPU and I/O statistics
+config BUSYBOX_CONFIG_LSOF
+ bool "lsof"
+ default BUSYBOX_DEFAULT_LSOF
+ help
+ Show open files in the format of:
+ PID <TAB> /path/to/executable <TAB> /path/to/opened/file
+config BUSYBOX_CONFIG_MPSTAT
+ bool "mpstat"
+ default BUSYBOX_DEFAULT_MPSTAT
+ help
+ Per-processor statistics
+config BUSYBOX_CONFIG_NMETER
+ bool "nmeter"
+ default BUSYBOX_DEFAULT_NMETER
+ help
+ Prints selected system stats continuously, one line per update.
+config BUSYBOX_CONFIG_PMAP
+ bool "pmap"
+ default BUSYBOX_DEFAULT_PMAP
+ help
+ Display processes' memory mappings.
+config BUSYBOX_CONFIG_POWERTOP
+ bool "powertop"
+ default BUSYBOX_DEFAULT_POWERTOP
+ help
+ Analyze power consumption on Intel-based laptops
+config BUSYBOX_CONFIG_PSTREE
+ bool "pstree"
+ default BUSYBOX_DEFAULT_PSTREE
+ help
+ Display a tree of processes.
+config BUSYBOX_CONFIG_PWDX
+ bool "pwdx"
+ default BUSYBOX_DEFAULT_PWDX
+ help
+ Report current working directory of a process
+config BUSYBOX_CONFIG_SMEMCAP
+ bool "smemcap"
+ default BUSYBOX_DEFAULT_SMEMCAP
+ help
+ smemcap is a tool for capturing process data for smem,
+ a memory usage statistic tool.
+config BUSYBOX_CONFIG_TOP
+ bool "top"
+ default BUSYBOX_DEFAULT_TOP
+ help
+ The top program provides a dynamic real-time view of a running
+ system.
+
+config BUSYBOX_CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
+ bool "Show CPU per-process usage percentage"
+ default BUSYBOX_DEFAULT_FEATURE_TOP_CPU_USAGE_PERCENTAGE
+ depends on BUSYBOX_CONFIG_TOP
+ help
+ Make top display CPU usage for each process.
+ This adds about 2k.
+
+config BUSYBOX_CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS
+ bool "Show CPU global usage percentage"
+ default BUSYBOX_DEFAULT_FEATURE_TOP_CPU_GLOBAL_PERCENTS
+ depends on BUSYBOX_CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
+ help
+ Makes top display "CPU: NN% usr NN% sys..." line.
+ This adds about 0.5k.
+
+config BUSYBOX_CONFIG_FEATURE_TOP_SMP_CPU
+ bool "SMP CPU usage display ('c' key)"
+ default BUSYBOX_DEFAULT_FEATURE_TOP_SMP_CPU
+ depends on BUSYBOX_CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS
+ help
+ Allow 'c' key to switch between individual/cumulative CPU stats
+ This adds about 0.5k.
+
+config BUSYBOX_CONFIG_FEATURE_TOP_DECIMALS
+ bool "Show 1/10th of a percent in CPU/mem statistics"
+ default BUSYBOX_DEFAULT_FEATURE_TOP_DECIMALS
+ depends on BUSYBOX_CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE
+ help
+ Show 1/10th of a percent in CPU/mem statistics.
+ This adds about 0.3k.
+
+config BUSYBOX_CONFIG_FEATURE_TOP_SMP_PROCESS
+ bool "Show CPU process runs on ('j' field)"
+ default BUSYBOX_DEFAULT_FEATURE_TOP_SMP_PROCESS
+ depends on BUSYBOX_CONFIG_TOP
+ help
+ Show CPU where process was last found running on.
+ This is the 'j' field.
+
+config BUSYBOX_CONFIG_FEATURE_TOPMEM
+ bool "Topmem command ('s' key)"
+ default BUSYBOX_DEFAULT_FEATURE_TOPMEM
+ depends on BUSYBOX_CONFIG_TOP
+ help
+ Enable 's' in top (gives lots of memory info).
+config BUSYBOX_CONFIG_UPTIME
+ bool "uptime"
+ default BUSYBOX_DEFAULT_UPTIME
+ select BUSYBOX_CONFIG_PLATFORM_LINUX #sysinfo()
+ help
+ uptime gives a one line display of the current time, how long
+ the system has been running, how many users are currently logged
+ on, and the system load averages for the past 1, 5, and 15 minutes.
+
+config BUSYBOX_CONFIG_FEATURE_UPTIME_UTMP_SUPPORT
+ bool "Support for showing the number of users"
+ default BUSYBOX_DEFAULT_FEATURE_UPTIME_UTMP_SUPPORT
+ depends on BUSYBOX_CONFIG_UPTIME && BUSYBOX_CONFIG_FEATURE_UTMP
+ help
+ Makes uptime display the number of users currently logged on.
+
+config BUSYBOX_CONFIG_FREE
+ bool "free"
+ default BUSYBOX_DEFAULT_FREE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX #sysinfo()
+ help
+ free displays the total amount of free and used physical and swap
+ memory in the system, as well as the buffers used by the kernel.
+ The shared memory column should be ignored; it is obsolete.
+
+config BUSYBOX_CONFIG_FUSER
+ bool "fuser"
+ default BUSYBOX_DEFAULT_FUSER
+ help
+ fuser lists all PIDs (Process IDs) that currently have a given
+ file open. fuser can also list all PIDs that have a given network
+ (TCP or UDP) port open.
+
+config BUSYBOX_CONFIG_KILL
+ bool "kill"
+ default BUSYBOX_DEFAULT_KILL
+ help
+ The command kill sends the specified signal to the specified
+ process or process group. If no signal is specified, the TERM
+ signal is sent.
+
+config BUSYBOX_CONFIG_KILLALL
+ bool "killall"
+ default BUSYBOX_DEFAULT_KILLALL
+ depends on BUSYBOX_CONFIG_KILL
+ help
+ killall sends a signal to all processes running any of the
+ specified commands. If no signal name is specified, SIGTERM is
+ sent.
+
+config BUSYBOX_CONFIG_KILLALL5
+ bool "killall5"
+ default BUSYBOX_DEFAULT_KILLALL5
+ depends on BUSYBOX_CONFIG_KILL
+
+config BUSYBOX_CONFIG_PGREP
+ bool "pgrep"
+ default BUSYBOX_DEFAULT_PGREP
+ help
+ Look for processes by name.
+
+config BUSYBOX_CONFIG_PIDOF
+ bool "pidof"
+ default BUSYBOX_DEFAULT_PIDOF
+ help
+ Pidof finds the process id's (pids) of the named programs. It prints
+ those id's on the standard output.
+
+config BUSYBOX_CONFIG_FEATURE_PIDOF_SINGLE
+ bool "Enable argument for single shot (-s)"
+ default BUSYBOX_DEFAULT_FEATURE_PIDOF_SINGLE
+ depends on BUSYBOX_CONFIG_PIDOF
+ help
+ Support argument '-s' for returning only the first pid found.
+
+config BUSYBOX_CONFIG_FEATURE_PIDOF_OMIT
+ bool "Enable argument for omitting pids (-o)"
+ default BUSYBOX_DEFAULT_FEATURE_PIDOF_OMIT
+ depends on BUSYBOX_CONFIG_PIDOF
+ help
+ Support argument '-o' for omitting the given pids in output.
+ The special pid %PPID can be used to name the parent process
+ of the pidof, in other words the calling shell or shell script.
+
+config BUSYBOX_CONFIG_PKILL
+ bool "pkill"
+ default BUSYBOX_DEFAULT_PKILL
+ help
+ Send signals to processes by name.
+
+config BUSYBOX_CONFIG_PS
+ bool "ps"
+ default BUSYBOX_DEFAULT_PS
+ help
+ ps gives a snapshot of the current processes.
+
+config BUSYBOX_CONFIG_FEATURE_PS_WIDE
+ bool "Enable wide output option (-w)"
+ default BUSYBOX_DEFAULT_FEATURE_PS_WIDE
+ depends on BUSYBOX_CONFIG_PS && !BUSYBOX_CONFIG_DESKTOP
+ help
+ Support argument 'w' for wide output.
+ If given once, 132 chars are printed, and if given more
+ than once, the length is unlimited.
+
+config BUSYBOX_CONFIG_FEATURE_PS_LONG
+ bool "Enable long output option (-l)"
+ default BUSYBOX_DEFAULT_FEATURE_PS_LONG
+ depends on BUSYBOX_CONFIG_PS && !BUSYBOX_CONFIG_DESKTOP
+ help
+ Support argument 'l' for long output.
+ Adds fields PPID, RSS, START, TIME & TTY
+
+config BUSYBOX_CONFIG_FEATURE_PS_TIME
+ bool "Enable time and elapsed time output"
+ default BUSYBOX_DEFAULT_FEATURE_PS_TIME
+ depends on BUSYBOX_CONFIG_PS && BUSYBOX_CONFIG_DESKTOP
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Support -o time and -o etime output specifiers.
+
+config BUSYBOX_CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS
+ bool "Enable additional ps columns"
+ default BUSYBOX_DEFAULT_FEATURE_PS_ADDITIONAL_COLUMNS
+ depends on BUSYBOX_CONFIG_PS && BUSYBOX_CONFIG_DESKTOP
+ help
+ Support -o rgroup, -o ruser, -o nice output specifiers.
+
+config BUSYBOX_CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS
+ bool "Support Linux prior to 2.4.0 and non-ELF systems"
+ default BUSYBOX_DEFAULT_FEATURE_PS_UNUSUAL_SYSTEMS
+ depends on BUSYBOX_CONFIG_FEATURE_PS_TIME
+ help
+ Include support for measuring HZ on old kernels and non-ELF systems
+ (if you are on Linux 2.4.0+ and use ELF, you don't need this)
+
+config BUSYBOX_CONFIG_RENICE
+ bool "renice"
+ default BUSYBOX_DEFAULT_RENICE
+ help
+ Renice alters the scheduling priority of one or more running
+ processes.
+
+config BUSYBOX_CONFIG_BB_SYSCTL
+ bool "sysctl"
+ default BUSYBOX_DEFAULT_BB_SYSCTL
+ help
+ Configure kernel parameters at runtime.
+
+config BUSYBOX_CONFIG_FEATURE_SHOW_THREADS
+ bool "Support for showing threads in ps/pstree/top"
+ default BUSYBOX_DEFAULT_FEATURE_SHOW_THREADS
+ depends on BUSYBOX_CONFIG_PS || BUSYBOX_CONFIG_TOP || BUSYBOX_CONFIG_PSTREE
+ help
+ Enables the ps -T option, showing of threads in pstree,
+ and 'h' command in top.
+
+config BUSYBOX_CONFIG_WATCH
+ bool "watch"
+ default BUSYBOX_DEFAULT_WATCH
+ help
+ watch is used to execute a program periodically, showing
+ output to the screen.
+
+endmenu
diff --git a/package/utils/busybox/config/runit/Config.in b/package/utils/busybox/config/runit/Config.in
new file mode 100644
index 0000000..8074fb1
--- /dev/null
+++ b/package/utils/busybox/config/runit/Config.in
@@ -0,0 +1,89 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Runit Utilities"
+
+
+config BUSYBOX_CONFIG_RUNSV
+ bool "runsv"
+ default BUSYBOX_DEFAULT_RUNSV
+ help
+ runsv starts and monitors a service and optionally an appendant log
+ service.
+
+config BUSYBOX_CONFIG_RUNSVDIR
+ bool "runsvdir"
+ default BUSYBOX_DEFAULT_RUNSVDIR
+ help
+ runsvdir starts a runsv process for each subdirectory, or symlink to
+ a directory, in the services directory dir, up to a limit of 1000
+ subdirectories, and restarts a runsv process if it terminates.
+
+config BUSYBOX_CONFIG_FEATURE_RUNSVDIR_LOG
+ bool "Enable scrolling argument log"
+ depends on BUSYBOX_CONFIG_RUNSVDIR
+ default BUSYBOX_DEFAULT_FEATURE_RUNSVDIR_LOG
+ help
+ Enable feature where second parameter of runsvdir holds last error
+ message (viewable via top/ps). Otherwise (feature is off
+ or no parameter), error messages go to stderr only.
+
+config BUSYBOX_CONFIG_SV
+ bool "sv"
+ default BUSYBOX_DEFAULT_SV
+ help
+ sv reports the current status and controls the state of services
+ monitored by the runsv supervisor.
+
+config BUSYBOX_CONFIG_SV_DEFAULT_SERVICE_DIR
+ string "Default directory for services"
+ default BUSYBOX_DEFAULT_SV_DEFAULT_SERVICE_DIR
+ depends on BUSYBOX_CONFIG_SV
+ help
+ Default directory for services.
+ Defaults to "/var/service"
+
+config BUSYBOX_CONFIG_SVLOGD
+ bool "svlogd"
+ default BUSYBOX_DEFAULT_SVLOGD
+ help
+ svlogd continuously reads log data from its standard input, optionally
+ filters log messages, and writes the data to one or more automatically
+ rotated logs.
+
+config BUSYBOX_CONFIG_CHPST
+ bool "chpst"
+ default BUSYBOX_DEFAULT_CHPST
+ help
+ chpst changes the process state according to the given options, and
+ execs specified program.
+
+config BUSYBOX_CONFIG_SETUIDGID
+ bool "setuidgid"
+ default BUSYBOX_DEFAULT_SETUIDGID
+ help
+ Sets soft resource limits as specified by options
+
+config BUSYBOX_CONFIG_ENVUIDGID
+ bool "envuidgid"
+ default BUSYBOX_DEFAULT_ENVUIDGID
+ help
+ Sets $UID to account's uid and $GID to account's gid
+
+config BUSYBOX_CONFIG_ENVDIR
+ bool "envdir"
+ default BUSYBOX_DEFAULT_ENVDIR
+ help
+ Sets various environment variables as specified by files
+ in the given directory
+
+config BUSYBOX_CONFIG_SOFTLIMIT
+ bool "softlimit"
+ default BUSYBOX_DEFAULT_SOFTLIMIT
+ help
+ Sets soft resource limits as specified by options
+
+endmenu
diff --git a/package/utils/busybox/config/selinux/Config.in b/package/utils/busybox/config/selinux/Config.in
new file mode 100644
index 0000000..3340e4b
--- /dev/null
+++ b/package/utils/busybox/config/selinux/Config.in
@@ -0,0 +1,124 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "SELinux Utilities"
+ depends on BUSYBOX_CONFIG_SELINUX
+
+
+config BUSYBOX_CONFIG_CHCON
+ bool "chcon"
+ default BUSYBOX_DEFAULT_CHCON
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support to change the security context of file.
+
+config BUSYBOX_CONFIG_FEATURE_CHCON_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_CHCON_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_CHCON && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the chcon applet.
+
+config BUSYBOX_CONFIG_GETENFORCE
+ bool "getenforce"
+ default BUSYBOX_DEFAULT_GETENFORCE
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support to get the current mode of SELinux.
+
+config BUSYBOX_CONFIG_GETSEBOOL
+ bool "getsebool"
+ default BUSYBOX_DEFAULT_GETSEBOOL
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support to get SELinux boolean values.
+
+config BUSYBOX_CONFIG_LOAD_POLICY
+ bool "load_policy"
+ default BUSYBOX_DEFAULT_LOAD_POLICY
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support to load SELinux policy.
+
+config BUSYBOX_CONFIG_MATCHPATHCON
+ bool "matchpathcon"
+ default BUSYBOX_DEFAULT_MATCHPATHCON
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support to get default security context of the
+ specified path from the file contexts configuration.
+
+config BUSYBOX_CONFIG_RESTORECON
+ bool "restorecon"
+ default BUSYBOX_DEFAULT_RESTORECON
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support to relabel files. The feature is almost
+ the same as setfiles, but usage is a little different.
+
+config BUSYBOX_CONFIG_RUNCON
+ bool "runcon"
+ default BUSYBOX_DEFAULT_RUNCON
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support to run command in speficied security context.
+
+config BUSYBOX_CONFIG_FEATURE_RUNCON_LONG_OPTIONS
+ bool "Enable long options"
+ default BUSYBOX_DEFAULT_FEATURE_RUNCON_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_RUNCON && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ Support long options for the runcon applet.
+
+config BUSYBOX_CONFIG_SELINUXENABLED
+ bool "selinuxenabled"
+ default BUSYBOX_DEFAULT_SELINUXENABLED
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support for this command to be used within shell scripts
+ to determine if selinux is enabled.
+
+config BUSYBOX_CONFIG_SETENFORCE
+ bool "setenforce"
+ default BUSYBOX_DEFAULT_SETENFORCE
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support to modify the mode SELinux is running in.
+
+config BUSYBOX_CONFIG_SETFILES
+ bool "setfiles"
+ default BUSYBOX_DEFAULT_SETFILES
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support to modify to relabel files.
+ Notice: If you built libselinux with -D_FILE_OFFSET_BITS=64,
+ (It is default in libselinux's Makefile), you _must_ enable
+ CONFIG_LFS.
+
+config BUSYBOX_CONFIG_FEATURE_SETFILES_CHECK_OPTION
+ bool "Enable check option"
+ default BUSYBOX_DEFAULT_FEATURE_SETFILES_CHECK_OPTION
+ depends on BUSYBOX_CONFIG_SETFILES
+ help
+ Support "-c" option (check the validity of the contexts against
+ the specified binary policy) for setfiles. Requires libsepol.
+
+config BUSYBOX_CONFIG_SETSEBOOL
+ bool "setsebool"
+ default BUSYBOX_DEFAULT_SETSEBOOL
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Enable support for change boolean.
+ semanage and -P option is not supported yet.
+
+config BUSYBOX_CONFIG_SESTATUS
+ bool "sestatus"
+ default BUSYBOX_DEFAULT_SESTATUS
+ depends on BUSYBOX_CONFIG_SELINUX
+ help
+ Displays the status of SELinux.
+
+endmenu
diff --git a/package/utils/busybox/config/shell/Config.in b/package/utils/busybox/config/shell/Config.in
new file mode 100644
index 0000000..69ecf14
--- /dev/null
+++ b/package/utils/busybox/config/shell/Config.in
@@ -0,0 +1,444 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Shells"
+
+config BUSYBOX_CONFIG_ASH
+ bool "ash"
+ default BUSYBOX_DEFAULT_ASH
+ depends on !BUSYBOX_CONFIG_NOMMU
+ help
+ Tha 'ash' shell adds about 60k in the default configuration and is
+ the most complete and most pedantically correct shell included with
+ busybox. This shell is actually a derivative of the Debian 'dash'
+ shell (by Herbert Xu), which was created by porting the 'ash' shell
+ (written by Kenneth Almquist) from NetBSD.
+
+config BUSYBOX_CONFIG_ASH_BASH_COMPAT
+ bool "bash-compatible extensions"
+ default BUSYBOX_DEFAULT_ASH_BASH_COMPAT
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable bash-compatible extensions.
+
+config BUSYBOX_CONFIG_ASH_IDLE_TIMEOUT
+ bool "Idle timeout variable"
+ default BUSYBOX_DEFAULT_ASH_IDLE_TIMEOUT
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enables bash-like auto-logout after $TMOUT seconds of idle time.
+
+config BUSYBOX_CONFIG_ASH_JOB_CONTROL
+ bool "Job control"
+ default BUSYBOX_DEFAULT_ASH_JOB_CONTROL
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable job control in the ash shell.
+
+config BUSYBOX_CONFIG_ASH_ALIAS
+ bool "Alias support"
+ default BUSYBOX_DEFAULT_ASH_ALIAS
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable alias support in the ash shell.
+
+config BUSYBOX_CONFIG_ASH_GETOPTS
+ bool "Builtin getopt to parse positional parameters"
+ default BUSYBOX_DEFAULT_ASH_GETOPTS
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable support for getopts builtin in ash.
+
+config BUSYBOX_CONFIG_ASH_BUILTIN_ECHO
+ bool "Builtin version of 'echo'"
+ default BUSYBOX_DEFAULT_ASH_BUILTIN_ECHO
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable support for echo builtin in ash.
+
+config BUSYBOX_CONFIG_ASH_BUILTIN_PRINTF
+ bool "Builtin version of 'printf'"
+ default BUSYBOX_DEFAULT_ASH_BUILTIN_PRINTF
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable support for printf builtin in ash.
+
+config BUSYBOX_CONFIG_ASH_BUILTIN_TEST
+ bool "Builtin version of 'test'"
+ default BUSYBOX_DEFAULT_ASH_BUILTIN_TEST
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable support for test builtin in ash.
+
+config BUSYBOX_CONFIG_ASH_HELP
+ bool "help builtin"
+ default BUSYBOX_DEFAULT_ASH_HELP
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable help builtin in ash.
+
+config BUSYBOX_CONFIG_ASH_CMDCMD
+ bool "'command' command to override shell builtins"
+ default BUSYBOX_DEFAULT_ASH_CMDCMD
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable support for the ash 'command' builtin, which allows
+ you to run the specified command with the specified arguments,
+ even when there is an ash builtin command with the same name.
+
+config BUSYBOX_CONFIG_ASH_MAIL
+ bool "Check for new mail on interactive shells"
+ default BUSYBOX_DEFAULT_ASH_MAIL
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable "check for new mail" function in the ash shell.
+
+config BUSYBOX_CONFIG_ASH_OPTIMIZE_FOR_SIZE
+ bool "Optimize for size instead of speed"
+ default BUSYBOX_DEFAULT_ASH_OPTIMIZE_FOR_SIZE
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Compile ash for reduced size at the price of speed.
+
+config BUSYBOX_CONFIG_ASH_RANDOM_SUPPORT
+ bool "Pseudorandom generator and $RANDOM variable"
+ default BUSYBOX_DEFAULT_ASH_RANDOM_SUPPORT
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ Enable pseudorandom generator and dynamic variable "$RANDOM".
+ Each read of "$RANDOM" will generate a new pseudorandom value.
+ You can reset the generator by using a specified start value.
+ After "unset RANDOM" the generator will switch off and this
+ variable will no longer have special treatment.
+
+config BUSYBOX_CONFIG_ASH_EXPAND_PRMT
+ bool "Expand prompt string"
+ default BUSYBOX_DEFAULT_ASH_EXPAND_PRMT
+ depends on BUSYBOX_CONFIG_ASH
+ help
+ "PS#" may contain volatile content, such as backquote commands.
+ This option recreates the prompt string from the environment
+ variable each time it is displayed.
+
+config BUSYBOX_CONFIG_CTTYHACK
+ bool "cttyhack"
+ default BUSYBOX_DEFAULT_CTTYHACK
+ help
+ One common problem reported on the mailing list is the "can't
+ access tty; job control turned off" error message, which typically
+ appears when one tries to use a shell with stdin/stdout on
+ /dev/console.
+ This device is special - it cannot be a controlling tty.
+
+ The proper solution is to use the correct device instead of
+ /dev/console.
+
+ cttyhack provides a "quick and dirty" solution to this problem.
+ It analyzes stdin with various ioctls, trying to determine whether
+ it is a /dev/ttyN or /dev/ttySN (virtual terminal or serial line).
+ On Linux it also checks sysfs for a pointer to the active console.
+ If cttyhack is able to find the real console device, it closes
+ stdin/out/err and reopens that device.
+ Then it executes the given program. Opening the device will make
+ that device a controlling tty. This may require cttyhack
+ to be a session leader.
+
+ Example for /etc/inittab (for busybox init):
+
+ ::respawn:/bin/cttyhack /bin/sh
+
+ Starting an interactive shell from boot shell script:
+
+ setsid cttyhack sh
+
+ Giving controlling tty to shell running with PID 1:
+
+ # exec cttyhack sh
+
+ Without cttyhack, you need to know exact tty name,
+ and do something like this:
+
+ # exec setsid sh -c 'exec sh </dev/tty1 >/dev/tty1 2>&1'
+
+ Starting getty on a controlling tty from a shell script:
+
+ # getty 115200 $(cttyhack)
+config BUSYBOX_CONFIG_HUSH
+ bool "hush"
+ default BUSYBOX_DEFAULT_HUSH
+ help
+ hush is a small shell (25k). It handles the normal flow control
+ constructs such as if/then/elif/else/fi, for/in/do/done, while loops,
+ case/esac. Redirections, here documents, $((arithmetic))
+ and functions are supported.
+
+ It will compile and work on no-mmu systems.
+
+ It does not handle select, aliases, tilde expansion,
+ &>file and >&file redirection of stdout+stderr.
+
+config BUSYBOX_CONFIG_HUSH_BASH_COMPAT
+ bool "bash-compatible extensions"
+ default BUSYBOX_DEFAULT_HUSH_BASH_COMPAT
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ Enable bash-compatible extensions.
+
+config BUSYBOX_CONFIG_HUSH_BRACE_EXPANSION
+ bool "Brace expansion"
+ default BUSYBOX_DEFAULT_HUSH_BRACE_EXPANSION
+ depends on BUSYBOX_CONFIG_HUSH_BASH_COMPAT
+ help
+ Enable {abc,def} extension.
+
+config BUSYBOX_CONFIG_HUSH_HELP
+ bool "help builtin"
+ default BUSYBOX_DEFAULT_HUSH_HELP
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ Enable help builtin in hush. Code size + ~1 kbyte.
+
+config BUSYBOX_CONFIG_HUSH_INTERACTIVE
+ bool "Interactive mode"
+ default BUSYBOX_DEFAULT_HUSH_INTERACTIVE
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ Enable interactive mode (prompt and command editing).
+ Without this, hush simply reads and executes commands
+ from stdin just like a shell script from a file.
+ No prompt, no PS1/PS2 magic shell variables.
+
+config BUSYBOX_CONFIG_HUSH_SAVEHISTORY
+ bool "Save command history to .hush_history"
+ default BUSYBOX_DEFAULT_HUSH_SAVEHISTORY
+ depends on BUSYBOX_CONFIG_HUSH_INTERACTIVE && BUSYBOX_CONFIG_FEATURE_EDITING_SAVEHISTORY
+ help
+ Enable history saving in hush.
+
+config BUSYBOX_CONFIG_HUSH_JOB
+ bool "Job control"
+ default BUSYBOX_DEFAULT_HUSH_JOB
+ depends on BUSYBOX_CONFIG_HUSH_INTERACTIVE
+ help
+ Enable job control: Ctrl-Z backgrounds, Ctrl-C interrupts current
+ command (not entire shell), fg/bg builtins work. Without this option,
+ "cmd &" still works by simply spawning a process and immediately
+ prompting for next command (or executing next command in a script),
+ but no separate process group is formed.
+
+config BUSYBOX_CONFIG_HUSH_TICK
+ bool "Process substitution"
+ default BUSYBOX_DEFAULT_HUSH_TICK
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ Enable process substitution `command` and $(command) in hush.
+
+config BUSYBOX_CONFIG_HUSH_IF
+ bool "Support if/then/elif/else/fi"
+ default BUSYBOX_DEFAULT_HUSH_IF
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ Enable if/then/elif/else/fi in hush.
+
+config BUSYBOX_CONFIG_HUSH_LOOPS
+ bool "Support for, while and until loops"
+ default BUSYBOX_DEFAULT_HUSH_LOOPS
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ Enable for, while and until loops in hush.
+
+config BUSYBOX_CONFIG_HUSH_CASE
+ bool "Support case ... esac statement"
+ default BUSYBOX_DEFAULT_HUSH_CASE
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ Enable case ... esac statement in hush. +400 bytes.
+
+config BUSYBOX_CONFIG_HUSH_FUNCTIONS
+ bool "Support funcname() { commands; } syntax"
+ default BUSYBOX_DEFAULT_HUSH_FUNCTIONS
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ Enable support for shell functions in hush. +800 bytes.
+
+config BUSYBOX_CONFIG_HUSH_LOCAL
+ bool "Support local builtin"
+ default BUSYBOX_DEFAULT_HUSH_LOCAL
+ depends on BUSYBOX_CONFIG_HUSH_FUNCTIONS
+ help
+ Enable support for local variables in functions.
+
+config BUSYBOX_CONFIG_HUSH_RANDOM_SUPPORT
+ bool "Pseudorandom generator and $RANDOM variable"
+ default BUSYBOX_DEFAULT_HUSH_RANDOM_SUPPORT
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ Enable pseudorandom generator and dynamic variable "$RANDOM".
+ Each read of "$RANDOM" will generate a new pseudorandom value.
+
+config BUSYBOX_CONFIG_HUSH_EXPORT_N
+ bool "Support 'export -n' option"
+ default BUSYBOX_DEFAULT_HUSH_EXPORT_N
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ export -n unexports variables. It is a bash extension.
+
+config BUSYBOX_CONFIG_HUSH_MODE_X
+ bool "Support 'hush -x' option and 'set -x' command"
+ default BUSYBOX_DEFAULT_HUSH_MODE_X
+ depends on BUSYBOX_CONFIG_HUSH
+ help
+ This instructs hush to print commands before execution.
+ Adds ~300 bytes.
+
+config BUSYBOX_CONFIG_MSH
+ bool "msh (deprecated: aliased to hush)"
+ default BUSYBOX_DEFAULT_MSH
+ select BUSYBOX_CONFIG_HUSH
+ help
+ msh is deprecated and will be removed, please migrate to hush.
+
+
+
+choice
+ prompt "Choose which shell is aliased to 'sh' name"
+ default BUSYBOX_CONFIG_FEATURE_SH_IS_ASH
+ help
+ Choose which shell you want to be executed by 'sh' alias.
+ The ash shell is the most bash compatible and full featured one.
+
+# note: cannot use "select ASH" here, it breaks "make allnoconfig"
+config BUSYBOX_CONFIG_FEATURE_SH_IS_ASH
+ depends on BUSYBOX_CONFIG_ASH
+ bool "ash"
+ depends on !BUSYBOX_CONFIG_NOMMU
+
+config BUSYBOX_CONFIG_FEATURE_SH_IS_HUSH
+ depends on BUSYBOX_CONFIG_HUSH
+ bool "hush"
+
+config BUSYBOX_CONFIG_FEATURE_SH_IS_NONE
+ bool "none"
+
+endchoice
+
+choice
+ prompt "Choose which shell is aliased to 'bash' name"
+ default BUSYBOX_CONFIG_FEATURE_BASH_IS_NONE
+ help
+ Choose which shell you want to be executed by 'bash' alias.
+ The ash shell is the most bash compatible and full featured one.
+
+ Note that selecting this option does not switch on any bash
+ compatibility code. It merely makes it possible to install
+ /bin/bash (sym)link and run scripts which start with
+ #!/bin/bash line.
+
+ Many systems use it in scripts which use bash-specific features,
+ even simple ones like $RANDOM. Without this option, busybox
+ can't be used for running them because it won't recongnize
+ "bash" as a supported applet name.
+
+config BUSYBOX_CONFIG_FEATURE_BASH_IS_ASH
+ depends on BUSYBOX_CONFIG_ASH
+ bool "ash"
+ depends on !BUSYBOX_CONFIG_NOMMU
+
+config BUSYBOX_CONFIG_FEATURE_BASH_IS_HUSH
+ depends on BUSYBOX_CONFIG_HUSH
+ bool "hush"
+
+config BUSYBOX_CONFIG_FEATURE_BASH_IS_NONE
+ bool "none"
+
+endchoice
+
+
+config BUSYBOX_CONFIG_SH_MATH_SUPPORT
+ bool "POSIX math support"
+ default BUSYBOX_DEFAULT_SH_MATH_SUPPORT
+ depends on BUSYBOX_CONFIG_ASH || BUSYBOX_CONFIG_HUSH
+ help
+ Enable math support in the shell via $((...)) syntax.
+
+config BUSYBOX_CONFIG_SH_MATH_SUPPORT_64
+ bool "Extend POSIX math support to 64 bit"
+ default BUSYBOX_DEFAULT_SH_MATH_SUPPORT_64
+ depends on BUSYBOX_CONFIG_SH_MATH_SUPPORT
+ help
+ Enable 64-bit math support in the shell. This will make the shell
+ slightly larger, but will allow computation with very large numbers.
+ This is not in POSIX, so do not rely on this in portable code.
+
+config BUSYBOX_CONFIG_FEATURE_SH_EXTRA_QUIET
+ bool "Hide message on interactive shell startup"
+ default BUSYBOX_DEFAULT_FEATURE_SH_EXTRA_QUIET
+ depends on BUSYBOX_CONFIG_HUSH || BUSYBOX_CONFIG_ASH
+ help
+ Remove the busybox introduction when starting a shell.
+
+config BUSYBOX_CONFIG_FEATURE_SH_STANDALONE
+ bool "Standalone shell"
+ default BUSYBOX_DEFAULT_FEATURE_SH_STANDALONE
+ depends on (BUSYBOX_CONFIG_HUSH || BUSYBOX_CONFIG_ASH) && BUSYBOX_CONFIG_FEATURE_PREFER_APPLETS
+ help
+ This option causes busybox shells to use busybox applets
+ in preference to executables in the PATH whenever possible. For
+ example, entering the command 'ifconfig' into the shell would cause
+ busybox to use the ifconfig busybox applet. Specifying the fully
+ qualified executable name, such as '/sbin/ifconfig' will still
+ execute the /sbin/ifconfig executable on the filesystem. This option
+ is generally used when creating a statically linked version of busybox
+ for use as a rescue shell, in the event that you screw up your system.
+
+ This is implemented by re-execing /proc/self/exe (typically)
+ with right parameters. Some selected applets ("NOFORK" applets)
+ can even be executed without creating new process.
+ Instead, busybox will call <applet>_main() internally.
+
+ However, this causes problems in chroot jails without mounted /proc
+ and with ps/top (command name can be shown as 'exe' for applets
+ started this way).
+# untrue?
+# Note that this will *also* cause applets to take precedence
+# over shell builtins of the same name. So turning this on will
+# eliminate any performance gained by turning on the builtin "echo"
+# and "test" commands in ash.
+# untrue?
+# Note that when using this option, the shell will attempt to directly
+# run '/bin/busybox'. If you do not have the busybox binary sitting in
+# that exact location with that exact name, this option will not work at
+# all.
+
+config BUSYBOX_CONFIG_FEATURE_SH_NOFORK
+ bool "Run 'nofork' applets directly"
+ default BUSYBOX_DEFAULT_FEATURE_SH_NOFORK
+ depends on (BUSYBOX_CONFIG_HUSH || BUSYBOX_CONFIG_ASH) && BUSYBOX_CONFIG_FEATURE_PREFER_APPLETS
+ help
+ This option causes busybox shells to not execute typical
+ fork/exec/wait sequence, but call <applet>_main directly,
+ if possible. (Sometimes it is not possible: for example,
+ this is not possible in pipes).
+
+ This will be done only for some applets (those which are marked
+ NOFORK in include/applets.h).
+
+ This may significantly speed up some shell scripts.
+
+ This feature is relatively new. Use with care. Report bugs
+ to project mailing list.
+
+config BUSYBOX_CONFIG_FEATURE_SH_HISTFILESIZE
+ bool "Use $HISTFILESIZE"
+ default BUSYBOX_DEFAULT_FEATURE_SH_HISTFILESIZE
+ depends on BUSYBOX_CONFIG_HUSH || BUSYBOX_CONFIG_ASH
+ help
+ This option makes busybox shells to use $HISTFILESIZE variable
+ to set shell history size. Note that its max value is capped
+ by "History size" setting in library tuning section.
+
+
+endmenu
diff --git a/package/utils/busybox/config/sysklogd/Config.in b/package/utils/busybox/config/sysklogd/Config.in
new file mode 100644
index 0000000..de36a1e
--- /dev/null
+++ b/package/utils/busybox/config/sysklogd/Config.in
@@ -0,0 +1,169 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "System Logging Utilities"
+
+
+config BUSYBOX_CONFIG_SYSLOGD
+ bool "syslogd"
+ default BUSYBOX_DEFAULT_SYSLOGD
+ help
+ The syslogd utility is used to record logs of all the
+ significant events that occur on a system. Every
+ message that is logged records the date and time of the
+ event, and will generally also record the name of the
+ application that generated the message. When used in
+ conjunction with klogd, messages from the Linux kernel
+ can also be recorded. This is terribly useful,
+ especially for finding what happened when something goes
+ wrong. And something almost always will go wrong if
+ you wait long enough....
+
+config BUSYBOX_CONFIG_FEATURE_ROTATE_LOGFILE
+ bool "Rotate message files"
+ default BUSYBOX_DEFAULT_FEATURE_ROTATE_LOGFILE
+ depends on BUSYBOX_CONFIG_SYSLOGD
+ help
+ This enables syslogd to rotate the message files
+ on his own. No need to use an external rotatescript.
+
+config BUSYBOX_CONFIG_FEATURE_REMOTE_LOG
+ bool "Remote Log support"
+ default BUSYBOX_DEFAULT_FEATURE_REMOTE_LOG
+ depends on BUSYBOX_CONFIG_SYSLOGD
+ help
+ When you enable this feature, the syslogd utility can
+ be used to send system log messages to another system
+ connected via a network. This allows the remote
+ machine to log all the system messages, which can be
+ terribly useful for reducing the number of serial
+ cables you use. It can also be a very good security
+ measure to prevent system logs from being tampered with
+ by an intruder.
+
+config BUSYBOX_CONFIG_FEATURE_SYSLOGD_DUP
+ bool "Support -D (drop dups) option"
+ default BUSYBOX_DEFAULT_FEATURE_SYSLOGD_DUP
+ depends on BUSYBOX_CONFIG_SYSLOGD
+ help
+ Option -D instructs syslogd to drop consecutive messages
+ which are totally the same.
+
+config BUSYBOX_CONFIG_FEATURE_SYSLOGD_CFG
+ bool "Support syslog.conf"
+ default BUSYBOX_DEFAULT_FEATURE_SYSLOGD_CFG
+ depends on BUSYBOX_CONFIG_SYSLOGD
+ help
+ Supports restricted syslogd config. See docs/syslog.conf.txt
+
+config BUSYBOX_CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE
+ int "Read buffer size in bytes"
+ default BUSYBOX_DEFAULT_FEATURE_SYSLOGD_READ_BUFFER_SIZE
+ range 256 20000
+ depends on BUSYBOX_CONFIG_SYSLOGD
+ help
+ This option sets the size of the syslog read buffer.
+ Actual memory usage increases around five times the
+ change done here.
+
+config BUSYBOX_CONFIG_FEATURE_IPC_SYSLOG
+ bool "Circular Buffer support"
+ default BUSYBOX_DEFAULT_FEATURE_IPC_SYSLOG
+ depends on BUSYBOX_CONFIG_SYSLOGD
+ help
+ When you enable this feature, the syslogd utility will
+ use a circular buffer to record system log messages.
+ When the buffer is filled it will continue to overwrite
+ the oldest messages. This can be very useful for
+ systems with little or no permanent storage, since
+ otherwise system logs can eventually fill up your
+ entire filesystem, which may cause your system to
+ break badly.
+
+config BUSYBOX_CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE
+ int "Circular buffer size in Kbytes (minimum 4KB)"
+ default BUSYBOX_DEFAULT_FEATURE_IPC_SYSLOG_BUFFER_SIZE
+ range 4 2147483647
+ depends on BUSYBOX_CONFIG_FEATURE_IPC_SYSLOG
+ help
+ This option sets the size of the circular buffer
+ used to record system log messages.
+
+config BUSYBOX_CONFIG_LOGREAD
+ bool "logread"
+ default BUSYBOX_DEFAULT_LOGREAD
+ depends on BUSYBOX_CONFIG_FEATURE_IPC_SYSLOG
+ help
+ If you enabled Circular Buffer support, you almost
+ certainly want to enable this feature as well. This
+ utility will allow you to read the messages that are
+ stored in the syslogd circular buffer.
+
+config BUSYBOX_CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING
+ bool "Double buffering"
+ default BUSYBOX_DEFAULT_FEATURE_LOGREAD_REDUCED_LOCKING
+ depends on BUSYBOX_CONFIG_LOGREAD
+ help
+ 'logread' ouput to slow serial terminals can have
+ side effects on syslog because of the semaphore.
+ This option make logread to double buffer copy
+ from circular buffer, minimizing semaphore
+ contention at some minor memory expense.
+
+config BUSYBOX_CONFIG_FEATURE_KMSG_SYSLOG
+ bool "Linux kernel printk buffer support"
+ default BUSYBOX_DEFAULT_FEATURE_KMSG_SYSLOG
+ depends on BUSYBOX_CONFIG_SYSLOGD
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ When you enable this feature, the syslogd utility will
+ write system log message to the Linux kernel's printk buffer.
+ This can be used as a smaller alternative to the syslogd IPC
+ support, as klogd and logread aren't needed.
+
+ NOTICE: Syslog facilities in log entries needs kernel 3.5+.
+
+config BUSYBOX_CONFIG_KLOGD
+ bool "klogd"
+ default BUSYBOX_DEFAULT_KLOGD
+ help
+ klogd is a utility which intercepts and logs all
+ messages from the Linux kernel and sends the messages
+ out to the 'syslogd' utility so they can be logged. If
+ you wish to record the messages produced by the kernel,
+ you should enable this option.
+
+comment "klogd should not be used together with syslog to kernel printk buffer"
+ depends on BUSYBOX_CONFIG_KLOGD && BUSYBOX_CONFIG_FEATURE_KMSG_SYSLOG
+
+config BUSYBOX_CONFIG_FEATURE_KLOGD_KLOGCTL
+ bool "Use the klogctl() interface"
+ default BUSYBOX_DEFAULT_FEATURE_KLOGD_KLOGCTL
+ depends on BUSYBOX_CONFIG_KLOGD
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The klogd applet supports two interfaces for reading
+ kernel messages. Linux provides the klogctl() interface
+ which allows reading messages from the kernel ring buffer
+ independently from the file system.
+
+ If you answer 'N' here, klogd will use the more portable
+ approach of reading them from /proc or a device node.
+ However, this method requires the file to be available.
+
+ If in doubt, say 'Y'.
+
+config BUSYBOX_CONFIG_LOGGER
+ bool "logger"
+ default BUSYBOX_DEFAULT_LOGGER
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ The logger utility allows you to send arbitrary text
+ messages to the system log (i.e. the 'syslogd' utility) so
+ they can be logged. This is generally used to help locate
+ problems that occur within programs and scripts.
+
+endmenu
diff --git a/package/utils/busybox/config/util-linux/Config.in b/package/utils/busybox/config/util-linux/Config.in
new file mode 100644
index 0000000..8d1464d
--- /dev/null
+++ b/package/utils/busybox/config/util-linux/Config.in
@@ -0,0 +1,792 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Linux System Utilities"
+
+config BUSYBOX_CONFIG_BLOCKDEV
+ bool "blockdev"
+ default BUSYBOX_DEFAULT_BLOCKDEV
+ help
+ Performs some ioctls with block devices.
+config BUSYBOX_CONFIG_FATATTR
+ bool "fatattr"
+ default BUSYBOX_DEFAULT_FATATTR
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ fatattr lists or changes the file attributes on a fat file system.
+config BUSYBOX_CONFIG_FSTRIM
+ bool "fstrim"
+ default BUSYBOX_DEFAULT_FSTRIM
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Discard unused blocks on a mounted filesystem.
+config BUSYBOX_CONFIG_MDEV
+ bool "mdev"
+ default BUSYBOX_DEFAULT_MDEV
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ mdev is a mini-udev implementation for dynamically creating device
+ nodes in the /dev directory.
+
+ For more information, please see docs/mdev.txt
+
+config BUSYBOX_CONFIG_FEATURE_MDEV_CONF
+ bool "Support /etc/mdev.conf"
+ default BUSYBOX_DEFAULT_FEATURE_MDEV_CONF
+ depends on BUSYBOX_CONFIG_MDEV
+ help
+ Add support for the mdev config file to control ownership and
+ permissions of the device nodes.
+
+ For more information, please see docs/mdev.txt
+
+config BUSYBOX_CONFIG_FEATURE_MDEV_RENAME
+ bool "Support subdirs/symlinks"
+ default BUSYBOX_DEFAULT_FEATURE_MDEV_RENAME
+ depends on BUSYBOX_CONFIG_FEATURE_MDEV_CONF
+ help
+ Add support for renaming devices and creating symlinks.
+
+ For more information, please see docs/mdev.txt
+
+config BUSYBOX_CONFIG_FEATURE_MDEV_RENAME_REGEXP
+ bool "Support regular expressions substitutions when renaming device"
+ default BUSYBOX_DEFAULT_FEATURE_MDEV_RENAME_REGEXP
+ depends on BUSYBOX_CONFIG_FEATURE_MDEV_RENAME
+ help
+ Add support for regular expressions substitutions when renaming
+ device.
+
+config BUSYBOX_CONFIG_FEATURE_MDEV_EXEC
+ bool "Support command execution at device addition/removal"
+ default BUSYBOX_DEFAULT_FEATURE_MDEV_EXEC
+ depends on BUSYBOX_CONFIG_FEATURE_MDEV_CONF
+ help
+ This adds support for an optional field to /etc/mdev.conf for
+ executing commands when devices are created/removed.
+
+ For more information, please see docs/mdev.txt
+
+config BUSYBOX_CONFIG_FEATURE_MDEV_LOAD_FIRMWARE
+ bool "Support loading of firmwares"
+ default BUSYBOX_DEFAULT_FEATURE_MDEV_LOAD_FIRMWARE
+ depends on BUSYBOX_CONFIG_MDEV
+ help
+ Some devices need to load firmware before they can be usable.
+
+ These devices will request userspace look up the files in
+ /lib/firmware/ and if it exists, send it to the kernel for
+ loading into the hardware.
+config BUSYBOX_CONFIG_REV
+ bool "rev"
+ default BUSYBOX_DEFAULT_REV
+ help
+ Reverse lines of a file or files.
+
+config BUSYBOX_CONFIG_ACPID
+ bool "acpid"
+ default BUSYBOX_DEFAULT_ACPID
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ acpid listens to ACPI events coming either in textual form from
+ /proc/acpi/event (though it is marked deprecated it is still widely
+ used and _is_ a standard) or in binary form from specified evdevs
+ (just use /dev/input/event*).
+
+ It parses the event to retrieve ACTION and a possible PARAMETER.
+ It then spawns /etc/acpi/<ACTION>[/<PARAMETER>] either via run-parts
+ (if the resulting path is a directory) or directly as an executable.
+
+ N.B. acpid relies on run-parts so have the latter installed.
+
+config BUSYBOX_CONFIG_FEATURE_ACPID_COMPAT
+ bool "Accept and ignore redundant options"
+ default BUSYBOX_DEFAULT_FEATURE_ACPID_COMPAT
+ depends on BUSYBOX_CONFIG_ACPID
+ help
+ Accept and ignore compatibility options -g -m -s -S -v.
+
+config BUSYBOX_CONFIG_BLKID
+ bool "blkid"
+ default BUSYBOX_DEFAULT_BLKID
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ select BUSYBOX_CONFIG_VOLUMEID
+ help
+ Lists labels and UUIDs of all filesystems.
+ WARNING:
+ With all submodules selected, it will add ~8k to busybox.
+
+config BUSYBOX_CONFIG_FEATURE_BLKID_TYPE
+ bool "Print filesystem type"
+ default BUSYBOX_DEFAULT_FEATURE_BLKID_TYPE
+ depends on BUSYBOX_CONFIG_BLKID
+ help
+ Show TYPE="filesystem type"
+
+config BUSYBOX_CONFIG_DMESG
+ bool "dmesg"
+ default BUSYBOX_DEFAULT_DMESG
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ dmesg is used to examine or control the kernel ring buffer. When the
+ Linux kernel prints messages to the system log, they are stored in
+ the kernel ring buffer. You can use dmesg to print the kernel's ring
+ buffer, clear the kernel ring buffer, change the size of the kernel
+ ring buffer, and change the priority level at which kernel messages
+ are also logged to the system console. Enable this option if you
+ wish to enable the 'dmesg' utility.
+
+config BUSYBOX_CONFIG_FEATURE_DMESG_PRETTY
+ bool "Pretty dmesg output"
+ default BUSYBOX_DEFAULT_FEATURE_DMESG_PRETTY
+ depends on BUSYBOX_CONFIG_DMESG
+ help
+ If you wish to scrub the syslog level from the output, say 'Y' here.
+ The syslog level is a string prefixed to every line with the form
+ "<#>".
+
+ With this option you will see:
+ # dmesg
+ Linux version 2.6.17.4 .....
+ BIOS-provided physical RAM map:
+ BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
+
+ Without this option you will see:
+ # dmesg
+ <5>Linux version 2.6.17.4 .....
+ <6>BIOS-provided physical RAM map:
+ <6> BIOS-e820: 0000000000000000 - 000000000009f000 (usable)
+
+config BUSYBOX_CONFIG_FBSET
+ bool "fbset"
+ default BUSYBOX_DEFAULT_FBSET
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ fbset is used to show or change the settings of a Linux frame buffer
+ device. The frame buffer device provides a simple and unique
+ interface to access a graphics display. Enable this option
+ if you wish to enable the 'fbset' utility.
+
+config BUSYBOX_CONFIG_FEATURE_FBSET_FANCY
+ bool "Turn on extra fbset options"
+ default BUSYBOX_DEFAULT_FEATURE_FBSET_FANCY
+ depends on BUSYBOX_CONFIG_FBSET
+ help
+ This option enables extended fbset options, allowing one to set the
+ framebuffer size, color depth, etc. interface to access a graphics
+ display. Enable this option if you wish to enable extended fbset
+ options.
+
+config BUSYBOX_CONFIG_FEATURE_FBSET_READMODE
+ bool "Turn on fbset readmode support"
+ default BUSYBOX_DEFAULT_FEATURE_FBSET_READMODE
+ depends on BUSYBOX_CONFIG_FBSET
+ help
+ This option allows fbset to read the video mode database stored by
+ default BUSYBOX_DEFAULT_FEATURE_FBSET_READMODE /etc/fb.modes, which can be used to set frame buffer
+ device to pre-defined video modes.
+
+config BUSYBOX_CONFIG_FDFLUSH
+ bool "fdflush"
+ default BUSYBOX_DEFAULT_FDFLUSH
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ fdflush is only needed when changing media on slightly-broken
+ removable media drives. It is used to make Linux believe that a
+ hardware disk-change switch has been actuated, which causes Linux to
+ forget anything it has cached from the previous media. If you have
+ such a slightly-broken drive, you will need to run fdflush every time
+ you change a disk. Most people have working hardware and can safely
+ leave this disabled.
+
+config BUSYBOX_CONFIG_FDFORMAT
+ bool "fdformat"
+ default BUSYBOX_DEFAULT_FDFORMAT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ fdformat is used to low-level format a floppy disk.
+
+config BUSYBOX_CONFIG_FDISK
+ bool "fdisk"
+ default BUSYBOX_DEFAULT_FDISK
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The fdisk utility is used to divide hard disks into one or more
+ logical disks, which are generally called partitions. This utility
+ can be used to list and edit the set of partitions or BSD style
+ 'disk slices' that are defined on a hard drive.
+
+config BUSYBOX_CONFIG_FDISK_SUPPORT_LARGE_DISKS
+ bool "Support over 4GB disks"
+ default BUSYBOX_DEFAULT_FDISK_SUPPORT_LARGE_DISKS
+ depends on BUSYBOX_CONFIG_FDISK
+ depends on !BUSYBOX_CONFIG_LFS # with LFS no special code is needed
+ help
+ Enable this option to support large disks > 4GB.
+
+config BUSYBOX_CONFIG_FEATURE_FDISK_WRITABLE
+ bool "Write support"
+ default BUSYBOX_DEFAULT_FEATURE_FDISK_WRITABLE
+ depends on BUSYBOX_CONFIG_FDISK
+ help
+ Enabling this option allows you to create or change a partition table
+ and write those changes out to disk. If you leave this option
+ disabled, you will only be able to view the partition table.
+
+config BUSYBOX_CONFIG_FEATURE_AIX_LABEL
+ bool "Support AIX disklabels"
+ default BUSYBOX_DEFAULT_FEATURE_AIX_LABEL
+ depends on BUSYBOX_CONFIG_FDISK && BUSYBOX_CONFIG_FEATURE_FDISK_WRITABLE
+ help
+ Enabling this option allows you to create or change AIX disklabels.
+ Most people can safely leave this option disabled.
+
+config BUSYBOX_CONFIG_FEATURE_SGI_LABEL
+ bool "Support SGI disklabels"
+ default BUSYBOX_DEFAULT_FEATURE_SGI_LABEL
+ depends on BUSYBOX_CONFIG_FDISK && BUSYBOX_CONFIG_FEATURE_FDISK_WRITABLE
+ help
+ Enabling this option allows you to create or change SGI disklabels.
+ Most people can safely leave this option disabled.
+
+config BUSYBOX_CONFIG_FEATURE_SUN_LABEL
+ bool "Support SUN disklabels"
+ default BUSYBOX_DEFAULT_FEATURE_SUN_LABEL
+ depends on BUSYBOX_CONFIG_FDISK && BUSYBOX_CONFIG_FEATURE_FDISK_WRITABLE
+ help
+ Enabling this option allows you to create or change SUN disklabels.
+ Most people can safely leave this option disabled.
+
+config BUSYBOX_CONFIG_FEATURE_OSF_LABEL
+ bool "Support BSD disklabels"
+ default BUSYBOX_DEFAULT_FEATURE_OSF_LABEL
+ depends on BUSYBOX_CONFIG_FDISK && BUSYBOX_CONFIG_FEATURE_FDISK_WRITABLE
+ help
+ Enabling this option allows you to create or change BSD disklabels
+ and define and edit BSD disk slices.
+
+config BUSYBOX_CONFIG_FEATURE_GPT_LABEL
+ bool "Support GPT disklabels"
+ default BUSYBOX_DEFAULT_FEATURE_GPT_LABEL
+ depends on BUSYBOX_CONFIG_FDISK && BUSYBOX_CONFIG_FEATURE_FDISK_WRITABLE
+ help
+ Enabling this option allows you to view GUID Partition Table
+ disklabels.
+
+config BUSYBOX_CONFIG_FEATURE_FDISK_ADVANCED
+ bool "Support expert mode"
+ default BUSYBOX_DEFAULT_FEATURE_FDISK_ADVANCED
+ depends on BUSYBOX_CONFIG_FDISK && BUSYBOX_CONFIG_FEATURE_FDISK_WRITABLE
+ help
+ Enabling this option allows you to do terribly unsafe things like
+ define arbitrary drive geometry, move the beginning of data in a
+ partition, and similarly evil things. Unless you have a very good
+ reason you would be wise to leave this disabled.
+
+config BUSYBOX_CONFIG_FINDFS
+ bool "findfs"
+ default BUSYBOX_DEFAULT_FINDFS
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ select BUSYBOX_CONFIG_VOLUMEID
+ help
+ Prints the name of a filesystem with given label or UUID.
+ WARNING:
+ With all submodules selected, it will add ~8k to busybox.
+
+config BUSYBOX_CONFIG_FLOCK
+ bool "flock"
+ default BUSYBOX_DEFAULT_FLOCK
+ help
+ Manage locks from shell scripts
+
+config BUSYBOX_CONFIG_FREERAMDISK
+ bool "freeramdisk"
+ default BUSYBOX_DEFAULT_FREERAMDISK
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Linux allows you to create ramdisks. This utility allows you to
+ delete them and completely free all memory that was used for the
+ ramdisk. For example, if you boot Linux into a ramdisk and later
+ pivot_root, you may want to free the memory that is allocated to the
+ ramdisk. If you have no use for freeing memory from a ramdisk, leave
+ this disabled.
+
+config BUSYBOX_CONFIG_FSCK_MINIX
+ bool "fsck_minix"
+ default BUSYBOX_DEFAULT_FSCK_MINIX
+ help
+ The minix filesystem is a nice, small, compact, read-write filesystem
+ with little overhead. It is not a journaling filesystem however and
+ can experience corruption if it is not properly unmounted or if the
+ power goes off in the middle of a write. This utility allows you to
+ check for and attempt to repair any corruption that occurs to a minix
+ filesystem.
+
+config BUSYBOX_CONFIG_MKFS_EXT2
+ bool "mkfs_ext2"
+ default BUSYBOX_DEFAULT_MKFS_EXT2
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Utility to create EXT2 filesystems.
+
+config BUSYBOX_CONFIG_MKFS_MINIX
+ bool "mkfs_minix"
+ default BUSYBOX_DEFAULT_MKFS_MINIX
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The minix filesystem is a nice, small, compact, read-write filesystem
+ with little overhead. If you wish to be able to create minix
+ filesystems this utility will do the job for you.
+
+config BUSYBOX_CONFIG_FEATURE_MINIX2
+ bool "Support Minix fs v2 (fsck_minix/mkfs_minix)"
+ default BUSYBOX_DEFAULT_FEATURE_MINIX2
+ depends on BUSYBOX_CONFIG_FSCK_MINIX || BUSYBOX_CONFIG_MKFS_MINIX
+ help
+ If you wish to be able to create version 2 minix filesystems, enable
+ this. If you enabled 'mkfs_minix' then you almost certainly want to
+ be using the version 2 filesystem support.
+
+config BUSYBOX_CONFIG_MKFS_REISER
+ bool "mkfs_reiser"
+ default BUSYBOX_DEFAULT_MKFS_REISER
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Utility to create ReiserFS filesystems.
+ Note: this applet needs a lot of testing and polishing.
+
+config BUSYBOX_CONFIG_MKFS_VFAT
+ bool "mkfs_vfat"
+ default BUSYBOX_DEFAULT_MKFS_VFAT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Utility to create FAT32 filesystems.
+
+config BUSYBOX_CONFIG_GETOPT
+ bool "getopt"
+ default BUSYBOX_DEFAULT_GETOPT
+ help
+ The getopt utility is used to break up (parse) options in command
+ lines to make it easy to write complex shell scripts that also check
+ for legal (and illegal) options. If you want to write horribly
+ complex shell scripts, or use some horribly complex shell script
+ written by others, this utility may be for you. Most people will
+ wisely leave this disabled.
+
+config BUSYBOX_CONFIG_FEATURE_GETOPT_LONG
+ bool "Support option -l"
+ default BUSYBOX_DEFAULT_FEATURE_GETOPT_LONG if BUSYBOX_CONFIG_LONG_OPTS
+ depends on BUSYBOX_CONFIG_GETOPT
+ help
+ Enable support for long options (option -l).
+
+config BUSYBOX_CONFIG_HEXDUMP
+ bool "hexdump"
+ default BUSYBOX_DEFAULT_HEXDUMP
+ help
+ The hexdump utility is used to display binary data in a readable
+ way that is comparable to the output from most hex editors.
+
+config BUSYBOX_CONFIG_FEATURE_HEXDUMP_REVERSE
+ bool "Support -R, reverse of 'hexdump -Cv'"
+ default BUSYBOX_DEFAULT_FEATURE_HEXDUMP_REVERSE
+ depends on BUSYBOX_CONFIG_HEXDUMP
+ help
+ The hexdump utility is used to display binary data in an ascii
+ readable way. This option creates binary data from an ascii input.
+ NB: this option is non-standard. It's unwise to use it in scripts
+ aimed to be portable.
+
+config BUSYBOX_CONFIG_HD
+ bool "hd"
+ default BUSYBOX_DEFAULT_HD
+ depends on BUSYBOX_CONFIG_HEXDUMP
+ help
+ hd is an alias to hexdump -C.
+
+config BUSYBOX_CONFIG_HWCLOCK
+ bool "hwclock"
+ default BUSYBOX_DEFAULT_HWCLOCK
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The hwclock utility is used to read and set the hardware clock
+ on a system. This is primarily used to set the current time on
+ shutdown in the hardware clock, so the hardware will keep the
+ correct time when Linux is _not_ running.
+
+config BUSYBOX_CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS
+ bool "Support long options (--hctosys,...)"
+ default BUSYBOX_DEFAULT_FEATURE_HWCLOCK_LONG_OPTIONS
+ depends on BUSYBOX_CONFIG_HWCLOCK && BUSYBOX_CONFIG_LONG_OPTS
+ help
+ By default, the hwclock utility only uses short options. If you
+ are overly fond of its long options, such as --hctosys, --utc, etc)
+ then enable this option.
+
+config BUSYBOX_CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS
+ bool "Use FHS /var/lib/hwclock/adjtime"
+ default BUSYBOX_DEFAULT_FEATURE_HWCLOCK_ADJTIME_FHS # util-linux-ng in Fedora 13 still uses /etc/adjtime
+ depends on BUSYBOX_CONFIG_HWCLOCK
+ help
+ Starting with FHS 2.3, the adjtime state file is supposed to exist
+ at /var/lib/hwclock/adjtime instead of /etc/adjtime. If you wish
+ to use the FHS behavior, answer Y here, otherwise answer N for the
+ classic /etc/adjtime path.
+
+ pathname.com/fhs/pub/fhs-2.3.html#VARLIBHWCLOCKSTATEDIRECTORYFORHWCLO
+
+config BUSYBOX_CONFIG_IPCRM
+ bool "ipcrm"
+ default BUSYBOX_DEFAULT_IPCRM
+ help
+ The ipcrm utility allows the removal of System V interprocess
+ communication (IPC) objects and the associated data structures
+ from the system.
+
+config BUSYBOX_CONFIG_IPCS
+ bool "ipcs"
+ default BUSYBOX_DEFAULT_IPCS
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The ipcs utility is used to provide information on the currently
+ allocated System V interprocess (IPC) objects in the system.
+
+config BUSYBOX_CONFIG_LOSETUP
+ bool "losetup"
+ default BUSYBOX_DEFAULT_LOSETUP
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ losetup is used to associate or detach a loop device with a regular
+ file or block device, and to query the status of a loop device. This
+ version does not currently support enabling data encryption.
+
+config BUSYBOX_CONFIG_LSPCI
+ bool "lspci"
+ default BUSYBOX_DEFAULT_LSPCI
+ #select PLATFORM_LINUX
+ help
+ lspci is a utility for displaying information about PCI buses in the
+ system and devices connected to them.
+
+ This version uses sysfs (/sys/bus/pci/devices) only.
+
+config BUSYBOX_CONFIG_LSUSB
+ bool "lsusb"
+ default BUSYBOX_DEFAULT_LSUSB
+ #select PLATFORM_LINUX
+ help
+ lsusb is a utility for displaying information about USB buses in the
+ system and devices connected to them.
+
+ This version uses sysfs (/sys/bus/usb/devices) only.
+
+config BUSYBOX_CONFIG_MKSWAP
+ bool "mkswap"
+ default BUSYBOX_DEFAULT_MKSWAP
+ help
+ The mkswap utility is used to configure a file or disk partition as
+ Linux swap space. This allows Linux to use the entire file or
+ partition as if it were additional RAM, which can greatly increase
+ the capability of low-memory machines. This additional memory is
+ much slower than real RAM, but can be very helpful at preventing your
+ applications being killed by the Linux out of memory (OOM) killer.
+ Once you have created swap space using 'mkswap' you need to enable
+ the swap space using the 'swapon' utility.
+
+config BUSYBOX_CONFIG_FEATURE_MKSWAP_UUID
+ bool "UUID support"
+ default BUSYBOX_DEFAULT_FEATURE_MKSWAP_UUID
+ depends on BUSYBOX_CONFIG_MKSWAP
+ help
+ Generate swap spaces with universally unique identifiers.
+
+config BUSYBOX_CONFIG_MORE
+ bool "more"
+ default BUSYBOX_DEFAULT_MORE
+ help
+ more is a simple utility which allows you to read text one screen
+ sized page at a time. If you want to read text that is larger than
+ the screen, and you are using anything faster than a 300 baud modem,
+ you will probably find this utility very helpful. If you don't have
+ any need to reading text files, you can leave this disabled.
+
+config BUSYBOX_CONFIG_MOUNT
+ bool "mount"
+ default BUSYBOX_DEFAULT_MOUNT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ All files and filesystems in Unix are arranged into one big directory
+ tree. The 'mount' utility is used to graft a filesystem onto a
+ particular part of the tree. A filesystem can either live on a block
+ device, or it can be accessible over the network, as is the case with
+ NFS filesystems. Most people using BusyBox will also want to enable
+ the 'mount' utility.
+
+config BUSYBOX_CONFIG_FEATURE_MOUNT_FAKE
+ bool "Support option -f"
+ default BUSYBOX_DEFAULT_FEATURE_MOUNT_FAKE
+ depends on BUSYBOX_CONFIG_MOUNT
+ help
+ Enable support for faking a file system mount.
+
+config BUSYBOX_CONFIG_FEATURE_MOUNT_VERBOSE
+ bool "Support option -v"
+ default BUSYBOX_DEFAULT_FEATURE_MOUNT_VERBOSE
+ depends on BUSYBOX_CONFIG_MOUNT
+ help
+ Enable multi-level -v[vv...] verbose messages. Useful if you
+ debug mount problems and want to see what is exactly passed
+ to the kernel.
+
+config BUSYBOX_CONFIG_FEATURE_MOUNT_HELPERS
+ bool "Support mount helpers"
+ default BUSYBOX_DEFAULT_FEATURE_MOUNT_HELPERS
+ depends on BUSYBOX_CONFIG_MOUNT
+ help
+ Enable mounting of virtual file systems via external helpers.
+ E.g. "mount obexfs#-b00.11.22.33.44.55 /mnt" will in effect call
+ "obexfs -b00.11.22.33.44.55 /mnt"
+ Also "mount -t sometype [-o opts] fs /mnt" will try
+ "sometype [-o opts] fs /mnt" if simple mount syscall fails.
+ The idea is to use such virtual filesystems in /etc/fstab.
+
+config BUSYBOX_CONFIG_FEATURE_MOUNT_LABEL
+ bool "Support specifying devices by label or UUID"
+ default BUSYBOX_DEFAULT_FEATURE_MOUNT_LABEL
+ depends on BUSYBOX_CONFIG_MOUNT
+ select BUSYBOX_CONFIG_VOLUMEID
+ help
+ This allows for specifying a device by label or uuid, rather than by
+ name. This feature utilizes the same functionality as blkid/findfs.
+ This also enables label or uuid support for swapon.
+
+config BUSYBOX_CONFIG_FEATURE_MOUNT_NFS
+ bool "Support mounting NFS file systems on Linux < 2.6.23"
+ default BUSYBOX_DEFAULT_FEATURE_MOUNT_NFS
+ depends on BUSYBOX_CONFIG_MOUNT
+ select BUSYBOX_CONFIG_FEATURE_HAVE_RPC
+ select BUSYBOX_CONFIG_FEATURE_SYSLOG
+ help
+ Enable mounting of NFS file systems on Linux kernels prior
+ to version 2.6.23. Note that in this case mounting of NFS
+ over IPv6 will not be possible.
+
+ Note that this option links in RPC support from libc,
+ which is rather large (~10 kbytes on uclibc).
+
+config BUSYBOX_CONFIG_FEATURE_MOUNT_CIFS
+ bool "Support mounting CIFS/SMB file systems"
+ default BUSYBOX_DEFAULT_FEATURE_MOUNT_CIFS
+ depends on BUSYBOX_CONFIG_MOUNT
+ help
+ Enable support for samba mounts.
+
+config BUSYBOX_CONFIG_FEATURE_MOUNT_FLAGS
+ depends on BUSYBOX_CONFIG_MOUNT
+ bool "Support lots of -o flags in mount"
+ default BUSYBOX_DEFAULT_FEATURE_MOUNT_FLAGS
+ help
+ Without this, mount only supports ro/rw/remount. With this, it
+ supports nosuid, suid, dev, nodev, exec, noexec, sync, async, atime,
+ noatime, diratime, nodiratime, loud, bind, move, shared, slave,
+ private, unbindable, rshared, rslave, rprivate, and runbindable.
+
+config BUSYBOX_CONFIG_FEATURE_MOUNT_FSTAB
+ depends on BUSYBOX_CONFIG_MOUNT
+ bool "Support /etc/fstab and -a"
+ default BUSYBOX_DEFAULT_FEATURE_MOUNT_FSTAB
+ help
+ Support mount all and looking for files in /etc/fstab.
+
+config BUSYBOX_CONFIG_PIVOT_ROOT
+ bool "pivot_root"
+ default BUSYBOX_DEFAULT_PIVOT_ROOT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The pivot_root utility swaps the mount points for the root filesystem
+ with some other mounted filesystem. This allows you to do all sorts
+ of wild and crazy things with your Linux system and is far more
+ powerful than 'chroot'.
+
+ Note: This is for initrd in linux 2.4. Under initramfs (introduced
+ in linux 2.6) use switch_root instead.
+
+config BUSYBOX_CONFIG_RDATE
+ bool "rdate"
+ default BUSYBOX_DEFAULT_RDATE
+ help
+ The rdate utility allows you to synchronize the date and time of your
+ system clock with the date and time of a remote networked system using
+ the RFC868 protocol, which is built into the inetd daemon on most
+ systems.
+
+config BUSYBOX_CONFIG_RDEV
+ bool "rdev"
+ default BUSYBOX_DEFAULT_RDEV
+ help
+ Print the device node associated with the filesystem mounted at '/'.
+
+config BUSYBOX_CONFIG_READPROFILE
+ bool "readprofile"
+ default BUSYBOX_DEFAULT_READPROFILE
+ #select PLATFORM_LINUX
+ help
+ This allows you to parse /proc/profile for basic profiling.
+
+config BUSYBOX_CONFIG_RTCWAKE
+ bool "rtcwake"
+ default BUSYBOX_DEFAULT_RTCWAKE
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ Enter a system sleep state until specified wakeup time.
+
+config BUSYBOX_CONFIG_SCRIPT
+ bool "script"
+ default BUSYBOX_DEFAULT_SCRIPT
+ help
+ The script makes typescript of terminal session.
+
+config BUSYBOX_CONFIG_SCRIPTREPLAY
+ bool "scriptreplay"
+ default BUSYBOX_DEFAULT_SCRIPTREPLAY
+ help
+ This program replays a typescript, using timing information
+ given by script -t.
+
+config BUSYBOX_CONFIG_SETARCH
+ bool "setarch"
+ default BUSYBOX_DEFAULT_SETARCH
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The linux32 utility is used to create a 32bit environment for the
+ specified program (usually a shell). It only makes sense to have
+ this util on a system that supports both 64bit and 32bit userland
+ (like amd64/x86, ppc64/ppc, sparc64/sparc, etc...).
+
+config BUSYBOX_CONFIG_SWAPONOFF
+ bool "swaponoff"
+ default BUSYBOX_DEFAULT_SWAPONOFF
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ This option enables both the 'swapon' and the 'swapoff' utilities.
+ Once you have created some swap space using 'mkswap', you also need
+ to enable your swap space with the 'swapon' utility. The 'swapoff'
+ utility is used, typically at system shutdown, to disable any swap
+ space. If you are not using any swap space, you can leave this
+ option disabled.
+
+config BUSYBOX_CONFIG_FEATURE_SWAPON_DISCARD
+ bool "Support discard option -d"
+ default BUSYBOX_DEFAULT_FEATURE_SWAPON_DISCARD
+ depends on BUSYBOX_CONFIG_SWAPONOFF
+ help
+ Enable support for discarding swap area blocks at swapon and/or as
+ the kernel frees them. This option enables both the -d option on
+ 'swapon' and the 'discard' option for swap entries in /etc/fstab.
+
+config BUSYBOX_CONFIG_FEATURE_SWAPON_PRI
+ bool "Support priority option -p"
+ default BUSYBOX_DEFAULT_FEATURE_SWAPON_PRI
+ depends on BUSYBOX_CONFIG_SWAPONOFF
+ help
+ Enable support for setting swap device priority in swapon.
+
+config BUSYBOX_CONFIG_SWITCH_ROOT
+ bool "switch_root"
+ default BUSYBOX_DEFAULT_SWITCH_ROOT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ The switch_root utility is used from initramfs to select a new
+ root device. Under initramfs, you have to use this instead of
+ pivot_root. (Stop reading here if you don't care why.)
+
+ Booting with initramfs extracts a gzipped cpio archive into rootfs
+ (which is a variant of ramfs/tmpfs). Because rootfs can't be moved
+ or unmounted*, pivot_root will not work from initramfs. Instead,
+ switch_root deletes everything out of rootfs (including itself),
+ does a mount --move that overmounts rootfs with the new root, and
+ then execs the specified init program.
+
+ * Because the Linux kernel uses rootfs internally as the starting
+ and ending point for searching through the kernel's doubly linked
+ list of active mount points. That's why.
+
+config BUSYBOX_CONFIG_UMOUNT
+ bool "umount"
+ default BUSYBOX_DEFAULT_UMOUNT
+ select BUSYBOX_CONFIG_PLATFORM_LINUX
+ help
+ When you want to remove a mounted filesystem from its current mount
+ point, for example when you are shutting down the system, the
+ 'umount' utility is the tool to use. If you enabled the 'mount'
+ utility, you almost certainly also want to enable 'umount'.
+
+config BUSYBOX_CONFIG_FEATURE_UMOUNT_ALL
+ bool "Support option -a"
+ default BUSYBOX_DEFAULT_FEATURE_UMOUNT_ALL
+ depends on BUSYBOX_CONFIG_UMOUNT
+ help
+ Support -a option to unmount all currently mounted filesystems.
+
+comment "Common options for mount/umount"
+ depends on BUSYBOX_CONFIG_MOUNT || BUSYBOX_CONFIG_UMOUNT
+
+config BUSYBOX_CONFIG_FEATURE_MOUNT_LOOP
+ bool "Support loopback mounts"
+ default BUSYBOX_DEFAULT_FEATURE_MOUNT_LOOP
+ depends on BUSYBOX_CONFIG_MOUNT || BUSYBOX_CONFIG_UMOUNT
+ help
+ Enabling this feature allows automatic mounting of files (containing
+ filesystem images) via the linux kernel's loopback devices.
+ The mount command will detect you are trying to mount a file instead
+ of a block device, and transparently associate the file with a
+ loopback device. The umount command will also free that loopback
+ device.
+
+ You can still use the 'losetup' utility (to manually associate files
+ with loop devices) if you need to do something advanced, such as
+ specify an offset or cryptographic options to the loopback device.
+ (If you don't want umount to free the loop device, use "umount -D".)
+
+config BUSYBOX_CONFIG_FEATURE_MOUNT_LOOP_CREATE
+ bool "Create new loopback devices if needed"
+ default BUSYBOX_DEFAULT_FEATURE_MOUNT_LOOP_CREATE
+ depends on BUSYBOX_CONFIG_FEATURE_MOUNT_LOOP
+ help
+ Linux kernels >= 2.6.24 support unlimited loopback devices. They are
+ allocated for use when trying to use a loop device. The loop device
+ must however exist.
+
+ This feature lets mount to try to create next /dev/loopN device
+ if it does not find a free one.
+
+config BUSYBOX_CONFIG_FEATURE_MTAB_SUPPORT
+ bool "Support for the old /etc/mtab file"
+ default BUSYBOX_DEFAULT_FEATURE_MTAB_SUPPORT
+ depends on BUSYBOX_CONFIG_MOUNT || BUSYBOX_CONFIG_UMOUNT
+ select BUSYBOX_CONFIG_FEATURE_MOUNT_FAKE
+ help
+ Historically, Unix systems kept track of the currently mounted
+ partitions in the file "/etc/mtab". These days, the kernel exports
+ the list of currently mounted partitions in "/proc/mounts", rendering
+ the old mtab file obsolete. (In modern systems, /etc/mtab should be
+ a symlink to /proc/mounts.)
+
+ The only reason to have mount maintain an /etc/mtab file itself is if
+ your stripped-down embedded system does not have a /proc directory.
+ If you must use this, keep in mind it's inherently brittle (for
+ example a mount under chroot won't update it), can't handle modern
+ features like separate per-process filesystem namespaces, requires
+ that your /etc directory be writable, tends to get easily confused
+ by --bind or --move mounts, won't update if you rename a directory
+ that contains a mount point, and so on. (In brief: avoid.)
+
+ About the only reason to use this is if you've removed /proc from
+ your kernel.
+
+source package/utils/busybox/config/util-linux/volume_id/Config.in
+
+endmenu
diff --git a/package/utils/busybox/config/util-linux/volume_id/Config.in b/package/utils/busybox/config/util-linux/volume_id/Config.in
new file mode 100644
index 0000000..306550b
--- /dev/null
+++ b/package/utils/busybox/config/util-linux/volume_id/Config.in
@@ -0,0 +1,304 @@
+# DO NOT EDIT. This file is generated from Config.src
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+config BUSYBOX_CONFIG_VOLUMEID
+ bool #No description makes it a hidden option
+ default BUSYBOX_DEFAULT_VOLUMEID
+
+menu "Filesystem/Volume identification"
+ depends on BUSYBOX_CONFIG_VOLUMEID
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_BTRFS
+ bool "btrfs filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_BTRFS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_CRAMFS
+ bool "cramfs filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_CRAMFS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_EXFAT
+ bool "exFAT filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_EXFAT
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ exFAT (extended FAT) is a proprietary file system designed especially
+ for flash drives. It has many features from NTFS, but with less
+ overhead. exFAT is used on most SDXC cards for consumer electronics.
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_EXT
+ bool "Ext filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_EXT
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_F2FS
+ bool "f2fs filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_F2FS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ F2FS (aka Flash-Friendly File System) is a log-structured file system,
+ which is adapted to newer forms of storage. F2FS also remedies some
+ known issues of the older log structured file systems, such as high
+ cleaning overhead.
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_FAT
+ bool "fat filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_FAT
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_HFS
+ bool "hfs filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_HFS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_ISO9660
+ bool "iso9660 filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_ISO9660
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_JFS
+ bool "jfs filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_JFS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_LINUXRAID
+ bool "linuxraid"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_LINUXRAID
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_LINUXSWAP
+ bool "linux swap filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_LINUXSWAP
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_LUKS
+ bool "luks filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_LUKS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_NILFS
+ bool "nilfs filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_NILFS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ NILFS is a New Implementation of a Log-Structured File System (LFS)
+ that supports continuous snapshots. This provides features like
+ versioning of the entire filesystem, restoration of files that
+ were deleted a few minutes ago. NILFS keeps consistency like
+ conventional LFS, so it provides quick recovery after system crashes.
+
+ The possible use of NILFS includes versioning, tamper detection,
+ SOX compliance logging, and so forth. It can serve as an alternative
+ filesystem for Linux desktop environment, or as a basis of advanced
+ storage appliances.
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_NTFS
+ bool "ntfs filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_NTFS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_OCFS2
+ bool "ocfs2 filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_OCFS2
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_REISERFS
+ bool "Reiser filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_REISERFS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_ROMFS
+ bool "romfs filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_ROMFS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_SQUASHFS
+ bool "SquashFS filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_SQUASHFS
+ depends on BUSYBOX_CONFIG_VOLUMEID && BUSYBOX_CONFIG_FEATURE_BLKID_TYPE
+ help
+ Squashfs is a compressed read-only filesystem for Linux. Squashfs is
+ intended for general read-only filesystem use and in constrained block
+ device/memory systems (e.g. embedded systems) where low overhead is
+ needed.
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_SYSV
+ bool "sysv filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_SYSV
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_UDF
+ bool "udf filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_UDF
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+### config FEATURE_VOLUMEID_HIGHPOINTRAID
+### bool "highpoint raid"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_HPFS
+### bool "hpfs filesystem"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_ISWRAID
+### bool "intel raid"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_LSIRAID
+### bool "lsi raid"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_LVM
+### bool "lvm"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_MAC
+### bool "mac filesystem"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_MINIX
+### bool "minix filesystem"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_MSDOS
+### bool "msdos filesystem"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_NVIDIARAID
+### bool "nvidia raid"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_PROMISERAID
+### bool "promise raid"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_SILICONRAID
+### bool "silicon raid"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_UFS
+### bool "ufs filesystem"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+### config FEATURE_VOLUMEID_VIARAID
+### bool "via raid"
+### default y
+### depends on VOLUMEID
+### help
+### TODO
+
+
+config BUSYBOX_CONFIG_FEATURE_VOLUMEID_XFS
+ bool "xfs filesystem"
+ default BUSYBOX_DEFAULT_FEATURE_VOLUMEID_XFS
+ depends on BUSYBOX_CONFIG_VOLUMEID
+ help
+ TODO
+
+
+endmenu
diff --git a/package/utils/busybox/convert_defaults.pl b/package/utils/busybox/convert_defaults.pl
new file mode 100755
index 0000000..dada6ef
--- /dev/null
+++ b/package/utils/busybox/convert_defaults.pl
@@ -0,0 +1,13 @@
+#!/usr/bin/env perl
+
+while (<>) {
+ /^(# )?CONFIG_([^=]+)(=(.+)| is not set)/ and do {
+ my $default = $4;
+ $1 and $default = "n";
+ my $name = $2;
+ my $type = "bool";
+ $default =~ /^\"/ and $type = "string";
+ $default =~ /^\d/ and $type = "int";
+ print "config BUSYBOX_DEFAULT_$name\n\t$type\n\tdefault $default\n";
+ };
+}
diff --git a/package/utils/busybox/convert_menuconfig.pl b/package/utils/busybox/convert_menuconfig.pl
new file mode 100755
index 0000000..fd99349
--- /dev/null
+++ b/package/utils/busybox/convert_menuconfig.pl
@@ -0,0 +1,75 @@
+#!/usr/bin/perl
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+use strict;
+my $PATH = $ARGV[0];
+($PATH and -d $PATH) or die 'invalid path';
+
+my %config;
+
+open FIND, "find \"$PATH\" -name Config.in |";
+while (<FIND>) {
+ chomp;
+ my $input = $_;
+ s/^$PATH\///g;
+ s/sysdeps\/linux\///g;
+ my $output = $_;
+ print STDERR "$input => $output\n";
+ $output =~ /^(.+)\/[^\/]+$/ and system("mkdir -p $1");
+
+ open INPUT, $input;
+ open OUTPUT, ">$output";
+ my ($cur, $default_set, $line);
+ while ($line = <INPUT>) {
+ next if $line =~ /^\s*mainmenu/;
+
+ # FIXME: make this dynamic
+ $line =~ s/default FEATURE_BUFFERS_USE_MALLOC/default FEATURE_BUFFERS_GO_ON_STACK/;
+ $line =~ s/default FEATURE_SH_IS_NONE/default FEATURE_SH_IS_ASH/;
+
+ if ($line =~ /^\s*config\s*([\w_]+)/) {
+ $cur = $1;
+ undef $default_set;
+ }
+ if ($line =~ /^\s*(menu|choice|end|source)/) {
+ undef $cur;
+ undef $default_set;
+ }
+ $line =~ s/^(\s*source\s+)/$1package\/utils\/busybox\/config\//;
+ if ($line =~ /^(\s*range\s*)(\w+)(\s+)(\w+)\s*$/) {
+ my $prefix = $1;
+ my $r1 = $2;
+ my $r2 = $4;
+ $r1 =~ s/^([a-zA-Z]+)/BUSYBOX_CONFIG_$1/;
+ $r2 =~ s/^([a-zA-Z]+)/BUSYBOX_CONFIG_$1/;
+ $line = "$prefix$r1 $r2\n";
+ }
+
+ $line =~ s/^(\s*(prompt "[^"]+" if|config|depends|depends on|select|default|default \w if)\s+\!?)([A-Z_])/$1BUSYBOX_CONFIG_$3/g;
+ $line =~ s/(( \|\| | \&\& | \( )!?)([A-Z_])/$1BUSYBOX_CONFIG_$3/g;
+ $line =~ s/(\( ?!?)([A-Z_]+ (\|\||&&))/$1BUSYBOX_CONFIG_$2/g;
+
+ if ($cur) {
+ ($cur eq 'LFS') and do {
+ $line =~ s/^(\s*(bool|tristate|string))\s*".+"$/$1/;
+ };
+ if ($line =~ /^\s*default/) {
+ my $c;
+ $default_set = 1;
+ $c = "BUSYBOX_DEFAULT_$cur";
+
+ $line =~ s/^(\s*default\s*)(\w+|"[^"]*")(.*)/$1$c$3/;
+ }
+ }
+
+ print OUTPUT $line;
+ }
+ close OUTPUT;
+ close INPUT;
+}
+close FIND;
diff --git a/package/utils/busybox/files/cron b/package/utils/busybox/files/cron
new file mode 100755
index 0000000..19ecc43
--- /dev/null
+++ b/package/utils/busybox/files/cron
@@ -0,0 +1,38 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2006-2011 OpenWrt.org
+
+START=50
+
+USE_PROCD=1
+PROG=/usr/sbin/crond
+
+validate_cron_section() {
+ uci_validate_section system system "${1}" \
+ 'cronloglevel:uinteger'
+}
+
+start_service () {
+ [ -z "$(ls /etc/crontabs/)" ] && return 1
+
+ loglevel=$(uci_get "system.@system[0].cronloglevel")
+
+ [ -z "${loglevel}" ] || {
+ /sbin/validate_data uinteger "${loglevel}" 2>/dev/null
+ [ "$?" -eq 0 ] || {
+ echo "validation failed"
+ return 1
+ }
+ }
+
+ mkdir -p /var/spool/cron
+ ln -s /etc/crontabs /var/spool/cron/ 2>/dev/null
+
+ procd_open_instance
+ procd_set_param command "$PROG" -f -c /etc/crontabs -l ${loglevel:-5}
+ procd_close_instance
+}
+
+service_triggers()
+{
+ procd_add_validation validate_cron_section
+}
diff --git a/package/utils/busybox/files/ntpd-hotplug b/package/utils/busybox/files/ntpd-hotplug
new file mode 100755
index 0000000..ddc1490
--- /dev/null
+++ b/package/utils/busybox/files/ntpd-hotplug
@@ -0,0 +1,3 @@
+#!/bin/sh
+[ "$1" = stratum ] || exit 0
+ACTION="$1" /sbin/hotplug-call ntp
diff --git a/package/utils/busybox/files/sysntpd b/package/utils/busybox/files/sysntpd
new file mode 100755
index 0000000..f73bb83
--- /dev/null
+++ b/package/utils/busybox/files/sysntpd
@@ -0,0 +1,42 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2011 OpenWrt.org
+
+START=98
+
+USE_PROCD=1
+PROG=/usr/sbin/ntpd
+HOTPLUG_SCRIPT=/usr/sbin/ntpd-hotplug
+
+validate_ntp_section() {
+ uci_validate_section system timeserver "${1}" \
+ 'server:list(host)' 'enabled:bool:1' 'enable_server:bool:0'
+}
+
+start_service() {
+ local server enabled enable_server peer
+
+ validate_ntp_section ntp || {
+ echo "validation failed"
+ return 1
+ }
+
+ [ $enabled = 0 ] && return
+
+ [ -z "$server" ] && return
+
+ procd_open_instance
+ procd_set_param command "$PROG" -n
+ [ "$enable_server" = "1" ] && procd_append_param command -l
+ [ -x "$HOTPLUG_SCRIPT" ] && procd_append_param command -S "$HOTPLUG_SCRIPT"
+ for peer in $server; do
+ procd_append_param command -p $peer
+ done
+ procd_set_param respawn
+ procd_close_instance
+}
+
+service_triggers()
+{
+ procd_add_reload_trigger "system"
+ procd_add_validation validate_ntp_section
+}
diff --git a/package/utils/busybox/patches/001-resource_h_include.patch b/package/utils/busybox/patches/001-resource_h_include.patch
new file mode 100644
index 0000000..5e2f172
--- /dev/null
+++ b/package/utils/busybox/patches/001-resource_h_include.patch
@@ -0,0 +1,10 @@
+--- a/include/libbb.h
++++ b/include/libbb.h
+@@ -40,6 +40,7 @@
+ #include <poll.h>
+ #include <sys/ioctl.h>
+ #include <sys/mman.h>
++#include <sys/resource.h>
+ #include <sys/socket.h>
+ #include <sys/stat.h>
+ #include <sys/time.h>
diff --git a/package/utils/busybox/patches/100-trylink_bash.patch b/package/utils/busybox/patches/100-trylink_bash.patch
new file mode 100644
index 0000000..f9571fc
--- /dev/null
+++ b/package/utils/busybox/patches/100-trylink_bash.patch
@@ -0,0 +1,8 @@
+--- a/scripts/trylink
++++ b/scripts/trylink
+@@ -1,4 +1,4 @@
+-#!/bin/sh
++#!/usr/bin/env bash
+
+ debug=false
+
diff --git a/package/utils/busybox/patches/101-gen_build_files_bash.patch b/package/utils/busybox/patches/101-gen_build_files_bash.patch
new file mode 100644
index 0000000..d258fb8
--- /dev/null
+++ b/package/utils/busybox/patches/101-gen_build_files_bash.patch
@@ -0,0 +1,8 @@
+--- a/scripts/gen_build_files.sh
++++ b/scripts/gen_build_files.sh
+@@ -1,4 +1,4 @@
+-#!/bin/sh
++#!/usr/bin/env bash
+
+ # Note: was using sed OPTS CMD -- FILES
+ # but users complain that many sed implementations
diff --git a/package/utils/busybox/patches/102-trylink_mktemp_fix.patch b/package/utils/busybox/patches/102-trylink_mktemp_fix.patch
new file mode 100644
index 0000000..ed1dcbb
--- /dev/null
+++ b/package/utils/busybox/patches/102-trylink_mktemp_fix.patch
@@ -0,0 +1,20 @@
+--- a/scripts/trylink
++++ b/scripts/trylink
+@@ -46,7 +46,7 @@ try() {
+ }
+
+ check_cc() {
+- local tempname="$(mktemp)"
++ local tempname="$(mktemp /tmp/tmp.XXXXXXXXXX)"
+ local r
+ echo "int main(int argc,char**argv){return argv?argc:0;}" >"$tempname".c
+ # Can use "-o /dev/null", but older gcc tend to *unlink it* on failure! :(
+@@ -61,7 +61,7 @@ check_cc() {
+ }
+
+ check_libc_is_glibc() {
+- local tempname="$(mktemp)"
++ local tempname="$(mktemp /tmp/tmp.XXXXXXXXXX)"
+ local r
+ echo "\
+ #include <stdlib.h>
diff --git a/package/utils/busybox/patches/110-no_static_libgcc.patch b/package/utils/busybox/patches/110-no_static_libgcc.patch
new file mode 100644
index 0000000..2148a09
--- /dev/null
+++ b/package/utils/busybox/patches/110-no_static_libgcc.patch
@@ -0,0 +1,11 @@
+--- a/Makefile.flags
++++ b/Makefile.flags
+@@ -51,7 +51,7 @@ CFLAGS += $(call cc-option,-fno-builtin-
+ # -fno-guess-branch-probability: prohibit pseudo-random guessing
+ # of branch probabilities (hopefully makes bloatcheck more stable):
+ CFLAGS += $(call cc-option,-fno-guess-branch-probability,)
+-CFLAGS += $(call cc-option,-funsigned-char -static-libgcc,)
++CFLAGS += $(call cc-option,-funsigned-char,)
+ CFLAGS += $(call cc-option,-falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1,)
+ # Defeat .eh_frame bloat (gcc 4.6.3 x86-32 defconfig: 20% smaller busybox binary):
+ CFLAGS += $(call cc-option,-fno-unwind-tables,)
diff --git a/package/utils/busybox/patches/120-remove_uclibc_rpc_check.patch b/package/utils/busybox/patches/120-remove_uclibc_rpc_check.patch
new file mode 100644
index 0000000..5499efd
--- /dev/null
+++ b/package/utils/busybox/patches/120-remove_uclibc_rpc_check.patch
@@ -0,0 +1,12 @@
+--- a/util-linux/mount.c
++++ b/util-linux/mount.c
+@@ -236,9 +236,6 @@
+ #if ENABLE_FEATURE_MOUNT_NFS
+ /* This is just a warning of a common mistake. Possibly this should be a
+ * uclibc faq entry rather than in busybox... */
+-# if defined(__UCLIBC__) && ! defined(__UCLIBC_HAS_RPC__)
+-# error "You need to build uClibc with UCLIBC_HAS_RPC for NFS support"
+-# endif
+ # include <rpc/rpc.h>
+ # include <rpc/pmap_prot.h>
+ # include <rpc/pmap_clnt.h>
diff --git a/package/utils/busybox/patches/130-mconf_missing_sigwinch.patch b/package/utils/busybox/patches/130-mconf_missing_sigwinch.patch
new file mode 100644
index 0000000..54f878a
--- /dev/null
+++ b/package/utils/busybox/patches/130-mconf_missing_sigwinch.patch
@@ -0,0 +1,13 @@
+--- a/scripts/kconfig/mconf.c
++++ b/scripts/kconfig/mconf.c
+@@ -27,6 +27,10 @@
+ #include <unistd.h>
+ #include <locale.h>
+
++#ifndef SIGWINCH
++#define SIGWINCH 28
++#endif
++
+ #define LKC_DIRECT_LINK
+ #include "lkc.h"
+
diff --git a/package/utils/busybox/patches/200-udhcpc_reduce_msgs.patch b/package/utils/busybox/patches/200-udhcpc_reduce_msgs.patch
new file mode 100644
index 0000000..1083675
--- /dev/null
+++ b/package/utils/busybox/patches/200-udhcpc_reduce_msgs.patch
@@ -0,0 +1,18 @@
+--- a/networking/udhcp/dhcpc.c
++++ b/networking/udhcp/dhcpc.c
+@@ -695,6 +695,7 @@ static int bcast_or_ucast(struct dhcp_pa
+ static NOINLINE int send_discover(uint32_t xid, uint32_t requested)
+ {
+ struct dhcp_packet packet;
++ static int msgs = 0;
+
+ /* Fill in: op, htype, hlen, cookie, chaddr fields,
+ * random xid field (we override it below),
+@@ -712,6 +713,7 @@ static NOINLINE int send_discover(uint32
+ */
+ add_client_options(&packet);
+
++ if (msgs++ < 3)
+ bb_info_msg("Sending discover...");
+ return raw_bcast_from_client_config_ifindex(&packet);
+ }
diff --git a/package/utils/busybox/patches/201-udhcpc_changed_ifindex.patch b/package/utils/busybox/patches/201-udhcpc_changed_ifindex.patch
new file mode 100644
index 0000000..f32cea2
--- /dev/null
+++ b/package/utils/busybox/patches/201-udhcpc_changed_ifindex.patch
@@ -0,0 +1,15 @@
+--- a/networking/udhcp/dhcpc.c
++++ b/networking/udhcp/dhcpc.c
+@@ -1418,6 +1418,12 @@ int udhcpc_main(int argc UNUSED_PARAM, c
+ /* silence "uninitialized!" warning */
+ unsigned timestamp_before_wait = timestamp_before_wait;
+
++ /* When running on a bridge, the ifindex may have changed (e.g. if
++ * member interfaces were added/removed or if the status of the
++ * bridge changed).
++ * Workaround: refresh it here before processing the next packet */
++ udhcp_read_interface(client_config.interface, &client_config.ifindex, NULL, client_config.client_mac);
++
+ //bb_error_msg("sockfd:%d, listen_mode:%d", sockfd, listen_mode);
+
+ /* Was opening raw or udp socket here
diff --git a/package/utils/busybox/patches/203-udhcpc_renew_no_deconfig.patch b/package/utils/busybox/patches/203-udhcpc_renew_no_deconfig.patch
new file mode 100644
index 0000000..f38b128
--- /dev/null
+++ b/package/utils/busybox/patches/203-udhcpc_renew_no_deconfig.patch
@@ -0,0 +1,10 @@
+--- a/networking/udhcp/dhcpc.c
++++ b/networking/udhcp/dhcpc.c
+@@ -1101,7 +1101,6 @@ static void perform_renew(void)
+ state = RENEW_REQUESTED;
+ break;
+ case RENEW_REQUESTED: /* impatient are we? fine, square 1 */
+- udhcp_run_script(NULL, "deconfig");
+ case REQUESTING:
+ case RELEASED:
+ change_listen_mode(LISTEN_RAW);
diff --git a/package/utils/busybox/patches/204-udhcpc_src_ip_rebind.patch b/package/utils/busybox/patches/204-udhcpc_src_ip_rebind.patch
new file mode 100644
index 0000000..21fec51
--- /dev/null
+++ b/package/utils/busybox/patches/204-udhcpc_src_ip_rebind.patch
@@ -0,0 +1,51 @@
+--- a/networking/udhcp/dhcpc.c
++++ b/networking/udhcp/dhcpc.c
+@@ -673,10 +673,10 @@ static void add_client_options(struct dh
+ * client reverts to using the IP broadcast address.
+ */
+
+-static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet)
++static int raw_bcast_from_client_config_ifindex(struct dhcp_packet *packet, uint32_t src_nip)
+ {
+ return udhcp_send_raw_packet(packet,
+- /*src*/ INADDR_ANY, CLIENT_PORT,
++ /*src*/ src_nip, CLIENT_PORT,
+ /*dst*/ INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR,
+ client_config.ifindex);
+ }
+@@ -687,7 +687,7 @@ static int bcast_or_ucast(struct dhcp_pa
+ return udhcp_send_kernel_packet(packet,
+ ciaddr, CLIENT_PORT,
+ server, SERVER_PORT);
+- return raw_bcast_from_client_config_ifindex(packet);
++ return raw_bcast_from_client_config_ifindex(packet, ciaddr);
+ }
+
+ /* Broadcast a DHCP discover packet to the network, with an optionally requested IP */
+@@ -715,7 +715,7 @@ static NOINLINE int send_discover(uint32
+
+ if (msgs++ < 3)
+ bb_info_msg("Sending discover...");
+- return raw_bcast_from_client_config_ifindex(&packet);
++ return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY);
+ }
+
+ /* Broadcast a DHCP request message */
+@@ -759,7 +759,7 @@ static NOINLINE int send_select(uint32_t
+
+ addr.s_addr = requested;
+ bb_info_msg("Sending select for %s...", inet_ntoa(addr));
+- return raw_bcast_from_client_config_ifindex(&packet);
++ return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY);
+ }
+
+ /* Unicast or broadcast a DHCP renew message */
+@@ -827,7 +827,7 @@ static NOINLINE int send_decline(/*uint3
+ udhcp_add_simple_option(&packet, DHCP_SERVER_ID, server);
+
+ bb_info_msg("Sending decline...");
+- return raw_bcast_from_client_config_ifindex(&packet);
++ return raw_bcast_from_client_config_ifindex(&packet, INADDR_ANY);
+ }
+ #endif
+
diff --git a/package/utils/busybox/patches/210-add_netmsg_util.patch b/package/utils/busybox/patches/210-add_netmsg_util.patch
new file mode 100644
index 0000000..8162e3b
--- /dev/null
+++ b/package/utils/busybox/patches/210-add_netmsg_util.patch
@@ -0,0 +1,103 @@
+--- a/include/applets.src.h
++++ b/include/applets.src.h
+@@ -254,6 +254,7 @@ IF_MT(APPLET(mt, BB_DIR_BIN, BB_SUID_DRO
+ IF_MV(APPLET(mv, BB_DIR_BIN, BB_SUID_DROP))
+ IF_NAMEIF(APPLET(nameif, BB_DIR_SBIN, BB_SUID_DROP))
+ IF_NC(APPLET(nc, BB_DIR_USR_BIN, BB_SUID_DROP))
++IF_NETMSG(APPLET(netmsg, BB_DIR_BIN, BB_SUID_REQUIRE))
+ IF_NETSTAT(APPLET(netstat, BB_DIR_BIN, BB_SUID_DROP))
+ IF_NICE(APPLET(nice, BB_DIR_BIN, BB_SUID_DROP))
+ IF_NOHUP(APPLET(nohup, BB_DIR_USR_BIN, BB_SUID_DROP))
+--- a/networking/Config.src
++++ b/networking/Config.src
+@@ -626,6 +626,12 @@ config FEATURE_IPCALC_LONG_OPTIONS
+ help
+ Support long options for the ipcalc applet.
+
++config NETMSG
++ bool "netmsg"
++ default n
++ help
++ simple program for sending udp broadcast messages
++
+ config NETSTAT
+ bool "netstat"
+ default y
+--- a/networking/Kbuild.src
++++ b/networking/Kbuild.src
+@@ -27,6 +27,7 @@ lib-$(CONFIG_IP) += ip.o
+ lib-$(CONFIG_IPCALC) += ipcalc.o
+ lib-$(CONFIG_NAMEIF) += nameif.o
+ lib-$(CONFIG_NC) += nc.o
++lib-$(CONFIG_NETMSG) += netmsg.o
+ lib-$(CONFIG_NETSTAT) += netstat.o
+ lib-$(CONFIG_NSLOOKUP) += nslookup.o
+ lib-$(CONFIG_NTPD) += ntpd.o
+--- /dev/null
++++ b/networking/netmsg.c
+@@ -0,0 +1,65 @@
++/*
++ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
++ *
++ * This is free software, licensed under the GNU General Public License v2.
++ */
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <netdb.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include "busybox.h"
++
++//usage:#define netmsg_trivial_usage NOUSAGE_STR
++//usage:#define netmsg_full_usage ""
++
++#ifndef CONFIG_NETMSG
++int main(int argc, char **argv)
++#else
++int netmsg_main(int argc, char **argv)
++#endif
++{
++ int s;
++ struct sockaddr_in addr;
++ int optval = 1;
++ unsigned char buf[1001];
++
++ if (argc != 3) {
++ fprintf(stderr, "usage: %s <ip> \"<message>\"\n", argv[0]);
++ exit(1);
++ }
++
++ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
++ perror("Opening socket");
++ exit(1);
++ }
++
++ memset(&addr, 0, sizeof(addr));
++ addr.sin_family = AF_INET;
++ addr.sin_addr.s_addr = inet_addr(argv[1]);
++ addr.sin_port = htons(0x1337);
++
++ memset(buf, 0, 1001);
++ buf[0] = 0xde;
++ buf[1] = 0xad;
++
++ strncpy(buf + 2, argv[2], 998);
++
++ if (setsockopt (s, SOL_SOCKET, SO_BROADCAST, (caddr_t) &optval, sizeof (optval)) < 0) {
++ perror("setsockopt()");
++ goto fail;
++ }
++
++ if (sendto(s, buf, 1001, 0, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
++ perror("sendto()");
++ goto fail;
++ }
++
++ return 0;
++
++fail:
++ close(s);
++ exit(1);
++}
diff --git a/package/utils/busybox/patches/220-add_lock_util.patch b/package/utils/busybox/patches/220-add_lock_util.patch
new file mode 100644
index 0000000..9cac9e6
--- /dev/null
+++ b/package/utils/busybox/patches/220-add_lock_util.patch
@@ -0,0 +1,182 @@
+--- a/include/applets.src.h
++++ b/include/applets.src.h
+@@ -211,6 +211,7 @@ IF_LN(APPLET_NOEXEC(ln, ln, BB_DIR_BIN,
+ IF_LOAD_POLICY(APPLET(load_policy, BB_DIR_USR_SBIN, BB_SUID_DROP))
+ IF_LOADFONT(APPLET(loadfont, BB_DIR_USR_SBIN, BB_SUID_DROP))
+ IF_LOADKMAP(APPLET(loadkmap, BB_DIR_SBIN, BB_SUID_DROP))
++IF_LOCK(APPLET(lock, BB_DIR_BIN, BB_SUID_DROP))
+ IF_LOGGER(APPLET(logger, BB_DIR_USR_BIN, BB_SUID_DROP))
+ /* Needs to be run by root or be suid root - needs to change uid and gid: */
+ IF_LOGIN(APPLET(login, BB_DIR_BIN, BB_SUID_REQUIRE))
+--- a/miscutils/Config.src
++++ b/miscutils/Config.src
+@@ -385,6 +385,12 @@ config FEATURE_HDPARM_HDIO_GETSET_DMA
+ help
+ Enables the 'hdparm -d' option to get/set using_dma flag.
+
++config LOCK
++ bool "lock"
++ default n
++ help
++ Small utility for using locks in scripts
++
+ config MAKEDEVS
+ bool "makedevs"
+ default y
+--- a/miscutils/Kbuild.src
++++ b/miscutils/Kbuild.src
+@@ -28,6 +28,7 @@ lib-$(CONFIG_INOTIFYD) += inotifyd.o
+ lib-$(CONFIG_FEATURE_LAST_SMALL)+= last.o
+ lib-$(CONFIG_FEATURE_LAST_FANCY)+= last_fancy.o
+ lib-$(CONFIG_LESS) += less.o
++lib-$(CONFIG_LOCK) += lock.o
+ lib-$(CONFIG_MAKEDEVS) += makedevs.o
+ lib-$(CONFIG_MAN) += man.o
+ lib-$(CONFIG_MICROCOM) += microcom.o
+--- /dev/null
++++ b/miscutils/lock.c
+@@ -0,0 +1,144 @@
++/*
++ * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org>
++ *
++ * This is free software, licensed under the GNU General Public License v2.
++ */
++#include <sys/types.h>
++#include <sys/file.h>
++#include <sys/stat.h>
++#include <signal.h>
++#include <fcntl.h>
++#include <unistd.h>
++#include <stdio.h>
++#include "busybox.h"
++
++//usage:#define lock_trivial_usage NOUSAGE_STR
++//usage:#define lock_full_usage ""
++
++static int unlock = 0;
++static int shared = 0;
++static int waitonly = 0;
++static int try_lock = 0;
++static int fd;
++static char *file;
++
++static void usage(char *name)
++{
++ fprintf(stderr, "Usage: %s [-suw] <filename>\n"
++ " -s Use shared locking\n"
++ " -u Unlock\n"
++ " -w Wait for the lock to become free, don't acquire lock\n"
++ " -n Don't wait for the lock to become free. Fail with exit code\n"
++ "\n", name);
++ exit(1);
++}
++
++static void exit_unlock(int sig)
++{
++ flock(fd, LOCK_UN);
++ exit(0);
++}
++
++static int do_unlock(void)
++{
++ FILE *f;
++ int i;
++
++ if ((f = fopen(file, "r")) == NULL)
++ return 0;
++
++ fscanf(f, "%d", &i);
++ if (i > 0)
++ kill(i, SIGTERM);
++
++ fclose(f);
++
++ return 0;
++}
++
++static int do_lock(void)
++{
++ int pid;
++ int flags;
++ char pidstr[8];
++
++ if ((fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0700)) < 0) {
++ if ((fd = open(file, O_RDWR)) < 0) {
++ fprintf(stderr, "Can't open %s\n", file);
++ return 1;
++ }
++ }
++
++ flags = shared ? LOCK_SH : LOCK_EX;
++ flags |= try_lock ? LOCK_NB : 0;
++
++ if (flock(fd, flags) < 0) {
++ fprintf(stderr, "Can't lock %s\n", file);
++ return 1;
++ }
++
++ pid = fork();
++
++ if (pid < 0)
++ return -1;
++
++ if (pid == 0) {
++ signal(SIGKILL, exit_unlock);
++ signal(SIGTERM, exit_unlock);
++ signal(SIGINT, exit_unlock);
++ if (waitonly)
++ exit_unlock(0);
++ else
++ while (1)
++ sleep(1);
++ } else {
++ if (!waitonly) {
++ lseek(fd, 0, SEEK_SET);
++ ftruncate(fd, 0);
++ sprintf(pidstr, "%d\n", pid);
++ write(fd, pidstr, strlen(pidstr));
++ close(fd);
++ }
++
++ return 0;
++ }
++ return 0;
++}
++
++int lock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
++int lock_main(int argc, char **argv)
++{
++ char **args = &argv[1];
++ int c = argc - 1;
++
++ while ((*args != NULL) && (*args)[0] == '-') {
++ char *ch = *args;
++ while (*(++ch) > 0) {
++ switch(*ch) {
++ case 'w':
++ waitonly = 1;
++ break;
++ case 's':
++ shared = 1;
++ break;
++ case 'u':
++ unlock = 1;
++ break;
++ case 'n':
++ try_lock = 1;
++ break;
++ }
++ }
++ c--;
++ args++;
++ }
++
++ if (c != 1)
++ usage(argv[0]);
++
++ file = *args;
++ if (unlock)
++ return do_unlock();
++ else
++ return do_lock();
++}
diff --git a/package/utils/busybox/patches/230-ntpd_delayed_resolve.patch b/package/utils/busybox/patches/230-ntpd_delayed_resolve.patch
new file mode 100644
index 0000000..b0af08e
--- /dev/null
+++ b/package/utils/busybox/patches/230-ntpd_delayed_resolve.patch
@@ -0,0 +1,48 @@
+--- a/networking/ntpd.c
++++ b/networking/ntpd.c
+@@ -265,6 +265,7 @@ typedef struct {
+ typedef struct {
+ len_and_sockaddr *p_lsa;
+ char *p_dotted;
++ char *p_hostname;
+ int p_fd;
+ int datapoint_idx;
+ uint32_t lastpkt_refid;
+@@ -766,8 +767,9 @@ add_peers(const char *s)
+ peer_t *p;
+
+ p = xzalloc(sizeof(*p));
+- p->p_lsa = xhost2sockaddr(s, 123);
+- p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa);
++ p->p_hostname = s;
++ p->p_lsa = NULL;
++ p->p_dotted = NULL;
+ p->p_fd = -1;
+ p->p_xmt_msg.m_status = MODE_CLIENT | (NTP_VERSION << 3);
+ p->next_action_time = G.cur_time; /* = set_next(p, 0); */
+@@ -816,6 +818,25 @@ send_query_to_peer(peer_t *p)
+ *
+ * Uncomment this and use strace to see it in action:
+ */
++
++ /* See if the peer hostname already resolved yet, if not, retry to resolv and return on failure */
++ if (!p->p_lsa)
++ {
++ p->p_lsa = host2sockaddr(p->p_hostname, 123);
++
++ if (p->p_lsa)
++ {
++ p->p_dotted = xmalloc_sockaddr2dotted_noport(&p->p_lsa->u.sa);
++ VERB1 bb_error_msg("resolved peer %s to %s", p->p_hostname, p->p_dotted);
++ }
++ else
++ {
++ set_next(p, RETRY_INTERVAL);
++ VERB1 bb_error_msg("could not resolve peer %s, skipping", p->p_hostname);
++ return;
++ }
++ }
++
+ #define PROBE_LOCAL_ADDR /* { len_and_sockaddr lsa; lsa.len = LSA_SIZEOF_SA; getsockname(p->query.fd, &lsa.u.sa, &lsa.len); } */
+
+ if (p->p_fd == -1) {
diff --git a/package/utils/busybox/patches/240-telnetd_intr.patch b/package/utils/busybox/patches/240-telnetd_intr.patch
new file mode 100644
index 0000000..ccb4ea4
--- /dev/null
+++ b/package/utils/busybox/patches/240-telnetd_intr.patch
@@ -0,0 +1,10 @@
+--- a/networking/telnetd.c
++++ b/networking/telnetd.c
+@@ -331,6 +331,7 @@ make_new_session(
+
+ /* Restore default signal handling ASAP */
+ bb_signals((1 << SIGCHLD) + (1 << SIGPIPE), SIG_DFL);
++ signal(SIGINT, SIG_DFL);
+
+ pid = getpid();
+
diff --git a/package/utils/busybox/patches/250-date-k-flag.patch b/package/utils/busybox/patches/250-date-k-flag.patch
new file mode 100644
index 0000000..f0dab26
--- /dev/null
+++ b/package/utils/busybox/patches/250-date-k-flag.patch
@@ -0,0 +1,87 @@
+--- a/coreutils/date.c
++++ b/coreutils/date.c
+@@ -123,6 +123,7 @@
+ //usage: IF_FEATURE_DATE_ISOFMT(
+ //usage: "\n -D FMT Use FMT for -d TIME conversion"
+ //usage: )
++//usage: "\n -k Set Kernel timezone from localtime and exit"
+ //usage: "\n"
+ //usage: "\nRecognized TIME formats:"
+ //usage: "\n hh:mm[:ss]"
+@@ -138,6 +139,7 @@
+ //usage: "Wed Apr 12 18:52:41 MDT 2000\n"
+
+ #include "libbb.h"
++#include <sys/time.h>
+ #if ENABLE_FEATURE_DATE_NANO
+ # include <sys/syscall.h>
+ #endif
+@@ -148,8 +150,9 @@ enum {
+ OPT_UTC = (1 << 2), /* u */
+ OPT_DATE = (1 << 3), /* d */
+ OPT_REFERENCE = (1 << 4), /* r */
+- OPT_TIMESPEC = (1 << 5) * ENABLE_FEATURE_DATE_ISOFMT, /* I */
+- OPT_HINT = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* D */
++ OPT_KERNELTZ = (1 << 5), /* k */
++ OPT_TIMESPEC = (1 << 6) * ENABLE_FEATURE_DATE_ISOFMT, /* I */
++ OPT_HINT = (1 << 7) * ENABLE_FEATURE_DATE_ISOFMT, /* D */
+ };
+
+ static void maybe_set_utc(int opt)
+@@ -167,12 +170,15 @@ static const char date_longopts[] ALIGN1
+ /* "universal\0" No_argument "u" */
+ "date\0" Required_argument "d"
+ "reference\0" Required_argument "r"
++ "set-kernel-tz\0" No_argument "k"
+ ;
+ #endif
+
+ int date_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+ int date_main(int argc UNUSED_PARAM, char **argv)
+ {
++ time_t tt;
++ struct timezone tz;
+ struct timespec ts;
+ struct tm tm_time;
+ char buf_fmt_dt2str[64];
+@@ -187,7 +193,7 @@ int date_main(int argc UNUSED_PARAM, cha
+ opt_complementary = "d--s:s--d"
+ IF_FEATURE_DATE_ISOFMT(":R--I:I--R");
+ IF_LONG_OPTS(applet_long_options = date_longopts;)
+- opt = getopt32(argv, "Rs:ud:r:"
++ opt = getopt32(argv, "Rs:ud:r:k"
+ IF_FEATURE_DATE_ISOFMT("I::D:"),
+ &date_str, &date_str, &filename
+ IF_FEATURE_DATE_ISOFMT(, &isofmt_arg, &fmt_str2dt));
+@@ -244,6 +250,31 @@ int date_main(int argc UNUSED_PARAM, cha
+ if (*argv)
+ bb_show_usage();
+
++ /* Setting of kernel timezone was requested */
++ if (opt & OPT_KERNELTZ) {
++ tt = time(NULL);
++ localtime_r(&tt, &tm_time);
++
++ /* workaround warp_clock() on first invocation */
++ memset(&tz, 0, sizeof(tz));
++ settimeofday(NULL, &tz);
++
++ memset(&tz, 0, sizeof(tz));
++#ifdef __USE_MISC
++ tz.tz_minuteswest = -(tm_time.tm_gmtoff / 60);
++#else
++ tz.tz_minuteswest = -(tm_time.__tm_gmtoff / 60);
++#endif
++
++ if (settimeofday(NULL, &tz))
++ {
++ bb_perror_msg("can't set kernel time zone");
++ return EXIT_FAILURE;
++ }
++
++ return EXIT_SUCCESS;
++ }
++
+ /* Now we have parsed all the information except the date format
+ * which depends on whether the clock is being set or read */
+
diff --git a/package/utils/busybox/patches/260-arping_missing_includes.patch b/package/utils/busybox/patches/260-arping_missing_includes.patch
new file mode 100644
index 0000000..a9d4a62
--- /dev/null
+++ b/package/utils/busybox/patches/260-arping_missing_includes.patch
@@ -0,0 +1,11 @@
+--- a/networking/arping.c
++++ b/networking/arping.c
+@@ -24,6 +24,8 @@
+
+ #include <arpa/inet.h>
+ #include <net/if.h>
++#include <net/if_arp.h>
++#include <netinet/if_ether.h>
+ #include <netinet/ether.h>
+ #include <netpacket/packet.h>
+
diff --git a/package/utils/busybox/patches/270-libbb_make_unicode_printable.patch b/package/utils/busybox/patches/270-libbb_make_unicode_printable.patch
new file mode 100644
index 0000000..0ae8340
--- /dev/null
+++ b/package/utils/busybox/patches/270-libbb_make_unicode_printable.patch
@@ -0,0 +1,20 @@
+--- a/libbb/printable_string.c
++++ b/libbb/printable_string.c
+@@ -28,8 +28,6 @@ const char* FAST_FUNC printable_string(u
+ }
+ if (c < ' ')
+ break;
+- if (c >= 0x7f)
+- break;
+ s++;
+ }
+
+@@ -42,7 +40,7 @@ const char* FAST_FUNC printable_string(u
+ unsigned char c = *d;
+ if (c == '\0')
+ break;
+- if (c < ' ' || c >= 0x7f)
++ if (c < ' ')
+ *d = '?';
+ d++;
+ }
diff --git a/package/utils/busybox/patches/301-ip-link-fix-netlink-msg-size.patch b/package/utils/busybox/patches/301-ip-link-fix-netlink-msg-size.patch
new file mode 100644
index 0000000..360324b
--- /dev/null
+++ b/package/utils/busybox/patches/301-ip-link-fix-netlink-msg-size.patch
@@ -0,0 +1,11 @@
+--- a/networking/libiproute/iplink.c
++++ b/networking/libiproute/iplink.c
+@@ -470,7 +470,7 @@ static int do_add_or_delete(char **argv,
+ }
+ xrtnl_open(&rth);
+ ll_init_map(&rth);
+- if (type_str) {
++ if (type_str && rtm == RTM_NEWLINK) {
+ struct rtattr *linkinfo = NLMSG_TAIL(&req.n);
+
+ addattr_l(&req.n, sizeof(req), IFLA_LINKINFO, NULL, 0);
diff --git a/package/utils/bzip2/Makefile b/package/utils/bzip2/Makefile
new file mode 100644
index 0000000..ba47cfb
--- /dev/null
+++ b/package/utils/bzip2/Makefile
@@ -0,0 +1,109 @@
+#
+# Copyright (C) 2007-2008 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=bzip2
+PKG_VERSION:=1.0.6
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.bzip.org/$(PKG_VERSION)
+PKG_MD5SUM:=00b516f4704d4a7cb50a1d97e6e8e15b
+PKG_MAINTAINER:=Steven Barth <cyrus@openwrt.org>
+
+PKG_LICENSE:=BZIP2
+PKG_LICENSE_FILES:=LICENSE
+
+include $(INCLUDE_DIR)/host-build.mk
+include $(INCLUDE_DIR)/package.mk
+
+define Package/bzip2/Default
+ SUBMENU:=Compression
+ URL:=http://www.bzip.org/
+endef
+
+define Package/libbz2
+$(call Package/bzip2/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ DEPENDS:=
+ TITLE:=bzip2 library.
+endef
+
+define Package/libbz2/description
+ bzip2 is a freely available, patent free, high-quality
+ data compressor. This packages provides libbz2 library.
+endef
+
+define Package/bzip2
+$(call Package/bzip2/Default)
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=+libbz2
+ TITLE:=bzip2 is a compression utility.
+endef
+
+define Package/bzip2/description
+ bzip2 is a freely available, patent free, high-quality
+ data compressor. This package provides the binary.
+endef
+
+TARGET_CFLAGS += \
+ $(FPIC) \
+ $(TARGET_LDFLAGS)
+
+CONFIGURE_ARGS += --prefix=/usr
+
+MAKE_FLAGS += \
+ -f Makefile-libbz2_so \
+ CFLAGS="$(TARGET_CFLAGS)" \
+ all
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_BUILD_DIR)/bzlib.h $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/libbz2.so.$(PKG_VERSION) $(1)/usr/lib/
+ $(LN) libbz2.so.$(PKG_VERSION) $(1)/usr/lib/libbz2.so.1.0
+ $(LN) libbz2.so.$(PKG_VERSION) $(1)/usr/lib/libbz2.so
+endef
+
+define Package/libbz2/install
+ $(INSTALL_DIR) $(1)/usr/lib/
+ $(CP) $(PKG_BUILD_DIR)/libbz2.so.$(PKG_VERSION) $(1)/usr/lib/
+ $(LN) libbz2.so.$(PKG_VERSION) $(1)/usr/lib/libbz2.so.1.0
+endef
+
+define Package/bzip2/install
+ $(INSTALL_DIR) $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/bzip2-shared $(1)/usr/bin/bzip2
+endef
+
+HOST_CFLAGS += \
+ $(FPIC) \
+ $(HOST_LDFLAGS)
+
+HOST_MAKE_FLAGS+= \
+ -f Makefile-libbz2_so \
+ CFLAGS="$(HOST_CFLAGS)" \
+ all
+
+HOST_CONFIGURE_ARGS+= \
+ --prefix=$(STAGING_DIR_HOST)
+
+define Host/Install
+ $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin/ $(STAGING_DIR_HOST)/usr/lib
+ $(MAKE) -C $(HOST_BUILD_DIR) PREFIX=$(STAGING_DIR_HOST)/usr/ install
+ $(CP) $(HOST_BUILD_DIR)/libbz2.so* $(STAGING_DIR_HOST)/usr/lib/
+ $(CP) $(HOST_BUILD_DIR)/libbz2.so.1.0 $(STAGING_DIR_HOST)/usr/lib/libbz2.so
+endef
+
+$(eval $(call HostBuild))
+
+$(eval $(call BuildPackage,libbz2))
+$(eval $(call BuildPackage,bzip2))
diff --git a/package/utils/e2fsprogs/Makefile b/package/utils/e2fsprogs/Makefile
new file mode 100644
index 0000000..6c835e6
--- /dev/null
+++ b/package/utils/e2fsprogs/Makefile
@@ -0,0 +1,230 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+# Copyright 2010 Vertical Communications
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=e2fsprogs
+PKG_VERSION:=1.42.12
+PKG_MD5SUM:=68255f51be017a93f2f6402fab06c2bf
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/e2fsprogs
+
+PKG_BUILD_DEPENDS:=util-linux
+PKG_INSTALL:=1
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/e2fsprogs/Default
+ URL:=http://e2fsprogs.sourceforge.net/
+ SUBMENU:=Filesystem
+endef
+
+define Package/e2fsprogs
+$(call Package/e2fsprogs/Default)
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Ext2/3/4 filesystem utilities
+ DEPENDS:=+libuuid +libext2fs
+endef
+
+define Package/e2fsprogs/description
+ This package contains essential ext2 filesystem utilities which consists of
+ e2fsck, mke2fs and most of the other core ext2 filesystem utilities.
+endef
+
+define Package/libext2fs
+$(call Package/e2fsprogs/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE:=ext2/3/4 filesystem library
+endef
+
+define Package/libext2fs/description
+ libext2fs is a library which can access ext2, ext3 and ext4 filesystems.
+endef
+
+define Package/tune2fs
+$(call Package/e2fsprogs)
+ TITLE:=Ext2 Filesystem tune utility
+ DEPENDS:= +e2fsprogs
+endef
+
+define Package/resize2fs
+$(call Package/e2fsprogs)
+ TITLE:=Ext2 Filesystem resize utility
+ DEPENDS:= +e2fsprogs
+endef
+
+define Package/badblocks
+$(call Package/e2fsprogs)
+ TITLE:=Ext2 Filesystem badblocks utility
+ DEPENDS:= +e2fsprogs
+endef
+
+define Package/dumpe2fs
+$(call Package/e2fsprogs)
+ TITLE:=Ext2 Filesystem information dumping utility
+ DEPENDS:= +e2fsprogs
+endef
+
+define Package/e2freefrag
+$(call Package/e2fsprogs)
+ TITLE:=Ext2 Filesystem free space fragmentation information utility
+ DEPENDS:= +e2fsprogs
+endef
+
+define Package/filefrag
+$(call Package/e2fsprogs)
+ TITLE:=Ext2 Filesystem file fragmentation report utility
+ DEPENDS:= +e2fsprogs
+endef
+
+define Package/debugfs
+$(call Package/e2fsprogs)
+ TITLE:=Ext2 Filesystem debugger
+ DEPENDS:= +e2fsprogs
+endef
+
+TARGET_CFLAGS += $(FPIC) -ffunction-sections -fdata-sections
+
+CONFIGURE_VARS += \
+ ac_cv_lib_pthread_sem_init=no
+
+CONFIGURE_ARGS += \
+ --disable-testio-debug \
+ --enable-elf-shlibs \
+ --disable-libuuid \
+ --enable-libblkid \
+ --disable-uuidd \
+ --disable-tls \
+ --disable-nls \
+ --disable-rpath
+
+define Build/Prepare
+ $(call Build/Prepare/Default)
+ $(CP) $(SCRIPT_DIR)/config.{guess,sub} $(PKG_BUILD_DIR)/config/
+endef
+
+define Build/Compile
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR)/util \
+ BUILDCC="$(HOSTCC)" \
+ CFLAGS="" \
+ CPPFLAGS="" \
+ LDFLAGS="" \
+ subst
+ +$(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+ LDFLAGS=-Wl,--gc-sections \
+ BUILDCC="$(HOSTCC)" \
+ DESTDIR="$(PKG_INSTALL_DIR)" \
+ LIBBLKID="$(PKG_BUILD_DIR)/lib/libblkid.a -luuid" \
+ all
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_BUILD_DIR)/lib/ext2fs/ext2fs.pc $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_BUILD_DIR)/lib/et/com_err.pc $(1)/usr/lib/pkgconfig
+
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/lib/libext2fs.{so,a}* $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/lib/libcom_err.{so,a}* $(1)/usr/lib
+
+ $(INSTALL_DIR) $(1)/usr/include/ext2fs
+ $(CP) $(PKG_BUILD_DIR)/lib/ext2fs/*.h $(1)/usr/include/ext2fs
+ $(INSTALL_DIR) $(1)/usr/include/et
+ $(CP) $(PKG_BUILD_DIR)/lib/et/*.h $(1)/usr/include/et
+endef
+
+define Package/e2fsprogs/conffiles
+/etc/e2fsck.conf
+endef
+
+define Package/e2fsprogs/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/e2fsck $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/mke2fs $(1)/usr/sbin/
+ $(LN) mke2fs $(1)/usr/sbin/mkfs.ext2
+ $(LN) mke2fs $(1)/usr/sbin/mkfs.ext3
+ $(LN) mke2fs $(1)/usr/sbin/mkfs.ext4
+ $(LN) e2fsck $(1)/usr/sbin/fsck.ext2
+ $(LN) e2fsck $(1)/usr/sbin/fsck.ext3
+ $(LN) e2fsck $(1)/usr/sbin/fsck.ext4
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libe2p.so.* $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_DIR) $(1)/lib/functions/fsck
+ $(INSTALL_DATA) ./files/e2fsck.sh $(1)/lib/functions/fsck/
+ $(INSTALL_DATA) ./files/e2fsck.conf $(1)/etc/e2fsck.conf
+endef
+
+define Package/libcom_err/install
+endef
+
+define Package/libext2fs/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) \
+ $(PKG_INSTALL_DIR)/usr/lib/libext2fs.so.* \
+ $(PKG_INSTALL_DIR)/usr/lib/libcom_err.so.* \
+ $(1)/usr/lib/
+endef
+
+define Package/libext2fs/install_lib
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/lib/ext2fs/libext2fs.a $(1)/usr/lib/libext2fs_pic.a
+endef
+
+define Package/tune2fs/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/tune2fs $(1)/usr/sbin/
+ $(LN) tune2fs $(1)/usr/sbin/findfs
+endef
+
+define Package/resize2fs/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/resize2fs $(1)/usr/sbin/
+endef
+
+define Package/badblocks/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/badblocks $(1)/usr/sbin/
+endef
+
+define Package/dumpe2fs/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/dumpe2fs $(1)/usr/sbin/
+endef
+
+define Package/e2freefrag/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/e2freefrag $(1)/usr/sbin/
+endef
+
+define Package/filefrag/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/filefrag $(1)/usr/sbin/
+endef
+
+define Package/debugfs/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/debugfs $(1)/usr/sbin/
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/libss.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,e2fsprogs))
+$(eval $(call BuildPackage,libext2fs))
+$(eval $(call BuildPackage,tune2fs))
+$(eval $(call BuildPackage,resize2fs))
+$(eval $(call BuildPackage,badblocks))
+$(eval $(call BuildPackage,dumpe2fs))
+$(eval $(call BuildPackage,e2freefrag))
+$(eval $(call BuildPackage,filefrag))
+$(eval $(call BuildPackage,debugfs))
diff --git a/package/utils/e2fsprogs/files/e2fsck.conf b/package/utils/e2fsprogs/files/e2fsck.conf
new file mode 100644
index 0000000..9c96b49
--- /dev/null
+++ b/package/utils/e2fsprogs/files/e2fsck.conf
@@ -0,0 +1,3 @@
+[options]
+broken_system_clock = true
+
diff --git a/package/utils/e2fsprogs/files/e2fsck.sh b/package/utils/e2fsprogs/files/e2fsck.sh
new file mode 100644
index 0000000..22031ed
--- /dev/null
+++ b/package/utils/e2fsprogs/files/e2fsck.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+# Copyright 2010 Vertical Communications
+# Copyright 2012 OpenWrt.org
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+fsck_e2fsck() {
+ set -o pipefail
+ e2fsck -p "$device" 2>&1 | logger -t "fstab: e2fsck ($device)"
+ local status="$?"
+ set +o pipefail
+ case "$status" in
+ 0|1) ;; #success
+ 2) reboot;;
+ 4) echo "e2fsck ($device): Warning! Uncorrected errors."| logger -t fstab
+ return 1
+ ;;
+ *) echo "e2fsck ($device): Error $status. Check not complete."| logger -t fstab;;
+ esac
+ return 0
+}
+
+fsck_ext2() {
+ fsck_e2fsck "$@"
+}
+
+fsck_ext3() {
+ fsck_e2fsck "$@"
+}
+
+fsck_ext4() {
+ fsck_e2fsck "$@"
+}
+
+append libmount_known_fsck "ext2"
+append libmount_known_fsck "ext3"
+append libmount_known_fsck "ext4"
diff --git a/package/utils/e2fsprogs/patches/001-com_err_version.patch b/package/utils/e2fsprogs/patches/001-com_err_version.patch
new file mode 100644
index 0000000..62f1e08
--- /dev/null
+++ b/package/utils/e2fsprogs/patches/001-com_err_version.patch
@@ -0,0 +1,13 @@
+--- a/lib/et/Makefile.in
++++ b/lib/et/Makefile.in
+@@ -25,8 +25,8 @@ SHARE_FILES= et_c.awk et_h.awk
+ LIBRARY= libcom_err
+ LIBDIR= et
+
+-ELF_VERSION = 2.1
+-ELF_SO_VERSION = 2
++ELF_VERSION = 0.0
++ELF_SO_VERSION = 0
+ ELF_IMAGE = libcom_err
+ ELF_MYDIR = et
+ ELF_INSTALL_DIR = $(root_libdir)
diff --git a/package/utils/fbtest/Makefile b/package/utils/fbtest/Makefile
new file mode 100644
index 0000000..05e67cb
--- /dev/null
+++ b/package/utils/fbtest/Makefile
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=fbtest
+PKG_RELEASE:=1
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/fbtest
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Frame buffer device testing tool
+ DEPENDS:=@DISPLAY_SUPPORT
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -Wall" \
+ LDFLAGS="$(TARGET_LDFLAGS)"
+endef
+
+define Package/fbtest/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/fbtest $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,fbtest))
diff --git a/package/utils/fbtest/src/Makefile b/package/utils/fbtest/src/Makefile
new file mode 100644
index 0000000..075bc0e
--- /dev/null
+++ b/package/utils/fbtest/src/Makefile
@@ -0,0 +1,14 @@
+CC = gcc
+CFLAGS = -Wall
+OBJS = fbtest.o
+
+all: fbtest
+
+%.o: %.c
+ $(CC) $(CFLAGS) -c -o $@ $<
+
+fbtest: $(OBJS)
+ $(CC) -o $@ $(OBJS)
+
+clean:
+ rm -f rbcfg *.o
diff --git a/package/utils/fbtest/src/fbtest.c b/package/utils/fbtest/src/fbtest.c
new file mode 100644
index 0000000..021b803
--- /dev/null
+++ b/package/utils/fbtest/src/fbtest.c
@@ -0,0 +1,446 @@
+/******************************************************************************
+ * fbtest - fbtest.c
+ * test program for the tuxbox-framebuffer device
+ * tests all GTX/eNX supported modes
+ *
+ * (c) 2003 Carsten Juttner (carjay@gmx.net)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * The Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ ******************************************************************************
+ * $Id: fbtest.c,v 1.5 2005/01/14 23:14:41 carjay Exp $
+ ******************************************************************************/
+
+// TODO: - should restore the colour map and mode to what it was before
+// - is colour map handled correctly?
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <fcntl.h>
+
+#include <linux/fb.h>
+
+#define FBDEV "/dev/fb0"
+
+struct vidsize{
+ int width;
+ int height;
+};
+static
+const struct vidsize vidsizetable[]={ // all supported sizes
+ {720,576},{720,480},{720,288},{720,240},
+ {640,576},{640,480},{640,288},{640,240},
+ {360,576},{360,480},{360,288},{360,240},
+ {320,576},{320,480},{320,288},{320,240}
+};
+#define VIDSIZENUM (sizeof(vidsizetable)/sizeof(struct vidsize))
+
+enum pixenum{ // keep in sync with pixname !
+ CLUT4=0,
+ CLUT8,
+ RGB565,
+ ARGB1555,
+ ARGB
+};
+const char *pixname[] = {
+ "CLUT4",
+ "CLUT8",
+ "RGB565",
+ "ARGB1555",
+ "ARGB"
+};
+
+struct pixelformat{
+ char *name;
+ struct fb_bitfield red;
+ struct fb_bitfield green;
+ struct fb_bitfield blue;
+ struct fb_bitfield transp;
+ char bpp;
+ char pixenum;
+};
+
+static // so far these are all modes supported by the eNX (only partially by GTX)
+const struct pixelformat pixelformattable[] = {
+ { .name = "CLUT4 ARGB8888", // CLUT4 (ARGB8888)
+ .bpp = 4, .pixenum = CLUT4,
+ .red = { .offset = 0, .length=8, .msb_right =0 },
+ .green = { .offset = 0, .length=8, .msb_right =0 },
+ .blue = { .offset = 0, .length=8, .msb_right =0 },
+ .transp= { .offset = 0, .length=8, .msb_right =0 }
+ },
+ { .name = "CLUT4 ARGB1555", // CLUT4 (ARGB1555)
+ .bpp = 4, .pixenum = CLUT4,
+ .red = { .offset = 0, .length=5, .msb_right =0 },
+ .green = { .offset = 0, .length=5, .msb_right =0 },
+ .blue = { .offset = 0, .length=5, .msb_right =0 },
+ .transp= { .offset = 0, .length=1, .msb_right =0 }
+ },
+ { .name = "CLUT8 ARGB8888", // CLUT8 (ARGB8888)
+ .bpp = 8, .pixenum = CLUT8,
+ .red = { .offset = 0, .length=8, .msb_right =0 },
+ .green = { .offset = 0, .length=8, .msb_right =0 },
+ .blue = { .offset = 0, .length=8, .msb_right =0 },
+ .transp= { .offset = 0, .length=8, .msb_right =0 }
+ },
+ { .name = "CLUT8 ARGB1555", // CLUT8 (ARGB1555)
+ .bpp = 8, .pixenum = CLUT8,
+ .red = { .offset = 0, .length=5, .msb_right =0 },
+ .green = { .offset = 0, .length=5, .msb_right =0 },
+ .blue = { .offset = 0, .length=5, .msb_right =0 },
+ .transp= { .offset = 0, .length=1, .msb_right =0 }
+ },
+ { .name = "ARGB1555", // ARGB1555
+ .bpp = 16, .pixenum = ARGB1555,
+ .red = { .offset = 10, .length=5, .msb_right =0 },
+ .green = { .offset = 5, .length=5, .msb_right =0 },
+ .blue = { .offset = 0, .length=5, .msb_right =0 },
+ .transp= { .offset = 15, .length=1, .msb_right =0 }
+ },
+ { .name = "RGB565", // RGB565
+ .bpp = 16, .pixenum = RGB565,
+ .red = { .offset = 11, .length=5, .msb_right =0 },
+ .green = { .offset = 5, .length=6, .msb_right =0 },
+ .blue = { .offset = 0, .length=5, .msb_right =0 },
+ .transp= { .offset = 0, .length=0, .msb_right =0 }
+ },
+ { .name = "ARGB", // 32 f*cking bits, the real McCoy :)
+ .bpp = 32, .pixenum = ARGB,
+ .red = { .offset = 16, .length=8, .msb_right =0 },
+ .green = { .offset = 8, .length=8, .msb_right =0 },
+ .blue = { .offset = 0, .length=8, .msb_right =0 },
+ .transp= { .offset = 24, .length=8, .msb_right =0 }
+ }
+};
+#define PIXELFORMATNUM (sizeof(pixelformattable)/sizeof(struct pixelformat))
+
+struct colour {
+ __u16 r;
+ __u16 g;
+ __u16 b;
+ __u16 a;
+};
+static
+struct colour colourtable[] = {
+ {.r =0xffff, .g = 0xffff, .b=0xffff, .a=0xffff}, // fully transparent white
+ {.r =0xffff, .g = 0x0000, .b=0x0000, .a=0x0000}, // red
+ {.r =0x0000, .g = 0xffff, .b=0x0000, .a=0x0000}, // green
+ {.r =0x0000, .g = 0x0000, .b=0xffff, .a=0x0000}, // blue
+ {.r =0x0000, .g = 0x0000, .b=0x0000, .a=0x0000} // black
+};
+#define COLOURNUM (sizeof(colourtable)/sizeof(struct colour))
+
+struct rect{
+ int x;
+ int y;
+ int width;
+ int height;
+ const struct colour *col;
+};
+struct pixel{ // up to 32 bits of pixel information
+ char byte[4];
+};
+
+void col2pixel (struct pixel *pix, const struct pixelformat *pixf, const struct colour *col){
+ switch (pixf->pixenum){
+ case RGB565:
+ pix->byte[0]=(col->r&0xf8)|(col->g&0xfc)>>5;
+ pix->byte[1]=(col->g&0xfc)<<3|(col->b&0xf8)>>3;
+ break;
+ case ARGB1555:
+ pix->byte[0]=(col->a&0x80)|(col->r&0xf8)>>1|(col->g&0xf8)>>6;
+ pix->byte[1]=(col->g&0xf8)<<2|(col->b&0xf8)>>3;
+ break;
+ case ARGB:
+ pix->byte[0]=col->a;
+ pix->byte[1]=col->r;
+ pix->byte[2]=col->g;
+ pix->byte[3]=col->b;
+ break;
+ default:
+ printf ("unknown pixelformat\n");
+ exit(1);
+ }
+}
+
+int setmode(int fbd, const struct pixelformat *pixf,const struct vidsize *vids){
+ struct fb_var_screeninfo var;
+ int stat;
+ stat = ioctl (fbd, FBIOGET_VSCREENINFO,&var);
+ if (stat<0) return -2;
+
+ var.xres= vids->width;
+ var.xres_virtual = vids->width;
+ var.yres= vids->height;
+ var.yres_virtual = vids->height;
+
+ var.bits_per_pixel = pixf->bpp;
+ var.red = pixf->red;
+ var.green = pixf->green;
+ var.blue = pixf->blue;
+ var.transp = pixf->transp;
+
+ stat = ioctl (fbd, FBIOPUT_VSCREENINFO,&var);
+ if (stat<0) return -1;
+ return 0;
+}
+
+// unefficient implementation, do NOT use it for your next ego shooter, please :)
+// for 4-Bit only rectangles with even width are supported
+// CLUT-modes use value of red component as index
+void drawrect(void *videoram, struct rect *r, const struct pixelformat *pixf, const struct vidsize *vids){
+ int x,y,corwidth, bpp = 0, tocopy = 1;
+ struct pixel pix;
+ unsigned char *pmem = videoram;
+ corwidth = r->width; // actually only "corrected" for 4 Bit
+
+ if (pixf->pixenum!=CLUT4&&pixf->pixenum!=CLUT8){
+ switch (pixf->pixenum){
+ case ARGB1555:
+ case RGB565:
+ bpp = 16;
+ tocopy = 2;
+ break;
+ case ARGB:
+ bpp = 32;
+ tocopy = 4;
+ break;
+ default:
+ printf ("drawrect: unknown pixelformat(%d) bpp:%d\n",pixf->pixenum,pixf->bpp);
+ exit(1);
+ }
+ col2pixel(&pix,pixf,r->col);
+ } else {
+ switch (pixf->pixenum){ // CLUT = Colour LookUp Table (palette)
+ case CLUT4: // take red value as index in this case
+ pix.byte[0]=(r->col->r)<<4|(r->col->r&0xf); // slightly cryptic... "rect->colour->red"
+ corwidth>>=1; // we copy bytes
+ bpp=4;
+ tocopy=1;
+ break;
+ case CLUT8:
+ pix.byte[0]=(r->col->r&0xff);
+ bpp=8;
+ tocopy=1;
+ break;
+ }
+ }
+ pmem=videoram+((((r->y*vids->width)+r->x)*bpp)>>3);
+ for (y=0;y<r->height;y++){
+ int offset = 0;
+ for (x=0;x<corwidth;x++){
+ memcpy (pmem+offset,pix.byte,tocopy);
+ offset+=tocopy;
+ }
+ pmem +=((vids->width*bpp)>>3); // skip one whole line, actually should be taken from "fix-info"
+ }
+}
+
+// create quick little test image, 4 colours from table
+void draw4field(void *videoram, const struct pixelformat *pixf, const struct vidsize *vids){
+ struct rect r;
+ struct colour c;
+ int height, width;
+ c.r = 1; // only used for the indexed modes, r is taken as index
+ height = vids->height;
+ width = vids->width;
+
+ r.height = height>>1;
+ r.width = width>>1;
+ r.x = 0; r.y = 0;
+ if (pixf->pixenum==CLUT4||pixf->pixenum==CLUT8) r.col = &c;
+ else r.col = &colourtable[1];
+ drawrect (videoram, &r, pixf, vids);
+
+ r.x = width/2; r.y = 0;
+ if (pixf->pixenum==CLUT4||pixf->pixenum==CLUT8) c.r = 2;
+ else r.col = &colourtable[2];
+ drawrect (videoram, &r, pixf, vids);
+
+ r.x = 0; r.y = height/2;
+ if (pixf->pixenum==CLUT4||pixf->pixenum==CLUT8) c.r = 3;
+ else r.col = &colourtable[3];
+ drawrect (videoram, &r, pixf, vids);
+
+ r.x = width/2; r.y = height/2;
+ if (pixf->pixenum==CLUT4||pixf->pixenum==CLUT8) c.r = 0;
+ else r.col = &colourtable[0];
+ drawrect (videoram, &r, pixf, vids);
+}
+
+void usage(char *name){
+ printf ("Usage: %s [options]\n"
+ "Options: -f<pixelformat>\n"
+ " where format is one of:\n"
+ " CLUT4,CLUT8,ARGB1555,RGB565,ARGB\n"
+ " -s<width>x<heigth>\n"
+ " where width is either 720,640,360,320\n"
+ " and height is either 288,240,480,576\n"
+ " -n\n"
+ " disables clearing the framebuffer after drawing\n"
+ " the testimage. This can be useful to keep the last\n"
+ " drawn image onscreen.\n"
+ "\nExample: %s -fRGB322\n",name,name);
+ exit(0);
+}
+
+int main (int argc,char **argv){
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+ struct fb_cmap cmap;
+ struct rect r;
+ int fbd;
+ unsigned char *pfb;
+ int stat;
+ int optchar,fmode=-1,smode=-1,clear=1;
+ int i_cmap,i_size,i_pix;
+ extern char *optarg;
+
+ if (argc!=0&&argc>4) usage(argv[0]);
+ while ( (optchar = getopt (argc,argv,"f:s:n"))!= -1){
+ int i,height,width;
+ switch (optchar){
+ case 'f':
+ for (i=0;i<(sizeof(pixname)/sizeof(char*));i++){
+ if (!strncmp (optarg,pixname[i],strlen(pixname[i]))){
+ fmode=i;
+ printf ("displaying only %s-modes\n",pixname[i]);
+ break;
+ }
+ }
+ if (fmode==-1){
+ printf ("unknown pixelformat\n");
+ exit(0);
+ }
+ break;
+ case 's':
+ if (sscanf (optarg,"%dx%d",&width,&height)!=2){
+ printf ("parsing size failed\n");
+ exit(0);
+ } else {
+ printf ("requested size %dx%d\n",width,height);
+ for (i=0;i<VIDSIZENUM;i++){
+ if (vidsizetable[i].width == width &&
+ vidsizetable[i].height == height){
+ smode = i;
+ break;
+ }
+ }
+ if (smode==-1){
+ printf ("this size is not supported\n");
+ exit(0);
+ }
+ }
+ break;
+ case 'n':
+ clear = 0;
+ printf ("clearing framebuffer after drawing is disabled\n");
+ break;
+ case '?':
+ usage (argv[0]);
+ }
+ }
+
+ fbd = open (FBDEV, O_RDWR);
+ if (fbd<0){
+ perror ("Error opening framebuffer device");
+ return 1;
+ }
+ stat = ioctl (fbd, FBIOGET_FSCREENINFO,&fix);
+ if (stat<0){
+ perror ("Error getting fix screeninfo");
+ return 1;
+ }
+ stat = ioctl (fbd, FBIOGET_VSCREENINFO,&var);
+ if (stat<0){
+ perror ("Error getting var screeninfo");
+ return 1;
+ }
+ stat = ioctl (fbd, FBIOPUT_VSCREENINFO,&var);
+ if (stat<0){
+ perror ("Error setting mode");
+ return 1;
+ }
+ pfb = mmap (0, fix.smem_len, PROT_READ|PROT_WRITE, MAP_SHARED, fbd, 0);
+ if (pfb == MAP_FAILED){
+ perror ("Error mmap'ing framebuffer device");
+ return 1;
+ }
+
+ // iterate over all modes
+ for (i_pix=0;i_pix<PIXELFORMATNUM;i_pix++){
+ if (fmode!=-1 && pixelformattable[i_pix].pixenum != fmode) continue;
+ printf ("testing: %s",pixelformattable[i_pix].name);
+ printf (" for sizes: \n");
+ for (i_size=0;i_size<VIDSIZENUM;i_size++){
+ if (smode!=-1 && i_size!=smode) continue;
+ printf ("%dx%d ",vidsizetable[i_size].width,vidsizetable[i_size].height);
+ fflush(stdout);
+ if ((i_size%4)==3) printf ("\n");
+
+ // try to set mode
+ stat = setmode(fbd,&pixelformattable[i_pix],&vidsizetable[i_size]);
+ if (stat==-2) perror ("fbtest: could not get fb_var-screeninfo from fb-device");
+ else if (stat==-1){
+ printf ("\nCould not set mode %s (%dx%d), possible reasons:\n"
+ "- you have a GTX (soz m8)\n"
+ "- your configuration does not have enough graphics RAM\n"
+ "- you found a bug\n"
+ "choose your poison accordingly...\n",
+ pixelformattable[i_pix].name,vidsizetable[i_size].width,vidsizetable[i_size].height);
+ continue;
+ }
+ // fill cmap;
+ cmap.len = 1;
+ if ((pixelformattable[i_pix].bpp==4)||
+ ((pixelformattable[i_pix].bpp==8)&&(pixelformattable[i_pix].red.length!=3))){
+ for (i_cmap=0;i_cmap<COLOURNUM;i_cmap++){
+ cmap.start=i_cmap;
+ cmap.red=&colourtable[i_cmap].r;
+ cmap.green=&colourtable[i_cmap].g;
+ cmap.blue=&colourtable[i_cmap].b;
+ cmap.transp=&colourtable[i_cmap].a;
+ stat = ioctl (fbd, FBIOPUTCMAP, &cmap);
+ if (stat<0) printf ("setting colourmap failed\n");
+ }
+ }
+ // create the test image
+ draw4field(pfb,&pixelformattable[i_pix],&vidsizetable[i_size]);
+ usleep (500000);
+ // clear screen
+ if (clear){
+ r.x=r.y=0;r.width = vidsizetable[i_size].width; r.height = vidsizetable[i_size].height;
+ r.col = &colourtable[4];
+ drawrect(pfb,&r,&pixelformattable[i_pix],&vidsizetable[i_size]);
+ }
+ }
+ printf ("\n");
+ }
+
+ stat = munmap (pfb,fix.smem_len);
+ if (stat<0){
+ perror ("Error munmap'ing framebuffer device");
+ return 1;
+ }
+ close (fbd);
+ return 0;
+}
diff --git a/package/utils/fuse/Makefile b/package/utils/fuse/Makefile
new file mode 100644
index 0000000..9adb6d3
--- /dev/null
+++ b/package/utils/fuse/Makefile
@@ -0,0 +1,101 @@
+#
+# Copyright (C) 2006-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=fuse
+PKG_VERSION:=2.9.3
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=@SF/$(PKG_NAME)
+PKG_MD5SUM:=33cae22ca50311446400daf8a6255c6a
+
+PKG_LICENSE:=LGPLv2.1 GPLv2
+PKG_LICENSE_FILES:=COPYING.LIB COPYING
+
+PKG_INSTALL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/fuse/Default
+ TITLE:=FUSE
+ URL:=http://fuse.sourceforge.net/
+endef
+
+define Package/fuse/Default/description
+ FUSE (Filesystem in UserSpacE)
+endef
+
+define Package/fuse-utils
+$(call Package/fuse/Default)
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=+libfuse
+ TITLE+= (utilities)
+ SUBMENU:=Filesystem
+endef
+
+define Package/fuse-utils/description
+$(call Package/fuse/Default/description)
+ This package contains the FUSE utilities.
+ - fusermount
+ - ulockmgr_server
+endef
+
+define Package/libfuse
+$(call Package/fuse/Default)
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE+= (library)
+ DEPENDS:=+kmod-fuse +libpthread
+ SUBMENU:=Filesystem
+endef
+
+define Package/libfuse/description
+$(call Package/fuse/Default/description)
+ This package contains the FUSE shared libraries, needed by other programs.
+ - libfuse
+ - libulockmgr
+endef
+
+# generic args
+CONFIGURE_ARGS += \
+ --enable-shared \
+ --enable-static \
+ --enable-lib \
+ --enable-util \
+ --disable-rpath \
+ --disable-example \
+ --disable-mtab
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/{fuse,fuse.h,ulockmgr.h} $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{fuse,ulockmgr}.{a,so*} $(1)/usr/lib/
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/fuse.pc $(1)/usr/lib/pkgconfig/
+ $(SED) 's,-I$$$${includedir}/fuse,,g' $(1)/usr/lib/pkgconfig/fuse.pc
+ $(SED) 's,-L$$$${libdir},,g' $(1)/usr/lib/pkgconfig/fuse.pc
+endef
+
+define Package/fuse-utils/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(CP) $(PKG_INSTALL_DIR)/sbin/mount.fuse $(1)/sbin/
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(CP) $(PKG_INSTALL_DIR)/usr/bin/{fusermount,ulockmgr_server} $(1)/usr/bin/
+endef
+
+define Package/libfuse/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/lib{fuse,ulockmgr}.so.* $(1)/usr/lib/
+endef
+
+$(eval $(call BuildPackage,fuse-utils))
+$(eval $(call BuildPackage,libfuse))
diff --git a/package/utils/fuse/patches/001-fix_exec_environment_for_mount_and_umount.patch b/package/utils/fuse/patches/001-fix_exec_environment_for_mount_and_umount.patch
new file mode 100644
index 0000000..392bb5e
--- /dev/null
+++ b/package/utils/fuse/patches/001-fix_exec_environment_for_mount_and_umount.patch
@@ -0,0 +1,59 @@
+From cfe13b7a217075ae741c018da50cd600e5330de2 Mon Sep 17 00:00:00 2001
+From: Miklos Szeredi <mszeredi@suse.cz>
+Date: Fri, 22 May 2015 10:58:43 +0200
+Subject: [PATCH] libfuse: fix exec environment for mount and umount
+
+Found by Tavis Ormandy (CVE-2015-3202).
+---
+--- a/lib/mount_util.c
++++ b/lib/mount_util.c
+@@ -95,10 +95,12 @@ static int add_mount(const char *prognam
+ goto out_restore;
+ }
+ if (res == 0) {
++ char *env = NULL;
++
+ sigprocmask(SIG_SETMASK, &oldmask, NULL);
+ setuid(geteuid());
+- execl("/bin/mount", "/bin/mount", "--no-canonicalize", "-i",
+- "-f", "-t", type, "-o", opts, fsname, mnt, NULL);
++ execle("/bin/mount", "/bin/mount", "--no-canonicalize", "-i",
++ "-f", "-t", type, "-o", opts, fsname, mnt, NULL, &env);
+ fprintf(stderr, "%s: failed to execute /bin/mount: %s\n",
+ progname, strerror(errno));
+ exit(1);
+@@ -146,10 +148,17 @@ static int exec_umount(const char *progn
+ goto out_restore;
+ }
+ if (res == 0) {
++ char *env = NULL;
++
+ sigprocmask(SIG_SETMASK, &oldmask, NULL);
+ setuid(geteuid());
+- execl("/bin/umount", "/bin/umount", "-i", rel_mnt,
+- lazy ? "-l" : NULL, NULL);
++ if (lazy) {
++ execle("/bin/umount", "/bin/umount", "-i", rel_mnt,
++ "-l", NULL, &env);
++ } else {
++ execle("/bin/umount", "/bin/umount", "-i", rel_mnt,
++ NULL, &env);
++ }
+ fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
+ progname, strerror(errno));
+ exit(1);
+@@ -205,10 +214,12 @@ static int remove_mount(const char *prog
+ goto out_restore;
+ }
+ if (res == 0) {
++ char *env = NULL;
++
+ sigprocmask(SIG_SETMASK, &oldmask, NULL);
+ setuid(geteuid());
+- execl("/bin/umount", "/bin/umount", "--no-canonicalize", "-i",
+- "--fake", mnt, NULL);
++ execle("/bin/umount", "/bin/umount", "--no-canonicalize", "-i",
++ "--fake", mnt, NULL, &env);
+ fprintf(stderr, "%s: failed to execute /bin/umount: %s\n",
+ progname, strerror(errno));
+ exit(1);
diff --git a/package/utils/fuse/patches/100-missing_includes.patch b/package/utils/fuse/patches/100-missing_includes.patch
new file mode 100644
index 0000000..0790bff
--- /dev/null
+++ b/package/utils/fuse/patches/100-missing_includes.patch
@@ -0,0 +1,20 @@
+--- a/lib/mount_util.c
++++ b/lib/mount_util.c
+@@ -16,6 +16,7 @@
+ #include <errno.h>
+ #include <fcntl.h>
+ #include <limits.h>
++#include <paths.h>
+ #ifndef __NetBSD__
+ #include <mntent.h>
+ #endif
+--- a/include/fuse.h
++++ b/include/fuse.h
+@@ -32,6 +32,7 @@
+ #include <sys/stat.h>
+ #include <sys/statvfs.h>
+ #include <sys/uio.h>
++#include <sys/file.h>
+
+ #ifdef __cplusplus
+ extern "C" {
diff --git a/package/utils/fuse/patches/112-no_break_on_mknod.patch b/package/utils/fuse/patches/112-no_break_on_mknod.patch
new file mode 100644
index 0000000..33f7c6c
--- /dev/null
+++ b/package/utils/fuse/patches/112-no_break_on_mknod.patch
@@ -0,0 +1,11 @@
+--- a/util/Makefile.in
++++ b/util/Makefile.in
+@@ -676,7 +676,7 @@ mount_util.c: $(top_srcdir)/lib/mount_ut
+
+ install-exec-hook:
+ -chmod u+s $(DESTDIR)$(bindir)/fusermount
+- @if test ! -e $(DESTDIR)/dev/fuse; then \
++ -@if test ! -e $(DESTDIR)/dev/fuse; then \
+ $(MKDIR_P) $(DESTDIR)/dev; \
+ echo "mknod $(DESTDIR)/dev/fuse -m 0666 c 10 229 || true"; \
+ mknod $(DESTDIR)/dev/fuse -m 0666 c 10 229 || true; \
diff --git a/package/utils/fuse/patches/200-backport_arm64_fuse_kernel_h_clean_includes.patch b/package/utils/fuse/patches/200-backport_arm64_fuse_kernel_h_clean_includes.patch
new file mode 100644
index 0000000..d45da84
--- /dev/null
+++ b/package/utils/fuse/patches/200-backport_arm64_fuse_kernel_h_clean_includes.patch
@@ -0,0 +1,30 @@
+From 914871b20a901e3e1e981c92bc42b1c93b7ab81b Mon Sep 17 00:00:00 2001
+From: Riku Voipio <riku.voipio@linaro.org>
+Date: Thu, 07 Feb 2013 11:04:21 +0000
+Subject: fuse_kernel.h: clean includes
+
+Use <linux/types.h> for linux and define types used for other operating systems
+using <stdint.h> types.
+---
+(limited to 'include/fuse_kernel.h')
+
+--- a/include/fuse_kernel.h
++++ b/include/fuse_kernel.h
+@@ -88,12 +88,16 @@
+ #ifndef _LINUX_FUSE_H
+ #define _LINUX_FUSE_H
+
+-#include <sys/types.h>
++#ifdef __linux__
++#include <linux/types.h>
++#else
++#include <stdint.h>
+ #define __u64 uint64_t
+ #define __s64 int64_t
+ #define __u32 uint32_t
+ #define __s32 int32_t
+ #define __u16 uint16_t
++#endif
+
+ /*
+ * Version negotiation:
diff --git a/package/utils/hostap-utils/Makefile b/package/utils/hostap-utils/Makefile
new file mode 100644
index 0000000..1d7b221
--- /dev/null
+++ b/package/utils/hostap-utils/Makefile
@@ -0,0 +1,44 @@
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=hostap-utils
+PKG_VERSION:=0.4.7
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://hostap.epitest.fi/releases/
+PKG_MD5SUM:=afe041581b8f01666e353bec20917c85
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/hostap-utils
+ SECTION:=net
+ CATEGORY:=Network
+ DEPENDS:=kmod-hostap
+ TITLE:=Host AP driver utility programs
+ URL:=http://hostap.epitest.fi/
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ $(TARGET_CONFIGURE_OPTS) \
+ CFLAGS="$(TARGET_CFLAGS) $(TARGET_CPPFLAGS) -Wall" \
+ all
+endef
+
+define Package/hostap-utils/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostap_crypt_conf $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostap_diag $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostap_io_debug $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/hostap_rid $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/prism2_srec $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/split_combined_hex $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,hostap-utils))
diff --git a/package/utils/jsonfilter/Makefile b/package/utils/jsonfilter/Makefile
new file mode 100644
index 0000000..34020df
--- /dev/null
+++ b/package/utils/jsonfilter/Makefile
@@ -0,0 +1,33 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=jsonfilter
+PKG_VERSION:=2014-06-19
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=http://git.openwrt.org/project/jsonpath.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=cdc760c58077f44fc40adbbe41e1556a67c1b9a9
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+CMAKE_INSTALL:=1
+
+PKG_MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+PKG_LICENSE:=ISC
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/jsonfilter
+ SECTION:=base
+ CATEGORY:=Base system
+ DEPENDS:=+libubox +libjson-c
+ TITLE:=OpenWrt JSON filter utility
+ URL:=http://git.openwrt.org/?p=project/jsonpath.git
+endef
+
+define Package/jsonfilter/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/jsonpath $(1)/usr/bin/jsonfilter
+endef
+
+$(eval $(call BuildPackage,jsonfilter))
diff --git a/package/utils/lua/Makefile b/package/utils/lua/Makefile
new file mode 100644
index 0000000..e81833d
--- /dev/null
+++ b/package/utils/lua/Makefile
@@ -0,0 +1,183 @@
+#
+# Copyright (C) 2006-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=lua
+PKG_VERSION:=5.1.5
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=http://www.lua.org/ftp/ \
+ http://ftp.gwdg.de/pub/languages/lua/ \
+ http://mirrors.dotsrc.org/lua/ \
+ http://www.tecgraf.puc-rio.br/lua/ftp/
+PKG_MD5SUM:=2e115fe26e435e33b0d5c022e4490567
+PKG_BUILD_PARALLEL:=1
+
+PKG_LICENSE:=MIT
+PKG_LICENSE_FILES:=COPYRIGHT
+
+HOST_PATCH_DIR := ./patches-host
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/host-build.mk
+
+define Package/lua/Default
+ SUBMENU:=Lua
+ SECTION:=lang
+ CATEGORY:=Languages
+ TITLE:=Lua programming language
+ URL:=http://www.lua.org/
+ MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+endef
+
+define Package/lua/Default/description
+ Lua is a powerful light-weight programming language designed for extending
+ applications. Lua is also frequently used as a general-purpose, stand-alone
+ language. Lua is free software.
+endef
+
+define Package/liblua
+$(call Package/lua/Default)
+ SUBMENU:=
+ SECTION:=libs
+ CATEGORY:=Libraries
+ TITLE+= (libraries)
+endef
+
+define Package/liblua/description
+$(call Package/lua/Default/description)
+ This package contains the Lua shared libraries, needed by other programs.
+endef
+
+define Package/lua
+$(call Package/lua/Default)
+ DEPENDS:=+liblua
+ TITLE+= (interpreter)
+endef
+
+define Package/lua/description
+$(call Package/lua/Default/description)
+ This package contains the Lua language interpreter.
+endef
+
+define Package/luac
+$(call Package/lua/Default)
+ DEPENDS:=+liblua
+ TITLE+= (compiler)
+endef
+
+define Package/luac/description
+$(call Package/lua/Default/description)
+ This package contains the Lua language compiler.
+endef
+
+define Package/lua-examples
+$(call Package/lua/Default)
+ DEPENDS:=lua
+ TITLE+= (examples)
+endef
+
+define Package/lua-examples/description
+$(call Package/lua/Default/description)
+ This package contains Lua language examples.
+endef
+
+define Build/Configure
+endef
+
+TARGET_CFLAGS += -DLUA_USE_LINUX $(FPIC) -std=gnu99
+
+ifneq ($(CONFIG_USE_GLIBC),)
+ ifeq ($(CONFIG_EGLIBC_OPTION_EGLIBC_UTMP),)
+ TARGET_CFLAGS += -DNO_GETLOGIN
+ endif
+endif
+
+define Build/Compile
+ $(MAKE) $(PKG_JOBS) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CROSS)gcc" \
+ AR="$(TARGET_CROSS)ar rcu" \
+ RANLIB="$(TARGET_CROSS)ranlib" \
+ INSTALL_ROOT=/usr \
+ CFLAGS="$(TARGET_CPPFLAGS) $(TARGET_CFLAGS)" \
+ MYLDFLAGS="$(TARGET_LDFLAGS)" \
+ PKG_VERSION=$(PKG_VERSION) \
+ linux
+ rm -rf $(PKG_INSTALL_DIR)
+ mkdir -p $(PKG_INSTALL_DIR)
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ INSTALL_TOP="$(PKG_INSTALL_DIR)/usr" \
+ install
+endef
+
+define Host/Configure
+ $(SED) 's,"/usr/local/","$(STAGING_DIR_HOST)/",' $(HOST_BUILD_DIR)/src/luaconf.h
+endef
+
+ifeq ($(HOST_OS),Darwin)
+ LUA_OS:=macosx
+else
+ ifeq ($(HOST_OS),FreeBSD)
+ LUA_OS:=freebsd
+ else
+ LUA_OS:=linux
+ endif
+endif
+
+define Host/Compile
+ $(MAKE) -C $(HOST_BUILD_DIR) \
+ CC="$(HOSTCC) -std=gnu99" \
+ $(LUA_OS)
+endef
+
+define Host/Install
+ $(MAKE) -C $(HOST_BUILD_DIR) \
+ INSTALL_TOP="$(STAGING_DIR_HOST)" \
+ install
+endef
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(1)/usr/include
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/lua{,lib,conf}.h $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/lauxlib.h $(1)/usr/include/
+ $(CP) $(PKG_INSTALL_DIR)/usr/include/lnum_config.h $(1)/usr/include/
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/liblua.{a,so*} $(1)/usr/lib/
+ $(LN) liblua.so.$(PKG_VERSION) $(1)/usr/lib/liblualib.so
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_BUILD_DIR)/etc/lua.pc $(1)/usr/lib/pkgconfig/
+endef
+
+define Package/liblua/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_INSTALL_DIR)/usr/lib/liblua.so.* $(1)/usr/lib/
+endef
+
+define Package/lua/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/lua $(1)/usr/bin/
+endef
+
+define Package/luac/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/luac $(1)/usr/bin/
+endef
+
+define Package/lua-examples/install
+ $(INSTALL_DIR) $(1)/usr/share/lua/examples
+ $(INSTALL_DATA) $(PKG_BUILD_DIR)/test/*.lua \
+ $(1)/usr/share/lua/examples/
+endef
+
+$(eval $(call BuildPackage,liblua))
+$(eval $(call BuildPackage,lua))
+$(eval $(call BuildPackage,luac))
+$(eval $(call BuildPackage,lua-examples))
+$(eval $(call HostBuild))
+
diff --git a/package/utils/lua/patches-host/010-lua-5.1.3-lnum-full-260308.patch b/package/utils/lua/patches-host/010-lua-5.1.3-lnum-full-260308.patch
new file mode 100644
index 0000000..74b8c6f
--- /dev/null
+++ b/package/utils/lua/patches-host/010-lua-5.1.3-lnum-full-260308.patch
@@ -0,0 +1,3736 @@
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -25,7 +25,7 @@ PLATS= aix ansi bsd freebsd generic linu
+ LUA_A= liblua.a
+ CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
+ lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
+- lundump.o lvm.o lzio.o
++ lundump.o lvm.o lzio.o lnum.o
+ LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
+ lstrlib.o loadlib.o linit.o
+
+@@ -148,6 +148,7 @@ llex.o: llex.c lua.h luaconf.h ldo.h lob
+ lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
+ lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
+ ltm.h lzio.h lmem.h ldo.h
++lnum.o: lnum.c lua.h llex.h lnum.h
+ loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h
+ lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \
+ ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h
+@@ -179,4 +180,18 @@ lzio.o: lzio.c lua.h luaconf.h llimits.h
+ print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \
+ ltm.h lzio.h lmem.h lopcodes.h lundump.h
+
++luaconf.h: lnum_config.h
++lapi.c: lnum.h
++lauxlib.c: llimits.h
++lbaselib.c: llimits.h lobject.h lapi.h
++lcode.c: lnum.h
++liolib.c: lnum.h llex.h
++llex.c: lnum.h
++lnum.h: lobject.h
++lobject.c: llex.h lnum.h
++ltable.c: lnum.h
++lua.c: llimits.h
++lvm.c: llex.h lnum.h
++print.c: lnum.h
++
+ # (end of Makefile)
+--- a/src/lapi.c
++++ b/src/lapi.c
+@@ -28,7 +28,7 @@
+ #include "ltm.h"
+ #include "lundump.h"
+ #include "lvm.h"
+-
++#include "lnum.h"
+
+
+ const char lua_ident[] =
+@@ -241,12 +241,13 @@ LUA_API void lua_pushvalue (lua_State *L
+
+ LUA_API int lua_type (lua_State *L, int idx) {
+ StkId o = index2adr(L, idx);
+- return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
++ return (o == luaO_nilobject) ? LUA_TNONE : ttype_ext(o);
+ }
+
+
+ LUA_API const char *lua_typename (lua_State *L, int t) {
+ UNUSED(L);
++ lua_assert( t!= LUA_TINT );
+ return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
+ }
+
+@@ -264,6 +265,14 @@ LUA_API int lua_isnumber (lua_State *L,
+ }
+
+
++LUA_API int lua_isinteger (lua_State *L, int idx) {
++ TValue tmp;
++ lua_Integer dum;
++ const TValue *o = index2adr(L, idx);
++ return tonumber(o,&tmp) && (ttisint(o) || tt_integer_valued(o,&dum));
++}
++
++
+ LUA_API int lua_isstring (lua_State *L, int idx) {
+ int t = lua_type(L, idx);
+ return (t == LUA_TSTRING || t == LUA_TNUMBER);
+@@ -309,31 +318,66 @@ LUA_API int lua_lessthan (lua_State *L,
+ }
+
+
+-
+ LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
+ TValue n;
+ const TValue *o = index2adr(L, idx);
+- if (tonumber(o, &n))
++ if (tonumber(o, &n)) {
++#ifdef LNUM_COMPLEX
++ if (nvalue_img(o) != 0)
++ luaG_runerror(L, "expecting a real number");
++#endif
+ return nvalue(o);
+- else
+- return 0;
++ }
++ return 0;
+ }
+
+
+ LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
+ TValue n;
++ /* Lua 5.1 documented behaviour is to return nonzero for non-integer:
++ * "If the number is not an integer, it is truncated in some non-specified way."
++ * I would suggest to change this, to return 0 for anything that would
++ * not fit in 'lua_Integer'.
++ */
++#ifdef LUA_COMPAT_TOINTEGER
++ /* Lua 5.1 compatible */
+ const TValue *o = index2adr(L, idx);
+ if (tonumber(o, &n)) {
+- lua_Integer res;
+- lua_Number num = nvalue(o);
+- lua_number2integer(res, num);
+- return res;
++ lua_Integer i;
++ lua_Number d;
++ if (ttisint(o)) return ivalue(o);
++ d= nvalue_fast(o);
++# ifdef LNUM_COMPLEX
++ if (nvalue_img_fast(o) != 0)
++ luaG_runerror(L, "expecting a real number");
++# endif
++ lua_number2integer(i, d);
++ return i;
+ }
+- else
+- return 0;
++#else
++ /* New suggestion */
++ const TValue *o = index2adr(L, idx);
++ if (tonumber(o, &n)) {
++ lua_Integer i;
++ if (ttisint(o)) return ivalue(o);
++ if (tt_integer_valued(o,&i)) return i;
++ }
++#endif
++ return 0;
+ }
+
+
++#ifdef LNUM_COMPLEX
++LUA_API lua_Complex lua_tocomplex (lua_State *L, int idx) {
++ TValue tmp;
++ const TValue *o = index2adr(L, idx);
++ if (tonumber(o, &tmp))
++ return nvalue_complex(o);
++ return 0;
++}
++#endif
++
++
+ LUA_API int lua_toboolean (lua_State *L, int idx) {
+ const TValue *o = index2adr(L, idx);
+ return !l_isfalse(o);
+@@ -364,6 +408,7 @@ LUA_API size_t lua_objlen (lua_State *L,
+ case LUA_TSTRING: return tsvalue(o)->len;
+ case LUA_TUSERDATA: return uvalue(o)->len;
+ case LUA_TTABLE: return luaH_getn(hvalue(o));
++ case LUA_TINT:
+ case LUA_TNUMBER: {
+ size_t l;
+ lua_lock(L); /* `luaV_tostring' may create a new string */
+@@ -426,6 +471,8 @@ LUA_API void lua_pushnil (lua_State *L)
+ }
+
+
++/* 'lua_pushnumber()' may lose accuracy on integers, 'lua_pushinteger' will not.
++ */
+ LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
+ lua_lock(L);
+ setnvalue(L->top, n);
+@@ -434,12 +481,22 @@ LUA_API void lua_pushnumber (lua_State *
+ }
+
+
+-LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
++LUA_API void lua_pushinteger (lua_State *L, lua_Integer i) {
++ lua_lock(L);
++ setivalue(L->top, i);
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++#ifdef LNUM_COMPLEX
++LUA_API void lua_pushcomplex (lua_State *L, lua_Complex v) {
+ lua_lock(L);
+- setnvalue(L->top, cast_num(n));
++ setnvalue_complex( L->top, v );
+ api_incr_top(L);
+ lua_unlock(L);
+ }
++#endif
+
+
+ LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
+@@ -569,7 +626,7 @@ LUA_API void lua_rawgeti (lua_State *L,
+ lua_lock(L);
+ o = index2adr(L, idx);
+ api_check(L, ttistable(o));
+- setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
++ setobj2s(L, L->top, luaH_getint(hvalue(o), n));
+ api_incr_top(L);
+ lua_unlock(L);
+ }
+@@ -597,6 +654,9 @@ LUA_API int lua_getmetatable (lua_State
+ case LUA_TUSERDATA:
+ mt = uvalue(obj)->metatable;
+ break;
++ case LUA_TINT:
++ mt = G(L)->mt[LUA_TNUMBER];
++ break;
+ default:
+ mt = G(L)->mt[ttype(obj)];
+ break;
+@@ -687,7 +747,7 @@ LUA_API void lua_rawseti (lua_State *L,
+ api_checknelems(L, 1);
+ o = index2adr(L, idx);
+ api_check(L, ttistable(o));
+- setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
++ setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1);
+ luaC_barriert(L, hvalue(o), L->top-1);
+ L->top--;
+ lua_unlock(L);
+@@ -721,7 +781,7 @@ LUA_API int lua_setmetatable (lua_State
+ break;
+ }
+ default: {
+- G(L)->mt[ttype(obj)] = mt;
++ G(L)->mt[ttype_ext(obj)] = mt;
+ break;
+ }
+ }
+@@ -1085,3 +1145,32 @@ LUA_API const char *lua_setupvalue (lua_
+ return name;
+ }
+
++
++/* Help function for 'luaB_tonumber()', avoids multiple str->number
++ * conversions for Lua "tonumber()".
++ *
++ * Also pushes floating point numbers with integer value as integer, which
++ * can be used by 'tonumber()' in scripts to bring values back to integer
++ * realm.
++ *
++ * Note: The 'back to integer realm' is _not_ to affect string conversions:
++ * 'tonumber("4294967295.1")' should give a floating point value, although
++ * the value would be 4294967296 (and storable in int64 realm).
++ */
++int lua_pushvalue_as_number (lua_State *L, int idx)
++{
++ const TValue *o = index2adr(L, idx);
++ TValue tmp;
++ lua_Integer i;
++ if (ttisnumber(o)) {
++ if ( (!ttisint(o)) && tt_integer_valued(o,&i)) {
++ lua_pushinteger( L, i );
++ return 1;
++ }
++ } else if (!tonumber(o, &tmp)) {
++ return 0;
++ }
++ if (ttisint(o)) lua_pushinteger( L, ivalue(o) );
++ else lua_pushnumber( L, nvalue_fast(o) );
++ return 1;
++}
+--- a/src/lapi.h
++++ b/src/lapi.h
+@@ -13,4 +13,6 @@
+
+ LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
+
++int lua_pushvalue_as_number (lua_State *L, int idx);
++
+ #endif
+--- a/src/lauxlib.c
++++ b/src/lauxlib.c
+@@ -23,7 +23,7 @@
+ #include "lua.h"
+
+ #include "lauxlib.h"
+-
++#include "llimits.h"
+
+ #define FREELIST_REF 0 /* free list of references */
+
+@@ -66,7 +66,7 @@ LUALIB_API int luaL_typerror (lua_State
+
+
+ static void tag_error (lua_State *L, int narg, int tag) {
+- luaL_typerror(L, narg, lua_typename(L, tag));
++ luaL_typerror(L, narg, tag==LUA_TINT ? "integer" : lua_typename(L, tag));
+ }
+
+
+@@ -188,8 +188,8 @@ LUALIB_API lua_Number luaL_optnumber (lu
+
+ LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
+ lua_Integer d = lua_tointeger(L, narg);
+- if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
+- tag_error(L, narg, LUA_TNUMBER);
++ if (d == 0 && !lua_isinteger(L, narg)) /* avoid extra test when d is not 0 */
++ tag_error(L, narg, LUA_TINT);
+ return d;
+ }
+
+@@ -200,6 +200,16 @@ LUALIB_API lua_Integer luaL_optinteger (
+ }
+
+
++#ifdef LNUM_COMPLEX
++LUALIB_API lua_Complex luaL_checkcomplex (lua_State *L, int narg) {
++ lua_Complex c = lua_tocomplex(L, narg);
++ if (c == 0 && !lua_isnumber(L, narg)) /* avoid extra test when c is not 0 */
++ tag_error(L, narg, LUA_TNUMBER);
++ return c;
++}
++#endif
++
++
+ LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
+ if (!lua_getmetatable(L, obj)) /* no metatable? */
+ return 0;
+--- a/src/lauxlib.h
++++ b/src/lauxlib.h
+@@ -57,6 +57,12 @@ LUALIB_API lua_Number (luaL_optnumber) (
+ LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
+ LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
+ lua_Integer def);
++#define luaL_checkint32(L,narg) ((int)luaL_checkinteger(L,narg))
++#define luaL_optint32(L,narg,def) ((int)luaL_optinteger(L,narg,def))
++
++#ifdef LNUM_COMPLEX
++ LUALIB_API lua_Complex (luaL_checkcomplex) (lua_State *L, int narg);
++#endif
+
+ LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
+ LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
+--- a/src/lbaselib.c
++++ b/src/lbaselib.c
+@@ -18,7 +18,9 @@
+
+ #include "lauxlib.h"
+ #include "lualib.h"
+-
++#include "llimits.h"
++#include "lobject.h"
++#include "lapi.h"
+
+
+
+@@ -54,20 +56,25 @@ static int luaB_tonumber (lua_State *L)
+ int base = luaL_optint(L, 2, 10);
+ if (base == 10) { /* standard conversion */
+ luaL_checkany(L, 1);
+- if (lua_isnumber(L, 1)) {
+- lua_pushnumber(L, lua_tonumber(L, 1));
++ if (lua_isnumber(L, 1)) { /* numeric string, or a number */
++ lua_pushvalue_as_number(L,1); /* API extension (not to lose accuracy here) */
+ return 1;
+- }
++ }
+ }
+ else {
+ const char *s1 = luaL_checkstring(L, 1);
+ char *s2;
+- unsigned long n;
++ unsigned LUA_INTEGER n;
+ luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
+- n = strtoul(s1, &s2, base);
++ n = lua_str2ul(s1, &s2, base);
+ if (s1 != s2) { /* at least one valid digit? */
+ while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
+ if (*s2 == '\0') { /* no invalid trailing characters? */
++
++ /* Push as number, there needs to be separate 'luaB_tointeger' for
++ * when the caller wants to preserve the bits (matters if unsigned
++ * values are used).
++ */
+ lua_pushnumber(L, (lua_Number)n);
+ return 1;
+ }
+@@ -144,7 +151,7 @@ static int luaB_setfenv (lua_State *L) {
+ luaL_checktype(L, 2, LUA_TTABLE);
+ getfunc(L, 0);
+ lua_pushvalue(L, 2);
+- if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
++ if (lua_isnumber(L, 1) && lua_tointeger(L, 1) == 0) {
+ /* change environment of current thread */
+ lua_pushthread(L);
+ lua_insert(L, -2);
+@@ -209,7 +216,7 @@ static int luaB_collectgarbage (lua_Stat
+ return 1;
+ }
+ default: {
+- lua_pushnumber(L, res);
++ lua_pushinteger(L, res);
+ return 1;
+ }
+ }
+@@ -631,6 +638,8 @@ static void base_open (lua_State *L) {
+ luaL_register(L, "_G", base_funcs);
+ lua_pushliteral(L, LUA_VERSION);
+ lua_setglobal(L, "_VERSION"); /* set global _VERSION */
++ lua_pushliteral(L, LUA_LNUM);
++ lua_setglobal(L, "_LNUM"); /* "[complex] double|float|ldouble int32|int64" */
+ /* `ipairs' and `pairs' need auxiliary functions as upvalues */
+ auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
+ auxopen(L, "pairs", luaB_pairs, luaB_next);
+--- a/src/lcode.c
++++ b/src/lcode.c
+@@ -22,13 +22,18 @@
+ #include "lopcodes.h"
+ #include "lparser.h"
+ #include "ltable.h"
++#include "lnum.h"
+
+
+ #define hasjumps(e) ((e)->t != (e)->f)
+
+-
+ static int isnumeral(expdesc *e) {
+- return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
++ int ek=
++#ifdef LNUM_COMPLEX
++ (e->k == VKNUM2) ||
++#endif
++ (e->k == VKINT) || (e->k == VKNUM);
++ return (ek && e->t == NO_JUMP && e->f == NO_JUMP);
+ }
+
+
+@@ -231,12 +236,16 @@ static int addk (FuncState *fs, TValue *
+ TValue *idx = luaH_set(L, fs->h, k);
+ Proto *f = fs->f;
+ int oldsize = f->sizek;
+- if (ttisnumber(idx)) {
+- lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
+- return cast_int(nvalue(idx));
++ if (ttype(idx)==LUA_TNUMBER) {
++ luai_normalize(idx);
++ lua_assert( ttype(idx)==LUA_TINT ); /* had no fraction */
++ }
++ if (ttisint(idx)) {
++ lua_assert(luaO_rawequalObj(&fs->f->k[ivalue(idx)], v));
++ return cast_int(ivalue(idx));
+ }
+ else { /* constant not found; create a new entry */
+- setnvalue(idx, cast_num(fs->nk));
++ setivalue(idx, fs->nk);
+ luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
+ MAXARG_Bx, "constant table overflow");
+ while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
+@@ -261,6 +270,21 @@ int luaK_numberK (FuncState *fs, lua_Num
+ }
+
+
++int luaK_integerK (FuncState *fs, lua_Integer r) {
++ TValue o;
++ setivalue(&o, r);
++ return addk(fs, &o, &o);
++}
++
++
++#ifdef LNUM_COMPLEX
++static int luaK_imagK (FuncState *fs, lua_Number r) {
++ TValue o;
++ setnvalue_complex(&o, r*I);
++ return addk(fs, &o, &o);
++}
++#endif
++
+ static int boolK (FuncState *fs, int b) {
+ TValue o;
+ setbvalue(&o, b);
+@@ -359,6 +383,16 @@ static void discharge2reg (FuncState *fs
+ luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
+ break;
+ }
++ case VKINT: {
++ luaK_codeABx(fs, OP_LOADK, reg, luaK_integerK(fs, e->u.ival));
++ break;
++ }
++#ifdef LNUM_COMPLEX
++ case VKNUM2: {
++ luaK_codeABx(fs, OP_LOADK, reg, luaK_imagK(fs, e->u.nval));
++ break;
++ }
++#endif
+ case VRELOCABLE: {
+ Instruction *pc = &getcode(fs, e);
+ SETARG_A(*pc, reg);
+@@ -444,6 +478,10 @@ void luaK_exp2val (FuncState *fs, expdes
+ int luaK_exp2RK (FuncState *fs, expdesc *e) {
+ luaK_exp2val(fs, e);
+ switch (e->k) {
++#ifdef LNUM_COMPLEX
++ case VKNUM2:
++#endif
++ case VKINT:
+ case VKNUM:
+ case VTRUE:
+ case VFALSE:
+@@ -451,6 +489,10 @@ int luaK_exp2RK (FuncState *fs, expdesc
+ if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
+ e->u.s.info = (e->k == VNIL) ? nilK(fs) :
+ (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
++ (e->k == VKINT) ? luaK_integerK(fs, e->u.ival) :
++#ifdef LNUM_COMPLEX
++ (e->k == VKNUM2) ? luaK_imagK(fs, e->u.nval) :
++#endif
+ boolK(fs, (e->k == VTRUE));
+ e->k = VK;
+ return RKASK(e->u.s.info);
+@@ -540,7 +582,10 @@ void luaK_goiftrue (FuncState *fs, expde
+ int pc; /* pc of last jump */
+ luaK_dischargevars(fs, e);
+ switch (e->k) {
+- case VK: case VKNUM: case VTRUE: {
++#ifdef LNUM_COMPLEX
++ case VKNUM2:
++#endif
++ case VKINT: case VK: case VKNUM: case VTRUE: {
+ pc = NO_JUMP; /* always true; do nothing */
+ break;
+ }
+@@ -590,7 +635,10 @@ static void codenot (FuncState *fs, expd
+ e->k = VTRUE;
+ break;
+ }
+- case VK: case VKNUM: case VTRUE: {
++#ifdef LNUM_COMPLEX
++ case VKNUM2:
++#endif
++ case VKINT: case VK: case VKNUM: case VTRUE: {
+ e->k = VFALSE;
+ break;
+ }
+@@ -626,25 +674,70 @@ void luaK_indexed (FuncState *fs, expdes
+
+ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
+ lua_Number v1, v2, r;
++ int vkres= VKNUM;
+ if (!isnumeral(e1) || !isnumeral(e2)) return 0;
+- v1 = e1->u.nval;
+- v2 = e2->u.nval;
++
++ /* real and imaginary parts don't mix. */
++#ifdef LNUM_COMPLEX
++ if (e1->k == VKNUM2) {
++ if ((op != OP_UNM) && (e2->k != VKNUM2)) return 0;
++ vkres= VKNUM2; }
++ else if (e2->k == VKNUM2) { return 0; }
++#endif
++ if ((e1->k == VKINT) && (e2->k == VKINT)) {
++ lua_Integer i1= e1->u.ival, i2= e2->u.ival;
++ lua_Integer rr;
++ int done= 0;
++ /* Integer/integer calculations (may end up producing floating point) */
++ switch (op) {
++ case OP_ADD: done= try_addint( &rr, i1, i2 ); break;
++ case OP_SUB: done= try_subint( &rr, i1, i2 ); break;
++ case OP_MUL: done= try_mulint( &rr, i1, i2 ); break;
++ case OP_DIV: done= try_divint( &rr, i1, i2 ); break;
++ case OP_MOD: done= try_modint( &rr, i1, i2 ); break;
++ case OP_POW: done= try_powint( &rr, i1, i2 ); break;
++ case OP_UNM: done= try_unmint( &rr, i1 ); break;
++ default: done= 0; break;
++ }
++ if (done) {
++ e1->u.ival = rr; /* remained within integer range */
++ return 1;
++ }
++ }
++ v1 = (e1->k == VKINT) ? ((lua_Number)e1->u.ival) : e1->u.nval;
++ v2 = (e2->k == VKINT) ? ((lua_Number)e2->u.ival) : e2->u.nval;
++
+ switch (op) {
+ case OP_ADD: r = luai_numadd(v1, v2); break;
+ case OP_SUB: r = luai_numsub(v1, v2); break;
+- case OP_MUL: r = luai_nummul(v1, v2); break;
++ case OP_MUL:
++#ifdef LNUM_COMPLEX
++ if (vkres==VKNUM2) return 0; /* leave to runtime (could do here, but not worth it?) */
++#endif
++ r = luai_nummul(v1, v2); break;
+ case OP_DIV:
+ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
+- r = luai_numdiv(v1, v2); break;
++#ifdef LNUM_COMPLEX
++ if (vkres==VKNUM2) return 0; /* leave to runtime */
++#endif
++ r = luai_numdiv(v1, v2); break;
+ case OP_MOD:
+ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
++#ifdef LNUM_COMPLEX
++ if (vkres==VKNUM2) return 0; /* leave to runtime */
++#endif
+ r = luai_nummod(v1, v2); break;
+- case OP_POW: r = luai_numpow(v1, v2); break;
++ case OP_POW:
++#ifdef LNUM_COMPLEX
++ if (vkres==VKNUM2) return 0; /* leave to runtime */
++#endif
++ r = luai_numpow(v1, v2); break;
+ case OP_UNM: r = luai_numunm(v1); break;
+ case OP_LEN: return 0; /* no constant folding for 'len' */
+ default: lua_assert(0); r = 0; break;
+ }
+ if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
++ e1->k = cast(expkind,vkres);
+ e1->u.nval = r;
+ return 1;
+ }
+@@ -688,7 +781,8 @@ static void codecomp (FuncState *fs, OpC
+
+ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
+ expdesc e2;
+- e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
++ e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
++
+ switch (op) {
+ case OPR_MINUS: {
+ if (!isnumeral(e))
+--- a/src/lcode.h
++++ b/src/lcode.h
+@@ -71,6 +71,6 @@ LUAI_FUNC void luaK_prefix (FuncState *f
+ LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
+ LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
+ LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
+-
++LUAI_FUNC int luaK_integerK (FuncState *fs, lua_Integer r);
+
+ #endif
+--- a/src/ldebug.c
++++ b/src/ldebug.c
+@@ -183,7 +183,7 @@ static void collectvalidlines (lua_State
+ int *lineinfo = f->l.p->lineinfo;
+ int i;
+ for (i=0; i<f->l.p->sizelineinfo; i++)
+- setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
++ setbvalue(luaH_setint(L, t, lineinfo[i]), 1);
+ sethvalue(L, L->top, t);
+ }
+ incr_top(L);
+@@ -566,7 +566,7 @@ static int isinstack (CallInfo *ci, cons
+
+ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+ const char *name = NULL;
+- const char *t = luaT_typenames[ttype(o)];
++ const char *t = luaT_typenames[ttype_ext(o)];
+ const char *kind = (isinstack(L->ci, o)) ?
+ getobjname(L, L->ci, cast_int(o - L->base), &name) :
+ NULL;
+@@ -594,8 +594,8 @@ void luaG_aritherror (lua_State *L, cons
+
+
+ int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
+- const char *t1 = luaT_typenames[ttype(p1)];
+- const char *t2 = luaT_typenames[ttype(p2)];
++ const char *t1 = luaT_typenames[ttype_ext(p1)];
++ const char *t2 = luaT_typenames[ttype_ext(p2)];
+ if (t1[2] == t2[2])
+ luaG_runerror(L, "attempt to compare two %s values", t1);
+ else
+--- a/src/ldo.c
++++ b/src/ldo.c
+@@ -220,9 +220,9 @@ static StkId adjust_varargs (lua_State *
+ luaD_checkstack(L, p->maxstacksize);
+ htab = luaH_new(L, nvar, 1); /* create `arg' table */
+ for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
+- setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
++ setobj2n(L, luaH_setint(L, htab, i+1), L->top - nvar + i);
+ /* store counter in field `n' */
+- setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
++ setivalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), nvar);
+ }
+ #endif
+ /* move fixed parameters to final position */
+--- a/src/ldump.c
++++ b/src/ldump.c
+@@ -52,6 +52,11 @@ static void DumpNumber(lua_Number x, Dum
+ DumpVar(x,D);
+ }
+
++static void DumpInteger(lua_Integer x, DumpState* D)
++{
++ DumpVar(x,D);
++}
++
+ static void DumpVector(const void* b, int n, size_t size, DumpState* D)
+ {
+ DumpInt(n,D);
+@@ -93,8 +98,11 @@ static void DumpConstants(const Proto* f
+ DumpChar(bvalue(o),D);
+ break;
+ case LUA_TNUMBER:
+- DumpNumber(nvalue(o),D);
++ DumpNumber(nvalue_fast(o),D);
+ break;
++ case LUA_TINT:
++ DumpInteger(ivalue(o),D);
++ break;
+ case LUA_TSTRING:
+ DumpString(rawtsvalue(o),D);
+ break;
+--- a/src/liolib.c
++++ b/src/liolib.c
+@@ -9,6 +9,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <ctype.h>
+
+ #define liolib_c
+ #define LUA_LIB
+@@ -18,7 +19,8 @@
+ #include "lauxlib.h"
+ #include "lualib.h"
+
+-
++#include "lnum.h"
++#include "llex.h"
+
+ #define IO_INPUT 1
+ #define IO_OUTPUT 2
+@@ -269,6 +271,13 @@ static int io_lines (lua_State *L) {
+ ** =======================================================
+ */
+
++/*
++* Many problems if we intend the same 'n' format specifier (see 'file:read()')
++* to work for both FP and integer numbers, without losing their accuracy. So
++* we don't. 'n' reads numbers as floating points, 'i' as integers. Old code
++* remains valid, but won't provide full integer accuracy (this only matters
++* with float FP and/or 64-bit integers).
++*/
+
+ static int read_number (lua_State *L, FILE *f) {
+ lua_Number d;
+@@ -282,6 +291,43 @@ static int read_number (lua_State *L, FI
+ }
+ }
+
++static int read_integer (lua_State *L, FILE *f) {
++ lua_Integer i;
++ if (fscanf(f, LUA_INTEGER_SCAN, &i) == 1) {
++ lua_pushinteger(L, i);
++ return 1;
++ }
++ else return 0; /* read fails */
++}
++
++#ifdef LNUM_COMPLEX
++static int read_complex (lua_State *L, FILE *f) {
++ /* NNN / NNNi / NNN+MMMi / NNN-MMMi */
++ lua_Number a,b;
++ if (fscanf(f, LUA_NUMBER_SCAN, &a) == 1) {
++ int c=fgetc(f);
++ switch(c) {
++ case 'i':
++ lua_pushcomplex(L, a*I);
++ return 1;
++ case '+':
++ case '-':
++ /* "i" is consumed if at the end; just 'NNN+MMM' will most likely
++ * behave as if "i" was there? (TBD: test)
++ */
++ if (fscanf(f, LUA_NUMBER_SCAN "i", &b) == 1) {
++ lua_pushcomplex(L, a+ (c=='+' ? b:-b)*I);
++ return 1;
++ }
++ }
++ ungetc( c,f );
++ lua_pushnumber(L,a); /*real part only*/
++ return 1;
++ }
++ return 0; /* read fails */
++}
++#endif
++
+
+ static int test_eof (lua_State *L, FILE *f) {
+ int c = getc(f);
+@@ -355,6 +401,14 @@ static int g_read (lua_State *L, FILE *f
+ case 'n': /* number */
+ success = read_number(L, f);
+ break;
++ case 'i': /* integer (full accuracy) */
++ success = read_integer(L, f);
++ break;
++#ifdef LNUM_COMPLEX
++ case 'c': /* complex */
++ success = read_complex(L, f);
++ break;
++#endif
+ case 'l': /* line */
+ success = read_line(L, f);
+ break;
+@@ -415,9 +469,10 @@ static int g_write (lua_State *L, FILE *
+ int status = 1;
+ for (; nargs--; arg++) {
+ if (lua_type(L, arg) == LUA_TNUMBER) {
+- /* optimization: could be done exactly as for strings */
+- status = status &&
+- fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
++ if (lua_isinteger(L,arg))
++ status = status && fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg)) > 0;
++ else
++ status = status && fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
+ }
+ else {
+ size_t l;
+@@ -460,7 +515,7 @@ static int f_setvbuf (lua_State *L) {
+ static const char *const modenames[] = {"no", "full", "line", NULL};
+ FILE *f = tofile(L);
+ int op = luaL_checkoption(L, 2, NULL, modenames);
+- lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
++ size_t sz = luaL_optint32(L, 3, LUAL_BUFFERSIZE);
+ int res = setvbuf(f, NULL, mode[op], sz);
+ return pushresult(L, res == 0, NULL);
+ }
+--- a/src/llex.c
++++ b/src/llex.c
+@@ -22,6 +22,7 @@
+ #include "lstring.h"
+ #include "ltable.h"
+ #include "lzio.h"
++#include "lnum.h"
+
+
+
+@@ -34,13 +35,17 @@
+
+
+ /* ORDER RESERVED */
+-const char *const luaX_tokens [] = {
++static const char *const luaX_tokens [] = {
+ "and", "break", "do", "else", "elseif",
+ "end", "false", "for", "function", "if",
+ "in", "local", "nil", "not", "or", "repeat",
+ "return", "then", "true", "until", "while",
+ "..", "...", "==", ">=", "<=", "~=",
+ "<number>", "<name>", "<string>", "<eof>",
++ "<integer>",
++#ifdef LNUM_COMPLEX
++ "<number2>",
++#endif
+ NULL
+ };
+
+@@ -90,7 +95,11 @@ static const char *txtToken (LexState *l
+ switch (token) {
+ case TK_NAME:
+ case TK_STRING:
++ case TK_INT:
+ case TK_NUMBER:
++#ifdef LNUM_COMPLEX
++ case TK_NUMBER2:
++#endif
+ save(ls, '\0');
+ return luaZ_buffer(ls->buff);
+ default:
+@@ -175,23 +184,27 @@ static void buffreplace (LexState *ls, c
+ if (p[n] == from) p[n] = to;
+ }
+
+-
+-static void trydecpoint (LexState *ls, SemInfo *seminfo) {
++/* TK_NUMBER (/ TK_NUMBER2) */
++static int trydecpoint (LexState *ls, SemInfo *seminfo) {
+ /* format error: try to update decimal point separator */
+ struct lconv *cv = localeconv();
+ char old = ls->decpoint;
++ int ret;
+ ls->decpoint = (cv ? cv->decimal_point[0] : '.');
+ buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
+- if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
++ ret= luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r, NULL);
++ if (!ret) {
+ /* format error with correct decimal point: no more options */
+ buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
+ luaX_lexerror(ls, "malformed number", TK_NUMBER);
+ }
++ return ret;
+ }
+
+
+-/* LUA_NUMBER */
+-static void read_numeral (LexState *ls, SemInfo *seminfo) {
++/* TK_NUMBER / TK_INT (/TK_NUMBER2) */
++static int read_numeral (LexState *ls, SemInfo *seminfo) {
++ int ret;
+ lua_assert(isdigit(ls->current));
+ do {
+ save_and_next(ls);
+@@ -202,8 +215,9 @@ static void read_numeral (LexState *ls,
+ save_and_next(ls);
+ save(ls, '\0');
+ buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
+- if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
+- trydecpoint(ls, seminfo); /* try to update decimal point separator */
++ ret= luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r, &seminfo->i );
++ if (!ret) return trydecpoint(ls, seminfo); /* try to update decimal point separator */
++ return ret;
+ }
+
+
+@@ -331,6 +345,7 @@ static void read_string (LexState *ls, i
+ }
+
+
++/* char / TK_* */
+ static int llex (LexState *ls, SemInfo *seminfo) {
+ luaZ_resetbuffer(ls->buff);
+ for (;;) {
+@@ -402,8 +417,7 @@ static int llex (LexState *ls, SemInfo *
+ }
+ else if (!isdigit(ls->current)) return '.';
+ else {
+- read_numeral(ls, seminfo);
+- return TK_NUMBER;
++ return read_numeral(ls, seminfo);
+ }
+ }
+ case EOZ: {
+@@ -416,8 +430,7 @@ static int llex (LexState *ls, SemInfo *
+ continue;
+ }
+ else if (isdigit(ls->current)) {
+- read_numeral(ls, seminfo);
+- return TK_NUMBER;
++ return read_numeral(ls, seminfo);
+ }
+ else if (isalpha(ls->current) || ls->current == '_') {
+ /* identifier or reserved word */
+--- a/src/llex.h
++++ b/src/llex.h
+@@ -29,19 +29,22 @@ enum RESERVED {
+ TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
+ /* other terminal symbols */
+ TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
+- TK_NAME, TK_STRING, TK_EOS
++ TK_NAME, TK_STRING, TK_EOS, TK_INT
++#ifdef LNUM_COMPLEX
++ , TK_NUMBER2 /* imaginary constants: Ni */
++#endif
+ };
+
+ /* number of reserved words */
+ #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
+
+
+-/* array with token `names' */
+-LUAI_DATA const char *const luaX_tokens [];
+-
+-
++/* SemInfo is a local data structure of 'llex.c', used for carrying a string
++ * or a number. A separate token (TK_*) will tell, how to interpret the data.
++ */
+ typedef union {
+ lua_Number r;
++ lua_Integer i;
+ TString *ts;
+ } SemInfo; /* semantics information */
+
+--- a/src/llimits.h
++++ b/src/llimits.h
+@@ -49,6 +49,7 @@ typedef LUAI_USER_ALIGNMENT_T L_Umaxalig
+
+ /* result of a `usual argument conversion' over lua_Number */
+ typedef LUAI_UACNUMBER l_uacNumber;
++typedef LUAI_UACINTEGER l_uacInteger;
+
+
+ /* internal assertions for in-house debugging */
+@@ -80,7 +81,6 @@ typedef LUAI_UACNUMBER l_uacNumber;
+ #define cast_int(i) cast(int, (i))
+
+
+-
+ /*
+ ** type for virtual-machine instructions
+ ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
+--- a/src/lmathlib.c
++++ b/src/lmathlib.c
+@@ -4,7 +4,6 @@
+ ** See Copyright Notice in lua.h
+ */
+
+-
+ #include <stdlib.h>
+ #include <math.h>
+
+@@ -16,113 +15,210 @@
+ #include "lauxlib.h"
+ #include "lualib.h"
+
++/* 'luai_vectpow()' as a replacement for 'cpow()'. Defined in the header; we
++ * don't intrude the code libs internal functions.
++ */
++#ifdef LNUM_COMPLEX
++# include "lnum.h"
++#endif
+
+ #undef PI
+-#define PI (3.14159265358979323846)
+-#define RADIANS_PER_DEGREE (PI/180.0)
+-
++#ifdef LNUM_FLOAT
++# define PI (3.14159265358979323846F)
++#elif defined(M_PI)
++# define PI M_PI
++#else
++# define PI (3.14159265358979323846264338327950288)
++#endif
++#define RADIANS_PER_DEGREE (PI/180)
+
++#undef HUGE
++#ifdef LNUM_FLOAT
++# define HUGE HUGE_VALF
++#elif defined(LNUM_LDOUBLE)
++# define HUGE HUGE_VALL
++#else
++# define HUGE HUGE_VAL
++#endif
+
+ static int math_abs (lua_State *L) {
+- lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushnumber(L, _LF(cabs) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(fabs) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_sin (lua_State *L) {
+- lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(csin) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(sin) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_sinh (lua_State *L) {
+- lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(csinh) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(sinh) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_cos (lua_State *L) {
+- lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(ccos) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(cos) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_cosh (lua_State *L) {
+- lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(ccosh) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(cosh) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_tan (lua_State *L) {
+- lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(ctan) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(tan) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_tanh (lua_State *L) {
+- lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(ctanh) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(tanh) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_asin (lua_State *L) {
+- lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(casin) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(asin) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_acos (lua_State *L) {
+- lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(cacos) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(acos) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_atan (lua_State *L) {
+- lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(catan) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(atan) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_atan2 (lua_State *L) {
+- lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
++ /* scalars only */
++ lua_pushnumber(L, _LF(atan2) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
+ return 1;
+ }
+
+ static int math_ceil (lua_State *L) {
+- lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_Complex v= luaL_checkcomplex(L, 1);
++ lua_pushcomplex(L, _LF(ceil) (_LF(creal)(v)) + _LF(ceil) (_LF(cimag)(v))*I);
++#else
++ lua_pushnumber(L, _LF(ceil) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_floor (lua_State *L) {
+- lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_Complex v= luaL_checkcomplex(L, 1);
++ lua_pushcomplex(L, _LF(floor) (_LF(creal)(v)) + _LF(floor) (_LF(cimag)(v))*I);
++#else
++ lua_pushnumber(L, _LF(floor) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+-static int math_fmod (lua_State *L) {
+- lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
++static int math_fmod (lua_State *L) {
++ /* scalars only */
++ lua_pushnumber(L, _LF(fmod) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
+ return 1;
+ }
+
+ static int math_modf (lua_State *L) {
+- double ip;
+- double fp = modf(luaL_checknumber(L, 1), &ip);
++ /* scalars only */
++ lua_Number ip;
++ lua_Number fp = _LF(modf) (luaL_checknumber(L, 1), &ip);
+ lua_pushnumber(L, ip);
+ lua_pushnumber(L, fp);
+ return 2;
+ }
+
+ static int math_sqrt (lua_State *L) {
+- lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(csqrt) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(sqrt) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_pow (lua_State *L) {
+- lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
++#ifdef LNUM_COMPLEX
++ /* C99 'cpow' gives somewhat inaccurate results (i.e. (-1)^2 = -1+1.2246467991474e-16i).
++ * 'luai_vectpow' smoothens such, reusing it is the reason we need to #include "lnum.h".
++ */
++ lua_pushcomplex(L, luai_vectpow(luaL_checkcomplex(L,1), luaL_checkcomplex(L,2)));
++#else
++ lua_pushnumber(L, _LF(pow) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
++#endif
+ return 1;
+ }
+
+ static int math_log (lua_State *L) {
+- lua_pushnumber(L, log(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(log) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_log10 (lua_State *L) {
+- lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ /* Not in standard <complex.h> , but easy to calculate: log_a(x) = log_b(x) / log_b(a)
++ */
++ lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)) / _LF(log) (10));
++#else
++ lua_pushnumber(L, _LF(log10) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_exp (lua_State *L) {
+- lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(cexp) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(exp) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+@@ -138,19 +234,20 @@ static int math_rad (lua_State *L) {
+
+ static int math_frexp (lua_State *L) {
+ int e;
+- lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
++ lua_pushnumber(L, _LF(frexp) (luaL_checknumber(L, 1), &e));
+ lua_pushinteger(L, e);
+ return 2;
+ }
+
+ static int math_ldexp (lua_State *L) {
+- lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
++ lua_pushnumber(L, _LF(ldexp) (luaL_checknumber(L, 1), luaL_checkint(L, 2)));
+ return 1;
+ }
+
+
+
+ static int math_min (lua_State *L) {
++ /* scalars only */
+ int n = lua_gettop(L); /* number of arguments */
+ lua_Number dmin = luaL_checknumber(L, 1);
+ int i;
+@@ -165,6 +262,7 @@ static int math_min (lua_State *L) {
+
+
+ static int math_max (lua_State *L) {
++ /* scalars only */
+ int n = lua_gettop(L); /* number of arguments */
+ lua_Number dmax = luaL_checknumber(L, 1);
+ int i;
+@@ -182,25 +280,20 @@ static int math_random (lua_State *L) {
+ /* the `%' avoids the (rare) case of r==1, and is needed also because on
+ some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
+ lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
+- switch (lua_gettop(L)) { /* check number of arguments */
+- case 0: { /* no arguments */
+- lua_pushnumber(L, r); /* Number between 0 and 1 */
+- break;
+- }
+- case 1: { /* only upper limit */
+- int u = luaL_checkint(L, 1);
+- luaL_argcheck(L, 1<=u, 1, "interval is empty");
+- lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
+- break;
+- }
+- case 2: { /* lower and upper limits */
+- int l = luaL_checkint(L, 1);
+- int u = luaL_checkint(L, 2);
+- luaL_argcheck(L, l<=u, 2, "interval is empty");
+- lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
+- break;
+- }
+- default: return luaL_error(L, "wrong number of arguments");
++ int n= lua_gettop(L); /* number of arguments */
++ if (n==0) { /* no arguments: range [0,1) */
++ lua_pushnumber(L, r);
++ } else if (n<=2) { /* int range [1,u] or [l,u] */
++ int l= n==1 ? 1 : luaL_checkint(L, 1);
++ int u = luaL_checkint(L, n);
++ int tmp;
++ lua_Number d;
++ luaL_argcheck(L, l<=u, n, "interval is empty");
++ d= _LF(floor)(r*(u-l+1));
++ lua_number2int(tmp,d);
++ lua_pushinteger(L, l+tmp);
++ } else {
++ return luaL_error(L, "wrong number of arguments");
+ }
+ return 1;
+ }
+@@ -211,6 +304,66 @@ static int math_randomseed (lua_State *L
+ return 0;
+ }
+
++/*
++* Lua 5.1 does not have acosh, asinh, atanh for scalars (not ANSI C)
++*/
++#if __STDC_VERSION__ >= 199901L
++static int math_acosh (lua_State *L) {
++# ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(cacosh) (luaL_checkcomplex(L,1)));
++# else
++ lua_pushnumber(L, _LF(acosh) (luaL_checknumber(L,1)));
++# endif
++ return 1;
++}
++static int math_asinh (lua_State *L) {
++# ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(casinh) (luaL_checkcomplex(L,1)));
++# else
++ lua_pushnumber(L, _LF(asinh) (luaL_checknumber(L,1)));
++# endif
++ return 1;
++}
++static int math_atanh (lua_State *L) {
++# ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(catanh) (luaL_checkcomplex(L,1)));
++# else
++ lua_pushnumber(L, _LF(atanh) (luaL_checknumber(L,1)));
++# endif
++ return 1;
++}
++#endif
++
++/*
++ * C99 complex functions, not covered above.
++*/
++#ifdef LNUM_COMPLEX
++static int math_arg (lua_State *L) {
++ lua_pushnumber(L, _LF(carg) (luaL_checkcomplex(L,1)));
++ return 1;
++}
++
++static int math_imag (lua_State *L) {
++ lua_pushnumber(L, _LF(cimag) (luaL_checkcomplex(L,1)));
++ return 1;
++}
++
++static int math_real (lua_State *L) {
++ lua_pushnumber(L, _LF(creal) (luaL_checkcomplex(L,1)));
++ return 1;
++}
++
++static int math_conj (lua_State *L) {
++ lua_pushcomplex(L, _LF(conj) (luaL_checkcomplex(L,1)));
++ return 1;
++}
++
++static int math_proj (lua_State *L) {
++ lua_pushcomplex(L, _LF(cproj) (luaL_checkcomplex(L,1)));
++ return 1;
++}
++#endif
++
+
+ static const luaL_Reg mathlib[] = {
+ {"abs", math_abs},
+@@ -241,6 +394,18 @@ static const luaL_Reg mathlib[] = {
+ {"sqrt", math_sqrt},
+ {"tanh", math_tanh},
+ {"tan", math_tan},
++#if __STDC_VERSION__ >= 199901L
++ {"acosh", math_acosh},
++ {"asinh", math_asinh},
++ {"atanh", math_atanh},
++#endif
++#ifdef LNUM_COMPLEX
++ {"arg", math_arg},
++ {"imag", math_imag},
++ {"real", math_real},
++ {"conj", math_conj},
++ {"proj", math_proj},
++#endif
+ {NULL, NULL}
+ };
+
+@@ -252,8 +417,10 @@ LUALIB_API int luaopen_math (lua_State *
+ luaL_register(L, LUA_MATHLIBNAME, mathlib);
+ lua_pushnumber(L, PI);
+ lua_setfield(L, -2, "pi");
+- lua_pushnumber(L, HUGE_VAL);
++ lua_pushnumber(L, HUGE);
+ lua_setfield(L, -2, "huge");
++ lua_pushinteger(L, LUA_INTEGER_MAX );
++ lua_setfield(L, -2, "hugeint");
+ #if defined(LUA_COMPAT_MOD)
+ lua_getfield(L, -1, "fmod");
+ lua_setfield(L, -2, "mod");
+--- /dev/null
++++ b/src/lnum.c
+@@ -0,0 +1,312 @@
++/*
++** $Id: lnum.c,v ... $
++** Internal number model
++** See Copyright Notice in lua.h
++*/
++
++#include <stdlib.h>
++#include <math.h>
++#include <ctype.h>
++#include <string.h>
++#include <stdio.h>
++#include <errno.h>
++
++#define lnum_c
++#define LUA_CORE
++
++#include "lua.h"
++#include "llex.h"
++#include "lnum.h"
++
++/*
++** lua_real2str converts a (non-complex) number to a string.
++** lua_str2real converts a string to a (non-complex) number.
++*/
++#define lua_real2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
++
++/*
++* Note: Only 'strtod()' is part of ANSI C; others are C99 and
++* may need '--std=c99' compiler setting (at least on Ubuntu 7.10).
++*
++* Visual C++ 2008 Express does not have 'strtof()', nor 'strtold()'.
++* References to '_strtold()' exist but don't compile. It seems best
++* to leave Windows users with DOUBLE only (or compile with MinGW).
++*
++* In practise, using '(long double)strtod' is a risky thing, since
++* it will cause accuracy loss in reading in numbers, and such losses
++* will pile up in later processing. Get a real 'strtold()' or don't
++* use that mode at all.
++*/
++#ifdef LNUM_DOUBLE
++# define lua_str2real strtod
++#elif defined(LNUM_FLOAT)
++# define lua_str2real strtof
++#elif defined(LNUM_LDOUBLE)
++# define lua_str2real strtold
++#endif
++
++#define lua_integer2str(s,v) sprintf((s), LUA_INTEGER_FMT, (v))
++
++/* 's' is expected to be LUAI_MAXNUMBER2STR long (enough for any number)
++*/
++void luaO_num2buf( char *s, const TValue *o )
++{
++ lua_Number n;
++ lua_assert( ttisnumber(o) );
++
++ /* Reason to handle integers differently is not only speed, but accuracy as
++ * well. We want to make any integer tostring() without roundings, at all.
++ */
++ if (ttisint(o)) {
++ lua_integer2str( s, ivalue(o) );
++ return;
++ }
++ n= nvalue_fast(o);
++ lua_real2str(s, n);
++
++#ifdef LNUM_COMPLEX
++ lua_Number n2= nvalue_img_fast(o);
++ if (n2!=0) { /* Postfix with +-Ni */
++ int re0= (n == 0);
++ char *s2= re0 ? s : strchr(s,'\0');
++ if ((!re0) && (n2>0)) *s2++= '+';
++ lua_real2str( s2, n2 );
++ strcat(s2,"i");
++ }
++#endif
++}
++
++/*
++* If a LUA_TNUMBER has integer value, give it.
++*/
++int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref ) {
++ lua_Number d;
++ lua_Integer i;
++
++ lua_assert( ttype(o)==LUA_TNUMBER );
++ lua_assert( ref );
++#ifdef LNUM_COMPLEX
++ if (nvalue_img_fast(o)!=0) return 0;
++#endif
++ d= nvalue_fast(o);
++ lua_number2integer(i, d);
++ if (cast_num(i) == d) {
++ *ref= i; return 1;
++ }
++ return 0;
++}
++
++/*
++ * Lua 5.1.3 (using 'strtod()') allows 0x+hex but not 0+octal. This is good,
++ * and we should NOT use 'autobase' 0 with 'strtoul[l]()' for this reason.
++ *
++ * Lua 5.1.3 allows '0x...' numbers to overflow and lose precision; this is not
++ * good. On Visual C++ 2008, 'strtod()' does not even take them in. Better to
++ * require hex values to fit 'lua_Integer' or give an error that they don't?
++ *
++ * Full hex range (0 .. 0xff..ff) is stored as integers, not to lose any bits.
++ * Numerical value of 0xff..ff will be -1, if used in calculations.
++ *
++ * Returns: TK_INT for a valid integer, '*endptr_ref' updated
++ * TK_NUMBER for seemingly numeric, to be parsed as floating point
++ * 0 for bad characters, not a number (or '0x' out of range)
++ */
++static int luaO_str2i (const char *s, lua_Integer *res, char **endptr_ref) {
++ char *endptr;
++ /* 'v' gets ULONG_MAX on possible overflow (which is > LUA_INTEGER_MAX);
++ * we don't have to check 'errno' here.
++ */
++ unsigned LUA_INTEGER v= lua_str2ul(s, &endptr, 10);
++ if (endptr == s) return 0; /* nothing numeric */
++ if (v==0 && *endptr=='x') {
++ errno= 0; /* needs to be set, 'strtoul[l]' does not clear it */
++ v= lua_str2ul(endptr+1, &endptr, 16); /* retry as hex, unsigned range */
++ if (errno==ERANGE) { /* clamped to 0xff..ff */
++#if (defined(LNUM_INT32) && !defined(LNUM_FLOAT)) || defined(LNUM_LDOUBLE)
++ return TK_NUMBER; /* Allow to be read as floating point (has more integer range) */
++#else
++ return 0; /* Reject the number */
++#endif
++ }
++ } else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
++ return TK_NUMBER; /* not in signed range, or has '.', 'e' etc. trailing */
++ }
++ *res= (lua_Integer)v;
++ *endptr_ref= endptr;
++ return TK_INT;
++}
++
++/* 0 / TK_NUMBER / TK_INT (/ TK_NUMBER2) */
++int luaO_str2d (const char *s, lua_Number *res_n, lua_Integer *res_i) {
++ char *endptr;
++ int ret= TK_NUMBER;
++ /* Check integers first, if caller is allowing.
++ * If 'res2'==NULL, they're only looking for floating point.
++ */
++ if (res_i) {
++ ret= luaO_str2i(s,res_i,&endptr);
++ if (ret==0) return 0;
++ }
++ if (ret==TK_NUMBER) {
++ lua_assert(res_n);
++ /* Note: Visual C++ 2008 Express 'strtod()' does not read in "0x..."
++ * numbers; it will read '0' and spit 'x' as endptr.
++ * This means hex constants not fitting in 'lua_Integer' won't
++ * be read in at all. What to do?
++ */
++ *res_n = lua_str2real(s, &endptr);
++ if (endptr == s) return 0; /* conversion failed */
++ /* Visual C++ 2008 'strtod()' does not allow "0x..." input. */
++#if defined(_MSC_VER) && !defined(LNUM_FLOAT) && !defined(LNUM_INT64)
++ if (*res_n==0 && *endptr=='x') {
++ /* Hex constant too big for 'lua_Integer' but that could fit in 'lua_Number'
++ * integer bits
++ */
++ unsigned __int64 v= _strtoui64( s, &endptr, 16 );
++ /* We just let > 64 bit values be clamped to _UI64_MAX (MSDN does not say 'errno'==ERANGE would be set) */
++ *res_n= cast_num(v);
++ if (*res_n != v) return 0; /* Would have lost accuracy */
++ }
++#endif
++#ifdef LNUM_COMPLEX
++ if (*endptr == 'i') { endptr++; ret= TK_NUMBER2; }
++#endif
++ }
++ if (*endptr) {
++ while (isspace(cast(unsigned char, *endptr))) endptr++;
++ if (*endptr) return 0; /* invalid trail */
++ }
++ return ret;
++}
++
++
++/* Functions for finding out, when integer operations remain in range
++ * (and doing them).
++ */
++int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++ lua_Integer v= ib+ic; /* may overflow */
++ if (ib>0 && ic>0) { if (v < 0) return 0; /*overflow, use floats*/ }
++ else if (ib<0 && ic<0) { if (v >= 0) return 0; }
++ *r= v;
++ return 1;
++}
++
++int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++ lua_Integer v= ib-ic; /* may overflow */
++ if (ib>=0 && ic<0) { if (v < 0) return 0; /*overflow, use floats*/ }
++ else if (ib<0 && ic>0) { if (v >= 0) return 0; }
++ *r= v;
++ return 1;
++}
++
++int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++ if (ib!=LUA_INTEGER_MIN && ic!=LUA_INTEGER_MIN) {
++ lua_Integer b= luai_abs(ib), c= luai_abs(ic);
++ if ( (ib==0) || (LUA_INTEGER_MAX/b >= c) ) {
++ *r= ib*ic; /* no overflow */
++ return 1;
++ }
++ } else if (ib==0 || ic==0) {
++ *r= 0; return 1;
++ }
++
++ /* Result can be LUA_INTEGER_MIN; if it is, calculating it using floating
++ * point will not cause accuracy loss.
++ */
++ if ( luai_nummul( cast_num(ib), cast_num(ic) ) == LUA_INTEGER_MIN ) {
++ *r= LUA_INTEGER_MIN;
++ return 1;
++ }
++ return 0;
++}
++
++int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++ /* N/0: leave to float side, to give an error
++ */
++ if (ic==0) return 0;
++
++ /* N/LUA_INTEGER_MIN: always non-integer results, or 0 or +1
++ */
++ if (ic==LUA_INTEGER_MIN) {
++ if (ib==LUA_INTEGER_MIN) { *r=1; return 1; }
++ if (ib==0) { *r=0; return 1; }
++
++ /* LUA_INTEGER_MIN (-2^31|63)/N: calculate using float side (either the division
++ * causes non-integer results, or there is no accuracy loss in int->fp->int
++ * conversions (N=2,4,8,..,256 and N=2^30,2^29,..2^23).
++ */
++ } else if (ib==LUA_INTEGER_MIN) {
++ lua_Number d= luai_numdiv( cast_num(LUA_INTEGER_MIN), cast_num(ic) );
++ lua_Integer i; lua_number2integer(i,d);
++ if (cast_num(i)==d) { *r= i; return 1; }
++
++ } else {
++ /* Note: We _can_ use ANSI C mod here, even on negative values, since
++ * we only test for == 0 (the sign would be implementation dependent).
++ */
++ if (ib%ic == 0) { *r= ib/ic; return 1; }
++ }
++
++ return 0;
++}
++
++int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++ if (ic!=0) {
++ /* ANSI C can be trusted when b%c==0, or when values are non-negative.
++ * b - (floor(b/c) * c)
++ * -->
++ * + +: b - (b/c) * c (b % c can be used)
++ * - -: b - (b/c) * c (b % c could work, but not defined by ANSI C)
++ * 0 -: b - (b/c) * c (=0, b % c could work, but not defined by ANSI C)
++ * - +: b - (b/c-1) * c (when b!=-c)
++ * + -: b - (b/c-1) * c (when b!=-c)
++ *
++ * o MIN%MIN ends up 0, via overflow in calcs but that does not matter.
++ * o MIN%MAX ends up MAX-1 (and other such numbers), also after overflow,
++ * but that does not matter, results do.
++ */
++ lua_Integer v= ib % ic;
++ if ( v!=0 && (ib<0 || ic<0) ) {
++ v= ib - ((ib/ic) - ((ib<=0 && ic<0) ? 0:1)) * ic;
++ }
++ /* Result should always have same sign as 2nd argument. (PIL2) */
++ lua_assert( (v<0) ? (ic<0) : (v>0) ? (ic>0) : 1 );
++ *r= v;
++ return 1;
++ }
++ return 0; /* let float side return NaN */
++}
++
++int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++
++ /* In FLOAT/INT32 or FLOAT|DOUBLE/INT64 modes, calculating integer powers
++ * via FP realm may lose accuracy (i.e. 7^11 = 1977326743, which fits int32
++ * but not 23-bit float mantissa).
++ *
++ * The current solution is dumb, but it works and uses little code. Use of
++ * integer powers is not anticipated to be very frequent (apart from 2^x,
++ * which is separately optimized).
++ */
++ if (ib==0) *r=0;
++ else if (ic<0) return 0; /* FP realm */
++ else if (ib==2 && ic < (int)sizeof(lua_Integer)*8-1) *r= ((lua_Integer)1)<<ic; /* 1,2,4,...2^30 | 2^62 optimization */
++ else if (ic==0) *r=1;
++ else if (luai_abs(ib)==1) *r= (ic%2) ? ib:1;
++ else {
++ lua_Integer x= ib;
++ while( --ic ) {
++ if (!try_mulint( &x, x, ib ))
++ return 0; /* FP realm */
++ }
++ *r= x;
++ }
++ return 1;
++}
++
++int try_unmint( lua_Integer *r, lua_Integer ib ) {
++ /* Negating LUA_INTEGER_MIN leaves the range. */
++ if ( ib != LUA_INTEGER_MIN )
++ { *r= -ib; return 1; }
++ return 0;
++}
++
+--- /dev/null
++++ b/src/lnum.h
+@@ -0,0 +1,116 @@
++/*
++** $Id: lnum.h,v ... $
++** Internal Number model
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lnum_h
++#define lnum_h
++
++#include <math.h>
++
++#include "lobject.h"
++
++/*
++** The luai_num* macros define the primitive operations over 'lua_Number's
++** (not 'lua_Integer's, not 'lua_Complex').
++*/
++#define luai_numadd(a,b) ((a)+(b))
++#define luai_numsub(a,b) ((a)-(b))
++#define luai_nummul(a,b) ((a)*(b))
++#define luai_numdiv(a,b) ((a)/(b))
++#define luai_nummod(a,b) ((a) - _LF(floor)((a)/(b))*(b))
++#define luai_numpow(a,b) (_LF(pow)(a,b))
++#define luai_numunm(a) (-(a))
++#define luai_numeq(a,b) ((a)==(b))
++#define luai_numlt(a,b) ((a)<(b))
++#define luai_numle(a,b) ((a)<=(b))
++#define luai_numisnan(a) (!luai_numeq((a), (a)))
++
++int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_unmint( lua_Integer *r, lua_Integer ib );
++
++#ifdef LNUM_COMPLEX
++ static inline lua_Complex luai_vectunm( lua_Complex a ) { return -a; }
++ static inline lua_Complex luai_vectadd( lua_Complex a, lua_Complex b ) { return a+b; }
++ static inline lua_Complex luai_vectsub( lua_Complex a, lua_Complex b ) { return a-b; }
++ static inline lua_Complex luai_vectmul( lua_Complex a, lua_Complex b ) { return a*b; }
++ static inline lua_Complex luai_vectdiv( lua_Complex a, lua_Complex b ) { return a/b; }
++
++/*
++ * C99 does not provide modulus for complex numbers. It most likely is not
++ * meaningful at all.
++ */
++
++/*
++ * Complex power
++ *
++ * C99 'cpow' gives inaccurate results for many common cases s.a. (1i)^2 ->
++ * -1+1.2246467991474e-16i (OS X 10.4, gcc 4.0.1 build 5367)
++ *
++ * [(a+bi)^(c+di)] = (r^c) * exp(-d*t) * cos(c*t + d*ln(r)) +
++ * = (r^c) * exp(-d*t) * sin(c*t + d*ln(r)) *i
++ * r = sqrt(a^2+b^2), t = arctan( b/a )
++ *
++ * Reference: <http://home.att.net/~srschmitt/complexnumbers.html>
++ * Could also be calculated using: x^y = exp(ln(x)*y)
++ *
++ * Note: Defined here (and not in .c) so 'lmathlib.c' can share the
++ * implementation.
++ */
++ static inline
++ lua_Complex luai_vectpow( lua_Complex a, lua_Complex b )
++ {
++# if 1
++ lua_Number ar= _LF(creal)(a), ai= _LF(cimag)(a);
++ lua_Number br= _LF(creal)(b), bi= _LF(cimag)(b);
++
++ if (ai==0 && bi==0) { /* a^c (real) */
++ return luai_numpow( ar, br );
++ }
++
++ int br_int= (int)br;
++
++ if ( ai!=0 && bi==0 && br_int==br && br_int!=0 && br_int!=INT_MIN ) {
++ /* (a+bi)^N, N = { +-1,+-2, ... +-INT_MAX }
++ */
++ lua_Number k= luai_numpow( _LF(sqrt) (ar*ar + ai*ai), br );
++ lua_Number cos_z, sin_z;
++
++ /* Situation depends upon c (N) in the following manner:
++ *
++ * N%4==0 => cos(c*t)=1, sin(c*t)=0
++ * (N*sign(b))%4==1 or (N*sign(b))%4==-3 => cos(c*t)=0, sin(c*t)=1
++ * N%4==2 or N%4==-2 => cos(c*t)=-1, sin(c*t)=0
++ * (N*sign(b))%4==-1 or (N*sign(b))%4==3 => cos(c*t)=0, sin(c*t)=-1
++ */
++ int br_int_abs = br_int<0 ? -br_int:br_int;
++
++ switch( (br_int_abs%4) * (br_int<0 ? -1:1) * (ai<0 ? -1:1) ) {
++ case 0: cos_z=1, sin_z=0; break;
++ case 2: case -2: cos_z=-1, sin_z=0; break;
++ case 1: case -3: cos_z=0, sin_z=1; break;
++ case 3: case -1: cos_z=0, sin_z=-1; break;
++ default: lua_assert(0); return 0;
++ }
++ return k*cos_z + (k*sin_z)*I;
++ }
++# endif
++ return _LF(cpow) ( a, b );
++ }
++#endif
++
++LUAI_FUNC int luaO_str2d (const char *s, lua_Number *res1, lua_Integer *res2);
++LUAI_FUNC void luaO_num2buf( char *s, const TValue *o );
++
++LUAI_FUNC int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref );
++
++#define luai_normalize(o) \
++{ lua_Integer _i; if (tt_integer_valued(o,&_i)) setivalue(o,_i); }
++
++#endif
+--- /dev/null
++++ b/src/lnum_config.h
+@@ -0,0 +1,221 @@
++/*
++** $Id: lnum_config.h,v ... $
++** Internal Number model
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lnum_config_h
++#define lnum_config_h
++
++/*
++** Default number modes
++*/
++#if (!defined LNUM_DOUBLE) && (!defined LNUM_FLOAT) && (!defined LNUM_LDOUBLE)
++# define LNUM_FLOAT
++#endif
++#if (!defined LNUM_INT16) && (!defined LNUM_INT32) && (!defined LNUM_INT64)
++# define LNUM_INT32
++#endif
++
++/*
++** Require C99 mode for COMPLEX, FLOAT and LDOUBLE (only DOUBLE is ANSI C).
++*/
++#if defined(LNUM_COMPLEX) && (__STDC_VERSION__ < 199901L)
++# error "Need C99 for complex (use '--std=c99' or similar)"
++#elif defined(LNUM_LDOUBLE) && (__STDC_VERSION__ < 199901L) && !defined(_MSC_VER)
++# error "Need C99 for 'long double' (use '--std=c99' or similar)"
++#elif defined(LNUM_FLOAT) && (__STDC_VERSION__ < 199901L)
++/* LNUM_FLOAT not supported on Windows */
++# error "Need C99 for 'float' (use '--std=c99' or similar)"
++#endif
++
++/*
++** Number mode identifier to accompany the version string.
++*/
++#ifdef LNUM_COMPLEX
++# define _LNUM1 "complex "
++#else
++# define _LNUM1 ""
++#endif
++#ifdef LNUM_DOUBLE
++# define _LNUM2 "double"
++#elif defined(LNUM_FLOAT)
++# define _LNUM2 "float"
++#elif defined(LNUM_LDOUBLE)
++# define _LNUM2 "ldouble"
++#endif
++#ifdef LNUM_INT32
++# define _LNUM3 "int32"
++#elif defined(LNUM_INT64)
++# define _LNUM3 "int64"
++#elif defined(LNUM_INT16)
++# define _LNUM3 "int16"
++#endif
++#define LUA_LNUM _LNUM1 _LNUM2 " " _LNUM3
++
++/*
++** LUA_NUMBER is the type of floating point number in Lua
++** LUA_NUMBER_SCAN is the format for reading numbers.
++** LUA_NUMBER_FMT is the format for writing numbers.
++*/
++#ifdef LNUM_FLOAT
++# define LUA_NUMBER float
++# define LUA_NUMBER_SCAN "%f"
++# define LUA_NUMBER_FMT "%g"
++#elif (defined LNUM_DOUBLE)
++# define LUA_NUMBER double
++# define LUA_NUMBER_SCAN "%lf"
++# define LUA_NUMBER_FMT "%.14g"
++#elif (defined LNUM_LDOUBLE)
++# define LUA_NUMBER long double
++# define LUA_NUMBER_SCAN "%Lg"
++# define LUA_NUMBER_FMT "%.20Lg"
++#endif
++
++
++/*
++** LUAI_MAXNUMBER2STR: size of a buffer fitting any number->string result.
++**
++** double: 24 (sign, x.xxxxxxxxxxxxxxe+nnnn, and \0)
++** int64: 21 (19 digits, sign, and \0)
++** long double: 43 for 128-bit (sign, x.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe+nnnn, and \0)
++** 30 for 80-bit (sign, x.xxxxxxxxxxxxxxxxxxxxe+nnnn, and \0)
++*/
++#ifdef LNUM_LDOUBLE
++# define _LUAI_MN2S 44
++#else
++# define _LUAI_MN2S 24
++#endif
++
++#ifdef LNUM_COMPLEX
++# define LUAI_MAXNUMBER2STR (2*_LUAI_MN2S)
++#else
++# define LUAI_MAXNUMBER2STR _LUAI_MN2S
++#endif
++
++/*
++** LUA_INTEGER is the integer type used by lua_pushinteger/lua_tointeger/lua_isinteger.
++** LUA_INTEGER_SCAN is the format for reading integers
++** LUA_INTEGER_FMT is the format for writing integers
++**
++** Note: Visual C++ 2005 does not have 'strtoull()', use '_strtoui64()' instead.
++*/
++#ifdef LNUM_INT32
++# if LUAI_BITSINT > 16
++# define LUA_INTEGER int
++# define LUA_INTEGER_SCAN "%d"
++# define LUA_INTEGER_FMT "%d"
++# else
++/* Note: 'LUA_INTEGER' being 'ptrdiff_t' (as in Lua 5.1) causes problems with
++ * 'printf()' operations. Also 'unsigned ptrdiff_t' is invalid.
++ */
++# define LUA_INTEGER long
++# define LUA_INTEGER_SCAN "%ld"
++# define LUA_INTEGER_FMT "%ld"
++# endif
++# define LUA_INTEGER_MAX 0x7FFFFFFF /* 2^31-1 */
++/* */
++#elif defined(LNUM_INT64)
++# define LUA_INTEGER long long
++# ifdef _MSC_VER
++# define lua_str2ul _strtoui64
++# else
++# define lua_str2ul strtoull
++# endif
++# define LUA_INTEGER_SCAN "%lld"
++# define LUA_INTEGER_FMT "%lld"
++# define LUA_INTEGER_MAX 0x7fffffffffffffffLL /* 2^63-1 */
++# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX - 1LL) /* -2^63 */
++/* */
++#elif defined(LNUM_INT16)
++# if LUAI_BITSINT > 16
++# define LUA_INTEGER short
++# define LUA_INTEGER_SCAN "%hd"
++# define LUA_INTEGER_FMT "%hd"
++# else
++# define LUA_INTEGER int
++# define LUA_INTEGER_SCAN "%d"
++# define LUA_INTEGER_FMT "%d"
++# endif
++# define LUA_INTEGER_MAX 0x7FFF /* 2^16-1 */
++#endif
++
++#ifndef lua_str2ul
++# define lua_str2ul (unsigned LUA_INTEGER)strtoul
++#endif
++#ifndef LUA_INTEGER_MIN
++# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
++#endif
++
++/*
++@@ lua_number2int is a macro to convert lua_Number to int.
++@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
++** CHANGE them if you know a faster way to convert a lua_Number to
++** int (with any rounding method and without throwing errors) in your
++** system. In Pentium machines, a naive typecast from double to int
++** in C is extremely slow, so any alternative is worth trying.
++*/
++
++/* On a Pentium, resort to a trick */
++#if defined(LNUM_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
++ (defined(__i386) || defined (_M_IX86) || defined(__i386__))
++
++/* On a Microsoft compiler, use assembler */
++# if defined(_MSC_VER)
++# define lua_number2int(i,d) __asm fld d __asm fistp i
++# else
++
++/* the next trick should work on any Pentium, but sometimes clashes
++ with a DirectX idiosyncrasy */
++union luai_Cast { double l_d; long l_l; };
++# define lua_number2int(i,d) \
++ { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
++# endif
++
++# ifndef LNUM_INT64
++# define lua_number2integer lua_number2int
++# endif
++
++/* this option always works, but may be slow */
++#else
++# define lua_number2int(i,d) ((i)=(int)(d))
++#endif
++
++/* Note: Some compilers (OS X gcc 4.0?) may choke on double->long long conversion
++ * since it can lose precision. Others do require 'long long' there.
++ */
++#ifndef lua_number2integer
++# define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
++#endif
++
++/*
++** 'luai_abs()' to give absolute value of 'lua_Integer'
++*/
++#ifdef LNUM_INT32
++# define luai_abs abs
++#elif defined(LNUM_INT64) && (__STDC_VERSION__ >= 199901L)
++# define luai_abs llabs
++#else
++# define luai_abs(v) ((v) >= 0 ? (v) : -(v))
++#endif
++
++/*
++** LUAI_UACNUMBER is the result of an 'usual argument conversion' over a number.
++** LUAI_UACINTEGER the same, over an integer.
++*/
++#define LUAI_UACNUMBER double
++#define LUAI_UACINTEGER long
++
++/* ANSI C only has math funcs for 'double. C99 required for float and long double
++ * variants.
++ */
++#ifdef LNUM_DOUBLE
++# define _LF(name) name
++#elif defined(LNUM_FLOAT)
++# define _LF(name) name ## f
++#elif defined(LNUM_LDOUBLE)
++# define _LF(name) name ## l
++#endif
++
++#endif
++
+--- a/src/lobject.c
++++ b/src/lobject.c
+@@ -21,7 +21,8 @@
+ #include "lstate.h"
+ #include "lstring.h"
+ #include "lvm.h"
+-
++#include "llex.h"
++#include "lnum.h"
+
+
+ const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
+@@ -70,12 +71,31 @@ int luaO_log2 (unsigned int x) {
+
+
+ int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
+- if (ttype(t1) != ttype(t2)) return 0;
++ if (!ttype_ext_same(t1,t2)) return 0;
+ else switch (ttype(t1)) {
+ case LUA_TNIL:
+ return 1;
++ case LUA_TINT:
++ if (ttype(t2)==LUA_TINT)
++ return ivalue(t1) == ivalue(t2);
++ else { /* t1:int, t2:num */
++#ifdef LNUM_COMPLEX
++ if (nvalue_img_fast(t2) != 0) return 0;
++#endif
++ /* Avoid doing accuracy losing cast, if possible. */
++ lua_Integer tmp;
++ if (tt_integer_valued(t2,&tmp))
++ return ivalue(t1) == tmp;
++ else
++ return luai_numeq( cast_num(ivalue(t1)), nvalue_fast(t2) );
++ }
+ case LUA_TNUMBER:
+- return luai_numeq(nvalue(t1), nvalue(t2));
++ if (ttype(t2)==LUA_TINT)
++ return luaO_rawequalObj(t2, t1); /* swap LUA_TINT to left */
++#ifdef LNUM_COMPLEX
++ if (!luai_numeq(nvalue_img_fast(t1), nvalue_img_fast(t2))) return 0;
++#endif
++ return luai_numeq(nvalue_fast(t1), nvalue_fast(t2));
+ case LUA_TBOOLEAN:
+ return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
+ case LUA_TLIGHTUSERDATA:
+@@ -86,21 +106,6 @@ int luaO_rawequalObj (const TValue *t1,
+ }
+ }
+
+-
+-int luaO_str2d (const char *s, lua_Number *result) {
+- char *endptr;
+- *result = lua_str2number(s, &endptr);
+- if (endptr == s) return 0; /* conversion failed */
+- if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
+- *result = cast_num(strtoul(s, &endptr, 16));
+- if (*endptr == '\0') return 1; /* most common case */
+- while (isspace(cast(unsigned char, *endptr))) endptr++;
+- if (*endptr != '\0') return 0; /* invalid trailing characters? */
+- return 1;
+-}
+-
+-
+-
+ static void pushstr (lua_State *L, const char *str) {
+ setsvalue2s(L, L->top, luaS_new(L, str));
+ incr_top(L);
+@@ -131,7 +136,11 @@ const char *luaO_pushvfstring (lua_State
+ break;
+ }
+ case 'd': {
+- setnvalue(L->top, cast_num(va_arg(argp, int)));
++ /* This is tricky for 64-bit integers; maybe they even cannot be
++ * supported on all compilers; depends on the conversions applied to
++ * variable argument lists. TBD: test!
++ */
++ setivalue(L->top, (lua_Integer) va_arg(argp, l_uacInteger));
+ incr_top(L);
+ break;
+ }
+@@ -212,3 +221,4 @@ void luaO_chunkid (char *out, const char
+ }
+ }
+ }
++
+--- a/src/lobject.h
++++ b/src/lobject.h
+@@ -17,7 +17,11 @@
+
+
+ /* tags for values visible from Lua */
+-#define LAST_TAG LUA_TTHREAD
++#if LUA_TINT > LUA_TTHREAD
++# define LAST_TAG LUA_TINT
++#else
++# define LAST_TAG LUA_TTHREAD
++#endif
+
+ #define NUM_TAGS (LAST_TAG+1)
+
+@@ -59,7 +63,12 @@ typedef struct GCheader {
+ typedef union {
+ GCObject *gc;
+ void *p;
++#ifdef LNUM_COMPLEX
++ lua_Complex n;
++#else
+ lua_Number n;
++#endif
++ lua_Integer i;
+ int b;
+ } Value;
+
+@@ -77,7 +86,11 @@ typedef struct lua_TValue {
+
+ /* Macros to test type */
+ #define ttisnil(o) (ttype(o) == LUA_TNIL)
+-#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
++#define ttisint(o) (ttype(o) == LUA_TINT)
++#define ttisnumber(o) ((ttype(o) == LUA_TINT) || (ttype(o) == LUA_TNUMBER))
++#ifdef LNUM_COMPLEX
++# define ttiscomplex(o) ((ttype(o) == LUA_TNUMBER) && (nvalue_img_fast(o)!=0))
++#endif
+ #define ttisstring(o) (ttype(o) == LUA_TSTRING)
+ #define ttistable(o) (ttype(o) == LUA_TTABLE)
+ #define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
+@@ -90,7 +103,25 @@ typedef struct lua_TValue {
+ #define ttype(o) ((o)->tt)
+ #define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
+ #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
+-#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
++
++#define ttype_ext(o) ( ttype(o) == LUA_TINT ? LUA_TNUMBER : ttype(o) )
++#define ttype_ext_same(o1,o2) ( (ttype(o1)==ttype(o2)) || (ttisnumber(o1) && ttisnumber(o2)) )
++
++/* '_fast' variants are for cases where 'ttype(o)' is known to be LUA_TNUMBER.
++ */
++#ifdef LNUM_COMPLEX
++# define nvalue_complex_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n )
++# define nvalue_fast(o) ( _LF(creal) ( nvalue_complex_fast(o) ) )
++# define nvalue_img_fast(o) ( _LF(cimag) ( nvalue_complex_fast(o) ) )
++# define nvalue_complex(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? (o)->value.i : (o)->value.n )
++# define nvalue_img(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? 0 : _LF(cimag)( (o)->value.n ) )
++# define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : _LF(creal)((o)->value.n) )
++#else
++# define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : (o)->value.n )
++# define nvalue_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n )
++#endif
++#define ivalue(o) check_exp( ttype(o)==LUA_TINT, (o)->value.i )
++
+ #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
+ #define tsvalue(o) (&rawtsvalue(o)->tsv)
+ #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
+@@ -116,8 +147,27 @@ typedef struct lua_TValue {
+ /* Macros to set values */
+ #define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
+
+-#define setnvalue(obj,x) \
+- { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
++/* Must not have side effects, 'x' may be expression.
++*/
++#define setivalue(obj,x) \
++ { TValue *i_o=(obj); i_o->value.i=(x); i_o->tt=LUA_TINT; }
++
++# define setnvalue(obj,x) \
++ { TValue *i_o=(obj); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; }
++
++/* Note: Complex always has "inline", both are C99.
++*/
++#ifdef LNUM_COMPLEX
++ static inline void setnvalue_complex_fast( TValue *obj, lua_Complex x ) {
++ lua_assert( _LF(cimag)(x) != 0 );
++ obj->value.n= x; obj->tt= LUA_TNUMBER;
++ }
++ static inline void setnvalue_complex( TValue *obj, lua_Complex x ) {
++ if (_LF(cimag)(x) == 0) { setnvalue(obj, _LF(creal)(x)); }
++ else { obj->value.n= x; obj->tt= LUA_TNUMBER; }
++ }
++#endif
++
+
+ #define setpvalue(obj,x) \
+ { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
+@@ -155,9 +205,6 @@ typedef struct lua_TValue {
+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
+ checkliveness(G(L),i_o); }
+
+-
+-
+-
+ #define setobj(L,obj1,obj2) \
+ { const TValue *o2=(obj2); TValue *o1=(obj1); \
+ o1->value = o2->value; o1->tt=o2->tt; \
+@@ -185,8 +232,11 @@ typedef struct lua_TValue {
+
+ #define setttype(obj, tt) (ttype(obj) = (tt))
+
+-
+-#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
++#if LUA_TINT >= LUA_TSTRING
++# define iscollectable(o) ((ttype(o) >= LUA_TSTRING) && (ttype(o) != LUA_TINT))
++#else
++# define iscollectable(o) (ttype(o) >= LUA_TSTRING)
++#endif
+
+
+
+@@ -370,12 +420,10 @@ LUAI_FUNC int luaO_log2 (unsigned int x)
+ LUAI_FUNC int luaO_int2fb (unsigned int x);
+ LUAI_FUNC int luaO_fb2int (int x);
+ LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
+-LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
+ LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
+ va_list argp);
+ LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
+ LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
+
+-
+ #endif
+
+--- a/src/loslib.c
++++ b/src/loslib.c
+@@ -186,15 +186,30 @@ static int os_time (lua_State *L) {
+ }
+ if (t == (time_t)(-1))
+ lua_pushnil(L);
+- else
+- lua_pushnumber(L, (lua_Number)t);
++ else {
++ /* On float systems the pushed value must be an integer, NOT a number.
++ * Otherwise, accuracy is lost in the time_t->float conversion.
++ */
++#ifdef LNUM_FLOAT
++ lua_pushinteger(L, (lua_Integer) t);
++#else
++ lua_pushnumber(L, (lua_Number) t);
++#endif
++ }
+ return 1;
+ }
+
+
+ static int os_difftime (lua_State *L) {
++#ifdef LNUM_FLOAT
++ lua_Integer i= (lua_Integer)
++ difftime( (time_t)(luaL_checkinteger(L, 1)),
++ (time_t)(luaL_optinteger(L, 2, 0)));
++ lua_pushinteger(L, i);
++#else
+ lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
+ (time_t)(luaL_optnumber(L, 2, 0))));
++#endif
+ return 1;
+ }
+
+--- a/src/lparser.c
++++ b/src/lparser.c
+@@ -33,7 +33,6 @@
+
+ #define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
+
+-
+ /*
+ ** nodes for block list (list of active blocks)
+ */
+@@ -72,7 +71,7 @@ static void errorlimit (FuncState *fs, i
+ const char *msg = (fs->f->linedefined == 0) ?
+ luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
+ luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
+- fs->f->linedefined, limit, what);
++ (fs->f->linedefined), limit, what);
+ luaX_lexerror(fs->ls, msg, 0);
+ }
+
+@@ -733,6 +732,18 @@ static void simpleexp (LexState *ls, exp
+ v->u.nval = ls->t.seminfo.r;
+ break;
+ }
++ case TK_INT: {
++ init_exp(v, VKINT, 0);
++ v->u.ival = ls->t.seminfo.i;
++ break;
++ }
++#ifdef LNUM_COMPLEX
++ case TK_NUMBER2: {
++ init_exp(v, VKNUM2, 0);
++ v->u.nval = ls->t.seminfo.r;
++ break;
++ }
++#endif
+ case TK_STRING: {
+ codestring(ls, v, ls->t.seminfo.ts);
+ break;
+@@ -1079,7 +1090,7 @@ static void fornum (LexState *ls, TStrin
+ if (testnext(ls, ','))
+ exp1(ls); /* optional step */
+ else { /* default step = 1 */
+- luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
++ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_integerK(fs, 1));
+ luaK_reserveregs(fs, 1);
+ }
+ forbody(ls, base, line, 1, 1);
+--- a/src/lparser.h
++++ b/src/lparser.h
+@@ -31,7 +31,11 @@ typedef enum {
+ VRELOCABLE, /* info = instruction pc */
+ VNONRELOC, /* info = result register */
+ VCALL, /* info = instruction pc */
+- VVARARG /* info = instruction pc */
++ VVARARG, /* info = instruction pc */
++ VKINT /* ival = integer value */
++#ifdef LNUM_COMPLEX
++ ,VKNUM2 /* nval = imaginary value */
++#endif
+ } expkind;
+
+ typedef struct expdesc {
+@@ -39,6 +43,7 @@ typedef struct expdesc {
+ union {
+ struct { int info, aux; } s;
+ lua_Number nval;
++ lua_Integer ival;
+ } u;
+ int t; /* patch list of `exit when true' */
+ int f; /* patch list of `exit when false' */
+--- a/src/lstrlib.c
++++ b/src/lstrlib.c
+@@ -43,8 +43,8 @@ static ptrdiff_t posrelat (ptrdiff_t pos
+ static int str_sub (lua_State *L) {
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+- ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
+- ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
++ ptrdiff_t start = posrelat(luaL_checkint32(L, 2), l);
++ ptrdiff_t end = posrelat(luaL_optint32(L, 3, -1), l);
+ if (start < 1) start = 1;
+ if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
+ if (start <= end)
+@@ -106,8 +106,8 @@ static int str_rep (lua_State *L) {
+ static int str_byte (lua_State *L) {
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+- ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
+- ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
++ ptrdiff_t posi = posrelat(luaL_optint32(L, 2, 1), l);
++ ptrdiff_t pose = posrelat(luaL_optint32(L, 3, posi), l);
+ int n, i;
+ if (posi <= 0) posi = 1;
+ if ((size_t)pose > l) pose = l;
+@@ -496,7 +496,7 @@ static int str_find_aux (lua_State *L, i
+ size_t l1, l2;
+ const char *s = luaL_checklstring(L, 1, &l1);
+ const char *p = luaL_checklstring(L, 2, &l2);
+- ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
++ ptrdiff_t init = posrelat(luaL_optint32(L, 3, 1), l1) - 1;
+ if (init < 0) init = 0;
+ else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
+ if (find && (lua_toboolean(L, 4) || /* explicit request? */
+@@ -690,7 +690,7 @@ static int str_gsub (lua_State *L) {
+ ** maximum size of each format specification (such as '%-099.99d')
+ ** (+10 accounts for %99.99x plus margin of error)
+ */
+-#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
++#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTEGER_FMT)-2 + 10)
+
+
+ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
+@@ -747,9 +747,9 @@ static const char *scanformat (lua_State
+ static void addintlen (char *form) {
+ size_t l = strlen(form);
+ char spec = form[l - 1];
+- strcpy(form + l - 1, LUA_INTFRMLEN);
+- form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
+- form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
++ const char *tmp= LUA_INTEGER_FMT; /* "%lld" or "%ld" */
++ strcpy(form + l - 1, tmp+1);
++ form[l + sizeof(LUA_INTEGER_FMT)-4] = spec;
+ }
+
+
+@@ -779,12 +779,12 @@ static int str_format (lua_State *L) {
+ }
+ case 'd': case 'i': {
+ addintlen(form);
+- sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
++ sprintf(buff, form, luaL_checkinteger(L, arg));
+ break;
+ }
+ case 'o': case 'u': case 'x': case 'X': {
+ addintlen(form);
+- sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
++ sprintf(buff, form, (unsigned LUA_INTEGER)luaL_checkinteger(L, arg));
+ break;
+ }
+ case 'e': case 'E': case 'f':
+--- a/src/ltable.c
++++ b/src/ltable.c
+@@ -33,6 +33,7 @@
+ #include "lobject.h"
+ #include "lstate.h"
+ #include "ltable.h"
++#include "lnum.h"
+
+
+ /*
+@@ -51,25 +52,15 @@
+
+ #define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
+ #define hashboolean(t,p) hashpow2(t, p)
+-
++#define hashint(t,i) hashpow2(t,i)
+
+ /*
+ ** for some types, it is better to avoid modulus by power of 2, as
+ ** they tend to have many 2 factors.
+ */
+ #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
+-
+-
+ #define hashpointer(t,p) hashmod(t, IntPoint(p))
+
+-
+-/*
+-** number of ints inside a lua_Number
+-*/
+-#define numints cast_int(sizeof(lua_Number)/sizeof(int))
+-
+-
+-
+ #define dummynode (&dummynode_)
+
+ static const Node dummynode_ = {
+@@ -80,27 +71,46 @@ static const Node dummynode_ = {
+
+ /*
+ ** hash for lua_Numbers
++**
++** for non-complex modes, never called with 'lua_Integer' value range (s.a. 0)
+ */
+ static Node *hashnum (const Table *t, lua_Number n) {
+- unsigned int a[numints];
+- int i;
+- if (luai_numeq(n, 0)) /* avoid problems with -0 */
+- return gnode(t, 0);
+- memcpy(a, &n, sizeof(a));
+- for (i = 1; i < numints; i++) a[0] += a[i];
+- return hashmod(t, a[0]);
++ const unsigned int *p= cast(const unsigned int *,&n);
++ unsigned int sum= *p;
++ unsigned int m= sizeof(lua_Number)/sizeof(int);
++ unsigned int i;
++ /* OS X Intel has 'm'==4 and gives "Bus error" if the last integer of
++ * 'n' is read; the actual size of long double is only 80 bits = 10 bytes.
++ * Linux x86 has 'm'==3, and does not require reduction.
++ */
++#if defined(LNUM_LDOUBLE) && defined(__i386__)
++ if (m>3) m--;
++#endif
++ for (i = 1; i < m; i++) sum += p[i];
++ return hashmod(t, sum);
+ }
+
+
+-
+ /*
+ ** returns the `main' position of an element in a table (that is, the index
+ ** of its hash value)
++**
++** Floating point numbers with integer value give the hash position of the
++** integer (so they use the same table position).
+ */
+ static Node *mainposition (const Table *t, const TValue *key) {
++ lua_Integer i;
+ switch (ttype(key)) {
+ case LUA_TNUMBER:
+- return hashnum(t, nvalue(key));
++ if (tt_integer_valued(key,&i))
++ return hashint(t, i);
++#ifdef LNUM_COMPLEX
++ if (nvalue_img_fast(key)!=0 && luai_numeq(nvalue_fast(key),0))
++ return gnode(t, 0); /* 0 and -0 to give same hash */
++#endif
++ return hashnum(t, nvalue_fast(key));
++ case LUA_TINT:
++ return hashint(t, ivalue(key));
+ case LUA_TSTRING:
+ return hashstr(t, rawtsvalue(key));
+ case LUA_TBOOLEAN:
+@@ -116,16 +126,20 @@ static Node *mainposition (const Table *
+ /*
+ ** returns the index for `key' if `key' is an appropriate key to live in
+ ** the array part of the table, -1 otherwise.
++**
++** Anything <=0 is taken as not being in the array part.
+ */
+-static int arrayindex (const TValue *key) {
+- if (ttisnumber(key)) {
+- lua_Number n = nvalue(key);
+- int k;
+- lua_number2int(k, n);
+- if (luai_numeq(cast_num(k), n))
+- return k;
++static int arrayindex (const TValue *key, int max) {
++ lua_Integer k;
++ switch( ttype(key) ) {
++ case LUA_TINT:
++ k= ivalue(key); break;
++ case LUA_TNUMBER:
++ if (tt_integer_valued(key,&k)) break;
++ default:
++ return -1; /* not to be used as array index */
+ }
+- return -1; /* `key' did not match some condition */
++ return ((k>0) && (k <= max)) ? cast_int(k) : -1;
+ }
+
+
+@@ -137,8 +151,8 @@ static int arrayindex (const TValue *key
+ static int findindex (lua_State *L, Table *t, StkId key) {
+ int i;
+ if (ttisnil(key)) return -1; /* first iteration */
+- i = arrayindex(key);
+- if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
++ i = arrayindex(key, t->sizearray);
++ if (i>0) /* inside array part? */
+ return i-1; /* yes; that's the index (corrected to C) */
+ else {
+ Node *n = mainposition(t, key);
+@@ -163,7 +177,7 @@ int luaH_next (lua_State *L, Table *t, S
+ int i = findindex(L, t, key); /* find original element */
+ for (i++; i < t->sizearray; i++) { /* try first array part */
+ if (!ttisnil(&t->array[i])) { /* a non-nil value? */
+- setnvalue(key, cast_num(i+1));
++ setivalue(key, i+1);
+ setobj2s(L, key+1, &t->array[i]);
+ return 1;
+ }
+@@ -209,8 +223,8 @@ static int computesizes (int nums[], int
+
+
+ static int countint (const TValue *key, int *nums) {
+- int k = arrayindex(key);
+- if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
++ int k = arrayindex(key,MAXASIZE);
++ if (k>0) { /* appropriate array index? */
+ nums[ceillog2(k)]++; /* count as such */
+ return 1;
+ }
+@@ -308,7 +322,7 @@ static void resize (lua_State *L, Table
+ /* re-insert elements from vanishing slice */
+ for (i=nasize; i<oldasize; i++) {
+ if (!ttisnil(&t->array[i]))
+- setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
++ setobjt2t(L, luaH_setint(L, t, i+1), &t->array[i]);
+ }
+ /* shrink array */
+ luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
+@@ -409,7 +423,9 @@ static TValue *newkey (lua_State *L, Tab
+ othern = mainposition(t, key2tval(mp));
+ if (othern != mp) { /* is colliding node out of its main position? */
+ /* yes; move colliding node into free position */
+- while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
++ while (gnext(othern) != mp) {
++ othern = gnext(othern); /* find previous */
++ }
+ gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
+ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
+ gnext(mp) = NULL; /* now `mp' is free */
+@@ -432,17 +448,18 @@ static TValue *newkey (lua_State *L, Tab
+ /*
+ ** search function for integers
+ */
+-const TValue *luaH_getnum (Table *t, int key) {
++const TValue *luaH_getint (Table *t, lua_Integer key) {
+ /* (1 <= key && key <= t->sizearray) */
+ if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
+ return &t->array[key-1];
+ else {
+- lua_Number nk = cast_num(key);
+- Node *n = hashnum(t, nk);
++ Node *n = hashint(t, key);
+ do { /* check whether `key' is somewhere in the chain */
+- if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
++ if (ttisint(gkey(n)) && (ivalue(gkey(n)) == key)) {
+ return gval(n); /* that's it */
+- else n = gnext(n);
++ } else {
++ n = gnext(n);
++ }
+ } while (n);
+ return luaO_nilobject;
+ }
+@@ -470,14 +487,12 @@ const TValue *luaH_get (Table *t, const
+ switch (ttype(key)) {
+ case LUA_TNIL: return luaO_nilobject;
+ case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
++ case LUA_TINT: return luaH_getint(t, ivalue(key));
+ case LUA_TNUMBER: {
+- int k;
+- lua_Number n = nvalue(key);
+- lua_number2int(k, n);
+- if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
+- return luaH_getnum(t, k); /* use specialized version */
+- /* else go through */
+- }
++ lua_Integer i;
++ if (tt_integer_valued(key,&i))
++ return luaH_getint(t,i);
++ } /* pass through */
+ default: {
+ Node *n = mainposition(t, key);
+ do { /* check whether `key' is somewhere in the chain */
+@@ -498,20 +513,25 @@ TValue *luaH_set (lua_State *L, Table *t
+ return cast(TValue *, p);
+ else {
+ if (ttisnil(key)) luaG_runerror(L, "table index is nil");
+- else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
+- luaG_runerror(L, "table index is NaN");
++ else if (ttype(key)==LUA_TNUMBER) {
++ lua_Integer k;
++ if (luai_numisnan(nvalue_fast(key)))
++ luaG_runerror(L, "table index is NaN");
++ if (tt_integer_valued(key,&k))
++ return luaH_setint(L, t, k);
++ }
+ return newkey(L, t, key);
+ }
+ }
+
+
+-TValue *luaH_setnum (lua_State *L, Table *t, int key) {
+- const TValue *p = luaH_getnum(t, key);
++TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key) {
++ const TValue *p = luaH_getint(t, key);
+ if (p != luaO_nilobject)
+ return cast(TValue *, p);
+ else {
+ TValue k;
+- setnvalue(&k, cast_num(key));
++ setivalue(&k, key);
+ return newkey(L, t, &k);
+ }
+ }
+@@ -533,20 +553,21 @@ static int unbound_search (Table *t, uns
+ unsigned int i = j; /* i is zero or a present index */
+ j++;
+ /* find `i' and `j' such that i is present and j is not */
+- while (!ttisnil(luaH_getnum(t, j))) {
++ while (!ttisnil(luaH_getint(t, j))) {
+ i = j;
+ j *= 2;
+ if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
+ /* table was built with bad purposes: resort to linear search */
+- i = 1;
+- while (!ttisnil(luaH_getnum(t, i))) i++;
+- return i - 1;
++ for( i = 1; i<MAX_INT+1; i++ ) {
++ if (ttisnil(luaH_getint(t, i))) break;
++ }
++ return i - 1; /* up to MAX_INT */
+ }
+ }
+ /* now do a binary search between them */
+ while (j - i > 1) {
+ unsigned int m = (i+j)/2;
+- if (ttisnil(luaH_getnum(t, m))) j = m;
++ if (ttisnil(luaH_getint(t, m))) j = m;
+ else i = m;
+ }
+ return i;
+--- a/src/ltable.h
++++ b/src/ltable.h
+@@ -18,8 +18,8 @@
+ #define key2tval(n) (&(n)->i_key.tvk)
+
+
+-LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
+-LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
++LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
++LUAI_FUNC TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key);
+ LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
+ LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
+ LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
+--- a/src/ltm.c
++++ b/src/ltm.c
+@@ -19,7 +19,6 @@
+ #include "ltm.h"
+
+
+-
+ const char *const luaT_typenames[] = {
+ "nil", "boolean", "userdata", "number",
+ "string", "table", "function", "userdata", "thread",
+@@ -67,6 +66,9 @@ const TValue *luaT_gettmbyobj (lua_State
+ case LUA_TUSERDATA:
+ mt = uvalue(o)->metatable;
+ break;
++ case LUA_TINT:
++ mt = G(L)->mt[LUA_TNUMBER];
++ break;
+ default:
+ mt = G(L)->mt[ttype(o)];
+ }
+--- a/src/lua.c
++++ b/src/lua.c
+@@ -16,7 +16,7 @@
+
+ #include "lauxlib.h"
+ #include "lualib.h"
+-
++#include "llimits.h"
+
+
+ static lua_State *globalL = NULL;
+@@ -382,6 +382,15 @@ int main (int argc, char **argv) {
+ l_message(argv[0], "cannot create state: not enough memory");
+ return EXIT_FAILURE;
+ }
++ /* Checking 'sizeof(lua_Integer)' cannot be made in preprocessor on all compilers.
++ */
++#ifdef LNUM_INT16
++ lua_assert( sizeof(lua_Integer) == 2 );
++#elif defined(LNUM_INT32)
++ lua_assert( sizeof(lua_Integer) == 4 );
++#elif defined(LNUM_INT64)
++ lua_assert( sizeof(lua_Integer) == 8 );
++#endif
+ s.argc = argc;
+ s.argv = argv;
+ status = lua_cpcall(L, &pmain, &s);
+--- a/src/lua.h
++++ b/src/lua.h
+@@ -19,7 +19,7 @@
+ #define LUA_VERSION "Lua 5.1"
+ #define LUA_RELEASE "Lua 5.1.5"
+ #define LUA_VERSION_NUM 501
+-#define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio"
++#define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio" " (" LUA_LNUM ")"
+ #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
+
+
+@@ -71,6 +71,16 @@ typedef void * (*lua_Alloc) (void *ud, v
+ */
+ #define LUA_TNONE (-1)
+
++/* LUA_TINT is an internal type, not visible to applications. There are three
++ * potential values where it can be tweaked to (code autoadjusts to these):
++ *
++ * -2: not 'usual' type value; good since 'LUA_TINT' is not part of the API
++ * LUA_TNUMBER+1: shifts other type values upwards, breaking binary compatibility
++ * not acceptable for 5.1, maybe 5.2 onwards?
++ * 9: greater than existing (5.1) type values.
++*/
++#define LUA_TINT (-2)
++
+ #define LUA_TNIL 0
+ #define LUA_TBOOLEAN 1
+ #define LUA_TLIGHTUSERDATA 2
+@@ -139,6 +149,8 @@ LUA_API int (lua_isuserdata)
+ LUA_API int (lua_type) (lua_State *L, int idx);
+ LUA_API const char *(lua_typename) (lua_State *L, int tp);
+
++LUA_API int (lua_isinteger) (lua_State *L, int idx);
++
+ LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
+ LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
+ LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
+@@ -244,6 +256,19 @@ LUA_API lua_Alloc (lua_getallocf) (lua_S
+ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
+
+
++/*
++* It is unnecessary to break Lua C API 'lua_tonumber()' compatibility, just
++* because the Lua number type is complex. Most C modules would use scalars
++* only. We'll introduce new 'lua_tocomplex' and 'lua_pushcomplex' for when
++* the module really wants to use them.
++*/
++#ifdef LNUM_COMPLEX
++ #include <complex.h>
++ typedef LUA_NUMBER complex lua_Complex;
++ LUA_API lua_Complex (lua_tocomplex) (lua_State *L, int idx);
++ LUA_API void (lua_pushcomplex) (lua_State *L, lua_Complex v);
++#endif
++
+
+ /*
+ ** ===============================================================
+@@ -268,7 +293,12 @@ LUA_API void lua_setallocf (lua_State *L
+ #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
+ #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
+ #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
+-#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
++
++#if LUA_TINT < 0
++# define lua_isnoneornil(L, n) ( (lua_type(L,(n)) <= 0) && (lua_type(L,(n)) != LUA_TINT) )
++#else
++# define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
++#endif
+
+ #define lua_pushliteral(L, s) \
+ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
+@@ -386,3 +416,4 @@ struct lua_Debug {
+
+
+ #endif
++
+--- a/src/luaconf.h
++++ b/src/luaconf.h
+@@ -10,7 +10,9 @@
+
+ #include <limits.h>
+ #include <stddef.h>
+-
++#ifdef lua_assert
++# include <assert.h>
++#endif
+
+ /*
+ ** ==================================================================
+@@ -136,14 +138,38 @@
+
+
+ /*
+-@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
+-** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
+-** machines, ptrdiff_t gives a good choice between int or long.)
++@@ LUAI_BITSINT defines the number of bits in an int.
++** CHANGE here if Lua cannot automatically detect the number of bits of
++** your machine. Probably you do not need to change this.
+ */
+-#define LUA_INTEGER ptrdiff_t
++/* avoid overflows in comparison */
++#if INT_MAX-20 < 32760
++#define LUAI_BITSINT 16
++#elif INT_MAX > 2147483640L
++/* int has at least 32 bits */
++#define LUAI_BITSINT 32
++#else
++#error "you must define LUA_BITSINT with number of bits in an integer"
++#endif
+
+
+ /*
++@@ LNUM_DOUBLE | LNUM_FLOAT | LNUM_LDOUBLE: Generic Lua number mode
++@@ LNUM_INT32 | LNUM_INT64: Integer type
++@@ LNUM_COMPLEX: Define for using 'a+bi' numbers
++@@
++@@ You can combine LNUM_xxx but only one of each group. I.e. '-DLNUM_FLOAT
++@@ -DLNUM_INT32 -DLNUM_COMPLEX' gives float range complex numbers, with
++@@ 32-bit scalar integer range optimized.
++**
++** These are kept in a separate configuration file mainly for ease of patching
++** (can be changed if integerated to Lua proper).
++*/
++/*#define LNUM_DOUBLE*/
++/*#define LNUM_INT32*/
++#include "lnum_config.h"
++
++/*
+ @@ LUA_API is a mark for all core API functions.
+ @@ LUALIB_API is a mark for all standard library functions.
+ ** CHANGE them if you need to define those functions in some special way.
+@@ -383,22 +409,6 @@
+
+
+ /*
+-@@ LUAI_BITSINT defines the number of bits in an int.
+-** CHANGE here if Lua cannot automatically detect the number of bits of
+-** your machine. Probably you do not need to change this.
+-*/
+-/* avoid overflows in comparison */
+-#if INT_MAX-20 < 32760
+-#define LUAI_BITSINT 16
+-#elif INT_MAX > 2147483640L
+-/* int has at least 32 bits */
+-#define LUAI_BITSINT 32
+-#else
+-#error "you must define LUA_BITSINT with number of bits in an integer"
+-#endif
+-
+-
+-/*
+ @@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
+ @@ LUAI_INT32 is an signed integer with at least 32 bits.
+ @@ LUAI_UMEM is an unsigned integer big enough to count the total
+@@ -425,6 +435,15 @@
+ #define LUAI_MEM long
+ #endif
+
++/*
++@@ LUAI_BOOL carries 0 and nonzero (normally 1). It may be defined as 'char'
++** (to save memory), 'int' (for speed), 'bool' (for C++) or '_Bool' (C99)
++*/
++#ifdef __cplusplus
++# define LUAI_BOOL bool
++#else
++# define LUAI_BOOL int
++#endif
+
+ /*
+ @@ LUAI_MAXCALLS limits the number of nested calls.
+@@ -490,101 +509,6 @@
+ /* }================================================================== */
+
+
+-
+-
+-/*
+-** {==================================================================
+-@@ LUA_NUMBER is the type of numbers in Lua.
+-** CHANGE the following definitions only if you want to build Lua
+-** with a number type different from double. You may also need to
+-** change lua_number2int & lua_number2integer.
+-** ===================================================================
+-*/
+-
+-#define LUA_NUMBER_DOUBLE
+-#define LUA_NUMBER double
+-
+-/*
+-@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
+-@* over a number.
+-*/
+-#define LUAI_UACNUMBER double
+-
+-
+-/*
+-@@ LUA_NUMBER_SCAN is the format for reading numbers.
+-@@ LUA_NUMBER_FMT is the format for writing numbers.
+-@@ lua_number2str converts a number to a string.
+-@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
+-@@ lua_str2number converts a string to a number.
+-*/
+-#define LUA_NUMBER_SCAN "%lf"
+-#define LUA_NUMBER_FMT "%.14g"
+-#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
+-#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
+-#define lua_str2number(s,p) strtod((s), (p))
+-
+-
+-/*
+-@@ The luai_num* macros define the primitive operations over numbers.
+-*/
+-#if defined(LUA_CORE)
+-#include <math.h>
+-#define luai_numadd(a,b) ((a)+(b))
+-#define luai_numsub(a,b) ((a)-(b))
+-#define luai_nummul(a,b) ((a)*(b))
+-#define luai_numdiv(a,b) ((a)/(b))
+-#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
+-#define luai_numpow(a,b) (pow(a,b))
+-#define luai_numunm(a) (-(a))
+-#define luai_numeq(a,b) ((a)==(b))
+-#define luai_numlt(a,b) ((a)<(b))
+-#define luai_numle(a,b) ((a)<=(b))
+-#define luai_numisnan(a) (!luai_numeq((a), (a)))
+-#endif
+-
+-
+-/*
+-@@ lua_number2int is a macro to convert lua_Number to int.
+-@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
+-** CHANGE them if you know a faster way to convert a lua_Number to
+-** int (with any rounding method and without throwing errors) in your
+-** system. In Pentium machines, a naive typecast from double to int
+-** in C is extremely slow, so any alternative is worth trying.
+-*/
+-
+-/* On a Pentium, resort to a trick */
+-#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
+- (defined(__i386) || defined (_M_IX86) || defined(__i386__))
+-
+-/* On a Microsoft compiler, use assembler */
+-#if defined(_MSC_VER)
+-
+-#define lua_number2int(i,d) __asm fld d __asm fistp i
+-#define lua_number2integer(i,n) lua_number2int(i, n)
+-
+-/* the next trick should work on any Pentium, but sometimes clashes
+- with a DirectX idiosyncrasy */
+-#else
+-
+-union luai_Cast { double l_d; long l_l; };
+-#define lua_number2int(i,d) \
+- { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
+-#define lua_number2integer(i,n) lua_number2int(i, n)
+-
+-#endif
+-
+-
+-/* this option always works, but may be slow */
+-#else
+-#define lua_number2int(i,d) ((i)=(int)(d))
+-#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
+-
+-#endif
+-
+-/* }================================================================== */
+-
+-
+ /*
+ @@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
+ ** CHANGE it if your system requires alignments larger than double. (For
+@@ -728,28 +652,6 @@ union luai_Cast { double l_d; long l_l;
+ #define luai_userstateyield(L,n) ((void)L)
+
+
+-/*
+-@@ LUA_INTFRMLEN is the length modifier for integer conversions
+-@* in 'string.format'.
+-@@ LUA_INTFRM_T is the integer type correspoding to the previous length
+-@* modifier.
+-** CHANGE them if your system supports long long or does not support long.
+-*/
+-
+-#if defined(LUA_USELONGLONG)
+-
+-#define LUA_INTFRMLEN "ll"
+-#define LUA_INTFRM_T long long
+-
+-#else
+-
+-#define LUA_INTFRMLEN "l"
+-#define LUA_INTFRM_T long
+-
+-#endif
+-
+-
+-
+ /* =================================================================== */
+
+ /*
+--- a/src/lundump.c
++++ b/src/lundump.c
+@@ -73,6 +73,13 @@ static lua_Number LoadNumber(LoadState*
+ return x;
+ }
+
++static lua_Integer LoadInteger(LoadState* S)
++{
++ lua_Integer x;
++ LoadVar(S,x);
++ return x;
++}
++
+ static TString* LoadString(LoadState* S)
+ {
+ size_t size;
+@@ -119,6 +126,9 @@ static void LoadConstants(LoadState* S,
+ case LUA_TNUMBER:
+ setnvalue(o,LoadNumber(S));
+ break;
++ case LUA_TINT: /* Integer type saved in bytecode (see lcode.c) */
++ setivalue(o,LoadInteger(S));
++ break;
+ case LUA_TSTRING:
+ setsvalue2n(S->L,o,LoadString(S));
+ break;
+@@ -223,5 +233,22 @@ void luaU_header (char* h)
+ *h++=(char)sizeof(size_t);
+ *h++=(char)sizeof(Instruction);
+ *h++=(char)sizeof(lua_Number);
+- *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
++
++ /*
++ * Last byte of header (0/1 in unpatched Lua 5.1.3):
++ *
++ * 0: lua_Number is float or double, lua_Integer not used. (nonpatched only)
++ * 1: lua_Number is integer (nonpatched only)
++ *
++ * +2: LNUM_INT16: sizeof(lua_Integer)
++ * +4: LNUM_INT32: sizeof(lua_Integer)
++ * +8: LNUM_INT64: sizeof(lua_Integer)
++ *
++ * +0x80: LNUM_COMPLEX
++ */
++ *h++ = (char)(sizeof(lua_Integer)
++#ifdef LNUM_COMPLEX
++ | 0x80
++#endif
++ );
+ }
+--- a/src/lvm.c
++++ b/src/lvm.c
+@@ -25,22 +25,35 @@
+ #include "ltable.h"
+ #include "ltm.h"
+ #include "lvm.h"
+-
+-
++#include "llex.h"
++#include "lnum.h"
+
+ /* limit for table tag-method chains (to avoid loops) */
+ #define MAXTAGLOOP 100
+
+
+-const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
+- lua_Number num;
++/*
++ * If 'obj' is a string, it is tried to be interpreted as a number.
++ */
++const TValue *luaV_tonumber ( const TValue *obj, TValue *n) {
++ lua_Number d;
++ lua_Integer i;
++
+ if (ttisnumber(obj)) return obj;
+- if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
+- setnvalue(n, num);
+- return n;
+- }
+- else
+- return NULL;
++
++ if (ttisstring(obj)) {
++ switch( luaO_str2d( svalue(obj), &d, &i ) ) {
++ case TK_INT:
++ setivalue(n,i); return n;
++ case TK_NUMBER:
++ setnvalue(n,d); return n;
++#ifdef LNUM_COMPLEX
++ case TK_NUMBER2: /* "N.NNNi", != 0 */
++ setnvalue_complex_fast(n, d*I); return n;
++#endif
++ }
++ }
++ return NULL;
+ }
+
+
+@@ -49,8 +62,7 @@ int luaV_tostring (lua_State *L, StkId o
+ return 0;
+ else {
+ char s[LUAI_MAXNUMBER2STR];
+- lua_Number n = nvalue(obj);
+- lua_number2str(s, n);
++ luaO_num2buf(s,obj);
+ setsvalue2s(L, obj, luaS_new(L, s));
+ return 1;
+ }
+@@ -222,59 +234,127 @@ static int l_strcmp (const TString *ls,
+ }
+
+
++#ifdef LNUM_COMPLEX
++void error_complex( lua_State *L, const TValue *l, const TValue *r )
++{
++ char buf1[ LUAI_MAXNUMBER2STR ];
++ char buf2[ LUAI_MAXNUMBER2STR ];
++ luaO_num2buf( buf1, l );
++ luaO_num2buf( buf2, r );
++ luaG_runerror( L, "unable to compare: %s with %s", buf1, buf2 );
++ /* no return */
++}
++#endif
++
++
+ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
+ int res;
+- if (ttype(l) != ttype(r))
++ int tl,tr;
++ lua_Integer tmp;
++
++ if (!ttype_ext_same(l,r))
+ return luaG_ordererror(L, l, r);
+- else if (ttisnumber(l))
+- return luai_numlt(nvalue(l), nvalue(r));
+- else if (ttisstring(l))
+- return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
+- else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
++#ifdef LNUM_COMPLEX
++ if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) )
++ error_complex( L, l, r );
++#endif
++ tl= ttype(l); tr= ttype(r);
++ if (tl==tr) { /* clear arithmetics */
++ switch(tl) {
++ case LUA_TINT: return ivalue(l) < ivalue(r);
++ case LUA_TNUMBER: return luai_numlt(nvalue_fast(l), nvalue_fast(r));
++ case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
++ }
++ } else if (tl==LUA_TINT) { /* l:int, r:num */
++ /* Avoid accuracy losing casts: if 'r' is integer by value, do comparisons
++ * in integer realm. Only otherwise cast 'l' to FP (which might change its
++ * value).
++ */
++ if (tt_integer_valued(r,&tmp))
++ return ivalue(l) < tmp;
++ else
++ return luai_numlt( cast_num(ivalue(l)), nvalue_fast(r) );
++
++ } else if (tl==LUA_TNUMBER) { /* l:num, r:int */
++ if (tt_integer_valued(l,&tmp))
++ return tmp < ivalue(r);
++ else
++ return luai_numlt( nvalue_fast(l), cast_num(ivalue(r)) );
++
++ } else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
+ return res;
++
+ return luaG_ordererror(L, l, r);
+ }
+
+
+ static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
+ int res;
+- if (ttype(l) != ttype(r))
++ int tl, tr;
++ lua_Integer tmp;
++
++ if (!ttype_ext_same(l,r))
+ return luaG_ordererror(L, l, r);
+- else if (ttisnumber(l))
+- return luai_numle(nvalue(l), nvalue(r));
+- else if (ttisstring(l))
+- return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
+- else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
++#ifdef LNUM_COMPLEX
++ if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) )
++ error_complex( L, l, r );
++#endif
++ tl= ttype(l); tr= ttype(r);
++ if (tl==tr) { /* clear arithmetics */
++ switch(tl) {
++ case LUA_TINT: return ivalue(l) <= ivalue(r);
++ case LUA_TNUMBER: return luai_numle(nvalue_fast(l), nvalue_fast(r));
++ case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
++ }
++ }
++ if (tl==LUA_TINT) { /* l:int, r:num */
++ if (tt_integer_valued(r,&tmp))
++ return ivalue(l) <= tmp;
++ else
++ return luai_numle( cast_num(ivalue(l)), nvalue_fast(r) );
++
++ } else if (tl==LUA_TNUMBER) { /* l:num, r:int */
++ if (tt_integer_valued(l,&tmp))
++ return tmp <= ivalue(r);
++ else
++ return luai_numle( nvalue_fast(l), cast_num(ivalue(r)) );
++
++ } else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
+ return res;
+ else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
+ return !res;
++
+ return luaG_ordererror(L, l, r);
+ }
+
+
+-int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
++/* Note: 'luaV_equalval()' and 'luaO_rawequalObj()' have largely overlapping
++ * implementation. LUA_TNIL..LUA_TLIGHTUSERDATA cases could be handled
++ * simply by the 'default' case here.
++ */
++int luaV_equalval (lua_State *L, const TValue *l, const TValue *r) {
+ const TValue *tm;
+- lua_assert(ttype(t1) == ttype(t2));
+- switch (ttype(t1)) {
++ lua_assert(ttype_ext_same(l,r));
++ switch (ttype(l)) {
+ case LUA_TNIL: return 1;
+- case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
+- case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
+- case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
++ case LUA_TINT:
++ case LUA_TNUMBER: return luaO_rawequalObj(l,r);
++ case LUA_TBOOLEAN: return bvalue(l) == bvalue(r); /* true must be 1 !! */
++ case LUA_TLIGHTUSERDATA: return pvalue(l) == pvalue(r);
+ case LUA_TUSERDATA: {
+- if (uvalue(t1) == uvalue(t2)) return 1;
+- tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
+- TM_EQ);
++ if (uvalue(l) == uvalue(r)) return 1;
++ tm = get_compTM(L, uvalue(l)->metatable, uvalue(r)->metatable, TM_EQ);
+ break; /* will try TM */
+ }
+ case LUA_TTABLE: {
+- if (hvalue(t1) == hvalue(t2)) return 1;
+- tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
++ if (hvalue(l) == hvalue(r)) return 1;
++ tm = get_compTM(L, hvalue(l)->metatable, hvalue(r)->metatable, TM_EQ);
+ break; /* will try TM */
+ }
+- default: return gcvalue(t1) == gcvalue(t2);
++ default: return gcvalue(l) == gcvalue(r);
+ }
+ if (tm == NULL) return 0; /* no TM? */
+- callTMres(L, L->top, tm, t1, t2); /* call TM */
++ callTMres(L, L->top, tm, l, r); /* call TM */
+ return !l_isfalse(L->top);
+ }
+
+@@ -314,30 +394,6 @@ void luaV_concat (lua_State *L, int tota
+ }
+
+
+-static void Arith (lua_State *L, StkId ra, const TValue *rb,
+- const TValue *rc, TMS op) {
+- TValue tempb, tempc;
+- const TValue *b, *c;
+- if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
+- (c = luaV_tonumber(rc, &tempc)) != NULL) {
+- lua_Number nb = nvalue(b), nc = nvalue(c);
+- switch (op) {
+- case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
+- case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
+- case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
+- case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
+- case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
+- case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
+- case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
+- default: lua_assert(0); break;
+- }
+- }
+- else if (!call_binTM(L, rb, rc, ra, op))
+- luaG_aritherror(L, rb, rc);
+-}
+-
+-
+-
+ /*
+ ** some macros for common tasks in `luaV_execute'
+ */
+@@ -361,17 +417,154 @@ static void Arith (lua_State *L, StkId r
+ #define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
+
+
+-#define arith_op(op,tm) { \
+- TValue *rb = RKB(i); \
+- TValue *rc = RKC(i); \
+- if (ttisnumber(rb) && ttisnumber(rc)) { \
+- lua_Number nb = nvalue(rb), nc = nvalue(rc); \
+- setnvalue(ra, op(nb, nc)); \
+- } \
+- else \
+- Protect(Arith(L, ra, rb, rc, tm)); \
++/* Note: if called for unary operations, 'rc'=='rb'.
++ */
++static void Arith (lua_State *L, StkId ra, const TValue *rb,
++ const TValue *rc, TMS op) {
++ TValue tempb, tempc;
++ const TValue *b, *c;
++ lua_Number nb,nc;
++
++ if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
++ (c = luaV_tonumber(rc, &tempc)) != NULL) {
++
++ /* Keep integer arithmetics in the integer realm, if possible.
++ */
++ if (ttisint(b) && ttisint(c)) {
++ lua_Integer ib = ivalue(b), ic = ivalue(c);
++ lua_Integer *ri = &ra->value.i;
++ ra->tt= LUA_TINT; /* part of 'setivalue(ra)' */
++ switch (op) {
++ case TM_ADD: if (try_addint( ri, ib, ic)) return; break;
++ case TM_SUB: if (try_subint( ri, ib, ic)) return; break;
++ case TM_MUL: if (try_mulint( ri, ib, ic)) return; break;
++ case TM_DIV: if (try_divint( ri, ib, ic)) return; break;
++ case TM_MOD: if (try_modint( ri, ib, ic)) return; break;
++ case TM_POW: if (try_powint( ri, ib, ic)) return; break;
++ case TM_UNM: if (try_unmint( ri, ib)) return; break;
++ default: lua_assert(0);
++ }
++ }
++ /* Fallback to floating point, when leaving range. */
++
++#ifdef LNUM_COMPLEX
++ if ((nvalue_img(b)!=0) || (nvalue_img(c)!=0)) {
++ lua_Complex r;
++ if (op==TM_UNM) {
++ r= -nvalue_complex_fast(b); /* never an integer (or scalar) */
++ setnvalue_complex_fast( ra, r );
++ } else {
++ lua_Complex bb= nvalue_complex(b), cc= nvalue_complex(c);
++ switch (op) {
++ case TM_ADD: r= bb + cc; break;
++ case TM_SUB: r= bb - cc; break;
++ case TM_MUL: r= bb * cc; break;
++ case TM_DIV: r= bb / cc; break;
++ case TM_MOD:
++ luaG_runerror(L, "attempt to use %% on complex numbers"); /* no return */
++ case TM_POW: r= luai_vectpow( bb, cc ); break;
++ default: lua_assert(0); r=0;
++ }
++ setnvalue_complex( ra, r );
+ }
++ return;
++ }
++#endif
++ nb = nvalue(b); nc = nvalue(c);
++ switch (op) {
++ case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); return;
++ case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); return;
++ case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); return;
++ case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); return;
++ case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); return;
++ case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); return;
++ case TM_UNM: setnvalue(ra, luai_numunm(nb)); return;
++ default: lua_assert(0);
++ }
++ }
++
++ /* Either operand not a number */
++ if (!call_binTM(L, rb, rc, ra, op))
++ luaG_aritherror(L, rb, rc);
++}
+
++/* Helper macro to sort arithmetic operations into four categories:
++ * TK_INT: integer - integer operands
++ * TK_NUMBER: number - number (non complex, either may be integer)
++ * TK_NUMBER2: complex numbers (at least the other)
++ * 0: non-numeric (at least the other)
++*/
++#ifdef LNUM_COMPLEX
++static inline int arith_mode( const TValue *rb, const TValue *rc ) {
++ if (ttisint(rb) && ttisint(rc)) return TK_INT;
++ if (ttiscomplex(rb) || ttiscomplex(rc)) return TK_NUMBER2;
++ if (ttisnumber(rb) && ttisnumber(rc)) return TK_NUMBER;
++ return 0;
++}
++#else
++# define arith_mode(rb,rc) \
++ ( (ttisint(rb) && ttisint(rc)) ? TK_INT : \
++ (ttisnumber(rb) && ttisnumber(rc)) ? TK_NUMBER : 0 )
++#endif
++
++/* arith_op macro for two operators:
++ * automatically chooses, which function (number, integer, complex) to use
++ */
++#define ARITH_OP2_START( op_num, op_int ) \
++ int failed= 0; \
++ switch( arith_mode(rb,rc) ) { \
++ case TK_INT: \
++ if (op_int ( &(ra)->value.i, ivalue(rb), ivalue(rc) )) \
++ { ra->tt= LUA_TINT; break; } /* else flow through */ \
++ case TK_NUMBER: \
++ setnvalue(ra, op_num ( nvalue(rb), nvalue(rc) )); break;
++
++#define ARITH_OP2_END \
++ default: \
++ failed= 1; break; \
++ } if (!failed) continue;
++
++#define arith_op_continue_scalar( op_num, op_int ) \
++ ARITH_OP2_START( op_num, op_int ) \
++ ARITH_OP2_END
++
++#ifdef LNUM_COMPLEX
++# define arith_op_continue( op_num, op_int, op_complex ) \
++ ARITH_OP2_START( op_num, op_int ) \
++ case TK_NUMBER2: \
++ setnvalue_complex( ra, op_complex ( nvalue_complex(rb), nvalue_complex(rc) ) ); break; \
++ ARITH_OP2_END
++#else
++# define arith_op_continue(op_num,op_int,_) arith_op_continue_scalar(op_num,op_int)
++#endif
++
++/* arith_op macro for one operator:
++ */
++#define ARITH_OP1_START( op_num, op_int ) \
++ int failed= 0; \
++ switch( arith_mode(rb,rb) ) { \
++ case TK_INT: \
++ if (op_int ( &(ra)->value.i, ivalue(rb) )) \
++ { ra->tt= LUA_TINT; break; } /* else flow through */ \
++ case TK_NUMBER: \
++ setnvalue(ra, op_num (nvalue(rb))); break; \
++
++#define ARITH_OP1_END \
++ default: \
++ failed= 1; break; \
++ } if (!failed) continue;
++
++#ifdef LNUM_COMPLEX
++# define arith_op1_continue( op_num, op_int, op_complex ) \
++ ARITH_OP1_START( op_num, op_int ) \
++ case TK_NUMBER2: \
++ setnvalue_complex( ra, op_complex ( nvalue_complex_fast(rb) )); break; \
++ ARITH_OP1_END
++#else
++# define arith_op1_continue( op_num, op_int, _ ) \
++ ARITH_OP1_START( op_num, op_int ) \
++ ARITH_OP1_END
++#endif
+
+
+ void luaV_execute (lua_State *L, int nexeccalls) {
+@@ -472,38 +665,45 @@ void luaV_execute (lua_State *L, int nex
+ continue;
+ }
+ case OP_ADD: {
+- arith_op(luai_numadd, TM_ADD);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue( luai_numadd, try_addint, luai_vectadd );
++ Protect(Arith(L, ra, rb, rc, TM_ADD)); \
+ continue;
+ }
+ case OP_SUB: {
+- arith_op(luai_numsub, TM_SUB);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue( luai_numsub, try_subint, luai_vectsub );
++ Protect(Arith(L, ra, rb, rc, TM_SUB));
+ continue;
+ }
+ case OP_MUL: {
+- arith_op(luai_nummul, TM_MUL);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue(luai_nummul, try_mulint, luai_vectmul);
++ Protect(Arith(L, ra, rb, rc, TM_MUL));
+ continue;
+ }
+ case OP_DIV: {
+- arith_op(luai_numdiv, TM_DIV);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue(luai_numdiv, try_divint, luai_vectdiv);
++ Protect(Arith(L, ra, rb, rc, TM_DIV));
+ continue;
+ }
+ case OP_MOD: {
+- arith_op(luai_nummod, TM_MOD);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue_scalar(luai_nummod, try_modint); /* scalars only */
++ Protect(Arith(L, ra, rb, rc, TM_MOD));
+ continue;
+ }
+ case OP_POW: {
+- arith_op(luai_numpow, TM_POW);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue(luai_numpow, try_powint, luai_vectpow);
++ Protect(Arith(L, ra, rb, rc, TM_POW));
+ continue;
+ }
+ case OP_UNM: {
+ TValue *rb = RB(i);
+- if (ttisnumber(rb)) {
+- lua_Number nb = nvalue(rb);
+- setnvalue(ra, luai_numunm(nb));
+- }
+- else {
+- Protect(Arith(L, ra, rb, rb, TM_UNM));
+- }
++ arith_op1_continue(luai_numunm, try_unmint, luai_vectunm);
++ Protect(Arith(L, ra, rb, rb, TM_UNM));
+ continue;
+ }
+ case OP_NOT: {
+@@ -515,11 +715,11 @@ void luaV_execute (lua_State *L, int nex
+ const TValue *rb = RB(i);
+ switch (ttype(rb)) {
+ case LUA_TTABLE: {
+- setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
++ setivalue(ra, luaH_getn(hvalue(rb)));
+ break;
+ }
+ case LUA_TSTRING: {
+- setnvalue(ra, cast_num(tsvalue(rb)->len));
++ setivalue(ra, tsvalue(rb)->len);
+ break;
+ }
+ default: { /* try metamethod */
+@@ -652,14 +852,30 @@ void luaV_execute (lua_State *L, int nex
+ }
+ }
+ case OP_FORLOOP: {
+- lua_Number step = nvalue(ra+2);
+- lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
+- lua_Number limit = nvalue(ra+1);
+- if (luai_numlt(0, step) ? luai_numle(idx, limit)
+- : luai_numle(limit, idx)) {
+- dojump(L, pc, GETARG_sBx(i)); /* jump back */
+- setnvalue(ra, idx); /* update internal index... */
+- setnvalue(ra+3, idx); /* ...and external index */
++ /* If start,step and limit are all integers, we don't need to check
++ * against overflow in the looping.
++ */
++ if (ttisint(ra) && ttisint(ra+1) && ttisint(ra+2)) {
++ lua_Integer step = ivalue(ra+2);
++ lua_Integer idx = ivalue(ra) + step; /* increment index */
++ lua_Integer limit = ivalue(ra+1);
++ if (step > 0 ? (idx <= limit) : (limit <= idx)) {
++ dojump(L, pc, GETARG_sBx(i)); /* jump back */
++ setivalue(ra, idx); /* update internal index... */
++ setivalue(ra+3, idx); /* ...and external index */
++ }
++ } else {
++ /* non-integer looping (don't use 'nvalue_fast', some may be integer!)
++ */
++ lua_Number step = nvalue(ra+2);
++ lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
++ lua_Number limit = nvalue(ra+1);
++ if (luai_numlt(0, step) ? luai_numle(idx, limit)
++ : luai_numle(limit, idx)) {
++ dojump(L, pc, GETARG_sBx(i)); /* jump back */
++ setnvalue(ra, idx); /* update internal index... */
++ setnvalue(ra+3, idx); /* ...and external index */
++ }
+ }
+ continue;
+ }
+@@ -668,13 +884,21 @@ void luaV_execute (lua_State *L, int nex
+ const TValue *plimit = ra+1;
+ const TValue *pstep = ra+2;
+ L->savedpc = pc; /* next steps may throw errors */
++ /* Using same location for tonumber's both arguments, effectively does
++ * in-place modification (string->number). */
+ if (!tonumber(init, ra))
+ luaG_runerror(L, LUA_QL("for") " initial value must be a number");
+ else if (!tonumber(plimit, ra+1))
+ luaG_runerror(L, LUA_QL("for") " limit must be a number");
+ else if (!tonumber(pstep, ra+2))
+ luaG_runerror(L, LUA_QL("for") " step must be a number");
+- setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
++ /* Step back one value (keep within integers if we can)
++ */
++ if (!( ttisint(ra) && ttisint(pstep) &&
++ try_subint( &ra->value.i, ivalue(ra), ivalue(pstep) ) )) {
++ /* don't use 'nvalue_fast()', values may be integer */
++ setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
++ }
+ dojump(L, pc, GETARG_sBx(i));
+ continue;
+ }
+@@ -711,7 +935,7 @@ void luaV_execute (lua_State *L, int nex
+ luaH_resizearray(L, h, last); /* pre-alloc it at once */
+ for (; n > 0; n--) {
+ TValue *val = ra+n;
+- setobj2t(L, luaH_setnum(L, h, last--), val);
++ setobj2t(L, luaH_setint(L, h, last--), val);
+ luaC_barriert(L, h, val);
+ }
+ continue;
+--- a/src/lvm.h
++++ b/src/lvm.h
+@@ -15,11 +15,9 @@
+
+ #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
+
+-#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
+- (((o) = luaV_tonumber(o,n)) != NULL))
++#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL))
+
+-#define equalobj(L,o1,o2) \
+- (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
++#define equalobj(L,o1,o2) (ttype_ext_same(o1,o2) && luaV_equalval(L, o1, o2))
+
+
+ LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
+--- a/src/print.c
++++ b/src/print.c
+@@ -14,6 +14,7 @@
+ #include "lobject.h"
+ #include "lopcodes.h"
+ #include "lundump.h"
++#include "lnum.h"
+
+ #define PrintFunction luaU_print
+
+@@ -59,8 +60,16 @@ static void PrintConstant(const Proto* f
+ case LUA_TBOOLEAN:
+ printf(bvalue(o) ? "true" : "false");
+ break;
++ case LUA_TINT:
++ printf(LUA_INTEGER_FMT,ivalue(o));
++ break;
+ case LUA_TNUMBER:
+- printf(LUA_NUMBER_FMT,nvalue(o));
++#ifdef LNUM_COMPLEX
++ // TBD: Do we get complex values here?
++ { lua_Number b= nvalue_img_fast(o);
++ printf( LUA_NUMBER_FMT "%s" LUA_NUMBER_FMT "i", nvalue_fast(o), b>=0 ? "+":"", b ); }
++#endif
++ printf(LUA_NUMBER_FMT,nvalue_fast(o));
+ break;
+ case LUA_TSTRING:
+ PrintString(rawtsvalue(o));
diff --git a/package/utils/lua/patches-host/011-lnum-use-double.patch b/package/utils/lua/patches-host/011-lnum-use-double.patch
new file mode 100644
index 0000000..14c720b
--- /dev/null
+++ b/package/utils/lua/patches-host/011-lnum-use-double.patch
@@ -0,0 +1,11 @@
+--- a/src/lnum_config.h
++++ b/src/lnum_config.h
+@@ -11,7 +11,7 @@
+ ** Default number modes
+ */
+ #if (!defined LNUM_DOUBLE) && (!defined LNUM_FLOAT) && (!defined LNUM_LDOUBLE)
+-# define LNUM_FLOAT
++# define LNUM_DOUBLE
+ #endif
+ #if (!defined LNUM_INT16) && (!defined LNUM_INT32) && (!defined LNUM_INT64)
+ # define LNUM_INT32
diff --git a/package/utils/lua/patches-host/015-lnum-ppc-compat.patch b/package/utils/lua/patches-host/015-lnum-ppc-compat.patch
new file mode 100644
index 0000000..2ea59f1
--- /dev/null
+++ b/package/utils/lua/patches-host/015-lnum-ppc-compat.patch
@@ -0,0 +1,11 @@
+--- a/src/lua.h
++++ b/src/lua.h
+@@ -79,7 +79,7 @@ typedef void * (*lua_Alloc) (void *ud, v
+ * not acceptable for 5.1, maybe 5.2 onwards?
+ * 9: greater than existing (5.1) type values.
+ */
+-#define LUA_TINT (-2)
++#define LUA_TINT 9
+
+ #define LUA_TNIL 0
+ #define LUA_TBOOLEAN 1
diff --git a/package/utils/lua/patches-host/030-archindependent-bytecode.patch b/package/utils/lua/patches-host/030-archindependent-bytecode.patch
new file mode 100644
index 0000000..8dfef85
--- /dev/null
+++ b/package/utils/lua/patches-host/030-archindependent-bytecode.patch
@@ -0,0 +1,111 @@
+--- a/src/ldump.c
++++ b/src/ldump.c
+@@ -67,12 +67,12 @@ static void DumpString(const TString* s,
+ {
+ if (s==NULL || getstr(s)==NULL)
+ {
+- size_t size=0;
++ unsigned int size=0;
+ DumpVar(size,D);
+ }
+ else
+ {
+- size_t size=s->tsv.len+1; /* include trailing '\0' */
++ unsigned int size=s->tsv.len+1; /* include trailing '\0' */
+ DumpVar(size,D);
+ DumpBlock(getstr(s),size,D);
+ }
+--- a/src/lundump.c
++++ b/src/lundump.c
+@@ -25,6 +25,7 @@ typedef struct {
+ ZIO* Z;
+ Mbuffer* b;
+ const char* name;
++ int swap;
+ } LoadState;
+
+ #ifdef LUAC_TRUST_BINARIES
+@@ -40,7 +41,6 @@ static void error(LoadState* S, const ch
+ }
+ #endif
+
+-#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
+ #define LoadByte(S) (lu_byte)LoadChar(S)
+ #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
+ #define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
+@@ -51,6 +51,49 @@ static void LoadBlock(LoadState* S, void
+ IF (r!=0, "unexpected end");
+ }
+
++static void LoadMem (LoadState* S, void* b, int n, size_t size)
++{
++ LoadBlock(S,b,n*size);
++ if (S->swap)
++ {
++ char* p=(char*) b;
++ char c;
++ switch (size)
++ {
++ case 1:
++ break;
++ case 2:
++ while (n--)
++ {
++ c=p[0]; p[0]=p[1]; p[1]=c;
++ p+=2;
++ }
++ break;
++ case 4:
++ while (n--)
++ {
++ c=p[0]; p[0]=p[3]; p[3]=c;
++ c=p[1]; p[1]=p[2]; p[2]=c;
++ p+=4;
++ }
++ break;
++ case 8:
++ while (n--)
++ {
++ c=p[0]; p[0]=p[7]; p[7]=c;
++ c=p[1]; p[1]=p[6]; p[6]=c;
++ c=p[2]; p[2]=p[5]; p[5]=c;
++ c=p[3]; p[3]=p[4]; p[4]=c;
++ p+=8;
++ }
++ break;
++ default:
++ IF(1, "bad size");
++ break;
++ }
++ }
++}
++
+ static int LoadChar(LoadState* S)
+ {
+ char x;
+@@ -82,7 +125,7 @@ static lua_Integer LoadInteger(LoadState
+
+ static TString* LoadString(LoadState* S)
+ {
+- size_t size;
++ unsigned int size;
+ LoadVar(S,size);
+ if (size==0)
+ return NULL;
+@@ -196,6 +239,7 @@ static void LoadHeader(LoadState* S)
+ char s[LUAC_HEADERSIZE];
+ luaU_header(h);
+ LoadBlock(S,s,LUAC_HEADERSIZE);
++ S->swap=(s[6]!=h[6]); s[6]=h[6];
+ IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
+ }
+
+@@ -230,7 +274,7 @@ void luaU_header (char* h)
+ *h++=(char)LUAC_FORMAT;
+ *h++=(char)*(char*)&x; /* endianness */
+ *h++=(char)sizeof(int);
+- *h++=(char)sizeof(size_t);
++ *h++=(char)sizeof(unsigned int);
+ *h++=(char)sizeof(Instruction);
+ *h++=(char)sizeof(lua_Number);
+
diff --git a/package/utils/lua/patches-host/100-no_readline.patch b/package/utils/lua/patches-host/100-no_readline.patch
new file mode 100644
index 0000000..209c302
--- /dev/null
+++ b/package/utils/lua/patches-host/100-no_readline.patch
@@ -0,0 +1,49 @@
+--- a/src/luaconf.h
++++ b/src/luaconf.h
+@@ -38,7 +38,6 @@
+ #if defined(LUA_USE_LINUX)
+ #define LUA_USE_POSIX
+ #define LUA_USE_DLOPEN /* needs an extra library: -ldl */
+-#define LUA_USE_READLINE /* needs some extra libraries */
+ #endif
+
+ #if defined(LUA_USE_MACOSX)
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -17,6 +17,7 @@
+ MYCFLAGS=
+ MYLDFLAGS=
+ MYLIBS=
++# USE_READLINE=1
+
+ # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
+
+@@ -75,7 +76,7 @@
+ @echo "MYLIBS = $(MYLIBS)"
+
+ # convenience targets for popular platforms
+-
++RFLAG=$(if $(USE_READLINE),-DLUA_USE_READLINE)
+ none:
+ @echo "Please choose a platform:"
+ @echo " $(PLATS)"
+@@ -90,16 +91,16 @@
+ $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E"
+
+ freebsd:
+- $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline"
++ $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" $(RFLAG)" MYLIBS="-Wl,-E$(if $(USE_READLINE), -lreadline)"
+
+ generic:
+ $(MAKE) all MYCFLAGS=
+
+ linux:
+- $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses"
++ $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX $(RFLAG)" MYLIBS="-Wl,-E -ldl $(if $(USE_READLINE), -lreadline -lhistory -lncurses)"
+
+ macosx:
+- $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline"
++ $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX $(if $(USE_READLINE), MYLIBS="-lreadline")
+ # use this on Mac OS X 10.3-
+ # $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX
+
diff --git a/package/utils/lua/patches/010-lua-5.1.3-lnum-full-260308.patch b/package/utils/lua/patches/010-lua-5.1.3-lnum-full-260308.patch
new file mode 100644
index 0000000..74b8c6f
--- /dev/null
+++ b/package/utils/lua/patches/010-lua-5.1.3-lnum-full-260308.patch
@@ -0,0 +1,3736 @@
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -25,7 +25,7 @@ PLATS= aix ansi bsd freebsd generic linu
+ LUA_A= liblua.a
+ CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
+ lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
+- lundump.o lvm.o lzio.o
++ lundump.o lvm.o lzio.o lnum.o
+ LIB_O= lauxlib.o lbaselib.o ldblib.o liolib.o lmathlib.o loslib.o ltablib.o \
+ lstrlib.o loadlib.o linit.o
+
+@@ -148,6 +148,7 @@ llex.o: llex.c lua.h luaconf.h ldo.h lob
+ lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
+ lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
+ ltm.h lzio.h lmem.h ldo.h
++lnum.o: lnum.c lua.h llex.h lnum.h
+ loadlib.o: loadlib.c lua.h luaconf.h lauxlib.h lualib.h
+ lobject.o: lobject.c lua.h luaconf.h ldo.h lobject.h llimits.h lstate.h \
+ ltm.h lzio.h lmem.h lstring.h lgc.h lvm.h
+@@ -179,4 +180,18 @@ lzio.o: lzio.c lua.h luaconf.h llimits.h
+ print.o: print.c ldebug.h lstate.h lua.h luaconf.h lobject.h llimits.h \
+ ltm.h lzio.h lmem.h lopcodes.h lundump.h
+
++luaconf.h: lnum_config.h
++lapi.c: lnum.h
++lauxlib.c: llimits.h
++lbaselib.c: llimits.h lobject.h lapi.h
++lcode.c: lnum.h
++liolib.c: lnum.h llex.h
++llex.c: lnum.h
++lnum.h: lobject.h
++lobject.c: llex.h lnum.h
++ltable.c: lnum.h
++lua.c: llimits.h
++lvm.c: llex.h lnum.h
++print.c: lnum.h
++
+ # (end of Makefile)
+--- a/src/lapi.c
++++ b/src/lapi.c
+@@ -28,7 +28,7 @@
+ #include "ltm.h"
+ #include "lundump.h"
+ #include "lvm.h"
+-
++#include "lnum.h"
+
+
+ const char lua_ident[] =
+@@ -241,12 +241,13 @@ LUA_API void lua_pushvalue (lua_State *L
+
+ LUA_API int lua_type (lua_State *L, int idx) {
+ StkId o = index2adr(L, idx);
+- return (o == luaO_nilobject) ? LUA_TNONE : ttype(o);
++ return (o == luaO_nilobject) ? LUA_TNONE : ttype_ext(o);
+ }
+
+
+ LUA_API const char *lua_typename (lua_State *L, int t) {
+ UNUSED(L);
++ lua_assert( t!= LUA_TINT );
+ return (t == LUA_TNONE) ? "no value" : luaT_typenames[t];
+ }
+
+@@ -264,6 +265,14 @@ LUA_API int lua_isnumber (lua_State *L,
+ }
+
+
++LUA_API int lua_isinteger (lua_State *L, int idx) {
++ TValue tmp;
++ lua_Integer dum;
++ const TValue *o = index2adr(L, idx);
++ return tonumber(o,&tmp) && (ttisint(o) || tt_integer_valued(o,&dum));
++}
++
++
+ LUA_API int lua_isstring (lua_State *L, int idx) {
+ int t = lua_type(L, idx);
+ return (t == LUA_TSTRING || t == LUA_TNUMBER);
+@@ -309,31 +318,66 @@ LUA_API int lua_lessthan (lua_State *L,
+ }
+
+
+-
+ LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
+ TValue n;
+ const TValue *o = index2adr(L, idx);
+- if (tonumber(o, &n))
++ if (tonumber(o, &n)) {
++#ifdef LNUM_COMPLEX
++ if (nvalue_img(o) != 0)
++ luaG_runerror(L, "expecting a real number");
++#endif
+ return nvalue(o);
+- else
+- return 0;
++ }
++ return 0;
+ }
+
+
+ LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
+ TValue n;
++ /* Lua 5.1 documented behaviour is to return nonzero for non-integer:
++ * "If the number is not an integer, it is truncated in some non-specified way."
++ * I would suggest to change this, to return 0 for anything that would
++ * not fit in 'lua_Integer'.
++ */
++#ifdef LUA_COMPAT_TOINTEGER
++ /* Lua 5.1 compatible */
+ const TValue *o = index2adr(L, idx);
+ if (tonumber(o, &n)) {
+- lua_Integer res;
+- lua_Number num = nvalue(o);
+- lua_number2integer(res, num);
+- return res;
++ lua_Integer i;
++ lua_Number d;
++ if (ttisint(o)) return ivalue(o);
++ d= nvalue_fast(o);
++# ifdef LNUM_COMPLEX
++ if (nvalue_img_fast(o) != 0)
++ luaG_runerror(L, "expecting a real number");
++# endif
++ lua_number2integer(i, d);
++ return i;
+ }
+- else
+- return 0;
++#else
++ /* New suggestion */
++ const TValue *o = index2adr(L, idx);
++ if (tonumber(o, &n)) {
++ lua_Integer i;
++ if (ttisint(o)) return ivalue(o);
++ if (tt_integer_valued(o,&i)) return i;
++ }
++#endif
++ return 0;
+ }
+
+
++#ifdef LNUM_COMPLEX
++LUA_API lua_Complex lua_tocomplex (lua_State *L, int idx) {
++ TValue tmp;
++ const TValue *o = index2adr(L, idx);
++ if (tonumber(o, &tmp))
++ return nvalue_complex(o);
++ return 0;
++}
++#endif
++
++
+ LUA_API int lua_toboolean (lua_State *L, int idx) {
+ const TValue *o = index2adr(L, idx);
+ return !l_isfalse(o);
+@@ -364,6 +408,7 @@ LUA_API size_t lua_objlen (lua_State *L,
+ case LUA_TSTRING: return tsvalue(o)->len;
+ case LUA_TUSERDATA: return uvalue(o)->len;
+ case LUA_TTABLE: return luaH_getn(hvalue(o));
++ case LUA_TINT:
+ case LUA_TNUMBER: {
+ size_t l;
+ lua_lock(L); /* `luaV_tostring' may create a new string */
+@@ -426,6 +471,8 @@ LUA_API void lua_pushnil (lua_State *L)
+ }
+
+
++/* 'lua_pushnumber()' may lose accuracy on integers, 'lua_pushinteger' will not.
++ */
+ LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
+ lua_lock(L);
+ setnvalue(L->top, n);
+@@ -434,12 +481,22 @@ LUA_API void lua_pushnumber (lua_State *
+ }
+
+
+-LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
++LUA_API void lua_pushinteger (lua_State *L, lua_Integer i) {
++ lua_lock(L);
++ setivalue(L->top, i);
++ api_incr_top(L);
++ lua_unlock(L);
++}
++
++
++#ifdef LNUM_COMPLEX
++LUA_API void lua_pushcomplex (lua_State *L, lua_Complex v) {
+ lua_lock(L);
+- setnvalue(L->top, cast_num(n));
++ setnvalue_complex( L->top, v );
+ api_incr_top(L);
+ lua_unlock(L);
+ }
++#endif
+
+
+ LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
+@@ -569,7 +626,7 @@ LUA_API void lua_rawgeti (lua_State *L,
+ lua_lock(L);
+ o = index2adr(L, idx);
+ api_check(L, ttistable(o));
+- setobj2s(L, L->top, luaH_getnum(hvalue(o), n));
++ setobj2s(L, L->top, luaH_getint(hvalue(o), n));
+ api_incr_top(L);
+ lua_unlock(L);
+ }
+@@ -597,6 +654,9 @@ LUA_API int lua_getmetatable (lua_State
+ case LUA_TUSERDATA:
+ mt = uvalue(obj)->metatable;
+ break;
++ case LUA_TINT:
++ mt = G(L)->mt[LUA_TNUMBER];
++ break;
+ default:
+ mt = G(L)->mt[ttype(obj)];
+ break;
+@@ -687,7 +747,7 @@ LUA_API void lua_rawseti (lua_State *L,
+ api_checknelems(L, 1);
+ o = index2adr(L, idx);
+ api_check(L, ttistable(o));
+- setobj2t(L, luaH_setnum(L, hvalue(o), n), L->top-1);
++ setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1);
+ luaC_barriert(L, hvalue(o), L->top-1);
+ L->top--;
+ lua_unlock(L);
+@@ -721,7 +781,7 @@ LUA_API int lua_setmetatable (lua_State
+ break;
+ }
+ default: {
+- G(L)->mt[ttype(obj)] = mt;
++ G(L)->mt[ttype_ext(obj)] = mt;
+ break;
+ }
+ }
+@@ -1085,3 +1145,32 @@ LUA_API const char *lua_setupvalue (lua_
+ return name;
+ }
+
++
++/* Help function for 'luaB_tonumber()', avoids multiple str->number
++ * conversions for Lua "tonumber()".
++ *
++ * Also pushes floating point numbers with integer value as integer, which
++ * can be used by 'tonumber()' in scripts to bring values back to integer
++ * realm.
++ *
++ * Note: The 'back to integer realm' is _not_ to affect string conversions:
++ * 'tonumber("4294967295.1")' should give a floating point value, although
++ * the value would be 4294967296 (and storable in int64 realm).
++ */
++int lua_pushvalue_as_number (lua_State *L, int idx)
++{
++ const TValue *o = index2adr(L, idx);
++ TValue tmp;
++ lua_Integer i;
++ if (ttisnumber(o)) {
++ if ( (!ttisint(o)) && tt_integer_valued(o,&i)) {
++ lua_pushinteger( L, i );
++ return 1;
++ }
++ } else if (!tonumber(o, &tmp)) {
++ return 0;
++ }
++ if (ttisint(o)) lua_pushinteger( L, ivalue(o) );
++ else lua_pushnumber( L, nvalue_fast(o) );
++ return 1;
++}
+--- a/src/lapi.h
++++ b/src/lapi.h
+@@ -13,4 +13,6 @@
+
+ LUAI_FUNC void luaA_pushobject (lua_State *L, const TValue *o);
+
++int lua_pushvalue_as_number (lua_State *L, int idx);
++
+ #endif
+--- a/src/lauxlib.c
++++ b/src/lauxlib.c
+@@ -23,7 +23,7 @@
+ #include "lua.h"
+
+ #include "lauxlib.h"
+-
++#include "llimits.h"
+
+ #define FREELIST_REF 0 /* free list of references */
+
+@@ -66,7 +66,7 @@ LUALIB_API int luaL_typerror (lua_State
+
+
+ static void tag_error (lua_State *L, int narg, int tag) {
+- luaL_typerror(L, narg, lua_typename(L, tag));
++ luaL_typerror(L, narg, tag==LUA_TINT ? "integer" : lua_typename(L, tag));
+ }
+
+
+@@ -188,8 +188,8 @@ LUALIB_API lua_Number luaL_optnumber (lu
+
+ LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
+ lua_Integer d = lua_tointeger(L, narg);
+- if (d == 0 && !lua_isnumber(L, narg)) /* avoid extra test when d is not 0 */
+- tag_error(L, narg, LUA_TNUMBER);
++ if (d == 0 && !lua_isinteger(L, narg)) /* avoid extra test when d is not 0 */
++ tag_error(L, narg, LUA_TINT);
+ return d;
+ }
+
+@@ -200,6 +200,16 @@ LUALIB_API lua_Integer luaL_optinteger (
+ }
+
+
++#ifdef LNUM_COMPLEX
++LUALIB_API lua_Complex luaL_checkcomplex (lua_State *L, int narg) {
++ lua_Complex c = lua_tocomplex(L, narg);
++ if (c == 0 && !lua_isnumber(L, narg)) /* avoid extra test when c is not 0 */
++ tag_error(L, narg, LUA_TNUMBER);
++ return c;
++}
++#endif
++
++
+ LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) {
+ if (!lua_getmetatable(L, obj)) /* no metatable? */
+ return 0;
+--- a/src/lauxlib.h
++++ b/src/lauxlib.h
+@@ -57,6 +57,12 @@ LUALIB_API lua_Number (luaL_optnumber) (
+ LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
+ LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
+ lua_Integer def);
++#define luaL_checkint32(L,narg) ((int)luaL_checkinteger(L,narg))
++#define luaL_optint32(L,narg,def) ((int)luaL_optinteger(L,narg,def))
++
++#ifdef LNUM_COMPLEX
++ LUALIB_API lua_Complex (luaL_checkcomplex) (lua_State *L, int narg);
++#endif
+
+ LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
+ LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);
+--- a/src/lbaselib.c
++++ b/src/lbaselib.c
+@@ -18,7 +18,9 @@
+
+ #include "lauxlib.h"
+ #include "lualib.h"
+-
++#include "llimits.h"
++#include "lobject.h"
++#include "lapi.h"
+
+
+
+@@ -54,20 +56,25 @@ static int luaB_tonumber (lua_State *L)
+ int base = luaL_optint(L, 2, 10);
+ if (base == 10) { /* standard conversion */
+ luaL_checkany(L, 1);
+- if (lua_isnumber(L, 1)) {
+- lua_pushnumber(L, lua_tonumber(L, 1));
++ if (lua_isnumber(L, 1)) { /* numeric string, or a number */
++ lua_pushvalue_as_number(L,1); /* API extension (not to lose accuracy here) */
+ return 1;
+- }
++ }
+ }
+ else {
+ const char *s1 = luaL_checkstring(L, 1);
+ char *s2;
+- unsigned long n;
++ unsigned LUA_INTEGER n;
+ luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
+- n = strtoul(s1, &s2, base);
++ n = lua_str2ul(s1, &s2, base);
+ if (s1 != s2) { /* at least one valid digit? */
+ while (isspace((unsigned char)(*s2))) s2++; /* skip trailing spaces */
+ if (*s2 == '\0') { /* no invalid trailing characters? */
++
++ /* Push as number, there needs to be separate 'luaB_tointeger' for
++ * when the caller wants to preserve the bits (matters if unsigned
++ * values are used).
++ */
+ lua_pushnumber(L, (lua_Number)n);
+ return 1;
+ }
+@@ -144,7 +151,7 @@ static int luaB_setfenv (lua_State *L) {
+ luaL_checktype(L, 2, LUA_TTABLE);
+ getfunc(L, 0);
+ lua_pushvalue(L, 2);
+- if (lua_isnumber(L, 1) && lua_tonumber(L, 1) == 0) {
++ if (lua_isnumber(L, 1) && lua_tointeger(L, 1) == 0) {
+ /* change environment of current thread */
+ lua_pushthread(L);
+ lua_insert(L, -2);
+@@ -209,7 +216,7 @@ static int luaB_collectgarbage (lua_Stat
+ return 1;
+ }
+ default: {
+- lua_pushnumber(L, res);
++ lua_pushinteger(L, res);
+ return 1;
+ }
+ }
+@@ -631,6 +638,8 @@ static void base_open (lua_State *L) {
+ luaL_register(L, "_G", base_funcs);
+ lua_pushliteral(L, LUA_VERSION);
+ lua_setglobal(L, "_VERSION"); /* set global _VERSION */
++ lua_pushliteral(L, LUA_LNUM);
++ lua_setglobal(L, "_LNUM"); /* "[complex] double|float|ldouble int32|int64" */
+ /* `ipairs' and `pairs' need auxiliary functions as upvalues */
+ auxopen(L, "ipairs", luaB_ipairs, ipairsaux);
+ auxopen(L, "pairs", luaB_pairs, luaB_next);
+--- a/src/lcode.c
++++ b/src/lcode.c
+@@ -22,13 +22,18 @@
+ #include "lopcodes.h"
+ #include "lparser.h"
+ #include "ltable.h"
++#include "lnum.h"
+
+
+ #define hasjumps(e) ((e)->t != (e)->f)
+
+-
+ static int isnumeral(expdesc *e) {
+- return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
++ int ek=
++#ifdef LNUM_COMPLEX
++ (e->k == VKNUM2) ||
++#endif
++ (e->k == VKINT) || (e->k == VKNUM);
++ return (ek && e->t == NO_JUMP && e->f == NO_JUMP);
+ }
+
+
+@@ -231,12 +236,16 @@ static int addk (FuncState *fs, TValue *
+ TValue *idx = luaH_set(L, fs->h, k);
+ Proto *f = fs->f;
+ int oldsize = f->sizek;
+- if (ttisnumber(idx)) {
+- lua_assert(luaO_rawequalObj(&fs->f->k[cast_int(nvalue(idx))], v));
+- return cast_int(nvalue(idx));
++ if (ttype(idx)==LUA_TNUMBER) {
++ luai_normalize(idx);
++ lua_assert( ttype(idx)==LUA_TINT ); /* had no fraction */
++ }
++ if (ttisint(idx)) {
++ lua_assert(luaO_rawequalObj(&fs->f->k[ivalue(idx)], v));
++ return cast_int(ivalue(idx));
+ }
+ else { /* constant not found; create a new entry */
+- setnvalue(idx, cast_num(fs->nk));
++ setivalue(idx, fs->nk);
+ luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
+ MAXARG_Bx, "constant table overflow");
+ while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
+@@ -261,6 +270,21 @@ int luaK_numberK (FuncState *fs, lua_Num
+ }
+
+
++int luaK_integerK (FuncState *fs, lua_Integer r) {
++ TValue o;
++ setivalue(&o, r);
++ return addk(fs, &o, &o);
++}
++
++
++#ifdef LNUM_COMPLEX
++static int luaK_imagK (FuncState *fs, lua_Number r) {
++ TValue o;
++ setnvalue_complex(&o, r*I);
++ return addk(fs, &o, &o);
++}
++#endif
++
+ static int boolK (FuncState *fs, int b) {
+ TValue o;
+ setbvalue(&o, b);
+@@ -359,6 +383,16 @@ static void discharge2reg (FuncState *fs
+ luaK_codeABx(fs, OP_LOADK, reg, luaK_numberK(fs, e->u.nval));
+ break;
+ }
++ case VKINT: {
++ luaK_codeABx(fs, OP_LOADK, reg, luaK_integerK(fs, e->u.ival));
++ break;
++ }
++#ifdef LNUM_COMPLEX
++ case VKNUM2: {
++ luaK_codeABx(fs, OP_LOADK, reg, luaK_imagK(fs, e->u.nval));
++ break;
++ }
++#endif
+ case VRELOCABLE: {
+ Instruction *pc = &getcode(fs, e);
+ SETARG_A(*pc, reg);
+@@ -444,6 +478,10 @@ void luaK_exp2val (FuncState *fs, expdes
+ int luaK_exp2RK (FuncState *fs, expdesc *e) {
+ luaK_exp2val(fs, e);
+ switch (e->k) {
++#ifdef LNUM_COMPLEX
++ case VKNUM2:
++#endif
++ case VKINT:
+ case VKNUM:
+ case VTRUE:
+ case VFALSE:
+@@ -451,6 +489,10 @@ int luaK_exp2RK (FuncState *fs, expdesc
+ if (fs->nk <= MAXINDEXRK) { /* constant fit in RK operand? */
+ e->u.s.info = (e->k == VNIL) ? nilK(fs) :
+ (e->k == VKNUM) ? luaK_numberK(fs, e->u.nval) :
++ (e->k == VKINT) ? luaK_integerK(fs, e->u.ival) :
++#ifdef LNUM_COMPLEX
++ (e->k == VKNUM2) ? luaK_imagK(fs, e->u.nval) :
++#endif
+ boolK(fs, (e->k == VTRUE));
+ e->k = VK;
+ return RKASK(e->u.s.info);
+@@ -540,7 +582,10 @@ void luaK_goiftrue (FuncState *fs, expde
+ int pc; /* pc of last jump */
+ luaK_dischargevars(fs, e);
+ switch (e->k) {
+- case VK: case VKNUM: case VTRUE: {
++#ifdef LNUM_COMPLEX
++ case VKNUM2:
++#endif
++ case VKINT: case VK: case VKNUM: case VTRUE: {
+ pc = NO_JUMP; /* always true; do nothing */
+ break;
+ }
+@@ -590,7 +635,10 @@ static void codenot (FuncState *fs, expd
+ e->k = VTRUE;
+ break;
+ }
+- case VK: case VKNUM: case VTRUE: {
++#ifdef LNUM_COMPLEX
++ case VKNUM2:
++#endif
++ case VKINT: case VK: case VKNUM: case VTRUE: {
+ e->k = VFALSE;
+ break;
+ }
+@@ -626,25 +674,70 @@ void luaK_indexed (FuncState *fs, expdes
+
+ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
+ lua_Number v1, v2, r;
++ int vkres= VKNUM;
+ if (!isnumeral(e1) || !isnumeral(e2)) return 0;
+- v1 = e1->u.nval;
+- v2 = e2->u.nval;
++
++ /* real and imaginary parts don't mix. */
++#ifdef LNUM_COMPLEX
++ if (e1->k == VKNUM2) {
++ if ((op != OP_UNM) && (e2->k != VKNUM2)) return 0;
++ vkres= VKNUM2; }
++ else if (e2->k == VKNUM2) { return 0; }
++#endif
++ if ((e1->k == VKINT) && (e2->k == VKINT)) {
++ lua_Integer i1= e1->u.ival, i2= e2->u.ival;
++ lua_Integer rr;
++ int done= 0;
++ /* Integer/integer calculations (may end up producing floating point) */
++ switch (op) {
++ case OP_ADD: done= try_addint( &rr, i1, i2 ); break;
++ case OP_SUB: done= try_subint( &rr, i1, i2 ); break;
++ case OP_MUL: done= try_mulint( &rr, i1, i2 ); break;
++ case OP_DIV: done= try_divint( &rr, i1, i2 ); break;
++ case OP_MOD: done= try_modint( &rr, i1, i2 ); break;
++ case OP_POW: done= try_powint( &rr, i1, i2 ); break;
++ case OP_UNM: done= try_unmint( &rr, i1 ); break;
++ default: done= 0; break;
++ }
++ if (done) {
++ e1->u.ival = rr; /* remained within integer range */
++ return 1;
++ }
++ }
++ v1 = (e1->k == VKINT) ? ((lua_Number)e1->u.ival) : e1->u.nval;
++ v2 = (e2->k == VKINT) ? ((lua_Number)e2->u.ival) : e2->u.nval;
++
+ switch (op) {
+ case OP_ADD: r = luai_numadd(v1, v2); break;
+ case OP_SUB: r = luai_numsub(v1, v2); break;
+- case OP_MUL: r = luai_nummul(v1, v2); break;
++ case OP_MUL:
++#ifdef LNUM_COMPLEX
++ if (vkres==VKNUM2) return 0; /* leave to runtime (could do here, but not worth it?) */
++#endif
++ r = luai_nummul(v1, v2); break;
+ case OP_DIV:
+ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
+- r = luai_numdiv(v1, v2); break;
++#ifdef LNUM_COMPLEX
++ if (vkres==VKNUM2) return 0; /* leave to runtime */
++#endif
++ r = luai_numdiv(v1, v2); break;
+ case OP_MOD:
+ if (v2 == 0) return 0; /* do not attempt to divide by 0 */
++#ifdef LNUM_COMPLEX
++ if (vkres==VKNUM2) return 0; /* leave to runtime */
++#endif
+ r = luai_nummod(v1, v2); break;
+- case OP_POW: r = luai_numpow(v1, v2); break;
++ case OP_POW:
++#ifdef LNUM_COMPLEX
++ if (vkres==VKNUM2) return 0; /* leave to runtime */
++#endif
++ r = luai_numpow(v1, v2); break;
+ case OP_UNM: r = luai_numunm(v1); break;
+ case OP_LEN: return 0; /* no constant folding for 'len' */
+ default: lua_assert(0); r = 0; break;
+ }
+ if (luai_numisnan(r)) return 0; /* do not attempt to produce NaN */
++ e1->k = cast(expkind,vkres);
+ e1->u.nval = r;
+ return 1;
+ }
+@@ -688,7 +781,8 @@ static void codecomp (FuncState *fs, OpC
+
+ void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e) {
+ expdesc e2;
+- e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
++ e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
++
+ switch (op) {
+ case OPR_MINUS: {
+ if (!isnumeral(e))
+--- a/src/lcode.h
++++ b/src/lcode.h
+@@ -71,6 +71,6 @@ LUAI_FUNC void luaK_prefix (FuncState *f
+ LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v);
+ LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, expdesc *v2);
+ LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore);
+-
++LUAI_FUNC int luaK_integerK (FuncState *fs, lua_Integer r);
+
+ #endif
+--- a/src/ldebug.c
++++ b/src/ldebug.c
+@@ -183,7 +183,7 @@ static void collectvalidlines (lua_State
+ int *lineinfo = f->l.p->lineinfo;
+ int i;
+ for (i=0; i<f->l.p->sizelineinfo; i++)
+- setbvalue(luaH_setnum(L, t, lineinfo[i]), 1);
++ setbvalue(luaH_setint(L, t, lineinfo[i]), 1);
+ sethvalue(L, L->top, t);
+ }
+ incr_top(L);
+@@ -566,7 +566,7 @@ static int isinstack (CallInfo *ci, cons
+
+ void luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+ const char *name = NULL;
+- const char *t = luaT_typenames[ttype(o)];
++ const char *t = luaT_typenames[ttype_ext(o)];
+ const char *kind = (isinstack(L->ci, o)) ?
+ getobjname(L, L->ci, cast_int(o - L->base), &name) :
+ NULL;
+@@ -594,8 +594,8 @@ void luaG_aritherror (lua_State *L, cons
+
+
+ int luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
+- const char *t1 = luaT_typenames[ttype(p1)];
+- const char *t2 = luaT_typenames[ttype(p2)];
++ const char *t1 = luaT_typenames[ttype_ext(p1)];
++ const char *t2 = luaT_typenames[ttype_ext(p2)];
+ if (t1[2] == t2[2])
+ luaG_runerror(L, "attempt to compare two %s values", t1);
+ else
+--- a/src/ldo.c
++++ b/src/ldo.c
+@@ -220,9 +220,9 @@ static StkId adjust_varargs (lua_State *
+ luaD_checkstack(L, p->maxstacksize);
+ htab = luaH_new(L, nvar, 1); /* create `arg' table */
+ for (i=0; i<nvar; i++) /* put extra arguments into `arg' table */
+- setobj2n(L, luaH_setnum(L, htab, i+1), L->top - nvar + i);
++ setobj2n(L, luaH_setint(L, htab, i+1), L->top - nvar + i);
+ /* store counter in field `n' */
+- setnvalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), cast_num(nvar));
++ setivalue(luaH_setstr(L, htab, luaS_newliteral(L, "n")), nvar);
+ }
+ #endif
+ /* move fixed parameters to final position */
+--- a/src/ldump.c
++++ b/src/ldump.c
+@@ -52,6 +52,11 @@ static void DumpNumber(lua_Number x, Dum
+ DumpVar(x,D);
+ }
+
++static void DumpInteger(lua_Integer x, DumpState* D)
++{
++ DumpVar(x,D);
++}
++
+ static void DumpVector(const void* b, int n, size_t size, DumpState* D)
+ {
+ DumpInt(n,D);
+@@ -93,8 +98,11 @@ static void DumpConstants(const Proto* f
+ DumpChar(bvalue(o),D);
+ break;
+ case LUA_TNUMBER:
+- DumpNumber(nvalue(o),D);
++ DumpNumber(nvalue_fast(o),D);
+ break;
++ case LUA_TINT:
++ DumpInteger(ivalue(o),D);
++ break;
+ case LUA_TSTRING:
+ DumpString(rawtsvalue(o),D);
+ break;
+--- a/src/liolib.c
++++ b/src/liolib.c
+@@ -9,6 +9,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <ctype.h>
+
+ #define liolib_c
+ #define LUA_LIB
+@@ -18,7 +19,8 @@
+ #include "lauxlib.h"
+ #include "lualib.h"
+
+-
++#include "lnum.h"
++#include "llex.h"
+
+ #define IO_INPUT 1
+ #define IO_OUTPUT 2
+@@ -269,6 +271,13 @@ static int io_lines (lua_State *L) {
+ ** =======================================================
+ */
+
++/*
++* Many problems if we intend the same 'n' format specifier (see 'file:read()')
++* to work for both FP and integer numbers, without losing their accuracy. So
++* we don't. 'n' reads numbers as floating points, 'i' as integers. Old code
++* remains valid, but won't provide full integer accuracy (this only matters
++* with float FP and/or 64-bit integers).
++*/
+
+ static int read_number (lua_State *L, FILE *f) {
+ lua_Number d;
+@@ -282,6 +291,43 @@ static int read_number (lua_State *L, FI
+ }
+ }
+
++static int read_integer (lua_State *L, FILE *f) {
++ lua_Integer i;
++ if (fscanf(f, LUA_INTEGER_SCAN, &i) == 1) {
++ lua_pushinteger(L, i);
++ return 1;
++ }
++ else return 0; /* read fails */
++}
++
++#ifdef LNUM_COMPLEX
++static int read_complex (lua_State *L, FILE *f) {
++ /* NNN / NNNi / NNN+MMMi / NNN-MMMi */
++ lua_Number a,b;
++ if (fscanf(f, LUA_NUMBER_SCAN, &a) == 1) {
++ int c=fgetc(f);
++ switch(c) {
++ case 'i':
++ lua_pushcomplex(L, a*I);
++ return 1;
++ case '+':
++ case '-':
++ /* "i" is consumed if at the end; just 'NNN+MMM' will most likely
++ * behave as if "i" was there? (TBD: test)
++ */
++ if (fscanf(f, LUA_NUMBER_SCAN "i", &b) == 1) {
++ lua_pushcomplex(L, a+ (c=='+' ? b:-b)*I);
++ return 1;
++ }
++ }
++ ungetc( c,f );
++ lua_pushnumber(L,a); /*real part only*/
++ return 1;
++ }
++ return 0; /* read fails */
++}
++#endif
++
+
+ static int test_eof (lua_State *L, FILE *f) {
+ int c = getc(f);
+@@ -355,6 +401,14 @@ static int g_read (lua_State *L, FILE *f
+ case 'n': /* number */
+ success = read_number(L, f);
+ break;
++ case 'i': /* integer (full accuracy) */
++ success = read_integer(L, f);
++ break;
++#ifdef LNUM_COMPLEX
++ case 'c': /* complex */
++ success = read_complex(L, f);
++ break;
++#endif
+ case 'l': /* line */
+ success = read_line(L, f);
+ break;
+@@ -415,9 +469,10 @@ static int g_write (lua_State *L, FILE *
+ int status = 1;
+ for (; nargs--; arg++) {
+ if (lua_type(L, arg) == LUA_TNUMBER) {
+- /* optimization: could be done exactly as for strings */
+- status = status &&
+- fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
++ if (lua_isinteger(L,arg))
++ status = status && fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg)) > 0;
++ else
++ status = status && fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
+ }
+ else {
+ size_t l;
+@@ -460,7 +515,7 @@ static int f_setvbuf (lua_State *L) {
+ static const char *const modenames[] = {"no", "full", "line", NULL};
+ FILE *f = tofile(L);
+ int op = luaL_checkoption(L, 2, NULL, modenames);
+- lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
++ size_t sz = luaL_optint32(L, 3, LUAL_BUFFERSIZE);
+ int res = setvbuf(f, NULL, mode[op], sz);
+ return pushresult(L, res == 0, NULL);
+ }
+--- a/src/llex.c
++++ b/src/llex.c
+@@ -22,6 +22,7 @@
+ #include "lstring.h"
+ #include "ltable.h"
+ #include "lzio.h"
++#include "lnum.h"
+
+
+
+@@ -34,13 +35,17 @@
+
+
+ /* ORDER RESERVED */
+-const char *const luaX_tokens [] = {
++static const char *const luaX_tokens [] = {
+ "and", "break", "do", "else", "elseif",
+ "end", "false", "for", "function", "if",
+ "in", "local", "nil", "not", "or", "repeat",
+ "return", "then", "true", "until", "while",
+ "..", "...", "==", ">=", "<=", "~=",
+ "<number>", "<name>", "<string>", "<eof>",
++ "<integer>",
++#ifdef LNUM_COMPLEX
++ "<number2>",
++#endif
+ NULL
+ };
+
+@@ -90,7 +95,11 @@ static const char *txtToken (LexState *l
+ switch (token) {
+ case TK_NAME:
+ case TK_STRING:
++ case TK_INT:
+ case TK_NUMBER:
++#ifdef LNUM_COMPLEX
++ case TK_NUMBER2:
++#endif
+ save(ls, '\0');
+ return luaZ_buffer(ls->buff);
+ default:
+@@ -175,23 +184,27 @@ static void buffreplace (LexState *ls, c
+ if (p[n] == from) p[n] = to;
+ }
+
+-
+-static void trydecpoint (LexState *ls, SemInfo *seminfo) {
++/* TK_NUMBER (/ TK_NUMBER2) */
++static int trydecpoint (LexState *ls, SemInfo *seminfo) {
+ /* format error: try to update decimal point separator */
+ struct lconv *cv = localeconv();
+ char old = ls->decpoint;
++ int ret;
+ ls->decpoint = (cv ? cv->decimal_point[0] : '.');
+ buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
+- if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
++ ret= luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r, NULL);
++ if (!ret) {
+ /* format error with correct decimal point: no more options */
+ buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
+ luaX_lexerror(ls, "malformed number", TK_NUMBER);
+ }
++ return ret;
+ }
+
+
+-/* LUA_NUMBER */
+-static void read_numeral (LexState *ls, SemInfo *seminfo) {
++/* TK_NUMBER / TK_INT (/TK_NUMBER2) */
++static int read_numeral (LexState *ls, SemInfo *seminfo) {
++ int ret;
+ lua_assert(isdigit(ls->current));
+ do {
+ save_and_next(ls);
+@@ -202,8 +215,9 @@ static void read_numeral (LexState *ls,
+ save_and_next(ls);
+ save(ls, '\0');
+ buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
+- if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) /* format error? */
+- trydecpoint(ls, seminfo); /* try to update decimal point separator */
++ ret= luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r, &seminfo->i );
++ if (!ret) return trydecpoint(ls, seminfo); /* try to update decimal point separator */
++ return ret;
+ }
+
+
+@@ -331,6 +345,7 @@ static void read_string (LexState *ls, i
+ }
+
+
++/* char / TK_* */
+ static int llex (LexState *ls, SemInfo *seminfo) {
+ luaZ_resetbuffer(ls->buff);
+ for (;;) {
+@@ -402,8 +417,7 @@ static int llex (LexState *ls, SemInfo *
+ }
+ else if (!isdigit(ls->current)) return '.';
+ else {
+- read_numeral(ls, seminfo);
+- return TK_NUMBER;
++ return read_numeral(ls, seminfo);
+ }
+ }
+ case EOZ: {
+@@ -416,8 +430,7 @@ static int llex (LexState *ls, SemInfo *
+ continue;
+ }
+ else if (isdigit(ls->current)) {
+- read_numeral(ls, seminfo);
+- return TK_NUMBER;
++ return read_numeral(ls, seminfo);
+ }
+ else if (isalpha(ls->current) || ls->current == '_') {
+ /* identifier or reserved word */
+--- a/src/llex.h
++++ b/src/llex.h
+@@ -29,19 +29,22 @@ enum RESERVED {
+ TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
+ /* other terminal symbols */
+ TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_NUMBER,
+- TK_NAME, TK_STRING, TK_EOS
++ TK_NAME, TK_STRING, TK_EOS, TK_INT
++#ifdef LNUM_COMPLEX
++ , TK_NUMBER2 /* imaginary constants: Ni */
++#endif
+ };
+
+ /* number of reserved words */
+ #define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1))
+
+
+-/* array with token `names' */
+-LUAI_DATA const char *const luaX_tokens [];
+-
+-
++/* SemInfo is a local data structure of 'llex.c', used for carrying a string
++ * or a number. A separate token (TK_*) will tell, how to interpret the data.
++ */
+ typedef union {
+ lua_Number r;
++ lua_Integer i;
+ TString *ts;
+ } SemInfo; /* semantics information */
+
+--- a/src/llimits.h
++++ b/src/llimits.h
+@@ -49,6 +49,7 @@ typedef LUAI_USER_ALIGNMENT_T L_Umaxalig
+
+ /* result of a `usual argument conversion' over lua_Number */
+ typedef LUAI_UACNUMBER l_uacNumber;
++typedef LUAI_UACINTEGER l_uacInteger;
+
+
+ /* internal assertions for in-house debugging */
+@@ -80,7 +81,6 @@ typedef LUAI_UACNUMBER l_uacNumber;
+ #define cast_int(i) cast(int, (i))
+
+
+-
+ /*
+ ** type for virtual-machine instructions
+ ** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
+--- a/src/lmathlib.c
++++ b/src/lmathlib.c
+@@ -4,7 +4,6 @@
+ ** See Copyright Notice in lua.h
+ */
+
+-
+ #include <stdlib.h>
+ #include <math.h>
+
+@@ -16,113 +15,210 @@
+ #include "lauxlib.h"
+ #include "lualib.h"
+
++/* 'luai_vectpow()' as a replacement for 'cpow()'. Defined in the header; we
++ * don't intrude the code libs internal functions.
++ */
++#ifdef LNUM_COMPLEX
++# include "lnum.h"
++#endif
+
+ #undef PI
+-#define PI (3.14159265358979323846)
+-#define RADIANS_PER_DEGREE (PI/180.0)
+-
++#ifdef LNUM_FLOAT
++# define PI (3.14159265358979323846F)
++#elif defined(M_PI)
++# define PI M_PI
++#else
++# define PI (3.14159265358979323846264338327950288)
++#endif
++#define RADIANS_PER_DEGREE (PI/180)
+
++#undef HUGE
++#ifdef LNUM_FLOAT
++# define HUGE HUGE_VALF
++#elif defined(LNUM_LDOUBLE)
++# define HUGE HUGE_VALL
++#else
++# define HUGE HUGE_VAL
++#endif
+
+ static int math_abs (lua_State *L) {
+- lua_pushnumber(L, fabs(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushnumber(L, _LF(cabs) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(fabs) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_sin (lua_State *L) {
+- lua_pushnumber(L, sin(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(csin) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(sin) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_sinh (lua_State *L) {
+- lua_pushnumber(L, sinh(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(csinh) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(sinh) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_cos (lua_State *L) {
+- lua_pushnumber(L, cos(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(ccos) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(cos) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_cosh (lua_State *L) {
+- lua_pushnumber(L, cosh(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(ccosh) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(cosh) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_tan (lua_State *L) {
+- lua_pushnumber(L, tan(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(ctan) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(tan) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_tanh (lua_State *L) {
+- lua_pushnumber(L, tanh(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(ctanh) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(tanh) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_asin (lua_State *L) {
+- lua_pushnumber(L, asin(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(casin) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(asin) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_acos (lua_State *L) {
+- lua_pushnumber(L, acos(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(cacos) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(acos) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_atan (lua_State *L) {
+- lua_pushnumber(L, atan(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(catan) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(atan) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_atan2 (lua_State *L) {
+- lua_pushnumber(L, atan2(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
++ /* scalars only */
++ lua_pushnumber(L, _LF(atan2) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
+ return 1;
+ }
+
+ static int math_ceil (lua_State *L) {
+- lua_pushnumber(L, ceil(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_Complex v= luaL_checkcomplex(L, 1);
++ lua_pushcomplex(L, _LF(ceil) (_LF(creal)(v)) + _LF(ceil) (_LF(cimag)(v))*I);
++#else
++ lua_pushnumber(L, _LF(ceil) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_floor (lua_State *L) {
+- lua_pushnumber(L, floor(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_Complex v= luaL_checkcomplex(L, 1);
++ lua_pushcomplex(L, _LF(floor) (_LF(creal)(v)) + _LF(floor) (_LF(cimag)(v))*I);
++#else
++ lua_pushnumber(L, _LF(floor) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+-static int math_fmod (lua_State *L) {
+- lua_pushnumber(L, fmod(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
++static int math_fmod (lua_State *L) {
++ /* scalars only */
++ lua_pushnumber(L, _LF(fmod) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
+ return 1;
+ }
+
+ static int math_modf (lua_State *L) {
+- double ip;
+- double fp = modf(luaL_checknumber(L, 1), &ip);
++ /* scalars only */
++ lua_Number ip;
++ lua_Number fp = _LF(modf) (luaL_checknumber(L, 1), &ip);
+ lua_pushnumber(L, ip);
+ lua_pushnumber(L, fp);
+ return 2;
+ }
+
+ static int math_sqrt (lua_State *L) {
+- lua_pushnumber(L, sqrt(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(csqrt) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(sqrt) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_pow (lua_State *L) {
+- lua_pushnumber(L, pow(luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
++#ifdef LNUM_COMPLEX
++ /* C99 'cpow' gives somewhat inaccurate results (i.e. (-1)^2 = -1+1.2246467991474e-16i).
++ * 'luai_vectpow' smoothens such, reusing it is the reason we need to #include "lnum.h".
++ */
++ lua_pushcomplex(L, luai_vectpow(luaL_checkcomplex(L,1), luaL_checkcomplex(L,2)));
++#else
++ lua_pushnumber(L, _LF(pow) (luaL_checknumber(L, 1), luaL_checknumber(L, 2)));
++#endif
+ return 1;
+ }
+
+ static int math_log (lua_State *L) {
+- lua_pushnumber(L, log(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(log) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_log10 (lua_State *L) {
+- lua_pushnumber(L, log10(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ /* Not in standard <complex.h> , but easy to calculate: log_a(x) = log_b(x) / log_b(a)
++ */
++ lua_pushcomplex(L, _LF(clog) (luaL_checkcomplex(L,1)) / _LF(log) (10));
++#else
++ lua_pushnumber(L, _LF(log10) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+ static int math_exp (lua_State *L) {
+- lua_pushnumber(L, exp(luaL_checknumber(L, 1)));
++#ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(cexp) (luaL_checkcomplex(L,1)));
++#else
++ lua_pushnumber(L, _LF(exp) (luaL_checknumber(L, 1)));
++#endif
+ return 1;
+ }
+
+@@ -138,19 +234,20 @@ static int math_rad (lua_State *L) {
+
+ static int math_frexp (lua_State *L) {
+ int e;
+- lua_pushnumber(L, frexp(luaL_checknumber(L, 1), &e));
++ lua_pushnumber(L, _LF(frexp) (luaL_checknumber(L, 1), &e));
+ lua_pushinteger(L, e);
+ return 2;
+ }
+
+ static int math_ldexp (lua_State *L) {
+- lua_pushnumber(L, ldexp(luaL_checknumber(L, 1), luaL_checkint(L, 2)));
++ lua_pushnumber(L, _LF(ldexp) (luaL_checknumber(L, 1), luaL_checkint(L, 2)));
+ return 1;
+ }
+
+
+
+ static int math_min (lua_State *L) {
++ /* scalars only */
+ int n = lua_gettop(L); /* number of arguments */
+ lua_Number dmin = luaL_checknumber(L, 1);
+ int i;
+@@ -165,6 +262,7 @@ static int math_min (lua_State *L) {
+
+
+ static int math_max (lua_State *L) {
++ /* scalars only */
+ int n = lua_gettop(L); /* number of arguments */
+ lua_Number dmax = luaL_checknumber(L, 1);
+ int i;
+@@ -182,25 +280,20 @@ static int math_random (lua_State *L) {
+ /* the `%' avoids the (rare) case of r==1, and is needed also because on
+ some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
+ lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
+- switch (lua_gettop(L)) { /* check number of arguments */
+- case 0: { /* no arguments */
+- lua_pushnumber(L, r); /* Number between 0 and 1 */
+- break;
+- }
+- case 1: { /* only upper limit */
+- int u = luaL_checkint(L, 1);
+- luaL_argcheck(L, 1<=u, 1, "interval is empty");
+- lua_pushnumber(L, floor(r*u)+1); /* int between 1 and `u' */
+- break;
+- }
+- case 2: { /* lower and upper limits */
+- int l = luaL_checkint(L, 1);
+- int u = luaL_checkint(L, 2);
+- luaL_argcheck(L, l<=u, 2, "interval is empty");
+- lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
+- break;
+- }
+- default: return luaL_error(L, "wrong number of arguments");
++ int n= lua_gettop(L); /* number of arguments */
++ if (n==0) { /* no arguments: range [0,1) */
++ lua_pushnumber(L, r);
++ } else if (n<=2) { /* int range [1,u] or [l,u] */
++ int l= n==1 ? 1 : luaL_checkint(L, 1);
++ int u = luaL_checkint(L, n);
++ int tmp;
++ lua_Number d;
++ luaL_argcheck(L, l<=u, n, "interval is empty");
++ d= _LF(floor)(r*(u-l+1));
++ lua_number2int(tmp,d);
++ lua_pushinteger(L, l+tmp);
++ } else {
++ return luaL_error(L, "wrong number of arguments");
+ }
+ return 1;
+ }
+@@ -211,6 +304,66 @@ static int math_randomseed (lua_State *L
+ return 0;
+ }
+
++/*
++* Lua 5.1 does not have acosh, asinh, atanh for scalars (not ANSI C)
++*/
++#if __STDC_VERSION__ >= 199901L
++static int math_acosh (lua_State *L) {
++# ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(cacosh) (luaL_checkcomplex(L,1)));
++# else
++ lua_pushnumber(L, _LF(acosh) (luaL_checknumber(L,1)));
++# endif
++ return 1;
++}
++static int math_asinh (lua_State *L) {
++# ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(casinh) (luaL_checkcomplex(L,1)));
++# else
++ lua_pushnumber(L, _LF(asinh) (luaL_checknumber(L,1)));
++# endif
++ return 1;
++}
++static int math_atanh (lua_State *L) {
++# ifdef LNUM_COMPLEX
++ lua_pushcomplex(L, _LF(catanh) (luaL_checkcomplex(L,1)));
++# else
++ lua_pushnumber(L, _LF(atanh) (luaL_checknumber(L,1)));
++# endif
++ return 1;
++}
++#endif
++
++/*
++ * C99 complex functions, not covered above.
++*/
++#ifdef LNUM_COMPLEX
++static int math_arg (lua_State *L) {
++ lua_pushnumber(L, _LF(carg) (luaL_checkcomplex(L,1)));
++ return 1;
++}
++
++static int math_imag (lua_State *L) {
++ lua_pushnumber(L, _LF(cimag) (luaL_checkcomplex(L,1)));
++ return 1;
++}
++
++static int math_real (lua_State *L) {
++ lua_pushnumber(L, _LF(creal) (luaL_checkcomplex(L,1)));
++ return 1;
++}
++
++static int math_conj (lua_State *L) {
++ lua_pushcomplex(L, _LF(conj) (luaL_checkcomplex(L,1)));
++ return 1;
++}
++
++static int math_proj (lua_State *L) {
++ lua_pushcomplex(L, _LF(cproj) (luaL_checkcomplex(L,1)));
++ return 1;
++}
++#endif
++
+
+ static const luaL_Reg mathlib[] = {
+ {"abs", math_abs},
+@@ -241,6 +394,18 @@ static const luaL_Reg mathlib[] = {
+ {"sqrt", math_sqrt},
+ {"tanh", math_tanh},
+ {"tan", math_tan},
++#if __STDC_VERSION__ >= 199901L
++ {"acosh", math_acosh},
++ {"asinh", math_asinh},
++ {"atanh", math_atanh},
++#endif
++#ifdef LNUM_COMPLEX
++ {"arg", math_arg},
++ {"imag", math_imag},
++ {"real", math_real},
++ {"conj", math_conj},
++ {"proj", math_proj},
++#endif
+ {NULL, NULL}
+ };
+
+@@ -252,8 +417,10 @@ LUALIB_API int luaopen_math (lua_State *
+ luaL_register(L, LUA_MATHLIBNAME, mathlib);
+ lua_pushnumber(L, PI);
+ lua_setfield(L, -2, "pi");
+- lua_pushnumber(L, HUGE_VAL);
++ lua_pushnumber(L, HUGE);
+ lua_setfield(L, -2, "huge");
++ lua_pushinteger(L, LUA_INTEGER_MAX );
++ lua_setfield(L, -2, "hugeint");
+ #if defined(LUA_COMPAT_MOD)
+ lua_getfield(L, -1, "fmod");
+ lua_setfield(L, -2, "mod");
+--- /dev/null
++++ b/src/lnum.c
+@@ -0,0 +1,312 @@
++/*
++** $Id: lnum.c,v ... $
++** Internal number model
++** See Copyright Notice in lua.h
++*/
++
++#include <stdlib.h>
++#include <math.h>
++#include <ctype.h>
++#include <string.h>
++#include <stdio.h>
++#include <errno.h>
++
++#define lnum_c
++#define LUA_CORE
++
++#include "lua.h"
++#include "llex.h"
++#include "lnum.h"
++
++/*
++** lua_real2str converts a (non-complex) number to a string.
++** lua_str2real converts a string to a (non-complex) number.
++*/
++#define lua_real2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
++
++/*
++* Note: Only 'strtod()' is part of ANSI C; others are C99 and
++* may need '--std=c99' compiler setting (at least on Ubuntu 7.10).
++*
++* Visual C++ 2008 Express does not have 'strtof()', nor 'strtold()'.
++* References to '_strtold()' exist but don't compile. It seems best
++* to leave Windows users with DOUBLE only (or compile with MinGW).
++*
++* In practise, using '(long double)strtod' is a risky thing, since
++* it will cause accuracy loss in reading in numbers, and such losses
++* will pile up in later processing. Get a real 'strtold()' or don't
++* use that mode at all.
++*/
++#ifdef LNUM_DOUBLE
++# define lua_str2real strtod
++#elif defined(LNUM_FLOAT)
++# define lua_str2real strtof
++#elif defined(LNUM_LDOUBLE)
++# define lua_str2real strtold
++#endif
++
++#define lua_integer2str(s,v) sprintf((s), LUA_INTEGER_FMT, (v))
++
++/* 's' is expected to be LUAI_MAXNUMBER2STR long (enough for any number)
++*/
++void luaO_num2buf( char *s, const TValue *o )
++{
++ lua_Number n;
++ lua_assert( ttisnumber(o) );
++
++ /* Reason to handle integers differently is not only speed, but accuracy as
++ * well. We want to make any integer tostring() without roundings, at all.
++ */
++ if (ttisint(o)) {
++ lua_integer2str( s, ivalue(o) );
++ return;
++ }
++ n= nvalue_fast(o);
++ lua_real2str(s, n);
++
++#ifdef LNUM_COMPLEX
++ lua_Number n2= nvalue_img_fast(o);
++ if (n2!=0) { /* Postfix with +-Ni */
++ int re0= (n == 0);
++ char *s2= re0 ? s : strchr(s,'\0');
++ if ((!re0) && (n2>0)) *s2++= '+';
++ lua_real2str( s2, n2 );
++ strcat(s2,"i");
++ }
++#endif
++}
++
++/*
++* If a LUA_TNUMBER has integer value, give it.
++*/
++int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref ) {
++ lua_Number d;
++ lua_Integer i;
++
++ lua_assert( ttype(o)==LUA_TNUMBER );
++ lua_assert( ref );
++#ifdef LNUM_COMPLEX
++ if (nvalue_img_fast(o)!=0) return 0;
++#endif
++ d= nvalue_fast(o);
++ lua_number2integer(i, d);
++ if (cast_num(i) == d) {
++ *ref= i; return 1;
++ }
++ return 0;
++}
++
++/*
++ * Lua 5.1.3 (using 'strtod()') allows 0x+hex but not 0+octal. This is good,
++ * and we should NOT use 'autobase' 0 with 'strtoul[l]()' for this reason.
++ *
++ * Lua 5.1.3 allows '0x...' numbers to overflow and lose precision; this is not
++ * good. On Visual C++ 2008, 'strtod()' does not even take them in. Better to
++ * require hex values to fit 'lua_Integer' or give an error that they don't?
++ *
++ * Full hex range (0 .. 0xff..ff) is stored as integers, not to lose any bits.
++ * Numerical value of 0xff..ff will be -1, if used in calculations.
++ *
++ * Returns: TK_INT for a valid integer, '*endptr_ref' updated
++ * TK_NUMBER for seemingly numeric, to be parsed as floating point
++ * 0 for bad characters, not a number (or '0x' out of range)
++ */
++static int luaO_str2i (const char *s, lua_Integer *res, char **endptr_ref) {
++ char *endptr;
++ /* 'v' gets ULONG_MAX on possible overflow (which is > LUA_INTEGER_MAX);
++ * we don't have to check 'errno' here.
++ */
++ unsigned LUA_INTEGER v= lua_str2ul(s, &endptr, 10);
++ if (endptr == s) return 0; /* nothing numeric */
++ if (v==0 && *endptr=='x') {
++ errno= 0; /* needs to be set, 'strtoul[l]' does not clear it */
++ v= lua_str2ul(endptr+1, &endptr, 16); /* retry as hex, unsigned range */
++ if (errno==ERANGE) { /* clamped to 0xff..ff */
++#if (defined(LNUM_INT32) && !defined(LNUM_FLOAT)) || defined(LNUM_LDOUBLE)
++ return TK_NUMBER; /* Allow to be read as floating point (has more integer range) */
++#else
++ return 0; /* Reject the number */
++#endif
++ }
++ } else if ((v > LUA_INTEGER_MAX) || (*endptr && (!isspace(*endptr)))) {
++ return TK_NUMBER; /* not in signed range, or has '.', 'e' etc. trailing */
++ }
++ *res= (lua_Integer)v;
++ *endptr_ref= endptr;
++ return TK_INT;
++}
++
++/* 0 / TK_NUMBER / TK_INT (/ TK_NUMBER2) */
++int luaO_str2d (const char *s, lua_Number *res_n, lua_Integer *res_i) {
++ char *endptr;
++ int ret= TK_NUMBER;
++ /* Check integers first, if caller is allowing.
++ * If 'res2'==NULL, they're only looking for floating point.
++ */
++ if (res_i) {
++ ret= luaO_str2i(s,res_i,&endptr);
++ if (ret==0) return 0;
++ }
++ if (ret==TK_NUMBER) {
++ lua_assert(res_n);
++ /* Note: Visual C++ 2008 Express 'strtod()' does not read in "0x..."
++ * numbers; it will read '0' and spit 'x' as endptr.
++ * This means hex constants not fitting in 'lua_Integer' won't
++ * be read in at all. What to do?
++ */
++ *res_n = lua_str2real(s, &endptr);
++ if (endptr == s) return 0; /* conversion failed */
++ /* Visual C++ 2008 'strtod()' does not allow "0x..." input. */
++#if defined(_MSC_VER) && !defined(LNUM_FLOAT) && !defined(LNUM_INT64)
++ if (*res_n==0 && *endptr=='x') {
++ /* Hex constant too big for 'lua_Integer' but that could fit in 'lua_Number'
++ * integer bits
++ */
++ unsigned __int64 v= _strtoui64( s, &endptr, 16 );
++ /* We just let > 64 bit values be clamped to _UI64_MAX (MSDN does not say 'errno'==ERANGE would be set) */
++ *res_n= cast_num(v);
++ if (*res_n != v) return 0; /* Would have lost accuracy */
++ }
++#endif
++#ifdef LNUM_COMPLEX
++ if (*endptr == 'i') { endptr++; ret= TK_NUMBER2; }
++#endif
++ }
++ if (*endptr) {
++ while (isspace(cast(unsigned char, *endptr))) endptr++;
++ if (*endptr) return 0; /* invalid trail */
++ }
++ return ret;
++}
++
++
++/* Functions for finding out, when integer operations remain in range
++ * (and doing them).
++ */
++int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++ lua_Integer v= ib+ic; /* may overflow */
++ if (ib>0 && ic>0) { if (v < 0) return 0; /*overflow, use floats*/ }
++ else if (ib<0 && ic<0) { if (v >= 0) return 0; }
++ *r= v;
++ return 1;
++}
++
++int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++ lua_Integer v= ib-ic; /* may overflow */
++ if (ib>=0 && ic<0) { if (v < 0) return 0; /*overflow, use floats*/ }
++ else if (ib<0 && ic>0) { if (v >= 0) return 0; }
++ *r= v;
++ return 1;
++}
++
++int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++ if (ib!=LUA_INTEGER_MIN && ic!=LUA_INTEGER_MIN) {
++ lua_Integer b= luai_abs(ib), c= luai_abs(ic);
++ if ( (ib==0) || (LUA_INTEGER_MAX/b >= c) ) {
++ *r= ib*ic; /* no overflow */
++ return 1;
++ }
++ } else if (ib==0 || ic==0) {
++ *r= 0; return 1;
++ }
++
++ /* Result can be LUA_INTEGER_MIN; if it is, calculating it using floating
++ * point will not cause accuracy loss.
++ */
++ if ( luai_nummul( cast_num(ib), cast_num(ic) ) == LUA_INTEGER_MIN ) {
++ *r= LUA_INTEGER_MIN;
++ return 1;
++ }
++ return 0;
++}
++
++int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++ /* N/0: leave to float side, to give an error
++ */
++ if (ic==0) return 0;
++
++ /* N/LUA_INTEGER_MIN: always non-integer results, or 0 or +1
++ */
++ if (ic==LUA_INTEGER_MIN) {
++ if (ib==LUA_INTEGER_MIN) { *r=1; return 1; }
++ if (ib==0) { *r=0; return 1; }
++
++ /* LUA_INTEGER_MIN (-2^31|63)/N: calculate using float side (either the division
++ * causes non-integer results, or there is no accuracy loss in int->fp->int
++ * conversions (N=2,4,8,..,256 and N=2^30,2^29,..2^23).
++ */
++ } else if (ib==LUA_INTEGER_MIN) {
++ lua_Number d= luai_numdiv( cast_num(LUA_INTEGER_MIN), cast_num(ic) );
++ lua_Integer i; lua_number2integer(i,d);
++ if (cast_num(i)==d) { *r= i; return 1; }
++
++ } else {
++ /* Note: We _can_ use ANSI C mod here, even on negative values, since
++ * we only test for == 0 (the sign would be implementation dependent).
++ */
++ if (ib%ic == 0) { *r= ib/ic; return 1; }
++ }
++
++ return 0;
++}
++
++int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++ if (ic!=0) {
++ /* ANSI C can be trusted when b%c==0, or when values are non-negative.
++ * b - (floor(b/c) * c)
++ * -->
++ * + +: b - (b/c) * c (b % c can be used)
++ * - -: b - (b/c) * c (b % c could work, but not defined by ANSI C)
++ * 0 -: b - (b/c) * c (=0, b % c could work, but not defined by ANSI C)
++ * - +: b - (b/c-1) * c (when b!=-c)
++ * + -: b - (b/c-1) * c (when b!=-c)
++ *
++ * o MIN%MIN ends up 0, via overflow in calcs but that does not matter.
++ * o MIN%MAX ends up MAX-1 (and other such numbers), also after overflow,
++ * but that does not matter, results do.
++ */
++ lua_Integer v= ib % ic;
++ if ( v!=0 && (ib<0 || ic<0) ) {
++ v= ib - ((ib/ic) - ((ib<=0 && ic<0) ? 0:1)) * ic;
++ }
++ /* Result should always have same sign as 2nd argument. (PIL2) */
++ lua_assert( (v<0) ? (ic<0) : (v>0) ? (ic>0) : 1 );
++ *r= v;
++ return 1;
++ }
++ return 0; /* let float side return NaN */
++}
++
++int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic ) {
++
++ /* In FLOAT/INT32 or FLOAT|DOUBLE/INT64 modes, calculating integer powers
++ * via FP realm may lose accuracy (i.e. 7^11 = 1977326743, which fits int32
++ * but not 23-bit float mantissa).
++ *
++ * The current solution is dumb, but it works and uses little code. Use of
++ * integer powers is not anticipated to be very frequent (apart from 2^x,
++ * which is separately optimized).
++ */
++ if (ib==0) *r=0;
++ else if (ic<0) return 0; /* FP realm */
++ else if (ib==2 && ic < (int)sizeof(lua_Integer)*8-1) *r= ((lua_Integer)1)<<ic; /* 1,2,4,...2^30 | 2^62 optimization */
++ else if (ic==0) *r=1;
++ else if (luai_abs(ib)==1) *r= (ic%2) ? ib:1;
++ else {
++ lua_Integer x= ib;
++ while( --ic ) {
++ if (!try_mulint( &x, x, ib ))
++ return 0; /* FP realm */
++ }
++ *r= x;
++ }
++ return 1;
++}
++
++int try_unmint( lua_Integer *r, lua_Integer ib ) {
++ /* Negating LUA_INTEGER_MIN leaves the range. */
++ if ( ib != LUA_INTEGER_MIN )
++ { *r= -ib; return 1; }
++ return 0;
++}
++
+--- /dev/null
++++ b/src/lnum.h
+@@ -0,0 +1,116 @@
++/*
++** $Id: lnum.h,v ... $
++** Internal Number model
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lnum_h
++#define lnum_h
++
++#include <math.h>
++
++#include "lobject.h"
++
++/*
++** The luai_num* macros define the primitive operations over 'lua_Number's
++** (not 'lua_Integer's, not 'lua_Complex').
++*/
++#define luai_numadd(a,b) ((a)+(b))
++#define luai_numsub(a,b) ((a)-(b))
++#define luai_nummul(a,b) ((a)*(b))
++#define luai_numdiv(a,b) ((a)/(b))
++#define luai_nummod(a,b) ((a) - _LF(floor)((a)/(b))*(b))
++#define luai_numpow(a,b) (_LF(pow)(a,b))
++#define luai_numunm(a) (-(a))
++#define luai_numeq(a,b) ((a)==(b))
++#define luai_numlt(a,b) ((a)<(b))
++#define luai_numle(a,b) ((a)<=(b))
++#define luai_numisnan(a) (!luai_numeq((a), (a)))
++
++int try_addint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_subint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_mulint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_divint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_modint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_powint( lua_Integer *r, lua_Integer ib, lua_Integer ic );
++int try_unmint( lua_Integer *r, lua_Integer ib );
++
++#ifdef LNUM_COMPLEX
++ static inline lua_Complex luai_vectunm( lua_Complex a ) { return -a; }
++ static inline lua_Complex luai_vectadd( lua_Complex a, lua_Complex b ) { return a+b; }
++ static inline lua_Complex luai_vectsub( lua_Complex a, lua_Complex b ) { return a-b; }
++ static inline lua_Complex luai_vectmul( lua_Complex a, lua_Complex b ) { return a*b; }
++ static inline lua_Complex luai_vectdiv( lua_Complex a, lua_Complex b ) { return a/b; }
++
++/*
++ * C99 does not provide modulus for complex numbers. It most likely is not
++ * meaningful at all.
++ */
++
++/*
++ * Complex power
++ *
++ * C99 'cpow' gives inaccurate results for many common cases s.a. (1i)^2 ->
++ * -1+1.2246467991474e-16i (OS X 10.4, gcc 4.0.1 build 5367)
++ *
++ * [(a+bi)^(c+di)] = (r^c) * exp(-d*t) * cos(c*t + d*ln(r)) +
++ * = (r^c) * exp(-d*t) * sin(c*t + d*ln(r)) *i
++ * r = sqrt(a^2+b^2), t = arctan( b/a )
++ *
++ * Reference: <http://home.att.net/~srschmitt/complexnumbers.html>
++ * Could also be calculated using: x^y = exp(ln(x)*y)
++ *
++ * Note: Defined here (and not in .c) so 'lmathlib.c' can share the
++ * implementation.
++ */
++ static inline
++ lua_Complex luai_vectpow( lua_Complex a, lua_Complex b )
++ {
++# if 1
++ lua_Number ar= _LF(creal)(a), ai= _LF(cimag)(a);
++ lua_Number br= _LF(creal)(b), bi= _LF(cimag)(b);
++
++ if (ai==0 && bi==0) { /* a^c (real) */
++ return luai_numpow( ar, br );
++ }
++
++ int br_int= (int)br;
++
++ if ( ai!=0 && bi==0 && br_int==br && br_int!=0 && br_int!=INT_MIN ) {
++ /* (a+bi)^N, N = { +-1,+-2, ... +-INT_MAX }
++ */
++ lua_Number k= luai_numpow( _LF(sqrt) (ar*ar + ai*ai), br );
++ lua_Number cos_z, sin_z;
++
++ /* Situation depends upon c (N) in the following manner:
++ *
++ * N%4==0 => cos(c*t)=1, sin(c*t)=0
++ * (N*sign(b))%4==1 or (N*sign(b))%4==-3 => cos(c*t)=0, sin(c*t)=1
++ * N%4==2 or N%4==-2 => cos(c*t)=-1, sin(c*t)=0
++ * (N*sign(b))%4==-1 or (N*sign(b))%4==3 => cos(c*t)=0, sin(c*t)=-1
++ */
++ int br_int_abs = br_int<0 ? -br_int:br_int;
++
++ switch( (br_int_abs%4) * (br_int<0 ? -1:1) * (ai<0 ? -1:1) ) {
++ case 0: cos_z=1, sin_z=0; break;
++ case 2: case -2: cos_z=-1, sin_z=0; break;
++ case 1: case -3: cos_z=0, sin_z=1; break;
++ case 3: case -1: cos_z=0, sin_z=-1; break;
++ default: lua_assert(0); return 0;
++ }
++ return k*cos_z + (k*sin_z)*I;
++ }
++# endif
++ return _LF(cpow) ( a, b );
++ }
++#endif
++
++LUAI_FUNC int luaO_str2d (const char *s, lua_Number *res1, lua_Integer *res2);
++LUAI_FUNC void luaO_num2buf( char *s, const TValue *o );
++
++LUAI_FUNC int /*bool*/ tt_integer_valued( const TValue *o, lua_Integer *ref );
++
++#define luai_normalize(o) \
++{ lua_Integer _i; if (tt_integer_valued(o,&_i)) setivalue(o,_i); }
++
++#endif
+--- /dev/null
++++ b/src/lnum_config.h
+@@ -0,0 +1,221 @@
++/*
++** $Id: lnum_config.h,v ... $
++** Internal Number model
++** See Copyright Notice in lua.h
++*/
++
++#ifndef lnum_config_h
++#define lnum_config_h
++
++/*
++** Default number modes
++*/
++#if (!defined LNUM_DOUBLE) && (!defined LNUM_FLOAT) && (!defined LNUM_LDOUBLE)
++# define LNUM_FLOAT
++#endif
++#if (!defined LNUM_INT16) && (!defined LNUM_INT32) && (!defined LNUM_INT64)
++# define LNUM_INT32
++#endif
++
++/*
++** Require C99 mode for COMPLEX, FLOAT and LDOUBLE (only DOUBLE is ANSI C).
++*/
++#if defined(LNUM_COMPLEX) && (__STDC_VERSION__ < 199901L)
++# error "Need C99 for complex (use '--std=c99' or similar)"
++#elif defined(LNUM_LDOUBLE) && (__STDC_VERSION__ < 199901L) && !defined(_MSC_VER)
++# error "Need C99 for 'long double' (use '--std=c99' or similar)"
++#elif defined(LNUM_FLOAT) && (__STDC_VERSION__ < 199901L)
++/* LNUM_FLOAT not supported on Windows */
++# error "Need C99 for 'float' (use '--std=c99' or similar)"
++#endif
++
++/*
++** Number mode identifier to accompany the version string.
++*/
++#ifdef LNUM_COMPLEX
++# define _LNUM1 "complex "
++#else
++# define _LNUM1 ""
++#endif
++#ifdef LNUM_DOUBLE
++# define _LNUM2 "double"
++#elif defined(LNUM_FLOAT)
++# define _LNUM2 "float"
++#elif defined(LNUM_LDOUBLE)
++# define _LNUM2 "ldouble"
++#endif
++#ifdef LNUM_INT32
++# define _LNUM3 "int32"
++#elif defined(LNUM_INT64)
++# define _LNUM3 "int64"
++#elif defined(LNUM_INT16)
++# define _LNUM3 "int16"
++#endif
++#define LUA_LNUM _LNUM1 _LNUM2 " " _LNUM3
++
++/*
++** LUA_NUMBER is the type of floating point number in Lua
++** LUA_NUMBER_SCAN is the format for reading numbers.
++** LUA_NUMBER_FMT is the format for writing numbers.
++*/
++#ifdef LNUM_FLOAT
++# define LUA_NUMBER float
++# define LUA_NUMBER_SCAN "%f"
++# define LUA_NUMBER_FMT "%g"
++#elif (defined LNUM_DOUBLE)
++# define LUA_NUMBER double
++# define LUA_NUMBER_SCAN "%lf"
++# define LUA_NUMBER_FMT "%.14g"
++#elif (defined LNUM_LDOUBLE)
++# define LUA_NUMBER long double
++# define LUA_NUMBER_SCAN "%Lg"
++# define LUA_NUMBER_FMT "%.20Lg"
++#endif
++
++
++/*
++** LUAI_MAXNUMBER2STR: size of a buffer fitting any number->string result.
++**
++** double: 24 (sign, x.xxxxxxxxxxxxxxe+nnnn, and \0)
++** int64: 21 (19 digits, sign, and \0)
++** long double: 43 for 128-bit (sign, x.xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxe+nnnn, and \0)
++** 30 for 80-bit (sign, x.xxxxxxxxxxxxxxxxxxxxe+nnnn, and \0)
++*/
++#ifdef LNUM_LDOUBLE
++# define _LUAI_MN2S 44
++#else
++# define _LUAI_MN2S 24
++#endif
++
++#ifdef LNUM_COMPLEX
++# define LUAI_MAXNUMBER2STR (2*_LUAI_MN2S)
++#else
++# define LUAI_MAXNUMBER2STR _LUAI_MN2S
++#endif
++
++/*
++** LUA_INTEGER is the integer type used by lua_pushinteger/lua_tointeger/lua_isinteger.
++** LUA_INTEGER_SCAN is the format for reading integers
++** LUA_INTEGER_FMT is the format for writing integers
++**
++** Note: Visual C++ 2005 does not have 'strtoull()', use '_strtoui64()' instead.
++*/
++#ifdef LNUM_INT32
++# if LUAI_BITSINT > 16
++# define LUA_INTEGER int
++# define LUA_INTEGER_SCAN "%d"
++# define LUA_INTEGER_FMT "%d"
++# else
++/* Note: 'LUA_INTEGER' being 'ptrdiff_t' (as in Lua 5.1) causes problems with
++ * 'printf()' operations. Also 'unsigned ptrdiff_t' is invalid.
++ */
++# define LUA_INTEGER long
++# define LUA_INTEGER_SCAN "%ld"
++# define LUA_INTEGER_FMT "%ld"
++# endif
++# define LUA_INTEGER_MAX 0x7FFFFFFF /* 2^31-1 */
++/* */
++#elif defined(LNUM_INT64)
++# define LUA_INTEGER long long
++# ifdef _MSC_VER
++# define lua_str2ul _strtoui64
++# else
++# define lua_str2ul strtoull
++# endif
++# define LUA_INTEGER_SCAN "%lld"
++# define LUA_INTEGER_FMT "%lld"
++# define LUA_INTEGER_MAX 0x7fffffffffffffffLL /* 2^63-1 */
++# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX - 1LL) /* -2^63 */
++/* */
++#elif defined(LNUM_INT16)
++# if LUAI_BITSINT > 16
++# define LUA_INTEGER short
++# define LUA_INTEGER_SCAN "%hd"
++# define LUA_INTEGER_FMT "%hd"
++# else
++# define LUA_INTEGER int
++# define LUA_INTEGER_SCAN "%d"
++# define LUA_INTEGER_FMT "%d"
++# endif
++# define LUA_INTEGER_MAX 0x7FFF /* 2^16-1 */
++#endif
++
++#ifndef lua_str2ul
++# define lua_str2ul (unsigned LUA_INTEGER)strtoul
++#endif
++#ifndef LUA_INTEGER_MIN
++# define LUA_INTEGER_MIN (-LUA_INTEGER_MAX -1) /* -2^16|32 */
++#endif
++
++/*
++@@ lua_number2int is a macro to convert lua_Number to int.
++@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
++** CHANGE them if you know a faster way to convert a lua_Number to
++** int (with any rounding method and without throwing errors) in your
++** system. In Pentium machines, a naive typecast from double to int
++** in C is extremely slow, so any alternative is worth trying.
++*/
++
++/* On a Pentium, resort to a trick */
++#if defined(LNUM_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
++ (defined(__i386) || defined (_M_IX86) || defined(__i386__))
++
++/* On a Microsoft compiler, use assembler */
++# if defined(_MSC_VER)
++# define lua_number2int(i,d) __asm fld d __asm fistp i
++# else
++
++/* the next trick should work on any Pentium, but sometimes clashes
++ with a DirectX idiosyncrasy */
++union luai_Cast { double l_d; long l_l; };
++# define lua_number2int(i,d) \
++ { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
++# endif
++
++# ifndef LNUM_INT64
++# define lua_number2integer lua_number2int
++# endif
++
++/* this option always works, but may be slow */
++#else
++# define lua_number2int(i,d) ((i)=(int)(d))
++#endif
++
++/* Note: Some compilers (OS X gcc 4.0?) may choke on double->long long conversion
++ * since it can lose precision. Others do require 'long long' there.
++ */
++#ifndef lua_number2integer
++# define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
++#endif
++
++/*
++** 'luai_abs()' to give absolute value of 'lua_Integer'
++*/
++#ifdef LNUM_INT32
++# define luai_abs abs
++#elif defined(LNUM_INT64) && (__STDC_VERSION__ >= 199901L)
++# define luai_abs llabs
++#else
++# define luai_abs(v) ((v) >= 0 ? (v) : -(v))
++#endif
++
++/*
++** LUAI_UACNUMBER is the result of an 'usual argument conversion' over a number.
++** LUAI_UACINTEGER the same, over an integer.
++*/
++#define LUAI_UACNUMBER double
++#define LUAI_UACINTEGER long
++
++/* ANSI C only has math funcs for 'double. C99 required for float and long double
++ * variants.
++ */
++#ifdef LNUM_DOUBLE
++# define _LF(name) name
++#elif defined(LNUM_FLOAT)
++# define _LF(name) name ## f
++#elif defined(LNUM_LDOUBLE)
++# define _LF(name) name ## l
++#endif
++
++#endif
++
+--- a/src/lobject.c
++++ b/src/lobject.c
+@@ -21,7 +21,8 @@
+ #include "lstate.h"
+ #include "lstring.h"
+ #include "lvm.h"
+-
++#include "llex.h"
++#include "lnum.h"
+
+
+ const TValue luaO_nilobject_ = {{NULL}, LUA_TNIL};
+@@ -70,12 +71,31 @@ int luaO_log2 (unsigned int x) {
+
+
+ int luaO_rawequalObj (const TValue *t1, const TValue *t2) {
+- if (ttype(t1) != ttype(t2)) return 0;
++ if (!ttype_ext_same(t1,t2)) return 0;
+ else switch (ttype(t1)) {
+ case LUA_TNIL:
+ return 1;
++ case LUA_TINT:
++ if (ttype(t2)==LUA_TINT)
++ return ivalue(t1) == ivalue(t2);
++ else { /* t1:int, t2:num */
++#ifdef LNUM_COMPLEX
++ if (nvalue_img_fast(t2) != 0) return 0;
++#endif
++ /* Avoid doing accuracy losing cast, if possible. */
++ lua_Integer tmp;
++ if (tt_integer_valued(t2,&tmp))
++ return ivalue(t1) == tmp;
++ else
++ return luai_numeq( cast_num(ivalue(t1)), nvalue_fast(t2) );
++ }
+ case LUA_TNUMBER:
+- return luai_numeq(nvalue(t1), nvalue(t2));
++ if (ttype(t2)==LUA_TINT)
++ return luaO_rawequalObj(t2, t1); /* swap LUA_TINT to left */
++#ifdef LNUM_COMPLEX
++ if (!luai_numeq(nvalue_img_fast(t1), nvalue_img_fast(t2))) return 0;
++#endif
++ return luai_numeq(nvalue_fast(t1), nvalue_fast(t2));
+ case LUA_TBOOLEAN:
+ return bvalue(t1) == bvalue(t2); /* boolean true must be 1 !! */
+ case LUA_TLIGHTUSERDATA:
+@@ -86,21 +106,6 @@ int luaO_rawequalObj (const TValue *t1,
+ }
+ }
+
+-
+-int luaO_str2d (const char *s, lua_Number *result) {
+- char *endptr;
+- *result = lua_str2number(s, &endptr);
+- if (endptr == s) return 0; /* conversion failed */
+- if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
+- *result = cast_num(strtoul(s, &endptr, 16));
+- if (*endptr == '\0') return 1; /* most common case */
+- while (isspace(cast(unsigned char, *endptr))) endptr++;
+- if (*endptr != '\0') return 0; /* invalid trailing characters? */
+- return 1;
+-}
+-
+-
+-
+ static void pushstr (lua_State *L, const char *str) {
+ setsvalue2s(L, L->top, luaS_new(L, str));
+ incr_top(L);
+@@ -131,7 +136,11 @@ const char *luaO_pushvfstring (lua_State
+ break;
+ }
+ case 'd': {
+- setnvalue(L->top, cast_num(va_arg(argp, int)));
++ /* This is tricky for 64-bit integers; maybe they even cannot be
++ * supported on all compilers; depends on the conversions applied to
++ * variable argument lists. TBD: test!
++ */
++ setivalue(L->top, (lua_Integer) va_arg(argp, l_uacInteger));
+ incr_top(L);
+ break;
+ }
+@@ -212,3 +221,4 @@ void luaO_chunkid (char *out, const char
+ }
+ }
+ }
++
+--- a/src/lobject.h
++++ b/src/lobject.h
+@@ -17,7 +17,11 @@
+
+
+ /* tags for values visible from Lua */
+-#define LAST_TAG LUA_TTHREAD
++#if LUA_TINT > LUA_TTHREAD
++# define LAST_TAG LUA_TINT
++#else
++# define LAST_TAG LUA_TTHREAD
++#endif
+
+ #define NUM_TAGS (LAST_TAG+1)
+
+@@ -59,7 +63,12 @@ typedef struct GCheader {
+ typedef union {
+ GCObject *gc;
+ void *p;
++#ifdef LNUM_COMPLEX
++ lua_Complex n;
++#else
+ lua_Number n;
++#endif
++ lua_Integer i;
+ int b;
+ } Value;
+
+@@ -77,7 +86,11 @@ typedef struct lua_TValue {
+
+ /* Macros to test type */
+ #define ttisnil(o) (ttype(o) == LUA_TNIL)
+-#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
++#define ttisint(o) (ttype(o) == LUA_TINT)
++#define ttisnumber(o) ((ttype(o) == LUA_TINT) || (ttype(o) == LUA_TNUMBER))
++#ifdef LNUM_COMPLEX
++# define ttiscomplex(o) ((ttype(o) == LUA_TNUMBER) && (nvalue_img_fast(o)!=0))
++#endif
+ #define ttisstring(o) (ttype(o) == LUA_TSTRING)
+ #define ttistable(o) (ttype(o) == LUA_TTABLE)
+ #define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
+@@ -90,7 +103,25 @@ typedef struct lua_TValue {
+ #define ttype(o) ((o)->tt)
+ #define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
+ #define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
+-#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
++
++#define ttype_ext(o) ( ttype(o) == LUA_TINT ? LUA_TNUMBER : ttype(o) )
++#define ttype_ext_same(o1,o2) ( (ttype(o1)==ttype(o2)) || (ttisnumber(o1) && ttisnumber(o2)) )
++
++/* '_fast' variants are for cases where 'ttype(o)' is known to be LUA_TNUMBER.
++ */
++#ifdef LNUM_COMPLEX
++# define nvalue_complex_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n )
++# define nvalue_fast(o) ( _LF(creal) ( nvalue_complex_fast(o) ) )
++# define nvalue_img_fast(o) ( _LF(cimag) ( nvalue_complex_fast(o) ) )
++# define nvalue_complex(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? (o)->value.i : (o)->value.n )
++# define nvalue_img(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? 0 : _LF(cimag)( (o)->value.n ) )
++# define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : _LF(creal)((o)->value.n) )
++#else
++# define nvalue(o) check_exp( ttisnumber(o), (ttype(o)==LUA_TINT) ? cast_num((o)->value.i) : (o)->value.n )
++# define nvalue_fast(o) check_exp( ttype(o)==LUA_TNUMBER, (o)->value.n )
++#endif
++#define ivalue(o) check_exp( ttype(o)==LUA_TINT, (o)->value.i )
++
+ #define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
+ #define tsvalue(o) (&rawtsvalue(o)->tsv)
+ #define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
+@@ -116,8 +147,27 @@ typedef struct lua_TValue {
+ /* Macros to set values */
+ #define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
+
+-#define setnvalue(obj,x) \
+- { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
++/* Must not have side effects, 'x' may be expression.
++*/
++#define setivalue(obj,x) \
++ { TValue *i_o=(obj); i_o->value.i=(x); i_o->tt=LUA_TINT; }
++
++# define setnvalue(obj,x) \
++ { TValue *i_o=(obj); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; }
++
++/* Note: Complex always has "inline", both are C99.
++*/
++#ifdef LNUM_COMPLEX
++ static inline void setnvalue_complex_fast( TValue *obj, lua_Complex x ) {
++ lua_assert( _LF(cimag)(x) != 0 );
++ obj->value.n= x; obj->tt= LUA_TNUMBER;
++ }
++ static inline void setnvalue_complex( TValue *obj, lua_Complex x ) {
++ if (_LF(cimag)(x) == 0) { setnvalue(obj, _LF(creal)(x)); }
++ else { obj->value.n= x; obj->tt= LUA_TNUMBER; }
++ }
++#endif
++
+
+ #define setpvalue(obj,x) \
+ { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
+@@ -155,9 +205,6 @@ typedef struct lua_TValue {
+ i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
+ checkliveness(G(L),i_o); }
+
+-
+-
+-
+ #define setobj(L,obj1,obj2) \
+ { const TValue *o2=(obj2); TValue *o1=(obj1); \
+ o1->value = o2->value; o1->tt=o2->tt; \
+@@ -185,8 +232,11 @@ typedef struct lua_TValue {
+
+ #define setttype(obj, tt) (ttype(obj) = (tt))
+
+-
+-#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
++#if LUA_TINT >= LUA_TSTRING
++# define iscollectable(o) ((ttype(o) >= LUA_TSTRING) && (ttype(o) != LUA_TINT))
++#else
++# define iscollectable(o) (ttype(o) >= LUA_TSTRING)
++#endif
+
+
+
+@@ -370,12 +420,10 @@ LUAI_FUNC int luaO_log2 (unsigned int x)
+ LUAI_FUNC int luaO_int2fb (unsigned int x);
+ LUAI_FUNC int luaO_fb2int (int x);
+ LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
+-LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
+ LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
+ va_list argp);
+ LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
+ LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len);
+
+-
+ #endif
+
+--- a/src/loslib.c
++++ b/src/loslib.c
+@@ -186,15 +186,30 @@ static int os_time (lua_State *L) {
+ }
+ if (t == (time_t)(-1))
+ lua_pushnil(L);
+- else
+- lua_pushnumber(L, (lua_Number)t);
++ else {
++ /* On float systems the pushed value must be an integer, NOT a number.
++ * Otherwise, accuracy is lost in the time_t->float conversion.
++ */
++#ifdef LNUM_FLOAT
++ lua_pushinteger(L, (lua_Integer) t);
++#else
++ lua_pushnumber(L, (lua_Number) t);
++#endif
++ }
+ return 1;
+ }
+
+
+ static int os_difftime (lua_State *L) {
++#ifdef LNUM_FLOAT
++ lua_Integer i= (lua_Integer)
++ difftime( (time_t)(luaL_checkinteger(L, 1)),
++ (time_t)(luaL_optinteger(L, 2, 0)));
++ lua_pushinteger(L, i);
++#else
+ lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
+ (time_t)(luaL_optnumber(L, 2, 0))));
++#endif
+ return 1;
+ }
+
+--- a/src/lparser.c
++++ b/src/lparser.c
+@@ -33,7 +33,6 @@
+
+ #define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
+
+-
+ /*
+ ** nodes for block list (list of active blocks)
+ */
+@@ -72,7 +71,7 @@ static void errorlimit (FuncState *fs, i
+ const char *msg = (fs->f->linedefined == 0) ?
+ luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
+ luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
+- fs->f->linedefined, limit, what);
++ (fs->f->linedefined), limit, what);
+ luaX_lexerror(fs->ls, msg, 0);
+ }
+
+@@ -733,6 +732,18 @@ static void simpleexp (LexState *ls, exp
+ v->u.nval = ls->t.seminfo.r;
+ break;
+ }
++ case TK_INT: {
++ init_exp(v, VKINT, 0);
++ v->u.ival = ls->t.seminfo.i;
++ break;
++ }
++#ifdef LNUM_COMPLEX
++ case TK_NUMBER2: {
++ init_exp(v, VKNUM2, 0);
++ v->u.nval = ls->t.seminfo.r;
++ break;
++ }
++#endif
+ case TK_STRING: {
+ codestring(ls, v, ls->t.seminfo.ts);
+ break;
+@@ -1079,7 +1090,7 @@ static void fornum (LexState *ls, TStrin
+ if (testnext(ls, ','))
+ exp1(ls); /* optional step */
+ else { /* default step = 1 */
+- luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
++ luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_integerK(fs, 1));
+ luaK_reserveregs(fs, 1);
+ }
+ forbody(ls, base, line, 1, 1);
+--- a/src/lparser.h
++++ b/src/lparser.h
+@@ -31,7 +31,11 @@ typedef enum {
+ VRELOCABLE, /* info = instruction pc */
+ VNONRELOC, /* info = result register */
+ VCALL, /* info = instruction pc */
+- VVARARG /* info = instruction pc */
++ VVARARG, /* info = instruction pc */
++ VKINT /* ival = integer value */
++#ifdef LNUM_COMPLEX
++ ,VKNUM2 /* nval = imaginary value */
++#endif
+ } expkind;
+
+ typedef struct expdesc {
+@@ -39,6 +43,7 @@ typedef struct expdesc {
+ union {
+ struct { int info, aux; } s;
+ lua_Number nval;
++ lua_Integer ival;
+ } u;
+ int t; /* patch list of `exit when true' */
+ int f; /* patch list of `exit when false' */
+--- a/src/lstrlib.c
++++ b/src/lstrlib.c
+@@ -43,8 +43,8 @@ static ptrdiff_t posrelat (ptrdiff_t pos
+ static int str_sub (lua_State *L) {
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+- ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
+- ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
++ ptrdiff_t start = posrelat(luaL_checkint32(L, 2), l);
++ ptrdiff_t end = posrelat(luaL_optint32(L, 3, -1), l);
+ if (start < 1) start = 1;
+ if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
+ if (start <= end)
+@@ -106,8 +106,8 @@ static int str_rep (lua_State *L) {
+ static int str_byte (lua_State *L) {
+ size_t l;
+ const char *s = luaL_checklstring(L, 1, &l);
+- ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
+- ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
++ ptrdiff_t posi = posrelat(luaL_optint32(L, 2, 1), l);
++ ptrdiff_t pose = posrelat(luaL_optint32(L, 3, posi), l);
+ int n, i;
+ if (posi <= 0) posi = 1;
+ if ((size_t)pose > l) pose = l;
+@@ -496,7 +496,7 @@ static int str_find_aux (lua_State *L, i
+ size_t l1, l2;
+ const char *s = luaL_checklstring(L, 1, &l1);
+ const char *p = luaL_checklstring(L, 2, &l2);
+- ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
++ ptrdiff_t init = posrelat(luaL_optint32(L, 3, 1), l1) - 1;
+ if (init < 0) init = 0;
+ else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
+ if (find && (lua_toboolean(L, 4) || /* explicit request? */
+@@ -690,7 +690,7 @@ static int str_gsub (lua_State *L) {
+ ** maximum size of each format specification (such as '%-099.99d')
+ ** (+10 accounts for %99.99x plus margin of error)
+ */
+-#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
++#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTEGER_FMT)-2 + 10)
+
+
+ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
+@@ -747,9 +747,9 @@ static const char *scanformat (lua_State
+ static void addintlen (char *form) {
+ size_t l = strlen(form);
+ char spec = form[l - 1];
+- strcpy(form + l - 1, LUA_INTFRMLEN);
+- form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
+- form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
++ const char *tmp= LUA_INTEGER_FMT; /* "%lld" or "%ld" */
++ strcpy(form + l - 1, tmp+1);
++ form[l + sizeof(LUA_INTEGER_FMT)-4] = spec;
+ }
+
+
+@@ -779,12 +779,12 @@ static int str_format (lua_State *L) {
+ }
+ case 'd': case 'i': {
+ addintlen(form);
+- sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
++ sprintf(buff, form, luaL_checkinteger(L, arg));
+ break;
+ }
+ case 'o': case 'u': case 'x': case 'X': {
+ addintlen(form);
+- sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
++ sprintf(buff, form, (unsigned LUA_INTEGER)luaL_checkinteger(L, arg));
+ break;
+ }
+ case 'e': case 'E': case 'f':
+--- a/src/ltable.c
++++ b/src/ltable.c
+@@ -33,6 +33,7 @@
+ #include "lobject.h"
+ #include "lstate.h"
+ #include "ltable.h"
++#include "lnum.h"
+
+
+ /*
+@@ -51,25 +52,15 @@
+
+ #define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
+ #define hashboolean(t,p) hashpow2(t, p)
+-
++#define hashint(t,i) hashpow2(t,i)
+
+ /*
+ ** for some types, it is better to avoid modulus by power of 2, as
+ ** they tend to have many 2 factors.
+ */
+ #define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1))))
+-
+-
+ #define hashpointer(t,p) hashmod(t, IntPoint(p))
+
+-
+-/*
+-** number of ints inside a lua_Number
+-*/
+-#define numints cast_int(sizeof(lua_Number)/sizeof(int))
+-
+-
+-
+ #define dummynode (&dummynode_)
+
+ static const Node dummynode_ = {
+@@ -80,27 +71,46 @@ static const Node dummynode_ = {
+
+ /*
+ ** hash for lua_Numbers
++**
++** for non-complex modes, never called with 'lua_Integer' value range (s.a. 0)
+ */
+ static Node *hashnum (const Table *t, lua_Number n) {
+- unsigned int a[numints];
+- int i;
+- if (luai_numeq(n, 0)) /* avoid problems with -0 */
+- return gnode(t, 0);
+- memcpy(a, &n, sizeof(a));
+- for (i = 1; i < numints; i++) a[0] += a[i];
+- return hashmod(t, a[0]);
++ const unsigned int *p= cast(const unsigned int *,&n);
++ unsigned int sum= *p;
++ unsigned int m= sizeof(lua_Number)/sizeof(int);
++ unsigned int i;
++ /* OS X Intel has 'm'==4 and gives "Bus error" if the last integer of
++ * 'n' is read; the actual size of long double is only 80 bits = 10 bytes.
++ * Linux x86 has 'm'==3, and does not require reduction.
++ */
++#if defined(LNUM_LDOUBLE) && defined(__i386__)
++ if (m>3) m--;
++#endif
++ for (i = 1; i < m; i++) sum += p[i];
++ return hashmod(t, sum);
+ }
+
+
+-
+ /*
+ ** returns the `main' position of an element in a table (that is, the index
+ ** of its hash value)
++**
++** Floating point numbers with integer value give the hash position of the
++** integer (so they use the same table position).
+ */
+ static Node *mainposition (const Table *t, const TValue *key) {
++ lua_Integer i;
+ switch (ttype(key)) {
+ case LUA_TNUMBER:
+- return hashnum(t, nvalue(key));
++ if (tt_integer_valued(key,&i))
++ return hashint(t, i);
++#ifdef LNUM_COMPLEX
++ if (nvalue_img_fast(key)!=0 && luai_numeq(nvalue_fast(key),0))
++ return gnode(t, 0); /* 0 and -0 to give same hash */
++#endif
++ return hashnum(t, nvalue_fast(key));
++ case LUA_TINT:
++ return hashint(t, ivalue(key));
+ case LUA_TSTRING:
+ return hashstr(t, rawtsvalue(key));
+ case LUA_TBOOLEAN:
+@@ -116,16 +126,20 @@ static Node *mainposition (const Table *
+ /*
+ ** returns the index for `key' if `key' is an appropriate key to live in
+ ** the array part of the table, -1 otherwise.
++**
++** Anything <=0 is taken as not being in the array part.
+ */
+-static int arrayindex (const TValue *key) {
+- if (ttisnumber(key)) {
+- lua_Number n = nvalue(key);
+- int k;
+- lua_number2int(k, n);
+- if (luai_numeq(cast_num(k), n))
+- return k;
++static int arrayindex (const TValue *key, int max) {
++ lua_Integer k;
++ switch( ttype(key) ) {
++ case LUA_TINT:
++ k= ivalue(key); break;
++ case LUA_TNUMBER:
++ if (tt_integer_valued(key,&k)) break;
++ default:
++ return -1; /* not to be used as array index */
+ }
+- return -1; /* `key' did not match some condition */
++ return ((k>0) && (k <= max)) ? cast_int(k) : -1;
+ }
+
+
+@@ -137,8 +151,8 @@ static int arrayindex (const TValue *key
+ static int findindex (lua_State *L, Table *t, StkId key) {
+ int i;
+ if (ttisnil(key)) return -1; /* first iteration */
+- i = arrayindex(key);
+- if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
++ i = arrayindex(key, t->sizearray);
++ if (i>0) /* inside array part? */
+ return i-1; /* yes; that's the index (corrected to C) */
+ else {
+ Node *n = mainposition(t, key);
+@@ -163,7 +177,7 @@ int luaH_next (lua_State *L, Table *t, S
+ int i = findindex(L, t, key); /* find original element */
+ for (i++; i < t->sizearray; i++) { /* try first array part */
+ if (!ttisnil(&t->array[i])) { /* a non-nil value? */
+- setnvalue(key, cast_num(i+1));
++ setivalue(key, i+1);
+ setobj2s(L, key+1, &t->array[i]);
+ return 1;
+ }
+@@ -209,8 +223,8 @@ static int computesizes (int nums[], int
+
+
+ static int countint (const TValue *key, int *nums) {
+- int k = arrayindex(key);
+- if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
++ int k = arrayindex(key,MAXASIZE);
++ if (k>0) { /* appropriate array index? */
+ nums[ceillog2(k)]++; /* count as such */
+ return 1;
+ }
+@@ -308,7 +322,7 @@ static void resize (lua_State *L, Table
+ /* re-insert elements from vanishing slice */
+ for (i=nasize; i<oldasize; i++) {
+ if (!ttisnil(&t->array[i]))
+- setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
++ setobjt2t(L, luaH_setint(L, t, i+1), &t->array[i]);
+ }
+ /* shrink array */
+ luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
+@@ -409,7 +423,9 @@ static TValue *newkey (lua_State *L, Tab
+ othern = mainposition(t, key2tval(mp));
+ if (othern != mp) { /* is colliding node out of its main position? */
+ /* yes; move colliding node into free position */
+- while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
++ while (gnext(othern) != mp) {
++ othern = gnext(othern); /* find previous */
++ }
+ gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
+ *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
+ gnext(mp) = NULL; /* now `mp' is free */
+@@ -432,17 +448,18 @@ static TValue *newkey (lua_State *L, Tab
+ /*
+ ** search function for integers
+ */
+-const TValue *luaH_getnum (Table *t, int key) {
++const TValue *luaH_getint (Table *t, lua_Integer key) {
+ /* (1 <= key && key <= t->sizearray) */
+ if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
+ return &t->array[key-1];
+ else {
+- lua_Number nk = cast_num(key);
+- Node *n = hashnum(t, nk);
++ Node *n = hashint(t, key);
+ do { /* check whether `key' is somewhere in the chain */
+- if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
++ if (ttisint(gkey(n)) && (ivalue(gkey(n)) == key)) {
+ return gval(n); /* that's it */
+- else n = gnext(n);
++ } else {
++ n = gnext(n);
++ }
+ } while (n);
+ return luaO_nilobject;
+ }
+@@ -470,14 +487,12 @@ const TValue *luaH_get (Table *t, const
+ switch (ttype(key)) {
+ case LUA_TNIL: return luaO_nilobject;
+ case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
++ case LUA_TINT: return luaH_getint(t, ivalue(key));
+ case LUA_TNUMBER: {
+- int k;
+- lua_Number n = nvalue(key);
+- lua_number2int(k, n);
+- if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
+- return luaH_getnum(t, k); /* use specialized version */
+- /* else go through */
+- }
++ lua_Integer i;
++ if (tt_integer_valued(key,&i))
++ return luaH_getint(t,i);
++ } /* pass through */
+ default: {
+ Node *n = mainposition(t, key);
+ do { /* check whether `key' is somewhere in the chain */
+@@ -498,20 +513,25 @@ TValue *luaH_set (lua_State *L, Table *t
+ return cast(TValue *, p);
+ else {
+ if (ttisnil(key)) luaG_runerror(L, "table index is nil");
+- else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
+- luaG_runerror(L, "table index is NaN");
++ else if (ttype(key)==LUA_TNUMBER) {
++ lua_Integer k;
++ if (luai_numisnan(nvalue_fast(key)))
++ luaG_runerror(L, "table index is NaN");
++ if (tt_integer_valued(key,&k))
++ return luaH_setint(L, t, k);
++ }
+ return newkey(L, t, key);
+ }
+ }
+
+
+-TValue *luaH_setnum (lua_State *L, Table *t, int key) {
+- const TValue *p = luaH_getnum(t, key);
++TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key) {
++ const TValue *p = luaH_getint(t, key);
+ if (p != luaO_nilobject)
+ return cast(TValue *, p);
+ else {
+ TValue k;
+- setnvalue(&k, cast_num(key));
++ setivalue(&k, key);
+ return newkey(L, t, &k);
+ }
+ }
+@@ -533,20 +553,21 @@ static int unbound_search (Table *t, uns
+ unsigned int i = j; /* i is zero or a present index */
+ j++;
+ /* find `i' and `j' such that i is present and j is not */
+- while (!ttisnil(luaH_getnum(t, j))) {
++ while (!ttisnil(luaH_getint(t, j))) {
+ i = j;
+ j *= 2;
+ if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
+ /* table was built with bad purposes: resort to linear search */
+- i = 1;
+- while (!ttisnil(luaH_getnum(t, i))) i++;
+- return i - 1;
++ for( i = 1; i<MAX_INT+1; i++ ) {
++ if (ttisnil(luaH_getint(t, i))) break;
++ }
++ return i - 1; /* up to MAX_INT */
+ }
+ }
+ /* now do a binary search between them */
+ while (j - i > 1) {
+ unsigned int m = (i+j)/2;
+- if (ttisnil(luaH_getnum(t, m))) j = m;
++ if (ttisnil(luaH_getint(t, m))) j = m;
+ else i = m;
+ }
+ return i;
+--- a/src/ltable.h
++++ b/src/ltable.h
+@@ -18,8 +18,8 @@
+ #define key2tval(n) (&(n)->i_key.tvk)
+
+
+-LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
+-LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
++LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
++LUAI_FUNC TValue *luaH_setint (lua_State *L, Table *t, lua_Integer key);
+ LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
+ LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
+ LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
+--- a/src/ltm.c
++++ b/src/ltm.c
+@@ -19,7 +19,6 @@
+ #include "ltm.h"
+
+
+-
+ const char *const luaT_typenames[] = {
+ "nil", "boolean", "userdata", "number",
+ "string", "table", "function", "userdata", "thread",
+@@ -67,6 +66,9 @@ const TValue *luaT_gettmbyobj (lua_State
+ case LUA_TUSERDATA:
+ mt = uvalue(o)->metatable;
+ break;
++ case LUA_TINT:
++ mt = G(L)->mt[LUA_TNUMBER];
++ break;
+ default:
+ mt = G(L)->mt[ttype(o)];
+ }
+--- a/src/lua.c
++++ b/src/lua.c
+@@ -16,7 +16,7 @@
+
+ #include "lauxlib.h"
+ #include "lualib.h"
+-
++#include "llimits.h"
+
+
+ static lua_State *globalL = NULL;
+@@ -382,6 +382,15 @@ int main (int argc, char **argv) {
+ l_message(argv[0], "cannot create state: not enough memory");
+ return EXIT_FAILURE;
+ }
++ /* Checking 'sizeof(lua_Integer)' cannot be made in preprocessor on all compilers.
++ */
++#ifdef LNUM_INT16
++ lua_assert( sizeof(lua_Integer) == 2 );
++#elif defined(LNUM_INT32)
++ lua_assert( sizeof(lua_Integer) == 4 );
++#elif defined(LNUM_INT64)
++ lua_assert( sizeof(lua_Integer) == 8 );
++#endif
+ s.argc = argc;
+ s.argv = argv;
+ status = lua_cpcall(L, &pmain, &s);
+--- a/src/lua.h
++++ b/src/lua.h
+@@ -19,7 +19,7 @@
+ #define LUA_VERSION "Lua 5.1"
+ #define LUA_RELEASE "Lua 5.1.5"
+ #define LUA_VERSION_NUM 501
+-#define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio"
++#define LUA_COPYRIGHT "Copyright (C) 1994-2012 Lua.org, PUC-Rio" " (" LUA_LNUM ")"
+ #define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
+
+
+@@ -71,6 +71,16 @@ typedef void * (*lua_Alloc) (void *ud, v
+ */
+ #define LUA_TNONE (-1)
+
++/* LUA_TINT is an internal type, not visible to applications. There are three
++ * potential values where it can be tweaked to (code autoadjusts to these):
++ *
++ * -2: not 'usual' type value; good since 'LUA_TINT' is not part of the API
++ * LUA_TNUMBER+1: shifts other type values upwards, breaking binary compatibility
++ * not acceptable for 5.1, maybe 5.2 onwards?
++ * 9: greater than existing (5.1) type values.
++*/
++#define LUA_TINT (-2)
++
+ #define LUA_TNIL 0
+ #define LUA_TBOOLEAN 1
+ #define LUA_TLIGHTUSERDATA 2
+@@ -139,6 +149,8 @@ LUA_API int (lua_isuserdata)
+ LUA_API int (lua_type) (lua_State *L, int idx);
+ LUA_API const char *(lua_typename) (lua_State *L, int tp);
+
++LUA_API int (lua_isinteger) (lua_State *L, int idx);
++
+ LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
+ LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
+ LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
+@@ -244,6 +256,19 @@ LUA_API lua_Alloc (lua_getallocf) (lua_S
+ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
+
+
++/*
++* It is unnecessary to break Lua C API 'lua_tonumber()' compatibility, just
++* because the Lua number type is complex. Most C modules would use scalars
++* only. We'll introduce new 'lua_tocomplex' and 'lua_pushcomplex' for when
++* the module really wants to use them.
++*/
++#ifdef LNUM_COMPLEX
++ #include <complex.h>
++ typedef LUA_NUMBER complex lua_Complex;
++ LUA_API lua_Complex (lua_tocomplex) (lua_State *L, int idx);
++ LUA_API void (lua_pushcomplex) (lua_State *L, lua_Complex v);
++#endif
++
+
+ /*
+ ** ===============================================================
+@@ -268,7 +293,12 @@ LUA_API void lua_setallocf (lua_State *L
+ #define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN)
+ #define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD)
+ #define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE)
+-#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
++
++#if LUA_TINT < 0
++# define lua_isnoneornil(L, n) ( (lua_type(L,(n)) <= 0) && (lua_type(L,(n)) != LUA_TINT) )
++#else
++# define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0)
++#endif
+
+ #define lua_pushliteral(L, s) \
+ lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
+@@ -386,3 +416,4 @@ struct lua_Debug {
+
+
+ #endif
++
+--- a/src/luaconf.h
++++ b/src/luaconf.h
+@@ -10,7 +10,9 @@
+
+ #include <limits.h>
+ #include <stddef.h>
+-
++#ifdef lua_assert
++# include <assert.h>
++#endif
+
+ /*
+ ** ==================================================================
+@@ -136,14 +138,38 @@
+
+
+ /*
+-@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
+-** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
+-** machines, ptrdiff_t gives a good choice between int or long.)
++@@ LUAI_BITSINT defines the number of bits in an int.
++** CHANGE here if Lua cannot automatically detect the number of bits of
++** your machine. Probably you do not need to change this.
+ */
+-#define LUA_INTEGER ptrdiff_t
++/* avoid overflows in comparison */
++#if INT_MAX-20 < 32760
++#define LUAI_BITSINT 16
++#elif INT_MAX > 2147483640L
++/* int has at least 32 bits */
++#define LUAI_BITSINT 32
++#else
++#error "you must define LUA_BITSINT with number of bits in an integer"
++#endif
+
+
+ /*
++@@ LNUM_DOUBLE | LNUM_FLOAT | LNUM_LDOUBLE: Generic Lua number mode
++@@ LNUM_INT32 | LNUM_INT64: Integer type
++@@ LNUM_COMPLEX: Define for using 'a+bi' numbers
++@@
++@@ You can combine LNUM_xxx but only one of each group. I.e. '-DLNUM_FLOAT
++@@ -DLNUM_INT32 -DLNUM_COMPLEX' gives float range complex numbers, with
++@@ 32-bit scalar integer range optimized.
++**
++** These are kept in a separate configuration file mainly for ease of patching
++** (can be changed if integerated to Lua proper).
++*/
++/*#define LNUM_DOUBLE*/
++/*#define LNUM_INT32*/
++#include "lnum_config.h"
++
++/*
+ @@ LUA_API is a mark for all core API functions.
+ @@ LUALIB_API is a mark for all standard library functions.
+ ** CHANGE them if you need to define those functions in some special way.
+@@ -383,22 +409,6 @@
+
+
+ /*
+-@@ LUAI_BITSINT defines the number of bits in an int.
+-** CHANGE here if Lua cannot automatically detect the number of bits of
+-** your machine. Probably you do not need to change this.
+-*/
+-/* avoid overflows in comparison */
+-#if INT_MAX-20 < 32760
+-#define LUAI_BITSINT 16
+-#elif INT_MAX > 2147483640L
+-/* int has at least 32 bits */
+-#define LUAI_BITSINT 32
+-#else
+-#error "you must define LUA_BITSINT with number of bits in an integer"
+-#endif
+-
+-
+-/*
+ @@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
+ @@ LUAI_INT32 is an signed integer with at least 32 bits.
+ @@ LUAI_UMEM is an unsigned integer big enough to count the total
+@@ -425,6 +435,15 @@
+ #define LUAI_MEM long
+ #endif
+
++/*
++@@ LUAI_BOOL carries 0 and nonzero (normally 1). It may be defined as 'char'
++** (to save memory), 'int' (for speed), 'bool' (for C++) or '_Bool' (C99)
++*/
++#ifdef __cplusplus
++# define LUAI_BOOL bool
++#else
++# define LUAI_BOOL int
++#endif
+
+ /*
+ @@ LUAI_MAXCALLS limits the number of nested calls.
+@@ -490,101 +509,6 @@
+ /* }================================================================== */
+
+
+-
+-
+-/*
+-** {==================================================================
+-@@ LUA_NUMBER is the type of numbers in Lua.
+-** CHANGE the following definitions only if you want to build Lua
+-** with a number type different from double. You may also need to
+-** change lua_number2int & lua_number2integer.
+-** ===================================================================
+-*/
+-
+-#define LUA_NUMBER_DOUBLE
+-#define LUA_NUMBER double
+-
+-/*
+-@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
+-@* over a number.
+-*/
+-#define LUAI_UACNUMBER double
+-
+-
+-/*
+-@@ LUA_NUMBER_SCAN is the format for reading numbers.
+-@@ LUA_NUMBER_FMT is the format for writing numbers.
+-@@ lua_number2str converts a number to a string.
+-@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
+-@@ lua_str2number converts a string to a number.
+-*/
+-#define LUA_NUMBER_SCAN "%lf"
+-#define LUA_NUMBER_FMT "%.14g"
+-#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
+-#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
+-#define lua_str2number(s,p) strtod((s), (p))
+-
+-
+-/*
+-@@ The luai_num* macros define the primitive operations over numbers.
+-*/
+-#if defined(LUA_CORE)
+-#include <math.h>
+-#define luai_numadd(a,b) ((a)+(b))
+-#define luai_numsub(a,b) ((a)-(b))
+-#define luai_nummul(a,b) ((a)*(b))
+-#define luai_numdiv(a,b) ((a)/(b))
+-#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
+-#define luai_numpow(a,b) (pow(a,b))
+-#define luai_numunm(a) (-(a))
+-#define luai_numeq(a,b) ((a)==(b))
+-#define luai_numlt(a,b) ((a)<(b))
+-#define luai_numle(a,b) ((a)<=(b))
+-#define luai_numisnan(a) (!luai_numeq((a), (a)))
+-#endif
+-
+-
+-/*
+-@@ lua_number2int is a macro to convert lua_Number to int.
+-@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
+-** CHANGE them if you know a faster way to convert a lua_Number to
+-** int (with any rounding method and without throwing errors) in your
+-** system. In Pentium machines, a naive typecast from double to int
+-** in C is extremely slow, so any alternative is worth trying.
+-*/
+-
+-/* On a Pentium, resort to a trick */
+-#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
+- (defined(__i386) || defined (_M_IX86) || defined(__i386__))
+-
+-/* On a Microsoft compiler, use assembler */
+-#if defined(_MSC_VER)
+-
+-#define lua_number2int(i,d) __asm fld d __asm fistp i
+-#define lua_number2integer(i,n) lua_number2int(i, n)
+-
+-/* the next trick should work on any Pentium, but sometimes clashes
+- with a DirectX idiosyncrasy */
+-#else
+-
+-union luai_Cast { double l_d; long l_l; };
+-#define lua_number2int(i,d) \
+- { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
+-#define lua_number2integer(i,n) lua_number2int(i, n)
+-
+-#endif
+-
+-
+-/* this option always works, but may be slow */
+-#else
+-#define lua_number2int(i,d) ((i)=(int)(d))
+-#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
+-
+-#endif
+-
+-/* }================================================================== */
+-
+-
+ /*
+ @@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
+ ** CHANGE it if your system requires alignments larger than double. (For
+@@ -728,28 +652,6 @@ union luai_Cast { double l_d; long l_l;
+ #define luai_userstateyield(L,n) ((void)L)
+
+
+-/*
+-@@ LUA_INTFRMLEN is the length modifier for integer conversions
+-@* in 'string.format'.
+-@@ LUA_INTFRM_T is the integer type correspoding to the previous length
+-@* modifier.
+-** CHANGE them if your system supports long long or does not support long.
+-*/
+-
+-#if defined(LUA_USELONGLONG)
+-
+-#define LUA_INTFRMLEN "ll"
+-#define LUA_INTFRM_T long long
+-
+-#else
+-
+-#define LUA_INTFRMLEN "l"
+-#define LUA_INTFRM_T long
+-
+-#endif
+-
+-
+-
+ /* =================================================================== */
+
+ /*
+--- a/src/lundump.c
++++ b/src/lundump.c
+@@ -73,6 +73,13 @@ static lua_Number LoadNumber(LoadState*
+ return x;
+ }
+
++static lua_Integer LoadInteger(LoadState* S)
++{
++ lua_Integer x;
++ LoadVar(S,x);
++ return x;
++}
++
+ static TString* LoadString(LoadState* S)
+ {
+ size_t size;
+@@ -119,6 +126,9 @@ static void LoadConstants(LoadState* S,
+ case LUA_TNUMBER:
+ setnvalue(o,LoadNumber(S));
+ break;
++ case LUA_TINT: /* Integer type saved in bytecode (see lcode.c) */
++ setivalue(o,LoadInteger(S));
++ break;
+ case LUA_TSTRING:
+ setsvalue2n(S->L,o,LoadString(S));
+ break;
+@@ -223,5 +233,22 @@ void luaU_header (char* h)
+ *h++=(char)sizeof(size_t);
+ *h++=(char)sizeof(Instruction);
+ *h++=(char)sizeof(lua_Number);
+- *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
++
++ /*
++ * Last byte of header (0/1 in unpatched Lua 5.1.3):
++ *
++ * 0: lua_Number is float or double, lua_Integer not used. (nonpatched only)
++ * 1: lua_Number is integer (nonpatched only)
++ *
++ * +2: LNUM_INT16: sizeof(lua_Integer)
++ * +4: LNUM_INT32: sizeof(lua_Integer)
++ * +8: LNUM_INT64: sizeof(lua_Integer)
++ *
++ * +0x80: LNUM_COMPLEX
++ */
++ *h++ = (char)(sizeof(lua_Integer)
++#ifdef LNUM_COMPLEX
++ | 0x80
++#endif
++ );
+ }
+--- a/src/lvm.c
++++ b/src/lvm.c
+@@ -25,22 +25,35 @@
+ #include "ltable.h"
+ #include "ltm.h"
+ #include "lvm.h"
+-
+-
++#include "llex.h"
++#include "lnum.h"
+
+ /* limit for table tag-method chains (to avoid loops) */
+ #define MAXTAGLOOP 100
+
+
+-const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
+- lua_Number num;
++/*
++ * If 'obj' is a string, it is tried to be interpreted as a number.
++ */
++const TValue *luaV_tonumber ( const TValue *obj, TValue *n) {
++ lua_Number d;
++ lua_Integer i;
++
+ if (ttisnumber(obj)) return obj;
+- if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
+- setnvalue(n, num);
+- return n;
+- }
+- else
+- return NULL;
++
++ if (ttisstring(obj)) {
++ switch( luaO_str2d( svalue(obj), &d, &i ) ) {
++ case TK_INT:
++ setivalue(n,i); return n;
++ case TK_NUMBER:
++ setnvalue(n,d); return n;
++#ifdef LNUM_COMPLEX
++ case TK_NUMBER2: /* "N.NNNi", != 0 */
++ setnvalue_complex_fast(n, d*I); return n;
++#endif
++ }
++ }
++ return NULL;
+ }
+
+
+@@ -49,8 +62,7 @@ int luaV_tostring (lua_State *L, StkId o
+ return 0;
+ else {
+ char s[LUAI_MAXNUMBER2STR];
+- lua_Number n = nvalue(obj);
+- lua_number2str(s, n);
++ luaO_num2buf(s,obj);
+ setsvalue2s(L, obj, luaS_new(L, s));
+ return 1;
+ }
+@@ -222,59 +234,127 @@ static int l_strcmp (const TString *ls,
+ }
+
+
++#ifdef LNUM_COMPLEX
++void error_complex( lua_State *L, const TValue *l, const TValue *r )
++{
++ char buf1[ LUAI_MAXNUMBER2STR ];
++ char buf2[ LUAI_MAXNUMBER2STR ];
++ luaO_num2buf( buf1, l );
++ luaO_num2buf( buf2, r );
++ luaG_runerror( L, "unable to compare: %s with %s", buf1, buf2 );
++ /* no return */
++}
++#endif
++
++
+ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
+ int res;
+- if (ttype(l) != ttype(r))
++ int tl,tr;
++ lua_Integer tmp;
++
++ if (!ttype_ext_same(l,r))
+ return luaG_ordererror(L, l, r);
+- else if (ttisnumber(l))
+- return luai_numlt(nvalue(l), nvalue(r));
+- else if (ttisstring(l))
+- return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
+- else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
++#ifdef LNUM_COMPLEX
++ if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) )
++ error_complex( L, l, r );
++#endif
++ tl= ttype(l); tr= ttype(r);
++ if (tl==tr) { /* clear arithmetics */
++ switch(tl) {
++ case LUA_TINT: return ivalue(l) < ivalue(r);
++ case LUA_TNUMBER: return luai_numlt(nvalue_fast(l), nvalue_fast(r));
++ case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
++ }
++ } else if (tl==LUA_TINT) { /* l:int, r:num */
++ /* Avoid accuracy losing casts: if 'r' is integer by value, do comparisons
++ * in integer realm. Only otherwise cast 'l' to FP (which might change its
++ * value).
++ */
++ if (tt_integer_valued(r,&tmp))
++ return ivalue(l) < tmp;
++ else
++ return luai_numlt( cast_num(ivalue(l)), nvalue_fast(r) );
++
++ } else if (tl==LUA_TNUMBER) { /* l:num, r:int */
++ if (tt_integer_valued(l,&tmp))
++ return tmp < ivalue(r);
++ else
++ return luai_numlt( nvalue_fast(l), cast_num(ivalue(r)) );
++
++ } else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
+ return res;
++
+ return luaG_ordererror(L, l, r);
+ }
+
+
+ static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
+ int res;
+- if (ttype(l) != ttype(r))
++ int tl, tr;
++ lua_Integer tmp;
++
++ if (!ttype_ext_same(l,r))
+ return luaG_ordererror(L, l, r);
+- else if (ttisnumber(l))
+- return luai_numle(nvalue(l), nvalue(r));
+- else if (ttisstring(l))
+- return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
+- else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
++#ifdef LNUM_COMPLEX
++ if ( (nvalue_img(l)!=0) || (nvalue_img(r)!=0) )
++ error_complex( L, l, r );
++#endif
++ tl= ttype(l); tr= ttype(r);
++ if (tl==tr) { /* clear arithmetics */
++ switch(tl) {
++ case LUA_TINT: return ivalue(l) <= ivalue(r);
++ case LUA_TNUMBER: return luai_numle(nvalue_fast(l), nvalue_fast(r));
++ case LUA_TSTRING: return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
++ }
++ }
++ if (tl==LUA_TINT) { /* l:int, r:num */
++ if (tt_integer_valued(r,&tmp))
++ return ivalue(l) <= tmp;
++ else
++ return luai_numle( cast_num(ivalue(l)), nvalue_fast(r) );
++
++ } else if (tl==LUA_TNUMBER) { /* l:num, r:int */
++ if (tt_integer_valued(l,&tmp))
++ return tmp <= ivalue(r);
++ else
++ return luai_numle( nvalue_fast(l), cast_num(ivalue(r)) );
++
++ } else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
+ return res;
+ else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
+ return !res;
++
+ return luaG_ordererror(L, l, r);
+ }
+
+
+-int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
++/* Note: 'luaV_equalval()' and 'luaO_rawequalObj()' have largely overlapping
++ * implementation. LUA_TNIL..LUA_TLIGHTUSERDATA cases could be handled
++ * simply by the 'default' case here.
++ */
++int luaV_equalval (lua_State *L, const TValue *l, const TValue *r) {
+ const TValue *tm;
+- lua_assert(ttype(t1) == ttype(t2));
+- switch (ttype(t1)) {
++ lua_assert(ttype_ext_same(l,r));
++ switch (ttype(l)) {
+ case LUA_TNIL: return 1;
+- case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
+- case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
+- case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
++ case LUA_TINT:
++ case LUA_TNUMBER: return luaO_rawequalObj(l,r);
++ case LUA_TBOOLEAN: return bvalue(l) == bvalue(r); /* true must be 1 !! */
++ case LUA_TLIGHTUSERDATA: return pvalue(l) == pvalue(r);
+ case LUA_TUSERDATA: {
+- if (uvalue(t1) == uvalue(t2)) return 1;
+- tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
+- TM_EQ);
++ if (uvalue(l) == uvalue(r)) return 1;
++ tm = get_compTM(L, uvalue(l)->metatable, uvalue(r)->metatable, TM_EQ);
+ break; /* will try TM */
+ }
+ case LUA_TTABLE: {
+- if (hvalue(t1) == hvalue(t2)) return 1;
+- tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
++ if (hvalue(l) == hvalue(r)) return 1;
++ tm = get_compTM(L, hvalue(l)->metatable, hvalue(r)->metatable, TM_EQ);
+ break; /* will try TM */
+ }
+- default: return gcvalue(t1) == gcvalue(t2);
++ default: return gcvalue(l) == gcvalue(r);
+ }
+ if (tm == NULL) return 0; /* no TM? */
+- callTMres(L, L->top, tm, t1, t2); /* call TM */
++ callTMres(L, L->top, tm, l, r); /* call TM */
+ return !l_isfalse(L->top);
+ }
+
+@@ -314,30 +394,6 @@ void luaV_concat (lua_State *L, int tota
+ }
+
+
+-static void Arith (lua_State *L, StkId ra, const TValue *rb,
+- const TValue *rc, TMS op) {
+- TValue tempb, tempc;
+- const TValue *b, *c;
+- if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
+- (c = luaV_tonumber(rc, &tempc)) != NULL) {
+- lua_Number nb = nvalue(b), nc = nvalue(c);
+- switch (op) {
+- case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
+- case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
+- case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
+- case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
+- case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
+- case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
+- case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
+- default: lua_assert(0); break;
+- }
+- }
+- else if (!call_binTM(L, rb, rc, ra, op))
+- luaG_aritherror(L, rb, rc);
+-}
+-
+-
+-
+ /*
+ ** some macros for common tasks in `luaV_execute'
+ */
+@@ -361,17 +417,154 @@ static void Arith (lua_State *L, StkId r
+ #define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
+
+
+-#define arith_op(op,tm) { \
+- TValue *rb = RKB(i); \
+- TValue *rc = RKC(i); \
+- if (ttisnumber(rb) && ttisnumber(rc)) { \
+- lua_Number nb = nvalue(rb), nc = nvalue(rc); \
+- setnvalue(ra, op(nb, nc)); \
+- } \
+- else \
+- Protect(Arith(L, ra, rb, rc, tm)); \
++/* Note: if called for unary operations, 'rc'=='rb'.
++ */
++static void Arith (lua_State *L, StkId ra, const TValue *rb,
++ const TValue *rc, TMS op) {
++ TValue tempb, tempc;
++ const TValue *b, *c;
++ lua_Number nb,nc;
++
++ if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
++ (c = luaV_tonumber(rc, &tempc)) != NULL) {
++
++ /* Keep integer arithmetics in the integer realm, if possible.
++ */
++ if (ttisint(b) && ttisint(c)) {
++ lua_Integer ib = ivalue(b), ic = ivalue(c);
++ lua_Integer *ri = &ra->value.i;
++ ra->tt= LUA_TINT; /* part of 'setivalue(ra)' */
++ switch (op) {
++ case TM_ADD: if (try_addint( ri, ib, ic)) return; break;
++ case TM_SUB: if (try_subint( ri, ib, ic)) return; break;
++ case TM_MUL: if (try_mulint( ri, ib, ic)) return; break;
++ case TM_DIV: if (try_divint( ri, ib, ic)) return; break;
++ case TM_MOD: if (try_modint( ri, ib, ic)) return; break;
++ case TM_POW: if (try_powint( ri, ib, ic)) return; break;
++ case TM_UNM: if (try_unmint( ri, ib)) return; break;
++ default: lua_assert(0);
++ }
++ }
++ /* Fallback to floating point, when leaving range. */
++
++#ifdef LNUM_COMPLEX
++ if ((nvalue_img(b)!=0) || (nvalue_img(c)!=0)) {
++ lua_Complex r;
++ if (op==TM_UNM) {
++ r= -nvalue_complex_fast(b); /* never an integer (or scalar) */
++ setnvalue_complex_fast( ra, r );
++ } else {
++ lua_Complex bb= nvalue_complex(b), cc= nvalue_complex(c);
++ switch (op) {
++ case TM_ADD: r= bb + cc; break;
++ case TM_SUB: r= bb - cc; break;
++ case TM_MUL: r= bb * cc; break;
++ case TM_DIV: r= bb / cc; break;
++ case TM_MOD:
++ luaG_runerror(L, "attempt to use %% on complex numbers"); /* no return */
++ case TM_POW: r= luai_vectpow( bb, cc ); break;
++ default: lua_assert(0); r=0;
++ }
++ setnvalue_complex( ra, r );
+ }
++ return;
++ }
++#endif
++ nb = nvalue(b); nc = nvalue(c);
++ switch (op) {
++ case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); return;
++ case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); return;
++ case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); return;
++ case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); return;
++ case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); return;
++ case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); return;
++ case TM_UNM: setnvalue(ra, luai_numunm(nb)); return;
++ default: lua_assert(0);
++ }
++ }
++
++ /* Either operand not a number */
++ if (!call_binTM(L, rb, rc, ra, op))
++ luaG_aritherror(L, rb, rc);
++}
+
++/* Helper macro to sort arithmetic operations into four categories:
++ * TK_INT: integer - integer operands
++ * TK_NUMBER: number - number (non complex, either may be integer)
++ * TK_NUMBER2: complex numbers (at least the other)
++ * 0: non-numeric (at least the other)
++*/
++#ifdef LNUM_COMPLEX
++static inline int arith_mode( const TValue *rb, const TValue *rc ) {
++ if (ttisint(rb) && ttisint(rc)) return TK_INT;
++ if (ttiscomplex(rb) || ttiscomplex(rc)) return TK_NUMBER2;
++ if (ttisnumber(rb) && ttisnumber(rc)) return TK_NUMBER;
++ return 0;
++}
++#else
++# define arith_mode(rb,rc) \
++ ( (ttisint(rb) && ttisint(rc)) ? TK_INT : \
++ (ttisnumber(rb) && ttisnumber(rc)) ? TK_NUMBER : 0 )
++#endif
++
++/* arith_op macro for two operators:
++ * automatically chooses, which function (number, integer, complex) to use
++ */
++#define ARITH_OP2_START( op_num, op_int ) \
++ int failed= 0; \
++ switch( arith_mode(rb,rc) ) { \
++ case TK_INT: \
++ if (op_int ( &(ra)->value.i, ivalue(rb), ivalue(rc) )) \
++ { ra->tt= LUA_TINT; break; } /* else flow through */ \
++ case TK_NUMBER: \
++ setnvalue(ra, op_num ( nvalue(rb), nvalue(rc) )); break;
++
++#define ARITH_OP2_END \
++ default: \
++ failed= 1; break; \
++ } if (!failed) continue;
++
++#define arith_op_continue_scalar( op_num, op_int ) \
++ ARITH_OP2_START( op_num, op_int ) \
++ ARITH_OP2_END
++
++#ifdef LNUM_COMPLEX
++# define arith_op_continue( op_num, op_int, op_complex ) \
++ ARITH_OP2_START( op_num, op_int ) \
++ case TK_NUMBER2: \
++ setnvalue_complex( ra, op_complex ( nvalue_complex(rb), nvalue_complex(rc) ) ); break; \
++ ARITH_OP2_END
++#else
++# define arith_op_continue(op_num,op_int,_) arith_op_continue_scalar(op_num,op_int)
++#endif
++
++/* arith_op macro for one operator:
++ */
++#define ARITH_OP1_START( op_num, op_int ) \
++ int failed= 0; \
++ switch( arith_mode(rb,rb) ) { \
++ case TK_INT: \
++ if (op_int ( &(ra)->value.i, ivalue(rb) )) \
++ { ra->tt= LUA_TINT; break; } /* else flow through */ \
++ case TK_NUMBER: \
++ setnvalue(ra, op_num (nvalue(rb))); break; \
++
++#define ARITH_OP1_END \
++ default: \
++ failed= 1; break; \
++ } if (!failed) continue;
++
++#ifdef LNUM_COMPLEX
++# define arith_op1_continue( op_num, op_int, op_complex ) \
++ ARITH_OP1_START( op_num, op_int ) \
++ case TK_NUMBER2: \
++ setnvalue_complex( ra, op_complex ( nvalue_complex_fast(rb) )); break; \
++ ARITH_OP1_END
++#else
++# define arith_op1_continue( op_num, op_int, _ ) \
++ ARITH_OP1_START( op_num, op_int ) \
++ ARITH_OP1_END
++#endif
+
+
+ void luaV_execute (lua_State *L, int nexeccalls) {
+@@ -472,38 +665,45 @@ void luaV_execute (lua_State *L, int nex
+ continue;
+ }
+ case OP_ADD: {
+- arith_op(luai_numadd, TM_ADD);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue( luai_numadd, try_addint, luai_vectadd );
++ Protect(Arith(L, ra, rb, rc, TM_ADD)); \
+ continue;
+ }
+ case OP_SUB: {
+- arith_op(luai_numsub, TM_SUB);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue( luai_numsub, try_subint, luai_vectsub );
++ Protect(Arith(L, ra, rb, rc, TM_SUB));
+ continue;
+ }
+ case OP_MUL: {
+- arith_op(luai_nummul, TM_MUL);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue(luai_nummul, try_mulint, luai_vectmul);
++ Protect(Arith(L, ra, rb, rc, TM_MUL));
+ continue;
+ }
+ case OP_DIV: {
+- arith_op(luai_numdiv, TM_DIV);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue(luai_numdiv, try_divint, luai_vectdiv);
++ Protect(Arith(L, ra, rb, rc, TM_DIV));
+ continue;
+ }
+ case OP_MOD: {
+- arith_op(luai_nummod, TM_MOD);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue_scalar(luai_nummod, try_modint); /* scalars only */
++ Protect(Arith(L, ra, rb, rc, TM_MOD));
+ continue;
+ }
+ case OP_POW: {
+- arith_op(luai_numpow, TM_POW);
++ TValue *rb = RKB(i), *rc= RKC(i);
++ arith_op_continue(luai_numpow, try_powint, luai_vectpow);
++ Protect(Arith(L, ra, rb, rc, TM_POW));
+ continue;
+ }
+ case OP_UNM: {
+ TValue *rb = RB(i);
+- if (ttisnumber(rb)) {
+- lua_Number nb = nvalue(rb);
+- setnvalue(ra, luai_numunm(nb));
+- }
+- else {
+- Protect(Arith(L, ra, rb, rb, TM_UNM));
+- }
++ arith_op1_continue(luai_numunm, try_unmint, luai_vectunm);
++ Protect(Arith(L, ra, rb, rb, TM_UNM));
+ continue;
+ }
+ case OP_NOT: {
+@@ -515,11 +715,11 @@ void luaV_execute (lua_State *L, int nex
+ const TValue *rb = RB(i);
+ switch (ttype(rb)) {
+ case LUA_TTABLE: {
+- setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
++ setivalue(ra, luaH_getn(hvalue(rb)));
+ break;
+ }
+ case LUA_TSTRING: {
+- setnvalue(ra, cast_num(tsvalue(rb)->len));
++ setivalue(ra, tsvalue(rb)->len);
+ break;
+ }
+ default: { /* try metamethod */
+@@ -652,14 +852,30 @@ void luaV_execute (lua_State *L, int nex
+ }
+ }
+ case OP_FORLOOP: {
+- lua_Number step = nvalue(ra+2);
+- lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
+- lua_Number limit = nvalue(ra+1);
+- if (luai_numlt(0, step) ? luai_numle(idx, limit)
+- : luai_numle(limit, idx)) {
+- dojump(L, pc, GETARG_sBx(i)); /* jump back */
+- setnvalue(ra, idx); /* update internal index... */
+- setnvalue(ra+3, idx); /* ...and external index */
++ /* If start,step and limit are all integers, we don't need to check
++ * against overflow in the looping.
++ */
++ if (ttisint(ra) && ttisint(ra+1) && ttisint(ra+2)) {
++ lua_Integer step = ivalue(ra+2);
++ lua_Integer idx = ivalue(ra) + step; /* increment index */
++ lua_Integer limit = ivalue(ra+1);
++ if (step > 0 ? (idx <= limit) : (limit <= idx)) {
++ dojump(L, pc, GETARG_sBx(i)); /* jump back */
++ setivalue(ra, idx); /* update internal index... */
++ setivalue(ra+3, idx); /* ...and external index */
++ }
++ } else {
++ /* non-integer looping (don't use 'nvalue_fast', some may be integer!)
++ */
++ lua_Number step = nvalue(ra+2);
++ lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
++ lua_Number limit = nvalue(ra+1);
++ if (luai_numlt(0, step) ? luai_numle(idx, limit)
++ : luai_numle(limit, idx)) {
++ dojump(L, pc, GETARG_sBx(i)); /* jump back */
++ setnvalue(ra, idx); /* update internal index... */
++ setnvalue(ra+3, idx); /* ...and external index */
++ }
+ }
+ continue;
+ }
+@@ -668,13 +884,21 @@ void luaV_execute (lua_State *L, int nex
+ const TValue *plimit = ra+1;
+ const TValue *pstep = ra+2;
+ L->savedpc = pc; /* next steps may throw errors */
++ /* Using same location for tonumber's both arguments, effectively does
++ * in-place modification (string->number). */
+ if (!tonumber(init, ra))
+ luaG_runerror(L, LUA_QL("for") " initial value must be a number");
+ else if (!tonumber(plimit, ra+1))
+ luaG_runerror(L, LUA_QL("for") " limit must be a number");
+ else if (!tonumber(pstep, ra+2))
+ luaG_runerror(L, LUA_QL("for") " step must be a number");
+- setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
++ /* Step back one value (keep within integers if we can)
++ */
++ if (!( ttisint(ra) && ttisint(pstep) &&
++ try_subint( &ra->value.i, ivalue(ra), ivalue(pstep) ) )) {
++ /* don't use 'nvalue_fast()', values may be integer */
++ setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
++ }
+ dojump(L, pc, GETARG_sBx(i));
+ continue;
+ }
+@@ -711,7 +935,7 @@ void luaV_execute (lua_State *L, int nex
+ luaH_resizearray(L, h, last); /* pre-alloc it at once */
+ for (; n > 0; n--) {
+ TValue *val = ra+n;
+- setobj2t(L, luaH_setnum(L, h, last--), val);
++ setobj2t(L, luaH_setint(L, h, last--), val);
+ luaC_barriert(L, h, val);
+ }
+ continue;
+--- a/src/lvm.h
++++ b/src/lvm.h
+@@ -15,11 +15,9 @@
+
+ #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
+
+-#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
+- (((o) = luaV_tonumber(o,n)) != NULL))
++#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL))
+
+-#define equalobj(L,o1,o2) \
+- (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
++#define equalobj(L,o1,o2) (ttype_ext_same(o1,o2) && luaV_equalval(L, o1, o2))
+
+
+ LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
+--- a/src/print.c
++++ b/src/print.c
+@@ -14,6 +14,7 @@
+ #include "lobject.h"
+ #include "lopcodes.h"
+ #include "lundump.h"
++#include "lnum.h"
+
+ #define PrintFunction luaU_print
+
+@@ -59,8 +60,16 @@ static void PrintConstant(const Proto* f
+ case LUA_TBOOLEAN:
+ printf(bvalue(o) ? "true" : "false");
+ break;
++ case LUA_TINT:
++ printf(LUA_INTEGER_FMT,ivalue(o));
++ break;
+ case LUA_TNUMBER:
+- printf(LUA_NUMBER_FMT,nvalue(o));
++#ifdef LNUM_COMPLEX
++ // TBD: Do we get complex values here?
++ { lua_Number b= nvalue_img_fast(o);
++ printf( LUA_NUMBER_FMT "%s" LUA_NUMBER_FMT "i", nvalue_fast(o), b>=0 ? "+":"", b ); }
++#endif
++ printf(LUA_NUMBER_FMT,nvalue_fast(o));
+ break;
+ case LUA_TSTRING:
+ PrintString(rawtsvalue(o));
diff --git a/package/utils/lua/patches/011-lnum-use-double.patch b/package/utils/lua/patches/011-lnum-use-double.patch
new file mode 100644
index 0000000..14c720b
--- /dev/null
+++ b/package/utils/lua/patches/011-lnum-use-double.patch
@@ -0,0 +1,11 @@
+--- a/src/lnum_config.h
++++ b/src/lnum_config.h
+@@ -11,7 +11,7 @@
+ ** Default number modes
+ */
+ #if (!defined LNUM_DOUBLE) && (!defined LNUM_FLOAT) && (!defined LNUM_LDOUBLE)
+-# define LNUM_FLOAT
++# define LNUM_DOUBLE
+ #endif
+ #if (!defined LNUM_INT16) && (!defined LNUM_INT32) && (!defined LNUM_INT64)
+ # define LNUM_INT32
diff --git a/package/utils/lua/patches/015-lnum-ppc-compat.patch b/package/utils/lua/patches/015-lnum-ppc-compat.patch
new file mode 100644
index 0000000..2ea59f1
--- /dev/null
+++ b/package/utils/lua/patches/015-lnum-ppc-compat.patch
@@ -0,0 +1,11 @@
+--- a/src/lua.h
++++ b/src/lua.h
+@@ -79,7 +79,7 @@ typedef void * (*lua_Alloc) (void *ud, v
+ * not acceptable for 5.1, maybe 5.2 onwards?
+ * 9: greater than existing (5.1) type values.
+ */
+-#define LUA_TINT (-2)
++#define LUA_TINT 9
+
+ #define LUA_TNIL 0
+ #define LUA_TBOOLEAN 1
diff --git a/package/utils/lua/patches/020-shared_liblua.patch b/package/utils/lua/patches/020-shared_liblua.patch
new file mode 100644
index 0000000..bcd410f
--- /dev/null
+++ b/package/utils/lua/patches/020-shared_liblua.patch
@@ -0,0 +1,140 @@
+--- a/Makefile
++++ b/Makefile
+@@ -42,8 +42,8 @@ PLATS= aix ansi bsd freebsd generic linu
+
+ # What to install.
+ TO_BIN= lua luac
+-TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp
+-TO_LIB= liblua.a
++TO_INC= lua.h luaconf.h lualib.h lauxlib.h ../etc/lua.hpp lnum_config.h
++TO_LIB= liblua.a liblua.so.$R
+ TO_MAN= lua.1 luac.1
+
+ # Lua version and release.
+@@ -63,6 +63,7 @@ install: dummy
+ cd src && $(INSTALL_EXEC) $(TO_BIN) $(INSTALL_BIN)
+ cd src && $(INSTALL_DATA) $(TO_INC) $(INSTALL_INC)
+ cd src && $(INSTALL_DATA) $(TO_LIB) $(INSTALL_LIB)
++ ln -s liblua.so.$R $(INSTALL_LIB)/liblua.so
+ cd doc && $(INSTALL_DATA) $(TO_MAN) $(INSTALL_MAN)
+
+ ranlib:
+--- a/src/ldo.h
++++ b/src/ldo.h
+@@ -46,7 +46,7 @@ LUAI_FUNC int luaD_pcall (lua_State *L,
+ LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult);
+ LUAI_FUNC void luaD_reallocCI (lua_State *L, int newsize);
+ LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize);
+-LUAI_FUNC void luaD_growstack (lua_State *L, int n);
++LUA_API void luaD_growstack (lua_State *L, int n);
+
+ LUAI_FUNC void luaD_throw (lua_State *L, int errcode);
+ LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
+--- a/src/lfunc.h
++++ b/src/lfunc.h
+@@ -18,7 +18,7 @@
+ cast(int, sizeof(TValue *)*((n)-1)))
+
+
+-LUAI_FUNC Proto *luaF_newproto (lua_State *L);
++LUA_API Proto *luaF_newproto (lua_State *L);
+ LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e);
+ LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems, Table *e);
+ LUAI_FUNC UpVal *luaF_newupval (lua_State *L);
+--- a/src/lmem.h
++++ b/src/lmem.h
+@@ -38,9 +38,9 @@
+ ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t))))
+
+
+-LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
++LUA_API void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
+ size_t size);
+-LUAI_FUNC void *luaM_toobig (lua_State *L);
++LUA_API void *luaM_toobig (lua_State *L);
+ LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size,
+ size_t size_elem, int limit,
+ const char *errormsg);
+--- a/src/lstring.h
++++ b/src/lstring.h
+@@ -25,7 +25,7 @@
+
+ LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
+ LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
+-LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
++LUA_API TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
+
+
+ #endif
+--- a/src/lundump.h
++++ b/src/lundump.h
+@@ -17,7 +17,7 @@ LUAI_FUNC Proto* luaU_undump (lua_State*
+ LUAI_FUNC void luaU_header (char* h);
+
+ /* dump one chunk; from ldump.c */
+-LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
++LUA_API int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
+
+ #ifdef luac_c
+ /* print one chunk; from print.c */
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -23,6 +23,7 @@ MYLIBS=
+ PLATS= aix ansi bsd freebsd generic linux macosx mingw posix solaris
+
+ LUA_A= liblua.a
++LUA_SO= liblua.so
+ CORE_O= lapi.o lcode.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o lmem.o \
+ lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o ltm.o \
+ lundump.o lvm.o lzio.o lnum.o
+@@ -33,11 +34,12 @@ LUA_T= lua
+ LUA_O= lua.o
+
+ LUAC_T= luac
+-LUAC_O= luac.o print.o
++LUAC_O= luac.o print.o lopcodes.o
+
+ ALL_O= $(CORE_O) $(LIB_O) $(LUA_O) $(LUAC_O)
+-ALL_T= $(LUA_A) $(LUA_T) $(LUAC_T)
++ALL_T= $(LUA_A) $(LUA_SO) $(LUA_T) $(LUAC_T)
+ ALL_A= $(LUA_A)
++ALL_SO= $(LUA_SO)
+
+ default: $(PLAT)
+
+@@ -47,14 +49,23 @@ o: $(ALL_O)
+
+ a: $(ALL_A)
+
++so: $(ALL_SO)
++
+ $(LUA_A): $(CORE_O) $(LIB_O)
+ $(AR) $@ $(CORE_O) $(LIB_O) # DLL needs all object files
+ $(RANLIB) $@
+
+-$(LUA_T): $(LUA_O) $(LUA_A)
+- $(CC) -o $@ $(MYLDFLAGS) $(LUA_O) $(LUA_A) $(LIBS)
++$(LUA_SO): $(CORE_O) $(LIB_O)
++ $(CC) -o $@.$(PKG_VERSION) -shared -Wl,-soname="$@.$(PKG_VERSION)" $?
++ ln -fs $@.$(PKG_VERSION) $@
++
++$(LUA_T): $(LUA_O) $(LUA_SO)
++ $(CC) -o $@ -L. -llua $(MYLDFLAGS) $(LUA_O) $(LIBS)
++
++$(LUAC_T): $(LUAC_O) $(LUA_SO)
++ $(CC) -o $@ -L. -llua $(MYLDFLAGS) $(LUAC_O) $(LIBS)
+
+-$(LUAC_T): $(LUAC_O) $(LUA_A)
++$(LUAC_T)-host: $(LUAC_O) $(LUA_A)
+ $(CC) -o $@ $(MYLDFLAGS) $(LUAC_O) $(LUA_A) $(LIBS)
+
+ clean:
+@@ -96,7 +107,7 @@ generic:
+ $(MAKE) all MYCFLAGS=
+
+ linux:
+- $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses"
++ $(MAKE) all MYCFLAGS+=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses"
+
+ macosx:
+ $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline"
diff --git a/package/utils/lua/patches/030-archindependent-bytecode.patch b/package/utils/lua/patches/030-archindependent-bytecode.patch
new file mode 100644
index 0000000..8dfef85
--- /dev/null
+++ b/package/utils/lua/patches/030-archindependent-bytecode.patch
@@ -0,0 +1,111 @@
+--- a/src/ldump.c
++++ b/src/ldump.c
+@@ -67,12 +67,12 @@ static void DumpString(const TString* s,
+ {
+ if (s==NULL || getstr(s)==NULL)
+ {
+- size_t size=0;
++ unsigned int size=0;
+ DumpVar(size,D);
+ }
+ else
+ {
+- size_t size=s->tsv.len+1; /* include trailing '\0' */
++ unsigned int size=s->tsv.len+1; /* include trailing '\0' */
+ DumpVar(size,D);
+ DumpBlock(getstr(s),size,D);
+ }
+--- a/src/lundump.c
++++ b/src/lundump.c
+@@ -25,6 +25,7 @@ typedef struct {
+ ZIO* Z;
+ Mbuffer* b;
+ const char* name;
++ int swap;
+ } LoadState;
+
+ #ifdef LUAC_TRUST_BINARIES
+@@ -40,7 +41,6 @@ static void error(LoadState* S, const ch
+ }
+ #endif
+
+-#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
+ #define LoadByte(S) (lu_byte)LoadChar(S)
+ #define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
+ #define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
+@@ -51,6 +51,49 @@ static void LoadBlock(LoadState* S, void
+ IF (r!=0, "unexpected end");
+ }
+
++static void LoadMem (LoadState* S, void* b, int n, size_t size)
++{
++ LoadBlock(S,b,n*size);
++ if (S->swap)
++ {
++ char* p=(char*) b;
++ char c;
++ switch (size)
++ {
++ case 1:
++ break;
++ case 2:
++ while (n--)
++ {
++ c=p[0]; p[0]=p[1]; p[1]=c;
++ p+=2;
++ }
++ break;
++ case 4:
++ while (n--)
++ {
++ c=p[0]; p[0]=p[3]; p[3]=c;
++ c=p[1]; p[1]=p[2]; p[2]=c;
++ p+=4;
++ }
++ break;
++ case 8:
++ while (n--)
++ {
++ c=p[0]; p[0]=p[7]; p[7]=c;
++ c=p[1]; p[1]=p[6]; p[6]=c;
++ c=p[2]; p[2]=p[5]; p[5]=c;
++ c=p[3]; p[3]=p[4]; p[4]=c;
++ p+=8;
++ }
++ break;
++ default:
++ IF(1, "bad size");
++ break;
++ }
++ }
++}
++
+ static int LoadChar(LoadState* S)
+ {
+ char x;
+@@ -82,7 +125,7 @@ static lua_Integer LoadInteger(LoadState
+
+ static TString* LoadString(LoadState* S)
+ {
+- size_t size;
++ unsigned int size;
+ LoadVar(S,size);
+ if (size==0)
+ return NULL;
+@@ -196,6 +239,7 @@ static void LoadHeader(LoadState* S)
+ char s[LUAC_HEADERSIZE];
+ luaU_header(h);
+ LoadBlock(S,s,LUAC_HEADERSIZE);
++ S->swap=(s[6]!=h[6]); s[6]=h[6];
+ IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
+ }
+
+@@ -230,7 +274,7 @@ void luaU_header (char* h)
+ *h++=(char)LUAC_FORMAT;
+ *h++=(char)*(char*)&x; /* endianness */
+ *h++=(char)sizeof(int);
+- *h++=(char)sizeof(size_t);
++ *h++=(char)sizeof(unsigned int);
+ *h++=(char)sizeof(Instruction);
+ *h++=(char)sizeof(lua_Number);
+
diff --git a/package/utils/lua/patches/040-use-symbolic-functions.patch b/package/utils/lua/patches/040-use-symbolic-functions.patch
new file mode 100644
index 0000000..f590695
--- /dev/null
+++ b/package/utils/lua/patches/040-use-symbolic-functions.patch
@@ -0,0 +1,11 @@
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -56,7 +56,7 @@ $(LUA_A): $(CORE_O) $(LIB_O)
+ $(RANLIB) $@
+
+ $(LUA_SO): $(CORE_O) $(LIB_O)
+- $(CC) -o $@.$(PKG_VERSION) -shared -Wl,-soname="$@.$(PKG_VERSION)" $?
++ $(CC) -o $@.$(PKG_VERSION) -Wl,-Bsymbolic-functions -shared -Wl,-soname="$@.$(PKG_VERSION)" $?
+ ln -fs $@.$(PKG_VERSION) $@
+
+ $(LUA_T): $(LUA_O) $(LUA_SO)
diff --git a/package/utils/lua/patches/050-honor-cflags.patch b/package/utils/lua/patches/050-honor-cflags.patch
new file mode 100644
index 0000000..dd65791
--- /dev/null
+++ b/package/utils/lua/patches/050-honor-cflags.patch
@@ -0,0 +1,11 @@
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -56,7 +56,7 @@ $(LUA_A): $(CORE_O) $(LIB_O)
+ $(RANLIB) $@
+
+ $(LUA_SO): $(CORE_O) $(LIB_O)
+- $(CC) -o $@.$(PKG_VERSION) -Wl,-Bsymbolic-functions -shared -Wl,-soname="$@.$(PKG_VERSION)" $?
++ $(CC) -o $@.$(PKG_VERSION) -Wl,-Bsymbolic-functions $(MYLDFLAGS) -shared -Wl,-soname="$@.$(PKG_VERSION)" $?
+ ln -fs $@.$(PKG_VERSION) $@
+
+
diff --git a/package/utils/lua/patches/100-no_readline.patch b/package/utils/lua/patches/100-no_readline.patch
new file mode 100644
index 0000000..0350e47
--- /dev/null
+++ b/package/utils/lua/patches/100-no_readline.patch
@@ -0,0 +1,49 @@
+--- a/src/luaconf.h
++++ b/src/luaconf.h
+@@ -38,7 +38,6 @@
+ #if defined(LUA_USE_LINUX)
+ #define LUA_USE_POSIX
+ #define LUA_USE_DLOPEN /* needs an extra library: -ldl */
+-#define LUA_USE_READLINE /* needs some extra libraries */
+ #endif
+
+ #if defined(LUA_USE_MACOSX)
+--- a/src/Makefile
++++ b/src/Makefile
+@@ -17,6 +17,7 @@ LIBS= -lm $(MYLIBS)
+ MYCFLAGS=
+ MYLDFLAGS=
+ MYLIBS=
++# USE_READLINE=1
+
+ # == END OF USER SETTINGS. NO NEED TO CHANGE ANYTHING BELOW THIS LINE =========
+
+@@ -86,7 +87,7 @@ echo:
+ @echo "MYLIBS = $(MYLIBS)"
+
+ # convenience targets for popular platforms
+-
++RFLAG=$(if $(USE_READLINE),-DLUA_USE_READLINE)
+ none:
+ @echo "Please choose a platform:"
+ @echo " $(PLATS)"
+@@ -101,16 +102,16 @@ bsd:
+ $(MAKE) all MYCFLAGS="-DLUA_USE_POSIX -DLUA_USE_DLOPEN" MYLIBS="-Wl,-E"
+
+ freebsd:
+- $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX" MYLIBS="-Wl,-E -lreadline"
++ $(MAKE) all MYCFLAGS="-DLUA_USE_LINUX $(RFLAG)" MYLIBS="-Wl,-E$(if $(USE_READLINE), -lreadline)"
+
+ generic:
+ $(MAKE) all MYCFLAGS=
+
+ linux:
+- $(MAKE) all MYCFLAGS+=-DLUA_USE_LINUX MYLIBS="-Wl,-E -ldl -lreadline -lhistory -lncurses"
++ $(MAKE) all MYCFLAGS+="-DLUA_USE_LINUX $(RFLAG)" MYLIBS="-Wl,-E -ldl $(if $(USE_READLINE), -lreadline -lhistory -lncurses)"
+
+ macosx:
+- $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX MYLIBS="-lreadline"
++ $(MAKE) all MYCFLAGS=-DLUA_USE_LINUX $(if $(USE_READLINE), MYLIBS="-lreadline")
+ # use this on Mac OS X 10.3-
+ # $(MAKE) all MYCFLAGS=-DLUA_USE_MACOSX
+
diff --git a/package/utils/lua/patches/200-lua-path.patch b/package/utils/lua/patches/200-lua-path.patch
new file mode 100644
index 0000000..0544577
--- /dev/null
+++ b/package/utils/lua/patches/200-lua-path.patch
@@ -0,0 +1,15 @@
+--- a/src/luaconf.h
++++ b/src/luaconf.h
+@@ -95,9 +95,9 @@
+ ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
+
+ #else
+-#define LUA_ROOT "/usr/local/"
+-#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
+-#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
++#define LUA_ROOT "/usr/"
++#define LUA_LDIR LUA_ROOT "share/lua/"
++#define LUA_CDIR LUA_ROOT "lib/lua/"
+ #define LUA_PATH_DEFAULT \
+ "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
diff --git a/package/utils/lua/patches/300-opcode_performance.patch b/package/utils/lua/patches/300-opcode_performance.patch
new file mode 100644
index 0000000..5fbb873
--- /dev/null
+++ b/package/utils/lua/patches/300-opcode_performance.patch
@@ -0,0 +1,363 @@
+--- a/src/lvm.c
++++ b/src/lvm.c
+@@ -31,6 +31,9 @@
+ /* limit for table tag-method chains (to avoid loops) */
+ #define MAXTAGLOOP 100
+
++#ifdef __GNUC__
++#define COMPUTED_GOTO 1
++#endif
+
+ /*
+ * If 'obj' is a string, it is tried to be interpreted as a number.
+@@ -566,12 +569,63 @@ static inline int arith_mode( const TVal
+ ARITH_OP1_END
+ #endif
+
++#ifdef COMPUTED_GOTO
++#define OPCODE_TARGET(op) DO_OP_##op:
++#define CALL_OPCODE(op) goto *opcodes[op];
++#define OPCODE_PTR(op) [OP_##op] = &&DO_OP_##op
++#else
++#define OPCODE_TARGET(op) case OP_##op:
++#define CALL_OPCODE(op) switch (op)
++#endif
++
+
+ void luaV_execute (lua_State *L, int nexeccalls) {
+ LClosure *cl;
+ StkId base;
+ TValue *k;
+ const Instruction *pc;
++#ifdef COMPUTED_GOTO
++ static const void *opcodes[] = {
++ OPCODE_PTR(MOVE),
++ OPCODE_PTR(LOADK),
++ OPCODE_PTR(LOADBOOL),
++ OPCODE_PTR(LOADNIL),
++ OPCODE_PTR(GETUPVAL),
++ OPCODE_PTR(GETGLOBAL),
++ OPCODE_PTR(GETTABLE),
++ OPCODE_PTR(SETGLOBAL),
++ OPCODE_PTR(SETUPVAL),
++ OPCODE_PTR(SETTABLE),
++ OPCODE_PTR(NEWTABLE),
++ OPCODE_PTR(SELF),
++ OPCODE_PTR(ADD),
++ OPCODE_PTR(SUB),
++ OPCODE_PTR(MUL),
++ OPCODE_PTR(DIV),
++ OPCODE_PTR(MOD),
++ OPCODE_PTR(POW),
++ OPCODE_PTR(UNM),
++ OPCODE_PTR(NOT),
++ OPCODE_PTR(LEN),
++ OPCODE_PTR(CONCAT),
++ OPCODE_PTR(JMP),
++ OPCODE_PTR(EQ),
++ OPCODE_PTR(LT),
++ OPCODE_PTR(LE),
++ OPCODE_PTR(TEST),
++ OPCODE_PTR(TESTSET),
++ OPCODE_PTR(CALL),
++ OPCODE_PTR(TAILCALL),
++ OPCODE_PTR(RETURN),
++ OPCODE_PTR(FORLOOP),
++ OPCODE_PTR(FORPREP),
++ OPCODE_PTR(TFORLOOP),
++ OPCODE_PTR(SETLIST),
++ OPCODE_PTR(CLOSE),
++ OPCODE_PTR(CLOSURE),
++ OPCODE_PTR(VARARG)
++ };
++#endif
+ reentry: /* entry point */
+ lua_assert(isLua(L->ci));
+ pc = L->savedpc;
+@@ -596,33 +650,33 @@ void luaV_execute (lua_State *L, int nex
+ lua_assert(base == L->base && L->base == L->ci->base);
+ lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
+ lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
+- switch (GET_OPCODE(i)) {
+- case OP_MOVE: {
++ CALL_OPCODE(GET_OPCODE(i)) {
++ OPCODE_TARGET(MOVE) {
+ setobjs2s(L, ra, RB(i));
+ continue;
+ }
+- case OP_LOADK: {
++ OPCODE_TARGET(LOADK) {
+ setobj2s(L, ra, KBx(i));
+ continue;
+ }
+- case OP_LOADBOOL: {
++ OPCODE_TARGET(LOADBOOL) {
+ setbvalue(ra, GETARG_B(i));
+ if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
+ continue;
+ }
+- case OP_LOADNIL: {
++ OPCODE_TARGET(LOADNIL) {
+ TValue *rb = RB(i);
+ do {
+ setnilvalue(rb--);
+ } while (rb >= ra);
+ continue;
+ }
+- case OP_GETUPVAL: {
++ OPCODE_TARGET(GETUPVAL) {
+ int b = GETARG_B(i);
+ setobj2s(L, ra, cl->upvals[b]->v);
+ continue;
+ }
+- case OP_GETGLOBAL: {
++ OPCODE_TARGET(GETGLOBAL) {
+ TValue g;
+ TValue *rb = KBx(i);
+ sethvalue(L, &g, cl->env);
+@@ -630,88 +684,88 @@ void luaV_execute (lua_State *L, int nex
+ Protect(luaV_gettable(L, &g, rb, ra));
+ continue;
+ }
+- case OP_GETTABLE: {
++ OPCODE_TARGET(GETTABLE) {
+ Protect(luaV_gettable(L, RB(i), RKC(i), ra));
+ continue;
+ }
+- case OP_SETGLOBAL: {
++ OPCODE_TARGET(SETGLOBAL) {
+ TValue g;
+ sethvalue(L, &g, cl->env);
+ lua_assert(ttisstring(KBx(i)));
+ Protect(luaV_settable(L, &g, KBx(i), ra));
+ continue;
+ }
+- case OP_SETUPVAL: {
++ OPCODE_TARGET(SETUPVAL) {
+ UpVal *uv = cl->upvals[GETARG_B(i)];
+ setobj(L, uv->v, ra);
+ luaC_barrier(L, uv, ra);
+ continue;
+ }
+- case OP_SETTABLE: {
++ OPCODE_TARGET(SETTABLE) {
+ Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
+ continue;
+ }
+- case OP_NEWTABLE: {
++ OPCODE_TARGET(NEWTABLE) {
+ int b = GETARG_B(i);
+ int c = GETARG_C(i);
+ sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
+ Protect(luaC_checkGC(L));
+ continue;
+ }
+- case OP_SELF: {
++ OPCODE_TARGET(SELF) {
+ StkId rb = RB(i);
+ setobjs2s(L, ra+1, rb);
+ Protect(luaV_gettable(L, rb, RKC(i), ra));
+ continue;
+ }
+- case OP_ADD: {
++ OPCODE_TARGET(ADD) {
+ TValue *rb = RKB(i), *rc= RKC(i);
+ arith_op_continue( luai_numadd, try_addint, luai_vectadd );
+ Protect(Arith(L, ra, rb, rc, TM_ADD)); \
+ continue;
+ }
+- case OP_SUB: {
++ OPCODE_TARGET(SUB) {
+ TValue *rb = RKB(i), *rc= RKC(i);
+ arith_op_continue( luai_numsub, try_subint, luai_vectsub );
+ Protect(Arith(L, ra, rb, rc, TM_SUB));
+ continue;
+ }
+- case OP_MUL: {
++ OPCODE_TARGET(MUL) {
+ TValue *rb = RKB(i), *rc= RKC(i);
+ arith_op_continue(luai_nummul, try_mulint, luai_vectmul);
+ Protect(Arith(L, ra, rb, rc, TM_MUL));
+ continue;
+ }
+- case OP_DIV: {
++ OPCODE_TARGET(DIV) {
+ TValue *rb = RKB(i), *rc= RKC(i);
+ arith_op_continue(luai_numdiv, try_divint, luai_vectdiv);
+ Protect(Arith(L, ra, rb, rc, TM_DIV));
+ continue;
+ }
+- case OP_MOD: {
++ OPCODE_TARGET(MOD) {
+ TValue *rb = RKB(i), *rc= RKC(i);
+ arith_op_continue_scalar(luai_nummod, try_modint); /* scalars only */
+ Protect(Arith(L, ra, rb, rc, TM_MOD));
+ continue;
+ }
+- case OP_POW: {
++ OPCODE_TARGET(POW) {
+ TValue *rb = RKB(i), *rc= RKC(i);
+ arith_op_continue(luai_numpow, try_powint, luai_vectpow);
+ Protect(Arith(L, ra, rb, rc, TM_POW));
+ continue;
+ }
+- case OP_UNM: {
++ OPCODE_TARGET(UNM) {
+ TValue *rb = RB(i);
+ arith_op1_continue(luai_numunm, try_unmint, luai_vectunm);
+ Protect(Arith(L, ra, rb, rb, TM_UNM));
+ continue;
+ }
+- case OP_NOT: {
++ OPCODE_TARGET(NOT) {
+ int res = l_isfalse(RB(i)); /* next assignment may change this value */
+ setbvalue(ra, res);
+ continue;
+ }
+- case OP_LEN: {
++ OPCODE_TARGET(LEN) {
+ const TValue *rb = RB(i);
+ switch (ttype(rb)) {
+ case LUA_TTABLE: {
+@@ -731,18 +785,18 @@ void luaV_execute (lua_State *L, int nex
+ }
+ continue;
+ }
+- case OP_CONCAT: {
++ OPCODE_TARGET(CONCAT) {
+ int b = GETARG_B(i);
+ int c = GETARG_C(i);
+ Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
+ setobjs2s(L, RA(i), base+b);
+ continue;
+ }
+- case OP_JMP: {
++ OPCODE_TARGET(JMP) {
+ dojump(L, pc, GETARG_sBx(i));
+ continue;
+ }
+- case OP_EQ: {
++ OPCODE_TARGET(EQ) {
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
+ Protect(
+@@ -752,7 +806,7 @@ void luaV_execute (lua_State *L, int nex
+ pc++;
+ continue;
+ }
+- case OP_LT: {
++ OPCODE_TARGET(LT) {
+ Protect(
+ if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
+ dojump(L, pc, GETARG_sBx(*pc));
+@@ -760,7 +814,7 @@ void luaV_execute (lua_State *L, int nex
+ pc++;
+ continue;
+ }
+- case OP_LE: {
++ OPCODE_TARGET(LE) {
+ Protect(
+ if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
+ dojump(L, pc, GETARG_sBx(*pc));
+@@ -768,13 +822,13 @@ void luaV_execute (lua_State *L, int nex
+ pc++;
+ continue;
+ }
+- case OP_TEST: {
++ OPCODE_TARGET(TEST) {
+ if (l_isfalse(ra) != GETARG_C(i))
+ dojump(L, pc, GETARG_sBx(*pc));
+ pc++;
+ continue;
+ }
+- case OP_TESTSET: {
++ OPCODE_TARGET(TESTSET) {
+ TValue *rb = RB(i);
+ if (l_isfalse(rb) != GETARG_C(i)) {
+ setobjs2s(L, ra, rb);
+@@ -783,7 +837,7 @@ void luaV_execute (lua_State *L, int nex
+ pc++;
+ continue;
+ }
+- case OP_CALL: {
++ OPCODE_TARGET(CALL) {
+ int b = GETARG_B(i);
+ int nresults = GETARG_C(i) - 1;
+ if (b != 0) L->top = ra+b; /* else previous instruction set top */
+@@ -804,7 +858,7 @@ void luaV_execute (lua_State *L, int nex
+ }
+ }
+ }
+- case OP_TAILCALL: {
++ OPCODE_TARGET(TAILCALL) {
+ int b = GETARG_B(i);
+ if (b != 0) L->top = ra+b; /* else previous instruction set top */
+ L->savedpc = pc;
+@@ -836,7 +890,7 @@ void luaV_execute (lua_State *L, int nex
+ }
+ }
+ }
+- case OP_RETURN: {
++ OPCODE_TARGET(RETURN) {
+ int b = GETARG_B(i);
+ if (b != 0) L->top = ra+b-1;
+ if (L->openupval) luaF_close(L, base);
+@@ -851,7 +905,7 @@ void luaV_execute (lua_State *L, int nex
+ goto reentry;
+ }
+ }
+- case OP_FORLOOP: {
++ OPCODE_TARGET(FORLOOP) {
+ /* If start,step and limit are all integers, we don't need to check
+ * against overflow in the looping.
+ */
+@@ -879,7 +933,7 @@ void luaV_execute (lua_State *L, int nex
+ }
+ continue;
+ }
+- case OP_FORPREP: {
++ OPCODE_TARGET(FORPREP) {
+ const TValue *init = ra;
+ const TValue *plimit = ra+1;
+ const TValue *pstep = ra+2;
+@@ -902,7 +956,7 @@ void luaV_execute (lua_State *L, int nex
+ dojump(L, pc, GETARG_sBx(i));
+ continue;
+ }
+- case OP_TFORLOOP: {
++ OPCODE_TARGET(TFORLOOP) {
+ StkId cb = ra + 3; /* call base */
+ setobjs2s(L, cb+2, ra+2);
+ setobjs2s(L, cb+1, ra+1);
+@@ -918,7 +972,7 @@ void luaV_execute (lua_State *L, int nex
+ pc++;
+ continue;
+ }
+- case OP_SETLIST: {
++ OPCODE_TARGET(SETLIST) {
+ int n = GETARG_B(i);
+ int c = GETARG_C(i);
+ int last;
+@@ -940,11 +994,11 @@ void luaV_execute (lua_State *L, int nex
+ }
+ continue;
+ }
+- case OP_CLOSE: {
++ OPCODE_TARGET(CLOSE) {
+ luaF_close(L, ra);
+ continue;
+ }
+- case OP_CLOSURE: {
++ OPCODE_TARGET(CLOSURE) {
+ Proto *p;
+ Closure *ncl;
+ int nup, j;
+@@ -964,7 +1018,7 @@ void luaV_execute (lua_State *L, int nex
+ Protect(luaC_checkGC(L));
+ continue;
+ }
+- case OP_VARARG: {
++ OPCODE_TARGET(VARARG) {
+ int b = GETARG_B(i) - 1;
+ int j;
+ CallInfo *ci = L->ci;
diff --git a/package/utils/mdadm/Makefile b/package/utils/mdadm/Makefile
new file mode 100644
index 0000000..69eec5b
--- /dev/null
+++ b/package/utils/mdadm/Makefile
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2008-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mdadm
+PKG_VERSION:=3.2.5
+PKG_RELEASE:=1
+
+PKG_SOURCE_URL:=@KERNEL/linux/utils/raid/mdadm
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_MD5SUM:=2fd33dedcdb06f0d1461f50ddabb7e4a
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+
+PKG_BUILD_PARALLEL:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/mdadm
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=A tool for managing Soft RAID under Linux
+ URL:=http://www.kernel.org/pub/linux/utils/raid/mdadm/
+ DEPENDS:=+@KERNEL_DIRECT_IO
+endef
+
+define Package/mdadm/description
+ A tool for managing Linux Software RAID arrays.
+endef
+
+TARGET_CFLAGS += -ffunction-sections -fdata-sections
+TARGET_LDFLAGS += -Wl,--gc-sections
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -DHAVE_STDINT_H" \
+ LDFLAGS="$(TARGET_LDFLAGS)" \
+ mdadm
+endef
+
+define Package/mdadm/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/mdadm $(1)/sbin
+endef
+
+$(eval $(call BuildPackage,mdadm))
diff --git a/package/utils/mdadm/patches/000-compile.patch b/package/utils/mdadm/patches/000-compile.patch
new file mode 100644
index 0000000..6d47489
--- /dev/null
+++ b/package/utils/mdadm/patches/000-compile.patch
@@ -0,0 +1,11 @@
+--- a/sha1.h
++++ b/sha1.h
+@@ -26,8 +26,6 @@
+ # include <limits.h>
+ #endif
+
+-#include "ansidecl.h"
+-
+ /* The following contortions are an attempt to use the C preprocessor
+ to determine an unsigned integral type that is 32 bits wide. An
+ alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but
diff --git a/package/utils/mdadm/patches/100-cross_compile.patch b/package/utils/mdadm/patches/100-cross_compile.patch
new file mode 100644
index 0000000..8709e57
--- /dev/null
+++ b/package/utils/mdadm/patches/100-cross_compile.patch
@@ -0,0 +1,19 @@
+--- a/Makefile
++++ b/Makefile
+@@ -76,7 +76,6 @@ FAILED_SLOTS_DIR = /run/mdadm/failed-slo
+ DIRFLAGS = -DMAP_DIR=\"$(MAP_DIR)\" -DMAP_FILE=\"$(MAP_FILE)\"
+ DIRFLAGS += -DMDMON_DIR=\"$(MDMON_DIR)\"
+ DIRFLAGS += -DFAILED_SLOTS_DIR=\"$(FAILED_SLOTS_DIR)\"
+-CFLAGS = $(CWFLAGS) $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\" $(CONFFILEFLAGS) $(DIRFLAGS)
+
+ # The glibc TLS ABI requires applications that call clone(2) to set up
+ # TLS data structures, use pthreads until mdmon implements this support
+@@ -183,7 +182,7 @@ raid6check : raid6check.o mdadm.h $(CHEC
+
+ mdassemble : $(ASSEMBLE_SRCS) $(INCL)
+ rm -f $(OBJS)
+- $(DIET_GCC) $(ASSEMBLE_FLAGS) -o mdassemble $(ASSEMBLE_SRCS) $(STATICSRC)
++ $(CC) $(ASSEMBLE_FLAGS) -o mdassemble $(ASSEMBLE_SRCS) $(STATICSRC)
+
+ mdassemble.static : $(ASSEMBLE_SRCS) $(INCL)
+ rm -f $(OBJS)
diff --git a/package/utils/mdadm/patches/200-reduce_size.patch b/package/utils/mdadm/patches/200-reduce_size.patch
new file mode 100644
index 0000000..3d8c2f4
--- /dev/null
+++ b/package/utils/mdadm/patches/200-reduce_size.patch
@@ -0,0 +1,25 @@
+--- a/Incremental.c
++++ b/Incremental.c
+@@ -1508,6 +1508,10 @@ static int Incremental_container(struct
+ if (ra_all == ra_blocked)
+ return 0;
+
++#ifndef MDADM_FULL
++ return 0;
++#endif
++
+ /* Now move all suitable spares from spare container */
+ domains = domain_from_array(list, st->ss->name);
+ memcpy(suuid, uuid_zero, sizeof(int[4]));
+--- a/util.c
++++ b/util.c
+@@ -928,7 +928,9 @@ void wait_for(char *dev, int fd)
+ struct superswitch *superlist[] =
+ {
+ &super0, &super1,
++#ifdef MDADM_FULL
+ &super_ddf, &super_imsm,
++#endif
+ &mbr, &gpt,
+ NULL };
+
diff --git a/package/utils/mkelfimage/Makefile b/package/utils/mkelfimage/Makefile
new file mode 100644
index 0000000..3a52e71
--- /dev/null
+++ b/package/utils/mkelfimage/Makefile
@@ -0,0 +1,35 @@
+#
+# Copyright (C) 2006 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=mkelfimage
+PKG_VERSION:=2.7
+
+PKG_SOURCE:=$(PKG_NAME)_$(PKG_VERSION).orig.tar.gz
+PKG_SOURCE_URL:=http://ftp.debian.org/debian/pool/main/m/mkelfimage/
+PKG_MD5SUM:=e505cb87e9c0cdc44cf03d2c4ea8c74b
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/mkelfimage
+ SECTION:=base
+ CATEGORY:=Base system
+ TITLE:=mkelfimage
+ HIDDEN:=1
+ DEPENDS:=@i386
+ DEFAULT:=y if TARGET_x86
+endef
+
+CONFIGURE_VARS += AS="$(TARGET_CROSS)as"
+MAKE_FLAGS += HOST_CC="$(HOSTCC)" DEFS="-I$(STAGING_DIR_HOST)/include"
+
+define Build/InstallDev
+ $(INSTALL_DIR) $(STAGING_DIR_HOST)/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/objdir/sbin/mkelfImage $(STAGING_DIR_HOST)/bin
+endef
+
+$(eval $(call BuildPackage,mkelfimage))
diff --git a/package/utils/mkelfimage/patches/no-stack-protector.patch b/package/utils/mkelfimage/patches/no-stack-protector.patch
new file mode 100644
index 0000000..108583a
--- /dev/null
+++ b/package/utils/mkelfimage/patches/no-stack-protector.patch
@@ -0,0 +1,11 @@
+--- mkelfimage-2.7.old//Makefile 2006-03-28 02:44:59.000000000 +0300
++++ mkelfimage-2.7/Makefile 2011-01-17 14:15:13.000000000 +0200
+@@ -14,7 +14,7 @@
+ pkglibdir = $(libdir)/$(PACKAGE)
+ pkgincludedir = $(includedir)/$(PACKAGE)
+
+-CPPFLAGS=-DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(RELEASE_DATE)"' -I include
++CPPFLAGS=-DVERSION='"$(VERSION)"' -DRELEASE_DATE='"$(RELEASE_DATE)"' -I include -fno-stack-protector
+ HOST_CPPFLAGS=$(CPPFLAGS)
+ I386_CPPFLAGS=$(CPPFLAGS) -I arch/i386/include
+ IA64_CPPFLAGS=$(CPPFLAGS) -I arch/ia64/include
diff --git a/package/utils/nvram/Makefile b/package/utils/nvram/Makefile
new file mode 100644
index 0000000..992f336
--- /dev/null
+++ b/package/utils/nvram/Makefile
@@ -0,0 +1,52 @@
+#
+# Copyright (C) 2009-2010 Jo-Philipp Wich <xm@subsignal.org>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=nvram
+PKG_RELEASE:=9
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/nvram
+ SECTION:=utils
+ CATEGORY:=Base system
+ TITLE:=Userspace port of the Broadcom NVRAM manipulation tool
+ MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
+ DEPENDS:=@TARGET_brcm47xx||@TARGET_bcm53xx||@TARGET_ar71xx
+endef
+
+define Package/nvram/description
+ This package contains an utility to manipulate NVRAM on Broadcom based devices.
+ It works on bcm47xx (Linux 2.6) without using the kernel api.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Configure
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -Wall" \
+ LDFLAGS="$(TARGET_LDFLAGS)"
+endef
+
+define Package/nvram/install
+ $(INSTALL_DIR) $(1)/etc/init.d
+ $(INSTALL_BIN) ./files/nvram.init $(1)/etc/init.d/nvram
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/nvram $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,nvram))
diff --git a/package/utils/nvram/files/nvram.init b/package/utils/nvram/files/nvram.init
new file mode 100755
index 0000000..467ab28
--- /dev/null
+++ b/package/utils/nvram/files/nvram.init
@@ -0,0 +1,98 @@
+#!/bin/sh /etc/rc.common
+# NVRAM setup
+#
+# This file handles the NVRAM quirks of various hardware.
+
+START=02
+alias debug=${DEBUG:-:}
+
+nvram_default() {
+ [ -z "$(nvram get $1)" ] && nvram set "$1=$2"
+}
+
+nvram_set() { # for the linksys fixup part
+ [ "$(nvram get "$1")" = "$2" -a "$2" != "" ] || {
+ COMMIT=1
+ /usr/sbin/nvram set "$1=$2"
+ }
+}
+
+fixup_linksys() {
+ # work around braindead CFE defaults in linksys routers
+ boardtype=$(nvram get boardtype)
+ boardnum=$(nvram get boardnum)
+ boardflags=$(($(nvram get boardflags)))
+ adm_switch="$(( ($boardflags & 0x80) >> 7 ))"
+
+ [ -n "$(nvram get vxkilled)" ] && boardtype=0 # don't mess with the ram settings on the hacked cfe
+ case "$(( $boardtype ))" in
+ "1800") #0x708
+ if [ "$adm_switch" = 0 ]; then
+ nvram_set sdram_init "$(printf 0x%04x $(( $(/usr/sbin/nvram get sdram_init) | 0x0100 )))"
+ [ "$COMMIT" = 1 ] && {
+ nvram_set clkfreq 216
+ nvram_set sdram_ncdl 0x0
+ nvram_set pa0itssit 62
+ nvram_set pa0b0 0x15eb
+ nvram_set pa0b1 0xfa82
+ nvram_set pa0b2 0xfe66
+ nvram_set pa0maxpwr 0x4e
+ }
+ fi
+ ;;
+ "1127") #0x467
+ nvram_set sdram_init "$(printf 0x%04x $(( $(/usr/sbin/nvram get sdram_init) | 0x0100 )))"
+ [ "$COMMIT" = 1 ] && {
+ nvram_set sdram_ncdl 0x0
+ nvram_set pa0itssit 62
+ nvram_set pa0b0 0x168b
+ nvram_set pa0b1 0xfabf
+ nvram_set pa0b2 0xfeaf
+ nvram_set pa0maxpwr 0x4e
+ }
+ ;;
+ "1071") #0x042f
+ # do sanity check first! max 0x0011 = 128mb
+ SDRAM_INIT=$(printf %d $(/usr/sbin/nvram get sdram_init))
+ [ "$SDRAM_INIT" -lt "9" -o "$SDRAM_INIT" -gt "17" ] && {
+ # set this to default: 0x09 only if value is invaild like 16MB on Asus WL-500GP
+ echo "sdram_init is invaild: $(printf 0x%04x $SDRAM_INIT), force to default!"
+ nvram_set sdram_init 0x0009
+ }
+ # on WRT54G3GV2 set flag, so checksum errors of firmware image 2 don't stop the boot process
+ noset_try_flag=$(nvram get noset_try_flag)
+ [ "$noset_try_flag" = 0 ] && {
+ echo "setting noset_try_flag to 1."
+ nvram_set noset_try_flag 1
+ }
+ [ "$COMMIT" = 1 ] && {
+ nvram_set sdram_ncdl 0x0
+ }
+ esac
+}
+
+start() {
+ # Don't do any fixups on the WGT634U
+ [ "$(cat /proc/diag/model)" = "Netgear WGT634U" ] && return
+
+ fixup_linksys
+
+ # OFDM Power Offset is set incorrectly on many boards.
+ # Setting it to 0 will increase the tx power to normal levels.
+ nvram_set opo 0x0
+
+ [ "$(nvram get il0macaddr)" = "00:90:4c:5f:00:2a" ] && {
+ # if default wifi mac, set two higher than the lan mac
+ nvram set il0macaddr=$(nvram get et0macaddr|
+ awk '{OFS=FS=":";for(x=7,y=2;--x;){$x=sprintf("%02x",(y+="0x"$x)%256);y/=256}print}')
+ }
+
+ [ "$(nvram get et0macaddr)" = "00:90:4c:c0:00:08" ] && {
+ # OvisLink WL-1600GL mac workaround
+ nvram set et0macaddr=$(hexdump -n 6 -s 130976 -e '5/1 "%02x:" "%02x" ' /dev/mtd/0)
+ nvram set il0macaddr=$(nvram get et0macaddr|
+ awk '{OFS=FS=":";for(x=7,y=2;--x;){$x=sprintf("%02x",(y+="0x"$x)%256);y/=256}print}')
+ }
+
+ [ "$COMMIT" = "1" ] && nvram commit
+}
diff --git a/package/utils/nvram/src/Makefile b/package/utils/nvram/src/Makefile
new file mode 100644
index 0000000..68a6354
--- /dev/null
+++ b/package/utils/nvram/src/Makefile
@@ -0,0 +1,7 @@
+all: nvram
+
+nvram:
+ $(CC) $(CFLAGS) -o $@ cli.c crc.c nvram.c $(LDFLAGS)
+
+clean:
+ rm -f nvram
diff --git a/package/utils/nvram/src/cli.c b/package/utils/nvram/src/cli.c
new file mode 100644
index 0000000..488d641
--- /dev/null
+++ b/package/utils/nvram/src/cli.c
@@ -0,0 +1,246 @@
+/*
+ * Command line interface for libnvram
+ *
+ * Copyright 2009, Jo-Philipp Wich <xm@subsignal.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *
+ * The libnvram code is based on Broadcom code for Linux 2.4.x .
+ *
+ */
+
+#include "nvram.h"
+
+
+static nvram_handle_t * nvram_open_rdonly(void)
+{
+ const char *file = nvram_find_staging();
+
+ if( file == NULL )
+ file = nvram_find_mtd();
+
+ if( file != NULL )
+ return nvram_open(file, NVRAM_RO);
+
+ return NULL;
+}
+
+static nvram_handle_t * nvram_open_staging(void)
+{
+ if( nvram_find_staging() != NULL || nvram_to_staging() == 0 )
+ return nvram_open(NVRAM_STAGING, NVRAM_RW);
+
+ return NULL;
+}
+
+static int do_show(nvram_handle_t *nvram)
+{
+ nvram_tuple_t *t;
+ int stat = 1;
+
+ if( (t = nvram_getall(nvram)) != NULL )
+ {
+ while( t )
+ {
+ printf("%s=%s\n", t->name, t->value);
+ t = t->next;
+ }
+
+ stat = 0;
+ }
+
+ return stat;
+}
+
+static int do_get(nvram_handle_t *nvram, const char *var)
+{
+ const char *val;
+ int stat = 1;
+
+ if( (val = nvram_get(nvram, var)) != NULL )
+ {
+ printf("%s\n", val);
+ stat = 0;
+ }
+
+ return stat;
+}
+
+static int do_unset(nvram_handle_t *nvram, const char *var)
+{
+ return nvram_unset(nvram, var);
+}
+
+static int do_set(nvram_handle_t *nvram, const char *pair)
+{
+ char *val = strstr(pair, "=");
+ char var[strlen(pair)];
+ int stat = 1;
+
+ if( val != NULL )
+ {
+ memset(var, 0, sizeof(var));
+ strncpy(var, pair, (int)(val-pair));
+ stat = nvram_set(nvram, var, (char *)(val + 1));
+ }
+
+ return stat;
+}
+
+static int do_info(nvram_handle_t *nvram)
+{
+ nvram_header_t *hdr = nvram_header(nvram);
+
+ /* CRC8 over the last 11 bytes of the header and data bytes */
+ uint8_t crc = hndcrc8((unsigned char *) &hdr[0] + NVRAM_CRC_START_POSITION,
+ hdr->len - NVRAM_CRC_START_POSITION, 0xff);
+
+ /* Show info */
+ printf("Magic: 0x%08X\n", hdr->magic);
+ printf("Length: 0x%08X\n", hdr->len);
+ printf("Offset: 0x%08X\n", nvram->offset);
+
+ printf("CRC8: 0x%02X (calculated: 0x%02X)\n",
+ hdr->crc_ver_init & 0xFF, crc);
+
+ printf("Version: 0x%02X\n", (hdr->crc_ver_init >> 8) & 0xFF);
+ printf("SDRAM init: 0x%04X\n", (hdr->crc_ver_init >> 16) & 0xFFFF);
+ printf("SDRAM config: 0x%04X\n", hdr->config_refresh & 0xFFFF);
+ printf("SDRAM refresh: 0x%04X\n", (hdr->config_refresh >> 16) & 0xFFFF);
+ printf("NCDL values: 0x%08X\n\n", hdr->config_ncdl);
+
+ printf("%i bytes used / %i bytes available (%.2f%%)\n",
+ hdr->len, nvram->length - nvram->offset - hdr->len,
+ (100.00 / (double)(nvram->length - nvram->offset)) * (double)hdr->len);
+
+ return 0;
+}
+
+
+int main( int argc, const char *argv[] )
+{
+ nvram_handle_t *nvram;
+ int commit = 0;
+ int write = 0;
+ int stat = 1;
+ int done = 0;
+ int i;
+
+ /* Ugly... iterate over arguments to see whether we can expect a write */
+ for( i = 1; i < argc; i++ )
+ if( ( !strcmp(argv[i], "set") && ++i < argc ) ||
+ ( !strcmp(argv[i], "unset") && ++i < argc ) ||
+ !strcmp(argv[i], "commit") )
+ {
+ write = 1;
+ break;
+ }
+
+
+ nvram = write ? nvram_open_staging() : nvram_open_rdonly();
+
+ if( nvram != NULL && argc > 1 )
+ {
+ for( i = 1; i < argc; i++ )
+ {
+ if( !strcmp(argv[i], "show") )
+ {
+ stat = do_show(nvram);
+ done++;
+ }
+ else if( !strcmp(argv[i], "info") )
+ {
+ stat = do_info(nvram);
+ done++;
+ }
+ else if( !strcmp(argv[i], "get") || !strcmp(argv[i], "unset") || !strcmp(argv[i], "set") )
+ {
+ if( (i+1) < argc )
+ {
+ switch(argv[i++][0])
+ {
+ case 'g':
+ stat = do_get(nvram, argv[i]);
+ break;
+
+ case 'u':
+ stat = do_unset(nvram, argv[i]);
+ break;
+
+ case 's':
+ stat = do_set(nvram, argv[i]);
+ break;
+ }
+ done++;
+ }
+ else
+ {
+ fprintf(stderr, "Command '%s' requires an argument!\n", argv[i]);
+ done = 0;
+ break;
+ }
+ }
+ else if( !strcmp(argv[i], "commit") )
+ {
+ commit = 1;
+ done++;
+ }
+ else
+ {
+ fprintf(stderr, "Unknown option '%s' !\n", argv[i]);
+ done = 0;
+ break;
+ }
+ }
+
+ if( write )
+ stat = nvram_commit(nvram);
+
+ nvram_close(nvram);
+
+ if( commit )
+ stat = staging_to_nvram();
+ }
+
+ if( !nvram )
+ {
+ fprintf(stderr,
+ "Could not open nvram! Possible reasons are:\n"
+ " - No device found (/proc not mounted or no nvram present)\n"
+ " - Insufficient permissions to open mtd device\n"
+ " - Insufficient memory to complete operation\n"
+ " - Memory mapping failed or not supported\n"
+ );
+
+ stat = 1;
+ }
+ else if( !done )
+ {
+ fprintf(stderr,
+ "Usage:\n"
+ " nvram show\n"
+ " nvram info\n"
+ " nvram get variable\n"
+ " nvram set variable=value [set ...]\n"
+ " nvram unset variable [unset ...]\n"
+ " nvram commit\n"
+ );
+
+ stat = 1;
+ }
+
+ return stat;
+}
diff --git a/package/utils/nvram/src/crc.c b/package/utils/nvram/src/crc.c
new file mode 100644
index 0000000..22a3665
--- /dev/null
+++ b/package/utils/nvram/src/crc.c
@@ -0,0 +1,69 @@
+#include "nvram.h"
+
+/*******************************************************************************
+ * crc8
+ *
+ * Computes a crc8 over the input data using the polynomial:
+ *
+ * x^8 + x^7 +x^6 + x^4 + x^2 + 1
+ *
+ * The caller provides the initial value (either CRC8_INIT_VALUE
+ * or the previous returned value) to allow for processing of
+ * discontiguous blocks of data. When generating the CRC the
+ * caller is responsible for complementing the final return value
+ * and inserting it into the byte stream. When checking, a final
+ * return value of CRC8_GOOD_VALUE indicates a valid CRC.
+ *
+ * Reference: Dallas Semiconductor Application Note 27
+ * Williams, Ross N., "A Painless Guide to CRC Error Detection Algorithms",
+ * ver 3, Aug 1993, ross@guest.adelaide.edu.au, Rocksoft Pty Ltd.,
+ * ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt
+ *
+ * ****************************************************************************
+ */
+
+static const uint8_t crc8_table[256] = {
+ 0x00, 0xF7, 0xB9, 0x4E, 0x25, 0xD2, 0x9C, 0x6B,
+ 0x4A, 0xBD, 0xF3, 0x04, 0x6F, 0x98, 0xD6, 0x21,
+ 0x94, 0x63, 0x2D, 0xDA, 0xB1, 0x46, 0x08, 0xFF,
+ 0xDE, 0x29, 0x67, 0x90, 0xFB, 0x0C, 0x42, 0xB5,
+ 0x7F, 0x88, 0xC6, 0x31, 0x5A, 0xAD, 0xE3, 0x14,
+ 0x35, 0xC2, 0x8C, 0x7B, 0x10, 0xE7, 0xA9, 0x5E,
+ 0xEB, 0x1C, 0x52, 0xA5, 0xCE, 0x39, 0x77, 0x80,
+ 0xA1, 0x56, 0x18, 0xEF, 0x84, 0x73, 0x3D, 0xCA,
+ 0xFE, 0x09, 0x47, 0xB0, 0xDB, 0x2C, 0x62, 0x95,
+ 0xB4, 0x43, 0x0D, 0xFA, 0x91, 0x66, 0x28, 0xDF,
+ 0x6A, 0x9D, 0xD3, 0x24, 0x4F, 0xB8, 0xF6, 0x01,
+ 0x20, 0xD7, 0x99, 0x6E, 0x05, 0xF2, 0xBC, 0x4B,
+ 0x81, 0x76, 0x38, 0xCF, 0xA4, 0x53, 0x1D, 0xEA,
+ 0xCB, 0x3C, 0x72, 0x85, 0xEE, 0x19, 0x57, 0xA0,
+ 0x15, 0xE2, 0xAC, 0x5B, 0x30, 0xC7, 0x89, 0x7E,
+ 0x5F, 0xA8, 0xE6, 0x11, 0x7A, 0x8D, 0xC3, 0x34,
+ 0xAB, 0x5C, 0x12, 0xE5, 0x8E, 0x79, 0x37, 0xC0,
+ 0xE1, 0x16, 0x58, 0xAF, 0xC4, 0x33, 0x7D, 0x8A,
+ 0x3F, 0xC8, 0x86, 0x71, 0x1A, 0xED, 0xA3, 0x54,
+ 0x75, 0x82, 0xCC, 0x3B, 0x50, 0xA7, 0xE9, 0x1E,
+ 0xD4, 0x23, 0x6D, 0x9A, 0xF1, 0x06, 0x48, 0xBF,
+ 0x9E, 0x69, 0x27, 0xD0, 0xBB, 0x4C, 0x02, 0xF5,
+ 0x40, 0xB7, 0xF9, 0x0E, 0x65, 0x92, 0xDC, 0x2B,
+ 0x0A, 0xFD, 0xB3, 0x44, 0x2F, 0xD8, 0x96, 0x61,
+ 0x55, 0xA2, 0xEC, 0x1B, 0x70, 0x87, 0xC9, 0x3E,
+ 0x1F, 0xE8, 0xA6, 0x51, 0x3A, 0xCD, 0x83, 0x74,
+ 0xC1, 0x36, 0x78, 0x8F, 0xE4, 0x13, 0x5D, 0xAA,
+ 0x8B, 0x7C, 0x32, 0xC5, 0xAE, 0x59, 0x17, 0xE0,
+ 0x2A, 0xDD, 0x93, 0x64, 0x0F, 0xF8, 0xB6, 0x41,
+ 0x60, 0x97, 0xD9, 0x2E, 0x45, 0xB2, 0xFC, 0x0B,
+ 0xBE, 0x49, 0x07, 0xF0, 0x9B, 0x6C, 0x22, 0xD5,
+ 0xF4, 0x03, 0x4D, 0xBA, 0xD1, 0x26, 0x68, 0x9F
+};
+
+uint8_t hndcrc8 (
+ uint8_t * pdata, /* pointer to array of data to process */
+ uint32_t nbytes, /* number of input data bytes to process */
+ uint8_t crc /* either CRC8_INIT_VALUE or previous return value */
+) {
+ while (nbytes-- > 0)
+ crc = crc8_table[(crc ^ *pdata++) & 0xff];
+
+ return crc;
+}
diff --git a/package/utils/nvram/src/nvram.c b/package/utils/nvram/src/nvram.c
new file mode 100644
index 0000000..0e42943
--- /dev/null
+++ b/package/utils/nvram/src/nvram.c
@@ -0,0 +1,540 @@
+/*
+ * NVRAM variable manipulation (common)
+ *
+ * Copyright 2004, Broadcom Corporation
+ * Copyright 2009-2010, OpenWrt.org
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ */
+
+#include "nvram.h"
+
+#define TRACE(msg) \
+ printf("%s(%i) in %s(): %s\n", \
+ __FILE__, __LINE__, __FUNCTION__, msg ? msg : "?")
+
+/* Size of "nvram" MTD partition */
+size_t nvram_part_size = 0;
+
+
+/*
+ * -- Helper functions --
+ */
+
+/* String hash */
+static uint32_t hash(const char *s)
+{
+ uint32_t hash = 0;
+
+ while (*s)
+ hash = 31 * hash + *s++;
+
+ return hash;
+}
+
+/* Free all tuples. */
+static void _nvram_free(nvram_handle_t *h)
+{
+ uint32_t i;
+ nvram_tuple_t *t, *next;
+
+ /* Free hash table */
+ for (i = 0; i < NVRAM_ARRAYSIZE(h->nvram_hash); i++) {
+ for (t = h->nvram_hash[i]; t; t = next) {
+ next = t->next;
+ free(t);
+ }
+ h->nvram_hash[i] = NULL;
+ }
+
+ /* Free dead table */
+ for (t = h->nvram_dead; t; t = next) {
+ next = t->next;
+ free(t);
+ }
+
+ h->nvram_dead = NULL;
+}
+
+/* (Re)allocate NVRAM tuples. */
+static nvram_tuple_t * _nvram_realloc( nvram_handle_t *h, nvram_tuple_t *t,
+ const char *name, const char *value )
+{
+ if ((strlen(value) + 1) > h->length - h->offset)
+ return NULL;
+
+ if (!t) {
+ if (!(t = malloc(sizeof(nvram_tuple_t) + strlen(name) + 1)))
+ return NULL;
+
+ /* Copy name */
+ t->name = (char *) &t[1];
+ strcpy(t->name, name);
+
+ t->value = NULL;
+ }
+
+ /* Copy value */
+ if (!t->value || strcmp(t->value, value))
+ {
+ if(!(t->value = (char *) realloc(t->value, strlen(value)+1)))
+ return NULL;
+
+ strcpy(t->value, value);
+ t->value[strlen(value)] = '\0';
+ }
+
+ return t;
+}
+
+/* (Re)initialize the hash table. */
+static int _nvram_rehash(nvram_handle_t *h)
+{
+ nvram_header_t *header = nvram_header(h);
+ char buf[] = "0xXXXXXXXX", *name, *value, *eq;
+
+ /* (Re)initialize hash table */
+ _nvram_free(h);
+
+ /* Parse and set "name=value\0 ... \0\0" */
+ name = (char *) &header[1];
+
+ for (; *name; name = value + strlen(value) + 1) {
+ if (!(eq = strchr(name, '=')))
+ break;
+ *eq = '\0';
+ value = eq + 1;
+ nvram_set(h, name, value);
+ *eq = '=';
+ }
+
+ /* Set special SDRAM parameters */
+ if (!nvram_get(h, "sdram_init")) {
+ sprintf(buf, "0x%04X", (uint16_t)(header->crc_ver_init >> 16));
+ nvram_set(h, "sdram_init", buf);
+ }
+ if (!nvram_get(h, "sdram_config")) {
+ sprintf(buf, "0x%04X", (uint16_t)(header->config_refresh & 0xffff));
+ nvram_set(h, "sdram_config", buf);
+ }
+ if (!nvram_get(h, "sdram_refresh")) {
+ sprintf(buf, "0x%04X",
+ (uint16_t)((header->config_refresh >> 16) & 0xffff));
+ nvram_set(h, "sdram_refresh", buf);
+ }
+ if (!nvram_get(h, "sdram_ncdl")) {
+ sprintf(buf, "0x%08X", header->config_ncdl);
+ nvram_set(h, "sdram_ncdl", buf);
+ }
+
+ return 0;
+}
+
+
+/*
+ * -- Public functions --
+ */
+
+/* Get nvram header. */
+nvram_header_t * nvram_header(nvram_handle_t *h)
+{
+ return (nvram_header_t *) &h->mmap[h->offset];
+}
+
+/* Get the value of an NVRAM variable. */
+char * nvram_get(nvram_handle_t *h, const char *name)
+{
+ uint32_t i;
+ nvram_tuple_t *t;
+ char *value;
+
+ if (!name)
+ return NULL;
+
+ /* Hash the name */
+ i = hash(name) % NVRAM_ARRAYSIZE(h->nvram_hash);
+
+ /* Find the associated tuple in the hash table */
+ for (t = h->nvram_hash[i]; t && strcmp(t->name, name); t = t->next);
+
+ value = t ? t->value : NULL;
+
+ return value;
+}
+
+/* Set the value of an NVRAM variable. */
+int nvram_set(nvram_handle_t *h, const char *name, const char *value)
+{
+ uint32_t i;
+ nvram_tuple_t *t, *u, **prev;
+
+ /* Hash the name */
+ i = hash(name) % NVRAM_ARRAYSIZE(h->nvram_hash);
+
+ /* Find the associated tuple in the hash table */
+ for (prev = &h->nvram_hash[i], t = *prev;
+ t && strcmp(t->name, name); prev = &t->next, t = *prev);
+
+ /* (Re)allocate tuple */
+ if (!(u = _nvram_realloc(h, t, name, value)))
+ return -12; /* -ENOMEM */
+
+ /* Value reallocated */
+ if (t && t == u)
+ return 0;
+
+ /* Move old tuple to the dead table */
+ if (t) {
+ *prev = t->next;
+ t->next = h->nvram_dead;
+ h->nvram_dead = t;
+ }
+
+ /* Add new tuple to the hash table */
+ u->next = h->nvram_hash[i];
+ h->nvram_hash[i] = u;
+
+ return 0;
+}
+
+/* Unset the value of an NVRAM variable. */
+int nvram_unset(nvram_handle_t *h, const char *name)
+{
+ uint32_t i;
+ nvram_tuple_t *t, **prev;
+
+ if (!name)
+ return 0;
+
+ /* Hash the name */
+ i = hash(name) % NVRAM_ARRAYSIZE(h->nvram_hash);
+
+ /* Find the associated tuple in the hash table */
+ for (prev = &h->nvram_hash[i], t = *prev;
+ t && strcmp(t->name, name); prev = &t->next, t = *prev);
+
+ /* Move it to the dead table */
+ if (t) {
+ *prev = t->next;
+ t->next = h->nvram_dead;
+ h->nvram_dead = t;
+ }
+
+ return 0;
+}
+
+/* Get all NVRAM variables. */
+nvram_tuple_t * nvram_getall(nvram_handle_t *h)
+{
+ int i;
+ nvram_tuple_t *t, *l, *x;
+
+ l = NULL;
+
+ for (i = 0; i < NVRAM_ARRAYSIZE(h->nvram_hash); i++) {
+ for (t = h->nvram_hash[i]; t; t = t->next) {
+ if( (x = (nvram_tuple_t *) malloc(sizeof(nvram_tuple_t))) != NULL )
+ {
+ x->name = t->name;
+ x->value = t->value;
+ x->next = l;
+ l = x;
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+
+ return l;
+}
+
+/* Regenerate NVRAM. */
+int nvram_commit(nvram_handle_t *h)
+{
+ nvram_header_t *header = nvram_header(h);
+ char *init, *config, *refresh, *ncdl;
+ char *ptr, *end;
+ int i;
+ nvram_tuple_t *t;
+ nvram_header_t tmp;
+ uint8_t crc;
+
+ /* Regenerate header */
+ header->magic = NVRAM_MAGIC;
+ header->crc_ver_init = (NVRAM_VERSION << 8);
+ if (!(init = nvram_get(h, "sdram_init")) ||
+ !(config = nvram_get(h, "sdram_config")) ||
+ !(refresh = nvram_get(h, "sdram_refresh")) ||
+ !(ncdl = nvram_get(h, "sdram_ncdl"))) {
+ header->crc_ver_init |= SDRAM_INIT << 16;
+ header->config_refresh = SDRAM_CONFIG;
+ header->config_refresh |= SDRAM_REFRESH << 16;
+ header->config_ncdl = 0;
+ } else {
+ header->crc_ver_init |= (strtoul(init, NULL, 0) & 0xffff) << 16;
+ header->config_refresh = strtoul(config, NULL, 0) & 0xffff;
+ header->config_refresh |= (strtoul(refresh, NULL, 0) & 0xffff) << 16;
+ header->config_ncdl = strtoul(ncdl, NULL, 0);
+ }
+
+ /* Clear data area */
+ ptr = (char *) header + sizeof(nvram_header_t);
+ memset(ptr, 0xFF, nvram_part_size - h->offset - sizeof(nvram_header_t));
+ memset(&tmp, 0, sizeof(nvram_header_t));
+
+ /* Leave space for a double NUL at the end */
+ end = (char *) header + nvram_part_size - h->offset - 2;
+
+ /* Write out all tuples */
+ for (i = 0; i < NVRAM_ARRAYSIZE(h->nvram_hash); i++) {
+ for (t = h->nvram_hash[i]; t; t = t->next) {
+ if ((ptr + strlen(t->name) + 1 + strlen(t->value) + 1) > end)
+ break;
+ ptr += sprintf(ptr, "%s=%s", t->name, t->value) + 1;
+ }
+ }
+
+ /* End with a double NULL and pad to 4 bytes */
+ *ptr = '\0';
+ ptr++;
+
+ if( (int)ptr % 4 )
+ memset(ptr, 0, 4 - ((int)ptr % 4));
+
+ ptr++;
+
+ /* Set new length */
+ header->len = NVRAM_ROUNDUP(ptr - (char *) header, 4);
+
+ /* Little-endian CRC8 over the last 11 bytes of the header */
+ tmp.crc_ver_init = header->crc_ver_init;
+ tmp.config_refresh = header->config_refresh;
+ tmp.config_ncdl = header->config_ncdl;
+ crc = hndcrc8((unsigned char *) &tmp + NVRAM_CRC_START_POSITION,
+ sizeof(nvram_header_t) - NVRAM_CRC_START_POSITION, 0xff);
+
+ /* Continue CRC8 over data bytes */
+ crc = hndcrc8((unsigned char *) &header[0] + sizeof(nvram_header_t),
+ header->len - sizeof(nvram_header_t), crc);
+
+ /* Set new CRC8 */
+ header->crc_ver_init |= crc;
+
+ /* Write out */
+ msync(h->mmap, h->length, MS_SYNC);
+ fsync(h->fd);
+
+ /* Reinitialize hash table */
+ return _nvram_rehash(h);
+}
+
+/* Open NVRAM and obtain a handle. */
+nvram_handle_t * nvram_open(const char *file, int rdonly)
+{
+ int i;
+ int fd;
+ char *mtd = NULL;
+ nvram_handle_t *h;
+ nvram_header_t *header;
+ int offset = -1;
+
+ /* If erase size or file are undefined then try to define them */
+ if( (nvram_part_size == 0) || (file == NULL) )
+ {
+ /* Finding the mtd will set the appropriate erase size */
+ if( (mtd = nvram_find_mtd()) == NULL || nvram_part_size == 0 )
+ {
+ free(mtd);
+ return NULL;
+ }
+ }
+
+ if( (fd = open(file ? file : mtd, O_RDWR)) > -1 )
+ {
+ char *mmap_area = (char *) mmap(
+ NULL, nvram_part_size, PROT_READ | PROT_WRITE,
+ (( rdonly == NVRAM_RO ) ? MAP_PRIVATE : MAP_SHARED) | MAP_LOCKED, fd, 0);
+
+ if( mmap_area != MAP_FAILED )
+ {
+ /*
+ * Start looking for NVRAM_MAGIC at beginning of MTD
+ * partition. Stop if there is less than NVRAM_MIN_SPACE
+ * to check, that was the lowest used size.
+ */
+ for( i = 0; i <= ((nvram_part_size - NVRAM_MIN_SPACE) / sizeof(uint32_t)); i++ )
+ {
+ if( ((uint32_t *)mmap_area)[i] == NVRAM_MAGIC )
+ {
+ offset = i * sizeof(uint32_t);
+ break;
+ }
+ }
+
+ if( offset < 0 )
+ {
+ free(mtd);
+ return NULL;
+ }
+ else if( (h = malloc(sizeof(nvram_handle_t))) != NULL )
+ {
+ memset(h, 0, sizeof(nvram_handle_t));
+
+ h->fd = fd;
+ h->mmap = mmap_area;
+ h->length = nvram_part_size;
+ h->offset = offset;
+
+ header = nvram_header(h);
+
+ if (header->magic == NVRAM_MAGIC &&
+ (rdonly || header->len < h->length - h->offset)) {
+ _nvram_rehash(h);
+ free(mtd);
+ return h;
+ }
+ else
+ {
+ munmap(h->mmap, h->length);
+ free(h);
+ }
+ }
+ }
+ }
+
+ free(mtd);
+ return NULL;
+}
+
+/* Close NVRAM and free memory. */
+int nvram_close(nvram_handle_t *h)
+{
+ _nvram_free(h);
+ munmap(h->mmap, h->length);
+ close(h->fd);
+ free(h);
+
+ return 0;
+}
+
+/* Determine NVRAM device node. */
+char * nvram_find_mtd(void)
+{
+ FILE *fp;
+ int i, part_size;
+ char dev[PATH_MAX];
+ char *path = NULL;
+ struct stat s;
+
+ if ((fp = fopen("/proc/mtd", "r")))
+ {
+ while( fgets(dev, sizeof(dev), fp) )
+ {
+ if( strstr(dev, "nvram") && sscanf(dev, "mtd%d: %08x", &i, &part_size) )
+ {
+ nvram_part_size = part_size;
+
+ sprintf(dev, "/dev/mtdblock%d", i);
+ if( stat(dev, &s) > -1 && (s.st_mode & S_IFBLK) )
+ {
+ if( (path = (char *) malloc(strlen(dev)+1)) != NULL )
+ {
+ strncpy(path, dev, strlen(dev)+1);
+ break;
+ }
+ }
+ }
+ }
+ fclose(fp);
+ }
+
+ return path;
+}
+
+/* Check NVRAM staging file. */
+char * nvram_find_staging(void)
+{
+ struct stat s;
+
+ if( (stat(NVRAM_STAGING, &s) > -1) && (s.st_mode & S_IFREG) )
+ {
+ return NVRAM_STAGING;
+ }
+
+ return NULL;
+}
+
+/* Copy NVRAM contents to staging file. */
+int nvram_to_staging(void)
+{
+ int fdmtd, fdstg, stat;
+ char *mtd = nvram_find_mtd();
+ char buf[nvram_part_size];
+
+ stat = -1;
+
+ if( (mtd != NULL) && (nvram_part_size > 0) )
+ {
+ if( (fdmtd = open(mtd, O_RDONLY)) > -1 )
+ {
+ if( read(fdmtd, buf, sizeof(buf)) == sizeof(buf) )
+ {
+ if((fdstg = open(NVRAM_STAGING, O_WRONLY | O_CREAT, 0600)) > -1)
+ {
+ write(fdstg, buf, sizeof(buf));
+ fsync(fdstg);
+ close(fdstg);
+
+ stat = 0;
+ }
+ }
+
+ close(fdmtd);
+ }
+ }
+
+ free(mtd);
+ return stat;
+}
+
+/* Copy staging file to NVRAM device. */
+int staging_to_nvram(void)
+{
+ int fdmtd, fdstg, stat;
+ char *mtd = nvram_find_mtd();
+ char buf[nvram_part_size];
+
+ stat = -1;
+
+ if( (mtd != NULL) && (nvram_part_size > 0) )
+ {
+ if( (fdstg = open(NVRAM_STAGING, O_RDONLY)) > -1 )
+ {
+ if( read(fdstg, buf, sizeof(buf)) == sizeof(buf) )
+ {
+ if( (fdmtd = open(mtd, O_WRONLY | O_SYNC)) > -1 )
+ {
+ write(fdmtd, buf, sizeof(buf));
+ fsync(fdmtd);
+ close(fdmtd);
+ stat = 0;
+ }
+ }
+
+ close(fdstg);
+
+ if( !stat )
+ stat = unlink(NVRAM_STAGING) ? 1 : 0;
+ }
+ }
+
+ free(mtd);
+ return stat;
+}
diff --git a/package/utils/nvram/src/nvram.h b/package/utils/nvram/src/nvram.h
new file mode 100644
index 0000000..724f33b
--- /dev/null
+++ b/package/utils/nvram/src/nvram.h
@@ -0,0 +1,123 @@
+/*
+ * NVRAM variable manipulation
+ *
+ * Copyright 2007, Broadcom Corporation
+ * Copyright 2009, OpenWrt.org
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ */
+
+#ifndef _nvram_h_
+#define _nvram_h_
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+#include <linux/limits.h>
+
+#include "sdinitvals.h"
+
+
+struct nvram_header {
+ uint32_t magic;
+ uint32_t len;
+ uint32_t crc_ver_init; /* 0:7 crc, 8:15 ver, 16:31 sdram_init */
+ uint32_t config_refresh; /* 0:15 sdram_config, 16:31 sdram_refresh */
+ uint32_t config_ncdl; /* ncdl values for memc */
+} __attribute__((__packed__));
+
+struct nvram_tuple {
+ char *name;
+ char *value;
+ struct nvram_tuple *next;
+};
+
+struct nvram_handle {
+ int fd;
+ char *mmap;
+ unsigned int length;
+ unsigned int offset;
+ struct nvram_tuple *nvram_hash[257];
+ struct nvram_tuple *nvram_dead;
+};
+
+typedef struct nvram_handle nvram_handle_t;
+typedef struct nvram_header nvram_header_t;
+typedef struct nvram_tuple nvram_tuple_t;
+
+
+/* Get nvram header. */
+nvram_header_t * nvram_header(nvram_handle_t *h);
+
+/* Set the value of an NVRAM variable */
+int nvram_set(nvram_handle_t *h, const char *name, const char *value);
+
+/* Get the value of an NVRAM variable. */
+char * nvram_get(nvram_handle_t *h, const char *name);
+
+/* Unset the value of an NVRAM variable. */
+int nvram_unset(nvram_handle_t *h, const char *name);
+
+/* Get all NVRAM variables. */
+nvram_tuple_t * nvram_getall(nvram_handle_t *h);
+
+/* Regenerate NVRAM. */
+int nvram_commit(nvram_handle_t *h);
+
+/* Open NVRAM and obtain a handle. */
+nvram_handle_t * nvram_open(const char *file, int rdonly);
+
+/* Close NVRAM and free memory. */
+int nvram_close(nvram_handle_t *h);
+
+/* Get the value of an NVRAM variable in a safe way, use "" instead of NULL. */
+#define nvram_safe_get(h, name) (nvram_get(h, name) ? : "")
+
+/* Computes a crc8 over the input data. */
+uint8_t hndcrc8 (uint8_t * pdata, uint32_t nbytes, uint8_t crc);
+
+/* Returns the crc value of the nvram. */
+uint8_t nvram_calc_crc(nvram_header_t * nvh);
+
+/* Determine NVRAM device node. */
+char * nvram_find_mtd(void);
+
+/* Copy NVRAM contents to staging file. */
+int nvram_to_staging(void);
+
+/* Copy staging file to NVRAM device. */
+int staging_to_nvram(void);
+
+/* Check NVRAM staging file. */
+char * nvram_find_staging(void);
+
+
+/* Staging file for NVRAM */
+#define NVRAM_STAGING "/tmp/.nvram"
+#define NVRAM_RO 1
+#define NVRAM_RW 0
+
+/* Helper macros */
+#define NVRAM_ARRAYSIZE(a) sizeof(a)/sizeof(a[0])
+#define NVRAM_ROUNDUP(x, y) ((((x)+((y)-1))/(y))*(y))
+
+/* NVRAM constants */
+#define NVRAM_MIN_SPACE 0x8000
+#define NVRAM_MAGIC 0x48534C46 /* 'FLSH' */
+#define NVRAM_VERSION 1
+
+#define NVRAM_CRC_START_POSITION 9 /* magic, len, crc8 to be skipped */
+
+
+#endif /* _nvram_h_ */
diff --git a/package/utils/nvram/src/sdinitvals.h b/package/utils/nvram/src/sdinitvals.h
new file mode 100644
index 0000000..5a289ad
--- /dev/null
+++ b/package/utils/nvram/src/sdinitvals.h
@@ -0,0 +1,30 @@
+/*
+ * SDRAM init values
+ *
+ * Copyright 2007, Broadcom Corporation
+ * Copyright 2009, OpenWrt.org
+ * All Rights Reserved.
+ *
+ * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
+ * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
+ * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
+ *
+ */
+
+#ifndef _sdinitvals_h_
+#define _sdinitvals_h_
+
+/* SDRAM refresh control (refresh) register bits */
+#define SDRAM_REF(p) (((p)&0xff) | SDRAM_REF_EN) /* Refresh period */
+#define SDRAM_REF_EN 0x8000 /* Writing 1 enables periodic refresh */
+
+/* SDRAM Core default Init values (OCP ID 0x803) */
+#define MEM4MX16X2 0x419 /* 16 MB */
+
+#define SDRAM_INIT MEM4MX16X2
+#define SDRAM_BURSTFULL 0x0000 /* Use full page bursts */
+#define SDRAM_CONFIG SDRAM_BURSTFULL
+#define SDRAM_REFRESH SDRAM_REF(0x40)
+
+#endif /* _sdinitvals_h_ */
diff --git a/package/utils/otrx/Makefile b/package/utils/otrx/Makefile
new file mode 100644
index 0000000..360fb17
--- /dev/null
+++ b/package/utils/otrx/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=otrx
+PKG_RELEASE:=1
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/otrx
+ SECTION:=utils
+ CATEGORY:=Base system
+ TITLE:=Utility for opening (analyzing) TRX firmware images
+ MAINTAINER:=Rafał Miłecki <zajec5@gmail.com>
+ DEPENDS:=@TARGET_brcm47xx||@TARGET_bcm53xx
+endef
+
+define Package/otrx/description
+ This package contains an utility that allows validating TRX images.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ CC="$(TARGET_CC)" \
+ CFLAGS="$(TARGET_CFLAGS) -Wall"
+endef
+
+define Package/otrx/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/otrx $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,otrx))
diff --git a/package/utils/otrx/src/Makefile b/package/utils/otrx/src/Makefile
new file mode 100644
index 0000000..df50ea4
--- /dev/null
+++ b/package/utils/otrx/src/Makefile
@@ -0,0 +1,7 @@
+all: otrx
+
+otrx:
+ $(CC) $(CFLAGS) -o $@ otrx.c -Wall
+
+clean:
+ rm -f otrx
diff --git a/package/utils/otrx/src/otrx.c b/package/utils/otrx/src/otrx.c
new file mode 100644
index 0000000..101a310
--- /dev/null
+++ b/package/utils/otrx/src/otrx.c
@@ -0,0 +1,577 @@
+/*
+ * otrx
+ *
+ * Copyright (C) 2015 Rafał Miłecki <zajec5@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ */
+
+#include <byteswap.h>
+#include <endian.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#if !defined(__BYTE_ORDER)
+#error "Unknown byte order"
+#endif
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define cpu_to_le32(x) bswap_32(x)
+#define le32_to_cpu(x) bswap_32(x)
+#elif __BYTE_ORDER == __LITTLE_ENDIAN
+#define cpu_to_le32(x) (x)
+#define le32_to_cpu(x) (x)
+#else
+#error "Unsupported endianness"
+#endif
+
+#define TRX_MAGIC 0x30524448
+#define TRX_FLAGS_OFFSET 12
+#define TRX_MAX_PARTS 3
+
+struct trx_header {
+ uint32_t magic;
+ uint32_t length;
+ uint32_t crc32;
+ uint16_t flags;
+ uint16_t version;
+ uint32_t offset[3];
+};
+
+char *trx_path;
+size_t trx_offset = 0;
+char *partition[TRX_MAX_PARTS] = {};
+
+static inline size_t otrx_min(size_t x, size_t y) {
+ return x < y ? x : y;
+}
+
+/**************************************************
+ * CRC32
+ **************************************************/
+
+static const uint32_t crc32_tbl[] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
+};
+
+uint32_t otrx_crc32(uint8_t *buf, size_t len) {
+ uint32_t crc = 0xffffffff;
+
+ while (len) {
+ crc = crc32_tbl[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+ buf++;
+ len--;
+ }
+
+ return crc;
+}
+
+/**************************************************
+ * Check
+ **************************************************/
+
+static void otrx_check_parse_options(int argc, char **argv) {
+ int c;
+
+ while ((c = getopt(argc, argv, "o:")) != -1) {
+ switch (c) {
+ case 'o':
+ trx_offset = atoi(optarg);
+ break;
+ }
+ }
+}
+
+static int otrx_check(int argc, char **argv) {
+ FILE *trx;
+ struct trx_header hdr;
+ size_t bytes, length;
+ uint8_t buf[1024];
+ uint32_t crc32;
+ int i;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "No TRX file passed\n");
+ err = -EINVAL;
+ goto out;
+ }
+ trx_path = argv[2];
+
+ optind = 3;
+ otrx_check_parse_options(argc, argv);
+
+ trx = fopen(trx_path, "r");
+ if (!trx) {
+ fprintf(stderr, "Couldn't open %s\n", trx_path);
+ err = -EACCES;
+ goto out;
+ }
+
+ fseek(trx, trx_offset, SEEK_SET);
+ bytes = fread(&hdr, 1, sizeof(hdr), trx);
+ if (bytes != sizeof(hdr)) {
+ fprintf(stderr, "Couldn't read %s header\n", trx_path);
+ err = -EIO;
+ goto err_close;
+ }
+
+ if (le32_to_cpu(hdr.magic) != TRX_MAGIC) {
+ fprintf(stderr, "Invalid TRX magic: 0x%08x\n", le32_to_cpu(hdr.magic));
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ length = le32_to_cpu(hdr.length);
+ if (length < sizeof(hdr)) {
+ fprintf(stderr, "Length read from TRX too low (%zu B)\n", length);
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ crc32 = 0xffffffff;
+ fseek(trx, trx_offset + TRX_FLAGS_OFFSET, SEEK_SET);
+ length -= TRX_FLAGS_OFFSET;
+ while ((bytes = fread(buf, 1, otrx_min(sizeof(buf), length), trx)) > 0) {
+ for (i = 0; i < bytes; i++)
+ crc32 = crc32_tbl[(crc32 ^ buf[i]) & 0xff] ^ (crc32 >> 8);
+ length -= bytes;
+ }
+
+ if (length) {
+ fprintf(stderr, "Couldn't read last %zd B of data from %s\n", length, trx_path);
+ err = -EIO;
+ goto err_close;
+ }
+
+ if (crc32 != le32_to_cpu(hdr.crc32)) {
+ fprintf(stderr, "Invalid data crc32: 0x%08x instead of 0x%08x\n", crc32, le32_to_cpu(hdr.crc32));
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ printf("Found a valid TRX version %d\n", le32_to_cpu(hdr.version));
+
+err_close:
+ fclose(trx);
+out:
+ return err;
+}
+
+/**************************************************
+ * Create
+ **************************************************/
+
+static void otrx_create_parse_options(int argc, char **argv) {
+}
+
+static ssize_t otrx_create_append_file(FILE *trx, const char *in_path) {
+ FILE *in;
+ size_t bytes;
+ ssize_t length = 0;
+ uint8_t buf[128];
+
+ in = fopen(in_path, "r");
+ if (!in) {
+ fprintf(stderr, "Couldn't open %s\n", in_path);
+ return -EACCES;
+ }
+
+ while ((bytes = fread(buf, 1, sizeof(buf), in)) > 0) {
+ if (fwrite(buf, 1, bytes, trx) != bytes) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", bytes, trx_path);
+ length = -EIO;
+ break;
+ }
+ length += bytes;
+ }
+
+ fclose(in);
+
+ return length;
+}
+
+static ssize_t otrx_create_append_zeros(FILE *trx, size_t length) {
+ uint8_t *buf;
+
+ buf = malloc(length);
+ if (!buf)
+ return -ENOMEM;
+ memset(buf, 0, length);
+
+ if (fwrite(buf, 1, length, trx) != length) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", length, trx_path);
+ return -EIO;
+ }
+
+ return length;
+}
+
+static ssize_t otrx_create_align(FILE *trx, size_t curr_offset, size_t alignment) {
+ if (curr_offset & (alignment - 1)) {
+ size_t length = alignment - (curr_offset % alignment);
+ return otrx_create_append_zeros(trx, length);
+ }
+
+ return 0;
+}
+
+static int otrx_create_write_hdr(FILE *trx, struct trx_header *hdr) {
+ size_t bytes, length;
+ uint8_t *buf;
+ uint32_t crc32;
+
+ hdr->magic = cpu_to_le32(TRX_MAGIC);
+ hdr->version = 1;
+
+ fseek(trx, 0, SEEK_SET);
+ bytes = fwrite(hdr, 1, sizeof(struct trx_header), trx);
+ if (bytes != sizeof(struct trx_header)) {
+ fprintf(stderr, "Couldn't write TRX header to %s\n", trx_path);
+ return -EIO;
+ }
+
+ length = le32_to_cpu(hdr->length);
+
+ buf = malloc(length);
+ if (!buf) {
+ fprintf(stderr, "Couldn't alloc %zu B buffer\n", length);
+ return -ENOMEM;
+ }
+
+ fseek(trx, 0, SEEK_SET);
+ bytes = fread(buf, 1, length, trx);
+ if (bytes != length) {
+ fprintf(stderr, "Couldn't read %zu B of data from %s\n", length, trx_path);
+ return -ENOMEM;
+ }
+
+ crc32 = otrx_crc32(buf + TRX_FLAGS_OFFSET, length - TRX_FLAGS_OFFSET);
+ hdr->crc32 = cpu_to_le32(crc32);
+
+ fseek(trx, 0, SEEK_SET);
+ bytes = fwrite(hdr, 1, sizeof(struct trx_header), trx);
+ if (bytes != sizeof(struct trx_header)) {
+ fprintf(stderr, "Couldn't write TRX header to %s\n", trx_path);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int otrx_create(int argc, char **argv) {
+ FILE *trx;
+ struct trx_header hdr = {};
+ ssize_t sbytes;
+ size_t curr_idx = 0;
+ size_t curr_offset = sizeof(hdr);
+ int c;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "No TRX file passed\n");
+ err = -EINVAL;
+ goto out;
+ }
+ trx_path = argv[2];
+
+ optind = 3;
+ otrx_create_parse_options(argc, argv);
+
+ trx = fopen(trx_path, "w+");
+ if (!trx) {
+ fprintf(stderr, "Couldn't open %s\n", trx_path);
+ err = -EACCES;
+ goto out;
+ }
+ fseek(trx, curr_offset, SEEK_SET);
+
+ optind = 3;
+ while ((c = getopt(argc, argv, "f:b:")) != -1) {
+ switch (c) {
+ case 'f':
+ if (curr_idx >= TRX_MAX_PARTS) {
+ err = -ENOSPC;
+ fprintf(stderr, "Reached TRX partitions limit, no place for %s\n", optarg);
+ goto err_close;
+ }
+
+ sbytes = otrx_create_append_file(trx, optarg);
+ if (sbytes < 0) {
+ fprintf(stderr, "Failed to append file %s\n", optarg);
+ } else {
+ hdr.offset[curr_idx++] = curr_offset;
+ curr_offset += sbytes;
+ }
+
+ sbytes = otrx_create_align(trx, curr_offset, 4);
+ if (sbytes < 0)
+ fprintf(stderr, "Failed to append zeros\n");
+ else
+ curr_offset += sbytes;
+
+ break;
+ case 'b':
+ sbytes = strtol(optarg, NULL, 0) - curr_offset;
+ if (sbytes < 0) {
+ fprintf(stderr, "Current TRX length is 0x%zx, can't pad it with zeros to 0x%lx\n", curr_offset, strtol(optarg, NULL, 0));
+ } else {
+ sbytes = otrx_create_append_zeros(trx, sbytes);
+ if (sbytes < 0)
+ fprintf(stderr, "Failed to append zeros\n");
+ else
+ curr_offset += sbytes;
+ }
+ break;
+ }
+ if (err)
+ break;
+ }
+
+ hdr.length = curr_offset;
+ otrx_create_write_hdr(trx, &hdr);
+err_close:
+ fclose(trx);
+out:
+ return err;
+}
+
+/**************************************************
+ * Extract
+ **************************************************/
+
+static void otrx_extract_parse_options(int argc, char **argv) {
+ int c;
+
+ while ((c = getopt(argc, argv, "c:e:o:1:2:3:")) != -1) {
+ switch (c) {
+ case 'o':
+ trx_offset = atoi(optarg);
+ break;
+ case '1':
+ partition[0] = optarg;
+ break;
+ case '2':
+ partition[1] = optarg;
+ break;
+ case '3':
+ partition[2] = optarg;
+ break;
+ }
+ }
+}
+
+static int otrx_extract_copy(FILE *trx, size_t offset, size_t length, char *out_path) {
+ FILE *out;
+ size_t bytes;
+ uint8_t *buf;
+ int err = 0;
+
+ out = fopen(out_path, "w");
+ if (!out) {
+ fprintf(stderr, "Couldn't open %s\n", out_path);
+ err = -EACCES;
+ goto out;
+ }
+
+ buf = malloc(length);
+ if (!buf) {
+ fprintf(stderr, "Couldn't alloc %zu B buffer\n", length);
+ err = -ENOMEM;
+ goto err_close;
+ }
+
+ fseek(trx, offset, SEEK_SET);
+ bytes = fread(buf, 1, length, trx);
+ if (bytes != length) {
+ fprintf(stderr, "Couldn't read %zu B of data from %s\n", length, trx_path);
+ err = -ENOMEM;
+ goto err_free_buf;
+ };
+
+ bytes = fwrite(buf, 1, length, out);
+ if (bytes != length) {
+ fprintf(stderr, "Couldn't write %zu B to %s\n", length, out_path);
+ err = -ENOMEM;
+ goto err_free_buf;
+ }
+
+ printf("Extracted 0x%zx bytes into %s\n", length, out_path);
+
+err_free_buf:
+ free(buf);
+err_close:
+ fclose(out);
+out:
+ return err;
+}
+
+static int otrx_extract(int argc, char **argv) {
+ FILE *trx;
+ struct trx_header hdr;
+ size_t bytes;
+ int i;
+ int err = 0;
+
+ if (argc < 3) {
+ fprintf(stderr, "No TRX file passed\n");
+ err = -EINVAL;
+ goto out;
+ }
+ trx_path = argv[2];
+
+ optind = 3;
+ otrx_extract_parse_options(argc, argv);
+
+ trx = fopen(trx_path, "r");
+ if (!trx) {
+ fprintf(stderr, "Couldn't open %s\n", trx_path);
+ err = -EACCES;
+ goto out;
+ }
+
+ fseek(trx, trx_offset, SEEK_SET);
+ bytes = fread(&hdr, 1, sizeof(hdr), trx);
+ if (bytes != sizeof(hdr)) {
+ fprintf(stderr, "Couldn't read %s header\n", trx_path);
+ err = -EIO;
+ goto err_close;
+ }
+
+ if (le32_to_cpu(hdr.magic) != TRX_MAGIC) {
+ fprintf(stderr, "Invalid TRX magic: 0x%08x\n", le32_to_cpu(hdr.magic));
+ err = -EINVAL;
+ goto err_close;
+ }
+
+ for (i = 0; i < TRX_MAX_PARTS; i++) {
+ size_t length;
+
+ if (!partition[i])
+ continue;
+ if (!hdr.offset[i]) {
+ printf("TRX doesn't contain partition %d, can't extract %s\n", i + 1, partition[i]);
+ continue;
+ }
+
+ if (i + 1 >= TRX_MAX_PARTS || !hdr.offset[i + 1])
+ length = le32_to_cpu(hdr.length) - le32_to_cpu(hdr.offset[i]);
+ else
+ length = le32_to_cpu(hdr.offset[i + 1]) - le32_to_cpu(hdr.offset[i]);
+
+ otrx_extract_copy(trx, trx_offset + le32_to_cpu(hdr.offset[i]), length, partition[i]);
+ }
+
+err_close:
+ fclose(trx);
+out:
+ return err;
+}
+
+/**************************************************
+ * Start
+ **************************************************/
+
+static void usage() {
+ printf("Usage:\n");
+ printf("\n");
+ printf("Checking TRX file:\n");
+ printf("\totrx check <file> [options]\tcheck if file is a valid TRX\n");
+ printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n");
+ printf("\n");
+ printf("Creating new TRX file:\n");
+ printf("\totrx create <file> [options] [partitions]\n");
+ printf("\t-f file\t\t\t\t[partition] start new partition with content copied from file\n");
+ printf("\t-b offset\t\t\t[partition] append zeros to partition till reaching absolute offset\n");
+ printf("\n");
+ printf("Extracting from TRX file:\n");
+ printf("\totrx extract <file> [options]\textract partitions from TRX file\n");
+ printf("\t-o offset\t\t\toffset of TRX data in file (default: 0)\n");
+ printf("\t-1 file\t\t\t\tfile to extract 1st partition to (optional)\n");
+ printf("\t-2 file\t\t\t\tfile to extract 2nd partition to (optional)\n");
+ printf("\t-3 file\t\t\t\tfile to extract 3rd partition to (optional)\n");
+}
+
+int main(int argc, char **argv) {
+ if (argc > 1) {
+ if (!strcmp(argv[1], "check"))
+ return otrx_check(argc, argv);
+ else if (!strcmp(argv[1], "create"))
+ return otrx_create(argc, argv);
+ else if (!strcmp(argv[1], "extract"))
+ return otrx_extract(argc, argv);
+ }
+
+ usage();
+ return 0;
+}
diff --git a/package/utils/px5g-standalone/Makefile b/package/utils/px5g-standalone/Makefile
new file mode 100644
index 0000000..bd02676
--- /dev/null
+++ b/package/utils/px5g-standalone/Makefile
@@ -0,0 +1,41 @@
+#
+# Copyright (C) 2010-2014 Jo-Philipp Wich <xm@subsignal.org>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=px5g-standalone
+PKG_RELEASE:=2
+
+PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
+PKG_CHECK_FORMAT_SECURITY:=0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/px5g-standalone
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Standalone X.509 certificate generator (standalone version)
+ MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
+endef
+
+define Package/px5g-standalone/description
+ Px5g is a tiny standalone X.509 certificate generator.
+ It suitable to create key files and certificates in DER
+ and PEM format for use with stunnel, uhttpd and others.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+ $(CP) ./src/* $(PKG_BUILD_DIR)/
+endef
+
+define Package/px5g-standalone/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/px5g $(1)/usr/sbin/px5g
+endef
+
+$(eval $(call BuildPackage,px5g-standalone))
diff --git a/package/utils/px5g-standalone/src/Makefile b/package/utils/px5g-standalone/src/Makefile
new file mode 100644
index 0000000..2bd9573
--- /dev/null
+++ b/package/utils/px5g-standalone/src/Makefile
@@ -0,0 +1,14 @@
+CFLAGS?=-O2
+CFLAGS+=
+SFLAGS:=--std=gnu99
+WFLAGS:=-Wall -Werror -pedantic
+LDFLAGS?=
+BINARY:=px5g
+
+all: $(BINARY)
+
+$(BINARY): *.c library/*.c
+ $(CC) -I. $(CFLAGS) $(SFLAGS) $(WFLAGS) $(LDFLAGS) -o $@ $+
+
+clean:
+ rm -f $(BINARY)
diff --git a/package/utils/px5g-standalone/src/library/base64.c b/package/utils/px5g-standalone/src/library/base64.c
new file mode 100644
index 0000000..b7cc5b8
--- /dev/null
+++ b/package/utils/px5g-standalone/src/library/base64.c
@@ -0,0 +1,264 @@
+/*
+ * RFC 1521 base64 encoding/decoding
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_BASE64_C)
+
+#include "polarssl/base64.h"
+
+static const unsigned char base64_enc_map[64] =
+{
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
+ 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
+ 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+ 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+ 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '+', '/'
+};
+
+static const unsigned char base64_dec_map[128] =
+{
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+ 127, 127, 127, 62, 127, 127, 127, 63, 52, 53,
+ 54, 55, 56, 57, 58, 59, 60, 61, 127, 127,
+ 127, 64, 127, 127, 127, 0, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 127, 127, 127, 127, 127, 127, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
+ 49, 50, 51, 127, 127, 127, 127, 127
+};
+
+/*
+ * Encode a buffer into base64 format
+ */
+int base64_encode( unsigned char *dst, int *dlen,
+ unsigned char *src, int slen )
+{
+ int i, n;
+ int C1, C2, C3;
+ unsigned char *p;
+
+ if( slen == 0 )
+ return( 0 );
+
+ n = (slen << 3) / 6;
+
+ switch( (slen << 3) - (n * 6) )
+ {
+ case 2: n += 3; break;
+ case 4: n += 2; break;
+ default: break;
+ }
+
+ if( *dlen < n + 1 )
+ {
+ *dlen = n + 1;
+ return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
+ }
+
+ n = (slen / 3) * 3;
+
+ for( i = 0, p = dst; i < n; i += 3 )
+ {
+ C1 = *src++;
+ C2 = *src++;
+ C3 = *src++;
+
+ *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
+ *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
+ *p++ = base64_enc_map[(((C2 & 15) << 2) + (C3 >> 6)) & 0x3F];
+ *p++ = base64_enc_map[C3 & 0x3F];
+ }
+
+ if( i < slen )
+ {
+ C1 = *src++;
+ C2 = ((i + 1) < slen) ? *src++ : 0;
+
+ *p++ = base64_enc_map[(C1 >> 2) & 0x3F];
+ *p++ = base64_enc_map[(((C1 & 3) << 4) + (C2 >> 4)) & 0x3F];
+
+ if( (i + 1) < slen )
+ *p++ = base64_enc_map[((C2 & 15) << 2) & 0x3F];
+ else *p++ = '=';
+
+ *p++ = '=';
+ }
+
+ *dlen = p - dst;
+ *p = 0;
+
+ return( 0 );
+}
+
+/*
+ * Decode a base64-formatted buffer
+ */
+int base64_decode( unsigned char *dst, int *dlen,
+ unsigned char *src, int slen )
+{
+ int i, j, n;
+ unsigned long x;
+ unsigned char *p;
+
+ for( i = j = n = 0; i < slen; i++ )
+ {
+ if( ( slen - i ) >= 2 &&
+ src[i] == '\r' && src[i + 1] == '\n' )
+ continue;
+
+ if( src[i] == '\n' )
+ continue;
+
+ if( src[i] == '=' && ++j > 2 )
+ return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
+
+ if( src[i] > 127 || base64_dec_map[src[i]] == 127 )
+ return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
+
+ if( base64_dec_map[src[i]] < 64 && j != 0 )
+ return( POLARSSL_ERR_BASE64_INVALID_CHARACTER );
+
+ n++;
+ }
+
+ if( n == 0 )
+ return( 0 );
+
+ n = ((n * 6) + 7) >> 3;
+
+ if( *dlen < n )
+ {
+ *dlen = n;
+ return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
+ }
+
+ for( j = 3, n = x = 0, p = dst; i > 0; i--, src++ )
+ {
+ if( *src == '\r' || *src == '\n' )
+ continue;
+
+ j -= ( base64_dec_map[*src] == 64 );
+ x = (x << 6) | ( base64_dec_map[*src] & 0x3F );
+
+ if( ++n == 4 )
+ {
+ n = 0;
+ if( j > 0 ) *p++ = (unsigned char)( x >> 16 );
+ if( j > 1 ) *p++ = (unsigned char)( x >> 8 );
+ if( j > 2 ) *p++ = (unsigned char)( x );
+ }
+ }
+
+ *dlen = p - dst;
+
+ return( 0 );
+}
+
+#if defined(POLARSSL_SELF_TEST)
+
+#include <string.h>
+#include <stdio.h>
+
+static const unsigned char base64_test_dec[64] =
+{
+ 0x24, 0x48, 0x6E, 0x56, 0x87, 0x62, 0x5A, 0xBD,
+ 0xBF, 0x17, 0xD9, 0xA2, 0xC4, 0x17, 0x1A, 0x01,
+ 0x94, 0xED, 0x8F, 0x1E, 0x11, 0xB3, 0xD7, 0x09,
+ 0x0C, 0xB6, 0xE9, 0x10, 0x6F, 0x22, 0xEE, 0x13,
+ 0xCA, 0xB3, 0x07, 0x05, 0x76, 0xC9, 0xFA, 0x31,
+ 0x6C, 0x08, 0x34, 0xFF, 0x8D, 0xC2, 0x6C, 0x38,
+ 0x00, 0x43, 0xE9, 0x54, 0x97, 0xAF, 0x50, 0x4B,
+ 0xD1, 0x41, 0xBA, 0x95, 0x31, 0x5A, 0x0B, 0x97
+};
+
+static const unsigned char base64_test_enc[] =
+ "JEhuVodiWr2/F9mixBcaAZTtjx4Rs9cJDLbpEG8i7hPK"
+ "swcFdsn6MWwINP+Nwmw4AEPpVJevUEvRQbqVMVoLlw==";
+
+/*
+ * Checkup routine
+ */
+int base64_self_test( int verbose )
+{
+ int len;
+ unsigned char *src, buffer[128];
+
+ if( verbose != 0 )
+ printf( " Base64 encoding test: " );
+
+ len = sizeof( buffer );
+ src = (unsigned char *) base64_test_dec;
+
+ if( base64_encode( buffer, &len, src, 64 ) != 0 ||
+ memcmp( base64_test_enc, buffer, 88 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n Base64 decoding test: " );
+
+ len = sizeof( buffer );
+ src = (unsigned char *) base64_test_enc;
+
+ if( base64_decode( buffer, &len, src, 88 ) != 0 ||
+ memcmp( base64_test_dec, buffer, 64 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n\n" );
+
+ return( 0 );
+}
+
+#endif
+
+#endif
diff --git a/package/utils/px5g-standalone/src/library/bignum.c b/package/utils/px5g-standalone/src/library/bignum.c
new file mode 100644
index 0000000..8b7c12f
--- /dev/null
+++ b/package/utils/px5g-standalone/src/library/bignum.c
@@ -0,0 +1,2010 @@
+/*
+ * Multi-precision integer library
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * This MPI implementation is based on:
+ *
+ * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
+ * http://www.stillhq.com/extracted/gnupg-api/mpi/
+ * http://math.libtomcrypt.com/files/tommath.pdf
+ */
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_BIGNUM_C)
+
+#include "polarssl/bignum.h"
+#include "polarssl/bn_mul.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+#define ciL ((int) sizeof(t_int)) /* chars in limb */
+#define biL (ciL << 3) /* bits in limb */
+#define biH (ciL << 2) /* half limb size */
+
+/*
+ * Convert between bits/chars and number of limbs
+ */
+#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
+#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
+
+/*
+ * Initialize one or more mpi
+ */
+void mpi_init( mpi *X, ... )
+{
+ va_list args;
+
+ va_start( args, X );
+
+ while( X != NULL )
+ {
+ X->s = 1;
+ X->n = 0;
+ X->p = NULL;
+
+ X = va_arg( args, mpi* );
+ }
+
+ va_end( args );
+}
+
+/*
+ * Unallocate one or more mpi
+ */
+void mpi_free( mpi *X, ... )
+{
+ va_list args;
+
+ va_start( args, X );
+
+ while( X != NULL )
+ {
+ if( X->p != NULL )
+ {
+ memset( X->p, 0, X->n * ciL );
+ free( X->p );
+ }
+
+ X->s = 1;
+ X->n = 0;
+ X->p = NULL;
+
+ X = va_arg( args, mpi* );
+ }
+
+ va_end( args );
+}
+
+/*
+ * Enlarge to the specified number of limbs
+ */
+int mpi_grow( mpi *X, int nblimbs )
+{
+ t_int *p;
+
+ if( X->n < nblimbs )
+ {
+ if( ( p = (t_int *) malloc( nblimbs * ciL ) ) == NULL )
+ return( 1 );
+
+ memset( p, 0, nblimbs * ciL );
+
+ if( X->p != NULL )
+ {
+ memcpy( p, X->p, X->n * ciL );
+ memset( X->p, 0, X->n * ciL );
+ free( X->p );
+ }
+
+ X->n = nblimbs;
+ X->p = p;
+ }
+
+ return( 0 );
+}
+
+/*
+ * Copy the contents of Y into X
+ */
+int mpi_copy( mpi *X, mpi *Y )
+{
+ int ret, i;
+
+ if( X == Y )
+ return( 0 );
+
+ for( i = Y->n - 1; i > 0; i-- )
+ if( Y->p[i] != 0 )
+ break;
+ i++;
+
+ X->s = Y->s;
+
+ MPI_CHK( mpi_grow( X, i ) );
+
+ memset( X->p, 0, X->n * ciL );
+ memcpy( X->p, Y->p, i * ciL );
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Swap the contents of X and Y
+ */
+void mpi_swap( mpi *X, mpi *Y )
+{
+ mpi T;
+
+ memcpy( &T, X, sizeof( mpi ) );
+ memcpy( X, Y, sizeof( mpi ) );
+ memcpy( Y, &T, sizeof( mpi ) );
+}
+
+/*
+ * Set value from integer
+ */
+int mpi_lset( mpi *X, int z )
+{
+ int ret;
+
+ MPI_CHK( mpi_grow( X, 1 ) );
+ memset( X->p, 0, X->n * ciL );
+
+ X->p[0] = ( z < 0 ) ? -z : z;
+ X->s = ( z < 0 ) ? -1 : 1;
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Return the number of least significant bits
+ */
+int mpi_lsb( mpi *X )
+{
+ int i, j, count = 0;
+
+ for( i = 0; i < X->n; i++ )
+ for( j = 0; j < (int) biL; j++, count++ )
+ if( ( ( X->p[i] >> j ) & 1 ) != 0 )
+ return( count );
+
+ return( 0 );
+}
+
+/*
+ * Return the number of most significant bits
+ */
+int mpi_msb( mpi *X )
+{
+ int i, j;
+
+ for( i = X->n - 1; i > 0; i-- )
+ if( X->p[i] != 0 )
+ break;
+
+ for( j = biL - 1; j >= 0; j-- )
+ if( ( ( X->p[i] >> j ) & 1 ) != 0 )
+ break;
+
+ return( ( i * biL ) + j + 1 );
+}
+
+/*
+ * Return the total size in bytes
+ */
+int mpi_size( mpi *X )
+{
+ return( ( mpi_msb( X ) + 7 ) >> 3 );
+}
+
+/*
+ * Convert an ASCII character to digit value
+ */
+static int mpi_get_digit( t_int *d, int radix, char c )
+{
+ *d = 255;
+
+ if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
+ if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
+ if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
+
+ if( *d >= (t_int) radix )
+ return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
+
+ return( 0 );
+}
+
+/*
+ * Import from an ASCII string
+ */
+int mpi_read_string( mpi *X, int radix, char *s )
+{
+ int ret, i, j, n;
+ t_int d;
+ mpi T;
+
+ if( radix < 2 || radix > 16 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ mpi_init( &T, NULL );
+
+ if( radix == 16 )
+ {
+ n = BITS_TO_LIMBS( strlen( s ) << 2 );
+
+ MPI_CHK( mpi_grow( X, n ) );
+ MPI_CHK( mpi_lset( X, 0 ) );
+
+ for( i = strlen( s ) - 1, j = 0; i >= 0; i--, j++ )
+ {
+ if( i == 0 && s[i] == '-' )
+ {
+ X->s = -1;
+ break;
+ }
+
+ MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
+ X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
+ }
+ }
+ else
+ {
+ MPI_CHK( mpi_lset( X, 0 ) );
+
+ for( i = 0; i < (int) strlen( s ); i++ )
+ {
+ if( i == 0 && s[i] == '-' )
+ {
+ X->s = -1;
+ continue;
+ }
+
+ MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
+ MPI_CHK( mpi_mul_int( &T, X, radix ) );
+ MPI_CHK( mpi_add_int( X, &T, d ) );
+ }
+ }
+
+cleanup:
+
+ mpi_free( &T, NULL );
+
+ return( ret );
+}
+
+/*
+ * Helper to write the digits high-order first
+ */
+static int mpi_write_hlp( mpi *X, int radix, char **p )
+{
+ int ret;
+ t_int r;
+
+ if( radix < 2 || radix > 16 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ MPI_CHK( mpi_mod_int( &r, X, radix ) );
+ MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
+
+ if( mpi_cmp_int( X, 0 ) != 0 )
+ MPI_CHK( mpi_write_hlp( X, radix, p ) );
+
+ if( r < 10 )
+ *(*p)++ = (char)( r + 0x30 );
+ else
+ *(*p)++ = (char)( r + 0x37 );
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Export into an ASCII string
+ */
+int mpi_write_string( mpi *X, int radix, char *s, int *slen )
+{
+ int ret = 0, n;
+ char *p;
+ mpi T;
+
+ if( radix < 2 || radix > 16 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ n = mpi_msb( X );
+ if( radix >= 4 ) n >>= 1;
+ if( radix >= 16 ) n >>= 1;
+ n += 3;
+
+ if( *slen < n )
+ {
+ *slen = n;
+ return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
+ }
+
+ p = s;
+ mpi_init( &T, NULL );
+
+ if( X->s == -1 )
+ *p++ = '-';
+
+ if( radix == 16 )
+ {
+ int c, i, j, k;
+
+ for( i = X->n - 1, k = 0; i >= 0; i-- )
+ {
+ for( j = ciL - 1; j >= 0; j-- )
+ {
+ c = ( X->p[i] >> (j << 3) ) & 0xFF;
+
+ if( c == 0 && k == 0 && (i + j) != 0 )
+ continue;
+
+ p += sprintf( p, "%02X", c );
+ k = 1;
+ }
+ }
+ }
+ else
+ {
+ MPI_CHK( mpi_copy( &T, X ) );
+ MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
+ }
+
+ *p++ = '\0';
+ *slen = p - s;
+
+cleanup:
+
+ mpi_free( &T, NULL );
+
+ return( ret );
+}
+
+/*
+ * Read X from an opened file
+ */
+int mpi_read_file( mpi *X, int radix, FILE *fin )
+{
+ t_int d;
+ int slen;
+ char *p;
+ char s[1024];
+
+ memset( s, 0, sizeof( s ) );
+ if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
+ return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
+
+ slen = strlen( s );
+ if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
+ if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
+
+ p = s + slen;
+ while( --p >= s )
+ if( mpi_get_digit( &d, radix, *p ) != 0 )
+ break;
+
+ return( mpi_read_string( X, radix, p + 1 ) );
+}
+
+/*
+ * Write X into an opened file (or stdout if fout == NULL)
+ */
+int mpi_write_file( char *p, mpi *X, int radix, FILE *fout )
+{
+ int n, ret;
+ size_t slen;
+ size_t plen;
+ char s[1024];
+
+ n = sizeof( s );
+ memset( s, 0, n );
+ n -= 2;
+
+ MPI_CHK( mpi_write_string( X, radix, s, (int *) &n ) );
+
+ if( p == NULL ) p = "";
+
+ plen = strlen( p );
+ slen = strlen( s );
+ s[slen++] = '\r';
+ s[slen++] = '\n';
+
+ if( fout != NULL )
+ {
+ if( fwrite( p, 1, plen, fout ) != plen ||
+ fwrite( s, 1, slen, fout ) != slen )
+ return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
+ }
+ else
+ printf( "%s%s", p, s );
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Import X from unsigned binary data, big endian
+ */
+int mpi_read_binary( mpi *X, unsigned char *buf, int buflen )
+{
+ int ret, i, j, n;
+
+ for( n = 0; n < buflen; n++ )
+ if( buf[n] != 0 )
+ break;
+
+ MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
+ MPI_CHK( mpi_lset( X, 0 ) );
+
+ for( i = buflen - 1, j = 0; i >= n; i--, j++ )
+ X->p[j / ciL] |= ((t_int) buf[i]) << ((j % ciL) << 3);
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Export X into unsigned binary data, big endian
+ */
+int mpi_write_binary( mpi *X, unsigned char *buf, int buflen )
+{
+ int i, j, n;
+
+ n = mpi_size( X );
+
+ if( buflen < n )
+ return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
+
+ memset( buf, 0, buflen );
+
+ for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
+ buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
+
+ return( 0 );
+}
+
+/*
+ * Left-shift: X <<= count
+ */
+int mpi_shift_l( mpi *X, int count )
+{
+ int ret, i, v0, t1;
+ t_int r0 = 0, r1;
+
+ v0 = count / (biL );
+ t1 = count & (biL - 1);
+
+ i = mpi_msb( X ) + count;
+
+ if( X->n * (int) biL < i )
+ MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
+
+ ret = 0;
+
+ /*
+ * shift by count / limb_size
+ */
+ if( v0 > 0 )
+ {
+ for( i = X->n - 1; i >= v0; i-- )
+ X->p[i] = X->p[i - v0];
+
+ for( ; i >= 0; i-- )
+ X->p[i] = 0;
+ }
+
+ /*
+ * shift by count % limb_size
+ */
+ if( t1 > 0 )
+ {
+ for( i = v0; i < X->n; i++ )
+ {
+ r1 = X->p[i] >> (biL - t1);
+ X->p[i] <<= t1;
+ X->p[i] |= r0;
+ r0 = r1;
+ }
+ }
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Right-shift: X >>= count
+ */
+int mpi_shift_r( mpi *X, int count )
+{
+ int i, v0, v1;
+ t_int r0 = 0, r1;
+
+ v0 = count / biL;
+ v1 = count & (biL - 1);
+
+ /*
+ * shift by count / limb_size
+ */
+ if( v0 > 0 )
+ {
+ for( i = 0; i < X->n - v0; i++ )
+ X->p[i] = X->p[i + v0];
+
+ for( ; i < X->n; i++ )
+ X->p[i] = 0;
+ }
+
+ /*
+ * shift by count % limb_size
+ */
+ if( v1 > 0 )
+ {
+ for( i = X->n - 1; i >= 0; i-- )
+ {
+ r1 = X->p[i] << (biL - v1);
+ X->p[i] >>= v1;
+ X->p[i] |= r0;
+ r0 = r1;
+ }
+ }
+
+ return( 0 );
+}
+
+/*
+ * Compare unsigned values
+ */
+int mpi_cmp_abs( mpi *X, mpi *Y )
+{
+ int i, j;
+
+ for( i = X->n - 1; i >= 0; i-- )
+ if( X->p[i] != 0 )
+ break;
+
+ for( j = Y->n - 1; j >= 0; j-- )
+ if( Y->p[j] != 0 )
+ break;
+
+ if( i < 0 && j < 0 )
+ return( 0 );
+
+ if( i > j ) return( 1 );
+ if( j > i ) return( -1 );
+
+ for( ; i >= 0; i-- )
+ {
+ if( X->p[i] > Y->p[i] ) return( 1 );
+ if( X->p[i] < Y->p[i] ) return( -1 );
+ }
+
+ return( 0 );
+}
+
+/*
+ * Compare signed values
+ */
+int mpi_cmp_mpi( mpi *X, mpi *Y )
+{
+ int i, j;
+
+ for( i = X->n - 1; i >= 0; i-- )
+ if( X->p[i] != 0 )
+ break;
+
+ for( j = Y->n - 1; j >= 0; j-- )
+ if( Y->p[j] != 0 )
+ break;
+
+ if( i < 0 && j < 0 )
+ return( 0 );
+
+ if( i > j ) return( X->s );
+ if( j > i ) return( -X->s );
+
+ if( X->s > 0 && Y->s < 0 ) return( 1 );
+ if( Y->s > 0 && X->s < 0 ) return( -1 );
+
+ for( ; i >= 0; i-- )
+ {
+ if( X->p[i] > Y->p[i] ) return( X->s );
+ if( X->p[i] < Y->p[i] ) return( -X->s );
+ }
+
+ return( 0 );
+}
+
+/*
+ * Compare signed values
+ */
+int mpi_cmp_int( mpi *X, int z )
+{
+ mpi Y;
+ t_int p[1];
+
+ *p = ( z < 0 ) ? -z : z;
+ Y.s = ( z < 0 ) ? -1 : 1;
+ Y.n = 1;
+ Y.p = p;
+
+ return( mpi_cmp_mpi( X, &Y ) );
+}
+
+/*
+ * Unsigned addition: X = |A| + |B| (HAC 14.7)
+ */
+int mpi_add_abs( mpi *X, mpi *A, mpi *B )
+{
+ int ret, i, j;
+ t_int *o, *p, c;
+
+ if( X == B )
+ {
+ mpi *T = A; A = X; B = T;
+ }
+
+ if( X != A )
+ MPI_CHK( mpi_copy( X, A ) );
+
+ for( j = B->n - 1; j >= 0; j-- )
+ if( B->p[j] != 0 )
+ break;
+
+ MPI_CHK( mpi_grow( X, j + 1 ) );
+
+ o = B->p; p = X->p; c = 0;
+
+ for( i = 0; i <= j; i++, o++, p++ )
+ {
+ *p += c; c = ( *p < c );
+ *p += *o; c += ( *p < *o );
+ }
+
+ while( c != 0 )
+ {
+ if( i >= X->n )
+ {
+ MPI_CHK( mpi_grow( X, i + 1 ) );
+ p = X->p + i;
+ }
+
+ *p += c; c = ( *p < c ); i++;
+ }
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Helper for mpi substraction
+ */
+static void mpi_sub_hlp( int n, t_int *s, t_int *d )
+{
+ int i;
+ t_int c, z;
+
+ for( i = c = 0; i < n; i++, s++, d++ )
+ {
+ z = ( *d < c ); *d -= c;
+ c = ( *d < *s ) + z; *d -= *s;
+ }
+
+ while( c != 0 )
+ {
+ z = ( *d < c ); *d -= c;
+ c = z; i++; d++;
+ }
+}
+
+/*
+ * Unsigned substraction: X = |A| - |B| (HAC 14.9)
+ */
+int mpi_sub_abs( mpi *X, mpi *A, mpi *B )
+{
+ mpi TB;
+ int ret, n;
+
+ if( mpi_cmp_abs( A, B ) < 0 )
+ return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
+
+ mpi_init( &TB, NULL );
+
+ if( X == B )
+ {
+ MPI_CHK( mpi_copy( &TB, B ) );
+ B = &TB;
+ }
+
+ if( X != A )
+ MPI_CHK( mpi_copy( X, A ) );
+
+ ret = 0;
+
+ for( n = B->n - 1; n >= 0; n-- )
+ if( B->p[n] != 0 )
+ break;
+
+ mpi_sub_hlp( n + 1, B->p, X->p );
+
+cleanup:
+
+ mpi_free( &TB, NULL );
+
+ return( ret );
+}
+
+/*
+ * Signed addition: X = A + B
+ */
+int mpi_add_mpi( mpi *X, mpi *A, mpi *B )
+{
+ int ret, s = A->s;
+
+ if( A->s * B->s < 0 )
+ {
+ if( mpi_cmp_abs( A, B ) >= 0 )
+ {
+ MPI_CHK( mpi_sub_abs( X, A, B ) );
+ X->s = s;
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_abs( X, B, A ) );
+ X->s = -s;
+ }
+ }
+ else
+ {
+ MPI_CHK( mpi_add_abs( X, A, B ) );
+ X->s = s;
+ }
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Signed substraction: X = A - B
+ */
+int mpi_sub_mpi( mpi *X, mpi *A, mpi *B )
+{
+ int ret, s = A->s;
+
+ if( A->s * B->s > 0 )
+ {
+ if( mpi_cmp_abs( A, B ) >= 0 )
+ {
+ MPI_CHK( mpi_sub_abs( X, A, B ) );
+ X->s = s;
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_abs( X, B, A ) );
+ X->s = -s;
+ }
+ }
+ else
+ {
+ MPI_CHK( mpi_add_abs( X, A, B ) );
+ X->s = s;
+ }
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Signed addition: X = A + b
+ */
+int mpi_add_int( mpi *X, mpi *A, int b )
+{
+ mpi _B;
+ t_int p[1];
+
+ p[0] = ( b < 0 ) ? -b : b;
+ _B.s = ( b < 0 ) ? -1 : 1;
+ _B.n = 1;
+ _B.p = p;
+
+ return( mpi_add_mpi( X, A, &_B ) );
+}
+
+/*
+ * Signed substraction: X = A - b
+ */
+int mpi_sub_int( mpi *X, mpi *A, int b )
+{
+ mpi _B;
+ t_int p[1];
+
+ p[0] = ( b < 0 ) ? -b : b;
+ _B.s = ( b < 0 ) ? -1 : 1;
+ _B.n = 1;
+ _B.p = p;
+
+ return( mpi_sub_mpi( X, A, &_B ) );
+}
+
+/*
+ * Helper for mpi multiplication
+ */
+static void mpi_mul_hlp( int i, t_int *s, t_int *d, t_int b )
+{
+ t_int c = 0, t = 0;
+
+#if defined(MULADDC_HUIT)
+ for( ; i >= 8; i -= 8 )
+ {
+ MULADDC_INIT
+ MULADDC_HUIT
+ MULADDC_STOP
+ }
+
+ for( ; i > 0; i-- )
+ {
+ MULADDC_INIT
+ MULADDC_CORE
+ MULADDC_STOP
+ }
+#else
+ for( ; i >= 16; i -= 16 )
+ {
+ MULADDC_INIT
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_STOP
+ }
+
+ for( ; i >= 8; i -= 8 )
+ {
+ MULADDC_INIT
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_CORE MULADDC_CORE
+ MULADDC_STOP
+ }
+
+ for( ; i > 0; i-- )
+ {
+ MULADDC_INIT
+ MULADDC_CORE
+ MULADDC_STOP
+ }
+#endif
+
+ t++;
+
+ do {
+ *d += c; c = ( *d < c ); d++;
+ }
+ while( c != 0 );
+}
+
+/*
+ * Baseline multiplication: X = A * B (HAC 14.12)
+ */
+int mpi_mul_mpi( mpi *X, mpi *A, mpi *B )
+{
+ int ret, i, j;
+ mpi TA, TB;
+
+ mpi_init( &TA, &TB, NULL );
+
+ if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
+ if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
+
+ for( i = A->n - 1; i >= 0; i-- )
+ if( A->p[i] != 0 )
+ break;
+
+ for( j = B->n - 1; j >= 0; j-- )
+ if( B->p[j] != 0 )
+ break;
+
+ MPI_CHK( mpi_grow( X, i + j + 2 ) );
+ MPI_CHK( mpi_lset( X, 0 ) );
+
+ for( i++; j >= 0; j-- )
+ mpi_mul_hlp( i, A->p, X->p + j, B->p[j] );
+
+ X->s = A->s * B->s;
+
+cleanup:
+
+ mpi_free( &TB, &TA, NULL );
+
+ return( ret );
+}
+
+/*
+ * Baseline multiplication: X = A * b
+ */
+int mpi_mul_int( mpi *X, mpi *A, t_int b )
+{
+ mpi _B;
+ t_int p[1];
+
+ _B.s = 1;
+ _B.n = 1;
+ _B.p = p;
+ p[0] = b;
+
+ return( mpi_mul_mpi( X, A, &_B ) );
+}
+
+/*
+ * Division by mpi: A = Q * B + R (HAC 14.20)
+ */
+int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B )
+{
+ int ret, i, n, t, k;
+ mpi X, Y, Z, T1, T2;
+
+ if( mpi_cmp_int( B, 0 ) == 0 )
+ return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
+
+ mpi_init( &X, &Y, &Z, &T1, &T2, NULL );
+
+ if( mpi_cmp_abs( A, B ) < 0 )
+ {
+ if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
+ if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
+ return( 0 );
+ }
+
+ MPI_CHK( mpi_copy( &X, A ) );
+ MPI_CHK( mpi_copy( &Y, B ) );
+ X.s = Y.s = 1;
+
+ MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
+ MPI_CHK( mpi_lset( &Z, 0 ) );
+ MPI_CHK( mpi_grow( &T1, 2 ) );
+ MPI_CHK( mpi_grow( &T2, 3 ) );
+
+ k = mpi_msb( &Y ) % biL;
+ if( k < (int) biL - 1 )
+ {
+ k = biL - 1 - k;
+ MPI_CHK( mpi_shift_l( &X, k ) );
+ MPI_CHK( mpi_shift_l( &Y, k ) );
+ }
+ else k = 0;
+
+ n = X.n - 1;
+ t = Y.n - 1;
+ mpi_shift_l( &Y, biL * (n - t) );
+
+ while( mpi_cmp_mpi( &X, &Y ) >= 0 )
+ {
+ Z.p[n - t]++;
+ mpi_sub_mpi( &X, &X, &Y );
+ }
+ mpi_shift_r( &Y, biL * (n - t) );
+
+ for( i = n; i > t ; i-- )
+ {
+ if( X.p[i] >= Y.p[t] )
+ Z.p[i - t - 1] = ~0;
+ else
+ {
+#if defined(POLARSSL_HAVE_LONGLONG)
+ t_dbl r;
+
+ r = (t_dbl) X.p[i] << biL;
+ r |= (t_dbl) X.p[i - 1];
+ r /= Y.p[t];
+ if( r > ((t_dbl) 1 << biL) - 1)
+ r = ((t_dbl) 1 << biL) - 1;
+
+ Z.p[i - t - 1] = (t_int) r;
+#else
+ /*
+ * __udiv_qrnnd_c, from gmp/longlong.h
+ */
+ t_int q0, q1, r0, r1;
+ t_int d0, d1, d, m;
+
+ d = Y.p[t];
+ d0 = ( d << biH ) >> biH;
+ d1 = ( d >> biH );
+
+ q1 = X.p[i] / d1;
+ r1 = X.p[i] - d1 * q1;
+ r1 <<= biH;
+ r1 |= ( X.p[i - 1] >> biH );
+
+ m = q1 * d0;
+ if( r1 < m )
+ {
+ q1--, r1 += d;
+ while( r1 >= d && r1 < m )
+ q1--, r1 += d;
+ }
+ r1 -= m;
+
+ q0 = r1 / d1;
+ r0 = r1 - d1 * q0;
+ r0 <<= biH;
+ r0 |= ( X.p[i - 1] << biH ) >> biH;
+
+ m = q0 * d0;
+ if( r0 < m )
+ {
+ q0--, r0 += d;
+ while( r0 >= d && r0 < m )
+ q0--, r0 += d;
+ }
+ r0 -= m;
+
+ Z.p[i - t - 1] = ( q1 << biH ) | q0;
+#endif
+ }
+
+ Z.p[i - t - 1]++;
+ do
+ {
+ Z.p[i - t - 1]--;
+
+ MPI_CHK( mpi_lset( &T1, 0 ) );
+ T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
+ T1.p[1] = Y.p[t];
+ MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
+
+ MPI_CHK( mpi_lset( &T2, 0 ) );
+ T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
+ T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
+ T2.p[2] = X.p[i];
+ }
+ while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
+
+ MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
+ MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
+ MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
+
+ if( mpi_cmp_int( &X, 0 ) < 0 )
+ {
+ MPI_CHK( mpi_copy( &T1, &Y ) );
+ MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
+ MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
+ Z.p[i - t - 1]--;
+ }
+ }
+
+ if( Q != NULL )
+ {
+ mpi_copy( Q, &Z );
+ Q->s = A->s * B->s;
+ }
+
+ if( R != NULL )
+ {
+ mpi_shift_r( &X, k );
+ mpi_copy( R, &X );
+
+ R->s = A->s;
+ if( mpi_cmp_int( R, 0 ) == 0 )
+ R->s = 1;
+ }
+
+cleanup:
+
+ mpi_free( &X, &Y, &Z, &T1, &T2, NULL );
+
+ return( ret );
+}
+
+/*
+ * Division by int: A = Q * b + R
+ *
+ * Returns 0 if successful
+ * 1 if memory allocation failed
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ */
+int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b )
+{
+ mpi _B;
+ t_int p[1];
+
+ p[0] = ( b < 0 ) ? -b : b;
+ _B.s = ( b < 0 ) ? -1 : 1;
+ _B.n = 1;
+ _B.p = p;
+
+ return( mpi_div_mpi( Q, R, A, &_B ) );
+}
+
+/*
+ * Modulo: R = A mod B
+ */
+int mpi_mod_mpi( mpi *R, mpi *A, mpi *B )
+{
+ int ret;
+
+ MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
+
+ while( mpi_cmp_int( R, 0 ) < 0 )
+ MPI_CHK( mpi_add_mpi( R, R, B ) );
+
+ while( mpi_cmp_mpi( R, B ) >= 0 )
+ MPI_CHK( mpi_sub_mpi( R, R, B ) );
+
+cleanup:
+
+ return( ret );
+}
+
+/*
+ * Modulo: r = A mod b
+ */
+int mpi_mod_int( t_int *r, mpi *A, int b )
+{
+ int i;
+ t_int x, y, z;
+
+ if( b == 0 )
+ return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
+
+ if( b < 0 )
+ b = -b;
+
+ /*
+ * handle trivial cases
+ */
+ if( b == 1 )
+ {
+ *r = 0;
+ return( 0 );
+ }
+
+ if( b == 2 )
+ {
+ *r = A->p[0] & 1;
+ return( 0 );
+ }
+
+ /*
+ * general case
+ */
+ for( i = A->n - 1, y = 0; i >= 0; i-- )
+ {
+ x = A->p[i];
+ y = ( y << biH ) | ( x >> biH );
+ z = y / b;
+ y -= z * b;
+
+ x <<= biH;
+ y = ( y << biH ) | ( x >> biH );
+ z = y / b;
+ y -= z * b;
+ }
+
+ *r = y;
+
+ return( 0 );
+}
+
+/*
+ * Fast Montgomery initialization (thanks to Tom St Denis)
+ */
+static void mpi_montg_init( t_int *mm, mpi *N )
+{
+ t_int x, m0 = N->p[0];
+
+ x = m0;
+ x += ( ( m0 + 2 ) & 4 ) << 1;
+ x *= ( 2 - ( m0 * x ) );
+
+ if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
+ if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
+ if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
+
+ *mm = ~x + 1;
+}
+
+/*
+ * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
+ */
+static void mpi_montmul( mpi *A, mpi *B, mpi *N, t_int mm, mpi *T )
+{
+ int i, n, m;
+ t_int u0, u1, *d;
+
+ memset( T->p, 0, T->n * ciL );
+
+ d = T->p;
+ n = N->n;
+ m = ( B->n < n ) ? B->n : n;
+
+ for( i = 0; i < n; i++ )
+ {
+ /*
+ * T = (T + u0*B + u1*N) / 2^biL
+ */
+ u0 = A->p[i];
+ u1 = ( d[0] + u0 * B->p[0] ) * mm;
+
+ mpi_mul_hlp( m, B->p, d, u0 );
+ mpi_mul_hlp( n, N->p, d, u1 );
+
+ *d++ = u0; d[n + 1] = 0;
+ }
+
+ memcpy( A->p, d, (n + 1) * ciL );
+
+ if( mpi_cmp_abs( A, N ) >= 0 )
+ mpi_sub_hlp( n, N->p, A->p );
+ else
+ /* prevent timing attacks */
+ mpi_sub_hlp( n, A->p, T->p );
+}
+
+/*
+ * Montgomery reduction: A = A * R^-1 mod N
+ */
+static void mpi_montred( mpi *A, mpi *N, t_int mm, mpi *T )
+{
+ t_int z = 1;
+ mpi U;
+
+ U.n = U.s = z;
+ U.p = &z;
+
+ mpi_montmul( A, &U, N, mm, T );
+}
+
+/*
+ * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
+ */
+int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR )
+{
+ int ret, i, j, wsize, wbits;
+ int bufsize, nblimbs, nbits;
+ t_int ei, mm, state;
+ mpi RR, T, W[64];
+
+ if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ /*
+ * Init temps and window size
+ */
+ mpi_montg_init( &mm, N );
+ mpi_init( &RR, &T, NULL );
+ memset( W, 0, sizeof( W ) );
+
+ i = mpi_msb( E );
+
+ wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
+ ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
+
+ j = N->n + 1;
+ MPI_CHK( mpi_grow( X, j ) );
+ MPI_CHK( mpi_grow( &W[1], j ) );
+ MPI_CHK( mpi_grow( &T, j * 2 ) );
+
+ /*
+ * If 1st call, pre-compute R^2 mod N
+ */
+ if( _RR == NULL || _RR->p == NULL )
+ {
+ MPI_CHK( mpi_lset( &RR, 1 ) );
+ MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
+ MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
+
+ if( _RR != NULL )
+ memcpy( _RR, &RR, sizeof( mpi ) );
+ }
+ else
+ memcpy( &RR, _RR, sizeof( mpi ) );
+
+ /*
+ * W[1] = A * R^2 * R^-1 mod N = A * R mod N
+ */
+ if( mpi_cmp_mpi( A, N ) >= 0 )
+ mpi_mod_mpi( &W[1], A, N );
+ else mpi_copy( &W[1], A );
+
+ mpi_montmul( &W[1], &RR, N, mm, &T );
+
+ /*
+ * X = R^2 * R^-1 mod N = R mod N
+ */
+ MPI_CHK( mpi_copy( X, &RR ) );
+ mpi_montred( X, N, mm, &T );
+
+ if( wsize > 1 )
+ {
+ /*
+ * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
+ */
+ j = 1 << (wsize - 1);
+
+ MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
+ MPI_CHK( mpi_copy( &W[j], &W[1] ) );
+
+ for( i = 0; i < wsize - 1; i++ )
+ mpi_montmul( &W[j], &W[j], N, mm, &T );
+
+ /*
+ * W[i] = W[i - 1] * W[1]
+ */
+ for( i = j + 1; i < (1 << wsize); i++ )
+ {
+ MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
+ MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
+
+ mpi_montmul( &W[i], &W[1], N, mm, &T );
+ }
+ }
+
+ nblimbs = E->n;
+ bufsize = 0;
+ nbits = 0;
+ wbits = 0;
+ state = 0;
+
+ while( 1 )
+ {
+ if( bufsize == 0 )
+ {
+ if( nblimbs-- == 0 )
+ break;
+
+ bufsize = sizeof( t_int ) << 3;
+ }
+
+ bufsize--;
+
+ ei = (E->p[nblimbs] >> bufsize) & 1;
+
+ /*
+ * skip leading 0s
+ */
+ if( ei == 0 && state == 0 )
+ continue;
+
+ if( ei == 0 && state == 1 )
+ {
+ /*
+ * out of window, square X
+ */
+ mpi_montmul( X, X, N, mm, &T );
+ continue;
+ }
+
+ /*
+ * add ei to current window
+ */
+ state = 2;
+
+ nbits++;
+ wbits |= (ei << (wsize - nbits));
+
+ if( nbits == wsize )
+ {
+ /*
+ * X = X^wsize R^-1 mod N
+ */
+ for( i = 0; i < wsize; i++ )
+ mpi_montmul( X, X, N, mm, &T );
+
+ /*
+ * X = X * W[wbits] R^-1 mod N
+ */
+ mpi_montmul( X, &W[wbits], N, mm, &T );
+
+ state--;
+ nbits = 0;
+ wbits = 0;
+ }
+ }
+
+ /*
+ * process the remaining bits
+ */
+ for( i = 0; i < nbits; i++ )
+ {
+ mpi_montmul( X, X, N, mm, &T );
+
+ wbits <<= 1;
+
+ if( (wbits & (1 << wsize)) != 0 )
+ mpi_montmul( X, &W[1], N, mm, &T );
+ }
+
+ /*
+ * X = A^E * R * R^-1 mod N = A^E mod N
+ */
+ mpi_montred( X, N, mm, &T );
+
+cleanup:
+
+ for( i = (1 << (wsize - 1)); i < (1 << wsize); i++ )
+ mpi_free( &W[i], NULL );
+
+ if( _RR != NULL )
+ mpi_free( &W[1], &T, NULL );
+ else mpi_free( &W[1], &T, &RR, NULL );
+
+ return( ret );
+}
+
+/*
+ * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
+ */
+int mpi_gcd( mpi *G, mpi *A, mpi *B )
+{
+ int ret, lz, lzt;
+ mpi TG, TA, TB;
+
+ mpi_init( &TG, &TA, &TB, NULL );
+
+ MPI_CHK( mpi_copy( &TA, A ) );
+ MPI_CHK( mpi_copy( &TB, B ) );
+
+ lz = mpi_lsb( &TA );
+ lzt = mpi_lsb( &TB );
+
+ if ( lzt < lz )
+ lz = lzt;
+
+ MPI_CHK( mpi_shift_r( &TA, lz ) );
+ MPI_CHK( mpi_shift_r( &TB, lz ) );
+
+ TA.s = TB.s = 1;
+
+ while( mpi_cmp_int( &TA, 0 ) != 0 )
+ {
+ MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
+ MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
+
+ if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
+ {
+ MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
+ MPI_CHK( mpi_shift_r( &TA, 1 ) );
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
+ MPI_CHK( mpi_shift_r( &TB, 1 ) );
+ }
+ }
+
+ MPI_CHK( mpi_shift_l( &TB, lz ) );
+ MPI_CHK( mpi_copy( G, &TB ) );
+
+cleanup:
+
+ mpi_free( &TB, &TA, &TG, NULL );
+
+ return( ret );
+}
+
+#if defined(POLARSSL_GENPRIME)
+
+/*
+ * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
+ */
+int mpi_inv_mod( mpi *X, mpi *A, mpi *N )
+{
+ int ret;
+ mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
+
+ if( mpi_cmp_int( N, 0 ) <= 0 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ mpi_init( &TA, &TU, &U1, &U2, &G,
+ &TB, &TV, &V1, &V2, NULL );
+
+ MPI_CHK( mpi_gcd( &G, A, N ) );
+
+ if( mpi_cmp_int( &G, 1 ) != 0 )
+ {
+ ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
+ goto cleanup;
+ }
+
+ MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
+ MPI_CHK( mpi_copy( &TU, &TA ) );
+ MPI_CHK( mpi_copy( &TB, N ) );
+ MPI_CHK( mpi_copy( &TV, N ) );
+
+ MPI_CHK( mpi_lset( &U1, 1 ) );
+ MPI_CHK( mpi_lset( &U2, 0 ) );
+ MPI_CHK( mpi_lset( &V1, 0 ) );
+ MPI_CHK( mpi_lset( &V2, 1 ) );
+
+ do
+ {
+ while( ( TU.p[0] & 1 ) == 0 )
+ {
+ MPI_CHK( mpi_shift_r( &TU, 1 ) );
+
+ if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
+ {
+ MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
+ MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
+ }
+
+ MPI_CHK( mpi_shift_r( &U1, 1 ) );
+ MPI_CHK( mpi_shift_r( &U2, 1 ) );
+ }
+
+ while( ( TV.p[0] & 1 ) == 0 )
+ {
+ MPI_CHK( mpi_shift_r( &TV, 1 ) );
+
+ if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
+ {
+ MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
+ MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
+ }
+
+ MPI_CHK( mpi_shift_r( &V1, 1 ) );
+ MPI_CHK( mpi_shift_r( &V2, 1 ) );
+ }
+
+ if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
+ {
+ MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
+ MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
+ MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
+ MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
+ MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
+ }
+ }
+ while( mpi_cmp_int( &TU, 0 ) != 0 );
+
+ while( mpi_cmp_int( &V1, 0 ) < 0 )
+ MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
+
+ while( mpi_cmp_mpi( &V1, N ) >= 0 )
+ MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
+
+ MPI_CHK( mpi_copy( X, &V1 ) );
+
+cleanup:
+
+ mpi_free( &V2, &V1, &TV, &TB, &G,
+ &U2, &U1, &TU, &TA, NULL );
+
+ return( ret );
+}
+
+static const int small_prime[] =
+{
+ 3, 5, 7, 11, 13, 17, 19, 23,
+ 29, 31, 37, 41, 43, 47, 53, 59,
+ 61, 67, 71, 73, 79, 83, 89, 97,
+ 101, 103, 107, 109, 113, 127, 131, 137,
+ 139, 149, 151, 157, 163, 167, 173, 179,
+ 181, 191, 193, 197, 199, 211, 223, 227,
+ 229, 233, 239, 241, 251, 257, 263, 269,
+ 271, 277, 281, 283, 293, 307, 311, 313,
+ 317, 331, 337, 347, 349, 353, 359, 367,
+ 373, 379, 383, 389, 397, 401, 409, 419,
+ 421, 431, 433, 439, 443, 449, 457, 461,
+ 463, 467, 479, 487, 491, 499, 503, 509,
+ 521, 523, 541, 547, 557, 563, 569, 571,
+ 577, 587, 593, 599, 601, 607, 613, 617,
+ 619, 631, 641, 643, 647, 653, 659, 661,
+ 673, 677, 683, 691, 701, 709, 719, 727,
+ 733, 739, 743, 751, 757, 761, 769, 773,
+ 787, 797, 809, 811, 821, 823, 827, 829,
+ 839, 853, 857, 859, 863, 877, 881, 883,
+ 887, 907, 911, 919, 929, 937, 941, 947,
+ 953, 967, 971, 977, 983, 991, 997, -103
+};
+
+/*
+ * Miller-Rabin primality test (HAC 4.24)
+ */
+int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
+{
+ int ret, i, j, n, s, xs;
+ mpi W, R, T, A, RR;
+ unsigned char *p;
+
+ if( mpi_cmp_int( X, 0 ) == 0 )
+ return( 0 );
+
+ mpi_init( &W, &R, &T, &A, &RR, NULL );
+
+ xs = X->s; X->s = 1;
+
+ /*
+ * test trivial factors first
+ */
+ if( ( X->p[0] & 1 ) == 0 )
+ return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
+
+ for( i = 0; small_prime[i] > 0; i++ )
+ {
+ t_int r;
+
+ if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
+ return( 0 );
+
+ MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
+
+ if( r == 0 )
+ return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
+ }
+
+ /*
+ * W = |X| - 1
+ * R = W >> lsb( W )
+ */
+ s = mpi_lsb( &W );
+ MPI_CHK( mpi_sub_int( &W, X, 1 ) );
+ MPI_CHK( mpi_copy( &R, &W ) );
+ MPI_CHK( mpi_shift_r( &R, s ) );
+
+ i = mpi_msb( X );
+ /*
+ * HAC, table 4.4
+ */
+ n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
+ ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
+ ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
+
+ for( i = 0; i < n; i++ )
+ {
+ /*
+ * pick a random A, 1 < A < |X| - 1
+ */
+ MPI_CHK( mpi_grow( &A, X->n ) );
+
+ p = (unsigned char *) A.p;
+ for( j = 0; j < A.n * ciL; j++ )
+ *p++ = (unsigned char) f_rng( p_rng );
+
+ j = mpi_msb( &A ) - mpi_msb( &W );
+ MPI_CHK( mpi_shift_r( &A, j + 1 ) );
+ A.p[0] |= 3;
+
+ /*
+ * A = A^R mod |X|
+ */
+ MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
+
+ if( mpi_cmp_mpi( &A, &W ) == 0 ||
+ mpi_cmp_int( &A, 1 ) == 0 )
+ continue;
+
+ j = 1;
+ while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
+ {
+ /*
+ * A = A * A mod |X|
+ */
+ MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
+ MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
+
+ if( mpi_cmp_int( &A, 1 ) == 0 )
+ break;
+
+ j++;
+ }
+
+ /*
+ * not prime if A != |X| - 1 or A == 1
+ */
+ if( mpi_cmp_mpi( &A, &W ) != 0 ||
+ mpi_cmp_int( &A, 1 ) == 0 )
+ {
+ ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
+ break;
+ }
+ }
+
+cleanup:
+
+ X->s = xs;
+
+ mpi_free( &RR, &A, &T, &R, &W, NULL );
+
+ return( ret );
+}
+
+/*
+ * Prime number generation
+ */
+int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
+ int (*f_rng)(void *), void *p_rng )
+{
+ int ret, k, n;
+ unsigned char *p;
+ mpi Y;
+
+ if( nbits < 3 )
+ return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
+
+ mpi_init( &Y, NULL );
+
+ n = BITS_TO_LIMBS( nbits );
+
+ MPI_CHK( mpi_grow( X, n ) );
+ MPI_CHK( mpi_lset( X, 0 ) );
+
+ p = (unsigned char *) X->p;
+ for( k = 0; k < X->n * ciL; k++ )
+ *p++ = (unsigned char) f_rng( p_rng );
+
+ k = mpi_msb( X );
+ if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
+ if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
+
+ X->p[0] |= 3;
+
+ if( dh_flag == 0 )
+ {
+ while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
+ {
+ if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
+ goto cleanup;
+
+ MPI_CHK( mpi_add_int( X, X, 2 ) );
+ }
+ }
+ else
+ {
+ MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
+ MPI_CHK( mpi_shift_r( &Y, 1 ) );
+
+ while( 1 )
+ {
+ if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
+ {
+ if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
+ break;
+
+ if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
+ goto cleanup;
+ }
+
+ if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
+ goto cleanup;
+
+ MPI_CHK( mpi_add_int( &Y, X, 1 ) );
+ MPI_CHK( mpi_add_int( X, X, 2 ) );
+ MPI_CHK( mpi_shift_r( &Y, 1 ) );
+ }
+ }
+
+cleanup:
+
+ mpi_free( &Y, NULL );
+
+ return( ret );
+}
+
+#endif
+
+#if defined(POLARSSL_SELF_TEST)
+
+#define GCD_PAIR_COUNT 3
+
+static const int gcd_pairs[GCD_PAIR_COUNT][3] =
+{
+ { 693, 609, 21 },
+ { 1764, 868, 28 },
+ { 768454923, 542167814, 1 }
+};
+
+/*
+ * Checkup routine
+ */
+int mpi_self_test( int verbose )
+{
+ int ret, i;
+ mpi A, E, N, X, Y, U, V;
+
+ mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL );
+
+ MPI_CHK( mpi_read_string( &A, 16,
+ "EFE021C2645FD1DC586E69184AF4A31E" \
+ "D5F53E93B5F123FA41680867BA110131" \
+ "944FE7952E2517337780CB0DB80E61AA" \
+ "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
+
+ MPI_CHK( mpi_read_string( &E, 16,
+ "B2E7EFD37075B9F03FF989C7C5051C20" \
+ "34D2A323810251127E7BF8625A4F49A5" \
+ "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
+ "5B5C25763222FEFCCFC38B832366C29E" ) );
+
+ MPI_CHK( mpi_read_string( &N, 16,
+ "0066A198186C18C10B2F5ED9B522752A" \
+ "9830B69916E535C8F047518A889A43A5" \
+ "94B6BED27A168D31D4A52F88925AA8F5" ) );
+
+ MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "602AB7ECA597A3D6B56FF9829A5E8B85" \
+ "9E857EA95A03512E2BAE7391688D264A" \
+ "A5663B0341DB9CCFD2C4C5F421FEC814" \
+ "8001B72E848A38CAE1C65F78E56ABDEF" \
+ "E12D3C039B8A02D6BE593F0BBBDA56F1" \
+ "ECF677152EF804370C1A305CAF3B5BF1" \
+ "30879B56C61DE584A0F53A2447A51E" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #1 (mul_mpi): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "256567336059E52CAE22925474705F39A94" ) );
+
+ MPI_CHK( mpi_read_string( &V, 16,
+ "6613F26162223DF488E9CD48CC132C7A" \
+ "0AC93C701B001B092E4E5B9F73BCD27B" \
+ "9EE50D0657C77F374E903CDFA4C642" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #2 (div_mpi): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 ||
+ mpi_cmp_mpi( &Y, &V ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "36E139AEA55215609D2816998ED020BB" \
+ "BD96C37890F65171D948E9BC7CBAA4D9" \
+ "325D24D6A3C12710F10A09FA08AB87" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #3 (exp_mod): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
+
+ MPI_CHK( mpi_read_string( &U, 16,
+ "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
+ "C3DBA76456363A10869622EAC2DD84EC" \
+ "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
+
+ if( verbose != 0 )
+ printf( " MPI test #4 (inv_mod): " );
+
+ if( mpi_cmp_mpi( &X, &U ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+ if( verbose != 0 )
+ printf( " MPI test #5 (simple gcd): " );
+
+ for ( i = 0; i < GCD_PAIR_COUNT; i++)
+ {
+ MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
+ MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
+
+ MPI_CHK( mpi_gcd( &A, &X, &Y ) );
+
+ if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed at %d\n", i );
+
+ return( 1 );
+ }
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+
+cleanup:
+
+ if( ret != 0 && verbose != 0 )
+ printf( "Unexpected error, return code = %08X\n", ret );
+
+ mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL );
+
+ if( verbose != 0 )
+ printf( "\n" );
+
+ return( ret );
+}
+
+#endif
+
+#endif
diff --git a/package/utils/px5g-standalone/src/library/rsa.c b/package/utils/px5g-standalone/src/library/rsa.c
new file mode 100644
index 0000000..131b6c6
--- /dev/null
+++ b/package/utils/px5g-standalone/src/library/rsa.c
@@ -0,0 +1,750 @@
+/*
+ * The RSA public-key cryptosystem
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * RSA was designed by Ron Rivest, Adi Shamir and Len Adleman.
+ *
+ * http://theory.lcs.mit.edu/~rivest/rsapaper.pdf
+ * http://www.cacr.math.uwaterloo.ca/hac/about/chap8.pdf
+ */
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_RSA_C)
+
+#include "polarssl/rsa.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+/*
+ * Initialize an RSA context
+ */
+void rsa_init( rsa_context *ctx,
+ int padding,
+ int hash_id,
+ int (*f_rng)(void *),
+ void *p_rng )
+{
+ memset( ctx, 0, sizeof( rsa_context ) );
+
+ ctx->padding = padding;
+ ctx->hash_id = hash_id;
+
+ ctx->f_rng = f_rng;
+ ctx->p_rng = p_rng;
+}
+
+#if defined(POLARSSL_GENPRIME)
+
+/*
+ * Generate an RSA keypair
+ */
+int rsa_gen_key( rsa_context *ctx, int nbits, int exponent )
+{
+ int ret;
+ mpi P1, Q1, H, G;
+
+ if( ctx->f_rng == NULL || nbits < 128 || exponent < 3 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ mpi_init( &P1, &Q1, &H, &G, NULL );
+
+ /*
+ * find primes P and Q with Q < P so that:
+ * GCD( E, (P-1)*(Q-1) ) == 1
+ */
+ MPI_CHK( mpi_lset( &ctx->E, exponent ) );
+
+ do
+ {
+ MPI_CHK( mpi_gen_prime( &ctx->P, ( nbits + 1 ) >> 1, 0,
+ ctx->f_rng, ctx->p_rng ) );
+
+ MPI_CHK( mpi_gen_prime( &ctx->Q, ( nbits + 1 ) >> 1, 0,
+ ctx->f_rng, ctx->p_rng ) );
+
+ if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) < 0 )
+ mpi_swap( &ctx->P, &ctx->Q );
+
+ if( mpi_cmp_mpi( &ctx->P, &ctx->Q ) == 0 )
+ continue;
+
+ MPI_CHK( mpi_mul_mpi( &ctx->N, &ctx->P, &ctx->Q ) );
+ if( mpi_msb( &ctx->N ) != nbits )
+ continue;
+
+ MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
+ MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
+ MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
+ MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
+ }
+ while( mpi_cmp_int( &G, 1 ) != 0 );
+
+ /*
+ * D = E^-1 mod ((P-1)*(Q-1))
+ * DP = D mod (P - 1)
+ * DQ = D mod (Q - 1)
+ * QP = Q^-1 mod P
+ */
+ MPI_CHK( mpi_inv_mod( &ctx->D , &ctx->E, &H ) );
+ MPI_CHK( mpi_mod_mpi( &ctx->DP, &ctx->D, &P1 ) );
+ MPI_CHK( mpi_mod_mpi( &ctx->DQ, &ctx->D, &Q1 ) );
+ MPI_CHK( mpi_inv_mod( &ctx->QP, &ctx->Q, &ctx->P ) );
+
+ ctx->len = ( mpi_msb( &ctx->N ) + 7 ) >> 3;
+
+cleanup:
+
+ mpi_free( &G, &H, &Q1, &P1, NULL );
+
+ if( ret != 0 )
+ {
+ rsa_free( ctx );
+ return( POLARSSL_ERR_RSA_KEY_GEN_FAILED | ret );
+ }
+
+ return( 0 );
+}
+
+#endif
+
+/*
+ * Check a public RSA key
+ */
+int rsa_check_pubkey( rsa_context *ctx )
+{
+ if( ( ctx->N.p[0] & 1 ) == 0 ||
+ ( ctx->E.p[0] & 1 ) == 0 )
+ return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+ if( mpi_msb( &ctx->N ) < 128 ||
+ mpi_msb( &ctx->N ) > 4096 )
+ return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+ if( mpi_msb( &ctx->E ) < 2 ||
+ mpi_msb( &ctx->E ) > 64 )
+ return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED );
+
+ return( 0 );
+}
+
+/*
+ * Check a private RSA key
+ */
+int rsa_check_privkey( rsa_context *ctx )
+{
+ int ret;
+ mpi PQ, DE, P1, Q1, H, I, G;
+
+ if( ( ret = rsa_check_pubkey( ctx ) ) != 0 )
+ return( ret );
+
+ mpi_init( &PQ, &DE, &P1, &Q1, &H, &I, &G, NULL );
+
+ MPI_CHK( mpi_mul_mpi( &PQ, &ctx->P, &ctx->Q ) );
+ MPI_CHK( mpi_mul_mpi( &DE, &ctx->D, &ctx->E ) );
+ MPI_CHK( mpi_sub_int( &P1, &ctx->P, 1 ) );
+ MPI_CHK( mpi_sub_int( &Q1, &ctx->Q, 1 ) );
+ MPI_CHK( mpi_mul_mpi( &H, &P1, &Q1 ) );
+ MPI_CHK( mpi_mod_mpi( &I, &DE, &H ) );
+ MPI_CHK( mpi_gcd( &G, &ctx->E, &H ) );
+
+ if( mpi_cmp_mpi( &PQ, &ctx->N ) == 0 &&
+ mpi_cmp_int( &I, 1 ) == 0 &&
+ mpi_cmp_int( &G, 1 ) == 0 )
+ {
+ mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
+ return( 0 );
+ }
+
+cleanup:
+
+ mpi_free( &G, &I, &H, &Q1, &P1, &DE, &PQ, NULL );
+ return( POLARSSL_ERR_RSA_KEY_CHECK_FAILED | ret );
+}
+
+/*
+ * Do an RSA public key operation
+ */
+int rsa_public( rsa_context *ctx,
+ unsigned char *input,
+ unsigned char *output )
+{
+ int ret, olen;
+ mpi T;
+
+ mpi_init( &T, NULL );
+
+ MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
+
+ if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+ {
+ mpi_free( &T, NULL );
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ olen = ctx->len;
+ MPI_CHK( mpi_exp_mod( &T, &T, &ctx->E, &ctx->N, &ctx->RN ) );
+ MPI_CHK( mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+
+ mpi_free( &T, NULL );
+
+ if( ret != 0 )
+ return( POLARSSL_ERR_RSA_PUBLIC_FAILED | ret );
+
+ return( 0 );
+}
+
+/*
+ * Do an RSA private key operation
+ */
+int rsa_private( rsa_context *ctx,
+ unsigned char *input,
+ unsigned char *output )
+{
+ int ret, olen;
+ mpi T, T1, T2;
+
+ mpi_init( &T, &T1, &T2, NULL );
+
+ MPI_CHK( mpi_read_binary( &T, input, ctx->len ) );
+
+ if( mpi_cmp_mpi( &T, &ctx->N ) >= 0 )
+ {
+ mpi_free( &T, NULL );
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+#if 0
+ MPI_CHK( mpi_exp_mod( &T, &T, &ctx->D, &ctx->N, &ctx->RN ) );
+#else
+ /*
+ * faster decryption using the CRT
+ *
+ * T1 = input ^ dP mod P
+ * T2 = input ^ dQ mod Q
+ */
+ MPI_CHK( mpi_exp_mod( &T1, &T, &ctx->DP, &ctx->P, &ctx->RP ) );
+ MPI_CHK( mpi_exp_mod( &T2, &T, &ctx->DQ, &ctx->Q, &ctx->RQ ) );
+
+ /*
+ * T = (T1 - T2) * (Q^-1 mod P) mod P
+ */
+ MPI_CHK( mpi_sub_mpi( &T, &T1, &T2 ) );
+ MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->QP ) );
+ MPI_CHK( mpi_mod_mpi( &T, &T1, &ctx->P ) );
+
+ /*
+ * output = T2 + T * Q
+ */
+ MPI_CHK( mpi_mul_mpi( &T1, &T, &ctx->Q ) );
+ MPI_CHK( mpi_add_mpi( &T, &T2, &T1 ) );
+#endif
+
+ olen = ctx->len;
+ MPI_CHK( mpi_write_binary( &T, output, olen ) );
+
+cleanup:
+
+ mpi_free( &T, &T1, &T2, NULL );
+
+ if( ret != 0 )
+ return( POLARSSL_ERR_RSA_PRIVATE_FAILED | ret );
+
+ return( 0 );
+}
+
+/*
+ * Add the message padding, then do an RSA operation
+ */
+int rsa_pkcs1_encrypt( rsa_context *ctx,
+ int mode, int ilen,
+ unsigned char *input,
+ unsigned char *output )
+{
+ int nb_pad, olen;
+ unsigned char *p = output;
+
+ olen = ctx->len;
+
+ switch( ctx->padding )
+ {
+ case RSA_PKCS_V15:
+
+ if( ilen < 0 || olen < ilen + 11 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ nb_pad = olen - 3 - ilen;
+
+ *p++ = 0;
+ *p++ = RSA_CRYPT;
+
+ while( nb_pad-- > 0 )
+ {
+ do {
+ *p = (unsigned char) rand();
+ } while( *p == 0 );
+ p++;
+ }
+ *p++ = 0;
+ memcpy( p, input, ilen );
+ break;
+
+ default:
+
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
+
+ return( ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, output, output )
+ : rsa_private( ctx, output, output ) );
+}
+
+/*
+ * Do an RSA operation, then remove the message padding
+ */
+int rsa_pkcs1_decrypt( rsa_context *ctx,
+ int mode, int *olen,
+ unsigned char *input,
+ unsigned char *output,
+ int output_max_len)
+{
+ int ret, ilen;
+ unsigned char *p;
+ unsigned char buf[512];
+
+ ilen = ctx->len;
+
+ if( ilen < 16 || ilen > (int) sizeof( buf ) )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ ret = ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, input, buf )
+ : rsa_private( ctx, input, buf );
+
+ if( ret != 0 )
+ return( ret );
+
+ p = buf;
+
+ switch( ctx->padding )
+ {
+ case RSA_PKCS_V15:
+
+ if( *p++ != 0 || *p++ != RSA_CRYPT )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+ while( *p != 0 )
+ {
+ if( p >= buf + ilen - 1 )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ p++;
+ }
+ p++;
+ break;
+
+ default:
+
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
+
+ if (ilen - (int)(p - buf) > output_max_len)
+ return( POLARSSL_ERR_RSA_OUTPUT_TO_LARGE );
+
+ *olen = ilen - (int)(p - buf);
+ memcpy( output, p, *olen );
+
+ return( 0 );
+}
+
+/*
+ * Do an RSA operation to sign the message digest
+ */
+int rsa_pkcs1_sign( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ unsigned char *hash,
+ unsigned char *sig )
+{
+ int nb_pad, olen;
+ unsigned char *p = sig;
+
+ olen = ctx->len;
+
+ switch( ctx->padding )
+ {
+ case RSA_PKCS_V15:
+
+ switch( hash_id )
+ {
+ case RSA_RAW:
+ nb_pad = olen - 3 - hashlen;
+ break;
+
+ case RSA_MD2:
+ case RSA_MD4:
+ case RSA_MD5:
+ nb_pad = olen - 3 - 34;
+ break;
+
+ case RSA_SHA1:
+ nb_pad = olen - 3 - 35;
+ break;
+
+ default:
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ if( nb_pad < 8 )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ *p++ = 0;
+ *p++ = RSA_SIGN;
+ memset( p, 0xFF, nb_pad );
+ p += nb_pad;
+ *p++ = 0;
+ break;
+
+ default:
+
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
+
+ switch( hash_id )
+ {
+ case RSA_RAW:
+ memcpy( p, hash, hashlen );
+ break;
+
+ case RSA_MD2:
+ memcpy( p, ASN1_HASH_MDX, 18 );
+ memcpy( p + 18, hash, 16 );
+ p[13] = 2; break;
+
+ case RSA_MD4:
+ memcpy( p, ASN1_HASH_MDX, 18 );
+ memcpy( p + 18, hash, 16 );
+ p[13] = 4; break;
+
+ case RSA_MD5:
+ memcpy( p, ASN1_HASH_MDX, 18 );
+ memcpy( p + 18, hash, 16 );
+ p[13] = 5; break;
+
+ case RSA_SHA1:
+ memcpy( p, ASN1_HASH_SHA1, 15 );
+ memcpy( p + 15, hash, 20 );
+ break;
+
+ default:
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+ }
+
+ return( ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, sig, sig )
+ : rsa_private( ctx, sig, sig ) );
+}
+
+/*
+ * Do an RSA operation and check the message digest
+ */
+int rsa_pkcs1_verify( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ unsigned char *hash,
+ unsigned char *sig )
+{
+ int ret, len, siglen;
+ unsigned char *p, c;
+ unsigned char buf[512];
+
+ siglen = ctx->len;
+
+ if( siglen < 16 || siglen > (int) sizeof( buf ) )
+ return( POLARSSL_ERR_RSA_BAD_INPUT_DATA );
+
+ ret = ( mode == RSA_PUBLIC )
+ ? rsa_public( ctx, sig, buf )
+ : rsa_private( ctx, sig, buf );
+
+ if( ret != 0 )
+ return( ret );
+
+ p = buf;
+
+ switch( ctx->padding )
+ {
+ case RSA_PKCS_V15:
+
+ if( *p++ != 0 || *p++ != RSA_SIGN )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+
+ while( *p != 0 )
+ {
+ if( p >= buf + siglen - 1 || *p != 0xFF )
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ p++;
+ }
+ p++;
+ break;
+
+ default:
+
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+ }
+
+ len = siglen - (int)( p - buf );
+
+ if( len == 34 )
+ {
+ c = p[13];
+ p[13] = 0;
+
+ if( memcmp( p, ASN1_HASH_MDX, 18 ) != 0 )
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+
+ if( ( c == 2 && hash_id == RSA_MD2 ) ||
+ ( c == 4 && hash_id == RSA_MD4 ) ||
+ ( c == 5 && hash_id == RSA_MD5 ) )
+ {
+ if( memcmp( p + 18, hash, 16 ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+ }
+ }
+
+ if( len == 35 && hash_id == RSA_SHA1 )
+ {
+ if( memcmp( p, ASN1_HASH_SHA1, 15 ) == 0 &&
+ memcmp( p + 15, hash, 20 ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+ }
+
+ if( len == hashlen && hash_id == RSA_RAW )
+ {
+ if( memcmp( p, hash, hashlen ) == 0 )
+ return( 0 );
+ else
+ return( POLARSSL_ERR_RSA_VERIFY_FAILED );
+ }
+
+ return( POLARSSL_ERR_RSA_INVALID_PADDING );
+}
+
+/*
+ * Free the components of an RSA key
+ */
+void rsa_free( rsa_context *ctx )
+{
+ mpi_free( &ctx->RQ, &ctx->RP, &ctx->RN,
+ &ctx->QP, &ctx->DQ, &ctx->DP,
+ &ctx->Q, &ctx->P, &ctx->D,
+ &ctx->E, &ctx->N, NULL );
+}
+
+#if defined(POLARSSL_SELF_TEST)
+
+#include "polarssl/sha1.h"
+
+/*
+ * Example RSA-1024 keypair, for test purposes
+ */
+#define KEY_LEN 128
+
+#define RSA_N "9292758453063D803DD603D5E777D788" \
+ "8ED1D5BF35786190FA2F23EBC0848AEA" \
+ "DDA92CA6C3D80B32C4D109BE0F36D6AE" \
+ "7130B9CED7ACDF54CFC7555AC14EEBAB" \
+ "93A89813FBF3C4F8066D2D800F7C38A8" \
+ "1AE31942917403FF4946B0A83D3D3E05" \
+ "EE57C6F5F5606FB5D4BC6CD34EE0801A" \
+ "5E94BB77B07507233A0BC7BAC8F90F79"
+
+#define RSA_E "10001"
+
+#define RSA_D "24BF6185468786FDD303083D25E64EFC" \
+ "66CA472BC44D253102F8B4A9D3BFA750" \
+ "91386C0077937FE33FA3252D28855837" \
+ "AE1B484A8A9A45F7EE8C0C634F99E8CD" \
+ "DF79C5CE07EE72C7F123142198164234" \
+ "CABB724CF78B8173B9F880FC86322407" \
+ "AF1FEDFDDE2BEB674CA15F3E81A1521E" \
+ "071513A1E85B5DFA031F21ECAE91A34D"
+
+#define RSA_P "C36D0EB7FCD285223CFB5AABA5BDA3D8" \
+ "2C01CAD19EA484A87EA4377637E75500" \
+ "FCB2005C5C7DD6EC4AC023CDA285D796" \
+ "C3D9E75E1EFC42488BB4F1D13AC30A57"
+
+#define RSA_Q "C000DF51A7C77AE8D7C7370C1FF55B69" \
+ "E211C2B9E5DB1ED0BF61D0D9899620F4" \
+ "910E4168387E3C30AA1E00C339A79508" \
+ "8452DD96A9A5EA5D9DCA68DA636032AF"
+
+#define RSA_DP "C1ACF567564274FB07A0BBAD5D26E298" \
+ "3C94D22288ACD763FD8E5600ED4A702D" \
+ "F84198A5F06C2E72236AE490C93F07F8" \
+ "3CC559CD27BC2D1CA488811730BB5725"
+
+#define RSA_DQ "4959CBF6F8FEF750AEE6977C155579C7" \
+ "D8AAEA56749EA28623272E4F7D0592AF" \
+ "7C1F1313CAC9471B5C523BFE592F517B" \
+ "407A1BD76C164B93DA2D32A383E58357"
+
+#define RSA_QP "9AE7FBC99546432DF71896FC239EADAE" \
+ "F38D18D2B2F0E2DD275AA977E2BF4411" \
+ "F5A3B2A5D33605AEBBCCBA7FEB9F2D2F" \
+ "A74206CEC169D74BF5A8C50D6F48EA08"
+
+#define PT_LEN 24
+#define RSA_PT "\xAA\xBB\xCC\x03\x02\x01\x00\xFF\xFF\xFF\xFF\xFF" \
+ "\x11\x22\x33\x0A\x0B\x0C\xCC\xDD\xDD\xDD\xDD\xDD"
+
+/*
+ * Checkup routine
+ */
+int rsa_self_test( int verbose )
+{
+ int len;
+ rsa_context rsa;
+ unsigned char sha1sum[20];
+ unsigned char rsa_plaintext[PT_LEN];
+ unsigned char rsa_decrypted[PT_LEN];
+ unsigned char rsa_ciphertext[KEY_LEN];
+
+ memset( &rsa, 0, sizeof( rsa_context ) );
+
+ rsa.len = KEY_LEN;
+ mpi_read_string( &rsa.N , 16, RSA_N );
+ mpi_read_string( &rsa.E , 16, RSA_E );
+ mpi_read_string( &rsa.D , 16, RSA_D );
+ mpi_read_string( &rsa.P , 16, RSA_P );
+ mpi_read_string( &rsa.Q , 16, RSA_Q );
+ mpi_read_string( &rsa.DP, 16, RSA_DP );
+ mpi_read_string( &rsa.DQ, 16, RSA_DQ );
+ mpi_read_string( &rsa.QP, 16, RSA_QP );
+
+ if( verbose != 0 )
+ printf( " RSA key validation: " );
+
+ if( rsa_check_pubkey( &rsa ) != 0 ||
+ rsa_check_privkey( &rsa ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n PKCS#1 encryption : " );
+
+ memcpy( rsa_plaintext, RSA_PT, PT_LEN );
+
+ if( rsa_pkcs1_encrypt( &rsa, RSA_PUBLIC, PT_LEN,
+ rsa_plaintext, rsa_ciphertext ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n PKCS#1 decryption : " );
+
+ if( rsa_pkcs1_decrypt( &rsa, RSA_PRIVATE, &len,
+ rsa_ciphertext, rsa_decrypted,
+ sizeof(rsa_decrypted) ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( memcmp( rsa_decrypted, rsa_plaintext, len ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n PKCS#1 data sign : " );
+
+ sha1( rsa_plaintext, PT_LEN, sha1sum );
+
+ if( rsa_pkcs1_sign( &rsa, RSA_PRIVATE, RSA_SHA1, 20,
+ sha1sum, rsa_ciphertext ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n PKCS#1 sig. verify: " );
+
+ if( rsa_pkcs1_verify( &rsa, RSA_PUBLIC, RSA_SHA1, 20,
+ sha1sum, rsa_ciphertext ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n\n" );
+
+ rsa_free( &rsa );
+
+ return( 0 );
+}
+
+#endif
+
+#endif
diff --git a/package/utils/px5g-standalone/src/library/sha1.c b/package/utils/px5g-standalone/src/library/sha1.c
new file mode 100644
index 0000000..54a4416
--- /dev/null
+++ b/package/utils/px5g-standalone/src/library/sha1.c
@@ -0,0 +1,622 @@
+/*
+ * FIPS-180-1 compliant SHA-1 implementation
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * The SHA-1 standard was published by NIST in 1993.
+ *
+ * http://www.itl.nist.gov/fipspubs/fip180-1.htm
+ */
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_SHA1_C)
+
+#include "polarssl/sha1.h"
+
+#include <string.h>
+#include <stdio.h>
+
+/*
+ * 32-bit integer manipulation macros (big endian)
+ */
+#ifndef GET_ULONG_BE
+#define GET_ULONG_BE(n,b,i) \
+{ \
+ (n) = ( (unsigned long) (b)[(i) ] << 24 ) \
+ | ( (unsigned long) (b)[(i) + 1] << 16 ) \
+ | ( (unsigned long) (b)[(i) + 2] << 8 ) \
+ | ( (unsigned long) (b)[(i) + 3] ); \
+}
+#endif
+
+#ifndef PUT_ULONG_BE
+#define PUT_ULONG_BE(n,b,i) \
+{ \
+ (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \
+ (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \
+ (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \
+ (b)[(i) + 3] = (unsigned char) ( (n) ); \
+}
+#endif
+
+/*
+ * SHA-1 context setup
+ */
+void sha1_starts( sha1_context *ctx )
+{
+ ctx->total[0] = 0;
+ ctx->total[1] = 0;
+
+ ctx->state[0] = 0x67452301;
+ ctx->state[1] = 0xEFCDAB89;
+ ctx->state[2] = 0x98BADCFE;
+ ctx->state[3] = 0x10325476;
+ ctx->state[4] = 0xC3D2E1F0;
+}
+
+static void sha1_process( sha1_context *ctx, unsigned char data[64] )
+{
+ unsigned long temp, W[16], A, B, C, D, E;
+
+ GET_ULONG_BE( W[ 0], data, 0 );
+ GET_ULONG_BE( W[ 1], data, 4 );
+ GET_ULONG_BE( W[ 2], data, 8 );
+ GET_ULONG_BE( W[ 3], data, 12 );
+ GET_ULONG_BE( W[ 4], data, 16 );
+ GET_ULONG_BE( W[ 5], data, 20 );
+ GET_ULONG_BE( W[ 6], data, 24 );
+ GET_ULONG_BE( W[ 7], data, 28 );
+ GET_ULONG_BE( W[ 8], data, 32 );
+ GET_ULONG_BE( W[ 9], data, 36 );
+ GET_ULONG_BE( W[10], data, 40 );
+ GET_ULONG_BE( W[11], data, 44 );
+ GET_ULONG_BE( W[12], data, 48 );
+ GET_ULONG_BE( W[13], data, 52 );
+ GET_ULONG_BE( W[14], data, 56 );
+ GET_ULONG_BE( W[15], data, 60 );
+
+#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))
+
+#define R(t) \
+( \
+ temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \
+ W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \
+ ( W[t & 0x0F] = S(temp,1) ) \
+)
+
+#define P(a,b,c,d,e,x) \
+{ \
+ e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \
+}
+
+ A = ctx->state[0];
+ B = ctx->state[1];
+ C = ctx->state[2];
+ D = ctx->state[3];
+ E = ctx->state[4];
+
+#define F(x,y,z) (z ^ (x & (y ^ z)))
+#define K 0x5A827999
+
+ P( A, B, C, D, E, W[0] );
+ P( E, A, B, C, D, W[1] );
+ P( D, E, A, B, C, W[2] );
+ P( C, D, E, A, B, W[3] );
+ P( B, C, D, E, A, W[4] );
+ P( A, B, C, D, E, W[5] );
+ P( E, A, B, C, D, W[6] );
+ P( D, E, A, B, C, W[7] );
+ P( C, D, E, A, B, W[8] );
+ P( B, C, D, E, A, W[9] );
+ P( A, B, C, D, E, W[10] );
+ P( E, A, B, C, D, W[11] );
+ P( D, E, A, B, C, W[12] );
+ P( C, D, E, A, B, W[13] );
+ P( B, C, D, E, A, W[14] );
+ P( A, B, C, D, E, W[15] );
+ P( E, A, B, C, D, R(16) );
+ P( D, E, A, B, C, R(17) );
+ P( C, D, E, A, B, R(18) );
+ P( B, C, D, E, A, R(19) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0x6ED9EBA1
+
+ P( A, B, C, D, E, R(20) );
+ P( E, A, B, C, D, R(21) );
+ P( D, E, A, B, C, R(22) );
+ P( C, D, E, A, B, R(23) );
+ P( B, C, D, E, A, R(24) );
+ P( A, B, C, D, E, R(25) );
+ P( E, A, B, C, D, R(26) );
+ P( D, E, A, B, C, R(27) );
+ P( C, D, E, A, B, R(28) );
+ P( B, C, D, E, A, R(29) );
+ P( A, B, C, D, E, R(30) );
+ P( E, A, B, C, D, R(31) );
+ P( D, E, A, B, C, R(32) );
+ P( C, D, E, A, B, R(33) );
+ P( B, C, D, E, A, R(34) );
+ P( A, B, C, D, E, R(35) );
+ P( E, A, B, C, D, R(36) );
+ P( D, E, A, B, C, R(37) );
+ P( C, D, E, A, B, R(38) );
+ P( B, C, D, E, A, R(39) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) ((x & y) | (z & (x | y)))
+#define K 0x8F1BBCDC
+
+ P( A, B, C, D, E, R(40) );
+ P( E, A, B, C, D, R(41) );
+ P( D, E, A, B, C, R(42) );
+ P( C, D, E, A, B, R(43) );
+ P( B, C, D, E, A, R(44) );
+ P( A, B, C, D, E, R(45) );
+ P( E, A, B, C, D, R(46) );
+ P( D, E, A, B, C, R(47) );
+ P( C, D, E, A, B, R(48) );
+ P( B, C, D, E, A, R(49) );
+ P( A, B, C, D, E, R(50) );
+ P( E, A, B, C, D, R(51) );
+ P( D, E, A, B, C, R(52) );
+ P( C, D, E, A, B, R(53) );
+ P( B, C, D, E, A, R(54) );
+ P( A, B, C, D, E, R(55) );
+ P( E, A, B, C, D, R(56) );
+ P( D, E, A, B, C, R(57) );
+ P( C, D, E, A, B, R(58) );
+ P( B, C, D, E, A, R(59) );
+
+#undef K
+#undef F
+
+#define F(x,y,z) (x ^ y ^ z)
+#define K 0xCA62C1D6
+
+ P( A, B, C, D, E, R(60) );
+ P( E, A, B, C, D, R(61) );
+ P( D, E, A, B, C, R(62) );
+ P( C, D, E, A, B, R(63) );
+ P( B, C, D, E, A, R(64) );
+ P( A, B, C, D, E, R(65) );
+ P( E, A, B, C, D, R(66) );
+ P( D, E, A, B, C, R(67) );
+ P( C, D, E, A, B, R(68) );
+ P( B, C, D, E, A, R(69) );
+ P( A, B, C, D, E, R(70) );
+ P( E, A, B, C, D, R(71) );
+ P( D, E, A, B, C, R(72) );
+ P( C, D, E, A, B, R(73) );
+ P( B, C, D, E, A, R(74) );
+ P( A, B, C, D, E, R(75) );
+ P( E, A, B, C, D, R(76) );
+ P( D, E, A, B, C, R(77) );
+ P( C, D, E, A, B, R(78) );
+ P( B, C, D, E, A, R(79) );
+
+#undef K
+#undef F
+
+ ctx->state[0] += A;
+ ctx->state[1] += B;
+ ctx->state[2] += C;
+ ctx->state[3] += D;
+ ctx->state[4] += E;
+}
+
+/*
+ * SHA-1 process buffer
+ */
+void sha1_update( sha1_context *ctx, unsigned char *input, int ilen )
+{
+ int fill;
+ unsigned long left;
+
+ if( ilen <= 0 )
+ return;
+
+ left = ctx->total[0] & 0x3F;
+ fill = 64 - left;
+
+ ctx->total[0] += ilen;
+ ctx->total[0] &= 0xFFFFFFFF;
+
+ if( ctx->total[0] < (unsigned long) ilen )
+ ctx->total[1]++;
+
+ if( left && ilen >= fill )
+ {
+ memcpy( (void *) (ctx->buffer + left),
+ (void *) input, fill );
+ sha1_process( ctx, ctx->buffer );
+ input += fill;
+ ilen -= fill;
+ left = 0;
+ }
+
+ while( ilen >= 64 )
+ {
+ sha1_process( ctx, input );
+ input += 64;
+ ilen -= 64;
+ }
+
+ if( ilen > 0 )
+ {
+ memcpy( (void *) (ctx->buffer + left),
+ (void *) input, ilen );
+ }
+}
+
+static const unsigned char sha1_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/*
+ * SHA-1 final digest
+ */
+void sha1_finish( sha1_context *ctx, unsigned char output[20] )
+{
+ unsigned long last, padn;
+ unsigned long high, low;
+ unsigned char msglen[8];
+
+ high = ( ctx->total[0] >> 29 )
+ | ( ctx->total[1] << 3 );
+ low = ( ctx->total[0] << 3 );
+
+ PUT_ULONG_BE( high, msglen, 0 );
+ PUT_ULONG_BE( low, msglen, 4 );
+
+ last = ctx->total[0] & 0x3F;
+ padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );
+
+ sha1_update( ctx, (unsigned char *) sha1_padding, padn );
+ sha1_update( ctx, msglen, 8 );
+
+ PUT_ULONG_BE( ctx->state[0], output, 0 );
+ PUT_ULONG_BE( ctx->state[1], output, 4 );
+ PUT_ULONG_BE( ctx->state[2], output, 8 );
+ PUT_ULONG_BE( ctx->state[3], output, 12 );
+ PUT_ULONG_BE( ctx->state[4], output, 16 );
+}
+
+/*
+ * output = SHA-1( input buffer )
+ */
+void sha1( unsigned char *input, int ilen, unsigned char output[20] )
+{
+ sha1_context ctx;
+
+ sha1_starts( &ctx );
+ sha1_update( &ctx, input, ilen );
+ sha1_finish( &ctx, output );
+
+ memset( &ctx, 0, sizeof( sha1_context ) );
+}
+
+/*
+ * output = SHA-1( file contents )
+ */
+int sha1_file( char *path, unsigned char output[20] )
+{
+ FILE *f;
+ size_t n;
+ sha1_context ctx;
+ unsigned char buf[1024];
+
+ if( ( f = fopen( path, "rb" ) ) == NULL )
+ return( 1 );
+
+ sha1_starts( &ctx );
+
+ while( ( n = fread( buf, 1, sizeof( buf ), f ) ) > 0 )
+ sha1_update( &ctx, buf, (int) n );
+
+ sha1_finish( &ctx, output );
+
+ memset( &ctx, 0, sizeof( sha1_context ) );
+
+ if( ferror( f ) != 0 )
+ {
+ fclose( f );
+ return( 2 );
+ }
+
+ fclose( f );
+ return( 0 );
+}
+
+/*
+ * SHA-1 HMAC context setup
+ */
+void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen )
+{
+ int i;
+ unsigned char sum[20];
+
+ if( keylen > 64 )
+ {
+ sha1( key, keylen, sum );
+ keylen = 20;
+ key = sum;
+ }
+
+ memset( ctx->ipad, 0x36, 64 );
+ memset( ctx->opad, 0x5C, 64 );
+
+ for( i = 0; i < keylen; i++ )
+ {
+ ctx->ipad[i] = (unsigned char)( ctx->ipad[i] ^ key[i] );
+ ctx->opad[i] = (unsigned char)( ctx->opad[i] ^ key[i] );
+ }
+
+ sha1_starts( ctx );
+ sha1_update( ctx, ctx->ipad, 64 );
+
+ memset( sum, 0, sizeof( sum ) );
+}
+
+/*
+ * SHA-1 HMAC process buffer
+ */
+void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen )
+{
+ sha1_update( ctx, input, ilen );
+}
+
+/*
+ * SHA-1 HMAC final digest
+ */
+void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] )
+{
+ unsigned char tmpbuf[20];
+
+ sha1_finish( ctx, tmpbuf );
+ sha1_starts( ctx );
+ sha1_update( ctx, ctx->opad, 64 );
+ sha1_update( ctx, tmpbuf, 20 );
+ sha1_finish( ctx, output );
+
+ memset( tmpbuf, 0, sizeof( tmpbuf ) );
+}
+
+/*
+ * output = HMAC-SHA-1( hmac key, input buffer )
+ */
+void sha1_hmac( unsigned char *key, int keylen,
+ unsigned char *input, int ilen,
+ unsigned char output[20] )
+{
+ sha1_context ctx;
+
+ sha1_hmac_starts( &ctx, key, keylen );
+ sha1_hmac_update( &ctx, input, ilen );
+ sha1_hmac_finish( &ctx, output );
+
+ memset( &ctx, 0, sizeof( sha1_context ) );
+}
+
+#if defined(POLARSSL_SELF_TEST)
+/*
+ * FIPS-180-1 test vectors
+ */
+static unsigned char sha1_test_buf[3][57] =
+{
+ { "abc" },
+ { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
+ { "" }
+};
+
+static const int sha1_test_buflen[3] =
+{
+ 3, 56, 1000
+};
+
+static const unsigned char sha1_test_sum[3][20] =
+{
+ { 0xA9, 0x99, 0x3E, 0x36, 0x47, 0x06, 0x81, 0x6A, 0xBA, 0x3E,
+ 0x25, 0x71, 0x78, 0x50, 0xC2, 0x6C, 0x9C, 0xD0, 0xD8, 0x9D },
+ { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E, 0xBA, 0xAE,
+ 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5, 0xE5, 0x46, 0x70, 0xF1 },
+ { 0x34, 0xAA, 0x97, 0x3C, 0xD4, 0xC4, 0xDA, 0xA4, 0xF6, 0x1E,
+ 0xEB, 0x2B, 0xDB, 0xAD, 0x27, 0x31, 0x65, 0x34, 0x01, 0x6F }
+};
+
+/*
+ * RFC 2202 test vectors
+ */
+static unsigned char sha1_hmac_test_key[7][26] =
+{
+ { "\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B\x0B"
+ "\x0B\x0B\x0B\x0B" },
+ { "Jefe" },
+ { "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA"
+ "\xAA\xAA\xAA\xAA" },
+ { "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10"
+ "\x11\x12\x13\x14\x15\x16\x17\x18\x19" },
+ { "\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x0C"
+ "\x0C\x0C\x0C\x0C" },
+ { "" }, /* 0xAA 80 times */
+ { "" }
+};
+
+static const int sha1_hmac_test_keylen[7] =
+{
+ 20, 4, 20, 25, 20, 80, 80
+};
+
+static unsigned char sha1_hmac_test_buf[7][74] =
+{
+ { "Hi There" },
+ { "what do ya want for nothing?" },
+ { "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD"
+ "\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD\xDD" },
+ { "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD"
+ "\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD\xCD" },
+ { "Test With Truncation" },
+ { "Test Using Larger Than Block-Size Key - Hash Key First" },
+ { "Test Using Larger Than Block-Size Key and Larger"
+ " Than One Block-Size Data" }
+};
+
+static const int sha1_hmac_test_buflen[7] =
+{
+ 8, 28, 50, 50, 20, 54, 73
+};
+
+static const unsigned char sha1_hmac_test_sum[7][20] =
+{
+ { 0xB6, 0x17, 0x31, 0x86, 0x55, 0x05, 0x72, 0x64, 0xE2, 0x8B,
+ 0xC0, 0xB6, 0xFB, 0x37, 0x8C, 0x8E, 0xF1, 0x46, 0xBE, 0x00 },
+ { 0xEF, 0xFC, 0xDF, 0x6A, 0xE5, 0xEB, 0x2F, 0xA2, 0xD2, 0x74,
+ 0x16, 0xD5, 0xF1, 0x84, 0xDF, 0x9C, 0x25, 0x9A, 0x7C, 0x79 },
+ { 0x12, 0x5D, 0x73, 0x42, 0xB9, 0xAC, 0x11, 0xCD, 0x91, 0xA3,
+ 0x9A, 0xF4, 0x8A, 0xA1, 0x7B, 0x4F, 0x63, 0xF1, 0x75, 0xD3 },
+ { 0x4C, 0x90, 0x07, 0xF4, 0x02, 0x62, 0x50, 0xC6, 0xBC, 0x84,
+ 0x14, 0xF9, 0xBF, 0x50, 0xC8, 0x6C, 0x2D, 0x72, 0x35, 0xDA },
+ { 0x4C, 0x1A, 0x03, 0x42, 0x4B, 0x55, 0xE0, 0x7F, 0xE7, 0xF2,
+ 0x7B, 0xE1 },
+ { 0xAA, 0x4A, 0xE5, 0xE1, 0x52, 0x72, 0xD0, 0x0E, 0x95, 0x70,
+ 0x56, 0x37, 0xCE, 0x8A, 0x3B, 0x55, 0xED, 0x40, 0x21, 0x12 },
+ { 0xE8, 0xE9, 0x9D, 0x0F, 0x45, 0x23, 0x7D, 0x78, 0x6D, 0x6B,
+ 0xBA, 0xA7, 0x96, 0x5C, 0x78, 0x08, 0xBB, 0xFF, 0x1A, 0x91 }
+};
+
+/*
+ * Checkup routine
+ */
+int sha1_self_test( int verbose )
+{
+ int i, j, buflen;
+ unsigned char buf[1024];
+ unsigned char sha1sum[20];
+ sha1_context ctx;
+
+ /*
+ * SHA-1
+ */
+ for( i = 0; i < 3; i++ )
+ {
+ if( verbose != 0 )
+ printf( " SHA-1 test #%d: ", i + 1 );
+
+ sha1_starts( &ctx );
+
+ if( i == 2 )
+ {
+ memset( buf, 'a', buflen = 1000 );
+
+ for( j = 0; j < 1000; j++ )
+ sha1_update( &ctx, buf, buflen );
+ }
+ else
+ sha1_update( &ctx, sha1_test_buf[i],
+ sha1_test_buflen[i] );
+
+ sha1_finish( &ctx, sha1sum );
+
+ if( memcmp( sha1sum, sha1_test_sum[i], 20 ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ printf( "\n" );
+
+ for( i = 0; i < 7; i++ )
+ {
+ if( verbose != 0 )
+ printf( " HMAC-SHA-1 test #%d: ", i + 1 );
+
+ if( i == 5 || i == 6 )
+ {
+ memset( buf, '\xAA', buflen = 80 );
+ sha1_hmac_starts( &ctx, buf, buflen );
+ }
+ else
+ sha1_hmac_starts( &ctx, sha1_hmac_test_key[i],
+ sha1_hmac_test_keylen[i] );
+
+ sha1_hmac_update( &ctx, sha1_hmac_test_buf[i],
+ sha1_hmac_test_buflen[i] );
+
+ sha1_hmac_finish( &ctx, sha1sum );
+
+ buflen = ( i == 4 ) ? 12 : 20;
+
+ if( memcmp( sha1sum, sha1_hmac_test_sum[i], buflen ) != 0 )
+ {
+ if( verbose != 0 )
+ printf( "failed\n" );
+
+ return( 1 );
+ }
+
+ if( verbose != 0 )
+ printf( "passed\n" );
+ }
+
+ if( verbose != 0 )
+ printf( "\n" );
+
+ return( 0 );
+}
+
+#endif
+
+#endif
diff --git a/package/utils/px5g-standalone/src/library/timing.c b/package/utils/px5g-standalone/src/library/timing.c
new file mode 100644
index 0000000..6b7ab74
--- /dev/null
+++ b/package/utils/px5g-standalone/src/library/timing.c
@@ -0,0 +1,265 @@
+/*
+ * Portable interface to the CPU cycle counter
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_TIMING_C)
+
+#include "polarssl/timing.h"
+
+#if defined(WIN32)
+
+#include <windows.h>
+#include <winbase.h>
+
+struct _hr_time
+{
+ LARGE_INTEGER start;
+};
+
+#else
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <time.h>
+
+struct _hr_time
+{
+ struct timeval start;
+};
+
+#endif
+
+#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
+
+unsigned long hardclock( void )
+{
+ unsigned long tsc;
+ __asm rdtsc
+ __asm mov [tsc], eax
+ return( tsc );
+}
+
+#else
+#if defined(__GNUC__) && defined(__i386__)
+
+unsigned long hardclock( void )
+{
+ unsigned long tsc;
+ asm( "rdtsc" : "=a" (tsc) );
+ return( tsc );
+}
+
+#else
+#if defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__))
+
+unsigned long hardclock( void )
+{
+ unsigned long lo, hi;
+ asm( "rdtsc" : "=a" (lo), "=d" (hi) );
+ return( lo | (hi << 32) );
+}
+
+#else
+#if defined(__GNUC__) && (defined(__powerpc__) || defined(__ppc__))
+
+unsigned long hardclock( void )
+{
+ unsigned long tbl, tbu0, tbu1;
+
+ do
+ {
+ asm( "mftbu %0" : "=r" (tbu0) );
+ asm( "mftb %0" : "=r" (tbl ) );
+ asm( "mftbu %0" : "=r" (tbu1) );
+ }
+ while( tbu0 != tbu1 );
+
+ return( tbl );
+}
+
+#else
+#if defined(__GNUC__) && defined(__sparc__)
+
+unsigned long hardclock( void )
+{
+ unsigned long tick;
+ asm( ".byte 0x83, 0x41, 0x00, 0x00" );
+ asm( "mov %%g1, %0" : "=r" (tick) );
+ return( tick );
+}
+
+#else
+#if defined(__GNUC__) && defined(__alpha__)
+
+unsigned long hardclock( void )
+{
+ unsigned long cc;
+ asm( "rpcc %0" : "=r" (cc) );
+ return( cc & 0xFFFFFFFF );
+}
+
+#else
+#if defined(__GNUC__) && defined(__ia64__)
+
+unsigned long hardclock( void )
+{
+ unsigned long itc;
+ asm( "mov %0 = ar.itc" : "=r" (itc) );
+ return( itc );
+}
+
+#else
+
+static int hardclock_init = 0;
+static struct timeval tv_init;
+
+unsigned long hardclock( void )
+{
+ struct timeval tv_cur;
+
+ if( hardclock_init == 0 )
+ {
+ gettimeofday( &tv_init, NULL );
+ hardclock_init = 1;
+ }
+
+ gettimeofday( &tv_cur, NULL );
+ return( ( tv_cur.tv_sec - tv_init.tv_sec ) * 1000000
+ + ( tv_cur.tv_usec - tv_init.tv_usec ) );
+}
+
+#endif /* generic */
+#endif /* IA-64 */
+#endif /* Alpha */
+#endif /* SPARC8 */
+#endif /* PowerPC */
+#endif /* AMD64 */
+#endif /* i586+ */
+
+int alarmed = 0;
+
+#if defined(WIN32)
+
+unsigned long get_timer( struct hr_time *val, int reset )
+{
+ unsigned long delta;
+ LARGE_INTEGER offset, hfreq;
+ struct _hr_time *t = (struct _hr_time *) val;
+
+ QueryPerformanceCounter( &offset );
+ QueryPerformanceFrequency( &hfreq );
+
+ delta = (unsigned long)( ( 1000 *
+ ( offset.QuadPart - t->start.QuadPart ) ) /
+ hfreq.QuadPart );
+
+ if( reset )
+ QueryPerformanceCounter( &t->start );
+
+ return( delta );
+}
+
+DWORD WINAPI TimerProc( LPVOID uElapse )
+{
+ Sleep( (DWORD) uElapse );
+ alarmed = 1;
+ return( TRUE );
+}
+
+void set_alarm( int seconds )
+{
+ DWORD ThreadId;
+
+ alarmed = 0;
+ CloseHandle( CreateThread( NULL, 0, TimerProc,
+ (LPVOID) ( seconds * 1000 ), 0, &ThreadId ) );
+}
+
+void m_sleep( int milliseconds )
+{
+ Sleep( milliseconds );
+}
+
+#else
+
+unsigned long get_timer( struct hr_time *val, int reset )
+{
+ unsigned long delta;
+ struct timeval offset;
+ struct _hr_time *t = (struct _hr_time *) val;
+
+ gettimeofday( &offset, NULL );
+
+ delta = ( offset.tv_sec - t->start.tv_sec ) * 1000
+ + ( offset.tv_usec - t->start.tv_usec ) / 1000;
+
+ if( reset )
+ {
+ t->start.tv_sec = offset.tv_sec;
+ t->start.tv_usec = offset.tv_usec;
+ }
+
+ return( delta );
+}
+
+static void sighandler( int signum )
+{
+ alarmed = 1;
+ signal( signum, sighandler );
+}
+
+void set_alarm( int seconds )
+{
+ alarmed = 0;
+ signal( SIGALRM, sighandler );
+ alarm( seconds );
+}
+
+void m_sleep( int milliseconds )
+{
+ struct timeval tv;
+
+ tv.tv_sec = milliseconds / 1000;
+ tv.tv_usec = milliseconds * 1000;
+
+ select( 0, NULL, NULL, NULL, &tv );
+}
+
+#endif
+
+#endif
diff --git a/package/utils/px5g-standalone/src/library/x509write.c b/package/utils/px5g-standalone/src/library/x509write.c
new file mode 100644
index 0000000..1091568
--- /dev/null
+++ b/package/utils/px5g-standalone/src/library/x509write.c
@@ -0,0 +1,1162 @@
+/*
+ * X.509 certificate and private key writing
+ *
+ * Copyright (C) 2006-2007 Pascal Vizeli <pvizeli@yahoo.de>
+ * Modifications (C) 2009 Steven Barth <steven@midlink.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+/*
+ * The ITU-T X.509 standard defines a certificat format for PKI.
+ *
+ * http://www.ietf.org/rfc/rfc2459.txt
+ * http://www.ietf.org/rfc/rfc3279.txt
+ *
+ * ftp://ftp.rsasecurity.com/pub/pkcs/ascii/pkcs-1v2.asc
+ *
+ * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
+ * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
+ *
+ * For CRS:
+ * http://www.faqs.org/rfcs/rfc2314.html
+ */
+#include "polarssl/config.h"
+#include "polarssl/x509.h"
+#include "polarssl/base64.h"
+#include "polarssl/sha1.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <time.h>
+
+#define and &&
+#define or ||
+
+#if defined _MSC_VER && !defined snprintf
+#define snprintf _snprintf
+#endif
+
+static int x509write_realloc_node(x509_node *node, size_t larger);
+static int x509write_file(x509_node *node, char *path, int format, const char* pem_prolog, const char* pem_epilog);
+
+/*
+ * evaluate how mani octet have this integer
+ */
+static int asn1_eval_octet(unsigned int digit)
+{
+ int i, byte;
+
+ for (byte = 4, i = 24; i >= 0; i -= 8, --byte)
+ if (((digit >> i) & 0xFF) != 0)
+ return byte;
+
+ return 0;
+}
+
+/*
+ * write the asn.1 lenght form into p
+ */
+static int asn1_add_len(unsigned int size, x509_node *node)
+{
+ if (size > 127) {
+
+ /* long size */
+ int byte = asn1_eval_octet(size);
+ int i = 0;
+
+ *(node->p) = (0x80 | byte) & 0xFF;
+ ++node->p;
+
+ for (i = byte; i > 0; --i) {
+
+ *(node->p) = (size >> ((i - 1) * 8)) & 0xFF;
+ ++node->p;
+ }
+
+ } else {
+
+ /* short size */
+ *(node->p) = size & 0xFF;
+ if (size != 0)
+ ++node->p;
+ }
+
+ return 0;
+}
+
+/*
+ * write a ans.1 object into p
+ */
+static int asn1_add_obj(unsigned char *value, unsigned int size, int tag,
+ x509_node *node)
+{
+ int tl = 2;
+
+ if (tag == ASN1_BIT_STRING)
+ ++tl;
+
+ if (size > 127)
+ x509write_realloc_node(node, (size_t) size + tl +
+ asn1_eval_octet(size));
+ else
+ x509write_realloc_node(node, (size_t) size + tl);
+
+ if (node->data == NULL)
+ return 1;
+
+ /* tag */
+ *(node->p) = tag & 0xFF;
+ ++node->p;
+
+ /* len */
+ if (tag == ASN1_BIT_STRING) {
+ asn1_add_len((unsigned int) size + 1, node);
+ *(node->p) = 0x00;
+ ++node->p;
+ } else {
+ asn1_add_len((unsigned int) size, node);
+ }
+
+ /* value */
+ if (size > 0) {
+
+ memcpy(node->p, value, (size_t) size);
+ if ((node->p += size -1) != node->end)
+ return POLARSSL_ERR_X509_POINT_ERROR;
+ } else {
+ /* make nothing -> NULL */
+ }
+
+ return 0;
+}
+
+/*
+ * write a asn.1 conform integer object
+ */
+static int asn1_add_int(signed int value, x509_node *node)
+{
+ signed int i = 0, neg = 1;
+ unsigned int byte, u_val = 0, tmp_val = 0;
+
+ /* if negate? */
+ if (value < 0) {
+ neg = -1;
+ u_val = ~value;
+ } else {
+ u_val = value;
+ }
+
+ byte = asn1_eval_octet(u_val);
+ /* 0 isn't NULL */
+ if (byte == 0)
+ byte = 1;
+
+ /* ASN.1 integer is signed! */
+ if (byte < 4 and ((u_val >> ((byte -1) * 8)) & 0xFF) == 0x80)
+ byte += 1;
+
+ if (x509write_realloc_node(node, (size_t) byte + 2) != 0)
+ return 1;
+
+ /* tag */
+ *(node->p) = ASN1_INTEGER;
+ ++node->p;
+
+ /* len */
+ asn1_add_len(byte, node);
+
+ /* value */
+ for (i = byte; i > 0; --i) {
+
+ tmp_val = (u_val >> ((i - 1) * 8)) & 0xFF;
+ if (neg == 1)
+ *(node->p) = tmp_val;
+ else
+ *(node->p) = ~tmp_val;
+
+ if (i > 1)
+ ++node->p;
+ }
+
+ if (node->p != node->end)
+ return POLARSSL_ERR_X509_POINT_ERROR;
+
+ return 0;
+}
+
+/*
+ * write a asn.1 conform mpi object
+ */
+static int asn1_add_mpi(mpi *value, int tag, x509_node *node)
+{
+ size_t size = (mpi_msb(value) / 8) + 1;
+ unsigned char *buf;
+ int buf_len = (int) size, tl = 2;
+
+ if (tag == ASN1_BIT_STRING)
+ ++tl;
+
+ if (size > 127)
+ x509write_realloc_node(node, size + (size_t) tl +
+ asn1_eval_octet((unsigned int)size));
+ else
+ x509write_realloc_node(node, size + (size_t) tl);
+
+ if (node->data == NULL)
+ return 1;
+
+ buf = (unsigned char*) malloc(size);
+ if (mpi_write_binary(value, buf, buf_len) != 0)
+ return POLARSSL_ERR_MPI_BUFFER_TOO_SMALL;
+
+ /* tag */
+ *(node->p) = tag & 0xFF;
+ ++node->p;
+
+ /* len */
+ if (tag == ASN1_BIT_STRING) {
+ asn1_add_len((unsigned int) size + 1, node);
+ *(node->p) = 0x00;
+ ++node->p;
+ } else {
+ asn1_add_len((unsigned int) size, node);
+ }
+
+ /* value */
+ memcpy(node->p, buf, size);
+ free(buf);
+
+ if ((node->p += (int) size -1) != node->end)
+ return POLARSSL_ERR_X509_POINT_ERROR;
+
+ return 0;
+}
+
+/*
+ * write a node into asn.1 conform object
+ */
+static int asn1_append_tag(x509_node *node, int tag)
+{
+ int tl = 2;
+
+ x509_node tmp;
+ x509write_init_node(&tmp);
+
+ if (tag == ASN1_BIT_STRING)
+ ++tl;
+
+ if (node->len > 127)
+ x509write_realloc_node(&tmp, node->len + (size_t) tl +
+ asn1_eval_octet((unsigned int)node->len));
+ else
+ x509write_realloc_node(&tmp, node->len + (size_t) tl);
+
+ if (tmp.data == NULL) {
+ x509write_free_node(&tmp);
+ return 1;
+ }
+
+ /* tag */
+ *(tmp.p) = tag & 0xFF;
+ ++tmp.p;
+
+ /* len */
+ if (tag == ASN1_BIT_STRING) {
+ asn1_add_len((unsigned int) node->len + 1, &tmp);
+ *(tmp.p) = 0x00;
+ ++tmp.p;
+ } else {
+ asn1_add_len((unsigned int) node->len, &tmp);
+ }
+
+ /* value */
+ memcpy(tmp.p, node->data, node->len);
+
+ /* good? */
+ if ((tmp.p += (int) node->len -1) != tmp.end) {
+ x509write_free_node(&tmp);
+ return POLARSSL_ERR_X509_POINT_ERROR;
+ }
+
+ free(node->data);
+ node->data = tmp.data;
+ node->p = tmp.p;
+ node->end = tmp.end;
+ node->len = tmp.len;
+
+ return 0;
+}
+
+/*
+ * write nodes into a asn.1 object
+ */
+static int asn1_append_nodes(x509_node *node, int tag, int anz, ...)
+{
+ va_list ap;
+ size_t size = 0;
+ x509_node *tmp;
+ int count;
+
+ va_start(ap, anz);
+ count = anz;
+
+ while (count--) {
+
+ tmp = va_arg(ap, x509_node*);
+ if (tmp->data != NULL)
+ size += tmp->len;
+ }
+
+ if ( size > 127) {
+ if (x509write_realloc_node(node, size + (size_t) 2 +
+ asn1_eval_octet(size)) != 0)
+ return 1;
+ } else {
+ if (x509write_realloc_node(node, size + (size_t) 2) != 0)
+ return 1;
+ }
+
+ /* tag */
+ *(node->p) = tag & 0xFF;
+ ++node->p;
+
+ /* len */
+ asn1_add_len(size, node);
+
+ /* value */
+ va_start(ap, anz);
+ count = anz;
+
+ while (count--) {
+
+ tmp = va_arg(ap, x509_node*);
+ if (tmp->data != NULL) {
+
+ memcpy(node->p, tmp->data, tmp->len);
+ if ((node->p += (int) tmp->len -1) != node->end)
+ ++node->p;
+ }
+ }
+
+ va_end(ap);
+ return 0;
+}
+
+/*
+ * write a ASN.1 conform object identifiere include a "tag"
+ */
+static int asn1_add_oid(x509_node *node, unsigned char *oid, size_t len,
+ int tag, int tag_val, unsigned char *value, size_t val_len)
+{
+ int ret;
+ x509_node tmp;
+
+ x509write_init_node(&tmp);
+
+ /* OBJECT IDENTIFIER */
+ if ((ret = asn1_add_obj(oid, len, ASN1_OID, &tmp)) != 0) {
+ x509write_free_node(&tmp);
+ return ret;
+ }
+
+ /* value */
+ if ((ret = asn1_add_obj(value, val_len, tag_val, &tmp)) != 0) {
+ x509write_free_node(&tmp);
+ return ret;
+ }
+
+ /* SET/SEQUENCE */
+ if ((ret = asn1_append_nodes(node, tag, 1, &tmp)) != 0) {
+ x509write_free_node(&tmp);
+ return ret;
+ }
+
+ x509write_free_node(&tmp);
+ return 0;
+}
+
+/*
+ * utcTime UTCTime
+ */
+static int asn1_add_date_utc(unsigned char *time, x509_node *node)
+{
+ unsigned char date[13], *sp;
+ x509_time xtime;
+ int ret;
+
+ sscanf((char*)time, "%d-%d-%d %d:%d:%d", &xtime.year, &xtime.mon,
+ &xtime.day, &xtime.hour, &xtime.min, &xtime.sec);
+
+ /* convert to YY */
+ if (xtime.year > 2000)
+ xtime.year -= 2000;
+ else
+ xtime.year -= 1900;
+
+ snprintf((char*)date, 13, "%2d%2d%2d%2d%2d%2d", xtime.year, xtime.mon, xtime.day,
+ xtime.hour, xtime.min, xtime.sec);
+
+ /* replace ' ' to '0' */
+ for (sp = date; *sp != '\0'; ++sp)
+ if (*sp == '\x20')
+ *sp = '\x30';
+
+ date[12] = 'Z';
+
+ if ((ret = asn1_add_obj(date, 13, ASN1_UTC_TIME, node)) != 0)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * serialize an rsa key into DER
+ */
+
+int x509write_serialize_key(rsa_context *rsa, x509_node *node)
+{
+ int ret = 0;
+ x509write_init_node(node);
+
+ /* vers, n, e, d, p, q, dp, dq, pq */
+ if ((ret = asn1_add_int(rsa->ver, node)) != 0)
+ return ret;
+ if ((ret = asn1_add_mpi(&rsa->N, ASN1_INTEGER, node)) != 0)
+ return ret;
+ if ((ret = asn1_add_mpi(&rsa->E, ASN1_INTEGER, node)) != 0)
+ return ret;
+ if ((ret = asn1_add_mpi(&rsa->D, ASN1_INTEGER, node)) != 0)
+ return ret;
+ if ((ret = asn1_add_mpi(&rsa->P, ASN1_INTEGER, node)) != 0)
+ return ret;
+ if ((ret = asn1_add_mpi(&rsa->Q, ASN1_INTEGER, node)) != 0)
+ return ret;
+ if ((ret = asn1_add_mpi(&rsa->DP, ASN1_INTEGER, node)) != 0)
+ return ret;
+ if ((ret = asn1_add_mpi(&rsa->DQ, ASN1_INTEGER, node)) != 0)
+ return ret;
+ if ((ret = asn1_add_mpi(&rsa->QP, ASN1_INTEGER, node)) != 0)
+ return ret;
+ if ((ret = asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * write a der/pem encoded rsa private key into a file
+ */
+int x509write_keyfile(rsa_context *rsa, char *path, int out_flag)
+{
+ int ret = 0;
+ const char key_beg[] = "-----BEGIN RSA PRIVATE KEY-----\n",
+ key_end[] = "-----END RSA PRIVATE KEY-----\n";
+ x509_node node;
+
+ x509write_init_node(&node);
+ if ((ret = x509write_serialize_key(rsa,&node)) != 0) {
+ x509write_free_node(&node);
+ return ret;
+ }
+
+ ret = x509write_file(&node,path,out_flag,key_beg,key_end);
+ x509write_free_node(&node);
+
+ return ret;
+}
+
+
+/*
+ * reasize the memory for node
+ */
+static int x509write_realloc_node(x509_node *node, size_t larger)
+{
+ /* init len */
+ if (node->data == NULL) {
+ node->len = 0;
+ node->data = malloc(larger);
+ if(node->data == NULL)
+ return 1;
+ } else {
+ /* realloc memory */
+ if ((node->data = realloc(node->data, node->len + larger)) == NULL)
+ return 1;
+ }
+
+ /* init pointer */
+ node->p = &node->data[node->len];
+ node->len += larger;
+ node->end = &node->data[node->len -1];
+
+ return 0;
+}
+
+/*
+ * init node
+ */
+void x509write_init_node(x509_node *node)
+{
+ memset(node, 0, sizeof(x509_node));
+}
+
+/*
+ * clean memory
+ */
+void x509write_free_node(x509_node *node)
+{
+ if (node->data != NULL)
+ free(node->data);
+ node->p = NULL;
+ node->end = NULL;
+ node->len = 0;
+}
+
+/*
+ * write a x509 certificate into file
+ */
+int x509write_crtfile(x509_raw *chain, unsigned char *path, int out_flag)
+{
+ const char cer_beg[] = "-----BEGIN CERTIFICATE-----\n",
+ cer_end[] = "-----END CERTIFICATE-----\n";
+
+ return x509write_file(&chain->raw, (char*)path, out_flag, cer_beg, cer_end);
+}
+
+/*
+ * write a x509 certificate into file
+ */
+int x509write_csrfile(x509_raw *chain, unsigned char *path, int out_flag)
+{
+ const char cer_beg[] = "-----BEGIN CERTIFICATE REQUEST-----\n",
+ cer_end[] = "-----END CERTIFICATE REQUEST-----\n";
+
+ return x509write_file(&chain->raw, (char*)path, out_flag, cer_beg, cer_end);
+}
+
+/*
+ * write an x509 file
+ */
+static int x509write_file(x509_node *node, char *path, int format,
+ const char* pem_prolog, const char* pem_epilog)
+{
+ FILE *ofstream = stdout;
+ int is_err = 1, buf_len, i, n;
+ unsigned char* base_buf;
+
+ if (path) {
+ if ((ofstream = fopen(path, "wb")) == NULL)
+ return 1;
+ }
+
+ switch (format) {
+ case X509_OUTPUT_DER:
+ if (fwrite(node->data, 1, node->len, ofstream)
+ != node->len)
+ is_err = -1;
+ break;
+
+ case X509_OUTPUT_PEM:
+ if (fprintf(ofstream,pem_prolog)<0) {
+ is_err = -1;
+ break;
+ }
+
+ buf_len = node->len << 1;
+ base_buf = (unsigned char*) malloc((size_t)buf_len);
+ memset(base_buf,0,buf_len);
+ if (base64_encode(base_buf, &buf_len, node->data,
+ (int) node->len) != 0) {
+ is_err = -1;
+ break;
+ }
+
+ n=strlen((char*)base_buf);
+ for(i=0;i<n;i+=64) {
+ fprintf(ofstream,"%.64s\n",&base_buf[i]);
+ }
+
+ if (fprintf(ofstream, pem_epilog)<0) {
+ is_err = -1;
+ break;
+ }
+
+ free(base_buf);
+ }
+
+ fclose(ofstream);
+
+ if (is_err == -1)
+ return 1;
+
+ return 0;
+}
+
+
+/*
+ * add the owner public key to x509 certificate
+ */
+int x509write_add_pubkey(x509_raw *chain, rsa_context *pubkey)
+{
+ x509_node n_tmp, n_tmp2, *node;
+ int ret;
+
+ node = &chain->subpubkey;
+
+ x509write_init_node(&n_tmp);
+ x509write_init_node(&n_tmp2);
+
+ /*
+ * RSAPublicKey ::= SEQUENCE {
+ * modulus INTEGER, -- n
+ * publicExponent INTEGER -- e
+ * }
+ */
+ if ((ret = asn1_add_mpi(&pubkey->N, ASN1_INTEGER, &n_tmp)) != 0) {
+ x509write_free_node(&n_tmp);
+ x509write_free_node(&n_tmp2);
+ return ret;
+ }
+ if ((ret = asn1_add_mpi(&pubkey->E, ASN1_INTEGER, &n_tmp)) != 0) {
+ x509write_free_node(&n_tmp);
+ x509write_free_node(&n_tmp2);
+ return ret;
+ }
+ if ((ret = asn1_append_tag(&n_tmp, ASN1_CONSTRUCTED | ASN1_SEQUENCE))
+ != 0) {
+ x509write_free_node(&n_tmp);
+ x509write_free_node(&n_tmp2);
+ return ret;
+ }
+
+ /*
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ * algorithm AlgorithmIdentifier,
+ * subjectPublicKey BIT STRING }
+ */
+ if ((ret = asn1_append_tag(&n_tmp, ASN1_BIT_STRING)) != 0) {
+ x509write_free_node(&n_tmp);
+ x509write_free_node(&n_tmp2);
+ return ret;
+ }
+ if ((ret = asn1_add_oid(&n_tmp2, (unsigned char*)OID_PKCS1_RSA, 9,
+ ASN1_CONSTRUCTED | ASN1_SEQUENCE, ASN1_NULL,
+ (unsigned char *)"", 0)) != 0) {
+ x509write_free_node(&n_tmp);
+ x509write_free_node(&n_tmp2);
+ return ret;
+ }
+
+ if ((ret = asn1_append_nodes(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE, 2,
+ &n_tmp2, &n_tmp))) {
+ x509write_free_node(&n_tmp);
+ x509write_free_node(&n_tmp2);
+ return ret;
+ }
+
+ x509write_free_node(&n_tmp);
+ x509write_free_node(&n_tmp2);
+ return 0;
+}
+
+/*
+ * RelativeDistinguishedName ::=
+ * SET OF AttributeTypeAndValue
+ *
+ * AttributeTypeAndValue ::= SEQUENCE {
+ * type AttributeType,
+ * value AttributeValue }
+ */
+static int x509write_add_name(x509_node *node, unsigned char *oid,
+ unsigned int oid_len, unsigned char *value, int len, int value_tag)
+{
+ int ret;
+ x509_node n_tmp;
+
+ x509write_init_node(&n_tmp);
+
+ if ((ret = asn1_add_oid(&n_tmp, oid, oid_len,
+ ASN1_CONSTRUCTED | ASN1_SEQUENCE, value_tag,
+ value, len))) {
+ x509write_free_node(&n_tmp);
+ return ret;
+ }
+
+ if ((asn1_append_nodes(node, ASN1_CONSTRUCTED | ASN1_SET, 1, &n_tmp))
+ != 0) {
+ x509write_free_node(&n_tmp);
+ return ret;
+ }
+
+ x509write_free_node(&n_tmp);
+ return 0;
+}
+
+/*
+ * Parse the name string and add to node
+ */
+static int x509write_parse_names(x509_node *node, unsigned char *names)
+{
+ unsigned char *sp, *begin = NULL;
+ unsigned char oid[3] = OID_X520, tag[4], *tag_sp = tag;
+ unsigned char *C = NULL, *CN = NULL, *O = NULL, *OU = NULL,
+ *ST = NULL, *L = NULL, *R = NULL;
+ int C_len = 0, CN_len = 0, O_len = 0, OU_len = 0, ST_len = 0,
+ L_len = 0, R_len = 0;
+ int ret = 0, is_tag = 1, is_begin = -1, len = 0;
+
+
+ for (sp = names; ; ++sp) {
+
+ /* filter tag */
+ if (is_tag == 1) {
+
+ if (tag_sp == &tag[3])
+ return POLARSSL_ERR_X509_VALUE_TO_LENGTH;
+
+ /* is tag end? */
+ if (*sp == '=') {
+ is_tag = -1;
+ *tag_sp = '\0';
+ is_begin = 1;
+ /* set len 0 (reset) */
+ len = 0;
+ } else {
+ /* tag hasn't ' '! */
+ if (*sp != ' ') {
+ *tag_sp = *sp;
+ ++tag_sp;
+ }
+ }
+ /* filter value */
+ } else {
+
+ /* set pointer of value begin */
+ if (is_begin == 1) {
+ begin = sp;
+ is_begin = -1;
+ }
+
+ /* is value at end? */
+ if (*sp == ';' or *sp == '\0') {
+ is_tag = 1;
+
+ /* common name */
+ if (tag[0] == 'C' and tag[1] == 'N') {
+ CN = begin;
+ CN_len = len;
+
+ /* organization */
+ } else if (tag[0] == 'O' and tag[1] == '\0') {
+ O = begin;
+ O_len = len;
+
+ /* country */
+ } else if (tag[0] == 'C' and tag[1] == '\0') {
+ C = begin;
+ C_len = len;
+
+ /* organisation unit */
+ } else if (tag[0] == 'O' and tag[1] == 'U') {
+ OU = begin;
+ OU_len = len;
+
+ /* state */
+ } else if (tag[0] == 'S' and tag[1] == 'T') {
+ ST = begin;
+ ST_len = len;
+
+ /* locality */
+ } else if (tag[0] == 'L' and tag[1] == '\0') {
+ L = begin;
+ L_len = len;
+
+ /* email */
+ } else if (tag[0] == 'R' and tag[1] == '\0') {
+ R = begin;
+ R_len = len;
+ }
+
+ /* set tag poiner to begin */
+ tag_sp = tag;
+
+ /* is at end? */
+ if (*sp == '\0' or *(sp +1) == '\0')
+ break;
+ } else {
+ ++len;
+ }
+ }
+
+ /* make saver */
+ if (*sp == '\0')
+ break;
+ } /* end for */
+
+ /* country */
+ if (C != NULL) {
+ oid[2] = X520_COUNTRY;
+ if ((ret = x509write_add_name(node, oid, 3, C, C_len,
+ ASN1_PRINTABLE_STRING)) != 0)
+ return ret;
+ }
+
+ /* state */
+ if (ST != NULL) {
+ oid[2] = X520_STATE;
+ if ((ret = x509write_add_name(node, oid, 3, ST, ST_len,
+ ASN1_PRINTABLE_STRING)) != 0)
+ return ret;
+ }
+
+ /* locality */
+ if (L != NULL) {
+ oid[2] = X520_LOCALITY;
+ if ((ret = x509write_add_name(node, oid, 3, L, L_len,
+ ASN1_PRINTABLE_STRING)) != 0)
+ return ret;
+ }
+
+ /* organization */
+ if (O != NULL) {
+ oid[2] = X520_ORGANIZATION;
+ if ((ret = x509write_add_name(node, oid, 3, O, O_len,
+ ASN1_PRINTABLE_STRING)) != 0)
+ return ret;
+ }
+
+ /* organisation unit */
+ if (OU != NULL) {
+ oid[2] = X520_ORG_UNIT;
+ if ((ret = x509write_add_name(node, oid, 3, OU, OU_len,
+ ASN1_PRINTABLE_STRING)) != 0)
+ return ret;
+ }
+
+ /* common name */
+ if (CN != NULL) {
+ oid[2] = X520_COMMON_NAME;
+ if ((ret = x509write_add_name(node, oid, 3, CN, CN_len,
+ ASN1_PRINTABLE_STRING)) != 0)
+ return ret;
+ }
+
+ /* email */
+ if (R != NULL) {
+ if ((ret = x509write_add_name(node, (unsigned char*)OID_PKCS9_EMAIL,
+ 9, R, R_len, ASN1_IA5_STRING)) != 0)
+ return ret;
+ }
+
+ if ((asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * Copy raw data from orginal ca to node
+ */
+static int x509write_copy_from_raw(x509_node *node, x509_buf *raw)
+{
+ if (x509write_realloc_node(node, raw->len) != 0)
+ return 1;
+
+ memcpy(node->p, raw->p, (size_t)raw->len);
+ if ((node->p += raw->len -1) != node->end)
+ return POLARSSL_ERR_X509_POINT_ERROR;
+
+ return 0;
+}
+
+/*
+ * Add the issuer
+ */
+
+int x509write_add_issuer(x509_raw *crt, unsigned char *issuer)
+{
+ return x509write_parse_names(&crt->issuer, issuer);
+}
+
+/*
+ * Add the subject
+ */
+int x509write_add_subject(x509_raw *crt, unsigned char *subject)
+{
+ return x509write_parse_names(&crt->subject, subject);
+}
+
+/*
+ * Copy issuer line from another cert to issuer
+ */
+int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt)
+{
+ return x509write_copy_from_raw(&crt->issuer, &from_crt->issuer_raw);
+}
+
+/*
+ * Copy subject line from another cert
+ */
+int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt)
+{
+ return x509write_copy_from_raw(&crt->subject, &from_crt->subject_raw);
+}
+
+/*
+ * Copy subject line form antoher cert into issuer
+ */
+int x509write_copy_issuer_form_subject(x509_raw *crt,
+ x509_cert *from_crt)
+{
+ return x509write_copy_from_raw(&crt->issuer, &from_crt->subject_raw);
+}
+
+/*
+ * Copy issuer line from another cert into subject
+ */
+int x509write_copy_subject_from_issuer(x509_raw *crt,
+ x509_cert * from_crt)
+{
+ return x509write_copy_from_raw(&crt->subject, &from_crt->issuer_raw);
+}
+
+/*
+ * Validity ::= SEQUENCE {
+ * notBefore Time,
+ * notAfter Time }
+ *
+ * Time ::= CHOICE {
+ * utcTime UTCTime,
+ * generalTime GeneralizedTime }
+ */
+/* TODO: No handle GeneralizedTime! */
+int x509write_add_validity(x509_raw *chain, unsigned char *befor,
+ unsigned char *after)
+{
+ int ret;
+
+ x509_node *node = &chain->validity;
+
+ /* notBefore */
+ if ((ret = asn1_add_date_utc(befor, node)) != 0)
+ return ret;
+
+ /* notAfter */
+ if ((ret = asn1_add_date_utc(after, node)) != 0)
+ return ret;
+
+ if ((ret = asn1_append_tag(node, ASN1_CONSTRUCTED | ASN1_SEQUENCE)) != 0)
+ return ret;
+
+ return 0;
+}
+
+/*
+ * make hash from tbs and sign that with private key
+ */
+static int x509write_make_sign(x509_raw *chain, rsa_context *privkey)
+{
+ int ret;
+ unsigned char hash[20], *sign;
+ size_t sign_len = (size_t) mpi_size(&privkey->N);
+
+ /* make hash */
+ sha1(chain->tbs.data, chain->tbs.len, hash);
+
+ /* create sign */
+ sign = (unsigned char *) malloc(sign_len);
+ if (sign == NULL)
+ return 1;
+
+ if ((ret = rsa_pkcs1_sign(privkey, RSA_PRIVATE, RSA_SHA1, 20, hash,
+ sign)) != 0)
+ return ret;
+
+ if ((ret = asn1_add_obj(sign, sign_len, ASN1_BIT_STRING,
+ &chain->sign)) != 0)
+ return ret;
+
+ /*
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL }
+ */
+ return asn1_add_oid(&chain->signalg, (unsigned char*)OID_PKCS1_RSA_SHA, 9,
+ ASN1_CONSTRUCTED | ASN1_SEQUENCE, ASN1_NULL,
+ (unsigned char*)"", 0);
+}
+
+/*
+ * Create a random serial
+ */
+static int get_random_serial(void)
+{
+ int random = 0;
+ FILE *fd;
+
+ fd = fopen("/dev/urandom", "r");
+
+ if (fd) {
+ if (fread(&random, 1, sizeof(random), fd) != sizeof(random))
+ random = 0;
+
+ fclose(fd);
+ }
+
+ return random;
+}
+
+/*
+ * Create a self signed certificate
+ */
+int x509write_create_sign(x509_raw *chain, rsa_context *privkey)
+{
+ int ret, serial;
+
+ /*
+ * Version ::= INTEGER { v1(0), v2(1), v3(2) }
+ */
+ if ((ret = asn1_add_int(2, &chain->version)) != 0)
+ return ret;
+
+ if ((ret = asn1_append_tag(&chain->version, ASN1_CONTEXT_SPECIFIC |
+ ASN1_CONSTRUCTED)) != 0)
+ return ret;
+
+
+ /*
+ * CertificateSerialNumber ::= INTEGER
+ */
+ serial = get_random_serial();
+
+ if (serial == 0)
+ return 1;
+
+ if ((ret = asn1_add_int(serial, &chain->serial)) != 0)
+ return ret;
+
+ /*
+ * AlgorithmIdentifier ::= SEQUENCE {
+ * algorithm OBJECT IDENTIFIER,
+ * parameters ANY DEFINED BY algorithm OPTIONAL }
+ */
+ if ((ret = asn1_add_oid(&chain->tbs_signalg,
+ (unsigned char*)OID_PKCS1_RSA_SHA, 9, ASN1_CONSTRUCTED |
+ ASN1_SEQUENCE, ASN1_NULL, (unsigned char*)"", 0)) != 0)
+ return ret;
+
+ /*
+ * Create the tbs
+ */
+ if ((ret = asn1_append_nodes(&chain->tbs, ASN1_CONSTRUCTED |
+ ASN1_SEQUENCE, 7, &chain->version, &chain->serial,
+ &chain->tbs_signalg, &chain->issuer, &chain->validity,
+ &chain->subject, &chain->subpubkey)) != 0)
+ return ret;
+
+ /* make signing */
+ if ((ret = x509write_make_sign(chain, privkey)) != 0)
+ return ret;
+
+ /* finishing */
+ if ((ret = asn1_append_nodes(&chain->raw, ASN1_CONSTRUCTED |
+ ASN1_SEQUENCE, 3, &chain->tbs, &chain->signalg,
+ &chain->sign)) != 0)
+ return ret;
+
+ return 0;
+}
+
+int x509write_create_selfsign(x509_raw *chain, rsa_context *privkey)
+{
+ /*
+ * On self signed certificate are subject and issuer the same
+ */
+ x509write_free_node(&chain->issuer);
+ chain->issuer = chain->subject;
+ return x509write_create_sign(chain, privkey);
+}
+
+/*
+ * CertificationRequestInfo ::= SEQUENCE {
+ * version Version,
+ * subject Name,
+ * subjectPublicKeyInfo SubjectPublicKeyInfo,
+ * attributes [0] IMPLICIT Attributes }
+ *
+ * CertificationRequest ::= SEQUENCE {
+ * certificationRequestInfo CertificationRequestInfo,
+ * signatureAlgorithm SignatureAlgorithmIdentifier,
+ * signature Signature }
+ *
+ * It use chain.serail for attributes!
+ *
+ */
+int x509write_create_csr(x509_raw *chain, rsa_context *privkey)
+{
+ int ret;
+
+ /* version ::= INTEGER */
+ if ((ret = asn1_add_int(0, &chain->version)) != 0)
+ return ret;
+
+ /* write attributes */
+ if ((ret = asn1_add_obj((unsigned char*)"", 0, ASN1_CONTEXT_SPECIFIC |
+ ASN1_CONSTRUCTED, &chain->serial)) != 0)
+ return ret;
+
+ /* create CertificationRequestInfo */
+ if ((ret = asn1_append_nodes(&chain->tbs, ASN1_CONSTRUCTED |
+ ASN1_SEQUENCE, 4, &chain->version, &chain->subject,
+ &chain->subpubkey, &chain->serial)) != 0)
+ return ret;
+
+ /* make signing */
+ if ((ret = x509write_make_sign(chain, privkey)) != 0)
+ return ret;
+
+ /* finish */
+ if ((ret = asn1_append_nodes(&chain->raw, ASN1_CONSTRUCTED | ASN1_SEQUENCE,
+ 3, &chain->tbs, &chain->signalg, &chain->sign)) != 0)
+ return ret;
+
+ return ret;
+}
+
+/*
+ * Free memory
+ */
+void x509write_free_raw(x509_raw *chain)
+{
+ x509write_free_node(&chain->raw);
+ x509write_free_node(&chain->tbs);
+ x509write_free_node(&chain->version);
+ x509write_free_node(&chain->serial);
+ x509write_free_node(&chain->tbs_signalg);
+ x509write_free_node(&chain->issuer);
+ x509write_free_node(&chain->validity);
+ if (chain->subject.data != chain->issuer.data)
+ x509write_free_node(&chain->subject);
+ x509write_free_node(&chain->subpubkey);
+ x509write_free_node(&chain->signalg);
+ x509write_free_node(&chain->sign);
+}
+
+void x509write_init_raw(x509_raw *chain)
+{
+ memset((void *) chain, 0, sizeof(x509_raw));
+}
+
diff --git a/package/utils/px5g-standalone/src/polarssl/base64.h b/package/utils/px5g-standalone/src/polarssl/base64.h
new file mode 100644
index 0000000..c48267b
--- /dev/null
+++ b/package/utils/px5g-standalone/src/polarssl/base64.h
@@ -0,0 +1,93 @@
+/**
+ * \file base64.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef POLARSSL_BASE64_H
+#define POLARSSL_BASE64_H
+
+#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x0010
+#define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x0012
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Encode a buffer into base64 format
+ *
+ * \param dst destination buffer
+ * \param dlen size of the buffer
+ * \param src source buffer
+ * \param slen amount of data to be encoded
+ *
+ * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
+ * *dlen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ *
+ * \note Call this function with *dlen = 0 to obtain the
+ * required buffer size in *dlen
+ */
+int base64_encode( unsigned char *dst, int *dlen,
+ unsigned char *src, int slen );
+
+/**
+ * \brief Decode a base64-formatted buffer
+ *
+ * \param dst destination buffer
+ * \param dlen size of the buffer
+ * \param src source buffer
+ * \param slen amount of data to be decoded
+ *
+ * \return 0 if successful, POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL, or
+ * POLARSSL_ERR_BASE64_INVALID_DATA if the input data is not
+ * correct. *dlen is always updated to reflect the amount
+ * of data that has (or would have) been written.
+ *
+ * \note Call this function with *dlen = 0 to obtain the
+ * required buffer size in *dlen
+ */
+int base64_decode( unsigned char *dst, int *dlen,
+ unsigned char *src, int slen );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int base64_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* base64.h */
diff --git a/package/utils/px5g-standalone/src/polarssl/bignum.h b/package/utils/px5g-standalone/src/polarssl/bignum.h
new file mode 100644
index 0000000..c667303
--- /dev/null
+++ b/package/utils/px5g-standalone/src/polarssl/bignum.h
@@ -0,0 +1,437 @@
+/**
+ * \file bignum.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef POLARSSL_BIGNUM_H
+#define POLARSSL_BIGNUM_H
+
+#include <stdio.h>
+
+#define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002
+#define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004
+#define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006
+#define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008
+#define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A
+#define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C
+#define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E
+
+#define MPI_CHK(f) if( ( ret = f ) != 0 ) goto cleanup
+
+/*
+ * Define the base integer type, architecture-wise
+ */
+#if defined(POLARSSL_HAVE_INT8)
+typedef unsigned char t_int;
+typedef unsigned short t_dbl;
+#else
+#if defined(POLARSSL_HAVE_INT16)
+typedef unsigned short t_int;
+typedef unsigned long t_dbl;
+#else
+ typedef unsigned long t_int;
+ #if defined(_MSC_VER) && defined(_M_IX86)
+ typedef unsigned __int64 t_dbl;
+ #else
+ #if defined(__amd64__) || defined(__x86_64__) || \
+ defined(__ppc64__) || defined(__powerpc64__) || \
+ defined(__ia64__) || defined(__alpha__)
+ typedef unsigned int t_dbl __attribute__((mode(TI)));
+ #else
+ typedef unsigned long long t_dbl;
+ #endif
+ #endif
+#endif
+#endif
+
+/**
+ * \brief MPI structure
+ */
+typedef struct
+{
+ int s; /*!< integer sign */
+ int n; /*!< total # of limbs */
+ t_int *p; /*!< pointer to limbs */
+}
+mpi;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initialize one or more mpi
+ */
+void mpi_init( mpi *X, ... );
+
+/**
+ * \brief Unallocate one or more mpi
+ */
+void mpi_free( mpi *X, ... );
+
+/**
+ * \brief Enlarge to the specified number of limbs
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_grow( mpi *X, int nblimbs );
+
+/**
+ * \brief Copy the contents of Y into X
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_copy( mpi *X, mpi *Y );
+
+/**
+ * \brief Swap the contents of X and Y
+ */
+void mpi_swap( mpi *X, mpi *Y );
+
+/**
+ * \brief Set value from integer
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_lset( mpi *X, int z );
+
+/**
+ * \brief Return the number of least significant bits
+ */
+int mpi_lsb( mpi *X );
+
+/**
+ * \brief Return the number of most significant bits
+ */
+int mpi_msb( mpi *X );
+
+/**
+ * \brief Return the total size in bytes
+ */
+int mpi_size( mpi *X );
+
+/**
+ * \brief Import from an ASCII string
+ *
+ * \param X destination mpi
+ * \param radix input numeric base
+ * \param s null-terminated string buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ */
+int mpi_read_string( mpi *X, int radix, char *s );
+
+/**
+ * \brief Export into an ASCII string
+ *
+ * \param X source mpi
+ * \param radix output numeric base
+ * \param s string buffer
+ * \param slen string buffer size
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ *
+ * \note Call this function with *slen = 0 to obtain the
+ * minimum required buffer size in *slen.
+ */
+int mpi_write_string( mpi *X, int radix, char *s, int *slen );
+
+/**
+ * \brief Read X from an opened file
+ *
+ * \param X destination mpi
+ * \param radix input numeric base
+ * \param fin input file handle
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ */
+int mpi_read_file( mpi *X, int radix, FILE *fin );
+
+/**
+ * \brief Write X into an opened file, or stdout
+ *
+ * \param p prefix, can be NULL
+ * \param X source mpi
+ * \param radix output numeric base
+ * \param fout output file handle
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_MPI_XXX error code
+ *
+ * \note Set fout == NULL to print X on the console.
+ */
+int mpi_write_file( char *p, mpi *X, int radix, FILE *fout );
+
+/**
+ * \brief Import X from unsigned binary data, big endian
+ *
+ * \param X destination mpi
+ * \param buf input buffer
+ * \param buflen input buffer size
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_read_binary( mpi *X, unsigned char *buf, int buflen );
+
+/**
+ * \brief Export X into unsigned binary data, big endian
+ *
+ * \param X source mpi
+ * \param buf output buffer
+ * \param buflen output buffer size
+ *
+ * \return 0 if successful,
+ * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough
+ *
+ * \note Call this function with *buflen = 0 to obtain the
+ * minimum required buffer size in *buflen.
+ */
+int mpi_write_binary( mpi *X, unsigned char *buf, int buflen );
+
+/**
+ * \brief Left-shift: X <<= count
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_shift_l( mpi *X, int count );
+
+/**
+ * \brief Right-shift: X >>= count
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_shift_r( mpi *X, int count );
+
+/**
+ * \brief Compare unsigned values
+ *
+ * \return 1 if |X| is greater than |Y|,
+ * -1 if |X| is lesser than |Y| or
+ * 0 if |X| is equal to |Y|
+ */
+int mpi_cmp_abs( mpi *X, mpi *Y );
+
+/**
+ * \brief Compare signed values
+ *
+ * \return 1 if X is greater than Y,
+ * -1 if X is lesser than Y or
+ * 0 if X is equal to Y
+ */
+int mpi_cmp_mpi( mpi *X, mpi *Y );
+
+/**
+ * \brief Compare signed values
+ *
+ * \return 1 if X is greater than z,
+ * -1 if X is lesser than z or
+ * 0 if X is equal to z
+ */
+int mpi_cmp_int( mpi *X, int z );
+
+/**
+ * \brief Unsigned addition: X = |A| + |B|
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_abs( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief Unsigned substraction: X = |A| - |B|
+ *
+ * \return 0 if successful,
+ * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A
+ */
+int mpi_sub_abs( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief Signed addition: X = A + B
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_mpi( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief Signed substraction: X = A - B
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_sub_mpi( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief Signed addition: X = A + b
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_add_int( mpi *X, mpi *A, int b );
+
+/**
+ * \brief Signed substraction: X = A - b
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_sub_int( mpi *X, mpi *A, int b );
+
+/**
+ * \brief Baseline multiplication: X = A * B
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_mul_mpi( mpi *X, mpi *A, mpi *B );
+
+/**
+ * \brief Baseline multiplication: X = A * b
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_mul_int( mpi *X, mpi *A, t_int b );
+
+/**
+ * \brief Division by mpi: A = Q * B + R
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
+ *
+ * \note Either Q or R can be NULL.
+ */
+int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B );
+
+/**
+ * \brief Division by int: A = Q * b + R
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ *
+ * \note Either Q or R can be NULL.
+ */
+int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b );
+
+/**
+ * \brief Modulo: R = A mod B
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0
+ */
+int mpi_mod_mpi( mpi *R, mpi *A, mpi *B );
+
+/**
+ * \brief Modulo: r = A mod b
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
+ */
+int mpi_mod_int( t_int *r, mpi *A, int b );
+
+/**
+ * \brief Sliding-window exponentiation: X = A^E mod N
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even
+ *
+ * \note _RR is used to avoid re-computing R*R mod N across
+ * multiple calls, which speeds up things a bit. It can
+ * be set to NULL if the extra performance is unneeded.
+ */
+int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR );
+
+/**
+ * \brief Greatest common divisor: G = gcd(A, B)
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed
+ */
+int mpi_gcd( mpi *G, mpi *A, mpi *B );
+
+/**
+ * \brief Modular inverse: X = A^-1 mod N
+ *
+ * \return 0 if successful,
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil
+ * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N
+ */
+int mpi_inv_mod( mpi *X, mpi *A, mpi *N );
+
+/**
+ * \brief Miller-Rabin primality test
+ *
+ * \return 0 if successful (probably prime),
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime
+ */
+int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng );
+
+/**
+ * \brief Prime number generation
+ *
+ * \param X destination mpi
+ * \param nbits required size of X in bits
+ * \param dh_flag if 1, then (X-1)/2 will be prime too
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \return 0 if successful (probably prime),
+ * 1 if memory allocation failed,
+ * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3
+ */
+int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
+ int (*f_rng)(void *), void *p_rng );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int mpi_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* bignum.h */
diff --git a/package/utils/px5g-standalone/src/polarssl/bn_mul.h b/package/utils/px5g-standalone/src/polarssl/bn_mul.h
new file mode 100644
index 0000000..f6d34da
--- /dev/null
+++ b/package/utils/px5g-standalone/src/polarssl/bn_mul.h
@@ -0,0 +1,731 @@
+/**
+ * \file bn_mul.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/*
+ * Multiply source vector [s] with b, add result
+ * to destination vector [d] and set carry c.
+ *
+ * Currently supports:
+ *
+ * . IA-32 (386+) . AMD64 / EM64T
+ * . IA-32 (SSE2) . Motorola 68000
+ * . PowerPC, 32-bit . MicroBlaze
+ * . PowerPC, 64-bit . TriCore
+ * . SPARC v8 . ARM v3+
+ * . Alpha . MIPS32
+ * . C, longlong . C, generic
+ */
+#ifndef POLARSSL_BN_MUL_H
+#define POLARSSL_BN_MUL_H
+
+#include "polarssl/config.h"
+
+#if defined(POLARSSL_HAVE_ASM)
+
+#if defined(__GNUC__)
+#if defined(__i386__)
+
+#define MULADDC_INIT \
+ asm( "movl %%ebx, %0 " : "=m" (t)); \
+ asm( "movl %0, %%esi " :: "m" (s)); \
+ asm( "movl %0, %%edi " :: "m" (d)); \
+ asm( "movl %0, %%ecx " :: "m" (c)); \
+ asm( "movl %0, %%ebx " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "lodsl " ); \
+ asm( "mull %ebx " ); \
+ asm( "addl %ecx, %eax " ); \
+ asm( "adcl $0, %edx " ); \
+ asm( "addl (%edi), %eax " ); \
+ asm( "adcl $0, %edx " ); \
+ asm( "movl %edx, %ecx " ); \
+ asm( "stosl " );
+
+#if defined(POLARSSL_HAVE_SSE2)
+
+#define MULADDC_HUIT \
+ asm( "movd %ecx, %mm1 " ); \
+ asm( "movd %ebx, %mm0 " ); \
+ asm( "movd (%edi), %mm3 " ); \
+ asm( "paddq %mm3, %mm1 " ); \
+ asm( "movd (%esi), %mm2 " ); \
+ asm( "pmuludq %mm0, %mm2 " ); \
+ asm( "movd 4(%esi), %mm4 " ); \
+ asm( "pmuludq %mm0, %mm4 " ); \
+ asm( "movd 8(%esi), %mm6 " ); \
+ asm( "pmuludq %mm0, %mm6 " ); \
+ asm( "movd 12(%esi), %mm7 " ); \
+ asm( "pmuludq %mm0, %mm7 " ); \
+ asm( "paddq %mm2, %mm1 " ); \
+ asm( "movd 4(%edi), %mm3 " ); \
+ asm( "paddq %mm4, %mm3 " ); \
+ asm( "movd 8(%edi), %mm5 " ); \
+ asm( "paddq %mm6, %mm5 " ); \
+ asm( "movd 12(%edi), %mm4 " ); \
+ asm( "paddq %mm4, %mm7 " ); \
+ asm( "movd %mm1, (%edi) " ); \
+ asm( "movd 16(%esi), %mm2 " ); \
+ asm( "pmuludq %mm0, %mm2 " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "movd 20(%esi), %mm4 " ); \
+ asm( "pmuludq %mm0, %mm4 " ); \
+ asm( "paddq %mm3, %mm1 " ); \
+ asm( "movd 24(%esi), %mm6 " ); \
+ asm( "pmuludq %mm0, %mm6 " ); \
+ asm( "movd %mm1, 4(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "movd 28(%esi), %mm3 " ); \
+ asm( "pmuludq %mm0, %mm3 " ); \
+ asm( "paddq %mm5, %mm1 " ); \
+ asm( "movd 16(%edi), %mm5 " ); \
+ asm( "paddq %mm5, %mm2 " ); \
+ asm( "movd %mm1, 8(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "paddq %mm7, %mm1 " ); \
+ asm( "movd 20(%edi), %mm5 " ); \
+ asm( "paddq %mm5, %mm4 " ); \
+ asm( "movd %mm1, 12(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "paddq %mm2, %mm1 " ); \
+ asm( "movd 24(%edi), %mm5 " ); \
+ asm( "paddq %mm5, %mm6 " ); \
+ asm( "movd %mm1, 16(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "paddq %mm4, %mm1 " ); \
+ asm( "movd 28(%edi), %mm5 " ); \
+ asm( "paddq %mm5, %mm3 " ); \
+ asm( "movd %mm1, 20(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "paddq %mm6, %mm1 " ); \
+ asm( "movd %mm1, 24(%edi) " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "paddq %mm3, %mm1 " ); \
+ asm( "movd %mm1, 28(%edi) " ); \
+ asm( "addl $32, %edi " ); \
+ asm( "addl $32, %esi " ); \
+ asm( "psrlq $32, %mm1 " ); \
+ asm( "movd %mm1, %ecx " );
+
+#define MULADDC_STOP \
+ asm( "emms " ); \
+ asm( "movl %0, %%ebx " :: "m" (t)); \
+ asm( "movl %%ecx, %0 " : "=m" (c)); \
+ asm( "movl %%edi, %0 " : "=m" (d)); \
+ asm( "movl %%esi, %0 " : "=m" (s) :: \
+ "eax", "ecx", "edx", "esi", "edi" );
+
+#else
+
+#define MULADDC_STOP \
+ asm( "movl %0, %%ebx " :: "m" (t)); \
+ asm( "movl %%ecx, %0 " : "=m" (c)); \
+ asm( "movl %%edi, %0 " : "=m" (d)); \
+ asm( "movl %%esi, %0 " : "=m" (s) :: \
+ "eax", "ecx", "edx", "esi", "edi" );
+
+#endif /* SSE2 */
+#endif /* i386 */
+
+#if defined(__amd64__) || defined (__x86_64__)
+
+#define MULADDC_INIT \
+ asm( "movq %0, %%rsi " :: "m" (s)); \
+ asm( "movq %0, %%rdi " :: "m" (d)); \
+ asm( "movq %0, %%rcx " :: "m" (c)); \
+ asm( "movq %0, %%rbx " :: "m" (b)); \
+ asm( "xorq %r8, %r8 " );
+
+#define MULADDC_CORE \
+ asm( "movq (%rsi),%rax " ); \
+ asm( "mulq %rbx " ); \
+ asm( "addq $8, %rsi " ); \
+ asm( "addq %rcx, %rax " ); \
+ asm( "movq %r8, %rcx " ); \
+ asm( "adcq $0, %rdx " ); \
+ asm( "nop " ); \
+ asm( "addq %rax, (%rdi) " ); \
+ asm( "adcq %rdx, %rcx " ); \
+ asm( "addq $8, %rdi " );
+
+#define MULADDC_STOP \
+ asm( "movq %%rcx, %0 " : "=m" (c)); \
+ asm( "movq %%rdi, %0 " : "=m" (d)); \
+ asm( "movq %%rsi, %0 " : "=m" (s) :: \
+ "rax", "rcx", "rdx", "rbx", "rsi", "rdi", "r8" );
+
+#endif /* AMD64 */
+
+#if defined(__mc68020__) || defined(__mcpu32__)
+
+#define MULADDC_INIT \
+ asm( "movl %0, %%a2 " :: "m" (s)); \
+ asm( "movl %0, %%a3 " :: "m" (d)); \
+ asm( "movl %0, %%d3 " :: "m" (c)); \
+ asm( "movl %0, %%d2 " :: "m" (b)); \
+ asm( "moveq #0, %d0 " );
+
+#define MULADDC_CORE \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "moveq #0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "addxl %d4, %d3 " );
+
+#define MULADDC_STOP \
+ asm( "movl %%d3, %0 " : "=m" (c)); \
+ asm( "movl %%a3, %0 " : "=m" (d)); \
+ asm( "movl %%a2, %0 " : "=m" (s) :: \
+ "d0", "d1", "d2", "d3", "d4", "a2", "a3" );
+
+#define MULADDC_HUIT \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d4:%d1 " ); \
+ asm( "addxl %d3, %d1 " ); \
+ asm( "addxl %d0, %d4 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "movel %a2@+, %d1 " ); \
+ asm( "mulul %d2, %d3:%d1 " ); \
+ asm( "addxl %d4, %d1 " ); \
+ asm( "addxl %d0, %d3 " ); \
+ asm( "addl %d1, %a3@+ " ); \
+ asm( "addxl %d0, %d3 " );
+
+#endif /* MC68000 */
+
+#if defined(__powerpc__) || defined(__ppc__)
+#if defined(__powerpc64__) || defined(__ppc64__)
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT \
+ asm( "ld r3, %0 " :: "m" (s)); \
+ asm( "ld r4, %0 " :: "m" (d)); \
+ asm( "ld r5, %0 " :: "m" (c)); \
+ asm( "ld r6, %0 " :: "m" (b)); \
+ asm( "addi r3, r3, -8 " ); \
+ asm( "addi r4, r4, -8 " ); \
+ asm( "addic r5, r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "ldu r7, 8(r3) " ); \
+ asm( "mulld r8, r7, r6 " ); \
+ asm( "mulhdu r9, r7, r6 " ); \
+ asm( "adde r8, r8, r5 " ); \
+ asm( "ld r7, 8(r4) " ); \
+ asm( "addze r5, r9 " ); \
+ asm( "addc r8, r8, r7 " ); \
+ asm( "stdu r8, 8(r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze r5, r5 " ); \
+ asm( "addi r4, r4, 8 " ); \
+ asm( "addi r3, r3, 8 " ); \
+ asm( "std r5, %0 " : "=m" (c)); \
+ asm( "std r4, %0 " : "=m" (d)); \
+ asm( "std r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#else
+
+#define MULADDC_INIT \
+ asm( "ld %%r3, %0 " :: "m" (s)); \
+ asm( "ld %%r4, %0 " :: "m" (d)); \
+ asm( "ld %%r5, %0 " :: "m" (c)); \
+ asm( "ld %%r6, %0 " :: "m" (b)); \
+ asm( "addi %r3, %r3, -8 " ); \
+ asm( "addi %r4, %r4, -8 " ); \
+ asm( "addic %r5, %r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "ldu %r7, 8(%r3) " ); \
+ asm( "mulld %r8, %r7, %r6 " ); \
+ asm( "mulhdu %r9, %r7, %r6 " ); \
+ asm( "adde %r8, %r8, %r5 " ); \
+ asm( "ld %r7, 8(%r4) " ); \
+ asm( "addze %r5, %r9 " ); \
+ asm( "addc %r8, %r8, %r7 " ); \
+ asm( "stdu %r8, 8(%r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze %r5, %r5 " ); \
+ asm( "addi %r4, %r4, 8 " ); \
+ asm( "addi %r3, %r3, 8 " ); \
+ asm( "std %%r5, %0 " : "=m" (c)); \
+ asm( "std %%r4, %0 " : "=m" (d)); \
+ asm( "std %%r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#endif
+
+#else /* PPC32 */
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#define MULADDC_INIT \
+ asm( "lwz r3, %0 " :: "m" (s)); \
+ asm( "lwz r4, %0 " :: "m" (d)); \
+ asm( "lwz r5, %0 " :: "m" (c)); \
+ asm( "lwz r6, %0 " :: "m" (b)); \
+ asm( "addi r3, r3, -4 " ); \
+ asm( "addi r4, r4, -4 " ); \
+ asm( "addic r5, r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "lwzu r7, 4(r3) " ); \
+ asm( "mullw r8, r7, r6 " ); \
+ asm( "mulhwu r9, r7, r6 " ); \
+ asm( "adde r8, r8, r5 " ); \
+ asm( "lwz r7, 4(r4) " ); \
+ asm( "addze r5, r9 " ); \
+ asm( "addc r8, r8, r7 " ); \
+ asm( "stwu r8, 4(r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze r5, r5 " ); \
+ asm( "addi r4, r4, 4 " ); \
+ asm( "addi r3, r3, 4 " ); \
+ asm( "stw r5, %0 " : "=m" (c)); \
+ asm( "stw r4, %0 " : "=m" (d)); \
+ asm( "stw r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#else
+
+#define MULADDC_INIT \
+ asm( "lwz %%r3, %0 " :: "m" (s)); \
+ asm( "lwz %%r4, %0 " :: "m" (d)); \
+ asm( "lwz %%r5, %0 " :: "m" (c)); \
+ asm( "lwz %%r6, %0 " :: "m" (b)); \
+ asm( "addi %r3, %r3, -4 " ); \
+ asm( "addi %r4, %r4, -4 " ); \
+ asm( "addic %r5, %r5, 0 " );
+
+#define MULADDC_CORE \
+ asm( "lwzu %r7, 4(%r3) " ); \
+ asm( "mullw %r8, %r7, %r6 " ); \
+ asm( "mulhwu %r9, %r7, %r6 " ); \
+ asm( "adde %r8, %r8, %r5 " ); \
+ asm( "lwz %r7, 4(%r4) " ); \
+ asm( "addze %r5, %r9 " ); \
+ asm( "addc %r8, %r8, %r7 " ); \
+ asm( "stwu %r8, 4(%r4) " );
+
+#define MULADDC_STOP \
+ asm( "addze %r5, %r5 " ); \
+ asm( "addi %r4, %r4, 4 " ); \
+ asm( "addi %r3, %r3, 4 " ); \
+ asm( "stw %%r5, %0 " : "=m" (c)); \
+ asm( "stw %%r4, %0 " : "=m" (d)); \
+ asm( "stw %%r3, %0 " : "=m" (s) :: \
+ "r3", "r4", "r5", "r6", "r7", "r8", "r9" );
+
+#endif
+
+#endif /* PPC32 */
+#endif /* PPC64 */
+
+#if defined(__sparc__)
+
+#define MULADDC_INIT \
+ asm( "ld %0, %%o0 " :: "m" (s)); \
+ asm( "ld %0, %%o1 " :: "m" (d)); \
+ asm( "ld %0, %%o2 " :: "m" (c)); \
+ asm( "ld %0, %%o3 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ld [%o0], %o4 " ); \
+ asm( "inc 4, %o0 " ); \
+ asm( "ld [%o1], %o5 " ); \
+ asm( "umul %o3, %o4, %o4 " ); \
+ asm( "addcc %o4, %o2, %o4 " ); \
+ asm( "rd %y, %g1 " ); \
+ asm( "addx %g1, 0, %g1 " ); \
+ asm( "addcc %o4, %o5, %o4 " ); \
+ asm( "st %o4, [%o1] " ); \
+ asm( "addx %g1, 0, %o2 " ); \
+ asm( "inc 4, %o1 " );
+
+#define MULADDC_STOP \
+ asm( "st %%o2, %0 " : "=m" (c)); \
+ asm( "st %%o1, %0 " : "=m" (d)); \
+ asm( "st %%o0, %0 " : "=m" (s) :: \
+ "g1", "o0", "o1", "o2", "o3", "o4", "o5" );
+
+#endif /* SPARCv8 */
+
+#if defined(__microblaze__) || defined(microblaze)
+
+#define MULADDC_INIT \
+ asm( "lwi r3, %0 " :: "m" (s)); \
+ asm( "lwi r4, %0 " :: "m" (d)); \
+ asm( "lwi r5, %0 " :: "m" (c)); \
+ asm( "lwi r6, %0 " :: "m" (b)); \
+ asm( "andi r7, r6, 0xffff" ); \
+ asm( "bsrli r6, r6, 16 " );
+
+#define MULADDC_CORE \
+ asm( "lhui r8, r3, 0 " ); \
+ asm( "addi r3, r3, 2 " ); \
+ asm( "lhui r9, r3, 0 " ); \
+ asm( "addi r3, r3, 2 " ); \
+ asm( "mul r10, r9, r6 " ); \
+ asm( "mul r11, r8, r7 " ); \
+ asm( "mul r12, r9, r7 " ); \
+ asm( "mul r13, r8, r6 " ); \
+ asm( "bsrli r8, r10, 16 " ); \
+ asm( "bsrli r9, r11, 16 " ); \
+ asm( "add r13, r13, r8 " ); \
+ asm( "add r13, r13, r9 " ); \
+ asm( "bslli r10, r10, 16 " ); \
+ asm( "bslli r11, r11, 16 " ); \
+ asm( "add r12, r12, r10 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "add r12, r12, r11 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "lwi r10, r4, 0 " ); \
+ asm( "add r12, r12, r10 " ); \
+ asm( "addc r13, r13, r0 " ); \
+ asm( "add r12, r12, r5 " ); \
+ asm( "addc r5, r13, r0 " ); \
+ asm( "swi r12, r4, 0 " ); \
+ asm( "addi r4, r4, 4 " );
+
+#define MULADDC_STOP \
+ asm( "swi r5, %0 " : "=m" (c)); \
+ asm( "swi r4, %0 " : "=m" (d)); \
+ asm( "swi r3, %0 " : "=m" (s) :: \
+ "r3", "r4" , "r5" , "r6" , "r7" , "r8" , \
+ "r9", "r10", "r11", "r12", "r13" );
+
+#endif /* MicroBlaze */
+
+#if defined(__tricore__)
+
+#define MULADDC_INIT \
+ asm( "ld.a %%a2, %0 " :: "m" (s)); \
+ asm( "ld.a %%a3, %0 " :: "m" (d)); \
+ asm( "ld.w %%d4, %0 " :: "m" (c)); \
+ asm( "ld.w %%d1, %0 " :: "m" (b)); \
+ asm( "xor %d5, %d5 " );
+
+#define MULADDC_CORE \
+ asm( "ld.w %d0, [%a2+] " ); \
+ asm( "madd.u %e2, %e4, %d0, %d1 " ); \
+ asm( "ld.w %d0, [%a3] " ); \
+ asm( "addx %d2, %d2, %d0 " ); \
+ asm( "addc %d3, %d3, 0 " ); \
+ asm( "mov %d4, %d3 " ); \
+ asm( "st.w [%a3+], %d2 " );
+
+#define MULADDC_STOP \
+ asm( "st.w %0, %%d4 " : "=m" (c)); \
+ asm( "st.a %0, %%a3 " : "=m" (d)); \
+ asm( "st.a %0, %%a2 " : "=m" (s) :: \
+ "d0", "d1", "e2", "d4", "a2", "a3" );
+
+#endif /* TriCore */
+
+#if defined(__arm__)
+
+#define MULADDC_INIT \
+ asm( "ldr r0, %0 " :: "m" (s)); \
+ asm( "ldr r1, %0 " :: "m" (d)); \
+ asm( "ldr r2, %0 " :: "m" (c)); \
+ asm( "ldr r3, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ldr r4, [r0], #4 " ); \
+ asm( "mov r5, #0 " ); \
+ asm( "ldr r6, [r1] " ); \
+ asm( "umlal r2, r5, r3, r4 " ); \
+ asm( "adds r7, r6, r2 " ); \
+ asm( "adc r2, r5, #0 " ); \
+ asm( "str r7, [r1], #4 " );
+
+#define MULADDC_STOP \
+ asm( "str r2, %0 " : "=m" (c)); \
+ asm( "str r1, %0 " : "=m" (d)); \
+ asm( "str r0, %0 " : "=m" (s) :: \
+ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7" );
+
+#endif /* ARMv3 */
+
+#if defined(__alpha__)
+
+#define MULADDC_INIT \
+ asm( "ldq $1, %0 " :: "m" (s)); \
+ asm( "ldq $2, %0 " :: "m" (d)); \
+ asm( "ldq $3, %0 " :: "m" (c)); \
+ asm( "ldq $4, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "ldq $6, 0($1) " ); \
+ asm( "addq $1, 8, $1 " ); \
+ asm( "mulq $6, $4, $7 " ); \
+ asm( "umulh $6, $4, $6 " ); \
+ asm( "addq $7, $3, $7 " ); \
+ asm( "cmpult $7, $3, $3 " ); \
+ asm( "ldq $5, 0($2) " ); \
+ asm( "addq $7, $5, $7 " ); \
+ asm( "cmpult $7, $5, $5 " ); \
+ asm( "stq $7, 0($2) " ); \
+ asm( "addq $2, 8, $2 " ); \
+ asm( "addq $6, $3, $3 " ); \
+ asm( "addq $5, $3, $3 " );
+
+#define MULADDC_STOP \
+ asm( "stq $3, %0 " : "=m" (c)); \
+ asm( "stq $2, %0 " : "=m" (d)); \
+ asm( "stq $1, %0 " : "=m" (s) :: \
+ "$1", "$2", "$3", "$4", "$5", "$6", "$7" );
+
+#endif /* Alpha */
+
+#if defined(__mips__)
+
+#define MULADDC_INIT \
+ asm( "lw $10, %0 " :: "m" (s)); \
+ asm( "lw $11, %0 " :: "m" (d)); \
+ asm( "lw $12, %0 " :: "m" (c)); \
+ asm( "lw $13, %0 " :: "m" (b));
+
+#define MULADDC_CORE \
+ asm( "lw $14, 0($10) " ); \
+ asm( "multu $13, $14 " ); \
+ asm( "addi $10, $10, 4 " ); \
+ asm( "mflo $14 " ); \
+ asm( "mfhi $9 " ); \
+ asm( "addu $14, $12, $14 " ); \
+ asm( "lw $15, 0($11) " ); \
+ asm( "sltu $12, $14, $12 " ); \
+ asm( "addu $15, $14, $15 " ); \
+ asm( "sltu $14, $15, $14 " ); \
+ asm( "addu $12, $12, $9 " ); \
+ asm( "sw $15, 0($11) " ); \
+ asm( "addu $12, $12, $14 " ); \
+ asm( "addi $11, $11, 4 " );
+
+#define MULADDC_STOP \
+ asm( "sw $12, %0 " : "=m" (c)); \
+ asm( "sw $11, %0 " : "=m" (d)); \
+ asm( "sw $10, %0 " : "=m" (s) :: \
+ "$9", "$10", "$11", "$12", "$13", "$14", "$15" );
+
+#endif /* MIPS */
+#endif /* GNUC */
+
+#if (defined(_MSC_VER) && defined(_M_IX86)) || defined(__WATCOMC__)
+
+#define MULADDC_INIT \
+ __asm mov esi, s \
+ __asm mov edi, d \
+ __asm mov ecx, c \
+ __asm mov ebx, b
+
+#define MULADDC_CORE \
+ __asm lodsd \
+ __asm mul ebx \
+ __asm add eax, ecx \
+ __asm adc edx, 0 \
+ __asm add eax, [edi] \
+ __asm adc edx, 0 \
+ __asm mov ecx, edx \
+ __asm stosd
+
+#if defined(POLARSSL_HAVE_SSE2)
+
+#define EMIT __asm _emit
+
+#define MULADDC_HUIT \
+ EMIT 0x0F EMIT 0x6E EMIT 0xC9 \
+ EMIT 0x0F EMIT 0x6E EMIT 0xC3 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x1F \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x6E EMIT 0x16 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x04 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x08 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x7E EMIT 0x0C \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF8 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
+ EMIT 0x0F EMIT 0x6E EMIT 0x5F EMIT 0x04 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xDC \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x08 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xEE \
+ EMIT 0x0F EMIT 0x6E EMIT 0x67 EMIT 0x0C \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xFC \
+ EMIT 0x0F EMIT 0x7E EMIT 0x0F \
+ EMIT 0x0F EMIT 0x6E EMIT 0x56 EMIT 0x10 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD0 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x66 EMIT 0x14 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xE0 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x6E EMIT 0x76 EMIT 0x18 \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xF0 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x04 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x6E EMIT 0x5E EMIT 0x1C \
+ EMIT 0x0F EMIT 0xF4 EMIT 0xD8 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCD \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x10 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xD5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x08 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCF \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x14 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xE5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x0C \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCA \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x18 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xF5 \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x10 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCC \
+ EMIT 0x0F EMIT 0x6E EMIT 0x6F EMIT 0x1C \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xDD \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x14 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCE \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x18 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0xD4 EMIT 0xCB \
+ EMIT 0x0F EMIT 0x7E EMIT 0x4F EMIT 0x1C \
+ EMIT 0x83 EMIT 0xC7 EMIT 0x20 \
+ EMIT 0x83 EMIT 0xC6 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x73 EMIT 0xD1 EMIT 0x20 \
+ EMIT 0x0F EMIT 0x7E EMIT 0xC9
+
+#define MULADDC_STOP \
+ EMIT 0x0F EMIT 0x77 \
+ __asm mov c, ecx \
+ __asm mov d, edi \
+ __asm mov s, esi \
+
+#else
+
+#define MULADDC_STOP \
+ __asm mov c, ecx \
+ __asm mov d, edi \
+ __asm mov s, esi \
+
+#endif /* SSE2 */
+#endif /* MSVC */
+
+#endif /* POLARSSL_HAVE_ASM */
+
+#if !defined(MULADDC_CORE)
+#if defined(POLARSSL_HAVE_LONGLONG)
+
+#define MULADDC_INIT \
+{ \
+ t_dbl r; \
+ t_int r0, r1;
+
+#define MULADDC_CORE \
+ r = *(s++) * (t_dbl) b; \
+ r0 = r; \
+ r1 = r >> biL; \
+ r0 += c; r1 += (r0 < c); \
+ r0 += *d; r1 += (r0 < *d); \
+ c = r1; *(d++) = r0;
+
+#define MULADDC_STOP \
+}
+
+#else
+#define MULADDC_INIT \
+{ \
+ t_int s0, s1, b0, b1; \
+ t_int r0, r1, rx, ry; \
+ b0 = ( b << biH ) >> biH; \
+ b1 = ( b >> biH );
+
+#define MULADDC_CORE \
+ s0 = ( *s << biH ) >> biH; \
+ s1 = ( *s >> biH ); s++; \
+ rx = s0 * b1; r0 = s0 * b0; \
+ ry = s1 * b0; r1 = s1 * b1; \
+ r1 += ( rx >> biH ); \
+ r1 += ( ry >> biH ); \
+ rx <<= biH; ry <<= biH; \
+ r0 += rx; r1 += (r0 < rx); \
+ r0 += ry; r1 += (r0 < ry); \
+ r0 += c; r1 += (r0 < c); \
+ r0 += *d; r1 += (r0 < *d); \
+ c = r1; *(d++) = r0;
+
+#define MULADDC_STOP \
+}
+
+#endif /* C (generic) */
+#endif /* C (longlong) */
+
+#endif /* bn_mul.h */
diff --git a/package/utils/px5g-standalone/src/polarssl/config.h b/package/utils/px5g-standalone/src/polarssl/config.h
new file mode 100644
index 0000000..79cd3db
--- /dev/null
+++ b/package/utils/px5g-standalone/src/polarssl/config.h
@@ -0,0 +1,329 @@
+/**
+ * \file config.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This set of compile-time options may be used to enable
+ * or disable features selectively, and reduce the global
+ * memory footprint.
+ */
+#ifndef POLARSSL_CONFIG_H
+#define POLARSSL_CONFIG_H
+
+#ifndef _CRT_SECURE_NO_DEPRECATE
+#define _CRT_SECURE_NO_DEPRECATE 1
+#endif
+
+/*
+ * Uncomment if native integers are 8-bit wide.
+ *
+#define POLARSSL_HAVE_INT8
+ */
+
+/*
+ * Uncomment if native integers are 16-bit wide.
+ *
+#define POLARSSL_HAVE_INT16
+ */
+
+/*
+ * Uncomment if the compiler supports long long.
+#define POLARSSL_HAVE_LONGLONG
+ */
+
+
+/*
+ * Uncomment to enable the use of assembly code.
+ */
+/* #define POLARSSL_HAVE_ASM */
+
+/*
+ * Uncomment if the CPU supports SSE2 (IA-32 specific).
+ *
+#define POLARSSL_HAVE_SSE2
+ */
+
+/*
+ * Enable all SSL/TLS debugging messages.
+ */
+#define POLARSSL_DEBUG_MSG
+
+/*
+ * Enable the checkup functions (*_self_test).
+ */
+#define POLARSSL_SELF_TEST
+
+/*
+ * Enable the prime-number generation code.
+ */
+#define POLARSSL_GENPRIME
+
+/*
+ * Uncomment this macro to store the AES tables in ROM.
+ *
+#define POLARSSL_AES_ROM_TABLES
+ */
+
+/*
+ * Module: library/aes.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites:
+ * SSL_RSA_AES_128_SHA
+ * SSL_RSA_AES_256_SHA
+ * SSL_EDH_RSA_AES_256_SHA
+ */
+#define POLARSSL_AES_C
+
+/*
+ * Module: library/arc4.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites:
+ * SSL_RSA_RC4_128_MD5
+ * SSL_RSA_RC4_128_SHA
+ */
+#define POLARSSL_ARC4_C
+
+/*
+ * Module: library/base64.c
+ * Caller: library/x509parse.c
+ *
+ * This module is required for X.509 support.
+ */
+#define POLARSSL_BASE64_C
+
+/*
+ * Module: library/bignum.c
+ * Caller: library/dhm.c
+ * library/rsa.c
+ * library/ssl_tls.c
+ * library/x509parse.c
+ *
+ * This module is required for RSA and DHM support.
+ */
+#define POLARSSL_BIGNUM_C
+
+/*
+ * Module: library/camellia.c
+ * Caller:
+ *
+ * This module enabled the following cipher suites:
+ */
+#define POLARSSL_CAMELLIA_C
+
+/*
+ * Module: library/certs.c
+ * Caller:
+ *
+ * This module is used for testing (ssl_client/server).
+ */
+#define POLARSSL_CERTS_C
+
+/*
+ * Module: library/debug.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * This module provides debugging functions.
+ */
+#define POLARSSL_DEBUG_C
+
+/*
+ * Module: library/des.c
+ * Caller: library/ssl_tls.c
+ *
+ * This module enables the following ciphersuites:
+ * SSL_RSA_DES_168_SHA
+ * SSL_EDH_RSA_DES_168_SHA
+ */
+#define POLARSSL_DES_C
+
+/*
+ * Module: library/dhm.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module enables the following ciphersuites:
+ * SSL_EDH_RSA_DES_168_SHA
+ * SSL_EDH_RSA_AES_256_SHA
+ */
+#define POLARSSL_DHM_C
+
+/*
+ * Module: library/havege.c
+ * Caller:
+ *
+ * This module enables the HAVEGE random number generator.
+ */
+#define POLARSSL_HAVEGE_C
+
+/*
+ * Module: library/md2.c
+ * Caller: library/x509parse.c
+ *
+ * Uncomment to enable support for (rare) MD2-signed X.509 certs.
+ *
+#define POLARSSL_MD2_C
+ */
+
+/*
+ * Module: library/md4.c
+ * Caller: library/x509parse.c
+ *
+ * Uncomment to enable support for (rare) MD4-signed X.509 certs.
+ *
+#define POLARSSL_MD4_C
+ */
+
+/*
+ * Module: library/md5.c
+ * Caller: library/ssl_tls.c
+ * library/x509parse.c
+ *
+ * This module is required for SSL/TLS and X.509.
+ */
+#define POLARSSL_MD5_C
+
+/*
+ * Module: library/net.c
+ * Caller:
+ *
+ * This module provides TCP/IP networking routines.
+ */
+#define POLARSSL_NET_C
+
+/*
+ * Module: library/padlock.c
+ * Caller: library/aes.c
+ *
+ * This modules adds support for the VIA PadLock on x86.
+ */
+#define POLARSSL_PADLOCK_C
+
+/*
+ * Module: library/rsa.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ * library/x509.c
+ *
+ * This module is required for SSL/TLS and MD5-signed certificates.
+ */
+#define POLARSSL_RSA_C
+
+/*
+ * Module: library/sha1.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ * library/x509parse.c
+ *
+ * This module is required for SSL/TLS and SHA1-signed certificates.
+ */
+#define POLARSSL_SHA1_C
+
+/*
+ * Module: library/sha2.c
+ * Caller:
+ *
+ * This module adds support for SHA-224 and SHA-256.
+ */
+#define POLARSSL_SHA2_C
+
+/*
+ * Module: library/sha4.c
+ * Caller:
+ *
+ * This module adds support for SHA-384 and SHA-512.
+ */
+#define POLARSSL_SHA4_C
+
+/*
+ * Module: library/ssl_cli.c
+ * Caller:
+ *
+ * This module is required for SSL/TLS client support.
+ */
+#define POLARSSL_SSL_CLI_C
+
+/*
+ * Module: library/ssl_srv.c
+ * Caller:
+ *
+ * This module is required for SSL/TLS server support.
+ */
+#define POLARSSL_SSL_SRV_C
+
+/*
+ * Module: library/ssl_tls.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ *
+ * This module is required for SSL/TLS.
+ */
+#define POLARSSL_SSL_TLS_C
+
+/*
+ * Module: library/timing.c
+ * Caller: library/havege.c
+ *
+ * This module is used by the HAVEGE random number generator.
+ */
+#define POLARSSL_TIMING_C
+
+/*
+ * Module: library/x509parse.c
+ * Caller: library/ssl_cli.c
+ * library/ssl_srv.c
+ * library/ssl_tls.c
+ *
+ * This module is required for X.509 certificate parsing.
+ */
+#define POLARSSL_X509_PARSE_C
+
+/*
+ * Module: library/x509_write.c
+ * Caller:
+ *
+ * This module is required for X.509 certificate writing.
+ */
+#define POLARSSL_X509_WRITE_C
+
+/*
+ * Module: library/xtea.c
+ * Caller:
+ */
+#define POLARSSL_XTEA_C
+
+#endif /* config.h */
diff --git a/package/utils/px5g-standalone/src/polarssl/rsa.h b/package/utils/px5g-standalone/src/polarssl/rsa.h
new file mode 100644
index 0000000..b31dc2f
--- /dev/null
+++ b/package/utils/px5g-standalone/src/polarssl/rsa.h
@@ -0,0 +1,309 @@
+/**
+ * \file rsa.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef POLARSSL_RSA_H
+#define POLARSSL_RSA_H
+
+#include "polarssl/bignum.h"
+
+#define POLARSSL_ERR_RSA_BAD_INPUT_DATA -0x0400
+#define POLARSSL_ERR_RSA_INVALID_PADDING -0x0410
+#define POLARSSL_ERR_RSA_KEY_GEN_FAILED -0x0420
+#define POLARSSL_ERR_RSA_KEY_CHECK_FAILED -0x0430
+#define POLARSSL_ERR_RSA_PUBLIC_FAILED -0x0440
+#define POLARSSL_ERR_RSA_PRIVATE_FAILED -0x0450
+#define POLARSSL_ERR_RSA_VERIFY_FAILED -0x0460
+#define POLARSSL_ERR_RSA_OUTPUT_TO_LARGE -0x0470
+
+/*
+ * PKCS#1 constants
+ */
+#define RSA_RAW 0
+#define RSA_MD2 2
+#define RSA_MD4 3
+#define RSA_MD5 4
+#define RSA_SHA1 5
+#define RSA_SHA256 6
+
+#define RSA_PUBLIC 0
+#define RSA_PRIVATE 1
+
+#define RSA_PKCS_V15 0
+#define RSA_PKCS_V21 1
+
+#define RSA_SIGN 1
+#define RSA_CRYPT 2
+
+/*
+ * DigestInfo ::= SEQUENCE {
+ * digestAlgorithm DigestAlgorithmIdentifier,
+ * digest Digest }
+ *
+ * DigestAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * Digest ::= OCTET STRING
+ */
+#define ASN1_HASH_MDX \
+ "\x30\x20\x30\x0C\x06\x08\x2A\x86\x48" \
+ "\x86\xF7\x0D\x02\x00\x05\x00\x04\x10"
+
+#define ASN1_HASH_SHA1 \
+ "\x30\x21\x30\x09\x06\x05\x2B\x0E\x03" \
+ "\x02\x1A\x05\x00\x04\x14"
+
+/**
+ * \brief RSA context structure
+ */
+typedef struct
+{
+ int ver; /*!< always 0 */
+ int len; /*!< size(N) in chars */
+
+ mpi N; /*!< public modulus */
+ mpi E; /*!< public exponent */
+
+ mpi D; /*!< private exponent */
+ mpi P; /*!< 1st prime factor */
+ mpi Q; /*!< 2nd prime factor */
+ mpi DP; /*!< D % (P - 1) */
+ mpi DQ; /*!< D % (Q - 1) */
+ mpi QP; /*!< 1 / (Q % P) */
+
+ mpi RN; /*!< cached R^2 mod N */
+ mpi RP; /*!< cached R^2 mod P */
+ mpi RQ; /*!< cached R^2 mod Q */
+
+ int padding; /*!< 1.5 or OAEP/PSS */
+ int hash_id; /*!< hash identifier */
+ int (*f_rng)(void *); /*!< RNG function */
+ void *p_rng; /*!< RNG parameter */
+}
+rsa_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Initialize an RSA context
+ *
+ * \param ctx RSA context to be initialized
+ * \param padding RSA_PKCS_V15 or RSA_PKCS_V21
+ * \param hash_id RSA_PKCS_V21 hash identifier
+ * \param f_rng RNG function
+ * \param p_rng RNG parameter
+ *
+ * \note The hash_id parameter is actually ignored
+ * when using RSA_PKCS_V15 padding.
+ *
+ * \note Currently (xyssl-0.8), RSA_PKCS_V21 padding
+ * is not supported.
+ */
+void rsa_init( rsa_context *ctx,
+ int padding,
+ int hash_id,
+ int (*f_rng)(void *),
+ void *p_rng );
+
+/**
+ * \brief Generate an RSA keypair
+ *
+ * \param ctx RSA context that will hold the key
+ * \param nbits size of the public key in bits
+ * \param exponent public exponent (e.g., 65537)
+ *
+ * \note rsa_init() must be called beforehand to setup
+ * the RSA context (especially f_rng and p_rng).
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_gen_key( rsa_context *ctx, int nbits, int exponent );
+
+/**
+ * \brief Check a public RSA key
+ *
+ * \param ctx RSA context to be checked
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_check_pubkey( rsa_context *ctx );
+
+/**
+ * \brief Check a private RSA key
+ *
+ * \param ctx RSA context to be checked
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ */
+int rsa_check_privkey( rsa_context *ctx );
+
+/**
+ * \brief Do an RSA public key operation
+ *
+ * \param ctx RSA context
+ * \param input input buffer
+ * \param output output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note This function does NOT take care of message
+ * padding. Also, be sure to set input[0] = 0.
+ *
+ * \note The input and output buffers must be large
+ * enough (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_public( rsa_context *ctx,
+ unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Do an RSA private key operation
+ *
+ * \param ctx RSA context
+ * \param input input buffer
+ * \param output output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The input and output buffers must be large
+ * enough (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_private( rsa_context *ctx,
+ unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Add the message padding, then do an RSA operation
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param ilen contains the the plaintext length
+ * \param input buffer holding the data to be encrypted
+ * \param output buffer that will hold the ciphertext
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_pkcs1_encrypt( rsa_context *ctx,
+ int mode, int ilen,
+ unsigned char *input,
+ unsigned char *output );
+
+/**
+ * \brief Do an RSA operation, then remove the message padding
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param input buffer holding the encrypted data
+ * \param output buffer that will hold the plaintext
+ * \param olen will contain the plaintext length
+ * \param output_max_len maximum length of the output buffer
+ *
+ * \return 0 if successful, or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The output buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used) otherwise
+ * an error is thrown.
+ */
+int rsa_pkcs1_decrypt( rsa_context *ctx,
+ int mode, int *olen,
+ unsigned char *input,
+ unsigned char *output,
+ int output_max_len);
+
+/**
+ * \brief Do a private RSA to sign a message digest
+ *
+ * \param ctx RSA context
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
+ * \param hashlen message digest length (for RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer that will hold the ciphertext
+ *
+ * \return 0 if the signing operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_pkcs1_sign( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief Do a public RSA and check the message digest
+ *
+ * \param ctx points to an RSA public key
+ * \param mode RSA_PUBLIC or RSA_PRIVATE
+ * \param hash_id RSA_RAW, RSA_MD{2,4,5} or RSA_SHA{1,256}
+ * \param hashlen message digest length (for RSA_RAW only)
+ * \param hash buffer holding the message digest
+ * \param sig buffer holding the ciphertext
+ *
+ * \return 0 if the verify operation was successful,
+ * or an POLARSSL_ERR_RSA_XXX error code
+ *
+ * \note The "sig" buffer must be as large as the size
+ * of ctx->N (eg. 128 bytes if RSA-1024 is used).
+ */
+int rsa_pkcs1_verify( rsa_context *ctx,
+ int mode,
+ int hash_id,
+ int hashlen,
+ unsigned char *hash,
+ unsigned char *sig );
+
+/**
+ * \brief Free the components of an RSA key
+ */
+void rsa_free( rsa_context *ctx );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int rsa_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* rsa.h */
diff --git a/package/utils/px5g-standalone/src/polarssl/sha1.h b/package/utils/px5g-standalone/src/polarssl/sha1.h
new file mode 100644
index 0000000..3ca7dc3
--- /dev/null
+++ b/package/utils/px5g-standalone/src/polarssl/sha1.h
@@ -0,0 +1,150 @@
+/**
+ * \file sha1.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef POLARSSL_SHA1_H
+#define POLARSSL_SHA1_H
+
+/**
+ * \brief SHA-1 context structure
+ */
+typedef struct
+{
+ unsigned long total[2]; /*!< number of bytes processed */
+ unsigned long state[5]; /*!< intermediate digest state */
+ unsigned char buffer[64]; /*!< data block being processed */
+
+ unsigned char ipad[64]; /*!< HMAC: inner padding */
+ unsigned char opad[64]; /*!< HMAC: outer padding */
+}
+sha1_context;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief SHA-1 context setup
+ *
+ * \param ctx context to be initialized
+ */
+void sha1_starts( sha1_context *ctx );
+
+/**
+ * \brief SHA-1 process buffer
+ *
+ * \param ctx SHA-1 context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ */
+void sha1_update( sha1_context *ctx, unsigned char *input, int ilen );
+
+/**
+ * \brief SHA-1 final digest
+ *
+ * \param ctx SHA-1 context
+ * \param output SHA-1 checksum result
+ */
+void sha1_finish( sha1_context *ctx, unsigned char output[20] );
+
+/**
+ * \brief Output = SHA-1( input buffer )
+ *
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output SHA-1 checksum result
+ */
+void sha1( unsigned char *input, int ilen, unsigned char output[20] );
+
+/**
+ * \brief Output = SHA-1( file contents )
+ *
+ * \param path input file name
+ * \param output SHA-1 checksum result
+ *
+ * \return 0 if successful, 1 if fopen failed,
+ * or 2 if fread failed
+ */
+int sha1_file( char *path, unsigned char output[20] );
+
+/**
+ * \brief SHA-1 HMAC context setup
+ *
+ * \param ctx HMAC context to be initialized
+ * \param key HMAC secret key
+ * \param keylen length of the HMAC key
+ */
+void sha1_hmac_starts( sha1_context *ctx, unsigned char *key, int keylen );
+
+/**
+ * \brief SHA-1 HMAC process buffer
+ *
+ * \param ctx HMAC context
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ */
+void sha1_hmac_update( sha1_context *ctx, unsigned char *input, int ilen );
+
+/**
+ * \brief SHA-1 HMAC final digest
+ *
+ * \param ctx HMAC context
+ * \param output SHA-1 HMAC checksum result
+ */
+void sha1_hmac_finish( sha1_context *ctx, unsigned char output[20] );
+
+/**
+ * \brief Output = HMAC-SHA-1( hmac key, input buffer )
+ *
+ * \param key HMAC secret key
+ * \param keylen length of the HMAC key
+ * \param input buffer holding the data
+ * \param ilen length of the input data
+ * \param output HMAC-SHA-1 result
+ */
+void sha1_hmac( unsigned char *key, int keylen,
+ unsigned char *input, int ilen,
+ unsigned char output[20] );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int sha1_self_test( int verbose );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* sha1.h */
diff --git a/package/utils/px5g-standalone/src/polarssl/timing.h b/package/utils/px5g-standalone/src/polarssl/timing.h
new file mode 100644
index 0000000..62d627f
--- /dev/null
+++ b/package/utils/px5g-standalone/src/polarssl/timing.h
@@ -0,0 +1,81 @@
+/**
+ * \file timing.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef POLARSSL_TIMING_H
+#define POLARSSL_TIMING_H
+
+/**
+ * \brief timer structure
+ */
+struct hr_time
+{
+ unsigned char opaque[32];
+};
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int alarmed;
+
+/**
+ * \brief Return the CPU cycle counter value
+ */
+unsigned long hardclock( void );
+
+/**
+ * \brief Return the elapsed time in milliseconds
+ *
+ * \param val points to a timer structure
+ * \param reset if set to 1, the timer is restarted
+ */
+unsigned long get_timer( struct hr_time *val, int reset );
+
+/**
+ * \brief Setup an alarm clock
+ *
+ * \param seconds delay before the "alarmed" flag is set
+ */
+void set_alarm( int seconds );
+
+/**
+ * \brief Sleep for a certain amount of time
+ */
+void m_sleep( int milliseconds );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* timing.h */
diff --git a/package/utils/px5g-standalone/src/polarssl/x509.h b/package/utils/px5g-standalone/src/polarssl/x509.h
new file mode 100644
index 0000000..908a1db
--- /dev/null
+++ b/package/utils/px5g-standalone/src/polarssl/x509.h
@@ -0,0 +1,549 @@
+/**
+ * \file x509.h
+ *
+ * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
+ *
+ * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the names of PolarSSL or XySSL nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+ * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef POLARSSL_X509_H
+#define POLARSSL_X509_H
+
+#include "polarssl/rsa.h"
+
+#define POLARSSL_ERR_ASN1_OUT_OF_DATA -0x0014
+#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG -0x0016
+#define POLARSSL_ERR_ASN1_INVALID_LENGTH -0x0018
+#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH -0x001A
+#define POLARSSL_ERR_ASN1_INVALID_DATA -0x001C
+
+#define POLARSSL_ERR_X509_FEATURE_UNAVAILABLE -0x0020
+#define POLARSSL_ERR_X509_CERT_INVALID_PEM -0x0040
+#define POLARSSL_ERR_X509_CERT_INVALID_FORMAT -0x0060
+#define POLARSSL_ERR_X509_CERT_INVALID_VERSION -0x0080
+#define POLARSSL_ERR_X509_CERT_INVALID_SERIAL -0x00A0
+#define POLARSSL_ERR_X509_CERT_INVALID_ALG -0x00C0
+#define POLARSSL_ERR_X509_CERT_INVALID_NAME -0x00E0
+#define POLARSSL_ERR_X509_CERT_INVALID_DATE -0x0100
+#define POLARSSL_ERR_X509_CERT_INVALID_PUBKEY -0x0120
+#define POLARSSL_ERR_X509_CERT_INVALID_SIGNATURE -0x0140
+#define POLARSSL_ERR_X509_CERT_INVALID_EXTENSIONS -0x0160
+#define POLARSSL_ERR_X509_CERT_UNKNOWN_VERSION -0x0180
+#define POLARSSL_ERR_X509_CERT_UNKNOWN_SIG_ALG -0x01A0
+#define POLARSSL_ERR_X509_CERT_UNKNOWN_PK_ALG -0x01C0
+#define POLARSSL_ERR_X509_CERT_SIG_MISMATCH -0x01E0
+#define POLARSSL_ERR_X509_CERT_VERIFY_FAILED -0x0200
+#define POLARSSL_ERR_X509_KEY_INVALID_PEM -0x0220
+#define POLARSSL_ERR_X509_KEY_INVALID_VERSION -0x0240
+#define POLARSSL_ERR_X509_KEY_INVALID_FORMAT -0x0260
+#define POLARSSL_ERR_X509_KEY_INVALID_ENC_IV -0x0280
+#define POLARSSL_ERR_X509_KEY_UNKNOWN_ENC_ALG -0x02A0
+#define POLARSSL_ERR_X509_KEY_PASSWORD_REQUIRED -0x02C0
+#define POLARSSL_ERR_X509_KEY_PASSWORD_MISMATCH -0x02E0
+#define POLARSSL_ERR_X509_POINT_ERROR -0x0300
+#define POLARSSL_ERR_X509_VALUE_TO_LENGTH -0x0320
+
+#define BADCERT_EXPIRED 1
+#define BADCERT_REVOKED 2
+#define BADCERT_CN_MISMATCH 4
+#define BADCERT_NOT_TRUSTED 8
+
+/*
+ * DER constants
+ */
+#define ASN1_BOOLEAN 0x01
+#define ASN1_INTEGER 0x02
+#define ASN1_BIT_STRING 0x03
+#define ASN1_OCTET_STRING 0x04
+#define ASN1_NULL 0x05
+#define ASN1_OID 0x06
+#define ASN1_UTF8_STRING 0x0C
+#define ASN1_SEQUENCE 0x10
+#define ASN1_SET 0x11
+#define ASN1_PRINTABLE_STRING 0x13
+#define ASN1_T61_STRING 0x14
+#define ASN1_IA5_STRING 0x16
+#define ASN1_UTC_TIME 0x17
+#define ASN1_UNIVERSAL_STRING 0x1C
+#define ASN1_BMP_STRING 0x1E
+#define ASN1_PRIMITIVE 0x00
+#define ASN1_CONSTRUCTED 0x20
+#define ASN1_CONTEXT_SPECIFIC 0x80
+
+/*
+ * various object identifiers
+ */
+#define X520_COMMON_NAME 3
+#define X520_COUNTRY 6
+#define X520_LOCALITY 7
+#define X520_STATE 8
+#define X520_ORGANIZATION 10
+#define X520_ORG_UNIT 11
+#define PKCS9_EMAIL 1
+
+#define X509_OUTPUT_DER 0x01
+#define X509_OUTPUT_PEM 0x02
+#define PEM_LINE_LENGTH 72
+#define X509_ISSUER 0x01
+#define X509_SUBJECT 0x02
+
+#define OID_X520 "\x55\x04"
+#define OID_CN "\x55\x04\x03"
+#define OID_PKCS1 "\x2A\x86\x48\x86\xF7\x0D\x01\x01"
+#define OID_PKCS1_RSA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x01"
+#define OID_PKCS1_RSA_SHA "\x2A\x86\x48\x86\xF7\x0D\x01\x01\x05"
+#define OID_PKCS9 "\x2A\x86\x48\x86\xF7\x0D\x01\x09"
+#define OID_PKCS9_EMAIL "\x2A\x86\x48\x86\xF7\x0D\x01\x09\x01"
+
+/*
+ * Structures for parsing X.509 certificates
+ */
+typedef struct _x509_buf
+{
+ int tag;
+ int len;
+ unsigned char *p;
+}
+x509_buf;
+
+typedef struct _x509_name
+{
+ x509_buf oid;
+ x509_buf val;
+ struct _x509_name *next;
+}
+x509_name;
+
+typedef struct _x509_time
+{
+ int year, mon, day;
+ int hour, min, sec;
+}
+x509_time;
+
+typedef struct _x509_cert
+{
+ x509_buf raw;
+ x509_buf tbs;
+
+ int version;
+ x509_buf serial;
+ x509_buf sig_oid1;
+
+ x509_buf issuer_raw;
+ x509_buf subject_raw;
+
+ x509_name issuer;
+ x509_name subject;
+
+ x509_time valid_from;
+ x509_time valid_to;
+
+ x509_buf pk_oid;
+ rsa_context rsa;
+
+ x509_buf issuer_id;
+ x509_buf subject_id;
+ x509_buf v3_ext;
+
+ int ca_istrue;
+ int max_pathlen;
+
+ x509_buf sig_oid2;
+ x509_buf sig;
+
+ struct _x509_cert *next;
+}
+x509_cert;
+
+/*
+ * Structures for writing X.509 certificates
+ */
+typedef struct _x509_node
+{
+ unsigned char *data;
+ unsigned char *p;
+ unsigned char *end;
+
+ size_t len;
+}
+x509_node;
+
+typedef struct _x509_raw
+{
+ x509_node raw;
+ x509_node tbs;
+
+ x509_node version;
+ x509_node serial;
+ x509_node tbs_signalg;
+ x509_node issuer;
+ x509_node validity;
+ x509_node subject;
+ x509_node subpubkey;
+
+ x509_node signalg;
+ x509_node sign;
+}
+x509_raw;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Parse one or more certificates and add them
+ * to the chained list
+ *
+ * \param chain points to the start of the chain
+ * \param buf buffer holding the certificate data
+ * \param buflen size of the buffer
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509parse_crt( x509_cert *crt, unsigned char *buf, int buflen );
+
+/**
+ * \brief Load one or more certificates and add them
+ * to the chained list
+ *
+ * \param chain points to the start of the chain
+ * \param path filename to read the certificates from
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509parse_crtfile( x509_cert *crt, char *path );
+
+/**
+ * \brief Parse a private RSA key
+ *
+ * \param rsa RSA context to be initialized
+ * \param buf input buffer
+ * \param buflen size of the buffer
+ * \param pwd password for decryption (optional)
+ * \param pwdlen size of the password
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509parse_key( rsa_context *rsa,
+ unsigned char *buf, int buflen,
+ unsigned char *pwd, int pwdlen );
+
+/**
+ * \brief Load and parse a private RSA key
+ *
+ * \param rsa RSA context to be initialized
+ * \param path filename to read the private key from
+ * \param pwd password to decrypt the file (can be NULL)
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509parse_keyfile( rsa_context *rsa, char *path, char *password );
+
+/**
+ * \brief Store the certificate DN in printable form into buf;
+ * no more than (end - buf) characters will be written.
+ */
+int x509parse_dn_gets( char *buf, char *end, x509_name *dn );
+
+/**
+ * \brief Returns an informational string about the
+ * certificate.
+ */
+char *x509parse_cert_info( char *prefix, x509_cert *crt );
+
+/**
+ * \brief Return 0 if the certificate is still valid,
+ * or BADCERT_EXPIRED
+ */
+int x509parse_expired( x509_cert *crt );
+
+/**
+ * \brief Verify the certificate signature
+ *
+ * \param crt a certificate to be verified
+ * \param trust_ca the trusted CA chain
+ * \param cn expected Common Name (can be set to
+ * NULL if the CN must not be verified)
+ * \param flags result of the verification
+ *
+ * \return 0 if successful or POLARSSL_ERR_X509_SIG_VERIFY_FAILED,
+ * in which case *flags will have one or more of
+ * the following values set:
+ * BADCERT_EXPIRED --
+ * BADCERT_REVOKED --
+ * BADCERT_CN_MISMATCH --
+ * BADCERT_NOT_TRUSTED
+ *
+ * \note TODO: add two arguments, depth and crl
+ */
+int x509parse_verify( x509_cert *crt,
+ x509_cert *trust_ca,
+ char *cn, int *flags );
+
+/**
+ * \brief Unallocate all certificate data
+ */
+void x509_free( x509_cert *crt );
+
+/**
+ * \brief Checkup routine
+ *
+ * \return 0 if successful, or 1 if the test failed
+ */
+int x509_self_test( int verbose );
+
+/**
+ * \brief Write a certificate info file
+ *
+ * \param chain points to the raw certificate data
+ * \param path filename to write the certificate to
+ * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_crtfile( x509_raw *chain,
+ unsigned char *path,
+ int format );
+
+/**
+ * \brief Write a certificate signing request message format file
+ *
+ * \param chain points to the raw certificate (with x509write_create_csr) data
+ * \param path filename to write the certificate to
+ * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_csrfile( x509_raw *chain,
+ unsigned char *path,
+ int format );
+
+/*
+ * \brief Write a private RSA key into a file
+ *
+ * \param rsa points to an RSA key
+ * \param path filename to write the key to
+ * \param format X509_OUTPUT_DER or X509_OUTPUT_PEM
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_keyfile( rsa_context *rsa,
+ char *path,
+ int format );
+
+/**
+ * \brief Add a public key to certificate
+ *
+ * \param chain points to the raw certificate data
+ * \param pubkey points to an RSA key
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_add_pubkey( x509_raw *chain, rsa_context *pubkey );
+
+/**
+ * \brief Create x509 subject/issuer field to raw certificate
+ * from string or CA cert. Make string NULL if you will
+ * use the CA copy function or make CA NULL then used
+ * the string parse.
+ *
+ * \param chain points to the raw certificate data
+ * \param names a string that can hold (separete with ";"):
+ * CN=CommonName
+ * -- O=Organization
+ * -- OU=OrgUnit
+ * -- ST=State
+ * -- L=Locality
+ * -- R=Email
+ * -- C=Country
+ * . Make that NULL if you didn't need that.
+ * \param flag flag is X509_ISSUER or X509_SUBJECT that defined
+ * where change
+ * \param ca the certificate for copy data. Make that NULL if you
+ * didn't need that.
+ * \param ca_flag set the ca field from copy to crt
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_add_customize ( x509_raw *crt,
+ unsigned char *names,
+ int flag,
+ x509_cert *ca,
+ int ca_flag );
+
+/**
+* \brief Add x509 issuer field
+*
+* \param chain points to the raw certificate data
+* \param issuer a string holding (separete with ";"):
+* CN=CommonName
+* -- O=Organization
+* -- OU=OrgUnit
+* -- ST=State
+* -- L=Locality
+* -- R=Email
+* -- C=Country
+* . Set this to NULL if not needed.
+* \return 0 if successful, or a specific X509 error code
+*/
+int x509write_add_issuer( x509_raw *crt, unsigned char *issuer);
+
+/**
+ * \brief Add x509 subject field
+ *
+ * \param chain points to the raw certificate data
+ * \param subject a string holding (separete with ";"):
+ * CN=CommonName
+ * -- O=Organization
+ * -- OU=OrgUnit
+ * -- ST=State
+ * -- L=Locality
+ * -- R=Email
+ * -- C=Country
+ * . Set this to NULL if not needed.
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_add_subject( x509_raw *crt, unsigned char *subject);
+
+/**
+* \brief Copy x509 issuer field from another certificate
+*
+* \param chain points to the raw certificate data
+* \param from_crt the certificate whose issuer is to be copied.
+* \return 0 if successful, or a specific X509 error code
+*/
+int x509write_copy_issuer(x509_raw *crt, x509_cert *from_crt);
+
+/**
+* \brief Copy x509 subject field from another certificate
+*
+* \param chain points to the raw certificate data
+* \param from_crt the certificate whose subject is to be copied.
+* \return 0 if successful, or a specific X509 error code
+*/
+int x509write_copy_subject(x509_raw *crt, x509_cert *from_crt);
+
+/**
+* \brief Copy x509 issuer field from the subject of another certificate
+*
+* \param chain points to the raw certificate data
+* \param from_crt the certificate whose subject is to be copied.
+* \return 0 if successful, or a specific X509 error code
+*/
+int x509write_copy_issuer_from_subject(x509_raw *crt, x509_cert *from_crt);
+
+/**
+* \brief Copy x509 subject field from the issuer of another certificate
+*
+* \param chain points to the raw certificate data
+* \param from_crt the certificate whose issuer is to be copied.
+* \return 0 if successful, or a specific X509 error code
+*/
+int x509write_copy_subject_from_issuer(x509_raw *crt, x509_cert *from_crt);
+
+/**
+ * \brief Create x509 validity time in UTC
+ *
+ * \param chain points to the raw certificate data
+ * \param before valid not before in format YYYY-MM-DD hh:mm:ss
+ * \param after valid not after in format YYYY-MM-DD hh:mm:ss
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_add_validity( x509_raw *crt,
+ unsigned char *before,
+ unsigned char *after );
+
+/**
+ * \brief Create a self-signed certificate
+ *
+ * \param chain points to the raw certificate data
+ * \param rsa a private key to sign the certificate
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_create_selfsign( x509_raw *crt, rsa_context *raw );
+
+/**
+ * \brief Create a certificate
+ *
+ * \param chain points to the raw certificate data
+ * \param rsa a private key to sign the certificate
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_create_sign( x509_raw *crt, rsa_context *raw );
+
+/**
+ * \brief Create a certificate signing request
+ *
+ * \param chain points to the raw certificate data. Didn't use the
+ * same chain that u have use for certificate.
+ * \param privkey a rsa private key
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_create_csr( x509_raw *chain, rsa_context *privkey );
+
+/**
+ * \brief Serialize an rsa key into DER
+ *
+ * \param rsa a rsa key for output
+ * \param node a x509 node for write into
+ *
+ * \return 0 if successful, or a specific X509 error code
+ */
+int x509write_serialize_key( rsa_context *rsa, x509_node *node );
+
+/**
+ * \brief Unallocate all raw certificate data
+ */
+void x509write_free_raw( x509_raw *crt );
+
+/**
+ * \brief Allocate all raw certificate data
+ */
+void x509write_init_raw( x509_raw *crt );
+
+/**
+ * \brief Unallocate all node certificate data
+ */
+void x509write_free_node( x509_node *crt_node );
+
+/**
+ * \brief Allocate all node certificate data
+ */
+void x509write_init_node( x509_node *crt_node );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* x509.h */
diff --git a/package/utils/px5g-standalone/src/px5g.c b/package/utils/px5g-standalone/src/px5g.c
new file mode 100644
index 0000000..34ab34f
--- /dev/null
+++ b/package/utils/px5g-standalone/src/px5g.c
@@ -0,0 +1,213 @@
+/*
+ * px5g - Embedded x509 key and certificate generator based on PolarSSL
+ *
+ * Copyright (C) 2009 Steven Barth <steven@midlink.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <limits.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "polarssl/bignum.h"
+#include "polarssl/x509.h"
+#include "polarssl/rsa.h"
+
+#define PX5G_VERSION "0.1"
+#define PX5G_COPY "Copyright (c) 2009 Steven Barth <steven@midlink.org>"
+#define PX5G_LICENSE "Licensed under the GNU Lesser General Public License v2.1"
+
+static int urandom_fd;
+
+static int _urandom(void *ctx)
+{
+ int ret;
+ read(urandom_fd, &ret, sizeof(ret));
+ return ret;
+}
+
+
+int rsakey(char **arg) {
+ rsa_context rsa;
+
+ unsigned int ksize = 512;
+ int exp = 65537;
+ char *path = NULL;
+ int flag = X509_OUTPUT_PEM;
+
+ while (*arg && **arg == '-') {
+ if (!strcmp(*arg, "-out") && arg[1]) {
+ path = arg[1];
+ arg++;
+ } else if (!strcmp(*arg, "-3")) {
+ exp = 3;
+ } else if (!strcmp(*arg, "-der")) {
+ flag = X509_OUTPUT_DER;
+ }
+ arg++;
+ }
+
+ if (*arg) {
+ ksize = (unsigned int)atoi(*arg);
+ }
+
+ rsa_init(&rsa, RSA_PKCS_V15, 0, _urandom, NULL);
+
+ fprintf(stderr, "Generating RSA private key, %i bit long modulus\n", ksize);
+ if (rsa_gen_key(&rsa, ksize, exp)) {
+ fprintf(stderr, "error: key generation failed\n");
+ return 1;
+ }
+
+ if (x509write_keyfile(&rsa, path, flag)) {
+ fprintf(stderr, "error: I/O error\n");
+ return 1;
+ }
+
+ rsa_free(&rsa);
+ return 0;
+}
+
+int selfsigned(char **arg) {
+ rsa_context rsa;
+ x509_node node;
+
+ char *subject = "";
+ unsigned int ksize = 512;
+ int exp = 65537;
+ unsigned int days = 30;
+ char *keypath = NULL, *certpath = NULL;
+ int flag = X509_OUTPUT_PEM;
+ time_t from = time(NULL), to;
+ char fstr[20], tstr[20];
+
+ while (*arg && **arg == '-') {
+ if (!strcmp(*arg, "-der")) {
+ flag = X509_OUTPUT_DER;
+ } else if (!strcmp(*arg, "-newkey") && arg[1]) {
+ if (strncmp(arg[1], "rsa:", 4)) {
+ fprintf(stderr, "error: invalid algorithm");
+ return 1;
+ }
+ ksize = (unsigned int)atoi(arg[1] + 4);
+ arg++;
+ } else if (!strcmp(*arg, "-days") && arg[1]) {
+ days = (unsigned int)atoi(arg[1]);
+ arg++;
+ } else if (!strcmp(*arg, "-keyout") && arg[1]) {
+ keypath = arg[1];
+ arg++;
+ } else if (!strcmp(*arg, "-out") && arg[1]) {
+ certpath = arg[1];
+ arg++;
+ } else if (!strcmp(*arg, "-subj") && arg[1]) {
+ if (arg[1][0] != '/' || strchr(arg[1], ';')) {
+ fprintf(stderr, "error: invalid subject");
+ return 1;
+ }
+ subject = calloc(strlen(arg[1]) + 1, 1);
+ char *oldc = arg[1] + 1, *newc = subject, *delim;
+ do {
+ delim = strchr(oldc, '=');
+ if (!delim) {
+ fprintf(stderr, "error: invalid subject");
+ return 1;
+ }
+ memcpy(newc, oldc, delim - oldc + 1);
+ newc += delim - oldc + 1;
+ oldc = delim + 1;
+
+ delim = strchr(oldc, '/');
+ if (!delim) {
+ delim = arg[1] + strlen(arg[1]);
+ }
+ memcpy(newc, oldc, delim - oldc);
+ newc += delim - oldc;
+ *newc++ = ';';
+ oldc = delim + 1;
+ } while(*delim);
+ arg++;
+ }
+ arg++;
+ }
+
+ rsa_init(&rsa, RSA_PKCS_V15, 0, _urandom, NULL);
+ x509write_init_node(&node);
+ fprintf(stderr, "Generating RSA private key, %i bit long modulus\n", ksize);
+ if (rsa_gen_key(&rsa, ksize, exp)) {
+ fprintf(stderr, "error: key generation failed\n");
+ return 1;
+ }
+
+ if (keypath) {
+ if (x509write_keyfile(&rsa, keypath, flag)) {
+ fprintf(stderr, "error: I/O error\n");
+ return 1;
+ }
+ }
+
+ from = (from < 1000000000) ? 1000000000 : from;
+ strftime(fstr, sizeof(fstr), "%F %H:%M:%S", gmtime(&from));
+ to = from + 60 * 60 * 24 * days;
+ if (to < from)
+ to = INT_MAX;
+ strftime(tstr, sizeof(tstr), "%F %H:%M:%S", gmtime(&to));
+
+ x509_raw cert;
+ x509write_init_raw(&cert);
+ x509write_add_pubkey(&cert, &rsa);
+ x509write_add_subject(&cert, (unsigned char*)subject);
+ x509write_add_validity(&cert, (unsigned char*)fstr, (unsigned char*)tstr);
+ fprintf(stderr, "Generating selfsigned certificate with subject '%s'"
+ " and validity %s-%s\n", subject, fstr, tstr);
+ if (x509write_create_selfsign(&cert, &rsa)) {
+ fprintf(stderr, "error: certificate generation failed\n");
+ }
+
+ if (x509write_crtfile(&cert, (unsigned char*)certpath, flag)) {
+ fprintf(stderr, "error: I/O error\n");
+ return 1;
+ }
+
+ x509write_free_raw(&cert);
+ rsa_free(&rsa);
+ return 0;
+}
+
+int main(int argc, char *argv[]) {
+ urandom_fd = open("/dev/urandom", O_RDONLY);
+ if (urandom_fd < 0) {
+ perror("open(/dev/urandom)");
+ return 1;
+ }
+
+ if (!argv[1]) {
+ //Usage
+ } else if (!strcmp(argv[1], "rsakey")) {
+ return rsakey(argv+2);
+ } else if (!strcmp(argv[1], "selfsigned")) {
+ return selfsigned(argv+2);
+ }
+
+ fprintf(stderr,
+ "PX5G X.509 Certificate Generator Utility v" PX5G_VERSION "\n" PX5G_COPY
+ "\nbased on PolarSSL by Christophe Devine and Paul Bakker\n\n");
+ fprintf(stderr, "Usage: %s [rsakey|selfsigned]\n", *argv);
+ return 1;
+}
diff --git a/package/utils/px5g/Makefile b/package/utils/px5g/Makefile
new file mode 100644
index 0000000..8677a8b
--- /dev/null
+++ b/package/utils/px5g/Makefile
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2010-2015 Jo-Philipp Wich <jow@openwrt.org>
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=px5g
+PKG_RELEASE:=3
+
+PKG_USE_MIPS16:=0
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/px5g
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=X.509 certificate generator (using PolarSSL)
+ MAINTAINER:=Jo-Philipp Wich <jow@openwrt.org>
+ DEPENDS:=+libpolarssl
+endef
+
+define Package/px5g/description
+ Px5g is a tiny standalone X.509 certificate generator.
+ It suitable to create key files and certificates in DER
+ and PEM format for use with stunnel, uhttpd and others.
+endef
+
+define Build/Prepare
+ mkdir -p $(PKG_BUILD_DIR)
+endef
+
+define Build/Compile
+ $(TARGET_CC) $(TARGET_CFLAGS) -o $(PKG_BUILD_DIR)/px5g px5g.c -lpolarssl
+endef
+
+define Package/px5g/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/px5g $(1)/usr/sbin/px5g
+endef
+
+$(eval $(call BuildPackage,px5g))
diff --git a/package/utils/px5g/px5g.c b/package/utils/px5g/px5g.c
new file mode 100644
index 0000000..eec8fd3
--- /dev/null
+++ b/package/utils/px5g/px5g.c
@@ -0,0 +1,273 @@
+/*
+ * px5g - Embedded x509 key and certificate generator based on PolarSSL
+ *
+ * Copyright (C) 2009 Steven Barth <steven@midlink.org>
+ * Copyright (C) 2014 Felix Fietkau <nbd@openwrt.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1 as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <sys/types.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdbool.h>
+
+#include <polarssl/bignum.h>
+#include <polarssl/x509_crt.h>
+#include <polarssl/rsa.h>
+
+#define PX5G_VERSION "0.2"
+#define PX5G_COPY "Copyright (c) 2009 Steven Barth <steven@midlink.org>"
+#define PX5G_LICENSE "Licensed under the GNU Lesser General Public License v2.1"
+
+static int urandom_fd;
+static char buf[16384];
+
+static int _urandom(void *ctx, unsigned char *out, size_t len)
+{
+ read(urandom_fd, out, len);
+ return 0;
+}
+
+static void write_file(const char *path, int len, bool pem)
+{
+ FILE *f = stdout;
+ const char *buf_start = buf;
+
+ if (!pem)
+ buf_start += sizeof(buf) - len;
+
+ if (!len) {
+ fprintf(stderr, "No data to write\n");
+ exit(1);
+ }
+
+ if (!f) {
+ fprintf(stderr, "error: I/O error\n");
+ exit(1);
+ }
+
+ if (path)
+ f = fopen(path, "w");
+
+ fwrite(buf_start, 1, len, f);
+ fclose(f);
+}
+
+static void write_key(pk_context *key, const char *path, bool pem)
+{
+ int len = 0;
+
+ if (pem) {
+ if (pk_write_key_pem(key, (void *) buf, sizeof(buf)) == 0)
+ len = strlen(buf);
+ } else {
+ len = pk_write_key_der(key, (void *) buf, sizeof(buf));
+ if (len < 0)
+ len = 0;
+ }
+
+ write_file(path, len, pem);
+}
+
+static void gen_key(pk_context *key, int ksize, int exp, bool pem)
+{
+ pk_init(key);
+ pk_init_ctx(key, pk_info_from_type(POLARSSL_PK_RSA));
+ fprintf(stderr, "Generating RSA private key, %i bit long modulus\n", ksize);
+ if (rsa_gen_key(pk_rsa(*key), _urandom, NULL, ksize, exp)) {
+ fprintf(stderr, "error: key generation failed\n");
+ exit(1);
+ }
+}
+
+int rsakey(char **arg)
+{
+ pk_context key;
+ unsigned int ksize = 512;
+ int exp = 65537;
+ char *path = NULL;
+ bool pem = true;
+
+ while (*arg && **arg == '-') {
+ if (!strcmp(*arg, "-out") && arg[1]) {
+ path = arg[1];
+ arg++;
+ } else if (!strcmp(*arg, "-3")) {
+ exp = 3;
+ } else if (!strcmp(*arg, "-der")) {
+ pem = false;
+ }
+ arg++;
+ }
+
+ if (*arg)
+ ksize = (unsigned int)atoi(*arg);
+
+ gen_key(&key, ksize, exp, pem);
+ write_key(&key, path, pem);
+
+ pk_free(&key);
+
+ return 0;
+}
+
+int selfsigned(char **arg)
+{
+ pk_context key;
+ x509write_cert cert;
+ mpi serial;
+
+ char *subject = "";
+ unsigned int ksize = 512;
+ int exp = 65537;
+ unsigned int days = 30;
+ char *keypath = NULL, *certpath = NULL;
+ bool pem = true;
+ time_t from = time(NULL), to;
+ char fstr[20], tstr[20], sstr[17];
+ int len;
+
+ while (*arg && **arg == '-') {
+ if (!strcmp(*arg, "-der")) {
+ pem = false;
+ } else if (!strcmp(*arg, "-newkey") && arg[1]) {
+ if (strncmp(arg[1], "rsa:", 4)) {
+ fprintf(stderr, "error: invalid algorithm");
+ return 1;
+ }
+ ksize = (unsigned int)atoi(arg[1] + 4);
+ arg++;
+ } else if (!strcmp(*arg, "-days") && arg[1]) {
+ days = (unsigned int)atoi(arg[1]);
+ arg++;
+ } else if (!strcmp(*arg, "-keyout") && arg[1]) {
+ keypath = arg[1];
+ arg++;
+ } else if (!strcmp(*arg, "-out") && arg[1]) {
+ certpath = arg[1];
+ arg++;
+ } else if (!strcmp(*arg, "-subj") && arg[1]) {
+ if (arg[1][0] != '/' || strchr(arg[1], ';')) {
+ fprintf(stderr, "error: invalid subject");
+ return 1;
+ }
+ subject = calloc(strlen(arg[1]) + 1, 1);
+ char *oldc = arg[1] + 1, *newc = subject, *delim;
+ do {
+ delim = strchr(oldc, '=');
+ if (!delim) {
+ fprintf(stderr, "error: invalid subject");
+ return 1;
+ }
+ memcpy(newc, oldc, delim - oldc + 1);
+ newc += delim - oldc + 1;
+ oldc = delim + 1;
+
+ delim = strchr(oldc, '/');
+ if (!delim) {
+ delim = arg[1] + strlen(arg[1]);
+ }
+ memcpy(newc, oldc, delim - oldc);
+ newc += delim - oldc;
+ *newc++ = ',';
+ oldc = delim + 1;
+ } while(*delim);
+ arg++;
+ }
+ arg++;
+ }
+
+ gen_key(&key, ksize, exp, pem);
+
+ if (keypath)
+ write_key(&key, keypath, pem);
+
+ from = (from < 1000000000) ? 1000000000 : from;
+ strftime(fstr, sizeof(fstr), "%Y%m%d%H%M%S", gmtime(&from));
+ to = from + 60 * 60 * 24 * days;
+ if (to < from)
+ to = INT_MAX;
+ strftime(tstr, sizeof(tstr), "%Y%m%d%H%M%S", gmtime(&to));
+
+ fprintf(stderr, "Generating selfsigned certificate with subject '%s'"
+ " and validity %s-%s\n", subject, fstr, tstr);
+
+ x509write_crt_init(&cert);
+ x509write_crt_set_md_alg(&cert, POLARSSL_MD_SHA1);
+ x509write_crt_set_issuer_key(&cert, &key);
+ x509write_crt_set_subject_key(&cert, &key);
+ x509write_crt_set_subject_name(&cert, subject);
+ x509write_crt_set_issuer_name(&cert, subject);
+ x509write_crt_set_validity(&cert, fstr, tstr);
+ x509write_crt_set_basic_constraints(&cert, 0, -1);
+ x509write_crt_set_subject_key_identifier(&cert);
+ x509write_crt_set_authority_key_identifier(&cert);
+
+ _urandom(NULL, buf, 8);
+ for (len = 0; len < 8; len++)
+ sprintf(sstr + len*2, "%02x", (unsigned char) buf[len]);
+
+ mpi_init(&serial);
+ mpi_read_string(&serial, 16, sstr);
+ x509write_crt_set_serial(&cert, &serial);
+
+ if (pem) {
+ if (x509write_crt_pem(&cert, (void *) buf, sizeof(buf), _urandom, NULL) < 0) {
+ fprintf(stderr, "Failed to generate certificate\n");
+ return 1;
+ }
+
+ len = strlen(buf);
+ } else {
+ len = x509write_crt_der(&cert, (void *) buf, sizeof(buf), _urandom, NULL);
+ if (len < 0) {
+ fprintf(stderr, "Failed to generate certificate: %d\n", len);
+ return 1;
+ }
+ }
+ write_file(certpath, len, pem);
+
+ x509write_crt_free(&cert);
+ mpi_free(&serial);
+ pk_free(&key);
+
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ urandom_fd = open("/dev/urandom", O_RDONLY);
+
+ if (!argv[1]) {
+ //Usage
+ } else if (!strcmp(argv[1], "rsakey")) {
+ return rsakey(argv+2);
+ } else if (!strcmp(argv[1], "selfsigned")) {
+ return selfsigned(argv+2);
+ }
+
+ fprintf(stderr,
+ "PX5G X.509 Certificate Generator Utility v" PX5G_VERSION "\n" PX5G_COPY
+ "\nbased on PolarSSL by Christophe Devine and Paul Bakker\n\n");
+ fprintf(stderr, "Usage: %s [rsakey|selfsigned]\n", *argv);
+ return 1;
+}
diff --git a/package/utils/spidev_test/Makefile b/package/utils/spidev_test/Makefile
new file mode 100644
index 0000000..807039a
--- /dev/null
+++ b/package/utils/spidev_test/Makefile
@@ -0,0 +1,43 @@
+#
+# Copyright (C) 2009 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+include $(INCLUDE_DIR)/kernel.mk
+
+PKG_NAME:=spidev-test
+PKG_RELEASE:=$(LINUX_VERSION)
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/spidev-test
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=+kmod-spi-dev
+ TITLE:=SPI testing utility
+ VERSION:=$(LINUX_VERSION)-$(PKG_RELEASE)
+ URL:=http://www.kernel.org
+ MAINTAINER:=Florian Fainelli <florian@openwrt.org>
+endef
+
+define Package/spidev-test/description
+ SPI testing utility.
+endef
+
+define Build/Prepare
+endef
+
+define Build/Compile
+ $(TARGET_CC) $(TARGET_CFLAGS) -o $(PKG_BUILD_DIR)/spidev_test \
+ $(LINUX_DIR)/Documentation/spi/spidev_test.c
+endef
+
+define Package/spidev-test/install
+ $(INSTALL_DIR) $(1)/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/spidev_test $(1)/sbin/
+endef
+
+$(eval $(call BuildPackage,spidev-test))
diff --git a/package/utils/ubi-utils/Makefile b/package/utils/ubi-utils/Makefile
new file mode 100644
index 0000000..b89a5d2
--- /dev/null
+++ b/package/utils/ubi-utils/Makefile
@@ -0,0 +1,61 @@
+#
+# Copyright (C) 2009-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ubi-utils
+PKG_REV:=7d2839b8dede3ae368780364b4a07473d2303219
+PKG_VERSION:=1.5.1
+PKG_RELEASE:=2
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=git://git.infradead.org/mtd-utils.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=$(PKG_REV)
+PKG_MIRROR_MD5SUM:=69b68adcfcbe786584771e5978534ab4
+
+PKG_INSTALL:=1
+
+PKG_BUILD_DEPENDS:=util-linux liblzo zlib
+
+PKG_LICENSE:=GPLv2
+PKG_LICENSE_FILES:=
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/ubi-utils
+ TITLE:=Utilities for ubi info/debug
+ SECTION:=utils
+ CATEGORY:=Utilities
+ URL:=http://www.linux-mtd.infradead.org/
+ DEPENDS:=@NAND_SUPPORT
+endef
+
+define Package/ubi-utils/description
+ Utilities for manipulating memory technology devices.
+endef
+
+MAKE_FLAGS += \
+ DESTDIR="$(PKG_INSTALL_DIR)" \
+ BUILDDIR="$(PKG_BUILD_DIR)" \
+ LDLIBS+="$(LIBGCC_S)" \
+ WITHOUT_XATTR=1 \
+ WITHOUT_LZO=1
+
+define Package/ubi-utils/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) \
+ $(PKG_INSTALL_DIR)/usr/sbin/{ubiattach,ubicrc32,ubiblock,ubidetach,ubiformat,ubimkvol} $(1)/usr/sbin/
+ $(INSTALL_BIN) \
+ $(PKG_INSTALL_DIR)/usr/sbin/{ubinfo,ubinize,ubirename,ubirmvol,ubirsvol,ubiupdatevol} $(1)/usr/sbin/
+endef
+
+
+$(eval $(call BuildPackage,ubi-utils))
diff --git a/package/utils/ubi-utils/patches/010-fix-rpmatch.patch b/package/utils/ubi-utils/patches/010-fix-rpmatch.patch
new file mode 100644
index 0000000..9d0de7f
--- /dev/null
+++ b/package/utils/ubi-utils/patches/010-fix-rpmatch.patch
@@ -0,0 +1,19 @@
+--- a/include/common.h
++++ b/include/common.h
+@@ -137,10 +137,12 @@ static inline bool prompt(const char *ms
+ }
+
+ if (strcmp("\n", line) != 0) {
+- switch (rpmatch(line)) {
+- case 0: ret = false; break;
+- case 1: ret = true; break;
+- case -1:
++ switch (line[0]) {
++ case 'N':
++ case 'n': ret = false; break;
++ case 'Y':
++ case 'y': ret = true; break;
++ default:
+ puts("unknown response; please try again");
+ continue;
+ }
diff --git a/package/utils/ubi-utils/patches/100-fix_includes.patch b/package/utils/ubi-utils/patches/100-fix_includes.patch
new file mode 100644
index 0000000..44421d0
--- /dev/null
+++ b/package/utils/ubi-utils/patches/100-fix_includes.patch
@@ -0,0 +1,30 @@
+--- a/lib/libfec.c
++++ b/lib/libfec.c
+@@ -45,6 +45,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <string.h>
++#include <sys/types.h>
+
+ /*
+ * stuff used for testing purposes only
+--- a/serve_image.c
++++ b/serve_image.c
+@@ -3,7 +3,6 @@
+
+ #include <time.h>
+ #include <errno.h>
+-#include <error.h>
+ #include <netdb.h>
+ #include <stdio.h>
+ #include <stdlib.h>
+--- a/recv_image.c
++++ b/recv_image.c
+@@ -4,7 +4,6 @@
+ #define _BSD_SOURCE /* struct ip_mreq */
+
+ #include <errno.h>
+-#include <error.h>
+ #include <stdio.h>
+ #include <netdb.h>
+ #include <stdlib.h>
diff --git a/package/utils/ubi-utils/patches/110-gcc5-fix.patch b/package/utils/ubi-utils/patches/110-gcc5-fix.patch
new file mode 100644
index 0000000..d871d67
--- /dev/null
+++ b/package/utils/ubi-utils/patches/110-gcc5-fix.patch
@@ -0,0 +1,41 @@
+--- a/mkfs.ubifs/hashtable/hashtable_itr.c
++++ b/mkfs.ubifs/hashtable/hashtable_itr.c
+@@ -35,18 +35,6 @@ hashtable_iterator(struct hashtable *h)
+ }
+
+ /*****************************************************************************/
+-/* key - return the key of the (key,value) pair at the current position */
+-/* value - return the value of the (key,value) pair at the current position */
+-
+-void *
+-hashtable_iterator_key(struct hashtable_itr *i)
+-{ return i->e->k; }
+-
+-void *
+-hashtable_iterator_value(struct hashtable_itr *i)
+-{ return i->e->v; }
+-
+-/*****************************************************************************/
+ /* advance - advance the iterator to the next element
+ * returns zero if advanced to end of table */
+
+--- a/mkfs.ubifs/hashtable/hashtable_itr.h
++++ b/mkfs.ubifs/hashtable/hashtable_itr.h
+@@ -28,7 +28,7 @@ hashtable_iterator(struct hashtable *h);
+ /* hashtable_iterator_key
+ * - return the value of the (key,value) pair at the current position */
+
+-extern inline void *
++static inline void *
+ hashtable_iterator_key(struct hashtable_itr *i)
+ {
+ return i->e->k;
+@@ -37,7 +37,7 @@ hashtable_iterator_key(struct hashtable_
+ /*****************************************************************************/
+ /* value - return the value of the (key,value) pair at the current position */
+
+-extern inline void *
++static inline void *
+ hashtable_iterator_value(struct hashtable_itr *i)
+ {
+ return i->e->v;
diff --git a/package/utils/ubi-utils/patches/130-lzma_jffs2.patch b/package/utils/ubi-utils/patches/130-lzma_jffs2.patch
new file mode 100644
index 0000000..8c3794d
--- /dev/null
+++ b/package/utils/ubi-utils/patches/130-lzma_jffs2.patch
@@ -0,0 +1,5029 @@
+--- a/Makefile
++++ b/Makefile
+@@ -3,7 +3,7 @@
+
+ VERSION = 1.5.1
+
+-CPPFLAGS += -D_GNU_SOURCE -I./include -I$(BUILDDIR)/include -I./ubi-utils/include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) $(UUIDCPPFLAGS)
++CPPFLAGS += -D_GNU_SOURCE -I./include -I$(BUILDDIR)/include -I./ubi-utils/include $(ZLIBCPPFLAGS) $(LZOCPPFLAGS) $(UUIDCPPFLAGS) -I./include/linux/lzma
+
+ ifeq ($(WITHOUT_XATTR), 1)
+ CPPFLAGS += -DWITHOUT_XATTR
+@@ -84,7 +84,7 @@ $(BUILDDIR)/include/version.h.tmp:
+ #
+ # Utils in top level
+ #
+-obj-mkfs.jffs2 = compr_rtime.o compr_zlib.o compr_lzo.o compr.o rbtree.o
++obj-mkfs.jffs2 = compr_rtime.o compr_zlib.o $(if $(WITHOUT_LZO),,compr_lzo.o) compr_lzma.o lzma/LzFind.o lzma/LzmaEnc.o lzma/LzmaDec.o compr.o rbtree.o
+ LDFLAGS_mkfs.jffs2 = $(ZLIBLDFLAGS) $(LZOLDFLAGS)
+ LDLIBS_mkfs.jffs2 = -lz $(LZOLDLIBS)
+
+--- a/compr.c
++++ b/compr.c
+@@ -520,6 +520,9 @@ int jffs2_compressors_init(void)
+ #ifdef CONFIG_JFFS2_LZO
+ jffs2_lzo_init();
+ #endif
++#ifdef CONFIG_JFFS2_LZMA
++ jffs2_lzma_init();
++#endif
+ return 0;
+ }
+
+@@ -534,5 +537,8 @@ int jffs2_compressors_exit(void)
+ #ifdef CONFIG_JFFS2_LZO
+ jffs2_lzo_exit();
+ #endif
++#ifdef CONFIG_JFFS2_LZMA
++ jffs2_lzma_exit();
++#endif
+ return 0;
+ }
+--- a/compr.h
++++ b/compr.h
+@@ -18,13 +18,14 @@
+
+ #define CONFIG_JFFS2_ZLIB
+ #define CONFIG_JFFS2_RTIME
+-#define CONFIG_JFFS2_LZO
++#define CONFIG_JFFS2_LZMA
+
+ #define JFFS2_RUBINMIPS_PRIORITY 10
+ #define JFFS2_DYNRUBIN_PRIORITY 20
+ #define JFFS2_RTIME_PRIORITY 50
+-#define JFFS2_ZLIB_PRIORITY 60
+-#define JFFS2_LZO_PRIORITY 80
++#define JFFS2_LZMA_PRIORITY 70
++#define JFFS2_ZLIB_PRIORITY 80
++#define JFFS2_LZO_PRIORITY 90
+
+ #define JFFS2_COMPR_MODE_NONE 0
+ #define JFFS2_COMPR_MODE_PRIORITY 1
+@@ -115,5 +116,10 @@ void jffs2_rtime_exit(void);
+ int jffs2_lzo_init(void);
+ void jffs2_lzo_exit(void);
+ #endif
++#ifdef CONFIG_JFFS2_LZMA
++int jffs2_lzma_init(void);
++void jffs2_lzma_exit(void);
++#endif
++
+
+ #endif /* __JFFS2_COMPR_H__ */
+--- /dev/null
++++ b/compr_lzma.c
+@@ -0,0 +1,128 @@
++/*
++ * JFFS2 -- Journalling Flash File System, Version 2.
++ *
++ * For licensing information, see the file 'LICENCE' in this directory.
++ *
++ * JFFS2 wrapper to the LZMA C SDK
++ *
++ */
++
++#include <linux/lzma.h>
++#include "compr.h"
++
++#ifdef __KERNEL__
++ static DEFINE_MUTEX(deflate_mutex);
++#endif
++
++CLzmaEncHandle *p;
++Byte propsEncoded[LZMA_PROPS_SIZE];
++SizeT propsSize = sizeof(propsEncoded);
++
++STATIC void lzma_free_workspace(void)
++{
++ LzmaEnc_Destroy(p, &lzma_alloc, &lzma_alloc);
++}
++
++STATIC int INIT lzma_alloc_workspace(CLzmaEncProps *props)
++{
++ if ((p = (CLzmaEncHandle *)LzmaEnc_Create(&lzma_alloc)) == NULL)
++ {
++ PRINT_ERROR("Failed to allocate lzma deflate workspace\n");
++ return -ENOMEM;
++ }
++
++ if (LzmaEnc_SetProps(p, props) != SZ_OK)
++ {
++ lzma_free_workspace();
++ return -1;
++ }
++
++ if (LzmaEnc_WriteProperties(p, propsEncoded, &propsSize) != SZ_OK)
++ {
++ lzma_free_workspace();
++ return -1;
++ }
++
++ return 0;
++}
++
++STATIC int jffs2_lzma_compress(unsigned char *data_in, unsigned char *cpage_out,
++ uint32_t *sourcelen, uint32_t *dstlen, void *model)
++{
++ SizeT compress_size = (SizeT)(*dstlen);
++ int ret;
++
++ #ifdef __KERNEL__
++ mutex_lock(&deflate_mutex);
++ #endif
++
++ ret = LzmaEnc_MemEncode(p, cpage_out, &compress_size, data_in, *sourcelen,
++ 0, NULL, &lzma_alloc, &lzma_alloc);
++
++ #ifdef __KERNEL__
++ mutex_unlock(&deflate_mutex);
++ #endif
++
++ if (ret != SZ_OK)
++ return -1;
++
++ *dstlen = (uint32_t)compress_size;
++
++ return 0;
++}
++
++STATIC int jffs2_lzma_decompress(unsigned char *data_in, unsigned char *cpage_out,
++ uint32_t srclen, uint32_t destlen, void *model)
++{
++ int ret;
++ SizeT dl = (SizeT)destlen;
++ SizeT sl = (SizeT)srclen;
++ ELzmaStatus status;
++
++ ret = LzmaDecode(cpage_out, &dl, data_in, &sl, propsEncoded,
++ propsSize, LZMA_FINISH_ANY, &status, &lzma_alloc);
++
++ if (ret != SZ_OK || status == LZMA_STATUS_NOT_FINISHED || dl != (SizeT)destlen)
++ return -1;
++
++ return 0;
++}
++
++static struct jffs2_compressor jffs2_lzma_comp = {
++ .priority = JFFS2_LZMA_PRIORITY,
++ .name = "lzma",
++ .compr = JFFS2_COMPR_LZMA,
++ .compress = &jffs2_lzma_compress,
++ .decompress = &jffs2_lzma_decompress,
++ .disabled = 0,
++};
++
++int INIT jffs2_lzma_init(void)
++{
++ int ret;
++ CLzmaEncProps props;
++ LzmaEncProps_Init(&props);
++
++ props.dictSize = LZMA_BEST_DICT(0x2000);
++ props.level = LZMA_BEST_LEVEL;
++ props.lc = LZMA_BEST_LC;
++ props.lp = LZMA_BEST_LP;
++ props.pb = LZMA_BEST_PB;
++ props.fb = LZMA_BEST_FB;
++
++ ret = lzma_alloc_workspace(&props);
++ if (ret < 0)
++ return ret;
++
++ ret = jffs2_register_compressor(&jffs2_lzma_comp);
++ if (ret)
++ lzma_free_workspace();
++
++ return ret;
++}
++
++void jffs2_lzma_exit(void)
++{
++ jffs2_unregister_compressor(&jffs2_lzma_comp);
++ lzma_free_workspace();
++}
+--- a/include/linux/jffs2.h
++++ b/include/linux/jffs2.h
+@@ -47,6 +47,7 @@
+ #define JFFS2_COMPR_DYNRUBIN 0x05
+ #define JFFS2_COMPR_ZLIB 0x06
+ #define JFFS2_COMPR_LZO 0x07
++#define JFFS2_COMPR_LZMA 0x08
+ /* Compatibility flags. */
+ #define JFFS2_COMPAT_MASK 0xc000 /* What do to if an unknown nodetype is found */
+ #define JFFS2_NODE_ACCURATE 0x2000
+--- /dev/null
++++ b/include/linux/lzma.h
+@@ -0,0 +1,61 @@
++#ifndef __LZMA_H__
++#define __LZMA_H__
++
++#ifdef __KERNEL__
++ #include <linux/kernel.h>
++ #include <linux/sched.h>
++ #include <linux/slab.h>
++ #include <linux/vmalloc.h>
++ #include <linux/init.h>
++ #define LZMA_MALLOC vmalloc
++ #define LZMA_FREE vfree
++ #define PRINT_ERROR(msg) printk(KERN_WARNING #msg)
++ #define INIT __init
++ #define STATIC static
++#else
++ #include <stdint.h>
++ #include <stdlib.h>
++ #include <stdio.h>
++ #include <unistd.h>
++ #include <string.h>
++ #include <errno.h>
++ #include <linux/jffs2.h>
++ #ifndef PAGE_SIZE
++ extern int page_size;
++ #define PAGE_SIZE page_size
++ #endif
++ #define LZMA_MALLOC malloc
++ #define LZMA_FREE free
++ #define PRINT_ERROR(msg) fprintf(stderr, msg)
++ #define INIT
++ #define STATIC
++#endif
++
++#include "lzma/LzmaDec.h"
++#include "lzma/LzmaEnc.h"
++
++#define LZMA_BEST_LEVEL (9)
++#define LZMA_BEST_LC (0)
++#define LZMA_BEST_LP (0)
++#define LZMA_BEST_PB (0)
++#define LZMA_BEST_FB (273)
++
++#define LZMA_BEST_DICT(n) (((int)((n) / 2)) * 2)
++
++static void *p_lzma_malloc(void *p, size_t size)
++{
++ if (size == 0)
++ return NULL;
++
++ return LZMA_MALLOC(size);
++}
++
++static void p_lzma_free(void *p, void *address)
++{
++ if (address != NULL)
++ LZMA_FREE(address);
++}
++
++static ISzAlloc lzma_alloc = {p_lzma_malloc, p_lzma_free};
++
++#endif
+--- /dev/null
++++ b/include/linux/lzma/LzFind.h
+@@ -0,0 +1,116 @@
++/* LzFind.h -- Match finder for LZ algorithms
++2008-04-04
++Copyright (c) 1999-2008 Igor Pavlov
++You can use any of the following license options:
++ 1) GNU Lesser General Public License (GNU LGPL)
++ 2) Common Public License (CPL)
++ 3) Common Development and Distribution License (CDDL) Version 1.0
++ 4) Igor Pavlov, as the author of this code, expressly permits you to
++ statically or dynamically link your code (or bind by name) to this file,
++ while you keep this file unmodified.
++*/
++
++#ifndef __LZFIND_H
++#define __LZFIND_H
++
++#include "Types.h"
++
++typedef UInt32 CLzRef;
++
++typedef struct _CMatchFinder
++{
++ Byte *buffer;
++ UInt32 pos;
++ UInt32 posLimit;
++ UInt32 streamPos;
++ UInt32 lenLimit;
++
++ UInt32 cyclicBufferPos;
++ UInt32 cyclicBufferSize; /* it must be = (historySize + 1) */
++
++ UInt32 matchMaxLen;
++ CLzRef *hash;
++ CLzRef *son;
++ UInt32 hashMask;
++ UInt32 cutValue;
++
++ Byte *bufferBase;
++ ISeqInStream *stream;
++ int streamEndWasReached;
++
++ UInt32 blockSize;
++ UInt32 keepSizeBefore;
++ UInt32 keepSizeAfter;
++
++ UInt32 numHashBytes;
++ int directInput;
++ int btMode;
++ /* int skipModeBits; */
++ int bigHash;
++ UInt32 historySize;
++ UInt32 fixedHashSize;
++ UInt32 hashSizeSum;
++ UInt32 numSons;
++ SRes result;
++ UInt32 crc[256];
++} CMatchFinder;
++
++#define Inline_MatchFinder_GetPointerToCurrentPos(p) ((p)->buffer)
++#define Inline_MatchFinder_GetIndexByte(p, index) ((p)->buffer[(Int32)(index)])
++
++#define Inline_MatchFinder_GetNumAvailableBytes(p) ((p)->streamPos - (p)->pos)
++
++int MatchFinder_NeedMove(CMatchFinder *p);
++Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p);
++void MatchFinder_MoveBlock(CMatchFinder *p);
++void MatchFinder_ReadIfRequired(CMatchFinder *p);
++
++void MatchFinder_Construct(CMatchFinder *p);
++
++/* Conditions:
++ historySize <= 3 GB
++ keepAddBufferBefore + matchMaxLen + keepAddBufferAfter < 511MB
++*/
++int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
++ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
++ ISzAlloc *alloc);
++void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc);
++void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems);
++void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue);
++
++UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *buffer, CLzRef *son,
++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 _cutValue,
++ UInt32 *distances, UInt32 maxLen);
++
++/*
++Conditions:
++ Mf_GetNumAvailableBytes_Func must be called before each Mf_GetMatchLen_Func.
++ Mf_GetPointerToCurrentPos_Func's result must be used only before any other function
++*/
++
++typedef void (*Mf_Init_Func)(void *object);
++typedef Byte (*Mf_GetIndexByte_Func)(void *object, Int32 index);
++typedef UInt32 (*Mf_GetNumAvailableBytes_Func)(void *object);
++typedef const Byte * (*Mf_GetPointerToCurrentPos_Func)(void *object);
++typedef UInt32 (*Mf_GetMatches_Func)(void *object, UInt32 *distances);
++typedef void (*Mf_Skip_Func)(void *object, UInt32);
++
++typedef struct _IMatchFinder
++{
++ Mf_Init_Func Init;
++ Mf_GetIndexByte_Func GetIndexByte;
++ Mf_GetNumAvailableBytes_Func GetNumAvailableBytes;
++ Mf_GetPointerToCurrentPos_Func GetPointerToCurrentPos;
++ Mf_GetMatches_Func GetMatches;
++ Mf_Skip_Func Skip;
++} IMatchFinder;
++
++void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable);
++
++void MatchFinder_Init(CMatchFinder *p);
++UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
++UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances);
++void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
++void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num);
++
++#endif
+--- /dev/null
++++ b/include/linux/lzma/LzHash.h
+@@ -0,0 +1,56 @@
++/* LzHash.h -- HASH functions for LZ algorithms
++2008-03-26
++Copyright (c) 1999-2008 Igor Pavlov
++Read LzFind.h for license options */
++
++#ifndef __LZHASH_H
++#define __LZHASH_H
++
++#define kHash2Size (1 << 10)
++#define kHash3Size (1 << 16)
++#define kHash4Size (1 << 20)
++
++#define kFix3HashSize (kHash2Size)
++#define kFix4HashSize (kHash2Size + kHash3Size)
++#define kFix5HashSize (kHash2Size + kHash3Size + kHash4Size)
++
++#define HASH2_CALC hashValue = cur[0] | ((UInt32)cur[1] << 8);
++
++#define HASH3_CALC { \
++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
++ hash2Value = temp & (kHash2Size - 1); \
++ hashValue = (temp ^ ((UInt32)cur[2] << 8)) & p->hashMask; }
++
++#define HASH4_CALC { \
++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
++ hash2Value = temp & (kHash2Size - 1); \
++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
++ hashValue = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & p->hashMask; }
++
++#define HASH5_CALC { \
++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
++ hash2Value = temp & (kHash2Size - 1); \
++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
++ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)); \
++ hashValue = (hash4Value ^ (p->crc[cur[4]] << 3)) & p->hashMask; \
++ hash4Value &= (kHash4Size - 1); }
++
++/* #define HASH_ZIP_CALC hashValue = ((cur[0] | ((UInt32)cur[1] << 8)) ^ p->crc[cur[2]]) & 0xFFFF; */
++#define HASH_ZIP_CALC hashValue = ((cur[2] | ((UInt32)cur[0] << 8)) ^ p->crc[cur[1]]) & 0xFFFF;
++
++
++#define MT_HASH2_CALC \
++ hash2Value = (p->crc[cur[0]] ^ cur[1]) & (kHash2Size - 1);
++
++#define MT_HASH3_CALC { \
++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
++ hash2Value = temp & (kHash2Size - 1); \
++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); }
++
++#define MT_HASH4_CALC { \
++ UInt32 temp = p->crc[cur[0]] ^ cur[1]; \
++ hash2Value = temp & (kHash2Size - 1); \
++ hash3Value = (temp ^ ((UInt32)cur[2] << 8)) & (kHash3Size - 1); \
++ hash4Value = (temp ^ ((UInt32)cur[2] << 8) ^ (p->crc[cur[3]] << 5)) & (kHash4Size - 1); }
++
++#endif
+--- /dev/null
++++ b/include/linux/lzma/LzmaDec.h
+@@ -0,0 +1,232 @@
++/* LzmaDec.h -- LZMA Decoder
++2008-04-29
++Copyright (c) 1999-2008 Igor Pavlov
++You can use any of the following license options:
++ 1) GNU Lesser General Public License (GNU LGPL)
++ 2) Common Public License (CPL)
++ 3) Common Development and Distribution License (CDDL) Version 1.0
++ 4) Igor Pavlov, as the author of this code, expressly permits you to
++ statically or dynamically link your code (or bind by name) to this file,
++ while you keep this file unmodified.
++*/
++
++#ifndef __LZMADEC_H
++#define __LZMADEC_H
++
++#include "Types.h"
++
++/* #define _LZMA_PROB32 */
++/* _LZMA_PROB32 can increase the speed on some CPUs,
++ but memory usage for CLzmaDec::probs will be doubled in that case */
++
++#ifdef _LZMA_PROB32
++#define CLzmaProb UInt32
++#else
++#define CLzmaProb UInt16
++#endif
++
++
++/* ---------- LZMA Properties ---------- */
++
++#define LZMA_PROPS_SIZE 5
++
++typedef struct _CLzmaProps
++{
++ unsigned lc, lp, pb;
++ UInt32 dicSize;
++} CLzmaProps;
++
++/* LzmaProps_Decode - decodes properties
++Returns:
++ SZ_OK
++ SZ_ERROR_UNSUPPORTED - Unsupported properties
++*/
++
++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
++
++
++/* ---------- LZMA Decoder state ---------- */
++
++/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
++ Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
++
++#define LZMA_REQUIRED_INPUT_MAX 20
++
++typedef struct
++{
++ CLzmaProps prop;
++ CLzmaProb *probs;
++ Byte *dic;
++ const Byte *buf;
++ UInt32 range, code;
++ SizeT dicPos;
++ SizeT dicBufSize;
++ UInt32 processedPos;
++ UInt32 checkDicSize;
++ unsigned state;
++ UInt32 reps[4];
++ unsigned remainLen;
++ int needFlush;
++ int needInitState;
++ UInt32 numProbs;
++ unsigned tempBufSize;
++ Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
++} CLzmaDec;
++
++#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
++
++void LzmaDec_Init(CLzmaDec *p);
++
++/* There are two types of LZMA streams:
++ 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
++ 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
++
++typedef enum
++{
++ LZMA_FINISH_ANY, /* finish at any point */
++ LZMA_FINISH_END /* block must be finished at the end */
++} ELzmaFinishMode;
++
++/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
++
++ You must use LZMA_FINISH_END, when you know that current output buffer
++ covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
++
++ If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
++ and output value of destLen will be less than output buffer size limit.
++ You can check status result also.
++
++ You can use multiple checks to test data integrity after full decompression:
++ 1) Check Result and "status" variable.
++ 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
++ 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
++ You must use correct finish mode in that case. */
++
++typedef enum
++{
++ LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
++ LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
++ LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
++ LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
++} ELzmaStatus;
++
++/* ELzmaStatus is used only as output value for function call */
++
++
++/* ---------- Interfaces ---------- */
++
++/* There are 3 levels of interfaces:
++ 1) Dictionary Interface
++ 2) Buffer Interface
++ 3) One Call Interface
++ You can select any of these interfaces, but don't mix functions from different
++ groups for same object. */
++
++
++/* There are two variants to allocate state for Dictionary Interface:
++ 1) LzmaDec_Allocate / LzmaDec_Free
++ 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
++ You can use variant 2, if you set dictionary buffer manually.
++ For Buffer Interface you must always use variant 1.
++
++LzmaDec_Allocate* can return:
++ SZ_OK
++ SZ_ERROR_MEM - Memory allocation error
++ SZ_ERROR_UNSUPPORTED - Unsupported properties
++*/
++
++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
++
++SRes LzmaDec_Allocate(CLzmaDec *state, const Byte *prop, unsigned propsSize, ISzAlloc *alloc);
++void LzmaDec_Free(CLzmaDec *state, ISzAlloc *alloc);
++
++/* ---------- Dictionary Interface ---------- */
++
++/* You can use it, if you want to eliminate the overhead for data copying from
++ dictionary to some other external buffer.
++ You must work with CLzmaDec variables directly in this interface.
++
++ STEPS:
++ LzmaDec_Constr()
++ LzmaDec_Allocate()
++ for (each new stream)
++ {
++ LzmaDec_Init()
++ while (it needs more decompression)
++ {
++ LzmaDec_DecodeToDic()
++ use data from CLzmaDec::dic and update CLzmaDec::dicPos
++ }
++ }
++ LzmaDec_Free()
++*/
++
++/* LzmaDec_DecodeToDic
++
++ The decoding to internal dictionary buffer (CLzmaDec::dic).
++ You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
++
++finishMode:
++ It has meaning only if the decoding reaches output limit (dicLimit).
++ LZMA_FINISH_ANY - Decode just dicLimit bytes.
++ LZMA_FINISH_END - Stream must be finished after dicLimit.
++
++Returns:
++ SZ_OK
++ status:
++ LZMA_STATUS_FINISHED_WITH_MARK
++ LZMA_STATUS_NOT_FINISHED
++ LZMA_STATUS_NEEDS_MORE_INPUT
++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
++ SZ_ERROR_DATA - Data error
++*/
++
++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
++ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
++
++
++/* ---------- Buffer Interface ---------- */
++
++/* It's zlib-like interface.
++ See LzmaDec_DecodeToDic description for information about STEPS and return results,
++ but you must use LzmaDec_DecodeToBuf instead of LzmaDec_DecodeToDic and you don't need
++ to work with CLzmaDec variables manually.
++
++finishMode:
++ It has meaning only if the decoding reaches output limit (*destLen).
++ LZMA_FINISH_ANY - Decode just destLen bytes.
++ LZMA_FINISH_END - Stream must be finished after (*destLen).
++*/
++
++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen,
++ const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
++
++
++/* ---------- One Call Interface ---------- */
++
++/* LzmaDecode
++
++finishMode:
++ It has meaning only if the decoding reaches output limit (*destLen).
++ LZMA_FINISH_ANY - Decode just destLen bytes.
++ LZMA_FINISH_END - Stream must be finished after (*destLen).
++
++Returns:
++ SZ_OK
++ status:
++ LZMA_STATUS_FINISHED_WITH_MARK
++ LZMA_STATUS_NOT_FINISHED
++ LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
++ SZ_ERROR_DATA - Data error
++ SZ_ERROR_MEM - Memory allocation error
++ SZ_ERROR_UNSUPPORTED - Unsupported properties
++ SZ_ERROR_INPUT_EOF - It needs more bytes in input buffer (src).
++*/
++
++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
++ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
++ ELzmaStatus *status, ISzAlloc *alloc);
++
++#endif
+--- /dev/null
++++ b/include/linux/lzma/LzmaEnc.h
+@@ -0,0 +1,74 @@
++/* LzmaEnc.h -- LZMA Encoder
++2008-04-27
++Copyright (c) 1999-2008 Igor Pavlov
++Read LzFind.h for license options */
++
++#ifndef __LZMAENC_H
++#define __LZMAENC_H
++
++#include "Types.h"
++
++#define LZMA_PROPS_SIZE 5
++
++typedef struct _CLzmaEncProps
++{
++ int level; /* 0 <= level <= 9 */
++ UInt32 dictSize; /* (1 << 12) <= dictSize <= (1 << 27) for 32-bit version
++ (1 << 12) <= dictSize <= (1 << 30) for 64-bit version
++ default = (1 << 24) */
++ int lc; /* 0 <= lc <= 8, default = 3 */
++ int lp; /* 0 <= lp <= 4, default = 0 */
++ int pb; /* 0 <= pb <= 4, default = 2 */
++ int algo; /* 0 - fast, 1 - normal, default = 1 */
++ int fb; /* 5 <= fb <= 273, default = 32 */
++ int btMode; /* 0 - hashChain Mode, 1 - binTree mode - normal, default = 1 */
++ int numHashBytes; /* 2, 3 or 4, default = 4 */
++ UInt32 mc; /* 1 <= mc <= (1 << 30), default = 32 */
++ unsigned writeEndMark; /* 0 - do not write EOPM, 1 - write EOPM, default = 0 */
++ int numThreads; /* 1 or 2, default = 2 */
++} CLzmaEncProps;
++
++void LzmaEncProps_Init(CLzmaEncProps *p);
++void LzmaEncProps_Normalize(CLzmaEncProps *p);
++UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2);
++
++
++/* ---------- CLzmaEncHandle Interface ---------- */
++
++/* LzmaEnc_* functions can return the following exit codes:
++Returns:
++ SZ_OK - OK
++ SZ_ERROR_MEM - Memory allocation error
++ SZ_ERROR_PARAM - Incorrect paramater in props
++ SZ_ERROR_WRITE - Write callback error.
++ SZ_ERROR_PROGRESS - some break from progress callback
++ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
++*/
++
++typedef void * CLzmaEncHandle;
++
++CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc);
++void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig);
++SRes LzmaEnc_SetProps(CLzmaEncHandle p, const CLzmaEncProps *props);
++SRes LzmaEnc_WriteProperties(CLzmaEncHandle p, Byte *properties, SizeT *size);
++SRes LzmaEnc_Encode(CLzmaEncHandle p, ISeqOutStream *outStream, ISeqInStream *inStream,
++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
++SRes LzmaEnc_MemEncode(CLzmaEncHandle p, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
++ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
++
++/* ---------- One Call Interface ---------- */
++
++/* LzmaEncode
++Return code:
++ SZ_OK - OK
++ SZ_ERROR_MEM - Memory allocation error
++ SZ_ERROR_PARAM - Incorrect paramater
++ SZ_ERROR_OUTPUT_EOF - output buffer overflow
++ SZ_ERROR_THREAD - errors in multithreading functions (only for Mt version)
++*/
++
++SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
++ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig);
++
++#endif
+--- /dev/null
++++ b/include/linux/lzma/Types.h
+@@ -0,0 +1,130 @@
++/* Types.h -- Basic types
++2008-04-11
++Igor Pavlov
++Public domain */
++
++#ifndef __7Z_TYPES_H
++#define __7Z_TYPES_H
++
++#define SZ_OK 0
++
++#define SZ_ERROR_DATA 1
++#define SZ_ERROR_MEM 2
++#define SZ_ERROR_CRC 3
++#define SZ_ERROR_UNSUPPORTED 4
++#define SZ_ERROR_PARAM 5
++#define SZ_ERROR_INPUT_EOF 6
++#define SZ_ERROR_OUTPUT_EOF 7
++#define SZ_ERROR_READ 8
++#define SZ_ERROR_WRITE 9
++#define SZ_ERROR_PROGRESS 10
++#define SZ_ERROR_FAIL 11
++#define SZ_ERROR_THREAD 12
++
++#define SZ_ERROR_ARCHIVE 16
++#define SZ_ERROR_NO_ARCHIVE 17
++
++typedef int SRes;
++
++#ifndef RINOK
++#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
++#endif
++
++typedef unsigned char Byte;
++typedef short Int16;
++typedef unsigned short UInt16;
++
++#ifdef _LZMA_UINT32_IS_ULONG
++typedef long Int32;
++typedef unsigned long UInt32;
++#else
++typedef int Int32;
++typedef unsigned int UInt32;
++#endif
++
++/* #define _SZ_NO_INT_64 */
++/* define it if your compiler doesn't support 64-bit integers */
++
++#ifdef _SZ_NO_INT_64
++
++typedef long Int64;
++typedef unsigned long UInt64;
++
++#else
++
++#if defined(_MSC_VER) || defined(__BORLANDC__)
++typedef __int64 Int64;
++typedef unsigned __int64 UInt64;
++#else
++typedef long long int Int64;
++typedef unsigned long long int UInt64;
++#endif
++
++#endif
++
++#ifdef _LZMA_NO_SYSTEM_SIZE_T
++typedef UInt32 SizeT;
++#else
++#include <stddef.h>
++typedef size_t SizeT;
++#endif
++
++typedef int Bool;
++#define True 1
++#define False 0
++
++
++#ifdef _MSC_VER
++
++#if _MSC_VER >= 1300
++#define MY_NO_INLINE __declspec(noinline)
++#else
++#define MY_NO_INLINE
++#endif
++
++#define MY_CDECL __cdecl
++#define MY_STD_CALL __stdcall
++#define MY_FAST_CALL MY_NO_INLINE __fastcall
++
++#else
++
++#define MY_CDECL
++#define MY_STD_CALL
++#define MY_FAST_CALL
++
++#endif
++
++
++/* The following interfaces use first parameter as pointer to structure */
++
++typedef struct
++{
++ SRes (*Read)(void *p, void *buf, size_t *size);
++ /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
++ (output(*size) < input(*size)) is allowed */
++} ISeqInStream;
++
++typedef struct
++{
++ size_t (*Write)(void *p, const void *buf, size_t size);
++ /* Returns: result - the number of actually written bytes.
++ (result < size) means error */
++} ISeqOutStream;
++
++typedef struct
++{
++ SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
++ /* Returns: result. (result != SZ_OK) means break.
++ Value (UInt64)(Int64)-1 for size means unknown value. */
++} ICompressProgress;
++
++typedef struct
++{
++ void *(*Alloc)(void *p, size_t size);
++ void (*Free)(void *p, void *address); /* address can be 0 */
++} ISzAlloc;
++
++#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
++#define IAlloc_Free(p, a) (p)->Free((p), a)
++
++#endif
+--- /dev/null
++++ b/lzma/LzFind.c
+@@ -0,0 +1,753 @@
++/* LzFind.c -- Match finder for LZ algorithms
++2008-04-04
++Copyright (c) 1999-2008 Igor Pavlov
++Read LzFind.h for license options */
++
++#include <string.h>
++
++#include "LzFind.h"
++#include "LzHash.h"
++
++#define kEmptyHashValue 0
++#define kMaxValForNormalize ((UInt32)0xFFFFFFFF)
++#define kNormalizeStepMin (1 << 10) /* it must be power of 2 */
++#define kNormalizeMask (~(kNormalizeStepMin - 1))
++#define kMaxHistorySize ((UInt32)3 << 30)
++
++#define kStartMaxLen 3
++
++static void LzInWindow_Free(CMatchFinder *p, ISzAlloc *alloc)
++{
++ if (!p->directInput)
++ {
++ alloc->Free(alloc, p->bufferBase);
++ p->bufferBase = 0;
++ }
++}
++
++/* keepSizeBefore + keepSizeAfter + keepSizeReserv must be < 4G) */
++
++static int LzInWindow_Create(CMatchFinder *p, UInt32 keepSizeReserv, ISzAlloc *alloc)
++{
++ UInt32 blockSize = p->keepSizeBefore + p->keepSizeAfter + keepSizeReserv;
++ if (p->directInput)
++ {
++ p->blockSize = blockSize;
++ return 1;
++ }
++ if (p->bufferBase == 0 || p->blockSize != blockSize)
++ {
++ LzInWindow_Free(p, alloc);
++ p->blockSize = blockSize;
++ p->bufferBase = (Byte *)alloc->Alloc(alloc, (size_t)blockSize);
++ }
++ return (p->bufferBase != 0);
++}
++
++Byte *MatchFinder_GetPointerToCurrentPos(CMatchFinder *p) { return p->buffer; }
++Byte MatchFinder_GetIndexByte(CMatchFinder *p, Int32 index) { return p->buffer[index]; }
++
++UInt32 MatchFinder_GetNumAvailableBytes(CMatchFinder *p) { return p->streamPos - p->pos; }
++
++void MatchFinder_ReduceOffsets(CMatchFinder *p, UInt32 subValue)
++{
++ p->posLimit -= subValue;
++ p->pos -= subValue;
++ p->streamPos -= subValue;
++}
++
++static void MatchFinder_ReadBlock(CMatchFinder *p)
++{
++ if (p->streamEndWasReached || p->result != SZ_OK)
++ return;
++ for (;;)
++ {
++ Byte *dest = p->buffer + (p->streamPos - p->pos);
++ size_t size = (p->bufferBase + p->blockSize - dest);
++ if (size == 0)
++ return;
++ p->result = p->stream->Read(p->stream, dest, &size);
++ if (p->result != SZ_OK)
++ return;
++ if (size == 0)
++ {
++ p->streamEndWasReached = 1;
++ return;
++ }
++ p->streamPos += (UInt32)size;
++ if (p->streamPos - p->pos > p->keepSizeAfter)
++ return;
++ }
++}
++
++void MatchFinder_MoveBlock(CMatchFinder *p)
++{
++ memmove(p->bufferBase,
++ p->buffer - p->keepSizeBefore,
++ (size_t)(p->streamPos - p->pos + p->keepSizeBefore));
++ p->buffer = p->bufferBase + p->keepSizeBefore;
++}
++
++int MatchFinder_NeedMove(CMatchFinder *p)
++{
++ /* if (p->streamEndWasReached) return 0; */
++ return ((size_t)(p->bufferBase + p->blockSize - p->buffer) <= p->keepSizeAfter);
++}
++
++void MatchFinder_ReadIfRequired(CMatchFinder *p)
++{
++ if (p->streamEndWasReached)
++ return;
++ if (p->keepSizeAfter >= p->streamPos - p->pos)
++ MatchFinder_ReadBlock(p);
++}
++
++static void MatchFinder_CheckAndMoveAndRead(CMatchFinder *p)
++{
++ if (MatchFinder_NeedMove(p))
++ MatchFinder_MoveBlock(p);
++ MatchFinder_ReadBlock(p);
++}
++
++static void MatchFinder_SetDefaultSettings(CMatchFinder *p)
++{
++ p->cutValue = 32;
++ p->btMode = 1;
++ p->numHashBytes = 4;
++ /* p->skipModeBits = 0; */
++ p->directInput = 0;
++ p->bigHash = 0;
++}
++
++#define kCrcPoly 0xEDB88320
++
++void MatchFinder_Construct(CMatchFinder *p)
++{
++ UInt32 i;
++ p->bufferBase = 0;
++ p->directInput = 0;
++ p->hash = 0;
++ MatchFinder_SetDefaultSettings(p);
++
++ for (i = 0; i < 256; i++)
++ {
++ UInt32 r = i;
++ int j;
++ for (j = 0; j < 8; j++)
++ r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
++ p->crc[i] = r;
++ }
++}
++
++static void MatchFinder_FreeThisClassMemory(CMatchFinder *p, ISzAlloc *alloc)
++{
++ alloc->Free(alloc, p->hash);
++ p->hash = 0;
++}
++
++void MatchFinder_Free(CMatchFinder *p, ISzAlloc *alloc)
++{
++ MatchFinder_FreeThisClassMemory(p, alloc);
++ LzInWindow_Free(p, alloc);
++}
++
++static CLzRef* AllocRefs(UInt32 num, ISzAlloc *alloc)
++{
++ size_t sizeInBytes = (size_t)num * sizeof(CLzRef);
++ if (sizeInBytes / sizeof(CLzRef) != num)
++ return 0;
++ return (CLzRef *)alloc->Alloc(alloc, sizeInBytes);
++}
++
++int MatchFinder_Create(CMatchFinder *p, UInt32 historySize,
++ UInt32 keepAddBufferBefore, UInt32 matchMaxLen, UInt32 keepAddBufferAfter,
++ ISzAlloc *alloc)
++{
++ UInt32 sizeReserv;
++ if (historySize > kMaxHistorySize)
++ {
++ MatchFinder_Free(p, alloc);
++ return 0;
++ }
++ sizeReserv = historySize >> 1;
++ if (historySize > ((UInt32)2 << 30))
++ sizeReserv = historySize >> 2;
++ sizeReserv += (keepAddBufferBefore + matchMaxLen + keepAddBufferAfter) / 2 + (1 << 19);
++
++ p->keepSizeBefore = historySize + keepAddBufferBefore + 1;
++ p->keepSizeAfter = matchMaxLen + keepAddBufferAfter;
++ /* we need one additional byte, since we use MoveBlock after pos++ and before dictionary using */
++ if (LzInWindow_Create(p, sizeReserv, alloc))
++ {
++ UInt32 newCyclicBufferSize = (historySize /* >> p->skipModeBits */) + 1;
++ UInt32 hs;
++ p->matchMaxLen = matchMaxLen;
++ {
++ p->fixedHashSize = 0;
++ if (p->numHashBytes == 2)
++ hs = (1 << 16) - 1;
++ else
++ {
++ hs = historySize - 1;
++ hs |= (hs >> 1);
++ hs |= (hs >> 2);
++ hs |= (hs >> 4);
++ hs |= (hs >> 8);
++ hs >>= 1;
++ /* hs >>= p->skipModeBits; */
++ hs |= 0xFFFF; /* don't change it! It's required for Deflate */
++ if (hs > (1 << 24))
++ {
++ if (p->numHashBytes == 3)
++ hs = (1 << 24) - 1;
++ else
++ hs >>= 1;
++ }
++ }
++ p->hashMask = hs;
++ hs++;
++ if (p->numHashBytes > 2) p->fixedHashSize += kHash2Size;
++ if (p->numHashBytes > 3) p->fixedHashSize += kHash3Size;
++ if (p->numHashBytes > 4) p->fixedHashSize += kHash4Size;
++ hs += p->fixedHashSize;
++ }
++
++ {
++ UInt32 prevSize = p->hashSizeSum + p->numSons;
++ UInt32 newSize;
++ p->historySize = historySize;
++ p->hashSizeSum = hs;
++ p->cyclicBufferSize = newCyclicBufferSize;
++ p->numSons = (p->btMode ? newCyclicBufferSize * 2 : newCyclicBufferSize);
++ newSize = p->hashSizeSum + p->numSons;
++ if (p->hash != 0 && prevSize == newSize)
++ return 1;
++ MatchFinder_FreeThisClassMemory(p, alloc);
++ p->hash = AllocRefs(newSize, alloc);
++ if (p->hash != 0)
++ {
++ p->son = p->hash + p->hashSizeSum;
++ return 1;
++ }
++ }
++ }
++ MatchFinder_Free(p, alloc);
++ return 0;
++}
++
++static void MatchFinder_SetLimits(CMatchFinder *p)
++{
++ UInt32 limit = kMaxValForNormalize - p->pos;
++ UInt32 limit2 = p->cyclicBufferSize - p->cyclicBufferPos;
++ if (limit2 < limit)
++ limit = limit2;
++ limit2 = p->streamPos - p->pos;
++ if (limit2 <= p->keepSizeAfter)
++ {
++ if (limit2 > 0)
++ limit2 = 1;
++ }
++ else
++ limit2 -= p->keepSizeAfter;
++ if (limit2 < limit)
++ limit = limit2;
++ {
++ UInt32 lenLimit = p->streamPos - p->pos;
++ if (lenLimit > p->matchMaxLen)
++ lenLimit = p->matchMaxLen;
++ p->lenLimit = lenLimit;
++ }
++ p->posLimit = p->pos + limit;
++}
++
++void MatchFinder_Init(CMatchFinder *p)
++{
++ UInt32 i;
++ for(i = 0; i < p->hashSizeSum; i++)
++ p->hash[i] = kEmptyHashValue;
++ p->cyclicBufferPos = 0;
++ p->buffer = p->bufferBase;
++ p->pos = p->streamPos = p->cyclicBufferSize;
++ p->result = SZ_OK;
++ p->streamEndWasReached = 0;
++ MatchFinder_ReadBlock(p);
++ MatchFinder_SetLimits(p);
++}
++
++static UInt32 MatchFinder_GetSubValue(CMatchFinder *p)
++{
++ return (p->pos - p->historySize - 1) & kNormalizeMask;
++}
++
++void MatchFinder_Normalize3(UInt32 subValue, CLzRef *items, UInt32 numItems)
++{
++ UInt32 i;
++ for (i = 0; i < numItems; i++)
++ {
++ UInt32 value = items[i];
++ if (value <= subValue)
++ value = kEmptyHashValue;
++ else
++ value -= subValue;
++ items[i] = value;
++ }
++}
++
++static void MatchFinder_Normalize(CMatchFinder *p)
++{
++ UInt32 subValue = MatchFinder_GetSubValue(p);
++ MatchFinder_Normalize3(subValue, p->hash, p->hashSizeSum + p->numSons);
++ MatchFinder_ReduceOffsets(p, subValue);
++}
++
++static void MatchFinder_CheckLimits(CMatchFinder *p)
++{
++ if (p->pos == kMaxValForNormalize)
++ MatchFinder_Normalize(p);
++ if (!p->streamEndWasReached && p->keepSizeAfter == p->streamPos - p->pos)
++ MatchFinder_CheckAndMoveAndRead(p);
++ if (p->cyclicBufferPos == p->cyclicBufferSize)
++ p->cyclicBufferPos = 0;
++ MatchFinder_SetLimits(p);
++}
++
++static UInt32 * Hc_GetMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
++ UInt32 *distances, UInt32 maxLen)
++{
++ son[_cyclicBufferPos] = curMatch;
++ for (;;)
++ {
++ UInt32 delta = pos - curMatch;
++ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
++ return distances;
++ {
++ const Byte *pb = cur - delta;
++ curMatch = son[_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)];
++ if (pb[maxLen] == cur[maxLen] && *pb == *cur)
++ {
++ UInt32 len = 0;
++ while(++len != lenLimit)
++ if (pb[len] != cur[len])
++ break;
++ if (maxLen < len)
++ {
++ *distances++ = maxLen = len;
++ *distances++ = delta - 1;
++ if (len == lenLimit)
++ return distances;
++ }
++ }
++ }
++ }
++}
++
++UInt32 * GetMatchesSpec1(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue,
++ UInt32 *distances, UInt32 maxLen)
++{
++ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
++ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
++ UInt32 len0 = 0, len1 = 0;
++ for (;;)
++ {
++ UInt32 delta = pos - curMatch;
++ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
++ {
++ *ptr0 = *ptr1 = kEmptyHashValue;
++ return distances;
++ }
++ {
++ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
++ const Byte *pb = cur - delta;
++ UInt32 len = (len0 < len1 ? len0 : len1);
++ if (pb[len] == cur[len])
++ {
++ if (++len != lenLimit && pb[len] == cur[len])
++ while(++len != lenLimit)
++ if (pb[len] != cur[len])
++ break;
++ if (maxLen < len)
++ {
++ *distances++ = maxLen = len;
++ *distances++ = delta - 1;
++ if (len == lenLimit)
++ {
++ *ptr1 = pair[0];
++ *ptr0 = pair[1];
++ return distances;
++ }
++ }
++ }
++ if (pb[len] < cur[len])
++ {
++ *ptr1 = curMatch;
++ ptr1 = pair + 1;
++ curMatch = *ptr1;
++ len1 = len;
++ }
++ else
++ {
++ *ptr0 = curMatch;
++ ptr0 = pair;
++ curMatch = *ptr0;
++ len0 = len;
++ }
++ }
++ }
++}
++
++static void SkipMatchesSpec(UInt32 lenLimit, UInt32 curMatch, UInt32 pos, const Byte *cur, CLzRef *son,
++ UInt32 _cyclicBufferPos, UInt32 _cyclicBufferSize, UInt32 cutValue)
++{
++ CLzRef *ptr0 = son + (_cyclicBufferPos << 1) + 1;
++ CLzRef *ptr1 = son + (_cyclicBufferPos << 1);
++ UInt32 len0 = 0, len1 = 0;
++ for (;;)
++ {
++ UInt32 delta = pos - curMatch;
++ if (cutValue-- == 0 || delta >= _cyclicBufferSize)
++ {
++ *ptr0 = *ptr1 = kEmptyHashValue;
++ return;
++ }
++ {
++ CLzRef *pair = son + ((_cyclicBufferPos - delta + ((delta > _cyclicBufferPos) ? _cyclicBufferSize : 0)) << 1);
++ const Byte *pb = cur - delta;
++ UInt32 len = (len0 < len1 ? len0 : len1);
++ if (pb[len] == cur[len])
++ {
++ while(++len != lenLimit)
++ if (pb[len] != cur[len])
++ break;
++ {
++ if (len == lenLimit)
++ {
++ *ptr1 = pair[0];
++ *ptr0 = pair[1];
++ return;
++ }
++ }
++ }
++ if (pb[len] < cur[len])
++ {
++ *ptr1 = curMatch;
++ ptr1 = pair + 1;
++ curMatch = *ptr1;
++ len1 = len;
++ }
++ else
++ {
++ *ptr0 = curMatch;
++ ptr0 = pair;
++ curMatch = *ptr0;
++ len0 = len;
++ }
++ }
++ }
++}
++
++#define MOVE_POS \
++ ++p->cyclicBufferPos; \
++ p->buffer++; \
++ if (++p->pos == p->posLimit) MatchFinder_CheckLimits(p);
++
++#define MOVE_POS_RET MOVE_POS return offset;
++
++static void MatchFinder_MovePos(CMatchFinder *p) { MOVE_POS; }
++
++#define GET_MATCHES_HEADER2(minLen, ret_op) \
++ UInt32 lenLimit; UInt32 hashValue; const Byte *cur; UInt32 curMatch; \
++ lenLimit = p->lenLimit; { if (lenLimit < minLen) { MatchFinder_MovePos(p); ret_op; }} \
++ cur = p->buffer;
++
++#define GET_MATCHES_HEADER(minLen) GET_MATCHES_HEADER2(minLen, return 0)
++#define SKIP_HEADER(minLen) GET_MATCHES_HEADER2(minLen, continue)
++
++#define MF_PARAMS(p) p->pos, p->buffer, p->son, p->cyclicBufferPos, p->cyclicBufferSize, p->cutValue
++
++#define GET_MATCHES_FOOTER(offset, maxLen) \
++ offset = (UInt32)(GetMatchesSpec1(lenLimit, curMatch, MF_PARAMS(p), \
++ distances + offset, maxLen) - distances); MOVE_POS_RET;
++
++#define SKIP_FOOTER \
++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p)); MOVE_POS;
++
++static UInt32 Bt2_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
++{
++ UInt32 offset;
++ GET_MATCHES_HEADER(2)
++ HASH2_CALC;
++ curMatch = p->hash[hashValue];
++ p->hash[hashValue] = p->pos;
++ offset = 0;
++ GET_MATCHES_FOOTER(offset, 1)
++}
++
++UInt32 Bt3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
++{
++ UInt32 offset;
++ GET_MATCHES_HEADER(3)
++ HASH_ZIP_CALC;
++ curMatch = p->hash[hashValue];
++ p->hash[hashValue] = p->pos;
++ offset = 0;
++ GET_MATCHES_FOOTER(offset, 2)
++}
++
++static UInt32 Bt3_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
++{
++ UInt32 hash2Value, delta2, maxLen, offset;
++ GET_MATCHES_HEADER(3)
++
++ HASH3_CALC;
++
++ delta2 = p->pos - p->hash[hash2Value];
++ curMatch = p->hash[kFix3HashSize + hashValue];
++
++ p->hash[hash2Value] =
++ p->hash[kFix3HashSize + hashValue] = p->pos;
++
++
++ maxLen = 2;
++ offset = 0;
++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
++ {
++ for (; maxLen != lenLimit; maxLen++)
++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
++ break;
++ distances[0] = maxLen;
++ distances[1] = delta2 - 1;
++ offset = 2;
++ if (maxLen == lenLimit)
++ {
++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
++ MOVE_POS_RET;
++ }
++ }
++ GET_MATCHES_FOOTER(offset, maxLen)
++}
++
++static UInt32 Bt4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
++{
++ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
++ GET_MATCHES_HEADER(4)
++
++ HASH4_CALC;
++
++ delta2 = p->pos - p->hash[ hash2Value];
++ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
++ curMatch = p->hash[kFix4HashSize + hashValue];
++
++ p->hash[ hash2Value] =
++ p->hash[kFix3HashSize + hash3Value] =
++ p->hash[kFix4HashSize + hashValue] = p->pos;
++
++ maxLen = 1;
++ offset = 0;
++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
++ {
++ distances[0] = maxLen = 2;
++ distances[1] = delta2 - 1;
++ offset = 2;
++ }
++ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
++ {
++ maxLen = 3;
++ distances[offset + 1] = delta3 - 1;
++ offset += 2;
++ delta2 = delta3;
++ }
++ if (offset != 0)
++ {
++ for (; maxLen != lenLimit; maxLen++)
++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
++ break;
++ distances[offset - 2] = maxLen;
++ if (maxLen == lenLimit)
++ {
++ SkipMatchesSpec(lenLimit, curMatch, MF_PARAMS(p));
++ MOVE_POS_RET;
++ }
++ }
++ if (maxLen < 3)
++ maxLen = 3;
++ GET_MATCHES_FOOTER(offset, maxLen)
++}
++
++static UInt32 Hc4_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
++{
++ UInt32 hash2Value, hash3Value, delta2, delta3, maxLen, offset;
++ GET_MATCHES_HEADER(4)
++
++ HASH4_CALC;
++
++ delta2 = p->pos - p->hash[ hash2Value];
++ delta3 = p->pos - p->hash[kFix3HashSize + hash3Value];
++ curMatch = p->hash[kFix4HashSize + hashValue];
++
++ p->hash[ hash2Value] =
++ p->hash[kFix3HashSize + hash3Value] =
++ p->hash[kFix4HashSize + hashValue] = p->pos;
++
++ maxLen = 1;
++ offset = 0;
++ if (delta2 < p->cyclicBufferSize && *(cur - delta2) == *cur)
++ {
++ distances[0] = maxLen = 2;
++ distances[1] = delta2 - 1;
++ offset = 2;
++ }
++ if (delta2 != delta3 && delta3 < p->cyclicBufferSize && *(cur - delta3) == *cur)
++ {
++ maxLen = 3;
++ distances[offset + 1] = delta3 - 1;
++ offset += 2;
++ delta2 = delta3;
++ }
++ if (offset != 0)
++ {
++ for (; maxLen != lenLimit; maxLen++)
++ if (cur[(ptrdiff_t)maxLen - delta2] != cur[maxLen])
++ break;
++ distances[offset - 2] = maxLen;
++ if (maxLen == lenLimit)
++ {
++ p->son[p->cyclicBufferPos] = curMatch;
++ MOVE_POS_RET;
++ }
++ }
++ if (maxLen < 3)
++ maxLen = 3;
++ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
++ distances + offset, maxLen) - (distances));
++ MOVE_POS_RET
++}
++
++UInt32 Hc3Zip_MatchFinder_GetMatches(CMatchFinder *p, UInt32 *distances)
++{
++ UInt32 offset;
++ GET_MATCHES_HEADER(3)
++ HASH_ZIP_CALC;
++ curMatch = p->hash[hashValue];
++ p->hash[hashValue] = p->pos;
++ offset = (UInt32)(Hc_GetMatchesSpec(lenLimit, curMatch, MF_PARAMS(p),
++ distances, 2) - (distances));
++ MOVE_POS_RET
++}
++
++static void Bt2_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
++{
++ do
++ {
++ SKIP_HEADER(2)
++ HASH2_CALC;
++ curMatch = p->hash[hashValue];
++ p->hash[hashValue] = p->pos;
++ SKIP_FOOTER
++ }
++ while (--num != 0);
++}
++
++void Bt3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
++{
++ do
++ {
++ SKIP_HEADER(3)
++ HASH_ZIP_CALC;
++ curMatch = p->hash[hashValue];
++ p->hash[hashValue] = p->pos;
++ SKIP_FOOTER
++ }
++ while (--num != 0);
++}
++
++static void Bt3_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
++{
++ do
++ {
++ UInt32 hash2Value;
++ SKIP_HEADER(3)
++ HASH3_CALC;
++ curMatch = p->hash[kFix3HashSize + hashValue];
++ p->hash[hash2Value] =
++ p->hash[kFix3HashSize + hashValue] = p->pos;
++ SKIP_FOOTER
++ }
++ while (--num != 0);
++}
++
++static void Bt4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
++{
++ do
++ {
++ UInt32 hash2Value, hash3Value;
++ SKIP_HEADER(4)
++ HASH4_CALC;
++ curMatch = p->hash[kFix4HashSize + hashValue];
++ p->hash[ hash2Value] =
++ p->hash[kFix3HashSize + hash3Value] = p->pos;
++ p->hash[kFix4HashSize + hashValue] = p->pos;
++ SKIP_FOOTER
++ }
++ while (--num != 0);
++}
++
++static void Hc4_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
++{
++ do
++ {
++ UInt32 hash2Value, hash3Value;
++ SKIP_HEADER(4)
++ HASH4_CALC;
++ curMatch = p->hash[kFix4HashSize + hashValue];
++ p->hash[ hash2Value] =
++ p->hash[kFix3HashSize + hash3Value] =
++ p->hash[kFix4HashSize + hashValue] = p->pos;
++ p->son[p->cyclicBufferPos] = curMatch;
++ MOVE_POS
++ }
++ while (--num != 0);
++}
++
++void Hc3Zip_MatchFinder_Skip(CMatchFinder *p, UInt32 num)
++{
++ do
++ {
++ SKIP_HEADER(3)
++ HASH_ZIP_CALC;
++ curMatch = p->hash[hashValue];
++ p->hash[hashValue] = p->pos;
++ p->son[p->cyclicBufferPos] = curMatch;
++ MOVE_POS
++ }
++ while (--num != 0);
++}
++
++void MatchFinder_CreateVTable(CMatchFinder *p, IMatchFinder *vTable)
++{
++ vTable->Init = (Mf_Init_Func)MatchFinder_Init;
++ vTable->GetIndexByte = (Mf_GetIndexByte_Func)MatchFinder_GetIndexByte;
++ vTable->GetNumAvailableBytes = (Mf_GetNumAvailableBytes_Func)MatchFinder_GetNumAvailableBytes;
++ vTable->GetPointerToCurrentPos = (Mf_GetPointerToCurrentPos_Func)MatchFinder_GetPointerToCurrentPos;
++ if (!p->btMode)
++ {
++ vTable->GetMatches = (Mf_GetMatches_Func)Hc4_MatchFinder_GetMatches;
++ vTable->Skip = (Mf_Skip_Func)Hc4_MatchFinder_Skip;
++ }
++ else if (p->numHashBytes == 2)
++ {
++ vTable->GetMatches = (Mf_GetMatches_Func)Bt2_MatchFinder_GetMatches;
++ vTable->Skip = (Mf_Skip_Func)Bt2_MatchFinder_Skip;
++ }
++ else if (p->numHashBytes == 3)
++ {
++ vTable->GetMatches = (Mf_GetMatches_Func)Bt3_MatchFinder_GetMatches;
++ vTable->Skip = (Mf_Skip_Func)Bt3_MatchFinder_Skip;
++ }
++ else
++ {
++ vTable->GetMatches = (Mf_GetMatches_Func)Bt4_MatchFinder_GetMatches;
++ vTable->Skip = (Mf_Skip_Func)Bt4_MatchFinder_Skip;
++ }
++}
+--- /dev/null
++++ b/lzma/LzmaDec.c
+@@ -0,0 +1,1014 @@
++/* LzmaDec.c -- LZMA Decoder
++2008-04-29
++Copyright (c) 1999-2008 Igor Pavlov
++Read LzmaDec.h for license options */
++
++#include "LzmaDec.h"
++
++#include <string.h>
++
++#define kNumTopBits 24
++#define kTopValue ((UInt32)1 << kNumTopBits)
++
++#define kNumBitModelTotalBits 11
++#define kBitModelTotal (1 << kNumBitModelTotalBits)
++#define kNumMoveBits 5
++
++#define RC_INIT_SIZE 5
++
++#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
++
++#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
++#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
++#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
++#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
++ { UPDATE_0(p); i = (i + i); A0; } else \
++ { UPDATE_1(p); i = (i + i) + 1; A1; }
++#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
++
++#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
++#define TREE_DECODE(probs, limit, i) \
++ { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
++
++/* #define _LZMA_SIZE_OPT */
++
++#ifdef _LZMA_SIZE_OPT
++#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
++#else
++#define TREE_6_DECODE(probs, i) \
++ { i = 1; \
++ TREE_GET_BIT(probs, i); \
++ TREE_GET_BIT(probs, i); \
++ TREE_GET_BIT(probs, i); \
++ TREE_GET_BIT(probs, i); \
++ TREE_GET_BIT(probs, i); \
++ TREE_GET_BIT(probs, i); \
++ i -= 0x40; }
++#endif
++
++#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
++
++#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
++#define UPDATE_0_CHECK range = bound;
++#define UPDATE_1_CHECK range -= bound; code -= bound;
++#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
++ { UPDATE_0_CHECK; i = (i + i); A0; } else \
++ { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
++#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
++#define TREE_DECODE_CHECK(probs, limit, i) \
++ { i = 1; do { GET_BIT_CHECK(probs + i, i) } while(i < limit); i -= limit; }
++
++
++#define kNumPosBitsMax 4
++#define kNumPosStatesMax (1 << kNumPosBitsMax)
++
++#define kLenNumLowBits 3
++#define kLenNumLowSymbols (1 << kLenNumLowBits)
++#define kLenNumMidBits 3
++#define kLenNumMidSymbols (1 << kLenNumMidBits)
++#define kLenNumHighBits 8
++#define kLenNumHighSymbols (1 << kLenNumHighBits)
++
++#define LenChoice 0
++#define LenChoice2 (LenChoice + 1)
++#define LenLow (LenChoice2 + 1)
++#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
++#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
++#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
++
++
++#define kNumStates 12
++#define kNumLitStates 7
++
++#define kStartPosModelIndex 4
++#define kEndPosModelIndex 14
++#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
++
++#define kNumPosSlotBits 6
++#define kNumLenToPosStates 4
++
++#define kNumAlignBits 4
++#define kAlignTableSize (1 << kNumAlignBits)
++
++#define kMatchMinLen 2
++#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
++
++#define IsMatch 0
++#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
++#define IsRepG0 (IsRep + kNumStates)
++#define IsRepG1 (IsRepG0 + kNumStates)
++#define IsRepG2 (IsRepG1 + kNumStates)
++#define IsRep0Long (IsRepG2 + kNumStates)
++#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
++#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
++#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
++#define LenCoder (Align + kAlignTableSize)
++#define RepLenCoder (LenCoder + kNumLenProbs)
++#define Literal (RepLenCoder + kNumLenProbs)
++
++#define LZMA_BASE_SIZE 1846
++#define LZMA_LIT_SIZE 768
++
++#define LzmaProps_GetNumProbs(p) ((UInt32)LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
++
++#if Literal != LZMA_BASE_SIZE
++StopCompilingDueBUG
++#endif
++
++/*
++#define LZMA_STREAM_WAS_FINISHED_ID (-1)
++#define LZMA_SPEC_LEN_OFFSET (-3)
++*/
++
++Byte kLiteralNextStates[kNumStates * 2] =
++{
++ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5,
++ 7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10
++};
++
++#define LZMA_DIC_MIN (1 << 12)
++
++/* First LZMA-symbol is always decoded.
++And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
++Out:
++ Result:
++ 0 - OK
++ 1 - Error
++ p->remainLen:
++ < kMatchSpecLenStart : normal remain
++ = kMatchSpecLenStart : finished
++ = kMatchSpecLenStart + 1 : Flush marker
++ = kMatchSpecLenStart + 2 : State Init Marker
++*/
++
++static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
++{
++ CLzmaProb *probs = p->probs;
++
++ unsigned state = p->state;
++ UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
++ unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
++ unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
++ unsigned lc = p->prop.lc;
++
++ Byte *dic = p->dic;
++ SizeT dicBufSize = p->dicBufSize;
++ SizeT dicPos = p->dicPos;
++
++ UInt32 processedPos = p->processedPos;
++ UInt32 checkDicSize = p->checkDicSize;
++ unsigned len = 0;
++
++ const Byte *buf = p->buf;
++ UInt32 range = p->range;
++ UInt32 code = p->code;
++
++ do
++ {
++ CLzmaProb *prob;
++ UInt32 bound;
++ unsigned ttt;
++ unsigned posState = processedPos & pbMask;
++
++ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
++ IF_BIT_0(prob)
++ {
++ unsigned symbol;
++ UPDATE_0(prob);
++ prob = probs + Literal;
++ if (checkDicSize != 0 || processedPos != 0)
++ prob += (LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
++ (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
++
++ if (state < kNumLitStates)
++ {
++ symbol = 1;
++ do { GET_BIT(prob + symbol, symbol) } while (symbol < 0x100);
++ }
++ else
++ {
++ unsigned matchByte = p->dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
++ unsigned offs = 0x100;
++ symbol = 1;
++ do
++ {
++ unsigned bit;
++ CLzmaProb *probLit;
++ matchByte <<= 1;
++ bit = (matchByte & offs);
++ probLit = prob + offs + bit + symbol;
++ GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
++ }
++ while (symbol < 0x100);
++ }
++ dic[dicPos++] = (Byte)symbol;
++ processedPos++;
++
++ state = kLiteralNextStates[state];
++ /* if (state < 4) state = 0; else if (state < 10) state -= 3; else state -= 6; */
++ continue;
++ }
++ else
++ {
++ UPDATE_1(prob);
++ prob = probs + IsRep + state;
++ IF_BIT_0(prob)
++ {
++ UPDATE_0(prob);
++ state += kNumStates;
++ prob = probs + LenCoder;
++ }
++ else
++ {
++ UPDATE_1(prob);
++ if (checkDicSize == 0 && processedPos == 0)
++ return SZ_ERROR_DATA;
++ prob = probs + IsRepG0 + state;
++ IF_BIT_0(prob)
++ {
++ UPDATE_0(prob);
++ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
++ IF_BIT_0(prob)
++ {
++ UPDATE_0(prob);
++ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
++ dicPos++;
++ processedPos++;
++ state = state < kNumLitStates ? 9 : 11;
++ continue;
++ }
++ UPDATE_1(prob);
++ }
++ else
++ {
++ UInt32 distance;
++ UPDATE_1(prob);
++ prob = probs + IsRepG1 + state;
++ IF_BIT_0(prob)
++ {
++ UPDATE_0(prob);
++ distance = rep1;
++ }
++ else
++ {
++ UPDATE_1(prob);
++ prob = probs + IsRepG2 + state;
++ IF_BIT_0(prob)
++ {
++ UPDATE_0(prob);
++ distance = rep2;
++ }
++ else
++ {
++ UPDATE_1(prob);
++ distance = rep3;
++ rep3 = rep2;
++ }
++ rep2 = rep1;
++ }
++ rep1 = rep0;
++ rep0 = distance;
++ }
++ state = state < kNumLitStates ? 8 : 11;
++ prob = probs + RepLenCoder;
++ }
++ {
++ unsigned limit, offset;
++ CLzmaProb *probLen = prob + LenChoice;
++ IF_BIT_0(probLen)
++ {
++ UPDATE_0(probLen);
++ probLen = prob + LenLow + (posState << kLenNumLowBits);
++ offset = 0;
++ limit = (1 << kLenNumLowBits);
++ }
++ else
++ {
++ UPDATE_1(probLen);
++ probLen = prob + LenChoice2;
++ IF_BIT_0(probLen)
++ {
++ UPDATE_0(probLen);
++ probLen = prob + LenMid + (posState << kLenNumMidBits);
++ offset = kLenNumLowSymbols;
++ limit = (1 << kLenNumMidBits);
++ }
++ else
++ {
++ UPDATE_1(probLen);
++ probLen = prob + LenHigh;
++ offset = kLenNumLowSymbols + kLenNumMidSymbols;
++ limit = (1 << kLenNumHighBits);
++ }
++ }
++ TREE_DECODE(probLen, limit, len);
++ len += offset;
++ }
++
++ if (state >= kNumStates)
++ {
++ UInt32 distance;
++ prob = probs + PosSlot +
++ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
++ TREE_6_DECODE(prob, distance);
++ if (distance >= kStartPosModelIndex)
++ {
++ unsigned posSlot = (unsigned)distance;
++ int numDirectBits = (int)(((distance >> 1) - 1));
++ distance = (2 | (distance & 1));
++ if (posSlot < kEndPosModelIndex)
++ {
++ distance <<= numDirectBits;
++ prob = probs + SpecPos + distance - posSlot - 1;
++ {
++ UInt32 mask = 1;
++ unsigned i = 1;
++ do
++ {
++ GET_BIT2(prob + i, i, ; , distance |= mask);
++ mask <<= 1;
++ }
++ while(--numDirectBits != 0);
++ }
++ }
++ else
++ {
++ numDirectBits -= kNumAlignBits;
++ do
++ {
++ NORMALIZE
++ range >>= 1;
++
++ {
++ UInt32 t;
++ code -= range;
++ t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
++ distance = (distance << 1) + (t + 1);
++ code += range & t;
++ }
++ /*
++ distance <<= 1;
++ if (code >= range)
++ {
++ code -= range;
++ distance |= 1;
++ }
++ */
++ }
++ while (--numDirectBits != 0);
++ prob = probs + Align;
++ distance <<= kNumAlignBits;
++ {
++ unsigned i = 1;
++ GET_BIT2(prob + i, i, ; , distance |= 1);
++ GET_BIT2(prob + i, i, ; , distance |= 2);
++ GET_BIT2(prob + i, i, ; , distance |= 4);
++ GET_BIT2(prob + i, i, ; , distance |= 8);
++ }
++ if (distance == (UInt32)0xFFFFFFFF)
++ {
++ len += kMatchSpecLenStart;
++ state -= kNumStates;
++ break;
++ }
++ }
++ }
++ rep3 = rep2;
++ rep2 = rep1;
++ rep1 = rep0;
++ rep0 = distance + 1;
++ if (checkDicSize == 0)
++ {
++ if (distance >= processedPos)
++ return SZ_ERROR_DATA;
++ }
++ else if (distance >= checkDicSize)
++ return SZ_ERROR_DATA;
++ state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
++ /* state = kLiteralNextStates[state]; */
++ }
++
++ len += kMatchMinLen;
++
++ {
++ SizeT rem = limit - dicPos;
++ unsigned curLen = ((rem < len) ? (unsigned)rem : len);
++ SizeT pos = (dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0);
++
++ processedPos += curLen;
++
++ len -= curLen;
++ if (pos + curLen <= dicBufSize)
++ {
++ Byte *dest = dic + dicPos;
++ ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
++ const Byte *lim = dest + curLen;
++ dicPos += curLen;
++ do
++ *(dest) = (Byte)*(dest + src);
++ while (++dest != lim);
++ }
++ else
++ {
++ do
++ {
++ dic[dicPos++] = dic[pos];
++ if (++pos == dicBufSize)
++ pos = 0;
++ }
++ while (--curLen != 0);
++ }
++ }
++ }
++ }
++ while (dicPos < limit && buf < bufLimit);
++ NORMALIZE;
++ p->buf = buf;
++ p->range = range;
++ p->code = code;
++ p->remainLen = len;
++ p->dicPos = dicPos;
++ p->processedPos = processedPos;
++ p->reps[0] = rep0;
++ p->reps[1] = rep1;
++ p->reps[2] = rep2;
++ p->reps[3] = rep3;
++ p->state = state;
++
++ return SZ_OK;
++}
++
++static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
++{
++ if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
++ {
++ Byte *dic = p->dic;
++ SizeT dicPos = p->dicPos;
++ SizeT dicBufSize = p->dicBufSize;
++ unsigned len = p->remainLen;
++ UInt32 rep0 = p->reps[0];
++ if (limit - dicPos < len)
++ len = (unsigned)(limit - dicPos);
++
++ if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
++ p->checkDicSize = p->prop.dicSize;
++
++ p->processedPos += len;
++ p->remainLen -= len;
++ while (len-- != 0)
++ {
++ dic[dicPos] = dic[(dicPos - rep0) + ((dicPos < rep0) ? dicBufSize : 0)];
++ dicPos++;
++ }
++ p->dicPos = dicPos;
++ }
++}
++
++/* LzmaDec_DecodeReal2 decodes LZMA-symbols and sets p->needFlush and p->needInit, if required. */
++
++static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
++{
++ do
++ {
++ SizeT limit2 = limit;
++ if (p->checkDicSize == 0)
++ {
++ UInt32 rem = p->prop.dicSize - p->processedPos;
++ if (limit - p->dicPos > rem)
++ limit2 = p->dicPos + rem;
++ }
++ RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
++ if (p->processedPos >= p->prop.dicSize)
++ p->checkDicSize = p->prop.dicSize;
++ LzmaDec_WriteRem(p, limit);
++ }
++ while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
++
++ if (p->remainLen > kMatchSpecLenStart)
++ {
++ p->remainLen = kMatchSpecLenStart;
++ }
++ return 0;
++}
++
++typedef enum
++{
++ DUMMY_ERROR, /* unexpected end of input stream */
++ DUMMY_LIT,
++ DUMMY_MATCH,
++ DUMMY_REP
++} ELzmaDummy;
++
++static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
++{
++ UInt32 range = p->range;
++ UInt32 code = p->code;
++ const Byte *bufLimit = buf + inSize;
++ CLzmaProb *probs = p->probs;
++ unsigned state = p->state;
++ ELzmaDummy res;
++
++ {
++ CLzmaProb *prob;
++ UInt32 bound;
++ unsigned ttt;
++ unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
++
++ prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
++ IF_BIT_0_CHECK(prob)
++ {
++ UPDATE_0_CHECK
++
++ /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
++
++ prob = probs + Literal;
++ if (p->checkDicSize != 0 || p->processedPos != 0)
++ prob += (LZMA_LIT_SIZE *
++ ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
++ (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
++
++ if (state < kNumLitStates)
++ {
++ unsigned symbol = 1;
++ do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
++ }
++ else
++ {
++ unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
++ ((p->dicPos < p->reps[0]) ? p->dicBufSize : 0)];
++ unsigned offs = 0x100;
++ unsigned symbol = 1;
++ do
++ {
++ unsigned bit;
++ CLzmaProb *probLit;
++ matchByte <<= 1;
++ bit = (matchByte & offs);
++ probLit = prob + offs + bit + symbol;
++ GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
++ }
++ while (symbol < 0x100);
++ }
++ res = DUMMY_LIT;
++ }
++ else
++ {
++ unsigned len;
++ UPDATE_1_CHECK;
++
++ prob = probs + IsRep + state;
++ IF_BIT_0_CHECK(prob)
++ {
++ UPDATE_0_CHECK;
++ state = 0;
++ prob = probs + LenCoder;
++ res = DUMMY_MATCH;
++ }
++ else
++ {
++ UPDATE_1_CHECK;
++ res = DUMMY_REP;
++ prob = probs + IsRepG0 + state;
++ IF_BIT_0_CHECK(prob)
++ {
++ UPDATE_0_CHECK;
++ prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
++ IF_BIT_0_CHECK(prob)
++ {
++ UPDATE_0_CHECK;
++ NORMALIZE_CHECK;
++ return DUMMY_REP;
++ }
++ else
++ {
++ UPDATE_1_CHECK;
++ }
++ }
++ else
++ {
++ UPDATE_1_CHECK;
++ prob = probs + IsRepG1 + state;
++ IF_BIT_0_CHECK(prob)
++ {
++ UPDATE_0_CHECK;
++ }
++ else
++ {
++ UPDATE_1_CHECK;
++ prob = probs + IsRepG2 + state;
++ IF_BIT_0_CHECK(prob)
++ {
++ UPDATE_0_CHECK;
++ }
++ else
++ {
++ UPDATE_1_CHECK;
++ }
++ }
++ }
++ state = kNumStates;
++ prob = probs + RepLenCoder;
++ }
++ {
++ unsigned limit, offset;
++ CLzmaProb *probLen = prob + LenChoice;
++ IF_BIT_0_CHECK(probLen)
++ {
++ UPDATE_0_CHECK;
++ probLen = prob + LenLow + (posState << kLenNumLowBits);
++ offset = 0;
++ limit = 1 << kLenNumLowBits;
++ }
++ else
++ {
++ UPDATE_1_CHECK;
++ probLen = prob + LenChoice2;
++ IF_BIT_0_CHECK(probLen)
++ {
++ UPDATE_0_CHECK;
++ probLen = prob + LenMid + (posState << kLenNumMidBits);
++ offset = kLenNumLowSymbols;
++ limit = 1 << kLenNumMidBits;
++ }
++ else
++ {
++ UPDATE_1_CHECK;
++ probLen = prob + LenHigh;
++ offset = kLenNumLowSymbols + kLenNumMidSymbols;
++ limit = 1 << kLenNumHighBits;
++ }
++ }
++ TREE_DECODE_CHECK(probLen, limit, len);
++ len += offset;
++ }
++
++ if (state < 4)
++ {
++ unsigned posSlot;
++ prob = probs + PosSlot +
++ ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
++ kNumPosSlotBits);
++ TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
++ if (posSlot >= kStartPosModelIndex)
++ {
++ int numDirectBits = ((posSlot >> 1) - 1);
++
++ /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
++
++ if (posSlot < kEndPosModelIndex)
++ {
++ prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
++ }
++ else
++ {
++ numDirectBits -= kNumAlignBits;
++ do
++ {
++ NORMALIZE_CHECK
++ range >>= 1;
++ code -= range & (((code - range) >> 31) - 1);
++ /* if (code >= range) code -= range; */
++ }
++ while (--numDirectBits != 0);
++ prob = probs + Align;
++ numDirectBits = kNumAlignBits;
++ }
++ {
++ unsigned i = 1;
++ do
++ {
++ GET_BIT_CHECK(prob + i, i);
++ }
++ while(--numDirectBits != 0);
++ }
++ }
++ }
++ }
++ }
++ NORMALIZE_CHECK;
++ return res;
++}
++
++
++static void LzmaDec_InitRc(CLzmaDec *p, const Byte *data)
++{
++ p->code = ((UInt32)data[1] << 24) | ((UInt32)data[2] << 16) | ((UInt32)data[3] << 8) | ((UInt32)data[4]);
++ p->range = 0xFFFFFFFF;
++ p->needFlush = 0;
++}
++
++void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
++{
++ p->needFlush = 1;
++ p->remainLen = 0;
++ p->tempBufSize = 0;
++
++ if (initDic)
++ {
++ p->processedPos = 0;
++ p->checkDicSize = 0;
++ p->needInitState = 1;
++ }
++ if (initState)
++ p->needInitState = 1;
++}
++
++void LzmaDec_Init(CLzmaDec *p)
++{
++ p->dicPos = 0;
++ LzmaDec_InitDicAndState(p, True, True);
++}
++
++static void LzmaDec_InitStateReal(CLzmaDec *p)
++{
++ UInt32 numProbs = Literal + ((UInt32)LZMA_LIT_SIZE << (p->prop.lc + p->prop.lp));
++ UInt32 i;
++ CLzmaProb *probs = p->probs;
++ for (i = 0; i < numProbs; i++)
++ probs[i] = kBitModelTotal >> 1;
++ p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
++ p->state = 0;
++ p->needInitState = 0;
++}
++
++SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
++ ELzmaFinishMode finishMode, ELzmaStatus *status)
++{
++ SizeT inSize = *srcLen;
++ (*srcLen) = 0;
++ LzmaDec_WriteRem(p, dicLimit);
++
++ *status = LZMA_STATUS_NOT_SPECIFIED;
++
++ while (p->remainLen != kMatchSpecLenStart)
++ {
++ int checkEndMarkNow;
++
++ if (p->needFlush != 0)
++ {
++ for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
++ p->tempBuf[p->tempBufSize++] = *src++;
++ if (p->tempBufSize < RC_INIT_SIZE)
++ {
++ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
++ return SZ_OK;
++ }
++ if (p->tempBuf[0] != 0)
++ return SZ_ERROR_DATA;
++
++ LzmaDec_InitRc(p, p->tempBuf);
++ p->tempBufSize = 0;
++ }
++
++ checkEndMarkNow = 0;
++ if (p->dicPos >= dicLimit)
++ {
++ if (p->remainLen == 0 && p->code == 0)
++ {
++ *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
++ return SZ_OK;
++ }
++ if (finishMode == LZMA_FINISH_ANY)
++ {
++ *status = LZMA_STATUS_NOT_FINISHED;
++ return SZ_OK;
++ }
++ if (p->remainLen != 0)
++ {
++ *status = LZMA_STATUS_NOT_FINISHED;
++ return SZ_ERROR_DATA;
++ }
++ checkEndMarkNow = 1;
++ }
++
++ if (p->needInitState)
++ LzmaDec_InitStateReal(p);
++
++ if (p->tempBufSize == 0)
++ {
++ SizeT processed;
++ const Byte *bufLimit;
++ if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
++ {
++ int dummyRes = LzmaDec_TryDummy(p, src, inSize);
++ if (dummyRes == DUMMY_ERROR)
++ {
++ memcpy(p->tempBuf, src, inSize);
++ p->tempBufSize = (unsigned)inSize;
++ (*srcLen) += inSize;
++ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
++ return SZ_OK;
++ }
++ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
++ {
++ *status = LZMA_STATUS_NOT_FINISHED;
++ return SZ_ERROR_DATA;
++ }
++ bufLimit = src;
++ }
++ else
++ bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
++ p->buf = src;
++ if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
++ return SZ_ERROR_DATA;
++ processed = p->buf - src;
++ (*srcLen) += processed;
++ src += processed;
++ inSize -= processed;
++ }
++ else
++ {
++ unsigned rem = p->tempBufSize, lookAhead = 0;
++ while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
++ p->tempBuf[rem++] = src[lookAhead++];
++ p->tempBufSize = rem;
++ if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
++ {
++ int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
++ if (dummyRes == DUMMY_ERROR)
++ {
++ (*srcLen) += lookAhead;
++ *status = LZMA_STATUS_NEEDS_MORE_INPUT;
++ return SZ_OK;
++ }
++ if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
++ {
++ *status = LZMA_STATUS_NOT_FINISHED;
++ return SZ_ERROR_DATA;
++ }
++ }
++ p->buf = p->tempBuf;
++ if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
++ return SZ_ERROR_DATA;
++ lookAhead -= (rem - (unsigned)(p->buf - p->tempBuf));
++ (*srcLen) += lookAhead;
++ src += lookAhead;
++ inSize -= lookAhead;
++ p->tempBufSize = 0;
++ }
++ }
++ if (p->code == 0)
++ *status = LZMA_STATUS_FINISHED_WITH_MARK;
++ return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
++}
++
++SRes LzmaDec_DecodeToBuf(CLzmaDec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
++{
++ SizeT outSize = *destLen;
++ SizeT inSize = *srcLen;
++ *srcLen = *destLen = 0;
++ for (;;)
++ {
++ SizeT inSizeCur = inSize, outSizeCur, dicPos;
++ ELzmaFinishMode curFinishMode;
++ SRes res;
++ if (p->dicPos == p->dicBufSize)
++ p->dicPos = 0;
++ dicPos = p->dicPos;
++ if (outSize > p->dicBufSize - dicPos)
++ {
++ outSizeCur = p->dicBufSize;
++ curFinishMode = LZMA_FINISH_ANY;
++ }
++ else
++ {
++ outSizeCur = dicPos + outSize;
++ curFinishMode = finishMode;
++ }
++
++ res = LzmaDec_DecodeToDic(p, outSizeCur, src, &inSizeCur, curFinishMode, status);
++ src += inSizeCur;
++ inSize -= inSizeCur;
++ *srcLen += inSizeCur;
++ outSizeCur = p->dicPos - dicPos;
++ memcpy(dest, p->dic + dicPos, outSizeCur);
++ dest += outSizeCur;
++ outSize -= outSizeCur;
++ *destLen += outSizeCur;
++ if (res != 0)
++ return res;
++ if (outSizeCur == 0 || outSize == 0)
++ return SZ_OK;
++ }
++}
++
++void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
++{
++ alloc->Free(alloc, p->probs);
++ p->probs = 0;
++}
++
++static void LzmaDec_FreeDict(CLzmaDec *p, ISzAlloc *alloc)
++{
++ alloc->Free(alloc, p->dic);
++ p->dic = 0;
++}
++
++void LzmaDec_Free(CLzmaDec *p, ISzAlloc *alloc)
++{
++ LzmaDec_FreeProbs(p, alloc);
++ LzmaDec_FreeDict(p, alloc);
++}
++
++SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
++{
++ UInt32 dicSize;
++ Byte d;
++
++ if (size < LZMA_PROPS_SIZE)
++ return SZ_ERROR_UNSUPPORTED;
++ else
++ dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
++
++ if (dicSize < LZMA_DIC_MIN)
++ dicSize = LZMA_DIC_MIN;
++ p->dicSize = dicSize;
++
++ d = data[0];
++ if (d >= (9 * 5 * 5))
++ return SZ_ERROR_UNSUPPORTED;
++
++ p->lc = d % 9;
++ d /= 9;
++ p->pb = d / 5;
++ p->lp = d % 5;
++
++ return SZ_OK;
++}
++
++static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
++{
++ UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
++ if (p->probs == 0 || numProbs != p->numProbs)
++ {
++ LzmaDec_FreeProbs(p, alloc);
++ p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
++ p->numProbs = numProbs;
++ if (p->probs == 0)
++ return SZ_ERROR_MEM;
++ }
++ return SZ_OK;
++}
++
++SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
++{
++ CLzmaProps propNew;
++ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
++ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
++ p->prop = propNew;
++ return SZ_OK;
++}
++
++SRes LzmaDec_Allocate(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
++{
++ CLzmaProps propNew;
++ SizeT dicBufSize;
++ RINOK(LzmaProps_Decode(&propNew, props, propsSize));
++ RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
++ dicBufSize = propNew.dicSize;
++ if (p->dic == 0 || dicBufSize != p->dicBufSize)
++ {
++ LzmaDec_FreeDict(p, alloc);
++ p->dic = (Byte *)alloc->Alloc(alloc, dicBufSize);
++ if (p->dic == 0)
++ {
++ LzmaDec_FreeProbs(p, alloc);
++ return SZ_ERROR_MEM;
++ }
++ }
++ p->dicBufSize = dicBufSize;
++ p->prop = propNew;
++ return SZ_OK;
++}
++
++SRes LzmaDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
++ const Byte *propData, unsigned propSize, ELzmaFinishMode finishMode,
++ ELzmaStatus *status, ISzAlloc *alloc)
++{
++ CLzmaDec p;
++ SRes res;
++ SizeT inSize = *srcLen;
++ SizeT outSize = *destLen;
++ *srcLen = *destLen = 0;
++ if (inSize < RC_INIT_SIZE)
++ return SZ_ERROR_INPUT_EOF;
++
++ LzmaDec_Construct(&p);
++ res = LzmaDec_AllocateProbs(&p, propData, propSize, alloc);
++ if (res != 0)
++ return res;
++ p.dic = dest;
++ p.dicBufSize = outSize;
++
++ LzmaDec_Init(&p);
++
++ *srcLen = inSize;
++ res = LzmaDec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
++
++ if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
++ res = SZ_ERROR_INPUT_EOF;
++
++ (*destLen) = p.dicPos;
++ LzmaDec_FreeProbs(&p, alloc);
++ return res;
++}
+--- /dev/null
++++ b/lzma/LzmaEnc.c
+@@ -0,0 +1,2335 @@
++/* LzmaEnc.c -- LZMA Encoder
++2008-04-28
++Copyright (c) 1999-2008 Igor Pavlov
++Read LzmaEnc.h for license options */
++
++#if defined(SHOW_STAT) || defined(SHOW_STAT2)
++#include <stdio.h>
++#endif
++
++#include <string.h>
++
++#include "LzmaEnc.h"
++
++#include "LzFind.h"
++#ifdef COMPRESS_MF_MT
++#include "LzFindMt.h"
++#endif
++
++/* #define SHOW_STAT */
++/* #define SHOW_STAT2 */
++
++#ifdef SHOW_STAT
++static int ttt = 0;
++#endif
++
++#define kBlockSizeMax ((1 << LZMA_NUM_BLOCK_SIZE_BITS) - 1)
++
++#define kBlockSize (9 << 10)
++#define kUnpackBlockSize (1 << 18)
++#define kMatchArraySize (1 << 21)
++#define kMatchRecordMaxSize ((LZMA_MATCH_LEN_MAX * 2 + 3) * LZMA_MATCH_LEN_MAX)
++
++#define kNumMaxDirectBits (31)
++
++#define kNumTopBits 24
++#define kTopValue ((UInt32)1 << kNumTopBits)
++
++#define kNumBitModelTotalBits 11
++#define kBitModelTotal (1 << kNumBitModelTotalBits)
++#define kNumMoveBits 5
++#define kProbInitValue (kBitModelTotal >> 1)
++
++#define kNumMoveReducingBits 4
++#define kNumBitPriceShiftBits 4
++#define kBitPrice (1 << kNumBitPriceShiftBits)
++
++void LzmaEncProps_Init(CLzmaEncProps *p)
++{
++ p->level = 5;
++ p->dictSize = p->mc = 0;
++ p->lc = p->lp = p->pb = p->algo = p->fb = p->btMode = p->numHashBytes = p->numThreads = -1;
++ p->writeEndMark = 0;
++}
++
++void LzmaEncProps_Normalize(CLzmaEncProps *p)
++{
++ int level = p->level;
++ if (level < 0) level = 5;
++ p->level = level;
++ if (p->dictSize == 0) p->dictSize = (level <= 5 ? (1 << (level * 2 + 14)) : (level == 6 ? (1 << 25) : (1 << 26)));
++ if (p->lc < 0) p->lc = 3;
++ if (p->lp < 0) p->lp = 0;
++ if (p->pb < 0) p->pb = 2;
++ if (p->algo < 0) p->algo = (level < 5 ? 0 : 1);
++ if (p->fb < 0) p->fb = (level < 7 ? 32 : 64);
++ if (p->btMode < 0) p->btMode = (p->algo == 0 ? 0 : 1);
++ if (p->numHashBytes < 0) p->numHashBytes = 4;
++ if (p->mc == 0) p->mc = (16 + (p->fb >> 1)) >> (p->btMode ? 0 : 1);
++ if (p->numThreads < 0) p->numThreads = ((p->btMode && p->algo) ? 2 : 1);
++}
++
++UInt32 LzmaEncProps_GetDictSize(const CLzmaEncProps *props2)
++{
++ CLzmaEncProps props = *props2;
++ LzmaEncProps_Normalize(&props);
++ return props.dictSize;
++}
++
++/* #define LZMA_LOG_BSR */
++/* Define it for Intel's CPU */
++
++
++#ifdef LZMA_LOG_BSR
++
++#define kDicLogSizeMaxCompress 30
++
++#define BSR2_RET(pos, res) { unsigned long i; _BitScanReverse(&i, (pos)); res = (i + i) + ((pos >> (i - 1)) & 1); }
++
++UInt32 GetPosSlot1(UInt32 pos)
++{
++ UInt32 res;
++ BSR2_RET(pos, res);
++ return res;
++}
++#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
++#define GetPosSlot(pos, res) { if (pos < 2) res = pos; else BSR2_RET(pos, res); }
++
++#else
++
++#define kNumLogBits (9 + (int)sizeof(size_t) / 2)
++#define kDicLogSizeMaxCompress ((kNumLogBits - 1) * 2 + 7)
++
++void LzmaEnc_FastPosInit(Byte *g_FastPos)
++{
++ int c = 2, slotFast;
++ g_FastPos[0] = 0;
++ g_FastPos[1] = 1;
++
++ for (slotFast = 2; slotFast < kNumLogBits * 2; slotFast++)
++ {
++ UInt32 k = (1 << ((slotFast >> 1) - 1));
++ UInt32 j;
++ for (j = 0; j < k; j++, c++)
++ g_FastPos[c] = (Byte)slotFast;
++ }
++}
++
++#define BSR2_RET(pos, res) { UInt32 i = 6 + ((kNumLogBits - 1) & \
++ (0 - (((((UInt32)1 << (kNumLogBits + 6)) - 1) - pos) >> 31))); \
++ res = p->g_FastPos[pos >> i] + (i * 2); }
++/*
++#define BSR2_RET(pos, res) { res = (pos < (1 << (kNumLogBits + 6))) ? \
++ p->g_FastPos[pos >> 6] + 12 : \
++ p->g_FastPos[pos >> (6 + kNumLogBits - 1)] + (6 + (kNumLogBits - 1)) * 2; }
++*/
++
++#define GetPosSlot1(pos) p->g_FastPos[pos]
++#define GetPosSlot2(pos, res) { BSR2_RET(pos, res); }
++#define GetPosSlot(pos, res) { if (pos < kNumFullDistances) res = p->g_FastPos[pos]; else BSR2_RET(pos, res); }
++
++#endif
++
++
++#define LZMA_NUM_REPS 4
++
++typedef unsigned CState;
++
++typedef struct _COptimal
++{
++ UInt32 price;
++
++ CState state;
++ int prev1IsChar;
++ int prev2;
++
++ UInt32 posPrev2;
++ UInt32 backPrev2;
++
++ UInt32 posPrev;
++ UInt32 backPrev;
++ UInt32 backs[LZMA_NUM_REPS];
++} COptimal;
++
++#define kNumOpts (1 << 12)
++
++#define kNumLenToPosStates 4
++#define kNumPosSlotBits 6
++#define kDicLogSizeMin 0
++#define kDicLogSizeMax 32
++#define kDistTableSizeMax (kDicLogSizeMax * 2)
++
++
++#define kNumAlignBits 4
++#define kAlignTableSize (1 << kNumAlignBits)
++#define kAlignMask (kAlignTableSize - 1)
++
++#define kStartPosModelIndex 4
++#define kEndPosModelIndex 14
++#define kNumPosModels (kEndPosModelIndex - kStartPosModelIndex)
++
++#define kNumFullDistances (1 << (kEndPosModelIndex / 2))
++
++#ifdef _LZMA_PROB32
++#define CLzmaProb UInt32
++#else
++#define CLzmaProb UInt16
++#endif
++
++#define LZMA_PB_MAX 4
++#define LZMA_LC_MAX 8
++#define LZMA_LP_MAX 4
++
++#define LZMA_NUM_PB_STATES_MAX (1 << LZMA_PB_MAX)
++
++
++#define kLenNumLowBits 3
++#define kLenNumLowSymbols (1 << kLenNumLowBits)
++#define kLenNumMidBits 3
++#define kLenNumMidSymbols (1 << kLenNumMidBits)
++#define kLenNumHighBits 8
++#define kLenNumHighSymbols (1 << kLenNumHighBits)
++
++#define kLenNumSymbolsTotal (kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
++
++#define LZMA_MATCH_LEN_MIN 2
++#define LZMA_MATCH_LEN_MAX (LZMA_MATCH_LEN_MIN + kLenNumSymbolsTotal - 1)
++
++#define kNumStates 12
++
++typedef struct
++{
++ CLzmaProb choice;
++ CLzmaProb choice2;
++ CLzmaProb low[LZMA_NUM_PB_STATES_MAX << kLenNumLowBits];
++ CLzmaProb mid[LZMA_NUM_PB_STATES_MAX << kLenNumMidBits];
++ CLzmaProb high[kLenNumHighSymbols];
++} CLenEnc;
++
++typedef struct
++{
++ CLenEnc p;
++ UInt32 prices[LZMA_NUM_PB_STATES_MAX][kLenNumSymbolsTotal];
++ UInt32 tableSize;
++ UInt32 counters[LZMA_NUM_PB_STATES_MAX];
++} CLenPriceEnc;
++
++typedef struct _CRangeEnc
++{
++ UInt32 range;
++ Byte cache;
++ UInt64 low;
++ UInt64 cacheSize;
++ Byte *buf;
++ Byte *bufLim;
++ Byte *bufBase;
++ ISeqOutStream *outStream;
++ UInt64 processed;
++ SRes res;
++} CRangeEnc;
++
++typedef struct _CSeqInStreamBuf
++{
++ ISeqInStream funcTable;
++ const Byte *data;
++ SizeT rem;
++} CSeqInStreamBuf;
++
++static SRes MyRead(void *pp, void *data, size_t *size)
++{
++ size_t curSize = *size;
++ CSeqInStreamBuf *p = (CSeqInStreamBuf *)pp;
++ if (p->rem < curSize)
++ curSize = p->rem;
++ memcpy(data, p->data, curSize);
++ p->rem -= curSize;
++ p->data += curSize;
++ *size = curSize;
++ return SZ_OK;
++}
++
++typedef struct
++{
++ CLzmaProb *litProbs;
++
++ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
++ CLzmaProb isRep[kNumStates];
++ CLzmaProb isRepG0[kNumStates];
++ CLzmaProb isRepG1[kNumStates];
++ CLzmaProb isRepG2[kNumStates];
++ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
++
++ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
++ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
++ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
++
++ CLenPriceEnc lenEnc;
++ CLenPriceEnc repLenEnc;
++
++ UInt32 reps[LZMA_NUM_REPS];
++ UInt32 state;
++} CSaveState;
++
++typedef struct _CLzmaEnc
++{
++ IMatchFinder matchFinder;
++ void *matchFinderObj;
++
++ #ifdef COMPRESS_MF_MT
++ Bool mtMode;
++ CMatchFinderMt matchFinderMt;
++ #endif
++
++ CMatchFinder matchFinderBase;
++
++ #ifdef COMPRESS_MF_MT
++ Byte pad[128];
++ #endif
++
++ UInt32 optimumEndIndex;
++ UInt32 optimumCurrentIndex;
++
++ Bool longestMatchWasFound;
++ UInt32 longestMatchLength;
++ UInt32 numDistancePairs;
++
++ COptimal opt[kNumOpts];
++
++ #ifndef LZMA_LOG_BSR
++ Byte g_FastPos[1 << kNumLogBits];
++ #endif
++
++ UInt32 ProbPrices[kBitModelTotal >> kNumMoveReducingBits];
++ UInt32 matchDistances[LZMA_MATCH_LEN_MAX * 2 + 2 + 1];
++ UInt32 numFastBytes;
++ UInt32 additionalOffset;
++ UInt32 reps[LZMA_NUM_REPS];
++ UInt32 state;
++
++ UInt32 posSlotPrices[kNumLenToPosStates][kDistTableSizeMax];
++ UInt32 distancesPrices[kNumLenToPosStates][kNumFullDistances];
++ UInt32 alignPrices[kAlignTableSize];
++ UInt32 alignPriceCount;
++
++ UInt32 distTableSize;
++
++ unsigned lc, lp, pb;
++ unsigned lpMask, pbMask;
++
++ CLzmaProb *litProbs;
++
++ CLzmaProb isMatch[kNumStates][LZMA_NUM_PB_STATES_MAX];
++ CLzmaProb isRep[kNumStates];
++ CLzmaProb isRepG0[kNumStates];
++ CLzmaProb isRepG1[kNumStates];
++ CLzmaProb isRepG2[kNumStates];
++ CLzmaProb isRep0Long[kNumStates][LZMA_NUM_PB_STATES_MAX];
++
++ CLzmaProb posSlotEncoder[kNumLenToPosStates][1 << kNumPosSlotBits];
++ CLzmaProb posEncoders[kNumFullDistances - kEndPosModelIndex];
++ CLzmaProb posAlignEncoder[1 << kNumAlignBits];
++
++ CLenPriceEnc lenEnc;
++ CLenPriceEnc repLenEnc;
++
++ unsigned lclp;
++
++ Bool fastMode;
++
++ CRangeEnc rc;
++
++ Bool writeEndMark;
++ UInt64 nowPos64;
++ UInt32 matchPriceCount;
++ Bool finished;
++ Bool multiThread;
++
++ SRes result;
++ UInt32 dictSize;
++ UInt32 matchFinderCycles;
++
++ ISeqInStream *inStream;
++ CSeqInStreamBuf seqBufInStream;
++
++ CSaveState saveState;
++} CLzmaEnc;
++
++void LzmaEnc_SaveState(CLzmaEncHandle pp)
++{
++ CLzmaEnc *p = (CLzmaEnc *)pp;
++ CSaveState *dest = &p->saveState;
++ int i;
++ dest->lenEnc = p->lenEnc;
++ dest->repLenEnc = p->repLenEnc;
++ dest->state = p->state;
++
++ for (i = 0; i < kNumStates; i++)
++ {
++ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
++ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
++ }
++ for (i = 0; i < kNumLenToPosStates; i++)
++ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
++ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
++ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
++ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
++ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
++ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
++ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
++ memcpy(dest->reps, p->reps, sizeof(p->reps));
++ memcpy(dest->litProbs, p->litProbs, (0x300 << p->lclp) * sizeof(CLzmaProb));
++}
++
++void LzmaEnc_RestoreState(CLzmaEncHandle pp)
++{
++ CLzmaEnc *dest = (CLzmaEnc *)pp;
++ const CSaveState *p = &dest->saveState;
++ int i;
++ dest->lenEnc = p->lenEnc;
++ dest->repLenEnc = p->repLenEnc;
++ dest->state = p->state;
++
++ for (i = 0; i < kNumStates; i++)
++ {
++ memcpy(dest->isMatch[i], p->isMatch[i], sizeof(p->isMatch[i]));
++ memcpy(dest->isRep0Long[i], p->isRep0Long[i], sizeof(p->isRep0Long[i]));
++ }
++ for (i = 0; i < kNumLenToPosStates; i++)
++ memcpy(dest->posSlotEncoder[i], p->posSlotEncoder[i], sizeof(p->posSlotEncoder[i]));
++ memcpy(dest->isRep, p->isRep, sizeof(p->isRep));
++ memcpy(dest->isRepG0, p->isRepG0, sizeof(p->isRepG0));
++ memcpy(dest->isRepG1, p->isRepG1, sizeof(p->isRepG1));
++ memcpy(dest->isRepG2, p->isRepG2, sizeof(p->isRepG2));
++ memcpy(dest->posEncoders, p->posEncoders, sizeof(p->posEncoders));
++ memcpy(dest->posAlignEncoder, p->posAlignEncoder, sizeof(p->posAlignEncoder));
++ memcpy(dest->reps, p->reps, sizeof(p->reps));
++ memcpy(dest->litProbs, p->litProbs, (0x300 << dest->lclp) * sizeof(CLzmaProb));
++}
++
++SRes LzmaEnc_SetProps(CLzmaEncHandle pp, const CLzmaEncProps *props2)
++{
++ CLzmaEnc *p = (CLzmaEnc *)pp;
++ CLzmaEncProps props = *props2;
++ LzmaEncProps_Normalize(&props);
++
++ if (props.lc > LZMA_LC_MAX || props.lp > LZMA_LP_MAX || props.pb > LZMA_PB_MAX ||
++ props.dictSize > (1 << kDicLogSizeMaxCompress) || props.dictSize > (1 << 30))
++ return SZ_ERROR_PARAM;
++ p->dictSize = props.dictSize;
++ p->matchFinderCycles = props.mc;
++ {
++ unsigned fb = props.fb;
++ if (fb < 5)
++ fb = 5;
++ if (fb > LZMA_MATCH_LEN_MAX)
++ fb = LZMA_MATCH_LEN_MAX;
++ p->numFastBytes = fb;
++ }
++ p->lc = props.lc;
++ p->lp = props.lp;
++ p->pb = props.pb;
++ p->fastMode = (props.algo == 0);
++ p->matchFinderBase.btMode = props.btMode;
++ {
++ UInt32 numHashBytes = 4;
++ if (props.btMode)
++ {
++ if (props.numHashBytes < 2)
++ numHashBytes = 2;
++ else if (props.numHashBytes < 4)
++ numHashBytes = props.numHashBytes;
++ }
++ p->matchFinderBase.numHashBytes = numHashBytes;
++ }
++
++ p->matchFinderBase.cutValue = props.mc;
++
++ p->writeEndMark = props.writeEndMark;
++
++ #ifdef COMPRESS_MF_MT
++ /*
++ if (newMultiThread != _multiThread)
++ {
++ ReleaseMatchFinder();
++ _multiThread = newMultiThread;
++ }
++ */
++ p->multiThread = (props.numThreads > 1);
++ #endif
++
++ return SZ_OK;
++}
++
++static const int kLiteralNextStates[kNumStates] = {0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5};
++static const int kMatchNextStates[kNumStates] = {7, 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, 10};
++static const int kRepNextStates[kNumStates] = {8, 8, 8, 8, 8, 8, 8, 11, 11, 11, 11, 11};
++static const int kShortRepNextStates[kNumStates]= {9, 9, 9, 9, 9, 9, 9, 11, 11, 11, 11, 11};
++
++/*
++ void UpdateChar() { Index = kLiteralNextStates[Index]; }
++ void UpdateMatch() { Index = kMatchNextStates[Index]; }
++ void UpdateRep() { Index = kRepNextStates[Index]; }
++ void UpdateShortRep() { Index = kShortRepNextStates[Index]; }
++*/
++
++#define IsCharState(s) ((s) < 7)
++
++
++#define GetLenToPosState(len) (((len) < kNumLenToPosStates + 1) ? (len) - 2 : kNumLenToPosStates - 1)
++
++#define kInfinityPrice (1 << 30)
++
++static void RangeEnc_Construct(CRangeEnc *p)
++{
++ p->outStream = 0;
++ p->bufBase = 0;
++}
++
++#define RangeEnc_GetProcessed(p) ((p)->processed + ((p)->buf - (p)->bufBase) + (p)->cacheSize)
++
++#define RC_BUF_SIZE (1 << 16)
++static int RangeEnc_Alloc(CRangeEnc *p, ISzAlloc *alloc)
++{
++ if (p->bufBase == 0)
++ {
++ p->bufBase = (Byte *)alloc->Alloc(alloc, RC_BUF_SIZE);
++ if (p->bufBase == 0)
++ return 0;
++ p->bufLim = p->bufBase + RC_BUF_SIZE;
++ }
++ return 1;
++}
++
++static void RangeEnc_Free(CRangeEnc *p, ISzAlloc *alloc)
++{
++ alloc->Free(alloc, p->bufBase);
++ p->bufBase = 0;
++}
++
++static void RangeEnc_Init(CRangeEnc *p)
++{
++ /* Stream.Init(); */
++ p->low = 0;
++ p->range = 0xFFFFFFFF;
++ p->cacheSize = 1;
++ p->cache = 0;
++
++ p->buf = p->bufBase;
++
++ p->processed = 0;
++ p->res = SZ_OK;
++}
++
++static void RangeEnc_FlushStream(CRangeEnc *p)
++{
++ size_t num;
++ if (p->res != SZ_OK)
++ return;
++ num = p->buf - p->bufBase;
++ if (num != p->outStream->Write(p->outStream, p->bufBase, num))
++ p->res = SZ_ERROR_WRITE;
++ p->processed += num;
++ p->buf = p->bufBase;
++}
++
++static void MY_FAST_CALL RangeEnc_ShiftLow(CRangeEnc *p)
++{
++ if ((UInt32)p->low < (UInt32)0xFF000000 || (int)(p->low >> 32) != 0)
++ {
++ Byte temp = p->cache;
++ do
++ {
++ Byte *buf = p->buf;
++ *buf++ = (Byte)(temp + (Byte)(p->low >> 32));
++ p->buf = buf;
++ if (buf == p->bufLim)
++ RangeEnc_FlushStream(p);
++ temp = 0xFF;
++ }
++ while (--p->cacheSize != 0);
++ p->cache = (Byte)((UInt32)p->low >> 24);
++ }
++ p->cacheSize++;
++ p->low = (UInt32)p->low << 8;
++}
++
++static void RangeEnc_FlushData(CRangeEnc *p)
++{
++ int i;
++ for (i = 0; i < 5; i++)
++ RangeEnc_ShiftLow(p);
++}
++
++static void RangeEnc_EncodeDirectBits(CRangeEnc *p, UInt32 value, int numBits)
++{
++ do
++ {
++ p->range >>= 1;
++ p->low += p->range & (0 - ((value >> --numBits) & 1));
++ if (p->range < kTopValue)
++ {
++ p->range <<= 8;
++ RangeEnc_ShiftLow(p);
++ }
++ }
++ while (numBits != 0);
++}
++
++static void RangeEnc_EncodeBit(CRangeEnc *p, CLzmaProb *prob, UInt32 symbol)
++{
++ UInt32 ttt = *prob;
++ UInt32 newBound = (p->range >> kNumBitModelTotalBits) * ttt;
++ if (symbol == 0)
++ {
++ p->range = newBound;
++ ttt += (kBitModelTotal - ttt) >> kNumMoveBits;
++ }
++ else
++ {
++ p->low += newBound;
++ p->range -= newBound;
++ ttt -= ttt >> kNumMoveBits;
++ }
++ *prob = (CLzmaProb)ttt;
++ if (p->range < kTopValue)
++ {
++ p->range <<= 8;
++ RangeEnc_ShiftLow(p);
++ }
++}
++
++static void LitEnc_Encode(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol)
++{
++ symbol |= 0x100;
++ do
++ {
++ RangeEnc_EncodeBit(p, probs + (symbol >> 8), (symbol >> 7) & 1);
++ symbol <<= 1;
++ }
++ while (symbol < 0x10000);
++}
++
++static void LitEnc_EncodeMatched(CRangeEnc *p, CLzmaProb *probs, UInt32 symbol, UInt32 matchByte)
++{
++ UInt32 offs = 0x100;
++ symbol |= 0x100;
++ do
++ {
++ matchByte <<= 1;
++ RangeEnc_EncodeBit(p, probs + (offs + (matchByte & offs) + (symbol >> 8)), (symbol >> 7) & 1);
++ symbol <<= 1;
++ offs &= ~(matchByte ^ symbol);
++ }
++ while (symbol < 0x10000);
++}
++
++void LzmaEnc_InitPriceTables(UInt32 *ProbPrices)
++{
++ UInt32 i;
++ for (i = (1 << kNumMoveReducingBits) / 2; i < kBitModelTotal; i += (1 << kNumMoveReducingBits))
++ {
++ const int kCyclesBits = kNumBitPriceShiftBits;
++ UInt32 w = i;
++ UInt32 bitCount = 0;
++ int j;
++ for (j = 0; j < kCyclesBits; j++)
++ {
++ w = w * w;
++ bitCount <<= 1;
++ while (w >= ((UInt32)1 << 16))
++ {
++ w >>= 1;
++ bitCount++;
++ }
++ }
++ ProbPrices[i >> kNumMoveReducingBits] = ((kNumBitModelTotalBits << kCyclesBits) - 15 - bitCount);
++ }
++}
++
++
++#define GET_PRICE(prob, symbol) \
++ p->ProbPrices[((prob) ^ (((-(int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
++
++#define GET_PRICEa(prob, symbol) \
++ ProbPrices[((prob) ^ ((-((int)(symbol))) & (kBitModelTotal - 1))) >> kNumMoveReducingBits];
++
++#define GET_PRICE_0(prob) p->ProbPrices[(prob) >> kNumMoveReducingBits]
++#define GET_PRICE_1(prob) p->ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
++
++#define GET_PRICE_0a(prob) ProbPrices[(prob) >> kNumMoveReducingBits]
++#define GET_PRICE_1a(prob) ProbPrices[((prob) ^ (kBitModelTotal - 1)) >> kNumMoveReducingBits]
++
++static UInt32 LitEnc_GetPrice(const CLzmaProb *probs, UInt32 symbol, UInt32 *ProbPrices)
++{
++ UInt32 price = 0;
++ symbol |= 0x100;
++ do
++ {
++ price += GET_PRICEa(probs[symbol >> 8], (symbol >> 7) & 1);
++ symbol <<= 1;
++ }
++ while (symbol < 0x10000);
++ return price;
++};
++
++static UInt32 LitEnc_GetPriceMatched(const CLzmaProb *probs, UInt32 symbol, UInt32 matchByte, UInt32 *ProbPrices)
++{
++ UInt32 price = 0;
++ UInt32 offs = 0x100;
++ symbol |= 0x100;
++ do
++ {
++ matchByte <<= 1;
++ price += GET_PRICEa(probs[offs + (matchByte & offs) + (symbol >> 8)], (symbol >> 7) & 1);
++ symbol <<= 1;
++ offs &= ~(matchByte ^ symbol);
++ }
++ while (symbol < 0x10000);
++ return price;
++};
++
++
++static void RcTree_Encode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
++{
++ UInt32 m = 1;
++ int i;
++ for (i = numBitLevels; i != 0 ;)
++ {
++ UInt32 bit;
++ i--;
++ bit = (symbol >> i) & 1;
++ RangeEnc_EncodeBit(rc, probs + m, bit);
++ m = (m << 1) | bit;
++ }
++};
++
++static void RcTree_ReverseEncode(CRangeEnc *rc, CLzmaProb *probs, int numBitLevels, UInt32 symbol)
++{
++ UInt32 m = 1;
++ int i;
++ for (i = 0; i < numBitLevels; i++)
++ {
++ UInt32 bit = symbol & 1;
++ RangeEnc_EncodeBit(rc, probs + m, bit);
++ m = (m << 1) | bit;
++ symbol >>= 1;
++ }
++}
++
++static UInt32 RcTree_GetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
++{
++ UInt32 price = 0;
++ symbol |= (1 << numBitLevels);
++ while (symbol != 1)
++ {
++ price += GET_PRICEa(probs[symbol >> 1], symbol & 1);
++ symbol >>= 1;
++ }
++ return price;
++}
++
++static UInt32 RcTree_ReverseGetPrice(const CLzmaProb *probs, int numBitLevels, UInt32 symbol, UInt32 *ProbPrices)
++{
++ UInt32 price = 0;
++ UInt32 m = 1;
++ int i;
++ for (i = numBitLevels; i != 0; i--)
++ {
++ UInt32 bit = symbol & 1;
++ symbol >>= 1;
++ price += GET_PRICEa(probs[m], bit);
++ m = (m << 1) | bit;
++ }
++ return price;
++}
++
++
++static void LenEnc_Init(CLenEnc *p)
++{
++ unsigned i;
++ p->choice = p->choice2 = kProbInitValue;
++ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumLowBits); i++)
++ p->low[i] = kProbInitValue;
++ for (i = 0; i < (LZMA_NUM_PB_STATES_MAX << kLenNumMidBits); i++)
++ p->mid[i] = kProbInitValue;
++ for (i = 0; i < kLenNumHighSymbols; i++)
++ p->high[i] = kProbInitValue;
++}
++
++static void LenEnc_Encode(CLenEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState)
++{
++ if (symbol < kLenNumLowSymbols)
++ {
++ RangeEnc_EncodeBit(rc, &p->choice, 0);
++ RcTree_Encode(rc, p->low + (posState << kLenNumLowBits), kLenNumLowBits, symbol);
++ }
++ else
++ {
++ RangeEnc_EncodeBit(rc, &p->choice, 1);
++ if (symbol < kLenNumLowSymbols + kLenNumMidSymbols)
++ {
++ RangeEnc_EncodeBit(rc, &p->choice2, 0);
++ RcTree_Encode(rc, p->mid + (posState << kLenNumMidBits), kLenNumMidBits, symbol - kLenNumLowSymbols);
++ }
++ else
++ {
++ RangeEnc_EncodeBit(rc, &p->choice2, 1);
++ RcTree_Encode(rc, p->high, kLenNumHighBits, symbol - kLenNumLowSymbols - kLenNumMidSymbols);
++ }
++ }
++}
++
++static void LenEnc_SetPrices(CLenEnc *p, UInt32 posState, UInt32 numSymbols, UInt32 *prices, UInt32 *ProbPrices)
++{
++ UInt32 a0 = GET_PRICE_0a(p->choice);
++ UInt32 a1 = GET_PRICE_1a(p->choice);
++ UInt32 b0 = a1 + GET_PRICE_0a(p->choice2);
++ UInt32 b1 = a1 + GET_PRICE_1a(p->choice2);
++ UInt32 i = 0;
++ for (i = 0; i < kLenNumLowSymbols; i++)
++ {
++ if (i >= numSymbols)
++ return;
++ prices[i] = a0 + RcTree_GetPrice(p->low + (posState << kLenNumLowBits), kLenNumLowBits, i, ProbPrices);
++ }
++ for (; i < kLenNumLowSymbols + kLenNumMidSymbols; i++)
++ {
++ if (i >= numSymbols)
++ return;
++ prices[i] = b0 + RcTree_GetPrice(p->mid + (posState << kLenNumMidBits), kLenNumMidBits, i - kLenNumLowSymbols, ProbPrices);
++ }
++ for (; i < numSymbols; i++)
++ prices[i] = b1 + RcTree_GetPrice(p->high, kLenNumHighBits, i - kLenNumLowSymbols - kLenNumMidSymbols, ProbPrices);
++}
++
++static void MY_FAST_CALL LenPriceEnc_UpdateTable(CLenPriceEnc *p, UInt32 posState, UInt32 *ProbPrices)
++{
++ LenEnc_SetPrices(&p->p, posState, p->tableSize, p->prices[posState], ProbPrices);
++ p->counters[posState] = p->tableSize;
++}
++
++static void LenPriceEnc_UpdateTables(CLenPriceEnc *p, UInt32 numPosStates, UInt32 *ProbPrices)
++{
++ UInt32 posState;
++ for (posState = 0; posState < numPosStates; posState++)
++ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
++}
++
++static void LenEnc_Encode2(CLenPriceEnc *p, CRangeEnc *rc, UInt32 symbol, UInt32 posState, Bool updatePrice, UInt32 *ProbPrices)
++{
++ LenEnc_Encode(&p->p, rc, symbol, posState);
++ if (updatePrice)
++ if (--p->counters[posState] == 0)
++ LenPriceEnc_UpdateTable(p, posState, ProbPrices);
++}
++
++
++
++
++static void MovePos(CLzmaEnc *p, UInt32 num)
++{
++ #ifdef SHOW_STAT
++ ttt += num;
++ printf("\n MovePos %d", num);
++ #endif
++ if (num != 0)
++ {
++ p->additionalOffset += num;
++ p->matchFinder.Skip(p->matchFinderObj, num);
++ }
++}
++
++static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
++{
++ UInt32 lenRes = 0, numDistancePairs;
++ numDistancePairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matchDistances);
++ #ifdef SHOW_STAT
++ printf("\n i = %d numPairs = %d ", ttt, numDistancePairs / 2);
++ if (ttt >= 61994)
++ ttt = ttt;
++
++ ttt++;
++ {
++ UInt32 i;
++ for (i = 0; i < numDistancePairs; i += 2)
++ printf("%2d %6d | ", p->matchDistances[i], p->matchDistances[i + 1]);
++ }
++ #endif
++ if (numDistancePairs > 0)
++ {
++ lenRes = p->matchDistances[numDistancePairs - 2];
++ if (lenRes == p->numFastBytes)
++ {
++ UInt32 numAvail = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) + 1;
++ const Byte *pby = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
++ UInt32 distance = p->matchDistances[numDistancePairs - 1] + 1;
++ if (numAvail > LZMA_MATCH_LEN_MAX)
++ numAvail = LZMA_MATCH_LEN_MAX;
++
++ {
++ const Byte *pby2 = pby - distance;
++ for (; lenRes < numAvail && pby[lenRes] == pby2[lenRes]; lenRes++);
++ }
++ }
++ }
++ p->additionalOffset++;
++ *numDistancePairsRes = numDistancePairs;
++ return lenRes;
++}
++
++
++#define MakeAsChar(p) (p)->backPrev = (UInt32)(-1); (p)->prev1IsChar = False;
++#define MakeAsShortRep(p) (p)->backPrev = 0; (p)->prev1IsChar = False;
++#define IsShortRep(p) ((p)->backPrev == 0)
++
++static UInt32 GetRepLen1Price(CLzmaEnc *p, UInt32 state, UInt32 posState)
++{
++ return
++ GET_PRICE_0(p->isRepG0[state]) +
++ GET_PRICE_0(p->isRep0Long[state][posState]);
++}
++
++static UInt32 GetPureRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 state, UInt32 posState)
++{
++ UInt32 price;
++ if (repIndex == 0)
++ {
++ price = GET_PRICE_0(p->isRepG0[state]);
++ price += GET_PRICE_1(p->isRep0Long[state][posState]);
++ }
++ else
++ {
++ price = GET_PRICE_1(p->isRepG0[state]);
++ if (repIndex == 1)
++ price += GET_PRICE_0(p->isRepG1[state]);
++ else
++ {
++ price += GET_PRICE_1(p->isRepG1[state]);
++ price += GET_PRICE(p->isRepG2[state], repIndex - 2);
++ }
++ }
++ return price;
++}
++
++static UInt32 GetRepPrice(CLzmaEnc *p, UInt32 repIndex, UInt32 len, UInt32 state, UInt32 posState)
++{
++ return p->repLenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN] +
++ GetPureRepPrice(p, repIndex, state, posState);
++}
++
++static UInt32 Backward(CLzmaEnc *p, UInt32 *backRes, UInt32 cur)
++{
++ UInt32 posMem = p->opt[cur].posPrev;
++ UInt32 backMem = p->opt[cur].backPrev;
++ p->optimumEndIndex = cur;
++ do
++ {
++ if (p->opt[cur].prev1IsChar)
++ {
++ MakeAsChar(&p->opt[posMem])
++ p->opt[posMem].posPrev = posMem - 1;
++ if (p->opt[cur].prev2)
++ {
++ p->opt[posMem - 1].prev1IsChar = False;
++ p->opt[posMem - 1].posPrev = p->opt[cur].posPrev2;
++ p->opt[posMem - 1].backPrev = p->opt[cur].backPrev2;
++ }
++ }
++ {
++ UInt32 posPrev = posMem;
++ UInt32 backCur = backMem;
++
++ backMem = p->opt[posPrev].backPrev;
++ posMem = p->opt[posPrev].posPrev;
++
++ p->opt[posPrev].backPrev = backCur;
++ p->opt[posPrev].posPrev = cur;
++ cur = posPrev;
++ }
++ }
++ while (cur != 0);
++ *backRes = p->opt[0].backPrev;
++ p->optimumCurrentIndex = p->opt[0].posPrev;
++ return p->optimumCurrentIndex;
++}
++
++#define LIT_PROBS(pos, prevByte) (p->litProbs + ((((pos) & p->lpMask) << p->lc) + ((prevByte) >> (8 - p->lc))) * 0x300)
++
++static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
++{
++ UInt32 numAvailableBytes, lenMain, numDistancePairs;
++ const Byte *data;
++ UInt32 reps[LZMA_NUM_REPS];
++ UInt32 repLens[LZMA_NUM_REPS];
++ UInt32 repMaxIndex, i;
++ UInt32 *matchDistances;
++ Byte currentByte, matchByte;
++ UInt32 posState;
++ UInt32 matchPrice, repMatchPrice;
++ UInt32 lenEnd;
++ UInt32 len;
++ UInt32 normalMatchPrice;
++ UInt32 cur;
++ if (p->optimumEndIndex != p->optimumCurrentIndex)
++ {
++ const COptimal *opt = &p->opt[p->optimumCurrentIndex];
++ UInt32 lenRes = opt->posPrev - p->optimumCurrentIndex;
++ *backRes = opt->backPrev;
++ p->optimumCurrentIndex = opt->posPrev;
++ return lenRes;
++ }
++ p->optimumCurrentIndex = p->optimumEndIndex = 0;
++
++ numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
++
++ if (!p->longestMatchWasFound)
++ {
++ lenMain = ReadMatchDistances(p, &numDistancePairs);
++ }
++ else
++ {
++ lenMain = p->longestMatchLength;
++ numDistancePairs = p->numDistancePairs;
++ p->longestMatchWasFound = False;
++ }
++
++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
++ if (numAvailableBytes < 2)
++ {
++ *backRes = (UInt32)(-1);
++ return 1;
++ }
++ if (numAvailableBytes > LZMA_MATCH_LEN_MAX)
++ numAvailableBytes = LZMA_MATCH_LEN_MAX;
++
++ repMaxIndex = 0;
++ for (i = 0; i < LZMA_NUM_REPS; i++)
++ {
++ UInt32 lenTest;
++ const Byte *data2;
++ reps[i] = p->reps[i];
++ data2 = data - (reps[i] + 1);
++ if (data[0] != data2[0] || data[1] != data2[1])
++ {
++ repLens[i] = 0;
++ continue;
++ }
++ for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
++ repLens[i] = lenTest;
++ if (lenTest > repLens[repMaxIndex])
++ repMaxIndex = i;
++ }
++ if (repLens[repMaxIndex] >= p->numFastBytes)
++ {
++ UInt32 lenRes;
++ *backRes = repMaxIndex;
++ lenRes = repLens[repMaxIndex];
++ MovePos(p, lenRes - 1);
++ return lenRes;
++ }
++
++ matchDistances = p->matchDistances;
++ if (lenMain >= p->numFastBytes)
++ {
++ *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS;
++ MovePos(p, lenMain - 1);
++ return lenMain;
++ }
++ currentByte = *data;
++ matchByte = *(data - (reps[0] + 1));
++
++ if (lenMain < 2 && currentByte != matchByte && repLens[repMaxIndex] < 2)
++ {
++ *backRes = (UInt32)-1;
++ return 1;
++ }
++
++ p->opt[0].state = (CState)p->state;
++
++ posState = (position & p->pbMask);
++
++ {
++ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
++ p->opt[1].price = GET_PRICE_0(p->isMatch[p->state][posState]) +
++ (!IsCharState(p->state) ?
++ LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) :
++ LitEnc_GetPrice(probs, currentByte, p->ProbPrices));
++ }
++
++ MakeAsChar(&p->opt[1]);
++
++ matchPrice = GET_PRICE_1(p->isMatch[p->state][posState]);
++ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[p->state]);
++
++ if (matchByte == currentByte)
++ {
++ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, p->state, posState);
++ if (shortRepPrice < p->opt[1].price)
++ {
++ p->opt[1].price = shortRepPrice;
++ MakeAsShortRep(&p->opt[1]);
++ }
++ }
++ lenEnd = ((lenMain >= repLens[repMaxIndex]) ? lenMain : repLens[repMaxIndex]);
++
++ if (lenEnd < 2)
++ {
++ *backRes = p->opt[1].backPrev;
++ return 1;
++ }
++
++ p->opt[1].posPrev = 0;
++ for (i = 0; i < LZMA_NUM_REPS; i++)
++ p->opt[0].backs[i] = reps[i];
++
++ len = lenEnd;
++ do
++ p->opt[len--].price = kInfinityPrice;
++ while (len >= 2);
++
++ for (i = 0; i < LZMA_NUM_REPS; i++)
++ {
++ UInt32 repLen = repLens[i];
++ UInt32 price;
++ if (repLen < 2)
++ continue;
++ price = repMatchPrice + GetPureRepPrice(p, i, p->state, posState);
++ do
++ {
++ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][repLen - 2];
++ COptimal *opt = &p->opt[repLen];
++ if (curAndLenPrice < opt->price)
++ {
++ opt->price = curAndLenPrice;
++ opt->posPrev = 0;
++ opt->backPrev = i;
++ opt->prev1IsChar = False;
++ }
++ }
++ while (--repLen >= 2);
++ }
++
++ normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[p->state]);
++
++ len = ((repLens[0] >= 2) ? repLens[0] + 1 : 2);
++ if (len <= lenMain)
++ {
++ UInt32 offs = 0;
++ while (len > matchDistances[offs])
++ offs += 2;
++ for (; ; len++)
++ {
++ COptimal *opt;
++ UInt32 distance = matchDistances[offs + 1];
++
++ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][len - LZMA_MATCH_LEN_MIN];
++ UInt32 lenToPosState = GetLenToPosState(len);
++ if (distance < kNumFullDistances)
++ curAndLenPrice += p->distancesPrices[lenToPosState][distance];
++ else
++ {
++ UInt32 slot;
++ GetPosSlot2(distance, slot);
++ curAndLenPrice += p->alignPrices[distance & kAlignMask] + p->posSlotPrices[lenToPosState][slot];
++ }
++ opt = &p->opt[len];
++ if (curAndLenPrice < opt->price)
++ {
++ opt->price = curAndLenPrice;
++ opt->posPrev = 0;
++ opt->backPrev = distance + LZMA_NUM_REPS;
++ opt->prev1IsChar = False;
++ }
++ if (len == matchDistances[offs])
++ {
++ offs += 2;
++ if (offs == numDistancePairs)
++ break;
++ }
++ }
++ }
++
++ cur = 0;
++
++ #ifdef SHOW_STAT2
++ if (position >= 0)
++ {
++ unsigned i;
++ printf("\n pos = %4X", position);
++ for (i = cur; i <= lenEnd; i++)
++ printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price);
++ }
++ #endif
++
++ for (;;)
++ {
++ UInt32 numAvailableBytesFull, newLen, numDistancePairs;
++ COptimal *curOpt;
++ UInt32 posPrev;
++ UInt32 state;
++ UInt32 curPrice;
++ Bool nextIsChar;
++ const Byte *data;
++ Byte currentByte, matchByte;
++ UInt32 posState;
++ UInt32 curAnd1Price;
++ COptimal *nextOpt;
++ UInt32 matchPrice, repMatchPrice;
++ UInt32 numAvailableBytes;
++ UInt32 startLen;
++
++ cur++;
++ if (cur == lenEnd)
++ return Backward(p, backRes, cur);
++
++ numAvailableBytesFull = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
++ newLen = ReadMatchDistances(p, &numDistancePairs);
++ if (newLen >= p->numFastBytes)
++ {
++ p->numDistancePairs = numDistancePairs;
++ p->longestMatchLength = newLen;
++ p->longestMatchWasFound = True;
++ return Backward(p, backRes, cur);
++ }
++ position++;
++ curOpt = &p->opt[cur];
++ posPrev = curOpt->posPrev;
++ if (curOpt->prev1IsChar)
++ {
++ posPrev--;
++ if (curOpt->prev2)
++ {
++ state = p->opt[curOpt->posPrev2].state;
++ if (curOpt->backPrev2 < LZMA_NUM_REPS)
++ state = kRepNextStates[state];
++ else
++ state = kMatchNextStates[state];
++ }
++ else
++ state = p->opt[posPrev].state;
++ state = kLiteralNextStates[state];
++ }
++ else
++ state = p->opt[posPrev].state;
++ if (posPrev == cur - 1)
++ {
++ if (IsShortRep(curOpt))
++ state = kShortRepNextStates[state];
++ else
++ state = kLiteralNextStates[state];
++ }
++ else
++ {
++ UInt32 pos;
++ const COptimal *prevOpt;
++ if (curOpt->prev1IsChar && curOpt->prev2)
++ {
++ posPrev = curOpt->posPrev2;
++ pos = curOpt->backPrev2;
++ state = kRepNextStates[state];
++ }
++ else
++ {
++ pos = curOpt->backPrev;
++ if (pos < LZMA_NUM_REPS)
++ state = kRepNextStates[state];
++ else
++ state = kMatchNextStates[state];
++ }
++ prevOpt = &p->opt[posPrev];
++ if (pos < LZMA_NUM_REPS)
++ {
++ UInt32 i;
++ reps[0] = prevOpt->backs[pos];
++ for (i = 1; i <= pos; i++)
++ reps[i] = prevOpt->backs[i - 1];
++ for (; i < LZMA_NUM_REPS; i++)
++ reps[i] = prevOpt->backs[i];
++ }
++ else
++ {
++ UInt32 i;
++ reps[0] = (pos - LZMA_NUM_REPS);
++ for (i = 1; i < LZMA_NUM_REPS; i++)
++ reps[i] = prevOpt->backs[i - 1];
++ }
++ }
++ curOpt->state = (CState)state;
++
++ curOpt->backs[0] = reps[0];
++ curOpt->backs[1] = reps[1];
++ curOpt->backs[2] = reps[2];
++ curOpt->backs[3] = reps[3];
++
++ curPrice = curOpt->price;
++ nextIsChar = False;
++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
++ currentByte = *data;
++ matchByte = *(data - (reps[0] + 1));
++
++ posState = (position & p->pbMask);
++
++ curAnd1Price = curPrice + GET_PRICE_0(p->isMatch[state][posState]);
++ {
++ const CLzmaProb *probs = LIT_PROBS(position, *(data - 1));
++ curAnd1Price +=
++ (!IsCharState(state) ?
++ LitEnc_GetPriceMatched(probs, currentByte, matchByte, p->ProbPrices) :
++ LitEnc_GetPrice(probs, currentByte, p->ProbPrices));
++ }
++
++ nextOpt = &p->opt[cur + 1];
++
++ if (curAnd1Price < nextOpt->price)
++ {
++ nextOpt->price = curAnd1Price;
++ nextOpt->posPrev = cur;
++ MakeAsChar(nextOpt);
++ nextIsChar = True;
++ }
++
++ matchPrice = curPrice + GET_PRICE_1(p->isMatch[state][posState]);
++ repMatchPrice = matchPrice + GET_PRICE_1(p->isRep[state]);
++
++ if (matchByte == currentByte && !(nextOpt->posPrev < cur && nextOpt->backPrev == 0))
++ {
++ UInt32 shortRepPrice = repMatchPrice + GetRepLen1Price(p, state, posState);
++ if (shortRepPrice <= nextOpt->price)
++ {
++ nextOpt->price = shortRepPrice;
++ nextOpt->posPrev = cur;
++ MakeAsShortRep(nextOpt);
++ nextIsChar = True;
++ }
++ }
++
++ {
++ UInt32 temp = kNumOpts - 1 - cur;
++ if (temp < numAvailableBytesFull)
++ numAvailableBytesFull = temp;
++ }
++ numAvailableBytes = numAvailableBytesFull;
++
++ if (numAvailableBytes < 2)
++ continue;
++ if (numAvailableBytes > p->numFastBytes)
++ numAvailableBytes = p->numFastBytes;
++ if (!nextIsChar && matchByte != currentByte) /* speed optimization */
++ {
++ /* try Literal + rep0 */
++ UInt32 temp;
++ UInt32 lenTest2;
++ const Byte *data2 = data - (reps[0] + 1);
++ UInt32 limit = p->numFastBytes + 1;
++ if (limit > numAvailableBytesFull)
++ limit = numAvailableBytesFull;
++
++ for (temp = 1; temp < limit && data[temp] == data2[temp]; temp++);
++ lenTest2 = temp - 1;
++ if (lenTest2 >= 2)
++ {
++ UInt32 state2 = kLiteralNextStates[state];
++ UInt32 posStateNext = (position + 1) & p->pbMask;
++ UInt32 nextRepMatchPrice = curAnd1Price +
++ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
++ GET_PRICE_1(p->isRep[state2]);
++ /* for (; lenTest2 >= 2; lenTest2--) */
++ {
++ UInt32 curAndLenPrice;
++ COptimal *opt;
++ UInt32 offset = cur + 1 + lenTest2;
++ while (lenEnd < offset)
++ p->opt[++lenEnd].price = kInfinityPrice;
++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
++ opt = &p->opt[offset];
++ if (curAndLenPrice < opt->price)
++ {
++ opt->price = curAndLenPrice;
++ opt->posPrev = cur + 1;
++ opt->backPrev = 0;
++ opt->prev1IsChar = True;
++ opt->prev2 = False;
++ }
++ }
++ }
++ }
++
++ startLen = 2; /* speed optimization */
++ {
++ UInt32 repIndex;
++ for (repIndex = 0; repIndex < LZMA_NUM_REPS; repIndex++)
++ {
++ UInt32 lenTest;
++ UInt32 lenTestTemp;
++ UInt32 price;
++ const Byte *data2 = data - (reps[repIndex] + 1);
++ if (data[0] != data2[0] || data[1] != data2[1])
++ continue;
++ for (lenTest = 2; lenTest < numAvailableBytes && data[lenTest] == data2[lenTest]; lenTest++);
++ while (lenEnd < cur + lenTest)
++ p->opt[++lenEnd].price = kInfinityPrice;
++ lenTestTemp = lenTest;
++ price = repMatchPrice + GetPureRepPrice(p, repIndex, state, posState);
++ do
++ {
++ UInt32 curAndLenPrice = price + p->repLenEnc.prices[posState][lenTest - 2];
++ COptimal *opt = &p->opt[cur + lenTest];
++ if (curAndLenPrice < opt->price)
++ {
++ opt->price = curAndLenPrice;
++ opt->posPrev = cur;
++ opt->backPrev = repIndex;
++ opt->prev1IsChar = False;
++ }
++ }
++ while (--lenTest >= 2);
++ lenTest = lenTestTemp;
++
++ if (repIndex == 0)
++ startLen = lenTest + 1;
++
++ /* if (_maxMode) */
++ {
++ UInt32 lenTest2 = lenTest + 1;
++ UInt32 limit = lenTest2 + p->numFastBytes;
++ UInt32 nextRepMatchPrice;
++ if (limit > numAvailableBytesFull)
++ limit = numAvailableBytesFull;
++ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
++ lenTest2 -= lenTest + 1;
++ if (lenTest2 >= 2)
++ {
++ UInt32 state2 = kRepNextStates[state];
++ UInt32 posStateNext = (position + lenTest) & p->pbMask;
++ UInt32 curAndLenCharPrice =
++ price + p->repLenEnc.prices[posState][lenTest - 2] +
++ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
++ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
++ data[lenTest], data2[lenTest], p->ProbPrices);
++ state2 = kLiteralNextStates[state2];
++ posStateNext = (position + lenTest + 1) & p->pbMask;
++ nextRepMatchPrice = curAndLenCharPrice +
++ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
++ GET_PRICE_1(p->isRep[state2]);
++
++ /* for (; lenTest2 >= 2; lenTest2--) */
++ {
++ UInt32 curAndLenPrice;
++ COptimal *opt;
++ UInt32 offset = cur + lenTest + 1 + lenTest2;
++ while (lenEnd < offset)
++ p->opt[++lenEnd].price = kInfinityPrice;
++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
++ opt = &p->opt[offset];
++ if (curAndLenPrice < opt->price)
++ {
++ opt->price = curAndLenPrice;
++ opt->posPrev = cur + lenTest + 1;
++ opt->backPrev = 0;
++ opt->prev1IsChar = True;
++ opt->prev2 = True;
++ opt->posPrev2 = cur;
++ opt->backPrev2 = repIndex;
++ }
++ }
++ }
++ }
++ }
++ }
++ /* for (UInt32 lenTest = 2; lenTest <= newLen; lenTest++) */
++ if (newLen > numAvailableBytes)
++ {
++ newLen = numAvailableBytes;
++ for (numDistancePairs = 0; newLen > matchDistances[numDistancePairs]; numDistancePairs += 2);
++ matchDistances[numDistancePairs] = newLen;
++ numDistancePairs += 2;
++ }
++ if (newLen >= startLen)
++ {
++ UInt32 normalMatchPrice = matchPrice + GET_PRICE_0(p->isRep[state]);
++ UInt32 offs, curBack, posSlot;
++ UInt32 lenTest;
++ while (lenEnd < cur + newLen)
++ p->opt[++lenEnd].price = kInfinityPrice;
++
++ offs = 0;
++ while (startLen > matchDistances[offs])
++ offs += 2;
++ curBack = matchDistances[offs + 1];
++ GetPosSlot2(curBack, posSlot);
++ for (lenTest = /*2*/ startLen; ; lenTest++)
++ {
++ UInt32 curAndLenPrice = normalMatchPrice + p->lenEnc.prices[posState][lenTest - LZMA_MATCH_LEN_MIN];
++ UInt32 lenToPosState = GetLenToPosState(lenTest);
++ COptimal *opt;
++ if (curBack < kNumFullDistances)
++ curAndLenPrice += p->distancesPrices[lenToPosState][curBack];
++ else
++ curAndLenPrice += p->posSlotPrices[lenToPosState][posSlot] + p->alignPrices[curBack & kAlignMask];
++
++ opt = &p->opt[cur + lenTest];
++ if (curAndLenPrice < opt->price)
++ {
++ opt->price = curAndLenPrice;
++ opt->posPrev = cur;
++ opt->backPrev = curBack + LZMA_NUM_REPS;
++ opt->prev1IsChar = False;
++ }
++
++ if (/*_maxMode && */lenTest == matchDistances[offs])
++ {
++ /* Try Match + Literal + Rep0 */
++ const Byte *data2 = data - (curBack + 1);
++ UInt32 lenTest2 = lenTest + 1;
++ UInt32 limit = lenTest2 + p->numFastBytes;
++ UInt32 nextRepMatchPrice;
++ if (limit > numAvailableBytesFull)
++ limit = numAvailableBytesFull;
++ for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
++ lenTest2 -= lenTest + 1;
++ if (lenTest2 >= 2)
++ {
++ UInt32 state2 = kMatchNextStates[state];
++ UInt32 posStateNext = (position + lenTest) & p->pbMask;
++ UInt32 curAndLenCharPrice = curAndLenPrice +
++ GET_PRICE_0(p->isMatch[state2][posStateNext]) +
++ LitEnc_GetPriceMatched(LIT_PROBS(position + lenTest, data[lenTest - 1]),
++ data[lenTest], data2[lenTest], p->ProbPrices);
++ state2 = kLiteralNextStates[state2];
++ posStateNext = (posStateNext + 1) & p->pbMask;
++ nextRepMatchPrice = curAndLenCharPrice +
++ GET_PRICE_1(p->isMatch[state2][posStateNext]) +
++ GET_PRICE_1(p->isRep[state2]);
++
++ /* for (; lenTest2 >= 2; lenTest2--) */
++ {
++ UInt32 offset = cur + lenTest + 1 + lenTest2;
++ UInt32 curAndLenPrice;
++ COptimal *opt;
++ while (lenEnd < offset)
++ p->opt[++lenEnd].price = kInfinityPrice;
++ curAndLenPrice = nextRepMatchPrice + GetRepPrice(p, 0, lenTest2, state2, posStateNext);
++ opt = &p->opt[offset];
++ if (curAndLenPrice < opt->price)
++ {
++ opt->price = curAndLenPrice;
++ opt->posPrev = cur + lenTest + 1;
++ opt->backPrev = 0;
++ opt->prev1IsChar = True;
++ opt->prev2 = True;
++ opt->posPrev2 = cur;
++ opt->backPrev2 = curBack + LZMA_NUM_REPS;
++ }
++ }
++ }
++ offs += 2;
++ if (offs == numDistancePairs)
++ break;
++ curBack = matchDistances[offs + 1];
++ if (curBack >= kNumFullDistances)
++ GetPosSlot2(curBack, posSlot);
++ }
++ }
++ }
++ }
++}
++
++#define ChangePair(smallDist, bigDist) (((bigDist) >> 7) > (smallDist))
++
++static UInt32 GetOptimumFast(CLzmaEnc *p, UInt32 *backRes)
++{
++ UInt32 numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
++ UInt32 lenMain, numDistancePairs;
++ const Byte *data;
++ UInt32 repLens[LZMA_NUM_REPS];
++ UInt32 repMaxIndex, i;
++ UInt32 *matchDistances;
++ UInt32 backMain;
++
++ if (!p->longestMatchWasFound)
++ {
++ lenMain = ReadMatchDistances(p, &numDistancePairs);
++ }
++ else
++ {
++ lenMain = p->longestMatchLength;
++ numDistancePairs = p->numDistancePairs;
++ p->longestMatchWasFound = False;
++ }
++
++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
++ if (numAvailableBytes > LZMA_MATCH_LEN_MAX)
++ numAvailableBytes = LZMA_MATCH_LEN_MAX;
++ if (numAvailableBytes < 2)
++ {
++ *backRes = (UInt32)(-1);
++ return 1;
++ }
++
++ repMaxIndex = 0;
++
++ for (i = 0; i < LZMA_NUM_REPS; i++)
++ {
++ const Byte *data2 = data - (p->reps[i] + 1);
++ UInt32 len;
++ if (data[0] != data2[0] || data[1] != data2[1])
++ {
++ repLens[i] = 0;
++ continue;
++ }
++ for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
++ if (len >= p->numFastBytes)
++ {
++ *backRes = i;
++ MovePos(p, len - 1);
++ return len;
++ }
++ repLens[i] = len;
++ if (len > repLens[repMaxIndex])
++ repMaxIndex = i;
++ }
++ matchDistances = p->matchDistances;
++ if (lenMain >= p->numFastBytes)
++ {
++ *backRes = matchDistances[numDistancePairs - 1] + LZMA_NUM_REPS;
++ MovePos(p, lenMain - 1);
++ return lenMain;
++ }
++
++ backMain = 0; /* for GCC */
++ if (lenMain >= 2)
++ {
++ backMain = matchDistances[numDistancePairs - 1];
++ while (numDistancePairs > 2 && lenMain == matchDistances[numDistancePairs - 4] + 1)
++ {
++ if (!ChangePair(matchDistances[numDistancePairs - 3], backMain))
++ break;
++ numDistancePairs -= 2;
++ lenMain = matchDistances[numDistancePairs - 2];
++ backMain = matchDistances[numDistancePairs - 1];
++ }
++ if (lenMain == 2 && backMain >= 0x80)
++ lenMain = 1;
++ }
++
++ if (repLens[repMaxIndex] >= 2)
++ {
++ if (repLens[repMaxIndex] + 1 >= lenMain ||
++ (repLens[repMaxIndex] + 2 >= lenMain && (backMain > (1 << 9))) ||
++ (repLens[repMaxIndex] + 3 >= lenMain && (backMain > (1 << 15))))
++ {
++ UInt32 lenRes;
++ *backRes = repMaxIndex;
++ lenRes = repLens[repMaxIndex];
++ MovePos(p, lenRes - 1);
++ return lenRes;
++ }
++ }
++
++ if (lenMain >= 2 && numAvailableBytes > 2)
++ {
++ UInt32 i;
++ numAvailableBytes = p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
++ p->longestMatchLength = ReadMatchDistances(p, &p->numDistancePairs);
++ if (p->longestMatchLength >= 2)
++ {
++ UInt32 newDistance = matchDistances[p->numDistancePairs - 1];
++ if ((p->longestMatchLength >= lenMain && newDistance < backMain) ||
++ (p->longestMatchLength == lenMain + 1 && !ChangePair(backMain, newDistance)) ||
++ (p->longestMatchLength > lenMain + 1) ||
++ (p->longestMatchLength + 1 >= lenMain && lenMain >= 3 && ChangePair(newDistance, backMain)))
++ {
++ p->longestMatchWasFound = True;
++ *backRes = (UInt32)(-1);
++ return 1;
++ }
++ }
++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - 1;
++ for (i = 0; i < LZMA_NUM_REPS; i++)
++ {
++ UInt32 len;
++ const Byte *data2 = data - (p->reps[i] + 1);
++ if (data[1] != data2[1] || data[2] != data2[2])
++ {
++ repLens[i] = 0;
++ continue;
++ }
++ for (len = 2; len < numAvailableBytes && data[len] == data2[len]; len++);
++ if (len + 1 >= lenMain)
++ {
++ p->longestMatchWasFound = True;
++ *backRes = (UInt32)(-1);
++ return 1;
++ }
++ }
++ *backRes = backMain + LZMA_NUM_REPS;
++ MovePos(p, lenMain - 2);
++ return lenMain;
++ }
++ *backRes = (UInt32)(-1);
++ return 1;
++}
++
++static void WriteEndMarker(CLzmaEnc *p, UInt32 posState)
++{
++ UInt32 len;
++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
++ p->state = kMatchNextStates[p->state];
++ len = LZMA_MATCH_LEN_MIN;
++ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
++ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, (1 << kNumPosSlotBits) - 1);
++ RangeEnc_EncodeDirectBits(&p->rc, (((UInt32)1 << 30) - 1) >> kNumAlignBits, 30 - kNumAlignBits);
++ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, kAlignMask);
++}
++
++static SRes CheckErrors(CLzmaEnc *p)
++{
++ if (p->result != SZ_OK)
++ return p->result;
++ if (p->rc.res != SZ_OK)
++ p->result = SZ_ERROR_WRITE;
++ if (p->matchFinderBase.result != SZ_OK)
++ p->result = SZ_ERROR_READ;
++ if (p->result != SZ_OK)
++ p->finished = True;
++ return p->result;
++}
++
++static SRes Flush(CLzmaEnc *p, UInt32 nowPos)
++{
++ /* ReleaseMFStream(); */
++ p->finished = True;
++ if (p->writeEndMark)
++ WriteEndMarker(p, nowPos & p->pbMask);
++ RangeEnc_FlushData(&p->rc);
++ RangeEnc_FlushStream(&p->rc);
++ return CheckErrors(p);
++}
++
++static void FillAlignPrices(CLzmaEnc *p)
++{
++ UInt32 i;
++ for (i = 0; i < kAlignTableSize; i++)
++ p->alignPrices[i] = RcTree_ReverseGetPrice(p->posAlignEncoder, kNumAlignBits, i, p->ProbPrices);
++ p->alignPriceCount = 0;
++}
++
++static void FillDistancesPrices(CLzmaEnc *p)
++{
++ UInt32 tempPrices[kNumFullDistances];
++ UInt32 i, lenToPosState;
++ for (i = kStartPosModelIndex; i < kNumFullDistances; i++)
++ {
++ UInt32 posSlot = GetPosSlot1(i);
++ UInt32 footerBits = ((posSlot >> 1) - 1);
++ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
++ tempPrices[i] = RcTree_ReverseGetPrice(p->posEncoders + base - posSlot - 1, footerBits, i - base, p->ProbPrices);
++ }
++
++ for (lenToPosState = 0; lenToPosState < kNumLenToPosStates; lenToPosState++)
++ {
++ UInt32 posSlot;
++ const CLzmaProb *encoder = p->posSlotEncoder[lenToPosState];
++ UInt32 *posSlotPrices = p->posSlotPrices[lenToPosState];
++ for (posSlot = 0; posSlot < p->distTableSize; posSlot++)
++ posSlotPrices[posSlot] = RcTree_GetPrice(encoder, kNumPosSlotBits, posSlot, p->ProbPrices);
++ for (posSlot = kEndPosModelIndex; posSlot < p->distTableSize; posSlot++)
++ posSlotPrices[posSlot] += ((((posSlot >> 1) - 1) - kNumAlignBits) << kNumBitPriceShiftBits);
++
++ {
++ UInt32 *distancesPrices = p->distancesPrices[lenToPosState];
++ UInt32 i;
++ for (i = 0; i < kStartPosModelIndex; i++)
++ distancesPrices[i] = posSlotPrices[i];
++ for (; i < kNumFullDistances; i++)
++ distancesPrices[i] = posSlotPrices[GetPosSlot1(i)] + tempPrices[i];
++ }
++ }
++ p->matchPriceCount = 0;
++}
++
++void LzmaEnc_Construct(CLzmaEnc *p)
++{
++ RangeEnc_Construct(&p->rc);
++ MatchFinder_Construct(&p->matchFinderBase);
++ #ifdef COMPRESS_MF_MT
++ MatchFinderMt_Construct(&p->matchFinderMt);
++ p->matchFinderMt.MatchFinder = &p->matchFinderBase;
++ #endif
++
++ {
++ CLzmaEncProps props;
++ LzmaEncProps_Init(&props);
++ LzmaEnc_SetProps(p, &props);
++ }
++
++ #ifndef LZMA_LOG_BSR
++ LzmaEnc_FastPosInit(p->g_FastPos);
++ #endif
++
++ LzmaEnc_InitPriceTables(p->ProbPrices);
++ p->litProbs = 0;
++ p->saveState.litProbs = 0;
++}
++
++CLzmaEncHandle LzmaEnc_Create(ISzAlloc *alloc)
++{
++ void *p;
++ p = alloc->Alloc(alloc, sizeof(CLzmaEnc));
++ if (p != 0)
++ LzmaEnc_Construct((CLzmaEnc *)p);
++ return p;
++}
++
++void LzmaEnc_FreeLits(CLzmaEnc *p, ISzAlloc *alloc)
++{
++ alloc->Free(alloc, p->litProbs);
++ alloc->Free(alloc, p->saveState.litProbs);
++ p->litProbs = 0;
++ p->saveState.litProbs = 0;
++}
++
++void LzmaEnc_Destruct(CLzmaEnc *p, ISzAlloc *alloc, ISzAlloc *allocBig)
++{
++ #ifdef COMPRESS_MF_MT
++ MatchFinderMt_Destruct(&p->matchFinderMt, allocBig);
++ #endif
++ MatchFinder_Free(&p->matchFinderBase, allocBig);
++ LzmaEnc_FreeLits(p, alloc);
++ RangeEnc_Free(&p->rc, alloc);
++}
++
++void LzmaEnc_Destroy(CLzmaEncHandle p, ISzAlloc *alloc, ISzAlloc *allocBig)
++{
++ LzmaEnc_Destruct((CLzmaEnc *)p, alloc, allocBig);
++ alloc->Free(alloc, p);
++}
++
++static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize, UInt32 maxUnpackSize)
++{
++ UInt32 nowPos32, startPos32;
++ if (p->inStream != 0)
++ {
++ p->matchFinderBase.stream = p->inStream;
++ p->matchFinder.Init(p->matchFinderObj);
++ p->inStream = 0;
++ }
++
++ if (p->finished)
++ return p->result;
++ RINOK(CheckErrors(p));
++
++ nowPos32 = (UInt32)p->nowPos64;
++ startPos32 = nowPos32;
++
++ if (p->nowPos64 == 0)
++ {
++ UInt32 numDistancePairs;
++ Byte curByte;
++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
++ return Flush(p, nowPos32);
++ ReadMatchDistances(p, &numDistancePairs);
++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][0], 0);
++ p->state = kLiteralNextStates[p->state];
++ curByte = p->matchFinder.GetIndexByte(p->matchFinderObj, 0 - p->additionalOffset);
++ LitEnc_Encode(&p->rc, p->litProbs, curByte);
++ p->additionalOffset--;
++ nowPos32++;
++ }
++
++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) != 0)
++ for (;;)
++ {
++ UInt32 pos, len, posState;
++
++ if (p->fastMode)
++ len = GetOptimumFast(p, &pos);
++ else
++ len = GetOptimum(p, nowPos32, &pos);
++
++ #ifdef SHOW_STAT2
++ printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos);
++ #endif
++
++ posState = nowPos32 & p->pbMask;
++ if (len == 1 && pos == 0xFFFFFFFF)
++ {
++ Byte curByte;
++ CLzmaProb *probs;
++ const Byte *data;
++
++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 0);
++ data = p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
++ curByte = *data;
++ probs = LIT_PROBS(nowPos32, *(data - 1));
++ if (IsCharState(p->state))
++ LitEnc_Encode(&p->rc, probs, curByte);
++ else
++ LitEnc_EncodeMatched(&p->rc, probs, curByte, *(data - p->reps[0] - 1));
++ p->state = kLiteralNextStates[p->state];
++ }
++ else
++ {
++ RangeEnc_EncodeBit(&p->rc, &p->isMatch[p->state][posState], 1);
++ if (pos < LZMA_NUM_REPS)
++ {
++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 1);
++ if (pos == 0)
++ {
++ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 0);
++ RangeEnc_EncodeBit(&p->rc, &p->isRep0Long[p->state][posState], ((len == 1) ? 0 : 1));
++ }
++ else
++ {
++ UInt32 distance = p->reps[pos];
++ RangeEnc_EncodeBit(&p->rc, &p->isRepG0[p->state], 1);
++ if (pos == 1)
++ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 0);
++ else
++ {
++ RangeEnc_EncodeBit(&p->rc, &p->isRepG1[p->state], 1);
++ RangeEnc_EncodeBit(&p->rc, &p->isRepG2[p->state], pos - 2);
++ if (pos == 3)
++ p->reps[3] = p->reps[2];
++ p->reps[2] = p->reps[1];
++ }
++ p->reps[1] = p->reps[0];
++ p->reps[0] = distance;
++ }
++ if (len == 1)
++ p->state = kShortRepNextStates[p->state];
++ else
++ {
++ LenEnc_Encode2(&p->repLenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
++ p->state = kRepNextStates[p->state];
++ }
++ }
++ else
++ {
++ UInt32 posSlot;
++ RangeEnc_EncodeBit(&p->rc, &p->isRep[p->state], 0);
++ p->state = kMatchNextStates[p->state];
++ LenEnc_Encode2(&p->lenEnc, &p->rc, len - LZMA_MATCH_LEN_MIN, posState, !p->fastMode, p->ProbPrices);
++ pos -= LZMA_NUM_REPS;
++ GetPosSlot(pos, posSlot);
++ RcTree_Encode(&p->rc, p->posSlotEncoder[GetLenToPosState(len)], kNumPosSlotBits, posSlot);
++
++ if (posSlot >= kStartPosModelIndex)
++ {
++ UInt32 footerBits = ((posSlot >> 1) - 1);
++ UInt32 base = ((2 | (posSlot & 1)) << footerBits);
++ UInt32 posReduced = pos - base;
++
++ if (posSlot < kEndPosModelIndex)
++ RcTree_ReverseEncode(&p->rc, p->posEncoders + base - posSlot - 1, footerBits, posReduced);
++ else
++ {
++ RangeEnc_EncodeDirectBits(&p->rc, posReduced >> kNumAlignBits, footerBits - kNumAlignBits);
++ RcTree_ReverseEncode(&p->rc, p->posAlignEncoder, kNumAlignBits, posReduced & kAlignMask);
++ p->alignPriceCount++;
++ }
++ }
++ p->reps[3] = p->reps[2];
++ p->reps[2] = p->reps[1];
++ p->reps[1] = p->reps[0];
++ p->reps[0] = pos;
++ p->matchPriceCount++;
++ }
++ }
++ p->additionalOffset -= len;
++ nowPos32 += len;
++ if (p->additionalOffset == 0)
++ {
++ UInt32 processed;
++ if (!p->fastMode)
++ {
++ if (p->matchPriceCount >= (1 << 7))
++ FillDistancesPrices(p);
++ if (p->alignPriceCount >= kAlignTableSize)
++ FillAlignPrices(p);
++ }
++ if (p->matchFinder.GetNumAvailableBytes(p->matchFinderObj) == 0)
++ break;
++ processed = nowPos32 - startPos32;
++ if (useLimits)
++ {
++ if (processed + kNumOpts + 300 >= maxUnpackSize ||
++ RangeEnc_GetProcessed(&p->rc) + kNumOpts * 2 >= maxPackSize)
++ break;
++ }
++ else if (processed >= (1 << 15))
++ {
++ p->nowPos64 += nowPos32 - startPos32;
++ return CheckErrors(p);
++ }
++ }
++ }
++ p->nowPos64 += nowPos32 - startPos32;
++ return Flush(p, nowPos32);
++}
++
++#define kBigHashDicLimit ((UInt32)1 << 24)
++
++static SRes LzmaEnc_Alloc(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
++{
++ UInt32 beforeSize = kNumOpts;
++ Bool btMode;
++ if (!RangeEnc_Alloc(&p->rc, alloc))
++ return SZ_ERROR_MEM;
++ btMode = (p->matchFinderBase.btMode != 0);
++ #ifdef COMPRESS_MF_MT
++ p->mtMode = (p->multiThread && !p->fastMode && btMode);
++ #endif
++
++ {
++ unsigned lclp = p->lc + p->lp;
++ if (p->litProbs == 0 || p->saveState.litProbs == 0 || p->lclp != lclp)
++ {
++ LzmaEnc_FreeLits(p, alloc);
++ p->litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
++ p->saveState.litProbs = (CLzmaProb *)alloc->Alloc(alloc, (0x300 << lclp) * sizeof(CLzmaProb));
++ if (p->litProbs == 0 || p->saveState.litProbs == 0)
++ {
++ LzmaEnc_FreeLits(p, alloc);
++ return SZ_ERROR_MEM;
++ }
++ p->lclp = lclp;
++ }
++ }
++
++ p->matchFinderBase.bigHash = (p->dictSize > kBigHashDicLimit);
++
++ if (beforeSize + p->dictSize < keepWindowSize)
++ beforeSize = keepWindowSize - p->dictSize;
++
++ #ifdef COMPRESS_MF_MT
++ if (p->mtMode)
++ {
++ RINOK(MatchFinderMt_Create(&p->matchFinderMt, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig));
++ p->matchFinderObj = &p->matchFinderMt;
++ MatchFinderMt_CreateVTable(&p->matchFinderMt, &p->matchFinder);
++ }
++ else
++ #endif
++ {
++ if (!MatchFinder_Create(&p->matchFinderBase, p->dictSize, beforeSize, p->numFastBytes, LZMA_MATCH_LEN_MAX, allocBig))
++ return SZ_ERROR_MEM;
++ p->matchFinderObj = &p->matchFinderBase;
++ MatchFinder_CreateVTable(&p->matchFinderBase, &p->matchFinder);
++ }
++ return SZ_OK;
++}
++
++void LzmaEnc_Init(CLzmaEnc *p)
++{
++ UInt32 i;
++ p->state = 0;
++ for(i = 0 ; i < LZMA_NUM_REPS; i++)
++ p->reps[i] = 0;
++
++ RangeEnc_Init(&p->rc);
++
++
++ for (i = 0; i < kNumStates; i++)
++ {
++ UInt32 j;
++ for (j = 0; j < LZMA_NUM_PB_STATES_MAX; j++)
++ {
++ p->isMatch[i][j] = kProbInitValue;
++ p->isRep0Long[i][j] = kProbInitValue;
++ }
++ p->isRep[i] = kProbInitValue;
++ p->isRepG0[i] = kProbInitValue;
++ p->isRepG1[i] = kProbInitValue;
++ p->isRepG2[i] = kProbInitValue;
++ }
++
++ {
++ UInt32 num = 0x300 << (p->lp + p->lc);
++ for (i = 0; i < num; i++)
++ p->litProbs[i] = kProbInitValue;
++ }
++
++ {
++ for (i = 0; i < kNumLenToPosStates; i++)
++ {
++ CLzmaProb *probs = p->posSlotEncoder[i];
++ UInt32 j;
++ for (j = 0; j < (1 << kNumPosSlotBits); j++)
++ probs[j] = kProbInitValue;
++ }
++ }
++ {
++ for(i = 0; i < kNumFullDistances - kEndPosModelIndex; i++)
++ p->posEncoders[i] = kProbInitValue;
++ }
++
++ LenEnc_Init(&p->lenEnc.p);
++ LenEnc_Init(&p->repLenEnc.p);
++
++ for (i = 0; i < (1 << kNumAlignBits); i++)
++ p->posAlignEncoder[i] = kProbInitValue;
++
++ p->longestMatchWasFound = False;
++ p->optimumEndIndex = 0;
++ p->optimumCurrentIndex = 0;
++ p->additionalOffset = 0;
++
++ p->pbMask = (1 << p->pb) - 1;
++ p->lpMask = (1 << p->lp) - 1;
++}
++
++void LzmaEnc_InitPrices(CLzmaEnc *p)
++{
++ if (!p->fastMode)
++ {
++ FillDistancesPrices(p);
++ FillAlignPrices(p);
++ }
++
++ p->lenEnc.tableSize =
++ p->repLenEnc.tableSize =
++ p->numFastBytes + 1 - LZMA_MATCH_LEN_MIN;
++ LenPriceEnc_UpdateTables(&p->lenEnc, 1 << p->pb, p->ProbPrices);
++ LenPriceEnc_UpdateTables(&p->repLenEnc, 1 << p->pb, p->ProbPrices);
++}
++
++static SRes LzmaEnc_AllocAndInit(CLzmaEnc *p, UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
++{
++ UInt32 i;
++ for (i = 0; i < (UInt32)kDicLogSizeMaxCompress; i++)
++ if (p->dictSize <= ((UInt32)1 << i))
++ break;
++ p->distTableSize = i * 2;
++
++ p->finished = False;
++ p->result = SZ_OK;
++ RINOK(LzmaEnc_Alloc(p, keepWindowSize, alloc, allocBig));
++ LzmaEnc_Init(p);
++ LzmaEnc_InitPrices(p);
++ p->nowPos64 = 0;
++ return SZ_OK;
++}
++
++static SRes LzmaEnc_Prepare(CLzmaEncHandle pp, ISeqInStream *inStream, ISeqOutStream *outStream,
++ ISzAlloc *alloc, ISzAlloc *allocBig)
++{
++ CLzmaEnc *p = (CLzmaEnc *)pp;
++ p->inStream = inStream;
++ p->rc.outStream = outStream;
++ return LzmaEnc_AllocAndInit(p, 0, alloc, allocBig);
++}
++
++SRes LzmaEnc_PrepareForLzma2(CLzmaEncHandle pp,
++ ISeqInStream *inStream, UInt32 keepWindowSize,
++ ISzAlloc *alloc, ISzAlloc *allocBig)
++{
++ CLzmaEnc *p = (CLzmaEnc *)pp;
++ p->inStream = inStream;
++ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
++}
++
++static void LzmaEnc_SetInputBuf(CLzmaEnc *p, const Byte *src, SizeT srcLen)
++{
++ p->seqBufInStream.funcTable.Read = MyRead;
++ p->seqBufInStream.data = src;
++ p->seqBufInStream.rem = srcLen;
++}
++
++SRes LzmaEnc_MemPrepare(CLzmaEncHandle pp, const Byte *src, SizeT srcLen,
++ UInt32 keepWindowSize, ISzAlloc *alloc, ISzAlloc *allocBig)
++{
++ CLzmaEnc *p = (CLzmaEnc *)pp;
++ LzmaEnc_SetInputBuf(p, src, srcLen);
++ p->inStream = &p->seqBufInStream.funcTable;
++ return LzmaEnc_AllocAndInit(p, keepWindowSize, alloc, allocBig);
++}
++
++void LzmaEnc_Finish(CLzmaEncHandle pp)
++{
++ #ifdef COMPRESS_MF_MT
++ CLzmaEnc *p = (CLzmaEnc *)pp;
++ if (p->mtMode)
++ MatchFinderMt_ReleaseStream(&p->matchFinderMt);
++ #endif
++}
++
++typedef struct _CSeqOutStreamBuf
++{
++ ISeqOutStream funcTable;
++ Byte *data;
++ SizeT rem;
++ Bool overflow;
++} CSeqOutStreamBuf;
++
++static size_t MyWrite(void *pp, const void *data, size_t size)
++{
++ CSeqOutStreamBuf *p = (CSeqOutStreamBuf *)pp;
++ if (p->rem < size)
++ {
++ size = p->rem;
++ p->overflow = True;
++ }
++ memcpy(p->data, data, size);
++ p->rem -= size;
++ p->data += size;
++ return size;
++}
++
++
++UInt32 LzmaEnc_GetNumAvailableBytes(CLzmaEncHandle pp)
++{
++ const CLzmaEnc *p = (CLzmaEnc *)pp;
++ return p->matchFinder.GetNumAvailableBytes(p->matchFinderObj);
++}
++
++const Byte *LzmaEnc_GetCurBuf(CLzmaEncHandle pp)
++{
++ const CLzmaEnc *p = (CLzmaEnc *)pp;
++ return p->matchFinder.GetPointerToCurrentPos(p->matchFinderObj) - p->additionalOffset;
++}
++
++SRes LzmaEnc_CodeOneMemBlock(CLzmaEncHandle pp, Bool reInit,
++ Byte *dest, size_t *destLen, UInt32 desiredPackSize, UInt32 *unpackSize)
++{
++ CLzmaEnc *p = (CLzmaEnc *)pp;
++ UInt64 nowPos64;
++ SRes res;
++ CSeqOutStreamBuf outStream;
++
++ outStream.funcTable.Write = MyWrite;
++ outStream.data = dest;
++ outStream.rem = *destLen;
++ outStream.overflow = False;
++
++ p->writeEndMark = False;
++ p->finished = False;
++ p->result = SZ_OK;
++
++ if (reInit)
++ LzmaEnc_Init(p);
++ LzmaEnc_InitPrices(p);
++ nowPos64 = p->nowPos64;
++ RangeEnc_Init(&p->rc);
++ p->rc.outStream = &outStream.funcTable;
++
++ res = LzmaEnc_CodeOneBlock(pp, True, desiredPackSize, *unpackSize);
++
++ *unpackSize = (UInt32)(p->nowPos64 - nowPos64);
++ *destLen -= outStream.rem;
++ if (outStream.overflow)
++ return SZ_ERROR_OUTPUT_EOF;
++
++ return res;
++}
++
++SRes LzmaEnc_Encode(CLzmaEncHandle pp, ISeqOutStream *outStream, ISeqInStream *inStream, ICompressProgress *progress,
++ ISzAlloc *alloc, ISzAlloc *allocBig)
++{
++ CLzmaEnc *p = (CLzmaEnc *)pp;
++ SRes res = SZ_OK;
++
++ #ifdef COMPRESS_MF_MT
++ Byte allocaDummy[0x300];
++ int i = 0;
++ for (i = 0; i < 16; i++)
++ allocaDummy[i] = (Byte)i;
++ #endif
++
++ RINOK(LzmaEnc_Prepare(pp, inStream, outStream, alloc, allocBig));
++
++ for (;;)
++ {
++ res = LzmaEnc_CodeOneBlock(pp, False, 0, 0);
++ if (res != SZ_OK || p->finished != 0)
++ break;
++ if (progress != 0)
++ {
++ res = progress->Progress(progress, p->nowPos64, RangeEnc_GetProcessed(&p->rc));
++ if (res != SZ_OK)
++ {
++ res = SZ_ERROR_PROGRESS;
++ break;
++ }
++ }
++ }
++ LzmaEnc_Finish(pp);
++ return res;
++}
++
++SRes LzmaEnc_WriteProperties(CLzmaEncHandle pp, Byte *props, SizeT *size)
++{
++ CLzmaEnc *p = (CLzmaEnc *)pp;
++ int i;
++ UInt32 dictSize = p->dictSize;
++ if (*size < LZMA_PROPS_SIZE)
++ return SZ_ERROR_PARAM;
++ *size = LZMA_PROPS_SIZE;
++ props[0] = (Byte)((p->pb * 5 + p->lp) * 9 + p->lc);
++
++ for (i = 11; i <= 30; i++)
++ {
++ if (dictSize <= ((UInt32)2 << i))
++ {
++ dictSize = (2 << i);
++ break;
++ }
++ if (dictSize <= ((UInt32)3 << i))
++ {
++ dictSize = (3 << i);
++ break;
++ }
++ }
++
++ for (i = 0; i < 4; i++)
++ props[1 + i] = (Byte)(dictSize >> (8 * i));
++ return SZ_OK;
++}
++
++SRes LzmaEnc_MemEncode(CLzmaEncHandle pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
++ int writeEndMark, ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
++{
++ SRes res;
++ CLzmaEnc *p = (CLzmaEnc *)pp;
++
++ CSeqOutStreamBuf outStream;
++
++ LzmaEnc_SetInputBuf(p, src, srcLen);
++
++ outStream.funcTable.Write = MyWrite;
++ outStream.data = dest;
++ outStream.rem = *destLen;
++ outStream.overflow = False;
++
++ p->writeEndMark = writeEndMark;
++ res = LzmaEnc_Encode(pp, &outStream.funcTable, &p->seqBufInStream.funcTable,
++ progress, alloc, allocBig);
++
++ *destLen -= outStream.rem;
++ if (outStream.overflow)
++ return SZ_ERROR_OUTPUT_EOF;
++ return res;
++}
++
++SRes LzmaEncode(Byte *dest, SizeT *destLen, const Byte *src, SizeT srcLen,
++ const CLzmaEncProps *props, Byte *propsEncoded, SizeT *propsSize, int writeEndMark,
++ ICompressProgress *progress, ISzAlloc *alloc, ISzAlloc *allocBig)
++{
++ CLzmaEnc *p = (CLzmaEnc *)LzmaEnc_Create(alloc);
++ SRes res;
++ if (p == 0)
++ return SZ_ERROR_MEM;
++
++ res = LzmaEnc_SetProps(p, props);
++ if (res == SZ_OK)
++ {
++ res = LzmaEnc_WriteProperties(p, propsEncoded, propsSize);
++ if (res == SZ_OK)
++ res = LzmaEnc_MemEncode(p, dest, destLen, src, srcLen,
++ writeEndMark, progress, alloc, allocBig);
++ }
++
++ LzmaEnc_Destroy(p, alloc, allocBig);
++ return res;
++}
+--- a/mkfs.jffs2.c
++++ b/mkfs.jffs2.c
+@@ -1659,11 +1659,11 @@ int main(int argc, char **argv)
+ }
+ erase_block_size *= units;
+
+- /* If it's less than 8KiB, they're not allowed */
+- if (erase_block_size < 0x2000) {
+- fprintf(stderr, "Erase size 0x%x too small. Increasing to 8KiB minimum\n",
++ /* If it's less than 4KiB, they're not allowed */
++ if (erase_block_size < 0x1000) {
++ fprintf(stderr, "Erase size 0x%x too small. Increasing to 4KiB minimum\n",
+ erase_block_size);
+- erase_block_size = 0x2000;
++ erase_block_size = 0x1000;
+ }
+ break;
+ }
diff --git a/package/utils/ugps/Makefile b/package/utils/ugps/Makefile
new file mode 100644
index 0000000..e30578f
--- /dev/null
+++ b/package/utils/ugps/Makefile
@@ -0,0 +1,50 @@
+#
+# Copyright (C) 2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=ugps
+PKG_VERSION:=2015-08-17
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_URL:=git://git.openwrt.org/project/ugps.git
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_VERSION:=971e6703eb9bed936cc62cd335105bd2acca14ef
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.bz2
+
+PKG_MAINTAINER:=John Crispin <blogic@openwrt.org>
+PKG_LICENSE:=GPL-2.0+
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Package/ugps
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=OpenWrt GPS Daemon
+ DEPENDS:=+libubox +libubus
+endef
+
+TARGET_CFLAGS += -I$(STAGING_DIR)/usr/include
+
+ifneq ($(CONFIG_USE_GLIBC),)
+ TARGET_CFLAGS += -D_DEFAULT_SOURCE
+endif
+
+define Package/ugps/conffiles
+/etc/config/gps
+endef
+
+define Package/ugps/install
+ $(INSTALL_DIR) $(1)/usr/sbin $(1)/etc/init.d $(1)/etc/config
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/ugps $(1)/usr/sbin/
+ $(INSTALL_BIN) ./files/ugps.init $(1)/etc/init.d/ugps
+ $(INSTALL_CONF) ./files/gps.config $(1)/etc/config/gps
+endef
+
+$(eval $(call BuildPackage,ugps))
diff --git a/package/utils/ugps/files/gps.config b/package/utils/ugps/files/gps.config
new file mode 100644
index 0000000..d997a59
--- /dev/null
+++ b/package/utils/ugps/files/gps.config
@@ -0,0 +1,2 @@
+config gps
+ option 'tty' 'ttyACM0'
diff --git a/package/utils/ugps/files/ugps.init b/package/utils/ugps/files/ugps.init
new file mode 100644
index 0000000..621d017
--- /dev/null
+++ b/package/utils/ugps/files/ugps.init
@@ -0,0 +1,22 @@
+#!/bin/sh /etc/rc.common
+# Copyright (c) 2014 OpenWrt.org
+
+START=80
+
+USE_PROCD=1
+PROG=/usr/sbin/ugps
+
+service_triggers() {
+ procd_add_reload_trigger gps
+}
+
+start_service() {
+ local tty="$(uci get gps.@gps[-1].tty)"
+
+ [ -d "/sys/class/tty/$tty/" ] || return
+
+ procd_open_instance
+ procd_set_param command "$PROG" "/dev/$tty"
+ procd_set_param respawn
+ procd_close_instance
+}
diff --git a/package/utils/usbmode/Makefile b/package/utils/usbmode/Makefile
new file mode 100644
index 0000000..8319d3e
--- /dev/null
+++ b/package/utils/usbmode/Makefile
@@ -0,0 +1,59 @@
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=usbmode
+PKG_VERSION:=2014-08-26
+PKG_RELEASE=$(PKG_SOURCE_VERSION)
+
+PKG_SOURCE_PROTO:=git
+PKG_SOURCE_URL:=http://git.openwrt.org/project/usbmode.git
+PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
+PKG_SOURCE_VERSION:=993a9a542791953c4804f7ddbb3a07756738e37a
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz
+CMAKE_INSTALL:=1
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=
+
+PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>
+
+PKG_DATA_VERSION:=20150115
+PKG_DATA_URL:=http://www.draisberghof.de/usb_modeswitch
+PKG_DATA_PATH:=usb-modeswitch-data-$(PKG_DATA_VERSION)
+PKG_DATA_FILENAME:=$(PKG_DATA_PATH).tar.bz2
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/cmake.mk
+
+define Download/data
+ FILE:=$(PKG_DATA_FILENAME)
+ URL:=$(PKG_DATA_URL)
+ MD5SUM:=662bcd56a97e560ea974bc710822de51
+endef
+$(eval $(call Download,data))
+
+define Package/usb-modeswitch
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=+libubox +libblobmsg-json +libusb-1.0
+ TITLE:=USB mode switching utility
+endef
+
+define Build/Prepare
+ $(Build/Prepare/Default)
+ tar xvfj $(DL_DIR)/$(PKG_DATA_FILENAME) -C $(PKG_BUILD_DIR)
+ rm -f \
+ $(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/05c6:1000:sVe=GT
+ cp ./data/* $(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/
+endef
+
+define Package/usb-modeswitch/install
+ $(INSTALL_DIR) $(1)/etc/hotplug.d/usb $(1)/etc/init.d $(1)/sbin
+ perl $(PKG_BUILD_DIR)/convert-modeswitch.pl \
+ $(PKG_BUILD_DIR)/$(PKG_DATA_PATH)/usb_modeswitch.d/* \
+ > $(1)/etc/usb-mode.json
+ $(INSTALL_DATA) ./files/usbmode.hotplug $(1)/etc/hotplug.d/usb/20-usb_mode
+ $(INSTALL_BIN) ./files/usbmode.init $(1)/etc/init.d/usbmode
+ $(CP) $(PKG_INSTALL_DIR)/usr/sbin/usbmode $(1)/sbin/
+endef
+
+$(eval $(call BuildPackage,usb-modeswitch))
diff --git a/package/utils/usbmode/data/12d1:1f16 b/package/utils/usbmode/data/12d1:1f16
new file mode 100644
index 0000000..beda01f
--- /dev/null
+++ b/package/utils/usbmode/data/12d1:1f16
@@ -0,0 +1,2 @@
+# Vodafone K5150
+MBIM=1
diff --git a/package/utils/usbmode/files/usbmode.hotplug b/package/utils/usbmode/files/usbmode.hotplug
new file mode 100644
index 0000000..b238894
--- /dev/null
+++ b/package/utils/usbmode/files/usbmode.hotplug
@@ -0,0 +1 @@
+/etc/init.d/usbmode start
diff --git a/package/utils/usbmode/files/usbmode.init b/package/utils/usbmode/files/usbmode.init
new file mode 100755
index 0000000..43e8ec5
--- /dev/null
+++ b/package/utils/usbmode/files/usbmode.init
@@ -0,0 +1,12 @@
+#!/bin/sh /etc/rc.common
+# Copyright (C) 2013 OpenWrt.org
+
+START=20
+USE_PROCD=1
+
+start_service()
+{
+ procd_open_instance
+ procd_set_param command "/sbin/usbmode" -s
+ procd_close_instance
+}
diff --git a/package/utils/usbreset/Makefile b/package/utils/usbreset/Makefile
new file mode 100644
index 0000000..d8efa54
--- /dev/null
+++ b/package/utils/usbreset/Makefile
@@ -0,0 +1,44 @@
+#
+# Copyright (C) 2011-2014 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=usbreset
+PKG_RELEASE:=4
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/usbreset
+ SECTION:=utils
+ CATEGORY:=Utilities
+ TITLE:=Utility to send a USB port reset to a USB device
+ MAINTAINER:=Jo-Philipp Wich <xm@subsignal.org>
+endef
+
+define Package/usbreset/description
+ This package contains the small usbreset utility which
+ can be used to send a USB port reset to a USB device -
+ useful for debugging or to force re-detection of particular
+ devices.
+endef
+
+define Build/Prepare
+ $(INSTALL_DIR) $(PKG_BUILD_DIR)
+ $(INSTALL_DATA) ./src/usbreset.c $(PKG_BUILD_DIR)/
+endef
+
+define Build/Compile
+ $(TARGET_CC) $(TARGET_CFLAGS) -Wall \
+ -o $(PKG_BUILD_DIR)/usbreset $(PKG_BUILD_DIR)/usbreset.c
+endef
+
+define Package/usbreset/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/usbreset $(1)/usr/bin/
+endef
+
+$(eval $(call BuildPackage,usbreset))
diff --git a/package/utils/usbreset/src/usbreset.c b/package/utils/usbreset/src/usbreset.c
new file mode 100644
index 0000000..ead30b1
--- /dev/null
+++ b/package/utils/usbreset/src/usbreset.c
@@ -0,0 +1,235 @@
+/* usbreset -- send a USB port reset to a USB device */
+
+/*
+
+http://marc.info/?l=linux-usb-users&m=116827193506484&w=2
+
+and needs mounted usbfs filesystem
+
+ sudo mount -t usbfs none /proc/bus/usb
+
+There is a way to suspend a USB device. In order to use it,
+you must have a kernel with CONFIG_PM_SYSFS_DEPRECATED turned on. To
+suspend a device, do (as root):
+
+ echo -n 2 >/sys/bus/usb/devices/.../power/state
+
+where the "..." is the ID for your device. To unsuspend, do the same
+thing but with a "0" instead of the "2" above.
+
+Note that this mechanism is slated to be removed from the kernel within
+the next year. Hopefully some other mechanism will take its place.
+
+> To reset a
+> device?
+
+Here's a program to do it. You invoke it as either
+
+ usbreset /proc/bus/usb/BBB/DDD
+or
+ usbreset /dev/usbB.D
+
+depending on how your system is set up, where BBB and DDD are the bus and
+device address numbers.
+
+Alan Stern
+
+*/
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <dirent.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+
+#include <linux/usbdevice_fs.h>
+
+
+static char *usbfs = NULL;
+
+struct usbentry {
+ int bus_num;
+ int dev_num;
+ int vendor_id;
+ int product_id;
+ char vendor_name[128];
+ char product_name[128];
+};
+
+
+static char *sysfs_attr(const char *dev, const char *attr)
+{
+ int fd, len = 0;
+ char path[PATH_MAX];
+ static char buf[129];
+
+ memset(buf, 0, sizeof(buf));
+ snprintf(path, sizeof(path) - 1, "/sys/bus/usb/devices/%s/%s", dev, attr);
+
+ if ((fd = open(path, O_RDONLY)) >= 0)
+ {
+ len = read(fd, buf, sizeof(buf) - 1);
+ close(fd);
+ }
+
+ while (--len > 0 && isspace(buf[len]))
+ buf[len] = 0;
+
+ return (len >= 0) ? buf : NULL;
+}
+
+static struct usbentry * parse_devlist(DIR *d)
+{
+ char *attr;
+ struct dirent *e;
+ static struct usbentry dev;
+
+ do {
+ e = readdir(d);
+
+ if (!e)
+ return NULL;
+ }
+ while(!isdigit(e->d_name[0]) || strchr(e->d_name, ':'));
+
+ memset(&dev, 0, sizeof(dev));
+
+ if ((attr = sysfs_attr(e->d_name, "busnum")) != NULL)
+ dev.bus_num = strtoul(attr, NULL, 10);
+
+ if ((attr = sysfs_attr(e->d_name, "devnum")) != NULL)
+ dev.dev_num = strtoul(attr, NULL, 10);
+
+ if ((attr = sysfs_attr(e->d_name, "idVendor")) != NULL)
+ dev.vendor_id = strtoul(attr, NULL, 16);
+
+ if ((attr = sysfs_attr(e->d_name, "idProduct")) != NULL)
+ dev.product_id = strtoul(attr, NULL, 16);
+
+ if ((attr = sysfs_attr(e->d_name, "manufacturer")) != NULL)
+ strcpy(dev.vendor_name, attr);
+
+ if ((attr = sysfs_attr(e->d_name, "product")) != NULL)
+ strcpy(dev.product_name, attr);
+
+ if (dev.bus_num && dev.dev_num && dev.vendor_id && dev.product_id)
+ return &dev;
+
+ return NULL;
+}
+
+static void list_devices(void)
+{
+ DIR *devs = opendir("/sys/bus/usb/devices");
+ struct usbentry *dev;
+
+ if (!devs)
+ return;
+
+ while ((dev = parse_devlist(devs)) != NULL)
+ {
+ printf(" Number %03d/%03d ID %04x:%04x %s\n",
+ dev->bus_num, dev->dev_num,
+ dev->vendor_id, dev->product_id,
+ dev->product_name);
+ }
+
+ closedir(devs);
+}
+
+struct usbentry * find_device(int *bus, int *dev,
+ int *vid, int *pid,
+ const char *product)
+{
+ DIR *devs = opendir("/sys/bus/usb/devices");
+
+ struct usbentry *e, *match = NULL;
+
+ if (!devs)
+ return NULL;
+
+ while ((e = parse_devlist(devs)) != NULL)
+ {
+ if ((bus && (e->bus_num == *bus) && (e->dev_num == *dev)) ||
+ (vid && (e->vendor_id == *vid) && (e->product_id == *pid)) ||
+ (product && !strcasecmp(e->product_name, product)))
+ {
+ match = e;
+ break;
+ }
+ }
+
+ closedir(devs);
+
+ return match;
+}
+
+static void reset_device(struct usbentry *dev)
+{
+ int fd;
+ char path[PATH_MAX];
+
+ snprintf(path, sizeof(path) - 1, "/dev/bus/usb/%03d/%03d",
+ dev->bus_num, dev->dev_num);
+
+ printf("Resetting %s ... ", dev->product_name);
+
+ if ((fd = open(path, O_WRONLY)) > -1)
+ {
+ if (ioctl(fd, USBDEVFS_RESET, 0) < 0)
+ printf("failed [%s]\n", strerror(errno));
+ else
+ printf("ok\n");
+
+ close(fd);
+ }
+ else
+ {
+ printf("can't open [%s]\n", strerror(errno));
+ }
+}
+
+
+int main(int argc, char **argv)
+{
+ int id1, id2;
+ struct usbentry *dev;
+
+ if ((argc == 2) && (sscanf(argv[1], "%3d/%3d", &id1, &id2) == 2))
+ {
+ dev = find_device(&id1, &id2, NULL, NULL, NULL);
+ }
+ else if ((argc == 2) && (sscanf(argv[1], "%4x:%4x", &id1, &id2) == 2))
+ {
+ dev = find_device(NULL, NULL, &id1, &id2, NULL);
+ }
+ else if ((argc == 2) && strlen(argv[1]) < 128)
+ {
+ dev = find_device(NULL, NULL, NULL, NULL, argv[1]);
+ }
+ else
+ {
+ printf("Usage:\n"
+ " usbreset PPPP:VVVV - reset by product and vendor id\n"
+ " usbreset BBB/DDD - reset by bus and device number\n"
+ " usbreset \"Product\" - reset by product name\n\n"
+ "Devices:\n");
+ list_devices();
+ return 1;
+ }
+
+ if (!dev)
+ {
+ fprintf(stderr, "No such device found\n");
+ return 1;
+ }
+
+ reset_device(dev);
+ return 0;
+}
diff --git a/package/utils/usbutils/Makefile b/package/utils/usbutils/Makefile
new file mode 100644
index 0000000..b1c058b
--- /dev/null
+++ b/package/utils/usbutils/Makefile
@@ -0,0 +1,57 @@
+#
+# Copyright (C) 2007-2013 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=usbutils
+PKG_VERSION:=007
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.bz2
+PKG_SOURCE_URL:=@KERNEL/linux/utils/usb/usbutils
+PKG_MD5SUM:=a6bd63d5c44cebb717a960eae22a3ca9
+
+USB_IDS_VERSION:=2013-01-16
+USB_IDS_MD5SUM:=2a2344907b6344f0935c86efaf9de620
+USB_IDS_FILE:=usb.ids.$(USB_IDS_VERSION).gz
+
+PKG_BUILD_PARALLEL:=1
+PKG_INSTALL:=1
+
+PKG_MAINTAINER := Felix Fietkau <nbd@openwrt.org>
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/usbutils
+ SECTION:=utils
+ CATEGORY:=Utilities
+ DEPENDS:=+libusb-1.0 +zlib +librt +libpthread
+ TITLE:=USB devices listing utilities
+ URL:=http://www.linux-usb.org/
+endef
+
+define Download/usb_ids
+ FILE:=$(USB_IDS_FILE)
+ URL:=http://mirror2.openwrt.org/sources
+ MD5SUM:=$(USB_IDS_MD5SUM)
+endef
+$(eval $(call Download,usb_ids))
+
+define Build/Prepare
+ $(Build/Prepare/Default)
+ echo '#!/bin/sh' > $(PKG_BUILD_DIR)/update-usbids.sh.in
+ echo 'cp $(DL_DIR)/$(USB_IDS_FILE) usb.ids.gz' >> $(PKG_BUILD_DIR)/update-usbids.sh.in
+endef
+
+define Package/usbutils/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/lsusb $(1)/usr/bin/
+ $(INSTALL_DIR) $(1)/usr/share
+ $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/usb.ids.gz $(1)/usr/share/
+endef
+
+$(eval $(call BuildPackage,usbutils))
diff --git a/package/utils/util-linux/Makefile b/package/utils/util-linux/Makefile
new file mode 100644
index 0000000..f037e6a
--- /dev/null
+++ b/package/utils/util-linux/Makefile
@@ -0,0 +1,644 @@
+#
+# Copyright (C) 2007-2015 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=util-linux
+PKG_VERSION:=2.25.2
+PKG_RELEASE:=4
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
+PKG_SOURCE_URL:=@KERNEL/linux/utils/$(PKG_NAME)/v2.25
+PKG_MD5SUM:=cab3d7be354000f629bc601238b629b3
+
+PKG_LICENSE:=GPL-2.0
+PKG_LICENSE_FILES:=COPYING getopt/COPYING libblkid/COPYING libmount/COPYING Documentation/licenses/COPYING.GPLv2 Documentation/licenses/COPYING.LGPLv2.1 libuuid/COPYING Documentation/licenses/COPYING.BSD-3
+
+PKG_BUILD_PARALLEL:=1
+
+PKG_CONFIG_DEPENDS:= \
+ CONFIG_PACKAGE_cal \
+ CONFIG_PACKAGE_cfdisk \
+ CONFIG_PACKAGE_setterm
+
+PKG_FIXUP:=autoreconf
+
+include $(INCLUDE_DIR)/package.mk
+
+define Package/util-linux/Default
+ SECTION:=utils
+ CATEGORY:=Utilities
+ URL:=http://www.kernel.org/pub/linux/utils/util-linux/
+endef
+
+CONFIGURE_ARGS += \
+ --disable-rpath \
+ --enable-new-mount \
+ --disable-tls \
+ --disable-sulogin \
+ --without-python \
+ --without-udev \
+ $(if $(CONFIG_PACKAGE_cal)$(CONFIG_PACKAGE_cfdisk)$(CONFIG_PACKAGE_setterm),--with-ncurses,--without-ncurses)
+
+TARGET_CFLAGS += $(FPIC) -std=gnu99
+
+define Build/InstallDev
+ $(MAKE) -C $(PKG_BUILD_DIR) \
+ BUILDCC="$(HOSTCC)" \
+ DESTDIR="$(1)" \
+ installdirs install-data
+
+ $(INSTALL_DIR) $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_BUILD_DIR)/libblkid/blkid.pc $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_BUILD_DIR)/libmount/mount.pc $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_BUILD_DIR)/libsmartcols/smartcols.pc $(1)/usr/lib/pkgconfig
+ $(CP) $(PKG_BUILD_DIR)/libuuid/uuid.pc $(1)/usr/lib/pkgconfig
+
+ $(INSTALL_DIR) $(1)/usr/include/blkid
+ $(CP) $(PKG_BUILD_DIR)/libblkid/src/blkid.h $(1)/usr/include/blkid
+ $(INSTALL_DIR) $(1)/usr/include/libmount
+ $(CP) $(PKG_BUILD_DIR)/libmount/src/libmount.h $(1)/usr/include/libmount
+ $(INSTALL_DIR) $(1)/usr/include/uuid
+ $(CP) $(PKG_BUILD_DIR)/libuuid/src/uuid.h $(1)/usr/include/uuid
+ $(INSTALL_DIR) $(1)/usr/include/smartcols
+ $(CP) $(PKG_BUILD_DIR)/libsmartcols/src/libsmartcols.h $(1)/usr/include/smartcols
+
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/.libs/libblkid.{a,so*} $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/.libs/libmount.{a,so*} $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/.libs/libuuid.{a,so*} $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/.libs/libsmartcols.{a,so*} $(1)/usr/lib
+endef
+
+define Package/libblkid
+$(call Package/util-linux/Default)
+ DEPENDS:=+libuuid
+ TITLE:=block device id library
+ SECTION:=libs
+ CATEGORY:=Libraries
+endef
+
+define Package/libblkid/description
+ The libblkid library is used to identify block devices (disks) as to their
+ content (e.g. filesystem type, partitions) as well as extracting additional
+ information such as filesystem labels/volume names, partitions, unique
+ identifiers/serial numbers...
+endef
+
+define Package/libmount
+$(call Package/util-linux/Default)
+ DEPENDS:=+libblkid
+ TITLE:=mount library
+ SECTION:=libs
+ CATEGORY:=Libraries
+endef
+
+define Package/libmount/description
+ The libmount library is used to parse /etc/fstab, /etc/mtab and
+ /proc/self/mountinfo files, manage the mtab file, evaluate mount options...
+endef
+
+define Package/libuuid
+$(call Package/util-linux/Default)
+ TITLE:=DCE compatible Universally Unique Identifier library
+ SECTION:=libs
+ CATEGORY:=Libraries
+endef
+
+define Package/libuuid/description
+ The UUID library is used to generate unique identifiers for objects
+ that may be accessible beyond the local system. This library
+ generates UUIDs compatible with those created by the Open Software
+ Foundation (OSF) Distributed Computing Environment (DCE) utility.
+endef
+
+define Package/libsmartcols
+$(call Package/util-linux/Default)
+ TITLE:=table or tree library
+ SECTION:=libs
+ CATEGORY:=Libraries
+endef
+
+define Package/libsmartcols/description
+ The smartcols library is used to print tables and trees in a pretty way.
+endef
+
+define Package/agetty
+$(call Package/util-linux/Default)
+ TITLE:=alternative Linux getty
+ SUBMENU=Terminal
+endef
+
+define Package/agetty/description
+ agetty opens a tty port, prompts for a login name and invokes the
+ /bin/login command
+endef
+
+define Package/blkid
+$(call Package/util-linux/Default)
+ TITLE:=locate/print block device attributes
+ DEPENDS:= +libblkid +libuuid
+ SUBMENU=disc
+endef
+
+define Package/blkid/description
+ The blkid program is the command-line interface to working with the libblkid
+ library.
+endef
+
+define Package/cal
+$(call Package/util-linux/Default)
+ TITLE:=display a calendar
+ DEPENDS:= +libncurses
+endef
+
+define Package/cal/description
+ cal displays a simple calendar
+endef
+
+define Package/cfdisk
+$(call Package/util-linux/Default)
+ TITLE:=display or manipulate disk partition table
+ DEPENDS:= +libblkid +libncurses +libsmartcols
+ SUBMENU:=disc
+endef
+
+define Package/cfdisk/description
+ cfdisk is a curses-based program for partitioning any hard disk drive
+endef
+
+define Package/dmesg
+$(call Package/util-linux/Default)
+ TITLE:=print or control the kernel ring buffer
+ DEPENDS:= +librt
+endef
+
+define Package/dmesg/description
+ dmesg is used to examine or control the kernel ring buffer
+endef
+
+define Package/fdisk
+$(call Package/util-linux/Default)
+ TITLE:=manipulate disk partition table
+ DEPENDS:= +libblkid +libsmartcols
+ SUBMENU=disc
+endef
+
+define Package/fdisk/description
+ a menu-driven program for creation and manipulation of partition tables
+endef
+
+define Package/findfs
+$(call Package/util-linux/Default)
+ TITLE:=find a filesystem by label or UUID
+ DEPENDS:= +libblkid
+ SUBMENU=disc
+endef
+
+define Package/findfs/description
+ findfs will search the disks in the system looking for a filesystem which has
+ a label matching label or a UUID equal to uuid
+endef
+
+define Package/flock
+$(call Package/util-linux/Default)
+ TITLE:=manage locks from shell scripts
+endef
+
+define Package/flock/description
+ manages flock locks from within shell scripts or the command line
+endef
+
+define Package/getopt
+$(call Package/util-linux/Default)
+ TITLE:=parse command options (enhanced)
+endef
+
+define Package/getopt/description
+ getopt is used to break up (parse) options in command lines for easy parsing
+ by shell procedures, and to check for legal options
+endef
+
+define Package/hwclock
+$(call Package/util-linux/Default)
+ TITLE:=query or set the hardware clock
+endef
+
+define Package/hwclock/description
+ hwclock is a tool for accessing the Hardware Clock
+endef
+
+define Package/logger
+$(call Package/util-linux/Default)
+ TITLE:=a shell command interface to the syslog system log module
+endef
+
+define Package/logger/description
+ logger makes entries in the system log, it provides a shell command interface
+ to the syslog system log module
+endef
+
+define Package/look
+$(call Package/util-linux/Default)
+ TITLE:=display lines beginning with a given string
+endef
+
+define Package/look/description
+ look utility displays any lines in file which contain string
+endef
+
+define Package/losetup
+$(call Package/util-linux/Default)
+ TITLE:=set up and control loop devices
+ DEPENDS:= +libsmartcols
+endef
+
+define Package/losetup/description
+ losetup is used to associate loop devices with regular files or block devices,
+ to detach loop devices and to query the status of a loop device
+endef
+
+define Package/lsblk
+$(call Package/util-linux/Default)
+ TITLE:=list block devices
+ DEPENDS:= +libblkid +libmount +libsmartcols
+ SUBMENU=disc
+endef
+
+define Package/lsblk/description
+ lsblk lists information about all or the specified block devices
+endef
+
+define Package/mcookie
+$(call Package/util-linux/Default)
+ TITLE:=generate magic cookies for xauth
+endef
+
+define Package/mcookie/description
+ mcookie generates a 128-bit random hexadecimal number for use with the X
+ authority system
+endef
+
+define Package/mount-utils
+$(call Package/util-linux/Default)
+ TITLE:=related (u)mount utilities
+ DEPENDS+= +libmount +libsmartcols
+endef
+
+define Package/mount-utils/description
+ contains: mount, umount, findmnt
+endef
+
+define Package/namei
+$(call Package/util-linux/Default)
+ TITLE:=follow a pathname until a terminal point is found
+endef
+
+define Package/namei/description
+ namei uses its arguments as pathnames to any type of Unix file (symlinks,
+ files, directories, and so forth)
+endef
+
+define Package/prlimit
+$(call Package/util-linux/Default)
+ TITLE:=get and set process resource limits
+ DEPENDS:= +libsmartcols
+endef
+
+define Package/prlimit/description
+ Given a process id and one or more resources, prlimit tries to retrieve
+ and/or modify the limits.
+endef
+
+define Package/rename
+$(call Package/util-linux/Default)
+ TITLE:=rename files
+endef
+
+define Package/rename/description
+ rename will rename the specified files by replacing the first occurrence of
+ expression in their name by replacement
+endef
+
+define Package/partx-utils
+$(call Package/util-linux/Default)
+ TITLE:=inform kernel about the presence and numbering of on-disk partitions
+ DEPENDS:= +libblkid +libsmartcols
+ SUBMENU=disc
+endef
+
+define Package/partx-utils/description
+ contains partx, addpart, delpart
+endef
+
+define Package/script-utils
+$(call Package/util-linux/Default)
+ TITLE:=make and replay typescript of terminal session
+ SUBMENU=Terminal
+endef
+
+define Package/script-utils/description
+ contains: script, scriptreplay
+endef
+
+define Package/setterm
+$(call Package/util-linux/Default)
+ TITLE:=set terminal attributes
+ DEPENDS:= +libncurses
+ SUBMENU:=Terminal
+endef
+
+define Package/setterm/description
+ setterm writes to standard output a character string that will invoke the
+ specified terminal capabilities
+endef
+
+define Package/sfdisk
+$(call Package/util-linux/Default)
+ TITLE:=partition table manipulator for Linux
+ SUBMENU=disc
+endef
+
+define Package/sfdisk/description
+ list the size of a partition, list the partitions on a device, check the
+ partitions on a device and repartition a device
+endef
+
+define Package/swap-utils
+$(call Package/util-linux/Default)
+ TITLE:=swap space management utilities
+ DEPENDS+= +libblkid
+ SUBMENU:=disc
+endef
+
+define Package/swap-utils/description
+ contains: mkswap, swaplabel
+endef
+
+define Package/uuidd
+$(call Package/util-linux/Default)
+ TITLE:=UUID generation daemon
+ DEPENDS:= +libuuid
+endef
+
+define Package/uuidd/description
+ The uuidd daemon is used by the UUID library to generate universally unique
+ identifiers (UUIDs), especially time-based UUIDs, in a secure and
+ guaranteed-unique fashion, even in the face of large numbers of threads
+ running on different CPUs trying to grab UUIDs.
+endef
+
+define Package/uuidgen
+$(call Package/util-linux/Default)
+ TITLE:=create a new UUID value
+ DEPENDS:= +libuuid
+endef
+
+define Package/uuidgen/description
+ The uuidgen program creates (and prints) a new universally unique identifier
+ (UUID) using the libuuid library. The new UUID can reasonably be considered
+ unique among all UUIDs created on the local system, and among UUIDs created on
+ other systems in the past and in the future.
+endef
+
+define Package/wall
+$(call Package/util-linux/Default)
+ TITLE:=send a message to everybody's terminal
+ SUBMENU=Terminal
+endef
+
+define Package/wall/description
+ wall sends a message to everybody logged in with their mesg permission
+ set to yes
+endef
+
+define Package/whereis
+$(call Package/util-linux/Default)
+ TITLE:=locate the binary, source, and manual page files for a command
+endef
+
+define Package/whereis/description
+ whereis locates source/binary and manuals sections for specified files
+endef
+
+define Package/wipefs
+$(call Package/util-linux/Default)
+ TITLE:=wipe a signature from a device
+ DEPENDS:= +libblkid
+ SUBMENU:=disc
+endef
+
+define Package/wipefs/description
+ wipefs can erase filesystem, raid or partition table signatures (magic
+ strings) from the specified device to make the signature invisible for
+ libblkid.
+endef
+
+define Package/libblkid/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/.libs/libblkid.so* $(1)/usr/lib/
+endef
+
+define Package/libmount/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/.libs/libmount.so* $(1)/usr/lib/
+endef
+
+define Package/libsmartcols/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/.libs/libsmartcols.so* $(1)/usr/lib/
+endef
+
+define Package/libuuid/install
+ $(INSTALL_DIR) $(1)/usr/lib
+ $(CP) $(PKG_BUILD_DIR)/.libs/libuuid.so* $(1)/usr/lib/
+endef
+
+define Package/agetty/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/agetty $(1)/usr/sbin/
+endef
+
+define Package/blkid/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/blkid $(1)/usr/sbin/
+endef
+
+define Package/cal/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/cal $(1)/usr/bin/
+endef
+
+define Package/cfdisk/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/cfdisk $(1)/usr/sbin/
+endef
+
+define Package/dmesg/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/dmesg $(1)/usr/sbin/
+endef
+
+define Package/fdisk/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/fdisk $(1)/usr/sbin/
+endef
+
+define Package/findfs/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/findfs $(1)/usr/sbin/
+endef
+
+define Package/flock/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/flock $(1)/usr/bin/
+endef
+
+define Package/getopt/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/getopt $(1)/usr/bin/
+endef
+
+define Package/hwclock/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/hwclock $(1)/usr/sbin/
+endef
+
+define Package/logger/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/logger $(1)/usr/bin/
+endef
+
+define Package/look/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/look $(1)/usr/bin/
+endef
+
+define Package/losetup/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/losetup $(1)/usr/sbin/
+endef
+
+define Package/lsblk/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/lsblk $(1)/usr/bin/
+endef
+
+define Package/mcookie/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/mcookie $(1)/usr/bin/
+endef
+
+define Package/mount-utils/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/{u,}mount $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/mountpoint $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/findmnt $(1)/usr/bin/
+endef
+
+define Package/namei/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/namei $(1)/usr/bin/
+endef
+
+define Package/prlimit/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/prlimit $(1)/usr/bin/
+endef
+
+define Package/rename/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/rename $(1)/usr/bin/
+endef
+
+define Package/partx-utils/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/partx $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/addpart $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/delpart $(1)/usr/sbin/
+endef
+
+define Package/script-utils/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/script $(1)/usr/bin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/scriptreplay $(1)/usr/bin/
+endef
+
+define Package/setterm/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/setterm $(1)/usr/bin/
+endef
+
+define Package/sfdisk/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/sfdisk $(1)/usr/sbin/
+endef
+
+define Package/swap-utils/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/mkswap $(1)/usr/sbin/
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/swaplabel $(1)/usr/sbin/
+endef
+
+define Package/uuidd/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/uuidd $(1)/usr/sbin/
+endef
+
+define Package/uuidgen/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/uuidgen $(1)/usr/bin/
+endef
+
+define Package/wall/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/wall $(1)/usr/bin/
+endef
+
+define Package/whereis/install
+ $(INSTALL_DIR) $(1)/usr/bin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/whereis $(1)/usr/bin/
+endef
+
+define Package/wipefs/install
+ $(INSTALL_DIR) $(1)/usr/sbin
+ $(INSTALL_BIN) $(PKG_BUILD_DIR)/.libs/wipefs $(1)/usr/sbin/
+endef
+
+$(eval $(call BuildPackage,libblkid))
+$(eval $(call BuildPackage,libmount))
+$(eval $(call BuildPackage,libsmartcols))
+$(eval $(call BuildPackage,libuuid))
+$(eval $(call BuildPackage,agetty))
+$(eval $(call BuildPackage,blkid))
+$(eval $(call BuildPackage,cal))
+$(eval $(call BuildPackage,cfdisk))
+$(eval $(call BuildPackage,dmesg))
+$(eval $(call BuildPackage,fdisk))
+$(eval $(call BuildPackage,findfs))
+$(eval $(call BuildPackage,flock))
+$(eval $(call BuildPackage,getopt))
+$(eval $(call BuildPackage,hwclock))
+$(eval $(call BuildPackage,logger))
+$(eval $(call BuildPackage,look))
+$(eval $(call BuildPackage,losetup))
+$(eval $(call BuildPackage,lsblk))
+$(eval $(call BuildPackage,mcookie))
+$(eval $(call BuildPackage,mount-utils))
+$(eval $(call BuildPackage,namei))
+$(eval $(call BuildPackage,prlimit))
+$(eval $(call BuildPackage,rename))
+$(eval $(call BuildPackage,partx-utils))
+$(eval $(call BuildPackage,script-utils))
+$(eval $(call BuildPackage,setterm))
+$(eval $(call BuildPackage,sfdisk))
+$(eval $(call BuildPackage,swap-utils))
+$(eval $(call BuildPackage,uuidd))
+$(eval $(call BuildPackage,uuidgen))
+$(eval $(call BuildPackage,wall))
+$(eval $(call BuildPackage,whereis))
+$(eval $(call BuildPackage,wipefs))
diff --git a/package/utils/util-linux/patches/0001-switch_root-improve-statfs-f_type-portability.patch b/package/utils/util-linux/patches/0001-switch_root-improve-statfs-f_type-portability.patch
new file mode 100644
index 0000000..761ace7
--- /dev/null
+++ b/package/utils/util-linux/patches/0001-switch_root-improve-statfs-f_type-portability.patch
@@ -0,0 +1,49 @@
+From 8f806bb1ea30f15db7ca36d1cfa79349f8115302 Mon Sep 17 00:00:00 2001
+From: Karel Zak <kzak@redhat.com>
+Date: Thu, 6 Nov 2014 12:50:27 +0100
+Subject: [PATCH] switch_root: improve statfs->f_type portability
+
+__SWORD_TYPE is not available everywhere, for example it's not defined
+by musl libc. It also seems that __SWORD_TYPE is not used for f_type
+on some architectures (s390x).
+
+Reported-by: Natanael Copa <ncopa@alpinelinux.org>
+Signed-off-by: Karel Zak <kzak@redhat.com>
+---
+ include/statfs_magic.h | 11 +++++++++++
+ sys-utils/switch_root.c | 4 ++--
+ 2 files changed, 13 insertions(+), 2 deletions(-)
+
+--- a/include/statfs_magic.h
++++ b/include/statfs_magic.h
+@@ -1,6 +1,17 @@
+ #ifndef UTIL_LINUX_STATFS_MAGIC_H
+ #define UTIL_LINUX_STATFS_MAGIC_H
+
++#include <sys/statfs.h>
++
++/*
++ * If possible then don't depend on internal libc __SWORD_TYPE type.
++ */
++#ifdef __GNUC__
++typedef __typeof__( ((struct statfs *)0)->f_type ) ul_statfs_ftype_t;
++#else
++typedef __SWORD_TYPE ul_statfs_ftype_t;
++#endif
++
+ /*
+ * Unfortunately, Linux kernel hedeader file <linux/magic.h> is incomplete
+ * mess and kernel returns by statfs f_type many numbers that are nowhere
+--- a/sys-utils/switch_root.c
++++ b/sys-utils/switch_root.c
+@@ -181,8 +181,8 @@ static int switchroot(const char *newroo
+ if (pid <= 0) {
+ struct statfs stfs;
+ if (fstatfs(cfd, &stfs) == 0 &&
+- (stfs.f_type == (__SWORD_TYPE)STATFS_RAMFS_MAGIC ||
+- stfs.f_type == (__SWORD_TYPE)STATFS_TMPFS_MAGIC))
++ (stfs.f_type == (ul_statfs_ftype_t) STATFS_RAMFS_MAGIC ||
++ stfs.f_type == (ul_statfs_ftype_t) STATFS_TMPFS_MAGIC))
+ recursiveRemove(cfd);
+ else
+ warn(_("old root filesystem is not an initramfs"));
diff --git a/package/utils/util-linux/patches/0002-lib-colors-use-static-buffers-when-parse-scheme.patch b/package/utils/util-linux/patches/0002-lib-colors-use-static-buffers-when-parse-scheme.patch
new file mode 100644
index 0000000..ccd82fd
--- /dev/null
+++ b/package/utils/util-linux/patches/0002-lib-colors-use-static-buffers-when-parse-scheme.patch
@@ -0,0 +1,126 @@
+From 6508db29ded734ac4ff5e5e19486c143c9eb3d89 Mon Sep 17 00:00:00 2001
+From: Karel Zak <kzak@redhat.com>
+Date: Fri, 21 Nov 2014 12:23:47 +0100
+Subject: [PATCH] lib/colors: use static buffers when parse scheme
+
+* use static buffers when parse scheme colors
+* cleanup deallocation on error in sequence parser
+
+Signed-off-by: Karel Zak <kzak@redhat.com>
+---
+
+This is modified upstream patch.
+
+--- a/lib/colors.c
++++ b/lib/colors.c
+@@ -416,28 +416,31 @@ static int colors_add_scheme(struct ul_c
+ char *name,
+ char *seq0)
+ {
+- struct ul_color_scheme *cs;
+- char *seq;
++ struct ul_color_scheme *cs = NULL;
++ char *seq = NULL;
+ int rc;
+
+ if (!cc || !name || !*name || !seq0 || !*seq0)
+ return -EINVAL;
+
+ rc = cn_sequence(seq0, &seq);
+- free(seq0);
+ if (rc)
+ return rc;
+
++ rc = -ENOMEM;
++
+ /* convert logical name (e.g. "red") to real ESC code */
+ if (isalpha(*seq)) {
+ const char *s = color_sequence_from_colorname(seq);
+ char *p;
+
+- if (!s)
+- return -EINVAL;
++ if (!s) {
++ rc = -EINVAL;
++ goto err;
++ }
+ p = strdup(s);
+ if (!p)
+- return -ENOMEM;
++ goto err;
+ free(seq);
+ seq = p;
+ }
+@@ -447,17 +450,28 @@ static int colors_add_scheme(struct ul_c
+ void *tmp = realloc(cc->schemes, (cc->nschemes + 10)
+ * sizeof(struct ul_color_scheme));
+ if (!tmp)
+- return -ENOMEM;
++ goto err;
+ cc->schemes = tmp;
+ cc->schemes_sz = cc->nschemes + 10;
+ }
+
+ /* add a new item */
+- cs = &cc->schemes[cc->nschemes++];
+- cs->name = name;
++ cs = &cc->schemes[cc->nschemes];
+ cs->seq = seq;
++ cs->name = strdup(name);
++ if (!cs->name)
++ goto err;
+
++ cc->nschemes++;
+ return 0;
++err:
++ if (cs) {
++ free(cs->seq);
++ free(cs->name);
++ cs->seq = cs->name = NULL;
++ } else
++ free(seq);
++ return rc;
+ }
+
+ /*
+@@ -543,7 +557,8 @@ static int colors_read_schemes(struct ul
+ {
+ int rc = 0;
+ FILE *f = NULL;
+- char buf[BUFSIZ];
++ char buf[BUFSIZ],
++ cn[129], seq[129];
+
+ if (!cc->configured)
+ rc = colors_read_configuration(cc);
+@@ -560,7 +575,6 @@ static int colors_read_schemes(struct ul
+ }
+
+ while (fgets(buf, sizeof(buf), f)) {
+- char *cn = NULL, *seq = NULL;
+ char *p = strchr(buf, '\n');
+
+ if (!p) {
+@@ -576,17 +590,14 @@ static int colors_read_schemes(struct ul
+ if (*p == '\0' || *p == '#')
+ continue;
+
+- rc = sscanf(p, UL_SCNsA" " /* name */
+- UL_SCNsA, /* color */
+- &cn, &seq);
+- if (rc == 2 && cn && seq)
++ rc = sscanf(p, "%128[^ ] %128[^\n ]", cn, seq);
++ if (rc == 2 && *cn && *seq) {
+ rc = colors_add_scheme(cc, cn, seq); /* set rc=0 on success */
+- if (rc) {
+- free(cn);
+- free(seq);
++ if (rc)
++ goto done;
+ }
+- rc = 0;
+ }
++ rc = 0;
+
+ done:
+ if (f)
diff --git a/package/utils/util-linux/patches/001-no-printf-alloc.patch b/package/utils/util-linux/patches/001-no-printf-alloc.patch
new file mode 100644
index 0000000..ad9eef0
--- /dev/null
+++ b/package/utils/util-linux/patches/001-no-printf-alloc.patch
@@ -0,0 +1,104 @@
+--- a/configure.ac
++++ b/configure.ac
+@@ -798,7 +798,6 @@ AC_ARG_ENABLE([libmount],
+ )
+ UL_BUILD_INIT([libmount])
+ UL_REQUIRES_BUILD([libmount], [libblkid])
+-UL_REQUIRES_HAVE([libmount], [scanf_alloc_modifier], [scanf string alloc modifier])
+ AM_CONDITIONAL([BUILD_LIBMOUNT], [test "x$build_libmount" = xyes])
+ AM_CONDITIONAL([BUILD_LIBMOUNT_TESTS], [test "x$build_libmount" = xyes -a "x$enable_static" = xyes])
+
+--- a/libmount/src/tab_parse.c
++++ b/libmount/src/tab_parse.c
+@@ -22,6 +22,10 @@
+ #include "pathnames.h"
+ #include "strutils.h"
+
++#ifndef HAVE_SCANF_MS_MODIFIER
++# define UL_SCNsA "%s"
++#endif
++
+ static int next_number(char **s, int *num)
+ {
+ char *end = NULL;
+@@ -52,16 +56,31 @@ static int mnt_parse_table_line(struct l
+ int rc, n = 0, xrc;
+ char *src = NULL, *fstype = NULL, *optstr = NULL;
+
++#ifndef HAVE_SCANF_MS_MODIFIER
++ size_t len = strlen(s) + 1;
++ src = malloc(len);
++ fstype = malloc(len);
++ fs->target = malloc(len);
++ optstr = malloc(len);
++#endif
++
+ rc = sscanf(s, UL_SCNsA" " /* (1) source */
+ UL_SCNsA" " /* (2) target */
+ UL_SCNsA" " /* (3) FS type */
+ UL_SCNsA" " /* (4) options */
+ "%n", /* byte count */
+
++#ifdef HAVE_SCANF_MS_MODIFIER
+ &src,
+ &fs->target,
+ &fstype,
+ &optstr,
++#else
++ src,
++ fs->target,
++ fstype,
++ optstr,
++#endif
+ &n);
+ xrc = rc;
+
+@@ -127,6 +146,16 @@ static int mnt_parse_mountinfo_line(stru
+ unsigned int maj, min;
+ char *fstype = NULL, *src = NULL, *p;
+
++#ifndef HAVE_SCANF_MS_MODIFIER
++ size_t len = strlen(s) + 1;
++ fs->root = malloc(len);
++ fs->target = malloc(len);
++ fs->vfs_optstr = malloc(len);
++ fs->fs_optstr = malloc(len);
++ fstype = malloc(len);
++ src = malloc(len);
++#endif
++
+ rc = sscanf(s, "%d " /* (1) id */
+ "%d " /* (2) parent */
+ "%u:%u " /* (3) maj:min */
+@@ -138,9 +167,15 @@ static int mnt_parse_mountinfo_line(stru
+ &fs->id,
+ &fs->parent,
+ &maj, &min,
++#ifdef HAVE_SCANF_MS_MODIFIER
+ &fs->root,
+ &fs->target,
+ &fs->vfs_optstr,
++#else
++ fs->root,
++ fs->target,
++ fs->vfs_optstr,
++#endif
+ &end);
+
+ if (rc >= 7 && end > 0)
+@@ -160,9 +195,15 @@ static int mnt_parse_mountinfo_line(stru
+ UL_SCNsA" " /* (9) source */
+ UL_SCNsA, /* (10) fs options (fs specific) */
+
++#ifdef HAVE_SCANF_MS_MODIFIER
+ &fstype,
+ &src,
+ &fs->fs_optstr);
++#else
++ fstype,
++ src,
++ fs->fs_optstr);
++#endif
+
+ if (rc >= 10) {
+ size_t sz;
diff --git a/package/utils/util-linux/patches/002-mkostemp.patch b/package/utils/util-linux/patches/002-mkostemp.patch
new file mode 100644
index 0000000..0281842
--- /dev/null
+++ b/package/utils/util-linux/patches/002-mkostemp.patch
@@ -0,0 +1,46 @@
+Support older hosts with latest util-linux-native
+
+mkostemp is not defined on older machines. So we detect this and
+provide a define that uses mkstemp instead.
+
+O_CLOEXEC is not defined on older machines. It is however defined
+in the 'c.h' header. Fix up the users to include 'c.h'.
+
+fdisks/fdisksunlabel.c was modified to use qsort_r, however
+this is not defined on older hosts. Revert:
+ commit c69bbca9c1f6645097bd20fe3a21f5a99a2a0698
+ fdisk: (sun): use ask API, remove global variable
+
+Upstream-Status: Inappropriate [other]
+Patches revert upstream changes in order to support older
+machines.
+
+Signed-off-by: Mark Hatle <mark.hatle@windriver.com>
+---
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -315,6 +315,7 @@ AC_CHECK_FUNCS([ \
+ llseek \
+ lseek64 \
+ mempcpy \
++ mkostemp \
+ nanosleep \
+ open_memstream \
+ personality \
+--- a/include/c.h
++++ b/include/c.h
+@@ -233,6 +233,13 @@ static inline int dirfd(DIR *d)
+ #endif
+
+ /*
++ * mkostemp replacement
++ */
++#ifndef HAVE_MKOSTEMP
++#define mkostemp(template, flags) mkstemp(template)
++#endif
++
++/*
+ * MAXHOSTNAMELEN replacement
+ */
+ static inline size_t get_hostname_max(void)
diff --git a/package/utils/util-linux/patches/003-fix_pkgconfig_files.patch b/package/utils/util-linux/patches/003-fix_pkgconfig_files.patch
new file mode 100644
index 0000000..ac590a0
--- /dev/null
+++ b/package/utils/util-linux/patches/003-fix_pkgconfig_files.patch
@@ -0,0 +1,62 @@
+--- a/libuuid/Makemodule.am
++++ b/libuuid/Makemodule.am
+@@ -4,7 +4,6 @@ include libuuid/man/Makemodule.am
+ include libuuid/src/Makemodule.am
+
+ pkgconfig_DATA += libuuid/uuid.pc
+-PATHFILES += libuuid/uuid.pc
+ EXTRA_DIST += libuuid/COPYING
+
+ endif # BUILD_LIBUUID
+--- a/configure.ac
++++ b/configure.ac
+@@ -1802,15 +1802,19 @@ AC_CONFIG_HEADERS([config.h])
+ #
+ AC_CONFIG_FILES([
+ Makefile
++libblkid/blkid.pc
+ libblkid/docs/Makefile
+ libblkid/docs/version.xml
+ libblkid/src/blkid.h
++libmount/mount.pc
+ libmount/docs/Makefile
+ libmount/docs/version.xml
+ libmount/src/libmount.h
++libsmartcols/smartcols.pc
+ libsmartcols/docs/Makefile
+ libsmartcols/docs/version.xml
+ libsmartcols/src/libsmartcols.h
++libuuid/uuid.pc
+ po/Makefile.in
+ ])
+
+--- a/libblkid/Makemodule.am
++++ b/libblkid/Makemodule.am
+@@ -9,7 +9,6 @@ SUBDIRS += libblkid/docs
+ endif
+
+ pkgconfig_DATA += libblkid/blkid.pc
+-PATHFILES += libblkid/blkid.pc
+ dist_man_MANS += libblkid/libblkid.3
+ EXTRA_DIST += libblkid/libblkid.3 libblkid/COPYING
+
+--- a/libmount/Makemodule.am
++++ b/libmount/Makemodule.am
+@@ -9,7 +9,6 @@ SUBDIRS += libmount/docs
+ endif
+
+ pkgconfig_DATA += libmount/mount.pc
+-PATHFILES += libmount/mount.pc
+ EXTRA_DIST += libmount/COPYING
+
+ endif # BUILD_LIBMOUNT
+--- a/libsmartcols/Makemodule.am
++++ b/libsmartcols/Makemodule.am
+@@ -8,7 +8,6 @@ SUBDIRS += libsmartcols/docs
+ endif
+
+ pkgconfig_DATA += libsmartcols/smartcols.pc
+-PATHFILES += libsmartcols/smartcols.pc
+ EXTRA_DIST += libsmartcols/COPYING
+
+ endif # BUILD_LIBSMARTCOLS
diff --git a/package/utils/xfsprogs/Makefile b/package/utils/xfsprogs/Makefile
new file mode 100644
index 0000000..6333077
--- /dev/null
+++ b/package/utils/xfsprogs/Makefile
@@ -0,0 +1,90 @@
+#
+# Copyright (C) 2006-2012 OpenWrt.org
+#
+# This is free software, licensed under the GNU General Public License v2.
+# See /LICENSE for more information.
+#
+
+include $(TOPDIR)/rules.mk
+
+PKG_NAME:=xfsprogs
+PKG_RELEASE:=1
+PKG_VERSION:=3.1.7
+PKG_SOURCE_URL:=ftp://oss.sgi.com/projects/xfs/previous/
+PKG_MD5SUM:=049cf9873794ea49d0bb3f12d45748a4
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_INSTALL:=1
+PKG_FIXUP:=autoreconf
+PKG_CHECK_FORMAT_SECURITY:=0
+
+include $(INCLUDE_DIR)/package.mk
+include $(INCLUDE_DIR)/nls.mk
+
+define Package/xfsprogs/default
+ SECTION:=utils
+ CATEGORY:=Utilities
+ SUBMENU:=Filesystem
+ DEPENDS:=+libuuid +libpthread +librt
+ URL:=http://oss.sgi.com/projects/xfs
+endef
+
+define Package/xfs-mkfs
+$(call Package/xfsprogs/default)
+ TITLE:=Utility for creating XFS filesystems
+endef
+
+define Package/xfs-fsck
+$(call Package/xfsprogs/default)
+ TITLE:=Utilities for checking and repairing XFS filesystems
+endef
+
+define Package/xfs-growfs
+$(call Package/xfsprogs/default)
+ TITLE:=Utility for increasing the size of XFS filesystems
+endef
+
+CONFIGURE_ARGS += \
+ --enable-gettext=no \
+ --enable-lib64=no \
+ --enable-blkid=no
+
+TARGET_CFLAGS += \
+ -I$(STAGING_DIR)/usr/include \
+ -D_LARGEFILE64_SOURCE \
+ -D_FILE_OFFSET_BITS=64 \
+ -D_GNU_SOURCE
+
+MAKE_FLAGS += \
+ DEBUG= Q= \
+ PCFLAGS="-Wall" \
+ PKG_PLATFORM=linux \
+ ENABLE_GETTEXT=no \
+ prefix=$(PKG_INSTALL_DIR)/usr \
+ exec_prefix=$(PKG_INSTALL_DIR)/usr \
+ PKG_SBIN_DIR=$(PKG_INSTALL_DIR)/usr/sbin \
+ PKG_ROOT_SBIN_DIR=$(PKG_INSTALL_DIR)/sbin \
+ PKG_MAN_DIR=$(PKG_INSTALL_DIR)/usr/man \
+ PKG_LOCALE_DIR=$(PKG_INSTALL_DIR)/usr/share/locale \
+ PKG_ROOT_LIB_DIR=$(PKG_INSTALL_DIR)/lib \
+ PKG_DOC_DIR=$(PKG_INSTALL_DIR)/usr/share/doc/xfsprogs
+
+define Package/xfs-mkfs/install
+ mkdir -p $(1)/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/mkfs.xfs $(1)/sbin
+endef
+
+define Package/xfs-fsck/install
+ mkdir -p $(1)/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/sbin/xfs_repair $(1)/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/xfs_db $(1)/sbin
+endef
+
+define Package/xfs-growfs/install
+ mkdir -p $(1)/sbin
+ $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/xfs_growfs $(1)/sbin
+endef
+
+$(eval $(call BuildPackage,xfs-mkfs))
+$(eval $(call BuildPackage,xfs-fsck))
+$(eval $(call BuildPackage,xfs-growfs))
diff --git a/package/utils/xfsprogs/patches/001-automake-compat.patch b/package/utils/xfsprogs/patches/001-automake-compat.patch
new file mode 100644
index 0000000..3003d6d
--- /dev/null
+++ b/package/utils/xfsprogs/patches/001-automake-compat.patch
@@ -0,0 +1,84 @@
+commit 2222aa77e11b959e0e5a0ded3482e56799593bc2
+Author: Jens Muecke <jens@nons.de>
+Date: Thu Jan 26 00:34:15 2012 +0100
+
+ 001-automake-compat
+
+diff --git a/configure.in b/configure.in
+index 664c0e9..d91b6ec 100644
+--- a/configure.in
++++ b/configure.in
+@@ -2,7 +2,8 @@ AC_INIT(include/libxfs.h)
+ AC_PREREQ(2.50)
+ AC_CONFIG_AUX_DIR([.])
+ AC_CONFIG_MACRO_DIR([m4])
+-AC_CONFIG_HEADER(include/platform_defs.h)
++# Put a dummy here (http://www.mail-archive.com/automake@gnu.org/msg09241.html)
++AC_CONFIG_HEADERS([doesnotexist.h include/platform_defs.h])
+ AC_PREFIX_DEFAULT(/usr)
+
+ AC_PROG_LIBTOOL
+diff --git a/include/builddefs.in b/include/builddefs.in
+index 81ebfcd..5a4a0e8 100644
+--- a/include/builddefs.in
++++ b/include/builddefs.in
+@@ -20,6 +20,8 @@
+ ifndef _BUILDDEFS_INCLUDED_
+ _BUILDDEFS_INCLUDED_ = 1
+
++SHELL = @SHELL@
++
+ DEBUG = @debug_build@
+ OPTIMIZER = @opt_build@
+ MALLOCLIB = @malloc_lib@
+diff --git a/m4/package_types.m4 b/m4/package_types.m4
+index 0a0e087..66a136a 100644
+--- a/m4/package_types.m4
++++ b/m4/package_types.m4
+@@ -9,7 +9,7 @@ AC_DEFUN([AC_TYPE_PSINT],
+ #include <stddef.h>
+ ], [
+ __psint_t psint;
+- ], AC_DEFINE(HAVE___PSINT_T) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no))
++ ], AC_DEFINE([HAVE___PSINT_T], [1], [Define if __psint_t exists]) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no))
+ ])
+
+ #
+@@ -23,7 +23,7 @@ AC_DEFUN([AC_TYPE_PSUNSIGNED],
+ #include <stddef.h>
+ ], [
+ __psunsigned_t psuint;
+- ], AC_DEFINE(HAVE___PSUNSIGNED_T) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no))
++ ], AC_DEFINE([HAVE___PSUNSIGNED_T], [1], [Define if __psunsigned_t exists]) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no))
+ ])
+
+ #
+@@ -37,7 +37,7 @@ AC_DEFUN([AC_TYPE_U32],
+ #include <stddef.h>
+ ], [
+ __u32 u32;
+- ], AC_DEFINE(HAVE___U32) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no))
++ ], AC_DEFINE([HAVE___U32], [1], [Define if __u32 exists]) AC_MSG_RESULT(yes) , AC_MSG_RESULT(no))
+ ])
+
+ #
+@@ -50,15 +50,15 @@ AC_DEFUN([AC_SIZEOF_POINTERS_AND_LONG],
+ AC_CHECK_SIZEOF(long, 4)
+ AC_CHECK_SIZEOF(char *, 4)
+ if test $ac_cv_sizeof_long -eq 4 -o $ac_cv_sizeof_long -eq 0; then
+- AC_DEFINE(HAVE_32BIT_LONG)
++ AC_DEFINE([HAVE_32BIT_LONG], [1], [Define if long is 32bit])
+ fi
+ if test $ac_cv_sizeof_long -eq 8; then
+- AC_DEFINE(HAVE_64BIT_LONG)
++ AC_DEFINE([HAVE_64BIT_LONG], [1], [Define if long is 64bit])
+ fi
+ if test $ac_cv_sizeof_char_p -eq 4 -o $ac_cv_sizeof_char_p -eq 0; then
+- AC_DEFINE(HAVE_32BIT_PTR)
++ AC_DEFINE([HAVE_32BIT_PTR], [1], [Define if char* is 32bit])
+ fi
+ if test $ac_cv_sizeof_char_p -eq 8; then
+- AC_DEFINE(HAVE_64BIT_PTR)
++ AC_DEFINE([HAVE_64BIT_PTR], [1], [Define if char* is 64bit])
+ fi
+ ])
diff --git a/package/utils/xfsprogs/patches/100-no_aio.patch b/package/utils/xfsprogs/patches/100-no_aio.patch
new file mode 100644
index 0000000..30d36b4
--- /dev/null
+++ b/package/utils/xfsprogs/patches/100-no_aio.patch
@@ -0,0 +1,21 @@
+commit e72b7bd12fdef06c3494b919376bfe886aa8bb4d
+Author: Jens Muecke <jens@nons.de>
+Date: Thu Jan 26 00:35:43 2012 +0100
+
+ 100-no_aio
+
+diff --git a/configure.in b/configure.in
+index d91b6ec..8dc8b4a 100644
+--- a/configure.in
++++ b/configure.in
+@@ -92,8 +92,8 @@ AC_PACKAGE_GLOBALS(xfsprogs)
+ AC_PACKAGE_UTILITIES(xfsprogs)
+ AC_MULTILIB($enable_lib64)
+
+-AC_PACKAGE_NEED_AIO_H
+-AC_PACKAGE_NEED_LIO_LISTIO
++librt="-lrt"
++AC_SUBST(librt)
+
+ AC_PACKAGE_NEED_UUID_H
+ AC_PACKAGE_NEED_UUIDCOMPARE
diff --git a/package/utils/xfsprogs/patches/110-uclibc_no_ustat.patch b/package/utils/xfsprogs/patches/110-uclibc_no_ustat.patch
new file mode 100644
index 0000000..071dfc1
--- /dev/null
+++ b/package/utils/xfsprogs/patches/110-uclibc_no_ustat.patch
@@ -0,0 +1,34 @@
+commit 7b1d0a98e779170232c0a81b4749ab934ec67a7e
+Author: Jens Muecke <jens@nons.de>
+Date: Thu Jan 26 00:36:42 2012 +0100
+
+ 110-uclibc_no_ustat
+
+diff --git a/libxfs/linux.c b/libxfs/linux.c
+index 2e07d54..6a6c905 100644
+--- a/libxfs/linux.c
++++ b/libxfs/linux.c
+@@ -21,7 +21,6 @@
+ #include <mntent.h>
+ #include <sys/stat.h>
+ #undef ustat
+-#include <sys/ustat.h>
+ #include <sys/mount.h>
+ #include <sys/ioctl.h>
+ #include <sys/sysinfo.h>
+@@ -49,6 +51,7 @@ static int max_block_alignment;
+ int
+ platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose)
+ {
++#if 0
+ /* Pad ust; pre-2.6.28 linux copies out too much in 32bit compat mode */
+ struct ustat ust[2];
+ struct stat64 st;
+@@ -68,6 +71,7 @@ platform_check_ismounted(char *name, char *block, struct stat64 *s, int verbose)
+ progname, name);
+ return 1;
+ }
++#endif
+ return 0;
+ }
+
diff --git a/package/utils/xfsprogs/patches/120-portability.patch b/package/utils/xfsprogs/patches/120-portability.patch
new file mode 100644
index 0000000..1e9b533
--- /dev/null
+++ b/package/utils/xfsprogs/patches/120-portability.patch
@@ -0,0 +1,47 @@
+commit d2aef8b3967e53fe58178f5af50fef488ee0faed
+Author: Jens Muecke <jens@nons.de>
+Date: Thu Jan 26 00:37:52 2012 +0100
+
+ 120-portability
+
+diff --git a/copy/xfs_copy.c b/copy/xfs_copy.c
+index c01e0b9..2e2f320 100644
+--- a/copy/xfs_copy.c
++++ b/copy/xfs_copy.c
+@@ -463,6 +463,15 @@ read_ag_header(int fd, xfs_agnumber_t agno, wbuf *buf, ag_header_t *ag,
+ }
+
+
++static void sig_mask(int type)
++{
++ sigset_t mask;
++ sigemptyset(&mask);
++ sigaddset(&mask, SIGCHLD);
++ sigprocmask(type, &mask, NULL);
++}
++
++
+ void
+ write_wbuf(void)
+ {
+@@ -478,9 +487,9 @@ write_wbuf(void)
+ if (target[i].state != INACTIVE)
+ pthread_mutex_unlock(&targ[i].wait); /* wake up */
+
+- sigrelse(SIGCHLD);
++ sig_mask(SIG_UNBLOCK);
+ pthread_mutex_lock(&mainwait);
+- sighold(SIGCHLD);
++ sig_mask(SIG_BLOCK);
+ }
+
+
+@@ -847,7 +856,7 @@ main(int argc, char **argv)
+ /* set up sigchild signal handler */
+
+ signal(SIGCHLD, handler);
+- sighold(SIGCHLD);
++ sig_mask(SIG_BLOCK);
+
+ /* make children */
+
diff --git a/package/utils/xfsprogs/patches/130-uclibc_no_xattr.patch b/package/utils/xfsprogs/patches/130-uclibc_no_xattr.patch
new file mode 100644
index 0000000..a9b5a6f
--- /dev/null
+++ b/package/utils/xfsprogs/patches/130-uclibc_no_xattr.patch
@@ -0,0 +1,34 @@
+commit 10d6058b24f18cb31889154f830b191849f45106
+Author: Jens Muecke <jens@nons.de>
+Date: Thu Jan 26 00:38:27 2012 +0100
+
+ 130-uclibc_no_xattr
+
+diff --git a/fsr/xfs_fsr.c b/fsr/xfs_fsr.c
+index 40c2e6f..4f54059 100644
+--- a/fsr/xfs_fsr.c
++++ b/fsr/xfs_fsr.c
+@@ -35,7 +35,6 @@
+ #include <sys/wait.h>
+ #include <sys/vfs.h>
+ #include <sys/statvfs.h>
+-#include <sys/xattr.h>
+
+
+ #ifndef XFS_XFLAG_NODEFRAG
+@@ -990,6 +992,7 @@ fsr_setup_attr_fork(
+ int tfd,
+ xfs_bstat_t *bstatp)
+ {
++#if 0
+ struct stat64 tstatbuf;
+ int i;
+ int last_forkoff = 0;
+@@ -1108,6 +1111,7 @@ fsr_setup_attr_fork(
+ out:
+ if (dflag)
+ fsrprintf(_("set temp attr\n"));
++#endif
+ return 0;
+ }
+
diff --git a/package/utils/xfsprogs/patches/140-no_po.patch b/package/utils/xfsprogs/patches/140-no_po.patch
new file mode 100644
index 0000000..f915a9c
--- /dev/null
+++ b/package/utils/xfsprogs/patches/140-no_po.patch
@@ -0,0 +1,20 @@
+diff -urN xfsprogs-3.1.7/Makefile xfsprogs-3.1.7.new/Makefile
+--- xfsprogs-3.1.7/Makefile 2011-11-18 00:30:24.000000000 +0100
++++ xfsprogs-3.1.7.new/Makefile 2012-04-20 14:15:48.641722955 +0200
+@@ -41,7 +41,7 @@
+
+ LIB_SUBDIRS = libxfs libxlog libxcmd libhandle libdisk
+ TOOL_SUBDIRS = copy db estimate fsck fsr growfs io logprint mkfs quota \
+- mdrestore repair rtcp m4 man doc po debian
++ mdrestore repair rtcp m4 man doc debian
+
+ SUBDIRS = include $(LIB_SUBDIRS) $(TOOL_SUBDIRS)
+
+@@ -135,7 +135,6 @@
+ $(Q)$(MAKE) $(MAKEOPTS) -C . $@
+ else
+ $(Q)$(MAKE) $(MAKEOPTS) $(SRCDIR)
+- $(Q)$(MAKE) $(MAKEOPTS) -C po
+ $(Q)$(MAKE) $(MAKEOPTS) source-link
+ $(Q)cd $(SRCDIR) && dpkg-buildpackage
+ endif
diff --git a/package/utils/xfsprogs/patches/150-include_fixes.patch b/package/utils/xfsprogs/patches/150-include_fixes.patch
new file mode 100644
index 0000000..793622a
--- /dev/null
+++ b/package/utils/xfsprogs/patches/150-include_fixes.patch
@@ -0,0 +1,72 @@
+--- a/libhandle/handle.c
++++ b/libhandle/handle.c
+@@ -20,6 +20,7 @@
+ #include <xfs/xfs.h>
+ #include <xfs/handle.h>
+ #include <xfs/parent.h>
++#include <linux/limits.h>
+
+ /* just pick a value we know is more than big enough */
+ #define MAXHANSIZ 64
+--- a/libhandle/jdm.c
++++ b/libhandle/jdm.c
+@@ -20,6 +20,7 @@
+ #include <xfs/handle.h>
+ #include <xfs/jdm.h>
+ #include <xfs/parent.h>
++#include <linux/limits.h>
+
+ /* internal fshandle - typecast to a void for external use */
+ #define FSHANDLE_SZ 8
+--- a/libdisk/evms.c
++++ b/libdisk/evms.c
+@@ -22,6 +22,7 @@
+ #include <fcntl.h>
+ #include <sys/ioctl.h>
+ #include <sys/sysmacros.h>
++#include <sys/stat.h>
+ #include <disk/volume.h>
+ #include "evms.h"
+
+--- a/libdisk/evms.h
++++ b/libdisk/evms.h
+@@ -16,6 +16,8 @@
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
++#include <sys/types.h>
++
+ #define EVMS_MAJOR 117
+ #define EVMS_GET_VOL_STRIPE_INFO \
+ _IOR(EVMS_MAJOR, 0xF0, struct evms_vol_stripe_info_s)
+--- a/libdisk/fstype.h
++++ b/libdisk/fstype.h
+@@ -192,7 +192,7 @@ struct adfs_super_block {
+ char s_dummy2[62];
+ char s_checksum[1];
+ };
+-#define adfsblksize(s) ((uint) s.s_blksize[0])
++#define adfsblksize(s) ((unsigned int) s.s_blksize[0])
+
+ /* found in first 4 bytes of block 1 */
+ struct vxfs_super_block {
+--- a/fsr/xfs_fsr.c
++++ b/fsr/xfs_fsr.c
+@@ -25,6 +25,7 @@
+ #include <xfs/xfs_dinode.h>
+ #include <xfs/xfs_attr_sf.h>
+
++#include <paths.h>
+ #include <fcntl.h>
+ #include <errno.h>
+ #include <malloc.h>
+--- a/libdisk/xvm.c
++++ b/libdisk/xvm.c
+@@ -22,6 +22,7 @@
+ #include <unistd.h>
+ #include <sys/stat.h>
+ #include <sys/ioctl.h>
++#include <sys/types.h>
+ #include <disk/volume.h>
+ #include "xvm.h"
+