Project import
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7491d7f
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,93 @@
+#
+#    Copyright (c) 2010-2011 Nest, Inc.
+#    All rights reserved.
+#
+#    This document is the property of Nest. It is considered
+#    confidential and proprietary information.
+#
+#    This document may not be reproduced or transmitted in any form,
+#    in whole or in part, without the express written permission of
+#    Nest.
+#
+#    Description:
+#      This file is the makefile for embedded Linux "Swiss Army Knife"
+#      application, BusyBox.
+#
+
+include pre.mak
+
+PackageName		:= busybox
+
+PackageExtension	:= tar.bz2
+PackageSeparator	:= -
+
+PackagePatchArgs	:= -p1
+
+PackageArchive		:= $(PackageName).$(PackageExtension)
+PackageSourceDir	:= $(PackageName)$(PackageSeparator)$(PackageVersion)
+
+PackageBuildMakefile	= $(call GenerateBuildPaths,Makefile)
+
+CleanPaths		+= $(PackageLicenseFile)
+
+all: $(PackageDefaultGoal)
+
+# Generate the package license contents.
+
+$(PackageSourceDir)/LICENSE: source
+
+$(PackageLicenseFile): $(PackageSourceDir)/LICENSE
+	$(copy-result)
+
+# Extract the source from the archive and apply patches, if any.
+
+$(PackageSourceDir): $(PackageArchive) $(PackagePatchPaths)
+	$(expand-and-patch-package)
+
+# Prepare the sources.
+
+.PHONY: source
+source: | $(PackageSourceDir)
+
+# Patch the sources, if necessary.
+
+.PHONY: patch
+patch: source
+
+# BusyBox has no way of explicitly setting CC, LD, OBJCOPY, et al and
+# instead relies on the value of CROSS_COMPILE. Consequently, we have
+# to ensure that 'ToolBinDir' is in 'PATH' so that the kernel build
+# infrastructure can find $(CROSS_COMPILE)gcc, $(CROSS_COMPILE)ld, et
+# al.
+
+configure build stage: PATH := $(PATH):$(ToolBinDir)
+
+# Generate the package build makefile and default configuration based
+# on the build configuration.
+
+$(PackageBuildMakefile): $(CURDIR)/configs/$(BuildConfig)_defconfig | $(PackageSourceDir) $(BuildDirectory)
+	$(Verbose)$(MAKE) $(JOBSFLAG) -C $(PackageSourceDir) O=$(CURDIR)/$(BuildDirectory) $<
+
+# Configure the source for building.
+
+.PHONY: configure
+configure: source $(PackageBuildMakefile)
+
+# Build the source.
+
+.PHONY: build
+build: configure
+	$(Verbose)$(MAKE) $(JOBSFLAG) -C $(BuildDirectory) busybox
+
+# Stage the build to a temporary installation area.
+
+.PHONY: stage
+stage: build | $(ResultDirectory)
+	$(Verbose)$(MAKE) $(JOBSFLAG) -C $(BuildDirectory) INSTALL="$(INSTALL) $(INSTALLFLAGS)" CONFIG_PREFIX=$(ResultDirectory) install
+
+clean:
+	$(Verbose)$(RM) $(RMFLAGS) -r $(PackageSourceDir)
+	$(Verbose)$(RM) $(RMFLAGS) -r $(BuildDirectory)
+	$(Verbose)$(RM) $(RMFLAGS) -r $(ResultDirectory)
+
+include post.mak
diff --git a/busybox-1.19.3/.indent.pro b/busybox-1.19.3/.indent.pro
new file mode 100644
index 0000000..492ecf1
--- /dev/null
+++ b/busybox-1.19.3/.indent.pro
@@ -0,0 +1,33 @@
+--blank-lines-after-declarations
+--blank-lines-after-procedures
+--break-before-boolean-operator
+--no-blank-lines-after-commas
+--braces-on-if-line
+--braces-on-struct-decl-line
+--comment-indentation25
+--declaration-comment-column25
+--no-comment-delimiters-on-blank-lines
+--cuddle-else
+--continuation-indentation4
+--case-indentation0
+--else-endif-column33
+--space-after-cast
+--line-comments-indentation0
+--declaration-indentation1
+--dont-format-first-column-comments
+--dont-format-comments
+--honour-newlines
+--indent-level4
+/* changed from 0 to 4 */
+--parameter-indentation4
+--line-length78 /* changed from 75 */
+--continue-at-parentheses
+--no-space-after-function-call-names
+--dont-break-procedure-type
+--dont-star-comments
+--leave-optional-blank-lines
+--dont-space-special-semicolon
+--tab-size4
+/* additions by Mark */
+--case-brace-indentation0
+--leave-preprocessor-space
diff --git a/busybox-1.19.3/AUTHORS b/busybox-1.19.3/AUTHORS
new file mode 100644
index 0000000..0908fc7
--- /dev/null
+++ b/busybox-1.19.3/AUTHORS
@@ -0,0 +1,176 @@
+List of the authors of code contained in BusyBox.
+
+If you have code in BusyBox, you should be listed here.  If you should be
+listed, or the description of what you have done needs more detail, or is
+incorrect, _please_ let me know.
+
+ -Erik
+
+-----------
+
+Peter Willis <psyphreak@phreaker.net>
+    eject
+
+Emanuele Aina <emanuele.aina@tiscali.it>
+    run-parts
+
+Erik Andersen <andersen@codepoet.org>
+    Tons of new stuff, major rewrite of most of the
+    core apps, tons of new apps as noted in header files.
+    Lots of tedious effort writing these boring docs that
+    nobody is going to actually read.
+
+Laurence Anderson <l.d.anderson@warwick.ac.uk>
+    rpm2cpio, unzip, get_header_cpio, read_gz interface, rpm
+
+Jeff Angielski <jeff@theptrgroup.com>
+    ftpput, ftpget
+
+Enrik Berkhan <Enrik.Berkhan@inka.de>
+    setconsole
+
+Jim Bauer <jfbauer@nfr.com>
+    modprobe shell dependency
+
+Edward Betts <edward@debian.org>
+    expr, hostid, logname, whoami
+
+John Beppu <beppu@codepoet.org>
+    du, nslookup, sort
+
+David Brownell <dbrownell@users.sourceforge.net>
+    zcip
+
+Brian Candler <B.Candler@pobox.com>
+    tiny-ls(ls)
+
+Randolph Chung <tausq@debian.org>
+    fbset, ping, hostname
+
+Dave Cinege <dcinege@psychosis.com>
+    more(v2), makedevs, dutmp, modularization, auto links file,
+    various fixes, Linux Router Project maintenance
+
+Jordan Crouse <jordan@cosmicpenguin.net>
+    ipcalc
+
+Magnus Damm <damm@opensource.se>
+    tftp client
+    insmod powerpc support
+
+Larry Doolittle <ldoolitt@recycle.lbl.gov>
+    pristine source directory compilation, lots of patches and fixes.
+
+Glenn Engel <glenne@engel.org>
+    httpd
+
+Gennady Feldman <gfeldman@gena01.com>
+    Sysklogd (single threaded syslogd, IPC Circular buffer support,
+    logread), various fixes.
+
+Robert Griebl <sandman@handhelds.org>
+    modprobe, hwclock, suid/sgid handling, tinylogin integration
+    many bugfixes and enhancements
+
+Karl M. Hegbloom <karlheg@debian.org>
+    cp_mv.c, the test suite, various fixes to utility.c, &c.
+
+Daniel Jacobowitz <dan@debian.org>
+    mktemp.c
+
+Matt Kraai <kraai@alumni.cmu.edu>
+    documentation, bugfixes, test suite
+
+Rob Landley <rob@landley.net>
+    Became busybox maintainer in 2006.
+
+    sed (major rewrite in 2003, and I now maintain the thing)
+    bunzip2 (complete from-scratch rewrite, then mjn3 optimized the result)
+    sort (more or less from scratch rewrite in 2004, I now maintain it)
+    mount (rewrite in 2005, I maintain the new one)
+
+Stephan Linz <linz@li-pro.net>
+    ipcalc, Red Hat equivalence
+
+John Lombardo <john@deltanet.com>
+    tr
+
+Glenn McGrath <glenn.l.mcgrath@gmail.com>
+    Common unarchiving code and unarchiving applets, ifupdown, ftpgetput,
+    nameif, sed, patch, fold, install, uudecode.
+    Various bugfixes, review and apply numerous patches.
+
+Manuel Novoa III <mjn3@codepoet.org>
+    cat, head, mkfifo, mknod, rmdir, sleep, tee, tty, uniq, usleep, wc, yes,
+    mesg, vconfig, nice, renice,
+    make_directory, parse_mode, dirname, mode_string,
+    get_last_path_component, simplify_path, and a number trivial libbb routines
+
+    also bug fixes, partial rewrites, and size optimizations in
+    ash, basename, cal, cmp, cp, df, du, echo, env, ln, logname, md5sum, mkdir,
+    mv, realpath, rm, sort, tail, touch, uname, watch, arith, human_readable,
+    interface, dutmp, ifconfig, route
+
+Vladimir Oleynik <dzo@simtreas.ru>
+    cmdedit; bb_mkdep, xargs(current), httpd(current);
+    ports: ash, crond, fdisk (initial, unmaintained now), inetd, stty, traceroute,
+    top;
+    locale, various fixes
+    and irreconcilable critic of everything not perfect.
+
+Bruce Perens <bruce@pixar.com>
+    Original author of BusyBox in 1995, 1996. Some of his code can
+    still be found hiding here and there...
+
+Rodney Radford <rradford@mindspring.com>
+    ipcs, ipcrm
+
+Tim Riker <Tim@Rikers.org>
+    bug fixes, member of fan club
+
+Kent Robotti <robotti@metconnect.com>
+    reset, tons and tons of bug reports and patches.
+
+Chip Rosenthal <chip@unicom.com>, <crosenth@covad.com>
+    wget - Contributed by permission of Covad Communications
+
+Pavel Roskin <proski@gnu.org>
+    Lots of bugs fixes and patches.
+
+Gyepi Sam <gyepi@praxis-sw.com>
+    Remote logging feature for syslogd
+
+Rob Sullivan <cogito.ergo.cogito@gmail.com>
+    comm
+
+Linus Torvalds
+    mkswap, fsck.minix, mkfs.minix
+
+Mark Whitley <markw@codepoet.org>
+    grep, sed, cut, xargs(previous),
+    style-guide, new-applet-HOWTO, bug fixes, etc.
+
+Charles P. Wright <cpwright@villagenet.com>
+    gzip, mini-netcat(nc)
+
+Enrique Zanardi <ezanardi@ull.es>
+    tarcat (since removed), loadkmap, various fixes, Debian maintenance
+
+Tito Ragusa <farmatito@tiscali.it>
+    devfsd and size optimizations in strings, openvt, chvt, deallocvt, hdparm,
+    fdformat, lsattr, chattr, id and eject.
+
+Paul Fox <pgf@foxharp.boston.ma.us>
+    vi editing mode for ash, various other patches/fixes
+
+Roberto A. Foglietta <me@roberto.foglietta.name>
+    port: dnsd
+
+Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
+    misc
+
+Mike Frysinger <vapier@gentoo.org>
+    initial e2fsprogs, printenv, setarch, sum, misc
+
+Jie Zhang <jie.zhang@analog.com>
+    fixed two bugs in msh and hush (exitcode of killed processes)
diff --git a/busybox-1.19.3/Config.in b/busybox-1.19.3/Config.in
new file mode 100644
index 0000000..1e71812
--- /dev/null
+++ b/busybox-1.19.3/Config.in
@@ -0,0 +1,779 @@
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+mainmenu "BusyBox Configuration"
+
+config HAVE_DOT_CONFIG
+	bool
+	default y
+
+menu "Busybox Settings"
+
+menu "General Configuration"
+
+config DESKTOP
+	bool "Enable options for full-blown desktop systems"
+	default y
+	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 EXTRA_COMPAT
+	bool "Provide compatible behavior for rare corner cases (bigger code)"
+	default n
+	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 INCLUDE_SUSv2
+	bool "Enable obsolete features removed before SUSv3"
+	default y
+	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 USE_PORTABLE_CODE
+	bool "Avoid using GCC-specific code constructs"
+	default n
+	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 PLATFORM_LINUX
+	bool "Enable Linux-specific applets and features"
+	default y
+	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 FEATURE_BUFFERS_USE_MALLOC
+	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 FEATURE_BUFFERS_USE_MALLOC
+	bool "Allocate with Malloc"
+
+config FEATURE_BUFFERS_GO_ON_STACK
+	bool "Allocate on the Stack"
+
+config FEATURE_BUFFERS_GO_IN_BSS
+	bool "Allocate in the .bss section"
+
+endchoice
+
+config SHOW_USAGE
+	bool "Show terse applet usage messages"
+	default y
+	help
+	  All BusyBox applets will show help messages when invoked with
+	  wrong arguments. You can turn off printing these terse usage
+	  messages if you say no here.
+	  This will save you up to 7k.
+
+config FEATURE_VERBOSE_USAGE
+	bool "Show verbose applet usage messages"
+	default y
+	depends on SHOW_USAGE
+	help
+	  All BusyBox applets will show more 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 FEATURE_COMPRESS_USAGE
+	bool "Store applet usage messages in compressed form"
+	default y
+	depends on SHOW_USAGE
+	help
+	  Store usage messages in 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 FEATURE_INSTALLER
+	bool "Support --install [-s] to install applet links at runtime"
+	default y
+	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 INSTALL_NO_USR
+	bool "Don't use /usr"
+	default n
+	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 LOCALE_SUPPORT
+	bool "Enable locale support (system needs locale for this to work)"
+	default n
+	help
+	  Enable this if your system has locale support and you would like
+	  busybox to support locale settings.
+
+config UNICODE_SUPPORT
+	bool "Support Unicode"
+	default y
+	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 UNICODE_USING_LOCALE
+	bool "Use libc routines for Unicode (else uses internal ones)"
+	default n
+	depends on UNICODE_SUPPORT && LOCALE_SUPPORT
+	help
+	  With this option on, Unicode support is implemented using libc
+	  routines. Otherwise, internal implementation is used.
+	  Internal implementation is smaller.
+
+config FEATURE_CHECK_UNICODE_IN_ENV
+	bool "Check $LANG environment variable"
+	default n
+	depends on UNICODE_SUPPORT && !UNICODE_USING_LOCALE
+	help
+	  With this option on, Unicode support is activated
+	  only if LANG variable has the value of the form "xxxx.utf8"
+
+	  Otherwise, Unicode support will be always enabled and active.
+
+config SUBST_WCHAR
+	int "Character code to substitute unprintable characters with"
+	depends on UNICODE_SUPPORT
+	default 63
+	help
+	  Typical values are 63 for '?' (works with any output device),
+	  30 for ASCII substitute control code,
+	  65533 (0xfffd) for Unicode replacement character.
+
+config LAST_SUPPORTED_WCHAR
+	int "Range of supported Unicode characters"
+	depends on UNICODE_SUPPORT
+	default 767
+	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 UNICODE_COMBINING_WCHARS
+	bool "Allow zero-width Unicode characters on output"
+	default n
+	depends on UNICODE_SUPPORT
+	help
+	  With this option off, any Unicode char with width of 0
+	  is substituted on output.
+
+config UNICODE_WIDE_WCHARS
+	bool "Allow wide Unicode characters on output"
+	default n
+	depends on UNICODE_SUPPORT
+	help
+	  With this option off, any Unicode char with width > 1
+	  is substituted on output.
+
+config UNICODE_BIDI_SUPPORT
+	bool "Bidirectional character-aware line input"
+	default n
+	depends on UNICODE_SUPPORT && !UNICODE_USING_LOCALE
+	help
+	  With this option on, right-to-left Unicode characters
+	  are treated differently on input (e.g. cursor movement).
+
+config UNICODE_NEUTRAL_TABLE
+	bool "In bidi input, support non-ASCII neutral chars too"
+	default n
+	depends on 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 UNICODE_PRESERVE_BROKEN
+	bool "Make it possible to enter sequences of chars which are not Unicode"
+	default n
+	depends on 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 LONG_OPTS
+	bool "Support for --long-options"
+	default y
+	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 FEATURE_DEVPTS
+	bool "Use the devpts filesystem for Unix98 PTYs"
+	default y
+	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 FEATURE_CLEAN_UP
+	bool "Clean up all memory before exiting (usually not needed)"
+	default n
+	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 FEATURE_UTMP
+	bool "Support utmp file"
+	default y
+	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 FEATURE_WTMP
+	bool "Support wtmp file"
+	default y
+	depends on 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 FEATURE_PIDFILE
+	bool "Support writing pidfiles"
+	default y
+	help
+	  This option makes some applets (e.g. crond, syslogd, inetd) write
+	  a pidfile in /var/run. Some applications rely on them.
+
+config FEATURE_SUID
+	bool "Support for SUID/SGID handling"
+	default y
+	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 priviledges 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 FEATURE_SUID_CONFIG
+	bool "Runtime SUID/SGID configuration via /etc/busybox.conf"
+	default y
+	depends on 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 FEATURE_SUID_CONFIG_QUIET
+	bool "Suppress warning message if /etc/busybox.conf is not readable"
+	default y
+	depends on 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 SELINUX
+	bool "Support NSA Security Enhanced Linux"
+	default n
+	select 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. Go visit
+		http://www.nsa.gov/selinux/index.html
+	  to download the necessary stuff to allow busybox to compile with
+	  this option enabled. 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 FEATURE_PREFER_APPLETS
+	bool "exec prefers applets"
+	default n
+	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_EXEC_PATH
+	string "Path to BusyBox executable"
+	default "/proc/self/exe"
+	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 FEATURE_SYSLOG
+	bool #No description makes it a hidden option
+	default n
+	#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 FEATURE_HAVE_RPC
+	bool #No description makes it a hidden option
+	default n
+	#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 STATIC
+	bool "Build BusyBox as a static binary (no shared libs)"
+	default n
+	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 PIE
+	bool "Build BusyBox as a position independent executable"
+	default n
+	depends on !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 NOMMU
+	bool "Force NOMMU build"
+	default n
+	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 BUILD_LIBBUSYBOX
+	bool "Build shared libbusybox"
+	default n
+	depends on !FEATURE_PREFER_APPLETS && !PIE && !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 FEATURE_INDIVIDUAL
+	bool "Produce a binary for each applet, linked against libbusybox"
+	default y
+	depends on 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 FEATURE_SHARED_BUSYBOX
+	bool "Produce additional busybox binary linked against libbusybox"
+	default y
+	depends on 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 LFS
+	bool "Build with Large File Support (for accessing files > 2 GB)"
+	default y
+	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 CROSS_COMPILER_PREFIX
+	string "Cross Compiler prefix"
+	default ""
+	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 EXTRA_CFLAGS
+	string "Additional CFLAGS"
+	default ""
+	help
+	  Additional CFLAGS to pass to the compiler verbatim.
+
+endmenu
+
+menu 'Debugging Options'
+
+config DEBUG
+	bool "Build BusyBox with extra Debugging symbols"
+	default n
+	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 DEBUG_PESSIMIZE
+	bool "Disable compiler optimizations"
+	default n
+	depends on 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 WERROR
+	bool "Abort compilation on any warning"
+	default n
+	help
+	  Selecting this will add -Werror to gcc command line.
+
+	  Most people should answer N.
+
+choice
+	prompt "Additional debugging library"
+	default 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 NO_DEBUG_LIB
+	bool "None"
+
+config DMALLOC
+	bool "Dmalloc"
+
+config EFENCE
+	bool "Electric-fence"
+
+endchoice
+
+endmenu
+
+menu 'Installation Options ("make install" behavior)'
+
+choice
+	prompt "What kind of applet links to install"
+	default INSTALL_APPLET_SYMLINKS
+	help
+	  Choose what kind of links to applets are created by "make install".
+
+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 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 INSTALL_APPLET_SCRIPT_WRAPPERS
+	bool "as script wrappers"
+	help
+	  Install applets as script wrappers that call the busybox binary.
+
+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 INSTALL_SH_APPLET_SYMLINK
+	depends on INSTALL_APPLET_SCRIPT_WRAPPERS
+	help
+	  Choose how you install /bin/sh applet link.
+
+config INSTALL_SH_APPLET_SYMLINK
+	bool "as soft-link"
+	help
+	  Install /bin/sh applet as soft-link to the busybox binary.
+
+config INSTALL_SH_APPLET_HARDLINK
+	bool "as hard-link"
+	help
+	  Install /bin/sh applet as hard-link to the busybox binary.
+
+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 PREFIX
+	string "BusyBox installation prefix"
+	default "./_install"
+	help
+	  Define your directory to install BusyBox files/subdirs in.
+
+endmenu
+
+source libbb/Config.in
+
+endmenu
+
+comment "Applets"
+
+source archival/Config.in
+source coreutils/Config.in
+source console-tools/Config.in
+source debianutils/Config.in
+source editors/Config.in
+source findutils/Config.in
+source init/Config.in
+source loginutils/Config.in
+source e2fsprogs/Config.in
+source modutils/Config.in
+source util-linux/Config.in
+source miscutils/Config.in
+source networking/Config.in
+source printutils/Config.in
+source mailutils/Config.in
+source procps/Config.in
+source runit/Config.in
+source selinux/Config.in
+source shell/Config.in
+source sysklogd/Config.in
diff --git a/busybox-1.19.3/INSTALL b/busybox-1.19.3/INSTALL
new file mode 100644
index 0000000..f93e5fb
--- /dev/null
+++ b/busybox-1.19.3/INSTALL
@@ -0,0 +1,139 @@
+Building:
+=========
+
+The BusyBox build process is similar to the Linux kernel build:
+
+  make menuconfig     # This creates a file called ".config"
+  make                # This creates the "busybox" executable
+  make install        # or make CONFIG_PREFIX=/path/from/root install
+
+The full list of configuration and install options is available by typing:
+
+  make help
+
+Quick Start:
+============
+
+The easy way to try out BusyBox for the first time, without having to install
+it, is to enable all features and then use "standalone shell" mode with a
+blank command $PATH.
+
+To enable all features, use "make defconfig", which produces the largest
+general-purpose configuration.  It's allyesconfig minus debugging options,
+optional packaging choices, and a few special-purpose features requiring
+extra configuration to use.  Then enable "standalone shell" feature:
+
+  make defconfig
+  make menuconfig
+  # select Busybox Settings
+  #   then General Configuration
+  #     then exec prefers applets
+  #   exit back to top level menu
+  #   select Shells
+  #     then Standalone shell
+  #   exit back to top level menu
+  # exit and save new configuration
+  #   OR
+  # use these commands to modify .config directly:
+  sed -e 's/.*FEATURE_PREFER_APPLETS.*/CONFIG_FEATURE_PREFER_APPLETS=y/' -i .config
+  sed -e 's/.*FEATURE_SH_STANDALONE.*/CONFIG_FEATURE_SH_STANDALONE=y/' -i .config
+  make
+  PATH= ./busybox ash
+
+Standalone shell mode causes busybox's built-in command shell to run
+any built-in busybox applets directly, without looking for external
+programs by that name.  Supplying an empty command path (as above) means
+the only commands busybox can find are the built-in ones.
+
+Note that the standalone shell requires CONFIG_BUSYBOX_EXEC_PATH
+to be set appropriately, depending on whether or not /proc/self/exe is
+available or not. If you do not have /proc, then point that config option
+to the location of your busybox binary, usually /bin/busybox.
+
+Configuring Busybox:
+====================
+
+Busybox is optimized for size, but enabling the full set of functionality
+still results in a fairly large executable -- more than 1 megabyte when
+statically linked.  To save space, busybox can be configured with only the
+set of applets needed for each environment.  The minimal configuration, with
+all applets disabled, produces a 4k executable.  (It's useless, but very small.)
+
+The manual configurator "make menuconfig" modifies the existing configuration.
+(For systems without ncurses, try "make config" instead.) The two most
+interesting starting configurations are "make allnoconfig" (to start with
+everything disabled and add just what you need), and "make defconfig" (to
+start with everything enabled and remove what you don't need).  If menuconfig
+is run without an existing configuration, make defconfig will run first to
+create a known starting point.
+
+Other starting configurations (mostly used for testing purposes) include
+"make allbareconfig" (enables all applets but disables all optional features),
+"make allyesconfig" (enables absolutely everything including debug features),
+and "make randconfig" (produce a random configuration).  The configs/ directory
+contains a number of additional configuration files ending in _defconfig which
+are useful in specific cases.  "make help" will list them.
+
+Configuring BusyBox produces a file ".config", which can be saved for future
+use.  Run "make oldconfig" to bring a .config file from an older version of
+busybox up to date.
+
+Installing Busybox:
+===================
+
+Busybox is a single executable that can behave like many different commands,
+and BusyBox uses the name it was invoked under to determine the desired
+behavior.  (Try "mv busybox ls" and then "./ls -l".)
+
+Installing busybox consists of creating symlinks (or hardlinks) to the busybox
+binary for each applet enabled in busybox, and making sure these symlinks are
+in the shell's command $PATH.  Running "make install" creates these symlinks,
+or "make install-hardlinks" creates hardlinks instead (useful on systems with
+a limited number of inodes).  This install process uses the file
+"busybox.links" (created by make), which contains the list of enabled applets
+and the path at which to install them.
+
+Installing links to busybox is not always necessary.  The special applet name
+"busybox" (or with any optional suffix, such as "busybox-static") uses the
+first argument to determine which applet to behave as, for example
+"./busybox cat LICENSE".  (Running the busybox applet with no arguments gives
+a list of all enabled applets.) The standalone shell can also call busybox
+applets without links to busybox under other names in the filesystem.  You can
+also configure a standalone install capability into the busybox base applet,
+and then install such links at runtime with one of "busybox --install" (for
+hardlinks) or "busybox --install -s" (for symlinks).
+
+If you enabled the busybox shared library feature (libbusybox.so) and want
+to run tests without installing, set your LD_LIBRARY_PATH accordingly when
+running the executable:
+
+  LD_LIBRARY_PATH=`pwd` ./busybox
+
+Building out-of-tree:
+=====================
+
+By default, the BusyBox build puts its temporary files in the source tree.
+Building from a read-only source tree, or building multiple configurations from
+the same source directory, requires the ability to put the temporary files
+somewhere else.
+
+To build out of tree, cd to an empty directory and configure busybox from there:
+
+  make KBUILD_SRC=/path/to/source -f /path/to/source/Makefile defconfig
+  make
+  make install
+
+Alternately, use the O=$BUILDPATH option (with an absolute path) during the
+configuration step, as in:
+
+  make O=/some/empty/directory allyesconfig
+  cd /some/empty/directory
+  make
+  make CONFIG_PREFIX=. install
+
+More Information:
+=================
+
+Se also the busybox FAQ, under the questions "How can I get started using
+BusyBox" and "How do I build a BusyBox-based system?"  The BusyBox FAQ is
+available from http://www.busybox.net/FAQ.html
diff --git a/busybox-1.19.3/LICENSE b/busybox-1.19.3/LICENSE
new file mode 100644
index 0000000..6f50a71
--- /dev/null
+++ b/busybox-1.19.3/LICENSE
@@ -0,0 +1,348 @@
+--- A note on GPL versions
+
+BusyBox is distributed under version 2 of the General Public License (included
+in its entirety, below).  Version 2 is the only version of this license which
+this version of BusyBox (or modified versions derived from this one) may be
+distributed under.
+
+------------------------------------------------------------------------
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/busybox-1.19.3/Makefile b/busybox-1.19.3/Makefile
new file mode 100644
index 0000000..9648c9c
--- /dev/null
+++ b/busybox-1.19.3/Makefile
@@ -0,0 +1,1341 @@
+VERSION = 1
+PATCHLEVEL = 19
+SUBLEVEL = 3
+EXTRAVERSION =
+NAME = Unnamed
+
+# *DOCUMENTATION*
+# To see a list of typical targets execute "make help"
+# More info can be located in ./README
+# Comments in this file are targeted only to the developer, do not
+# expect to learn how to build the kernel reading this file.
+
+# Do not print "Entering directory ..."
+MAKEFLAGS += --no-print-directory
+
+# We are using a recursive build, so we need to do a little thinking
+# to get the ordering right.
+#
+# Most importantly: sub-Makefiles should only ever modify files in
+# their own directory. If in some directory we have a dependency on
+# a file in another dir (which doesn't happen often, but it's often
+# unavoidable when linking the built-in.o targets which finally
+# turn into busybox), we will call a sub make in that other dir, and
+# after that we are sure that everything which is in that other dir
+# is now up to date.
+#
+# The only cases where we need to modify files which have global
+# effects are thus separated out and done before the recursive
+# descending is started. They are now explicitly listed as the
+# prepare rule.
+
+# To put more focus on warnings, be less verbose as default
+# Use 'make V=1' to see the full commands
+
+ifdef V
+  ifeq ("$(origin V)", "command line")
+    KBUILD_VERBOSE = $(V)
+  endif
+endif
+ifndef KBUILD_VERBOSE
+  KBUILD_VERBOSE = 0
+endif
+
+# Call sparse as part of compilation of C files
+# Use 'make C=1' to enable sparse checking
+
+ifdef C
+  ifeq ("$(origin C)", "command line")
+    KBUILD_CHECKSRC = $(C)
+  endif
+endif
+ifndef KBUILD_CHECKSRC
+  KBUILD_CHECKSRC = 0
+endif
+
+# Use make M=dir to specify directory of external module to build
+# Old syntax make ... SUBDIRS=$PWD is still supported
+# Setting the environment variable KBUILD_EXTMOD take precedence
+ifdef SUBDIRS
+  KBUILD_EXTMOD ?= $(SUBDIRS)
+endif
+ifdef M
+  ifeq ("$(origin M)", "command line")
+    KBUILD_EXTMOD := $(M)
+  endif
+endif
+
+
+# kbuild supports saving output files in a separate directory.
+# To locate output files in a separate directory two syntaxes are supported.
+# In both cases the working directory must be the root of the kernel src.
+# 1) O=
+# Use "make O=dir/to/store/output/files/"
+#
+# 2) Set KBUILD_OUTPUT
+# Set the environment variable KBUILD_OUTPUT to point to the directory
+# where the output files shall be placed.
+# export KBUILD_OUTPUT=dir/to/store/output/files/
+# make
+#
+# The O= assignment takes precedence over the KBUILD_OUTPUT environment
+# variable.
+
+
+# KBUILD_SRC is set on invocation of make in OBJ directory
+# KBUILD_SRC is not intended to be used by the regular user (for now)
+ifeq ($(KBUILD_SRC),)
+
+# OK, Make called in directory where kernel src resides
+# Do we want to locate output files in a separate directory?
+ifdef O
+  ifeq ("$(origin O)", "command line")
+    KBUILD_OUTPUT := $(O)
+  endif
+endif
+
+# That's our default target when none is given on the command line
+PHONY := _all
+_all:
+
+ifneq ($(KBUILD_OUTPUT),)
+# Invoke a second make in the output directory, passing relevant variables
+# check that the output directory actually exists
+saved-output := $(KBUILD_OUTPUT)
+KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd)
+$(if $(KBUILD_OUTPUT),, \
+     $(error output directory "$(saved-output)" does not exist))
+
+PHONY += $(MAKECMDGOALS)
+
+$(filter-out _all,$(MAKECMDGOALS)) _all:
+	$(if $(KBUILD_VERBOSE:1=),@)$(MAKE) -C $(KBUILD_OUTPUT) \
+	KBUILD_SRC=$(CURDIR) \
+	KBUILD_EXTMOD="$(KBUILD_EXTMOD)" -f $(CURDIR)/Makefile $@
+
+# Leave processing to above invocation of make
+skip-makefile := 1
+endif # ifneq ($(KBUILD_OUTPUT),)
+endif # ifeq ($(KBUILD_SRC),)
+
+# We process the rest of the Makefile if this is the final invocation of make
+ifeq ($(skip-makefile),)
+
+# If building an external module we do not care about the all: rule
+# but instead _all depend on modules
+PHONY += all
+ifeq ($(KBUILD_EXTMOD),)
+_all: all
+else
+_all: modules
+endif
+
+srctree		:= $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR))
+TOPDIR		:= $(srctree)
+# FIXME - TOPDIR is obsolete, use srctree/objtree
+objtree		:= $(CURDIR)
+src		:= $(srctree)
+obj		:= $(objtree)
+
+VPATH		:= $(srctree)$(if $(KBUILD_EXTMOD),:$(KBUILD_EXTMOD))
+
+export srctree objtree VPATH TOPDIR
+
+
+# Cross compiling and selecting different set of gcc/bin-utils
+# ---------------------------------------------------------------------------
+#
+# When performing cross compilation for other architectures ARCH shall be set
+# to the target architecture. (See arch/* for the possibilities).
+# ARCH can be set during invocation of make:
+# make ARCH=ia64
+# Another way is to have ARCH set in the environment.
+# The default ARCH is the host where make is executed.
+
+# CROSS_COMPILE specify the prefix used for all executables used
+# during compilation. Only gcc and related bin-utils executables
+# are prefixed with $(CROSS_COMPILE).
+# CROSS_COMPILE can be set on the command line
+# make CROSS_COMPILE=ia64-linux-
+# Alternatively CROSS_COMPILE can be set in the environment.
+# Default value for CROSS_COMPILE is not to prefix executables
+# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
+
+CROSS_COMPILE ?=
+# bbox: we may have CONFIG_CROSS_COMPILER_PREFIX in .config,
+# and it has not been included yet... thus using an awkward syntax.
+ifeq ($(CROSS_COMPILE),)
+CROSS_COMPILE := $(shell grep ^CONFIG_CROSS_COMPILER_PREFIX .config 2>/dev/null)
+CROSS_COMPILE := $(subst CONFIG_CROSS_COMPILER_PREFIX=,,$(CROSS_COMPILE))
+CROSS_COMPILE := $(subst ",,$(CROSS_COMPILE))
+#")
+endif
+
+# SUBARCH tells the usermode build what the underlying arch is.  That is set
+# first, and if a usermode build is happening, the "ARCH=um" on the command
+# line overrides the setting of ARCH below.  If a native build is happening,
+# then ARCH is assigned, getting whatever value it gets normally, and
+# SUBARCH is subsequently ignored.
+
+ifneq ($(CROSS_COMPILE),)
+SUBARCH := $(shell echo $(CROSS_COMPILE) | cut -d- -f1)
+else
+SUBARCH := $(shell uname -m)
+endif
+SUBARCH := $(shell echo $(SUBARCH) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
+					 -e s/arm.*/arm/ -e s/sa110/arm/ \
+					 -e s/s390x/s390/ -e s/parisc64/parisc/ \
+					 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ )
+
+ARCH ?= $(SUBARCH)
+
+# Architecture as present in compile.h
+UTS_MACHINE := $(ARCH)
+
+# SHELL used by kbuild
+CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \
+	  else if [ -x /bin/bash ]; then echo /bin/bash; \
+	  else echo sh; fi ; fi)
+
+# 	Decide whether to build built-in, modular, or both.
+#	Normally, just do built-in.
+
+KBUILD_MODULES :=
+KBUILD_BUILTIN := 1
+
+#	If we have only "make modules", don't compile built-in objects.
+#	When we're building modules with modversions, we need to consider
+#	the built-in objects during the descend as well, in order to
+#	make sure the checksums are uptodate before we record them.
+
+ifeq ($(MAKECMDGOALS),modules)
+  KBUILD_BUILTIN := $(if $(CONFIG_MODVERSIONS),1)
+endif
+
+#	If we have "make <whatever> modules", compile modules
+#	in addition to whatever we do anyway.
+#	Just "make" or "make all" shall build modules as well
+
+ifneq ($(filter all _all modules,$(MAKECMDGOALS)),)
+  KBUILD_MODULES := 1
+endif
+
+ifeq ($(MAKECMDGOALS),)
+  KBUILD_MODULES := 1
+endif
+
+export KBUILD_MODULES KBUILD_BUILTIN
+export KBUILD_CHECKSRC KBUILD_SRC KBUILD_EXTMOD
+
+# Beautify output
+# ---------------------------------------------------------------------------
+#
+# Normally, we echo the whole command before executing it. By making
+# that echo $($(quiet)$(cmd)), we now have the possibility to set
+# $(quiet) to choose other forms of output instead, e.g.
+#
+#         quiet_cmd_cc_o_c = Compiling $(RELDIR)/$@
+#         cmd_cc_o_c       = $(CC) $(c_flags) -c -o $@ $<
+#
+# If $(quiet) is empty, the whole command will be printed.
+# If it is set to "quiet_", only the short version will be printed.
+# If it is set to "silent_", nothing wil be printed at all, since
+# the variable $(silent_cmd_cc_o_c) doesn't exist.
+#
+# A simple variant is to prefix commands with $(Q) - that's useful
+# for commands that shall be hidden in non-verbose mode.
+#
+#	$(Q)ln $@ :<
+#
+# If KBUILD_VERBOSE equals 0 then the above command will be hidden.
+# If KBUILD_VERBOSE equals 1 then the above command is displayed.
+
+ifeq ($(KBUILD_VERBOSE),1)
+  quiet =
+  Q =
+else
+  quiet=quiet_
+  Q = @
+endif
+
+# If the user is running make -s (silent mode), suppress echoing of
+# commands
+
+ifneq ($(findstring s,$(MAKEFLAGS)),)
+  quiet=silent_
+endif
+
+export quiet Q KBUILD_VERBOSE
+
+
+# Look for make include files relative to root of kernel src
+MAKEFLAGS += --include-dir=$(srctree)
+
+HOSTCC  	= gcc
+HOSTCXX  	= g++
+HOSTCFLAGS	:=
+HOSTCXXFLAGS	:=
+# We need some generic definitions
+include $(srctree)/scripts/Kbuild.include
+
+HOSTCFLAGS	+= $(call hostcc-option,-Wall -Wstrict-prototypes -O2 -fomit-frame-pointer,)
+HOSTCXXFLAGS	+= -O2
+
+# For maximum performance (+ possibly random breakage, uncomment
+# the following)
+
+MAKEFLAGS += -rR
+
+# Make variables (CC, etc...)
+
+AS		= $(CROSS_COMPILE)as
+CC		= $(CROSS_COMPILE)gcc
+LD		= $(CC) -nostdlib
+CPP		= $(CC) -E
+AR		= $(CROSS_COMPILE)ar
+NM		= $(CROSS_COMPILE)nm
+STRIP		= $(CROSS_COMPILE)strip
+OBJCOPY		= $(CROSS_COMPILE)objcopy
+OBJDUMP		= $(CROSS_COMPILE)objdump
+AWK		= awk
+GENKSYMS	= scripts/genksyms/genksyms
+DEPMOD		= /sbin/depmod
+KALLSYMS	= scripts/kallsyms
+PERL		= perl
+CHECK		= sparse
+
+CHECKFLAGS     := -D__linux__ -Dlinux -D__STDC__ -Dunix -D__unix__ -Wbitwise $(CF)
+MODFLAGS	= -DMODULE
+CFLAGS_MODULE   = $(MODFLAGS)
+AFLAGS_MODULE   = $(MODFLAGS)
+LDFLAGS_MODULE  = -r
+CFLAGS_KERNEL	=
+AFLAGS_KERNEL	=
+
+
+# Use LINUXINCLUDE when you must reference the include/ directory.
+# Needed to be compatible with the O= option
+CFLAGS		:= $(CFLAGS)
+# Added only to final link stage of busybox binary
+CFLAGS_busybox	:= $(CFLAGS_busybox)
+CPPFLAGS	:= $(CPPFLAGS)
+AFLAGS		:= $(AFLAGS)
+LDFLAGS		:= $(LDFLAGS)
+LDLIBS		:=
+
+# Read KERNELRELEASE from .kernelrelease (if it exists)
+KERNELRELEASE = $(shell cat .kernelrelease 2> /dev/null)
+KERNELVERSION = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+
+export	VERSION PATCHLEVEL SUBLEVEL KERNELRELEASE KERNELVERSION \
+	ARCH CONFIG_SHELL HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \
+	CPP AR NM STRIP OBJCOPY OBJDUMP MAKE AWK GENKSYMS PERL UTS_MACHINE \
+	HOSTCXX HOSTCXXFLAGS LDFLAGS_MODULE CHECK CHECKFLAGS
+
+export CPPFLAGS NOSTDINC_FLAGS LINUXINCLUDE OBJCOPYFLAGS LDFLAGS
+export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
+export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
+export FLTFLAGS
+
+# When compiling out-of-tree modules, put MODVERDIR in the module
+# tree rather than in the kernel tree. The kernel tree might
+# even be read-only.
+export MODVERDIR := $(if $(KBUILD_EXTMOD),$(firstword $(KBUILD_EXTMOD))/).tmp_versions
+
+# Files to ignore in find ... statements
+
+RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS -o -name .pc -o -name .hg -o -name .git \) -prune -o
+export RCS_TAR_IGNORE := --exclude SCCS --exclude BitKeeper --exclude .svn --exclude CVS --exclude .pc --exclude .hg --exclude .git
+
+# ===========================================================================
+# Rules shared between *config targets and build targets
+
+# Basic helpers built in scripts/
+PHONY += scripts_basic
+scripts_basic:
+	$(Q)$(MAKE) $(build)=scripts/basic
+
+# To avoid any implicit rule to kick in, define an empty command.
+scripts/basic/%: scripts_basic ;
+
+# This target generates Kbuild's and Config.in's from *.c files
+PHONY += gen_build_files
+gen_build_files: $(wildcard $(srctree)/*/*.c) $(wildcard $(srctree)/*/*/*.c)
+	$(Q)$(srctree)/scripts/gen_build_files.sh $(srctree) $(objtree)
+
+# bbox: we have helpers in applets/
+# we depend on scripts_basic, since scripts/basic/fixdep
+# must be built before any other host prog
+PHONY += applets_dir
+applets_dir: scripts_basic gen_build_files
+	$(Q)$(MAKE) $(build)=applets
+
+applets/%: applets_dir ;
+
+PHONY += outputmakefile
+# outputmakefile generates a Makefile in the output directory, if using a
+# separate output directory. This allows convenient use of make in the
+# output directory.
+outputmakefile:
+ifneq ($(KBUILD_SRC),)
+	$(Q)$(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \
+	    $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL)
+endif
+
+# To make sure we do not include .config for any of the *config targets
+# catch them early, and hand them over to scripts/kconfig/Makefile
+# It is allowed to specify more targets when calling make, including
+# mixing *config targets and build targets.
+# For example 'make oldconfig all'.
+# Detect when mixed targets is specified, and make a second invocation
+# of make so .config is not included in this case either (for *config).
+
+no-dot-config-targets := clean mrproper distclean \
+			 cscope TAGS tags help %docs
+#bbox# check% is removed from above
+
+config-targets := 0
+mixed-targets  := 0
+dot-config     := 1
+
+ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),)
+	ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),)
+		dot-config := 0
+	endif
+endif
+
+ifeq ($(KBUILD_EXTMOD),)
+        ifneq ($(filter config %config,$(MAKECMDGOALS)),)
+                config-targets := 1
+                ifneq ($(filter-out config %config,$(MAKECMDGOALS)),)
+                        mixed-targets := 1
+                endif
+        endif
+endif
+
+ifeq ($(mixed-targets),1)
+# ===========================================================================
+# We're called with mixed targets (*config and build targets).
+# Handle them one by one.
+
+%:: FORCE
+	$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= $@
+
+else
+ifeq ($(config-targets),1)
+# ===========================================================================
+# *config targets only - make sure prerequisites are updated, and descend
+# in scripts/kconfig to make the *config target
+
+# Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
+# KBUILD_DEFCONFIG may point out an alternative default configuration
+# used for 'make defconfig'
+-include $(srctree)/arch/$(ARCH)/Makefile
+export KBUILD_DEFCONFIG
+
+config: scripts_basic outputmakefile gen_build_files FORCE
+	$(Q)mkdir -p include
+	$(Q)$(MAKE) $(build)=scripts/kconfig $@
+	$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease
+
+%config: scripts_basic outputmakefile gen_build_files FORCE
+	$(Q)mkdir -p include
+	$(Q)$(MAKE) $(build)=scripts/kconfig $@
+	$(Q)$(MAKE) -C $(srctree) KBUILD_SRC= .kernelrelease
+
+else
+# ===========================================================================
+# Build targets only - this includes busybox, arch specific targets, clean
+# targets and others. In general all targets except *config targets.
+
+ifeq ($(KBUILD_EXTMOD),)
+# Additional helpers built in scripts/
+# Carefully list dependencies so we do not try to build scripts twice
+# in parallel
+PHONY += scripts
+scripts: gen_build_files scripts_basic include/config/MARKER
+	$(Q)$(MAKE) $(build)=$(@)
+
+scripts_basic: include/autoconf.h
+
+# Objects we will link into busybox / subdirs we need to visit
+core-y		:= \
+		applets/ \
+
+libs-y		:= \
+		archival/ \
+		archival/libarchive/ \
+		console-tools/ \
+		coreutils/ \
+		coreutils/libcoreutils/ \
+		debianutils/ \
+		e2fsprogs/ \
+		editors/ \
+		findutils/ \
+		init/ \
+		libbb/ \
+		libpwdgrp/ \
+		loginutils/ \
+		mailutils/ \
+		miscutils/ \
+		modutils/ \
+		networking/ \
+		networking/libiproute/ \
+		networking/udhcp/ \
+		printutils/ \
+		procps/ \
+		runit/ \
+		selinux/ \
+		shell/ \
+		sysklogd/ \
+		util-linux/ \
+		util-linux/volume_id/ \
+
+endif # KBUILD_EXTMOD
+
+ifeq ($(dot-config),1)
+# In this section, we need .config
+
+# Read in dependencies to all Kconfig* files, make sure to run
+# oldconfig if changes are detected.
+-include .kconfig.d
+
+-include .config
+
+# If .config needs to be updated, it will be done via the dependency
+# that autoconf has on .config.
+# To avoid any implicit rule to kick in, define an empty command
+.config .kconfig.d: ;
+
+# Now we can define CFLAGS etc according to .config
+include $(srctree)/Makefile.flags
+
+# If .config is newer than include/autoconf.h, someone tinkered
+# with it and forgot to run make oldconfig.
+# If kconfig.d is missing then we are probarly in a cleaned tree so
+# we execute the config step to be sure to catch updated Kconfig files
+include/autoconf.h: .kconfig.d .config $(wildcard $(srctree)/*/*.c) $(wildcard $(srctree)/*/*/*.c) | gen_build_files
+	$(Q)$(MAKE) -f $(srctree)/Makefile silentoldconfig
+
+include/usage.h: gen_build_files
+
+else
+# Dummy target needed, because used as prerequisite
+include/autoconf.h: ;
+endif
+
+# The all: target is the default when no target is given on the
+# command line.
+# This allow a user to issue only 'make' to build a kernel including modules
+# Defaults busybox but it is usually overridden in the arch makefile
+all: busybox doc
+
+-include $(srctree)/arch/$(ARCH)/Makefile
+
+# arch Makefile may override CC so keep this after arch Makefile is included
+#bbox# NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include)
+CHECKFLAGS += $(NOSTDINC_FLAGS)
+
+# Default kernel image to build when no specific target is given.
+# KBUILD_IMAGE may be overruled on the commandline or
+# set in the environment
+# Also any assignments in arch/$(ARCH)/Makefile take precedence over
+# this default value
+export KBUILD_IMAGE ?= busybox
+
+#
+# INSTALL_PATH specifies where to place the updated kernel and system map
+# images. Default is /boot, but you can set it to other values
+export	INSTALL_PATH ?= /boot
+
+#
+# INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory
+# relocations required by build roots.  This is not defined in the
+# makefile but the arguement can be passed to make if needed.
+#
+
+MODLIB	= $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)
+export MODLIB
+
+
+ifeq ($(KBUILD_EXTMOD),)
+busybox-dirs	:= $(patsubst %/,%,$(filter %/, $(core-y) $(core-m) $(libs-y) $(libs-m)))
+
+busybox-alldirs	:= $(sort $(busybox-dirs) $(patsubst %/,%,$(filter %/, \
+		     $(core-n) $(core-) $(libs-n) $(libs-) \
+		)))
+
+core-y		:= $(patsubst %/, %/built-in.o, $(core-y))
+libs-y1		:= $(patsubst %/, %/lib.a, $(libs-y))
+libs-y2		:= $(patsubst %/, %/built-in.o, $(libs-y))
+libs-y		:= $(libs-y1) $(libs-y2)
+
+# Build busybox
+# ---------------------------------------------------------------------------
+# busybox is build from the objects selected by $(busybox-init) and
+# $(busybox-main). Most are built-in.o files from top-level directories
+# in the kernel tree, others are specified in arch/$(ARCH)Makefile.
+# Ordering when linking is important, and $(busybox-init) must be first.
+#
+# busybox
+#   ^
+#   |
+#   +-< $(busybox-init)
+#   |   +--< init/version.o + more
+#   |
+#   +--< $(busybox-main)
+#   |    +--< driver/built-in.o mm/built-in.o + more
+#   |
+#   +-< kallsyms.o (see description in CONFIG_KALLSYMS section)
+#
+# busybox version (uname -v) cannot be updated during normal
+# descending-into-subdirs phase since we do not yet know if we need to
+# update busybox.
+# Therefore this step is delayed until just before final link of busybox -
+# except in the kallsyms case where it is done just before adding the
+# symbols to the kernel.
+#
+# System.map is generated to document addresses of all kernel symbols
+
+busybox-all  := $(core-y) $(libs-y)
+
+# Rule to link busybox - also used during CONFIG_KALLSYMS
+# May be overridden by arch/$(ARCH)/Makefile
+quiet_cmd_busybox__ ?= LINK    $@
+      cmd_busybox__ ?= $(srctree)/scripts/trylink \
+      "$@" \
+      "$(CC)" \
+      "$(CFLAGS) $(CFLAGS_busybox)" \
+      "$(LDFLAGS) $(EXTRA_LDFLAGS)" \
+      "$(core-y)" \
+      "$(libs-y)" \
+      "$(LDLIBS)"
+
+# Generate System.map
+quiet_cmd_sysmap = SYSMAP
+      cmd_sysmap = $(CONFIG_SHELL) $(srctree)/scripts/mksysmap
+
+# Link of busybox
+# If CONFIG_KALLSYMS is set .version is already updated
+# Generate System.map and verify that the content is consistent
+# Use + in front of the busybox_version rule to silent warning with make -j2
+# First command is ':' to allow us to use + in front of the rule
+define rule_busybox__
+	:
+	$(call cmd,busybox__)
+	$(Q)echo 'cmd_$@ := $(cmd_busybox__)' > $(@D)/.$(@F).cmd
+endef
+
+
+ifdef CONFIG_KALLSYMS
+# Generate section listing all symbols and add it into busybox $(kallsyms.o)
+# It's a three stage process:
+# o .tmp_busybox1 has all symbols and sections, but __kallsyms is
+#   empty
+#   Running kallsyms on that gives us .tmp_kallsyms1.o with
+#   the right size - busybox version (uname -v) is updated during this step
+# o .tmp_busybox2 now has a __kallsyms section of the right size,
+#   but due to the added section, some addresses have shifted.
+#   From here, we generate a correct .tmp_kallsyms2.o
+# o The correct .tmp_kallsyms2.o is linked into the final busybox.
+# o Verify that the System.map from busybox matches the map from
+#   .tmp_busybox2, just in case we did not generate kallsyms correctly.
+# o If CONFIG_KALLSYMS_EXTRA_PASS is set, do an extra pass using
+#   .tmp_busybox3 and .tmp_kallsyms3.o.  This is only meant as a
+#   temporary bypass to allow the kernel to be built while the
+#   maintainers work out what went wrong with kallsyms.
+
+ifdef CONFIG_KALLSYMS_EXTRA_PASS
+last_kallsyms := 3
+else
+last_kallsyms := 2
+endif
+
+kallsyms.o := .tmp_kallsyms$(last_kallsyms).o
+
+define verify_kallsyms
+	$(Q)$(if $($(quiet)cmd_sysmap),                       \
+	  echo '  $($(quiet)cmd_sysmap) .tmp_System.map' &&)  \
+	  $(cmd_sysmap) .tmp_busybox$(last_kallsyms) .tmp_System.map
+	$(Q)cmp -s System.map .tmp_System.map ||              \
+		(echo Inconsistent kallsyms data;             \
+		 echo Try setting CONFIG_KALLSYMS_EXTRA_PASS; \
+		 rm .tmp_kallsyms* ; /bin/false )
+endef
+
+# Update busybox version before link
+# Use + in front of this rule to silent warning about make -j1
+# First command is ':' to allow us to use + in front of this rule
+cmd_ksym_ld = $(cmd_busybox__)
+define rule_ksym_ld
+	:
+	+$(call cmd,busybox_version)
+	$(call cmd,busybox__)
+	$(Q)echo 'cmd_$@ := $(cmd_busybox__)' > $(@D)/.$(@F).cmd
+endef
+
+# Generate .S file with all kernel symbols
+quiet_cmd_kallsyms = KSYM    $@
+      cmd_kallsyms = $(NM) -n $< | $(KALLSYMS) \
+                     $(if $(CONFIG_KALLSYMS_ALL),--all-symbols) > $@
+
+.tmp_kallsyms1.o .tmp_kallsyms2.o .tmp_kallsyms3.o: %.o: %.S scripts FORCE
+	$(call if_changed_dep,as_o_S)
+
+.tmp_kallsyms%.S: .tmp_busybox% $(KALLSYMS)
+	$(call cmd,kallsyms)
+
+# .tmp_busybox1 must be complete except kallsyms, so update busybox version
+.tmp_busybox1: $(busybox-lds) $(busybox-all) FORCE
+	$(call if_changed_rule,ksym_ld)
+
+.tmp_busybox2: $(busybox-lds) $(busybox-all) .tmp_kallsyms1.o FORCE
+	$(call if_changed,busybox__)
+
+.tmp_busybox3: $(busybox-lds) $(busybox-all) .tmp_kallsyms2.o FORCE
+	$(call if_changed,busybox__)
+
+# Needs to visit scripts/ before $(KALLSYMS) can be used.
+$(KALLSYMS): scripts ;
+
+# Generate some data for debugging strange kallsyms problems
+debug_kallsyms: .tmp_map$(last_kallsyms)
+
+.tmp_map%: .tmp_busybox% FORCE
+	($(OBJDUMP) -h $< | $(AWK) '/^ +[0-9]/{print $$4 " 0 " $$2}'; $(NM) $<) | sort > $@
+
+.tmp_map3: .tmp_map2
+
+.tmp_map2: .tmp_map1
+
+endif # ifdef CONFIG_KALLSYMS
+
+# busybox image - including updated kernel symbols
+busybox_unstripped: $(busybox-all) FORCE
+	$(call if_changed_rule,busybox__)
+	$(Q)rm -f .old_version
+
+busybox: busybox_unstripped
+ifeq ($(SKIP_STRIP),y)
+	$(Q)cp $< $@
+else
+	$(Q)$(STRIP) -s --remove-section=.note --remove-section=.comment \
+		busybox_unstripped -o $@
+# strip is confused by PIE executable and does not set exec bits
+	$(Q)chmod a+x $@
+endif
+
+# The actual objects are generated when descending,
+# make sure no implicit rule kicks in
+$(sort $(busybox-all)): $(busybox-dirs) ;
+
+# Handle descending into subdirectories listed in $(busybox-dirs)
+# Preset locale variables to speed up the build process. Limit locale
+# tweaks to this spot to avoid wrong language settings when running
+# make menuconfig etc.
+# Error messages still appears in the original language
+
+PHONY += $(busybox-dirs)
+$(busybox-dirs): prepare scripts
+	$(Q)$(MAKE) $(build)=$@
+
+# Build the kernel release string
+# The KERNELRELEASE is stored in a file named .kernelrelease
+# to be used when executing for example make install or make modules_install
+#
+# Take the contents of any files called localversion* and the config
+# variable CONFIG_LOCALVERSION and append them to KERNELRELEASE.
+# LOCALVERSION from the command line override all of this
+
+nullstring :=
+space      := $(nullstring) # end of line
+
+___localver = $(objtree)/localversion* $(srctree)/localversion*
+__localver  = $(sort $(wildcard $(___localver)))
+# skip backup files (containing '~')
+_localver = $(foreach f, $(__localver), $(if $(findstring ~, $(f)),,$(f)))
+
+localver = $(subst $(space),, \
+	   $(shell cat /dev/null $(_localver)) \
+	   $(patsubst "%",%,$(CONFIG_LOCALVERSION)))
+
+# If CONFIG_LOCALVERSION_AUTO is set scripts/setlocalversion is called
+# and if the SCM is know a tag from the SCM is appended.
+# The appended tag is determinded by the SCM used.
+#
+# Currently, only git is supported.
+# Other SCMs can edit scripts/setlocalversion and add the appropriate
+# checks as needed.
+ifdef _BB_DISABLED_CONFIG_LOCALVERSION_AUTO
+	_localver-auto = $(shell $(CONFIG_SHELL) \
+	                  $(srctree)/scripts/setlocalversion $(srctree))
+	localver-auto  = $(LOCALVERSION)$(_localver-auto)
+endif
+
+localver-full = $(localver)$(localver-auto)
+
+# Store (new) KERNELRELASE string in .kernelrelease
+kernelrelease = $(KERNELVERSION)$(localver-full)
+.kernelrelease: FORCE
+	$(Q)rm -f $@
+	$(Q)echo $(kernelrelease) > $@
+
+
+# Things we need to do before we recursively start building the kernel
+# or the modules are listed in "prepare".
+# A multi level approach is used. prepareN is processed before prepareN-1.
+# archprepare is used in arch Makefiles and when processed asm symlink,
+# version.h and scripts_basic is processed / created.
+
+# Listed in dependency order
+PHONY += prepare archprepare prepare0 prepare1 prepare2 prepare3
+
+# prepare-all is deprecated, use prepare as valid replacement
+PHONY += prepare-all
+
+# prepare3 is used to check if we are building in a separate output directory,
+# and if so do:
+# 1) Check that make has not been executed in the kernel src $(srctree)
+# 2) Create the include2 directory, used for the second asm symlink
+prepare3: .kernelrelease
+ifneq ($(KBUILD_SRC),)
+	@echo '  Using $(srctree) as source for busybox'
+	$(Q)if [ -f $(srctree)/.config ]; then \
+		echo "  $(srctree) is not clean, please run 'make mrproper'";\
+		echo "  in the '$(srctree)' directory.";\
+		/bin/false; \
+	fi;
+	$(Q)if [ ! -d include2 ]; then mkdir -p include2; fi;
+	$(Q)ln -fsn $(srctree)/include/asm-$(ARCH) include2/asm
+endif
+
+# prepare2 creates a makefile if using a separate output directory
+prepare2: prepare3 outputmakefile
+
+prepare1: prepare2 include/config/MARKER
+ifneq ($(KBUILD_MODULES),)
+	$(Q)mkdir -p $(MODVERDIR)
+	$(Q)rm -f $(MODVERDIR)/*
+endif
+
+archprepare: prepare1 scripts_basic applets_dir
+
+prepare0: archprepare FORCE
+	$(Q)$(MAKE) $(build)=.
+
+# All the preparing..
+prepare prepare-all: prepare0
+
+#	Leave this as default for preprocessing busybox.lds.S, which is now
+#	done in arch/$(ARCH)/kernel/Makefile
+
+export CPPFLAGS_busybox.lds += -P -C -U$(ARCH)
+
+# 	FIXME: The asm symlink changes when $(ARCH) changes. That's
+#	hard to detect, but I suppose "make mrproper" is a good idea
+#	before switching between archs anyway.
+
+#bbox# include/asm:
+#bbox# 	@echo '  SYMLINK $@ -> include/asm-$(ARCH)'
+#bbox# 	$(Q)if [ ! -d include ]; then mkdir -p include; fi;
+#bbox# 	@ln -fsn asm-$(ARCH) $@
+
+# 	Split autoconf.h into include/linux/config/*
+quiet_cmd_gen_bbconfigopts = GEN     include/bbconfigopts.h
+      cmd_gen_bbconfigopts = $(srctree)/scripts/mkconfigs include/bbconfigopts.h include/bbconfigopts_bz2.h
+quiet_cmd_split_autoconf   = SPLIT   include/autoconf.h -> include/config/*
+      cmd_split_autoconf   = scripts/basic/split-include include/autoconf.h include/config
+#bbox# piggybacked generation of few .h files
+include/config/MARKER: scripts/basic/split-include include/autoconf.h
+	$(call cmd,split_autoconf)
+	$(call cmd,gen_bbconfigopts)
+	@touch $@
+
+# Generate some files
+# ---------------------------------------------------------------------------
+
+# KERNELRELEASE can change from a few different places, meaning version.h
+# needs to be updated, so this check is forced on all builds
+
+uts_len := 64
+
+define filechk_version.h
+	if [ `echo -n "$(KERNELRELEASE)" | wc -c ` -gt $(uts_len) ]; then \
+	  echo '"$(KERNELRELEASE)" exceeds $(uts_len) characters' >&2; \
+	  exit 1; \
+	fi; \
+	(echo \#define UTS_RELEASE \"$(KERNELRELEASE)\"; \
+	  echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)`; \
+	 echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))'; \
+	)
+endef
+
+# ---------------------------------------------------------------------------
+
+PHONY += depend dep
+depend dep:
+	@echo '*** Warning: make $@ is unnecessary now.'
+
+# ---------------------------------------------------------------------------
+# Modules
+
+ifdef _BB_DISABLED_CONFIG_MODULES
+
+# 	By default, build modules as well
+
+all: modules
+
+#	Build modules
+
+PHONY += modules
+modules: $(busybox-dirs) $(if $(KBUILD_BUILTIN),busybox)
+	@echo '  Building modules, stage 2.';
+	$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
+
+
+# Target to prepare building external modules
+PHONY += modules_prepare
+modules_prepare: prepare scripts
+
+# Target to install modules
+PHONY += modules_install
+modules_install: _modinst_ _modinst_post
+
+PHONY += _modinst_
+_modinst_:
+	@if [ -z "`$(DEPMOD) -V 2>/dev/null | grep module-init-tools`" ]; then \
+		echo "Warning: you may need to install module-init-tools"; \
+		echo "See http://www.codemonkey.org.uk/docs/post-halloween-2.6.txt";\
+		sleep 1; \
+	fi
+	@rm -rf $(MODLIB)/kernel
+	@rm -f $(MODLIB)/source
+	@mkdir -p $(MODLIB)/kernel
+	@ln -s $(srctree) $(MODLIB)/source
+	@if [ ! $(objtree) -ef  $(MODLIB)/build ]; then \
+		rm -f $(MODLIB)/build ; \
+		ln -s $(objtree) $(MODLIB)/build ; \
+	fi
+	$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst
+
+# If System.map exists, run depmod.  This deliberately does not have a
+# dependency on System.map since that would run the dependency tree on
+# busybox.  This depmod is only for convenience to give the initial
+# boot a modules.dep even before / is mounted read-write.  However the
+# boot script depmod is the master version.
+ifeq "$(strip $(INSTALL_MOD_PATH))" ""
+depmod_opts	:=
+else
+depmod_opts	:= -b $(INSTALL_MOD_PATH) -r
+endif
+PHONY += _modinst_post
+_modinst_post: _modinst_
+	if [ -r System.map -a -x $(DEPMOD) ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
+
+else # CONFIG_MODULES
+
+# Modules not configured
+# ---------------------------------------------------------------------------
+
+modules modules_install: FORCE
+	@echo
+	@echo "The present busybox configuration has modules disabled."
+	@echo "Type 'make config' and enable loadable module support."
+	@echo "Then build a kernel with module support enabled."
+	@echo
+	@exit 1
+
+endif # CONFIG_MODULES
+
+###
+# Cleaning is done on three levels.
+# make clean     Delete most generated files
+#                Leave enough to build external modules
+# make mrproper  Delete the current configuration, and all generated files
+# make distclean Remove editor backup files, patch leftover files and the like
+
+# Directories & files removed with 'make clean'
+CLEAN_DIRS  += $(MODVERDIR) _install 0_lib
+CLEAN_FILES +=	busybox busybox_unstripped* busybox.links \
+                System.map .kernelrelease \
+                .tmp_kallsyms* .tmp_version .tmp_busybox* .tmp_System.map
+
+# Directories & files removed with 'make mrproper'
+MRPROPER_DIRS  += include/config include2
+MRPROPER_FILES += .config .config.old include/asm .version .old_version \
+		  include/NUM_APPLETS.h \
+		  include/autoconf.h \
+		  include/bbconfigopts.h \
+		  include/bbconfigopts_bz2.h \
+		  include/usage_compressed.h \
+		  include/applet_tables.h \
+		  include/applets.h \
+		  include/usage.h \
+		  applets/usage \
+		  .kernelrelease Module.symvers tags TAGS cscope* \
+		  busybox_old
+
+# clean - Delete most, but leave enough to build external modules
+#
+clean: rm-dirs  := $(CLEAN_DIRS)
+clean: rm-files := $(CLEAN_FILES)
+clean-dirs      := $(addprefix _clean_,$(srctree) $(busybox-alldirs))
+
+PHONY += $(clean-dirs) clean archclean
+$(clean-dirs):
+	$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
+
+clean: archclean $(clean-dirs)
+	$(call cmd,rmdirs)
+	$(call cmd,rmfiles)
+	@find . $(RCS_FIND_IGNORE) \
+		\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
+		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \
+		-type f -print | xargs rm -f
+
+PHONY += doc-clean
+doc-clean: rm-files := docs/busybox.pod \
+		  docs/BusyBox.html docs/busybox.1 docs/BusyBox.txt
+doc-clean:
+	$(call cmd,rmfiles)
+
+# mrproper - Delete all generated files, including .config
+#
+mrproper: rm-dirs  := $(wildcard $(MRPROPER_DIRS))
+mrproper: rm-files := $(wildcard $(MRPROPER_FILES))
+mrproper-dirs      := $(addprefix _mrproper_,scripts)
+
+PHONY += $(mrproper-dirs) mrproper archmrproper
+$(mrproper-dirs):
+	$(Q)$(MAKE) $(clean)=$(patsubst _mrproper_%,%,$@)
+
+mrproper: clean archmrproper $(mrproper-dirs)
+	$(call cmd,rmdirs)
+	$(call cmd,rmfiles)
+	@find . -name Config.src | sed 's/.src$$/.in/' | xargs -r rm -f
+	@find . -name Kbuild.src | sed 's/.src$$//' | xargs -r rm -f
+
+# distclean
+#
+PHONY += distclean
+
+distclean: mrproper
+	@find $(srctree) $(RCS_FIND_IGNORE) \
+		\( -name '*.orig' -o -name '*.rej' -o -name '*~' \
+		-o -name '*.bak' -o -name '#*#' -o -name '.*.orig' \
+		-o -name '.*.rej' -o -name '*.tmp' -o -size 0 \
+		-o -name '*%' -o -name '.*.cmd' -o -name 'core' \) \
+		-type f -print | xargs rm -f
+
+
+# Packaging of the kernel to various formats
+# ---------------------------------------------------------------------------
+# rpm target kept for backward compatibility
+package-dir	:= $(srctree)/scripts/package
+
+%pkg: FORCE
+	$(Q)$(MAKE) $(build)=$(package-dir) $@
+rpm: FORCE
+	$(Q)$(MAKE) $(build)=$(package-dir) $@
+
+
+# Brief documentation of the typical targets used
+# ---------------------------------------------------------------------------
+
+boards := $(wildcard $(srctree)/configs/*_defconfig)
+boards := $(notdir $(boards))
+
+-include $(srctree)/Makefile.help
+
+# Documentation targets
+# ---------------------------------------------------------------------------
+%docs: scripts_basic FORCE
+	$(Q)$(MAKE) $(build)=Documentation/DocBook $@
+
+else # KBUILD_EXTMOD
+
+###
+# External module support.
+# When building external modules the kernel used as basis is considered
+# read-only, and no consistency checks are made and the make
+# system is not used on the basis kernel. If updates are required
+# in the basis kernel ordinary make commands (without M=...) must
+# be used.
+#
+# The following are the only valid targets when building external
+# modules.
+# make M=dir clean     Delete all automatically generated files
+# make M=dir modules   Make all modules in specified dir
+# make M=dir	       Same as 'make M=dir modules'
+# make M=dir modules_install
+#                      Install the modules build in the module directory
+#                      Assumes install directory is already created
+
+# We are always building modules
+KBUILD_MODULES := 1
+PHONY += crmodverdir
+crmodverdir:
+	$(Q)mkdir -p $(MODVERDIR)
+	$(Q)rm -f $(MODVERDIR)/*
+
+PHONY += $(objtree)/Module.symvers
+$(objtree)/Module.symvers:
+	@test -e $(objtree)/Module.symvers || ( \
+	echo; \
+	echo "  WARNING: Symbol version dump $(objtree)/Module.symvers"; \
+	echo "           is missing; modules will have no dependencies and modversions."; \
+	echo )
+
+module-dirs := $(addprefix _module_,$(KBUILD_EXTMOD))
+PHONY += $(module-dirs) modules
+$(module-dirs): crmodverdir $(objtree)/Module.symvers
+	$(Q)$(MAKE) $(build)=$(patsubst _module_%,%,$@)
+
+modules: $(module-dirs)
+	@echo '  Building modules, stage 2.';
+	$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
+
+PHONY += modules_install
+modules_install: _emodinst_ _emodinst_post
+
+install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra)
+PHONY += _emodinst_
+_emodinst_:
+	$(Q)mkdir -p $(MODLIB)/$(install-dir)
+	$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst
+
+# Run depmod only is we have System.map and depmod is executable
+quiet_cmd_depmod = DEPMOD  $(KERNELRELEASE)
+      cmd_depmod = if [ -r System.map -a -x $(DEPMOD) ]; then \
+                      $(DEPMOD) -ae -F System.map             \
+                      $(if $(strip $(INSTALL_MOD_PATH)),      \
+		      -b $(INSTALL_MOD_PATH) -r)              \
+		      $(KERNELRELEASE);                       \
+                   fi
+
+PHONY += _emodinst_post
+_emodinst_post: _emodinst_
+	$(call cmd,depmod)
+
+clean-dirs := $(addprefix _clean_,$(KBUILD_EXTMOD))
+
+PHONY += $(clean-dirs) clean
+$(clean-dirs):
+	$(Q)$(MAKE) $(clean)=$(patsubst _clean_%,%,$@)
+
+clean:	rm-dirs := $(MODVERDIR)
+clean: $(clean-dirs)
+	$(call cmd,rmdirs)
+	@find $(KBUILD_EXTMOD) $(RCS_FIND_IGNORE) \
+		\( -name '*.[oas]' -o -name '*.ko' -o -name '.*.cmd' \
+		-o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \) \
+		-type f -print | xargs rm -f
+
+# Dummies...
+PHONY += prepare scripts
+prepare: ;
+scripts: ;
+endif # KBUILD_EXTMOD
+
+# Generate tags for editors
+# ---------------------------------------------------------------------------
+
+#We want __srctree to totally vanish out when KBUILD_OUTPUT is not set
+#(which is the most common case IMHO) to avoid unneeded clutter in the big tags file.
+#Adding $(srctree) adds about 20M on i386 to the size of the output file!
+
+ifeq ($(src),$(obj))
+__srctree =
+else
+__srctree = $(srctree)/
+endif
+
+ifeq ($(ALLSOURCE_ARCHS),)
+ifeq ($(ARCH),um)
+ALLINCLUDE_ARCHS := $(ARCH) $(SUBARCH)
+else
+ALLINCLUDE_ARCHS := $(ARCH)
+endif
+else
+#Allow user to specify only ALLSOURCE_PATHS on the command line, keeping existing behaviour.
+ALLINCLUDE_ARCHS := $(ALLSOURCE_ARCHS)
+endif
+
+ALLSOURCE_ARCHS := $(ARCH)
+
+define all-sources
+	( find $(__srctree) $(RCS_FIND_IGNORE) \
+	       \( -name include -o -name arch \) -prune -o \
+	       -name '*.[chS]' -print; \
+	  for ARCH in $(ALLSOURCE_ARCHS) ; do \
+	       find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \
+	            -name '*.[chS]' -print; \
+	  done ; \
+	  find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \
+	       -name '*.[chS]' -print; \
+	  find $(__srctree)include $(RCS_FIND_IGNORE) \
+	       \( -name config -o -name 'asm-*' \) -prune \
+	       -o -name '*.[chS]' -print; \
+	  for ARCH in $(ALLINCLUDE_ARCHS) ; do \
+	       find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \
+	            -name '*.[chS]' -print; \
+	  done ; \
+	  find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \
+	       -name '*.[chS]' -print )
+endef
+
+quiet_cmd_cscope-file = FILELST cscope.files
+      cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files
+
+quiet_cmd_cscope = MAKE    cscope.out
+      cmd_cscope = cscope -b
+
+cscope: FORCE
+	$(call cmd,cscope-file)
+	$(call cmd,cscope)
+
+quiet_cmd_TAGS = MAKE   $@
+define cmd_TAGS
+	rm -f $@; \
+	ETAGSF=`etags --version | grep -i exuberant >/dev/null &&     \
+                echo "-I __initdata,__exitdata,__acquires,__releases  \
+                      -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL              \
+                      --extra=+f --c-kinds=+px"`;                     \
+                $(all-sources) | xargs etags $$ETAGSF -a
+endef
+
+TAGS: FORCE
+	$(call cmd,TAGS)
+
+
+quiet_cmd_tags = MAKE   $@
+define cmd_tags
+	rm -f $@; \
+	CTAGSF=`ctags --version | grep -i exuberant >/dev/null &&     \
+                echo "-I __initdata,__exitdata,__acquires,__releases  \
+                      -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL              \
+                      --extra=+f --c-kinds=+px"`;                     \
+                $(all-sources) | xargs ctags $$CTAGSF -a
+endef
+
+tags: FORCE
+	$(call cmd,tags)
+
+
+# Scripts to check various things for consistency
+# ---------------------------------------------------------------------------
+
+includecheck:
+	find * $(RCS_FIND_IGNORE) \
+		-name '*.[hcS]' -type f -print | sort \
+		| xargs $(PERL) -w scripts/checkincludes.pl
+
+versioncheck:
+	find * $(RCS_FIND_IGNORE) \
+		-name '*.[hcS]' -type f -print | sort \
+		| xargs $(PERL) -w scripts/checkversion.pl
+
+namespacecheck:
+	$(PERL) $(srctree)/scripts/namespace.pl
+
+endif #ifeq ($(config-targets),1)
+endif #ifeq ($(mixed-targets),1)
+
+PHONY += checkstack
+checkstack:
+	$(OBJDUMP) -d busybox $$(find . -name '*.ko') | \
+	$(PERL) $(src)/scripts/checkstack.pl $(ARCH)
+
+kernelrelease:
+	$(if $(wildcard .kernelrelease), $(Q)echo $(KERNELRELEASE), \
+	$(error kernelrelease not valid - run 'make *config' to update it))
+kernelversion:
+	@echo $(KERNELVERSION)
+
+# Single targets
+# ---------------------------------------------------------------------------
+# Single targets are compatible with:
+# - build whith mixed source and output
+# - build with separate output dir 'make O=...'
+# - external modules
+#
+#  target-dir => where to store outputfile
+#  build-dir  => directory in kernel source tree to use
+
+ifeq ($(KBUILD_EXTMOD),)
+        build-dir  = $(patsubst %/,%,$(dir $@))
+        target-dir = $(dir $@)
+else
+        zap-slash=$(filter-out .,$(patsubst %/,%,$(dir $@)))
+        build-dir  = $(KBUILD_EXTMOD)$(if $(zap-slash),/$(zap-slash))
+        target-dir = $(if $(KBUILD_EXTMOD),$(dir $<),$(dir $@))
+endif
+
+%.s: %.c prepare scripts FORCE
+	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+%.i: %.c prepare scripts FORCE
+	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+%.o: %.c prepare scripts FORCE
+	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+%.lst: %.c prepare scripts FORCE
+	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+%.s: %.S prepare scripts FORCE
+	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+%.o: %.S prepare scripts FORCE
+	$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
+
+# Modules
+%/: prepare scripts FORCE
+	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
+	$(build)=$(build-dir)
+/: prepare scripts FORCE
+	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
+	$(build)=$(build-dir)
+
+%.ko: prepare scripts FORCE
+	$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1)   \
+	$(build)=$(build-dir) $(@:.ko=.o)
+	$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost
+
+# FIXME Should go into a make.lib or something
+# ===========================================================================
+
+quiet_cmd_rmdirs = $(if $(wildcard $(rm-dirs)),CLEAN   $(wildcard $(rm-dirs)))
+      cmd_rmdirs = rm -rf $(rm-dirs)
+
+quiet_cmd_rmfiles = $(if $(wildcard $(rm-files)),CLEAN   $(wildcard $(rm-files)))
+      cmd_rmfiles = rm -f $(rm-files)
+
+
+a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(AFLAGS_KERNEL) \
+	  $(NOSTDINC_FLAGS) $(CPPFLAGS) \
+	  $(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
+
+quiet_cmd_as_o_S = AS      $@
+cmd_as_o_S       = $(CC) $(a_flags) -c -o $@ $<
+
+# read all saved command lines
+
+targets := $(wildcard $(sort $(targets)))
+cmd_files := $(wildcard .*.cmd $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd))
+
+ifneq ($(cmd_files),)
+  $(cmd_files): ;	# Do not try to update included dependency files
+  include $(cmd_files)
+endif
+
+# Shorthand for $(Q)$(MAKE) -f scripts/Makefile.clean obj=dir
+# Usage:
+# $(Q)$(MAKE) $(clean)=dir
+clean := -f $(if $(KBUILD_SRC),$(srctree)/)scripts/Makefile.clean obj
+
+endif	# skip-makefile
+
+PHONY += FORCE
+FORCE:
+
+-include $(srctree)/Makefile.custom
+
+# Declare the contents of the .PHONY variable as phony.  We keep that
+# information in a variable se we can use it in if_changed and friends.
+.PHONY: $(PHONY)
diff --git a/busybox-1.19.3/Makefile.custom b/busybox-1.19.3/Makefile.custom
new file mode 100644
index 0000000..6da79e6
--- /dev/null
+++ b/busybox-1.19.3/Makefile.custom
@@ -0,0 +1,178 @@
+# ==========================================================================
+# Build system
+# ==========================================================================
+
+busybox.links: $(srctree)/applets/busybox.mkll $(objtree)/include/autoconf.h include/applets.h
+	$(Q)-$(SHELL) $^ >$@
+
+.PHONY: install
+ifeq ($(CONFIG_INSTALL_APPLET_SYMLINKS),y)
+INSTALL_OPTS:= --symlinks
+endif
+ifeq ($(CONFIG_INSTALL_APPLET_HARDLINKS),y)
+INSTALL_OPTS:= --hardlinks
+endif
+ifeq ($(CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS),y)
+ifeq ($(CONFIG_INSTALL_SH_APPLET_SYMLINK),y)
+INSTALL_OPTS:= --sw-sh-sym
+endif
+ifeq ($(CONFIG_INSTALL_SH_APPLET_HARDLINK),y)
+INSTALL_OPTS:= --sw-sh-hard
+endif
+ifeq ($(CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER),y)
+INSTALL_OPTS:= --scriptwrapper
+endif
+endif
+install: $(srctree)/applets/install.sh busybox busybox.links
+	$(Q)DO_INSTALL_LIBS="$(strip $(LIBBUSYBOX_SONAME) $(DO_INSTALL_LIBS))" \
+		$(SHELL) $< $(CONFIG_PREFIX) $(INSTALL_OPTS)
+ifeq ($(strip $(CONFIG_FEATURE_SUID)),y)
+	@echo
+	@echo
+	@echo --------------------------------------------------
+	@echo You will probably need to make your busybox binary
+	@echo setuid root to ensure all configured applets will
+	@echo work properly.
+	@echo --------------------------------------------------
+	@echo
+endif
+
+uninstall: busybox.links
+	rm -f $(CONFIG_PREFIX)/bin/busybox
+	for i in `cat busybox.links` ; do rm -f $(CONFIG_PREFIX)$$i; done
+ifneq ($(strip $(DO_INSTALL_LIBS)),n)
+	for i in $(LIBBUSYBOX_SONAME) $(DO_INSTALL_LIBS); do \
+		rm -f $(CONFIG_PREFIX)$$i; \
+	done
+endif
+
+# Not very elegant: copies testsuite to objdir...
+# (cp -pPR is POSIX-compliant (cp -dpR or cp -a would not be))
+.PHONY: check
+.PHONY: test
+check test: busybox busybox.links
+	test -d $(objtree)/testsuite || cp -pPR $(srctree)/testsuite $(objtree)
+	bindir=$(objtree) srcdir=$(srctree)/testsuite \
+	$(SHELL) -c "cd $(objtree)/testsuite && $(srctree)/testsuite/runtest $(if $(KBUILD_VERBOSE:0=),-v)"
+
+.PHONY: release
+release: distclean
+	cd ..; \
+	rm -r -f busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION); \
+	cp -pPR busybox busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) && { \
+	find busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ -type d \
+		-name .svn \
+		-print \
+		-exec rm -r -f {} \; ; \
+	find busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ -type d \
+		-name .git \
+		-print \
+		-exec rm -r -f {} \; ; \
+	find busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ -type f \
+		-name .\#* \
+		-print \
+		-exec rm -f {} \; ; \
+	tar -czf busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION).tar.gz \
+		busybox-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)/ ; }
+
+.PHONY: checkhelp
+checkhelp:
+	$(Q)$(srctree)/scripts/checkhelp.awk \
+		$(patsubst %,$(srctree)/%,$(wildcard $(patsubst %,%/Config.in,$(busybox-dirs) ./)))
+
+.PHONY: sizes
+sizes: busybox_unstripped
+	$(NM) --size-sort $(<)
+
+.PHONY: bloatcheck
+bloatcheck: busybox_old busybox_unstripped
+	@$(srctree)/scripts/bloat-o-meter busybox_old busybox_unstripped
+	@$(CROSS_COMPILE)size busybox_old busybox_unstripped
+
+.PHONY: baseline
+baseline: busybox_unstripped
+	@mv busybox_unstripped busybox_old
+
+.PHONY: objsizes
+objsizes: busybox_unstripped
+	$(srctree)/scripts/objsizes
+
+.PHONY: stksizes
+stksizes: busybox_unstripped
+	$(CROSS_COMPILE)objdump -d busybox_unstripped | $(srctree)/scripts/checkstack.pl $(ARCH) | uniq
+
+.PHONY: bigdata
+bigdata: busybox_unstripped
+	$(CROSS_COMPILE)nm --size-sort busybox_unstripped | grep -vi ' [trw] '
+
+# Documentation Targets
+.PHONY: doc
+doc: docs/busybox.pod docs/BusyBox.txt docs/busybox.1 docs/BusyBox.html
+
+# FIXME: Doesn't belong here
+       cmd_doc =
+ quiet_cmd_doc = $(Q)echo "  DOC     $(@F)"
+silent_cmd_doc =
+disp_doc       = $($(quiet)cmd_doc)
+
+# sed adds newlines after "Options:" etc,
+# this is needed in order to get good BusyBox.{1,txt,html}
+docs/busybox.pod: $(srctree)/docs/busybox_header.pod \
+		include/usage.h \
+		$(srctree)/docs/busybox_footer.pod \
+		applets/usage_pod
+	$(disp_doc)
+	$(Q)-mkdir -p docs
+	$(Q)-( \
+	    cat $(srctree)/docs/busybox_header.pod; \
+	    echo; \
+	    applets/usage_pod | sed 's/^[A-Za-z][A-Za-z ]*[a-z]:$$/&\n/'; \
+	    cat $(srctree)/docs/busybox_footer.pod; \
+	    ) > docs/busybox.pod
+
+docs/BusyBox.txt: docs/busybox.pod
+	$(disp_doc)
+	$(Q)-mkdir -p docs
+	$(Q)-pod2text $< > $@
+
+docs/busybox.1: docs/busybox.pod
+	$(disp_doc)
+	$(Q)-mkdir -p docs
+	$(Q)-pod2man --center=busybox --release="version $(KERNELVERSION)" $< > $@
+
+docs/BusyBox.html: docs/busybox.net/BusyBox.html
+	$(disp_doc)
+	$(Q)-mkdir -p docs
+	$(Q)-rm -f docs/BusyBox.html
+	$(Q)-cp docs/busybox.net/BusyBox.html docs/BusyBox.html
+
+docs/busybox.net/BusyBox.html: docs/busybox.pod
+	$(Q)-mkdir -p docs/busybox.net
+	$(Q)-pod2html --noindex $< > $@
+	$(Q)-rm -f pod2htm*
+
+# documentation, cross-reference
+# Modern distributions already ship synopsis packages (e.g. debian)
+# If you have an old distribution go to http://synopsis.fresco.org/
+syn_tgt = $(wildcard $(patsubst %,%/*.c,$(busybox-alldirs)))
+syn     = $(patsubst %.c, %.syn, $(syn_tgt))
+
+comma:= ,
+brace_open:= (
+brace_close:= )
+
+SYN_CPPFLAGS := $(strip $(CPPFLAGS) $(EXTRA_CPPFLAGS))
+SYN_CPPFLAGS := $(subst $(brace_open),\$(brace_open),$(SYN_CPPFLAGS))
+SYN_CPPFLAGS := $(subst $(brace_close),\$(brace_close),$(SYN_CPPFLAGS))
+#SYN_CPPFLAGS := $(subst ",\",$(SYN_CPPFLAGS))
+#")
+#SYN_CPPFLAGS := [$(patsubst %,'%'$(comma),$(SYN_CPPFLAGS))'']
+
+%.syn: %.c
+	synopsis -p C -l Comments.SSDFilter,Comments.Previous -Wp,preprocess=True,cppflags="'$(SYN_CPPFLAGS)'" -o $@ $<
+
+.PHONY: html
+html: $(syn)
+	synopsis -f HTML -Wf,title="'BusyBox Documentation'" -o $@ $^
+
+-include $(srctree)/Makefile.local
diff --git a/busybox-1.19.3/Makefile.flags b/busybox-1.19.3/Makefile.flags
new file mode 100644
index 0000000..4ef5318
--- /dev/null
+++ b/busybox-1.19.3/Makefile.flags
@@ -0,0 +1,132 @@
+# ==========================================================================
+# Build system
+# ==========================================================================
+
+BB_VER = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
+export BB_VER
+SKIP_STRIP ?= n
+
+# -std=gnu99 needed for [U]LLONG_MAX on some systems
+CPPFLAGS += $(call cc-option,-std=gnu99,)
+
+CPPFLAGS += \
+	-Iinclude -Ilibbb \
+	$(if $(KBUILD_SRC),-Iinclude2 -I$(srctree)/include -I$(srctree)/libbb) \
+	-include include/autoconf.h \
+	-D_GNU_SOURCE -DNDEBUG \
+	$(if $(CONFIG_LFS),-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64) \
+	-D"BB_VER=KBUILD_STR($(BB_VER))" -DBB_BT=AUTOCONF_TIMESTAMP
+
+CFLAGS += $(call cc-option,-Wall,)
+CFLAGS += $(call cc-option,-Wshadow,)
+CFLAGS += $(call cc-option,-Wwrite-strings,)
+CFLAGS += $(call cc-option,-Wundef,)
+CFLAGS += $(call cc-option,-Wstrict-prototypes,)
+CFLAGS += $(call cc-option,-Wunused -Wunused-parameter,)
+CFLAGS += $(call cc-option,-Wunused-function -Wunused-value,)
+CFLAGS += $(call cc-option,-Wmissing-prototypes -Wmissing-declarations,)
+# warn about C99 declaration after statement
+CFLAGS += $(call cc-option,-Wdeclaration-after-statement,)
+# If you want to add more -Wsomething above, make sure that it is
+# still possible to build bbox without warnings.
+
+ifeq ($(CONFIG_WERROR),y)
+CFLAGS += $(call cc-option,-Werror,)
+## TODO:
+## gcc version 4.4.0 20090506 (Red Hat 4.4.0-4) (GCC) is a PITA:
+## const char *ptr; ... off_t v = *(off_t*)ptr; -> BOOM
+## and no easy way to convince it to shut the hell up.
+## We have a lot of such things all over the place.
+## Classic *(off_t*)(void*)ptr does not work,
+## and I am unwilling to do crazy gcc specific ({ void *ppp = ...; })
+## stuff in macros. This would obfuscate the code too much.
+## Maybe try __attribute__((__may_alias__))?
+CFLAGS += $(call cc-ifversion, -ge, 0404, -fno-strict-aliasing)
+endif
+# gcc 3.x emits bogus "old style proto" warning on find.c:alloc_action()
+CFLAGS += $(call cc-ifversion, -ge, 0400, -Wold-style-definition)
+
+CFLAGS += $(call cc-option,-fno-builtin-strlen -finline-limit=0 -fomit-frame-pointer -ffunction-sections -fdata-sections,)
+# -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,-falign-functions=1 -falign-jumps=1 -falign-labels=1 -falign-loops=1,)
+
+# FIXME: These warnings are at least partially to be concerned about and should
+# be fixed..
+#CFLAGS += $(call cc-option,-Wconversion,)
+
+ifneq ($(CONFIG_DEBUG),y)
+CFLAGS += $(call cc-option,-Os,$(call cc-option,-O2,))
+else
+CFLAGS += $(call cc-option,-g,)
+#CFLAGS += "-D_FORTIFY_SOURCE=2"
+ifeq ($(CONFIG_DEBUG_PESSIMIZE),y)
+CFLAGS += $(call cc-option,-O0,)
+else
+CFLAGS += $(call cc-option,-Os,$(call cc-option,-O2,))
+endif
+endif
+
+# If arch/$(ARCH)/Makefile did not override it (with, say, -fPIC)...
+ARCH_FPIC ?= -fpic
+ARCH_FPIE ?= -fpie
+ARCH_PIE ?= -pie
+
+ifeq ($(CONFIG_BUILD_LIBBUSYBOX),y)
+# on i386: 14% smaller libbusybox.so
+# (code itself is 9% bigger, we save on relocs/PLT/GOT)
+CFLAGS += $(ARCH_FPIC)
+# and another 4% reduction of libbusybox.so:
+# (external entry points must be marked EXTERNALLY_VISIBLE)
+CFLAGS += $(call cc-option,-fvisibility=hidden)
+endif
+
+ifeq ($(CONFIG_STATIC),y)
+CFLAGS_busybox += -static
+endif
+
+ifeq ($(CONFIG_PIE),y)
+CFLAGS_busybox += $(ARCH_PIE)
+CFLAGS += $(ARCH_FPIE)
+endif
+
+ifneq ($(CONFIG_EXTRA_CFLAGS),)
+CFLAGS += $(strip $(subst ",,$(CONFIG_EXTRA_CFLAGS)))
+#"))
+endif
+
+LDLIBS += m crypt
+
+ifeq ($(CONFIG_PAM),y)
+LDLIBS += pam pam_misc
+endif
+
+ifeq ($(CONFIG_SELINUX),y)
+LDLIBS += selinux sepol
+endif
+
+ifeq ($(CONFIG_EFENCE),y)
+LDLIBS += efence
+endif
+
+ifeq ($(CONFIG_DMALLOC),y)
+LDLIBS += dmalloc
+endif
+
+# If a flat binary should be built, CFLAGS_busybox="-elf2flt"
+# env var should be set for make invocation.
+# Here we check whether CFLAGS_busybox indeed contains that flag.
+# (For historical reasons, we also check LDFLAGS, which doesn't
+# seem to be entirely correct variable to put "-elf2flt" into).
+W_ELF2FLT = -elf2flt
+ifneq (,$(findstring $(W_ELF2FLT),$(LDFLAGS) $(CFLAGS_busybox)))
+SKIP_STRIP = y
+endif
+
+# Busybox is a stack-fatty so make sure we increase default size
+# TODO: use "make stksizes" to find & fix big stack users
+# (we stole scripts/checkstack.pl from the kernel... thanks guys!)
+# Reduced from 20k to 16k in 1.9.0.
+FLTFLAGS += -s 16000
diff --git a/busybox-1.19.3/Makefile.help b/busybox-1.19.3/Makefile.help
new file mode 100644
index 0000000..119dd6f
--- /dev/null
+++ b/busybox-1.19.3/Makefile.help
@@ -0,0 +1,48 @@
+# ==========================================================================
+# Build system
+# ==========================================================================
+
+help:
+	@echo 'Cleaning:'
+	@echo '  clean			- delete temporary files created by build'
+	@echo '  distclean		- delete all non-source files (including .config)'
+	@echo '  doc-clean		- delete all generated documentation'
+	@echo
+	@echo 'Build:'
+	@echo '  all			- Executable and documentation'
+	@echo '  busybox		- the swiss-army executable'
+	@echo '  doc			- docs/BusyBox.{txt,html,1}'
+	@echo '  html			- create html-based cross-reference'
+	@echo
+	@echo 'Configuration:'
+	@echo '  allnoconfig		- disable all symbols in .config'
+	@echo '  allyesconfig		- enable all symbols in .config (see defconfig)'
+	@echo '  config		- text based configurator (of last resort)'
+	@echo '  defconfig		- set .config to largest generic configuration'
+	@echo '  menuconfig		- interactive curses-based configurator'
+	@echo '  oldconfig		- resolve any unresolved symbols in .config'
+	@echo '  hosttools  		- build sed for the host.'
+	@echo '  			  You can use these commands if the commands on the host'
+	@echo '  			  is unusable. Afterwards use it like:'
+	@echo '  			  make SED="$(objtree)/sed"'
+	@$(if $(boards), \
+		$(foreach b, $(boards), \
+		printf "  %-21s - Build for %s\\n" $(b) $(subst _defconfig,,$(b));) \
+		echo '')
+	@echo
+	@echo 'Installation:'
+	@echo '  install		- install busybox into CONFIG_PREFIX'
+	@echo '  uninstall'
+	@echo
+	@echo 'Development:'
+	@echo '  baseline		- create busybox_old for bloatcheck.'
+	@echo '  bloatcheck		- show size difference between old and new versions'
+	@echo '  check			- run the test suite for all applets'
+	@echo '  checkhelp		- check for missing help-entries in Config.in'
+	@echo '  randconfig		- generate a random configuration'
+	@echo '  release		- create a distribution tarball'
+	@echo '  sizes			- show size of all enabled busybox symbols'
+	@echo '  objsizes		- show size of each .o object built'
+	@echo '  bigdata		- show data objects, biggest first'
+	@echo '  stksizes		- show stack users, biggest first'
+	@echo
diff --git a/busybox-1.19.3/README b/busybox-1.19.3/README
new file mode 100644
index 0000000..b940e35
--- /dev/null
+++ b/busybox-1.19.3/README
@@ -0,0 +1,204 @@
+Please see the LICENSE file for details on copying and usage.
+Please refer to the INSTALL file for instructions on how to build.
+
+What is busybox:
+
+  BusyBox combines tiny versions of many common UNIX utilities into a single
+  small executable.  It provides minimalist replacements for most of the
+  utilities you usually find in bzip2, coreutils, dhcp, diffutils, e2fsprogs,
+  file, findutils, gawk, grep, inetutils, less, modutils, net-tools, procps,
+  sed, shadow, sysklogd, sysvinit, tar, util-linux, and vim.  The utilities
+  in BusyBox often have fewer options than their full-featured cousins;
+  however, the options that are included provide the expected functionality
+  and behave very much like their larger counterparts.
+
+  BusyBox has been written with size-optimization and limited resources in
+  mind, both to produce small binaries and to reduce run-time memory usage.
+  Busybox is also extremely modular so you can easily include or exclude
+  commands (or features) at compile time.  This makes it easy to customize
+  embedded systems; to create a working system, just add /dev, /etc, and a
+  Linux kernel.  Busybox (usually together with uClibc) has also been used as
+  a component of "thin client" desktop systems, live-CD distributions, rescue
+  disks, installers, and so on.
+
+  BusyBox provides a fairly complete POSIX environment for any small system,
+  both embedded environments and more full featured systems concerned about
+  space.  Busybox is slowly working towards implementing the full Single Unix
+  Specification V3 (http://www.opengroup.org/onlinepubs/009695399/), but isn't
+  there yet (and for size reasons will probably support at most UTF-8 for
+  internationalization).  We are also interested in passing the Linux Test
+  Project (http://ltp.sourceforge.net).
+
+----------------
+
+Using busybox:
+
+  BusyBox is extremely configurable.  This allows you to include only the
+  components and options you need, thereby reducing binary size.  Run 'make
+  config' or 'make menuconfig' to select the functionality that you wish to
+  enable.  (See 'make help' for more commands.)
+
+  The behavior of busybox is determined by the name it's called under: as
+  "cp" it behaves like cp, as "sed" it behaves like sed, and so on.  Called
+  as "busybox" it takes the second argument as the name of the applet to
+  run (I.E. "./busybox ls -l /proc").
+
+  The "standalone shell" mode is an easy way to try out busybox; this is a
+  command shell that calls the built-in applets without needing them to be
+  installed in the path.  (Note that this requires /proc to be mounted, if
+  testing from a boot floppy or in a chroot environment.)
+
+  The build automatically generates a file "busybox.links", which is used by
+  'make install' to create symlinks to the BusyBox binary for all compiled in
+  commands.  This uses the CONFIG_PREFIX environment variable to specify
+  where to install, and installs hardlinks or symlinks depending
+  on the configuration preferences.  (You can also manually run
+  the install script at "applets/install.sh").
+
+----------------
+
+Downloading the current source code:
+
+  Source for the latest released version, as well as daily snapshots, can always
+  be downloaded from
+
+    http://busybox.net/downloads/
+
+  You can browse the up to the minute source code and change history online.
+
+    http://git.busybox.net/busybox/
+
+  Anonymous GIT access is available.  For instructions, check out:
+
+    http://www.busybox.net/source.html
+
+  For those that are actively contributing and would like to check files in,
+  see:
+
+    http://busybox.net/developer.html
+
+  The developers also have a bug and patch tracking system
+  (https://bugs.busybox.net) although posting a bug/patch to the mailing list
+  is generally a faster way of getting it fixed, and the complete archive of
+  what happened is the git changelog.
+
+  Note: if you want to compile busybox in a busybox environment you must
+  select CONFIG_DESKTOP.
+
+----------------
+
+Getting help:
+
+  when you find you need help, you can check out the busybox mailing list
+  archives at http://busybox.net/lists/busybox/ or even join
+  the mailing list if you are interested.
+
+----------------
+
+Bugs:
+
+  if you find bugs, please submit a detailed bug report to the busybox mailing
+  list at busybox@busybox.net.  a well-written bug report should include a
+  transcript of a shell session that demonstrates the bad behavior and enables
+  anyone else to duplicate the bug on their own machine. the following is such
+  an example:
+
+    to: busybox@busybox.net
+    from: diligent@testing.linux.org
+    subject: /bin/date doesn't work
+
+    package: busybox
+    version: 1.00
+
+    when i execute busybox 'date' it produces unexpected results.
+    with gnu date i get the following output:
+
+	$ date
+	fri oct  8 14:19:41 mdt 2004
+
+    but when i use busybox date i get this instead:
+
+	$ date
+	illegal instruction
+
+    i am using debian unstable, kernel version 2.4.25-vrs2 on a netwinder,
+    and the latest uclibc from cvs.
+
+	-diligent
+
+  note the careful description and use of examples showing not only what
+  busybox does, but also a counter example showing what an equivalent app
+  does (or pointing to the text of a relevant standard).  Bug reports lacking
+  such detail may never be fixed...  Thanks for understanding.
+
+----------------
+
+Portability:
+
+  Busybox is developed and tested on Linux 2.4 and 2.6 kernels, compiled
+  with gcc (the unit-at-a-time optimizations in version 3.4 and later are
+  worth upgrading to get, but older versions should work), and linked against
+  uClibc (0.9.27 or greater) or glibc (2.2 or greater).  In such an
+  environment, the full set of busybox features should work, and if
+  anything doesn't we want to know about it so we can fix it.
+
+  There are many other environments out there, in which busybox may build
+  and run just fine.  We just don't test them.  Since busybox consists of a
+  large number of more or less independent applets, portability is a question
+  of which features work where.  Some busybox applets (such as cat and rm) are
+  highly portable and likely to work just about anywhere, while others (such as
+  insmod and losetup) require recent Linux kernels with recent C libraries.
+
+  Earlier versions of Linux and glibc may or may not work, for any given
+  configuration.  Linux 2.2 or earlier should mostly work (there's still
+  some support code in things like mount.c) but this is no longer regularly
+  tested, and inherently won't support certain features (such as long files
+  and --bind mounts).  The same is true for glibc 2.0 and 2.1: expect a higher
+  testing and debugging burden using such old infrastructure.  (The busybox
+  developers are not very interested in supporting these older versions, but
+  will probably accept small self-contained patches to fix simple problems.)
+
+  Some environments are not recommended.  Early versions of uClibc were buggy
+  and missing many features: upgrade.  Linking against libc5 or dietlibc is
+  not supported and not interesting to the busybox developers.  (The first is
+  obsolete and has no known size or feature advantages over uClibc, the second
+  has known bugs that its developers have actively refused to fix.)  Ancient
+  Linux kernels (2.0.x and earlier) are similarly uninteresting.
+
+  In theory it's possible to use Busybox under other operating systems (such as
+  MacOS X, Solaris, Cygwin, or the BSD Fork Du Jour).  This generally involves
+  a different kernel and a different C library at the same time.  While it
+  should be possible to port the majority of the code to work in one of
+  these environments, don't be surprised if it doesn't work out of the box.  If
+  you're into that sort of thing, start small (selecting just a few applets)
+  and work your way up.
+
+  In 2005 Shaun Jackman has ported busybox to a combination of newlib
+  and libgloss, and some of his patches have been integrated.
+
+Supported hardware:
+
+  BusyBox in general will build on any architecture supported by gcc.  We
+  support both 32 and 64 bit platforms, and both big and little endian
+  systems.
+
+  Under 2.4 Linux kernels, kernel module loading was implemented in a
+  platform-specific manner.  Busybox's insmod utility has been reported to
+  work under ARM, CRIS, H8/300, x86, ia64, x86_64, m68k, MIPS, PowerPC, S390,
+  SH3/4/5, Sparc, v850e, and x86_64.  Anything else probably won't work.
+
+  The module loading mechanism for the 2.6 kernel is much more generic, and
+  we believe 2.6.x kernel module loading support should work on all
+  architectures supported by the kernel.
+
+----------------
+
+Please feed suggestions, bug reports, insults, and bribes back to the busybox
+mailing list:
+
+	busybox@busybox.net
+
+and/or maintainer:
+
+	Denys Vlasenko
+	<vda.linux@googlemail.com>
diff --git a/busybox-1.19.3/TODO b/busybox-1.19.3/TODO
new file mode 100644
index 0000000..8b9f87f
--- /dev/null
+++ b/busybox-1.19.3/TODO
@@ -0,0 +1,276 @@
+Busybox TODO
+
+Harvest patches from
+http://git.openembedded.org/cgit.cgi/openembedded/tree/recipes/busybox/
+
+Stuff that needs to be done.  This is organized by who plans to get around to
+doing it eventually, but that doesn't mean they "own" the item.  If you want to
+do one of these bounce an email off the person it's listed under to see if they
+have any suggestions how they plan to go about it, and to minimize conflicts
+between your work and theirs.  But otherwise, all of these are fair game.
+
+Rob Landley suggested this:
+  Implement bb_realpath() that can handle NULL on non-glibc.
+
+  sh
+    The command shell situation is a mess.  We have two different
+    shells that don't really share any code, and the "standalone shell" doesn't
+    work all that well (especially not in a chroot environment), due to apps not
+    being reentrant.
+
+  Do a SUSv3 audit
+    Look at the full Single Unix Specification version 3 (available online at
+    "http://www.opengroup.org/onlinepubs/009695399/nfindex.html") and
+    figure out which of our apps are compliant, and what we're missing that
+    we might actually care about.
+
+    Even better would be some kind of automated compliance test harness that
+    exercises each command line option and the various corner cases.
+
+  Internationalization
+    How much internationalization should we do?
+
+    The low hanging fruit is UTF-8 character set support.  We should do this.
+    See TODO_unicode file.
+
+    We also have lots of hardwired english text messages.  Consolidating this
+    into some kind of message table not only makes translation easier, but
+    also allows us to consolidate redundant (or close) strings.
+
+    We probably don't want to be bloated with locale support.  (Not unless we
+    can cleanly export it from our underlying C library without having to
+    concern ourselves with it directly.  Perhaps a few specific things like a
+    config option for "date" are low hanging fruit here?)
+
+    What level should things happen at?  How much do we care about
+    internationalizing the text console when X11 and xterms are so much better
+    at it?  (There's some infrastructure here we don't implement: The
+    "unicode_start" and "unicode_stop" shell scripts need "vt-is-UTF8" and a
+    --unicode option to loadkeys.  That implies a real loadkeys/dumpkeys
+    implementation to replace loadkmap/dumpkmap.  Plus messing with console font
+    loading.  Is it worth it, or do we just say "use X"?)
+
+  Individual compilation of applets.
+    It would be nice if busybox had the option to compile to individual applets,
+    for people who want an alternate implementation less bloated than the gnu
+    utils (or simply with less political baggage), but without it being one big
+    executable.
+
+    Turning libbb into a real dll is another possibility, especially if libbb
+    could export some of the other library interfaces we've already more or less
+    got the code for (like zlib).
+
+  buildroot - Make a "dogfood" option
+    Busybox 1.1 will be capable of replacing most gnu packages for real world
+    use, such as developing software or in a live CD.  It needs wider testing.
+
+    Busybox should now be able to replace bzip2, coreutils, e2fsprogs, file,
+    findutils, gawk, grep, inetutils, less, modutils, net-tools, patch, procps,
+    sed, shadow, sysklogd, sysvinit, tar, util-linux, and vim.  The resulting
+    system should be self-hosting (I.E. able to rebuild itself from source
+    code).  This means it would need (at least) binutils, gcc, and make, or
+    equivalents.
+
+    It would be a good "eating our own dogfood" test if buildroot had the option
+    of using a "make allyesconfig" busybox instead of the all of the above
+    packages.  Anything that's wrong with the resulting system, we can fix.  (It
+    would be nice to be able to upgrade busybox to be able to replace bash and
+    diffutils as well, but we're not there yet.)
+
+    One example of an existing system that does this already is Firmware Linux:
+      http://www.landley.net/code/firmware
+
+  initramfs
+    Busybox should have a sample initramfs build script.  This depends on
+    shell, mdev, and switch_root.
+
+  mkdep
+    Write a mkdep that doesn't segfault if there's a directory it doesn't
+    have permission to read, isn't based on manually editing the output of
+    lexx and yacc, doesn't make such a mess under include/config, etc.
+
+  Group globals into unions of structures.
+    Go through and turn all the global and static variables into structures,
+    and have all those structures be in a big union shared between processes,
+    so busybox uses less bss.  (This is a big win on nommu machines.)  See
+    sed.c and mdev.c for examples.
+
+  Go through bugs.busybox.net and close out all of that somehow.
+    This one's open to everybody, but I'll wind up doing it...
+
+Bernhard Reutner-Fischer <busybox@busybox.net> suggests to look at these:
+  New debug options:
+    -Wlarger-than-127
+    Cleanup any big users
+  Collate BUFSIZ IOBUF_SIZE MY_BUF_SIZE PIPE_PROGRESS_SIZE BUFSIZE PIPESIZE
+    make bb_common_bufsiz1 configurable, size wise.
+    make pipesize configurable, size wise.
+    Use bb_common_bufsiz1 throughout applets!
+
+As yet unclaimed:
+
+----
+diff
+  Make sure we handle empty files properly:
+    From the patch man page:
+
+    you can remove a file by sending out a context diff that compares
+    the file to be deleted with an empty file dated the Epoch.  The
+    file will be removed unless patch is conforming to POSIX and the
+    -E or --remove-empty-files option is not given.
+---
+patch
+  Should have simple fuzz factor support to apply patches at an offset which
+  shouldn't take up too much space.
+
+  And while we're at it, a new patch filename quoting format is apparently
+  coming soon:  http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2
+---
+stty / catv
+  stty's visible() function and catv's guts are identical. Merge them into
+  an appropriate libbb function.
+---
+struct suffix_mult
+  Several duplicate users of: grep -r "1024\*1024" * -B2 -A1
+  Merge to a single size_suffixes[] in libbb.
+  Users: head tail od_bloaty hexdump and (partially as it wouldn't hurt) svlogd
+---
+tail
+  ./busybox tail -f foo.c~ TODO
+  should not print fmt=header_fmt for subsequent date >> TODO; i.e. only
+  fmt+ if another (not the current) file did change
+
+Architectural issues:
+
+bb_close() with fsync()
+  We should have a bb_close() in place of normal close, with a CONFIG_ option
+  to not just check the return value of close() for an error, but fsync().
+  Close can't reliably report anything useful because if write() accepted the
+  data then it either went out to the network or it's in cache or a pipe
+  buffer.  Either way, there's no guarantee it'll make it to its final
+  destination before close() gets called, so there's no guarantee that any
+  error will be reported.
+
+  You need to call fsync() if you care about errors that occur after write(),
+  but that can have a big performance impact.  So make it a config option.
+---
+Unify archivers
+  Lots of archivers have the same general infrastructure.  The directory
+  traversal code should be factored out, and the guts of each archiver could
+  be some setup code and a series of callbacks for "add this file",
+  "add this directory", "add this symlink" and so on.
+
+  This could clean up tar and zip, and make it cheaper to add cpio and ar
+  write support, and possibly even cheaply add things like mkisofs or
+  mksquashfs someday, if they become relevant.
+---
+Text buffer support.
+  Several existing applets (sort, vi, less...) read
+  a whole file into memory and act on it.  Use open_read_close().
+---
+Memory Allocation
+  We have a CONFIG_BUFFER mechanism that lets us select whether to do memory
+  allocation on the stack or the heap.  Unfortunately, we're not using it much.
+  We need to audit our memory allocations and turn a lot of malloc/free calls
+  into RESERVE_CONFIG_BUFFER/RELEASE_CONFIG_BUFFER.
+  For a start, see e.g. make EXTRA_CFLAGS=-Wlarger-than-64
+
+  And while we're at it, many of the CONFIG_FEATURE_CLEAN_UP #ifdefs will be
+  optimized out by the compiler in the stack allocation case (since there's no
+  free for an alloca()), and this means that various cleanup loops that just
+  call free might also be optimized out by the compiler if written right, so
+  we can yank those #ifdefs too, and generally clean up the code.
+---
+FEATURE_CLEAN_UP
+  This is more an unresolved issue than a to-do item.  More thought is needed.
+
+  Normally we rely on exit() to free memory, close files and unmap segments
+  for us.  This makes most calls to free(), close(), and unmap() optional in
+  busybox applets that don't intend to run for very long, and optional stuff
+  can be omitted to save size.
+
+  The idea was raised that we could simulate fork/exit with setjmp/longjmp
+  for _really_ brainless embedded systems, or speed up the standalone shell
+  by not forking.  Doing so would require a reliable FEATURE_CLEAN_UP.
+  Unfortunately, this isn't as easy as it sounds.
+
+  The problem is, lots of things exit(), sometimes unexpectedly (xmalloc())
+  and sometimes reliably (bb_perror_msg_and_die() or show_usage()).  This
+  jumps out of the normal flow control and bypasses any cleanup code we
+  put at the end of our applets.
+
+  It's possible to add hooks to libbb functions like xmalloc() and xopen()
+  to add their entries to a linked list, which could be traversed and
+  freed/closed automatically.  (This would need to be able to free just the
+  entries after a checkpoint to be usable for a forkless standalone shell.
+  You don't want to free the shell's own resources.)
+
+  Right now, FEATURE_CLEAN_UP is more or less a debugging aid, to make things
+  like valgrind happy.  It's also documentation of _what_ we're trusting
+  exit() to clean up for us.  But new infrastructure to auto-free stuff would
+  render the existing FEATURE_CLEAN_UP code redundant.
+
+  For right now, exit() handles it just fine.
+
+
+Minor stuff:
+  watchdog.c could autodetect the timer duration via:
+    if(!ioctl (fd, WDIOC_GETTIMEOUT, &tmo)) timer_duration = 1 + (tmo / 2);
+  Unfortunately, that needs linux/watchdog.h and that contains unfiltered
+  kernel types on some distros, which breaks the build.
+---
+  use bb_error_msg where appropriate: See
+  egrep "(printf.*\([[:space:]]*(stderr|2)|[^_]write.*\([[:space:]]*(stderr|2))"
+---
+  use bb_perror_msg where appropriate: See
+  egrep "[^_]perror"
+---
+  possible code duplication ingroup() and is_a_group_member()
+---
+  Move __get_hz() to a better place and (re)use it in route.c, ash.c
+---
+  See grep -r strtod
+  Alot of duplication that wants cleanup.
+---
+  in_ether duplicated in network/{interface,ifconfig}.c
+---
+  unify progress_meter. wget, flash_eraseall, pipe_progress, fbsplash, setfiles.
+---
+  support start-stop-daemon -d <chdir-path>
+---
+vdprintf() -> similar sized functionality
+---
+
+(TODO list after discussion 11.05.2009)
+
+* shrink tc/brctl/ip
+  tc/brctl seem like fairly large things to try and tackle in your timeframe,
+  and i think people have posted attempts in the past. Adding additional
+  options to ip though seems reasonable.
+
+* add tests for some applets
+
+* implement POSIX utilities and audit them for POSIX conformance. then
+  audit them for GNU conformance. then document all your findings in a new
+  doc/conformance.txt file while perhaps implementing some of the missing
+  features.
+  you can find the latest POSIX documentation (1003.1-2008) here:
+  http://www.opengroup.org/onlinepubs/9699919799/
+  and the complete list of all utilities that POSIX covers:
+  http://www.opengroup.org/onlinepubs/9699919799/idx/utilities.html
+  The first step would to generate a file/matrix what is already archived
+  (also IPV6)
+
+* implement 'at'
+
+* rpcbind (former portmap) or equivalent
+  so that we don't have to use -o nolock on nfs mounts
+
+* check IPV6 compliance
+
+* generate a mini example using kernel+busybox only (+libc) for example
+
+* more support for advanced linux 2.6.x features, see: iotop
+  most likely there is more
+
+* even more support for statistics: mpstat, iostat, powertop....
diff --git a/busybox-1.19.3/TODO_unicode b/busybox-1.19.3/TODO_unicode
new file mode 100644
index 0000000..b310e8d
--- /dev/null
+++ b/busybox-1.19.3/TODO_unicode
@@ -0,0 +1,45 @@
+Already fixed applets:
+cal
+lsmod
+df
+dumpleases
+
+Applets which may need unicode handling (more extensive than sanitizing
+of filenames in error messages):
+
+ls - work in progress
+expand, unexpand - uses unicode_strlen, not scrlen
+ash, hush through lineedit - uses unicode_strlen, not scrlen
+top - need to sanitize process args
+ps - need to sanitize process args
+less
+more
+vi
+ed
+cut
+awk
+sed
+tr
+grep egrep fgrep
+fold
+sort
+head, tail
+catv - "display nonprinting chars" - what this could mean for unicode?
+wc
+chat
+dumpkmap
+last - just line up columns
+man
+microcom
+strings
+watch
+
+Unsure, may need fixing:
+
+hostname - do we really want to protect against bad chars in it?
+patch
+addgroup, adduser, delgroup, deluser
+telnet
+telnetd
+od
+printf
diff --git a/busybox-1.19.3/applets/Kbuild.src b/busybox-1.19.3/applets/Kbuild.src
new file mode 100644
index 0000000..b612399
--- /dev/null
+++ b/busybox-1.19.3/applets/Kbuild.src
@@ -0,0 +1,47 @@
+# Makefile for busybox
+#
+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
+#
+# Licensed under GPLv2, see file LICENSE in this source tree.
+
+obj-y :=
+obj-y += applets.o
+
+hostprogs-y:=
+hostprogs-y += usage usage_pod applet_tables
+
+always:= $(hostprogs-y)
+
+# Generated files need additional love
+
+# This trick decreases amount of rebuilds
+# if tree is merely renamed/copied
+ifeq ($(srctree),$(objtree))
+srctree_slash =
+else
+srctree_slash = $(srctree)/
+endif
+
+HOSTCFLAGS_usage.o = -I$(srctree_slash)include -Iinclude
+HOSTCFLAGS_usage_pod.o = -I$(srctree_slash)include -Iinclude
+
+applets/applets.o: include/usage_compressed.h include/applet_tables.h
+
+applets/applet_tables: .config include/applets.h
+applets/usage:         .config include/applets.h
+applets/usage_pod:     .config include/applet_tables.h include/applets.h
+
+quiet_cmd_gen_usage_compressed = GEN     include/usage_compressed.h
+      cmd_gen_usage_compressed = $(srctree_slash)applets/usage_compressed include/usage_compressed.h applets
+
+include/usage_compressed.h: applets/usage $(srctree_slash)applets/usage_compressed
+	$(call cmd,gen_usage_compressed)
+
+quiet_cmd_gen_applet_tables = GEN     include/applet_tables.h
+      cmd_gen_applet_tables = applets/applet_tables include/applet_tables.h include/NUM_APPLETS.h
+
+include/applet_tables.h: applets/applet_tables
+	$(call cmd,gen_applet_tables)
+
+include/NUM_APPLETS.h: applets/applet_tables
+	$(call cmd,gen_applet_tables)
diff --git a/busybox-1.19.3/applets/applet_tables.c b/busybox-1.19.3/applets/applet_tables.c
new file mode 100644
index 0000000..a475747
--- /dev/null
+++ b/busybox-1.19.3/applets/applet_tables.c
@@ -0,0 +1,164 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Applet table generator.
+ * Runs on host and produces include/applet_tables.h
+ *
+ * Copyright (C) 2007 Denys Vlasenko <vda.linux@googlemail.com>
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#undef ARRAY_SIZE
+#define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0])))
+
+#include "../include/autoconf.h"
+#include "../include/applet_metadata.h"
+
+struct bb_applet {
+	const char *name;
+	const char *main;
+	enum bb_install_loc_t install_loc;
+	enum bb_suid_t need_suid;
+	/* true if instead of fork(); exec("applet"); waitpid();
+	 * one can do fork(); exit(applet_main(argc,argv)); waitpid(); */
+	unsigned char noexec;
+	/* Even nicer */
+	/* true if instead of fork(); exec("applet"); waitpid();
+	 * one can simply call applet_main(argc,argv); */
+	unsigned char nofork;
+};
+
+/* Define struct bb_applet applets[] */
+#include "../include/applets.h"
+
+enum { NUM_APPLETS = ARRAY_SIZE(applets) };
+
+static int offset[NUM_APPLETS];
+
+static int cmp_name(const void *a, const void *b)
+{
+	const struct bb_applet *aa = a;
+	const struct bb_applet *bb = b;
+	return strcmp(aa->name, bb->name);
+}
+
+int main(int argc, char **argv)
+{
+	int i;
+	int ofs;
+	unsigned MAX_APPLET_NAME_LEN = 1;
+
+	qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name);
+
+	ofs = 0;
+	for (i = 0; i < NUM_APPLETS; i++) {
+		offset[i] = ofs;
+		ofs += strlen(applets[i].name) + 1;
+	}
+	/* We reuse 4 high-order bits of offset array for other purposes,
+	 * so if they are indeed needed, refuse to proceed */
+	if (ofs > 0xfff)
+		return 1;
+	if (!argv[1])
+		return 1;
+
+	i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666);
+	if (i < 0)
+		return 1;
+	dup2(i, 1);
+
+	/* Keep in sync with include/busybox.h! */
+
+	printf("/* This is a generated file, don't edit */\n\n");
+
+	printf("#define NUM_APPLETS %u\n", NUM_APPLETS);
+	if (NUM_APPLETS == 1) {
+		char *dash_to_underscore, *p;
+		printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name);
+		/* Example: "ether-wake" -> "ether_wake" */
+		p = dash_to_underscore = strdup(applets[0].name);
+		p--;
+		while (*++p)
+			if (*p == '-')
+				*p = '_';
+		printf("#define SINGLE_APPLET_MAIN %s_main\n", dash_to_underscore);
+	}
+	printf("\n");
+
+	//printf("#ifndef SKIP_definitions\n");
+	printf("const char applet_names[] ALIGN1 = \"\"\n");
+	for (i = 0; i < NUM_APPLETS; i++) {
+		printf("\"%s\" \"\\0\"\n", applets[i].name);
+		if (MAX_APPLET_NAME_LEN < strlen(applets[i].name))
+			MAX_APPLET_NAME_LEN = strlen(applets[i].name);
+	}
+	printf(";\n\n");
+
+	printf("#ifndef SKIP_applet_main\n");
+	printf("int (*const applet_main[])(int argc, char **argv) = {\n");
+	for (i = 0; i < NUM_APPLETS; i++) {
+		printf("%s_main,\n", applets[i].main);
+	}
+	printf("};\n");
+	printf("#endif\n\n");
+
+	printf("const uint16_t applet_nameofs[] ALIGN2 = {\n");
+	for (i = 0; i < NUM_APPLETS; i++) {
+		printf("0x%04x,\n",
+			offset[i]
+#if ENABLE_FEATURE_PREFER_APPLETS
+			+ (applets[i].nofork << 12)
+			+ (applets[i].noexec << 13)
+#endif
+#if ENABLE_FEATURE_SUID
+			+ (applets[i].need_suid << 14) /* 2 bits */
+#endif
+		);
+	}
+	printf("};\n\n");
+
+#if ENABLE_FEATURE_INSTALLER
+	printf("const uint8_t applet_install_loc[] ALIGN1 = {\n");
+	i = 0;
+	while (i < NUM_APPLETS) {
+		int v = applets[i].install_loc; /* 3 bits */
+		if (++i < NUM_APPLETS)
+			v |= applets[i].install_loc << 4; /* 3 bits */
+		printf("0x%02x,\n", v);
+		i++;
+	}
+	printf("};\n");
+#endif
+	//printf("#endif /* SKIP_definitions */\n");
+	printf("\n");
+	printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN);
+
+	if (argv[2]) {
+		char line_old[80];
+		char line_new[80];
+		FILE *fp;
+
+		line_old[0] = 0;
+		fp = fopen(argv[2], "r");
+		if (fp) {
+			fgets(line_old, sizeof(line_old), fp);
+			fclose(fp);
+		}
+		sprintf(line_new, "#define NUM_APPLETS %u\n", NUM_APPLETS);
+		if (strcmp(line_old, line_new) != 0) {
+			fp = fopen(argv[2], "w");
+			if (!fp)
+				return 1;
+			fputs(line_new, fp);
+		}
+	}
+
+	return 0;
+}
diff --git a/busybox-1.19.3/applets/applets.c b/busybox-1.19.3/applets/applets.c
new file mode 100644
index 0000000..98c2b44
--- /dev/null
+++ b/busybox-1.19.3/applets/applets.c
@@ -0,0 +1,16 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Stub for linking busybox binary against libbusybox.
+ *
+ * Copyright (C) 2007 Denys Vlasenko <vda.linux@googlemail.com>
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+#include "busybox.h"
+
+#if ENABLE_BUILD_LIBBUSYBOX
+int main(int argc UNUSED_PARAM, char **argv)
+{
+	return lbb_main(argv);
+}
+#endif
diff --git a/busybox-1.19.3/applets/busybox.mkll b/busybox-1.19.3/applets/busybox.mkll
new file mode 100755
index 0000000..68dbf21
--- /dev/null
+++ b/busybox-1.19.3/applets/busybox.mkll
@@ -0,0 +1,24 @@
+#!/bin/sh
+# Make busybox links list file.
+
+# input $1: full path to Config.h
+# input $2: full path to applets.h
+# output (stdout): list of pathnames that should be linked to busybox
+
+# Maintainer: Larry Doolittle <ldoolitt@recycle.lbl.gov>
+
+export LC_ALL=POSIX
+export LC_CTYPE=POSIX
+
+CONFIG_H=${1:-include/autoconf.h}
+APPLETS_H=${2:-include/applets.h}
+$HOSTCC -E -DMAKE_LINKS -include $CONFIG_H $APPLETS_H |
+  awk '/^[ \t]*LINK/{
+	dir=substr($2,7)
+	gsub("_","/",dir)
+	if(dir=="/ROOT") dir=""
+	file=$3
+	gsub("\"","",file)
+	if (file=="busybox") next
+	print tolower(dir) "/" file
+  }'
diff --git a/busybox-1.19.3/applets/individual.c b/busybox-1.19.3/applets/individual.c
new file mode 100644
index 0000000..1e74e4c
--- /dev/null
+++ b/busybox-1.19.3/applets/individual.c
@@ -0,0 +1,24 @@
+/* Minimal wrapper to build an individual busybox applet.
+ *
+ * Copyright 2005 Rob Landley <rob@landley.net
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+
+const char *applet_name;
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "usage.h"
+
+int main(int argc, char **argv)
+{
+	applet_name = argv[0];
+	return APPLET_main(argc,argv);
+}
+
+void bb_show_usage(void)
+{
+	fputs(APPLET_full_usage "\n", stdout);
+	exit(EXIT_FAILURE);
+}
diff --git a/busybox-1.19.3/applets/install.sh b/busybox-1.19.3/applets/install.sh
new file mode 100755
index 0000000..95b4719
--- /dev/null
+++ b/busybox-1.19.3/applets/install.sh
@@ -0,0 +1,113 @@
+#!/bin/sh
+
+export LC_ALL=POSIX
+export LC_CTYPE=POSIX
+
+prefix=$1
+if [ -z "$prefix" ]; then
+	echo "usage: applets/install.sh DESTINATION [--symlinks/--hardlinks/--scriptwrapper]"
+	exit 1
+fi
+
+h=`sort busybox.links | uniq`
+
+linkopts=""
+scriptwrapper="n"
+cleanup="0"
+noclobber="0"
+case "$2" in
+	--hardlinks)     linkopts="-f";;
+	--symlinks)      linkopts="-fs";;
+	--scriptwrapper) scriptwrapper="y";swrapall="y";;
+	--sw-sh-hard)    scriptwrapper="y";linkopts="-f";;
+	--sw-sh-sym)     scriptwrapper="y";linkopts="-fs";;
+	--cleanup)       cleanup="1";;
+	--noclobber)     noclobber="1";;
+	"")              h="";;
+	*)               echo "Unknown install option: $2"; exit 1;;
+esac
+
+if [ -n "$DO_INSTALL_LIBS" ] && [ "$DO_INSTALL_LIBS" != "n" ]; then
+	# get the target dir for the libs
+	# assume it starts with lib
+	libdir=$($CC -print-file-name=libc.so | \
+		 sed -n 's%^.*\(/lib[^\/]*\)/libc.so%\1%p')
+	if test -z "$libdir"; then
+		libdir=/lib
+	fi
+
+	mkdir -p "$prefix/$libdir" || exit 1
+	for i in $DO_INSTALL_LIBS; do
+		rm -f "$prefix/$libdir/$i" || exit 1
+		if [ -f "$i" ]; then
+			cp -pPR "$i" "$prefix/$libdir/" || exit 1
+			chmod 0644 "$prefix/$libdir/$i" || exit 1
+		fi
+	done
+fi
+
+if [ "$cleanup" = "1" ] && [ -e "$prefix/bin/busybox" ]; then
+	inode=`ls -i "$prefix/bin/busybox" | awk '{print $1}'`
+	sub_shell_it=`
+		cd "$prefix"
+		for d in usr/sbin usr/bin sbin bin; do
+			pd=$PWD
+			if [ -d "$d" ]; then
+				cd "$d"
+				ls -iL . | grep "^ *$inode" | awk '{print $2}' | env -i xargs rm -f
+			fi
+			cd "$pd"
+		done
+		`
+	exit 0
+fi
+
+rm -f "$prefix/bin/busybox" || exit 1
+mkdir -p "$prefix/bin" || exit 1
+install -m 755 busybox "$prefix/bin/busybox" || exit 1
+
+for i in $h; do
+	appdir=`dirname "$i"`
+	mkdir -p "$prefix/$appdir" || exit 1
+	if [ "$scriptwrapper" = "y" ]; then
+		if [ "$swrapall" != "y" ] && [ "$i" = "/bin/sh" ]; then
+			ln $linkopts busybox "$prefix/$i" || exit 1
+		else
+			rm -f "$prefix/$i"
+			echo "#!/bin/busybox" >"$prefix/$i"
+			chmod +x "$prefix/$i"
+		fi
+		echo "	$prefix/$i"
+	else
+		if [ "$2" = "--hardlinks" ]; then
+			bb_path="$prefix/bin/busybox"
+		else
+			case "$appdir" in
+			/)
+				bb_path="bin/busybox"
+			;;
+			/bin)
+				bb_path="busybox"
+			;;
+			/sbin)
+				bb_path="../bin/busybox"
+			;;
+			/usr/bin | /usr/sbin)
+				bb_path="../../bin/busybox"
+			;;
+			*)
+				echo "Unknown installation directory: $appdir"
+				exit 1
+			;;
+			esac
+		fi
+		if [ "$noclobber" = "0" ] || [ ! -e "$prefix/$i" ]; then
+			echo "  $prefix/$i -> $bb_path"
+			ln $linkopts "$bb_path" "$prefix/$i" || exit 1
+		else
+			echo "  $prefix/$i already exists"
+		fi
+	fi
+done
+
+exit 0
diff --git a/busybox-1.19.3/applets/usage.c b/busybox-1.19.3/applets/usage.c
new file mode 100644
index 0000000..94520ff
--- /dev/null
+++ b/busybox-1.19.3/applets/usage.c
@@ -0,0 +1,55 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright (C) 2008 Denys Vlasenko.
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "autoconf.h"
+
+/* Since we can't use platform.h, have to do this again by hand: */
+#if ENABLE_NOMMU
+# define BB_MMU 0
+# define USE_FOR_NOMMU(...) __VA_ARGS__
+# define USE_FOR_MMU(...)
+#else
+# define BB_MMU 1
+# define USE_FOR_NOMMU(...)
+# define USE_FOR_MMU(...) __VA_ARGS__
+#endif
+
+#include "usage.h"
+#define MAKE_USAGE(aname, usage) { aname, usage },
+static struct usage_data {
+	const char *aname;
+	const char *usage;
+} usage_array[] = {
+#include "applets.h"
+};
+
+static int compare_func(const void *a, const void *b)
+{
+	const struct usage_data *ua = a;
+	const struct usage_data *ub = b;
+	return strcmp(ua->aname, ub->aname);
+}
+
+int main(void)
+{
+	int i;
+	int num_messages = sizeof(usage_array) / sizeof(usage_array[0]);
+
+	if (num_messages == 0)
+		return 0;
+
+	qsort(usage_array,
+		num_messages, sizeof(usage_array[0]),
+		compare_func);
+	for (i = 0; i < num_messages; i++)
+		write(STDOUT_FILENO, usage_array[i].usage, strlen(usage_array[i].usage) + 1);
+
+	return 0;
+}
diff --git a/busybox-1.19.3/applets/usage_compressed b/busybox-1.19.3/applets/usage_compressed
new file mode 100755
index 0000000..af66bc5
--- /dev/null
+++ b/busybox-1.19.3/applets/usage_compressed
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+target="$1"
+loc="$2"
+
+test "$target" || exit 1
+test "$loc" || loc=.
+test -x "$loc/usage" || exit 1
+test "$SED" || SED=sed
+test "$DD" || DD=dd
+
+# Some people were bitten by their system lacking a (proper) od
+od -v -t x1 </dev/null >/dev/null
+if test $? != 0; then
+	echo 'od tool is not installed or cannot accept "-v -t x1" options'
+	exit 1
+fi
+
+exec >"$target.$$"
+
+echo '#define UNPACKED_USAGE "" \'
+"$loc/usage" | od -v -t x1 \
+| $SED -e 's/^[^ ]*//' \
+	-e 's/ //g' \
+	-e '/^$/d' \
+	-e 's/\(..\)/\\x\1/g' \
+	-e 's/^/"/' \
+	-e 's/$/" \\/'
+echo ''
+
+echo '#define PACKED_USAGE \'
+## Breaks on big-endian systems!
+## # Extra effort to avoid using "od -t x1": -t is not available
+## # in non-CONFIG_DESKTOPed busybox od
+##
+## "$loc/usage" | bzip2 -1 | od -v -x \
+## | $SED -e 's/^[^ ]*//' \
+##	-e 's/ //g' \
+##	-e '/^$/d' \
+##	-e 's/\(..\)\(..\)/0x\2,0x\1,/g'
+##	-e 's/$/ \\/'
+"$loc/usage" | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -t x1 \
+| $SED -e 's/^[^ ]*//' \
+	-e 's/ //g' \
+	-e '/^$/d' \
+	-e 's/\(..\)/0x\1,/g' \
+	-e 's/$/ \\/'
+echo ''
+
+mv -- "$target.$$" "$target"
diff --git a/busybox-1.19.3/applets/usage_pod.c b/busybox-1.19.3/applets/usage_pod.c
new file mode 100644
index 0000000..0b1c4aa
--- /dev/null
+++ b/busybox-1.19.3/applets/usage_pod.c
@@ -0,0 +1,111 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright (C) 2009 Denys Vlasenko.
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+#include "autoconf.h"
+
+#define SKIP_applet_main
+#define ALIGN1 /* nothing, just to placate applet_tables.h */
+#define ALIGN2 /* nothing, just to placate applet_tables.h */
+#include "applet_tables.h"
+
+/* Since we can't use platform.h, have to do this again by hand: */
+#if ENABLE_NOMMU
+# define BB_MMU 0
+# define USE_FOR_NOMMU(...) __VA_ARGS__
+# define USE_FOR_MMU(...)
+#else
+# define BB_MMU 1
+# define USE_FOR_NOMMU(...)
+# define USE_FOR_MMU(...) __VA_ARGS__
+#endif
+
+#include "usage.h"
+#define MAKE_USAGE(aname, usage) { aname, usage },
+static struct usage_data {
+	const char *aname;
+	const char *usage;
+} usage_array[] = {
+#include "applets.h"
+};
+
+static int compare_func(const void *a, const void *b)
+{
+	const struct usage_data *ua = a;
+	const struct usage_data *ub = b;
+	return strcmp(ua->aname, ub->aname);
+}
+
+int main(void)
+{
+	int col, len2;
+
+	int i;
+	int num_messages = sizeof(usage_array) / sizeof(usage_array[0]);
+
+	if (num_messages == 0)
+		return 0;
+
+	qsort(usage_array,
+		num_messages, sizeof(usage_array[0]),
+		compare_func);
+
+	col = 0;
+	for (i = 0; i < num_messages; i++) {
+		len2 = strlen(usage_array[i].aname) + 2;
+		if (col >= 76 - len2) {
+			printf(",\n");
+			col = 0;
+		}
+		if (col == 0) {
+			col = 6;
+			printf("\t");
+		} else {
+			printf(", ");
+		}
+		printf(usage_array[i].aname);
+		col += len2;
+	}
+	printf("\n\n");
+
+	printf("=head1 COMMAND DESCRIPTIONS\n\n");
+	printf("=over 4\n\n");
+
+	for (i = 0; i < num_messages; i++) {
+		if (usage_array[i].aname[0] >= 'a' && usage_array[i].aname[0] <= 'z'
+		 && usage_array[i].usage[0] != NOUSAGE_STR[0]
+		) {
+			printf("=item B<%s>\n\n", usage_array[i].aname);
+			if (usage_array[i].usage[0])
+				printf("%s %s\n\n", usage_array[i].aname, usage_array[i].usage);
+			else
+				printf("%s\n\n", usage_array[i].aname);
+		}
+	}
+	return 0;
+}
+
+/* TODO: we used to make options bold with B<> and output an example too:
+
+=item B<cat>
+
+cat [B<-u>] [FILE]...
+
+Concatenate FILE(s) and print them to stdout
+
+Options:
+        -u      Use unbuffered i/o (ignored)
+
+Example:
+        $ cat /proc/uptime
+        110716.72 17.67
+
+*/
diff --git a/busybox-1.19.3/arch/i386/Makefile b/busybox-1.19.3/arch/i386/Makefile
new file mode 100644
index 0000000..e6c99c6
--- /dev/null
+++ b/busybox-1.19.3/arch/i386/Makefile
@@ -0,0 +1,7 @@
+# ==========================================================================
+# Build system
+# ==========================================================================
+
+# -mpreferred-stack-boundary=2 is essential in preventing gcc 4.2.x
+# from aligning stack to 16 bytes. (Which is gcc's way of supporting SSE).
+CFLAGS += $(call cc-option,-march=i386 -mpreferred-stack-boundary=2,)
diff --git a/busybox-1.19.3/archival/Config.src b/busybox-1.19.3/archival/Config.src
new file mode 100644
index 0000000..81788ec
--- /dev/null
+++ b/busybox-1.19.3/archival/Config.src
@@ -0,0 +1,379 @@
+#
+# For a description of the syntax of this configuration file,
+# see scripts/kbuild/config-language.txt.
+#
+
+menu "Archival Utilities"
+
+INSERT
+
+config FEATURE_SEAMLESS_XZ
+	bool "Make tar, rpm, modprobe etc understand .xz data"
+	default y
+	help
+	  Make tar, rpm, modprobe etc understand .xz data.
+
+config FEATURE_SEAMLESS_LZMA
+	bool "Make tar, rpm, modprobe etc understand .lzma data"
+	default y
+	help
+	  Make tar, rpm, modprobe etc understand .lzma data.
+
+config FEATURE_SEAMLESS_BZ2
+	bool "Make tar, rpm, modprobe etc understand .bz2 data"
+	default y
+	help
+	  Make tar, rpm, modprobe etc understand .bz2 data.
+
+config FEATURE_SEAMLESS_GZ
+	bool "Make tar, rpm, modprobe etc understand .gz data"
+	default y
+	help
+	  Make tar, rpm, modprobe etc understand .gz data.
+
+config FEATURE_SEAMLESS_Z
+	bool "Make tar and gunzip understand .Z data"
+	default n
+	help
+	  Make tar and gunzip understand .Z data.
+
+config AR
+	bool "ar"
+	default n  # 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 FEATURE_AR_LONG_FILENAMES
+	bool "Support for long filenames (not needed for debs)"
+	default y
+	depends on 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 FEATURE_AR_CREATE
+	bool "Support archive creation"
+	default y
+	depends on AR
+	help
+	  This enables archive creation (-c and -r) with busybox ar.
+
+config BUNZIP2
+	bool "bunzip2"
+	default y
+	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 BZIP2
+	bool "bzip2"
+	default y
+	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 CPIO
+	bool "cpio"
+	default y
+	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 FEATURE_CPIO_O
+	bool "Support for archive creation"
+	default y
+	depends on CPIO
+	help
+	  This implementation of cpio can create cpio archives in the "newc"
+	  format only.
+
+config FEATURE_CPIO_P
+	bool "Support for passthrough mode"
+	default y
+	depends on FEATURE_CPIO_O
+	help
+	  Passthrough mode. Rarely used.
+
+config DPKG
+	bool "dpkg"
+	default n
+	select 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 DPKG_DEB
+	bool "dpkg_deb"
+	default n
+	select 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 FEATURE_DPKG_DEB_EXTRACT_ONLY
+	bool "Extract only (-x)"
+	default n
+	depends on 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 GUNZIP
+	bool "gunzip"
+	default y
+	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 GZIP
+	bool "gzip"
+	default y
+	help
+	  gzip is used to compress files.
+	  It's probably the most widely used UNIX compression program.
+
+config FEATURE_GZIP_LONG_OPTIONS
+	bool "Enable long options"
+	default y
+	depends on GZIP && LONG_OPTS
+	help
+	  Enable use of long options, increases size by about 106 Bytes
+
+config LZOP
+	bool "lzop"
+	default y
+	help
+	  Lzop compression/decompresion.
+
+config LZOP_COMPR_HIGH
+	bool "lzop compression levels 7,8,9 (not very useful)"
+	default n
+	depends on 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 RPM2CPIO
+	bool "rpm2cpio"
+	default y
+	help
+	  Converts a RPM file into a CPIO archive.
+
+config RPM
+	bool "rpm"
+	default y
+	help
+	  Mini RPM applet - queries and extracts RPM packages.
+
+config TAR
+	bool "tar"
+	default y
+	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 FEATURE_TAR_CREATE
+	bool "Enable archive creation"
+	default y
+	depends on TAR
+	help
+	  If you enable this option you'll be able to create
+	  tar archives using the `-c' option.
+
+config FEATURE_TAR_AUTODETECT
+	bool "Autodetect compressed tarballs"
+	default y
+	depends on TAR && (FEATURE_SEAMLESS_Z || FEATURE_SEAMLESS_GZ || FEATURE_SEAMLESS_BZ2 || FEATURE_SEAMLESS_LZMA || FEATURE_SEAMLESS_XZ)
+	help
+	  With this option tar can automatically detect compressed
+	  tarballs. Currently it works only on files (not pipes etc).
+
+config FEATURE_TAR_FROM
+	bool "Enable -X (exclude from) and -T (include from) options)"
+	default y
+	depends on 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 FEATURE_TAR_OLDGNU_COMPATIBILITY
+	bool "Support for old tar header format"
+	default y
+	depends on TAR || 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 FEATURE_TAR_OLDSUN_COMPATIBILITY
+	bool "Enable untarring of tarballs with checksums produced by buggy Sun tar"
+	default y
+	depends on TAR || 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 FEATURE_TAR_GNU_EXTENSIONS
+	bool "Support for GNU tar extensions (long filenames)"
+	default y
+	depends on TAR || DPKG
+	help
+	  With this option busybox supports GNU long filenames and
+	  linknames.
+
+config FEATURE_TAR_LONG_OPTIONS
+	bool "Enable long options"
+	default y
+	depends on TAR && LONG_OPTS
+	help
+	  Enable use of long options, increases size by about 400 Bytes
+
+config FEATURE_TAR_TO_COMMAND
+	bool "Support for writing to an external program"
+	default y
+	depends on TAR && 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 FEATURE_TAR_UNAME_GNAME
+	bool "Enable use of user and group names"
+	default y
+	depends on 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 FEATURE_TAR_NOPRESERVE_TIME
+	bool "Enable -m (do not preserve time) option"
+	default y
+	depends on TAR
+	help
+	  With this option busybox supports GNU tar -m
+	  (do not preserve time) option.
+
+config FEATURE_TAR_SELINUX
+	bool "Support for extracting SELinux labels"
+	default n
+	depends on TAR && SELINUX
+	help
+	  With this option busybox supports restoring SELinux labels
+	  when extracting files from tar archives.
+
+config UNCOMPRESS
+	bool "uncompress"
+	default n
+	help
+	  uncompress is used to decompress archives created by compress.
+	  Not much used anymore, replaced by gzip/gunzip.
+
+config UNLZMA
+	bool "unlzma"
+	default y
+	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 de-compression only.
+	  On an x86 system, this applet adds about 4K.
+
+	  Unless you have a specific application which requires unlzma, you
+	  should probably say N here.
+
+config FEATURE_LZMA_FAST
+	bool "Optimize unlzma for speed"
+	default y
+	depends on UNLZMA
+	help
+	  This option reduces decompression time by about 25% at the cost of
+	  a 1K bigger binary.
+
+config LZMA
+	bool "Provide lzma alias which supports only unpacking"
+	default y
+	depends on 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 UNXZ
+	bool "unxz"
+	default y
+	help
+	  unxz is a unlzma successor.
+
+config XZ
+	bool "Provide xz alias which supports only unpacking"
+	default y
+	depends on 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 UNZIP
+	bool "unzip"
+	default y
+	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/busybox-1.19.3/archival/Kbuild.src b/busybox-1.19.3/archival/Kbuild.src
new file mode 100644
index 0000000..3466452
--- /dev/null
+++ b/busybox-1.19.3/archival/Kbuild.src
@@ -0,0 +1,30 @@
+# Makefile for busybox
+#
+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
+#
+# Licensed under GPLv2, see file LICENSE in this source tree.
+
+libs-y				+= libarchive/
+
+lib-y:=
+
+INSERT
+
+lib-$(CONFIG_AR)		+= ar.o
+lib-$(CONFIG_CPIO)		+= cpio.o
+lib-$(CONFIG_DPKG)		+= dpkg.o
+lib-$(CONFIG_DPKG_DEB)		+= dpkg_deb.o
+lib-$(CONFIG_RPM2CPIO)		+= rpm2cpio.o
+lib-$(CONFIG_RPM)		+= rpm.o
+lib-$(CONFIG_TAR)		+= tar.o
+lib-$(CONFIG_UNZIP)		+= unzip.o
+
+lib-$(CONFIG_LZOP)		+= lzop.o bbunzip.o
+lib-$(CONFIG_GZIP)		+= gzip.o bbunzip.o
+lib-$(CONFIG_BZIP2)		+= bzip2.o bbunzip.o
+
+lib-$(CONFIG_UNXZ)		+= bbunzip.o
+lib-$(CONFIG_UNLZMA)		+= bbunzip.o
+lib-$(CONFIG_BUNZIP2)		+= bbunzip.o
+lib-$(CONFIG_GUNZIP)		+= bbunzip.o
+lib-$(CONFIG_UNCOMPRESS)	+= bbunzip.o
diff --git a/busybox-1.19.3/archival/ar.c b/busybox-1.19.3/archival/ar.c
new file mode 100644
index 0000000..acad20f
--- /dev/null
+++ b/busybox-1.19.3/archival/ar.c
@@ -0,0 +1,261 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini ar implementation for busybox
+ *
+ * Copyright (C) 2000 by Glenn McGrath
+ *
+ * Based in part on BusyBox tar, Debian dpkg-deb and GNU ar.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ *
+ * Archive creation support:
+ * Copyright (C) 2010 Nokia Corporation. All rights reserved.
+ * Written by Alexander Shishkin.
+ *
+ * There is no single standard to adhere to so ar may not portable
+ * between different systems
+ * http://www.unix-systems.org/single_unix_specification_v2/xcu/ar.html
+ */
+
+//usage:#define ar_trivial_usage
+//usage:       "[-o] [-v] [-p] [-t] [-x] ARCHIVE FILES"
+//usage:#define ar_full_usage "\n\n"
+//usage:       "Extract or list FILES from an ar archive\n"
+//usage:     "\n	-o	Preserve original dates"
+//usage:     "\n	-p	Extract to stdout"
+//usage:     "\n	-t	List"
+//usage:     "\n	-x	Extract"
+//usage:     "\n	-v	Verbose"
+
+#include "libbb.h"
+#include "archive.h"
+#include "ar.h"
+
+#if ENABLE_FEATURE_AR_CREATE
+/* filter out entries with same names as specified on the command line */
+static char FAST_FUNC filter_replaceable(archive_handle_t *handle)
+{
+	if (find_list_entry(handle->accept, handle->file_header->name))
+		return EXIT_FAILURE;
+
+	return EXIT_SUCCESS;
+}
+
+static void output_ar_header(archive_handle_t *handle)
+{
+	/* GNU ar 2.19.51.0.14 creates malformed archives
+	 * if input files are >10G. It also truncates files >4GB
+	 * (uses "size mod 4G"). We abort in this case:
+	 * We could add support for up to 10G files, but this is unlikely to be useful.
+	 * Note that unpacking side limits all fields to "unsigned int" data type,
+	 * and treats "all ones" as an error indicator. Thus max we allow here is UINT_MAX-1.
+	 */
+	enum {
+		/* for 2nd field: mtime */
+		MAX11CHARS = UINT_MAX > 0xffffffff ? (unsigned)99999999999 : UINT_MAX-1,
+		/* for last field: filesize */
+		MAX10CHARS = UINT_MAX > 0xffffffff ? (unsigned)9999999999 : UINT_MAX-1,
+	};
+
+	struct file_header_t *fh = handle->file_header;
+
+	if (handle->offset & 1) {
+		xwrite(handle->src_fd, "\n", 1);
+		handle->offset++;
+	}
+
+	/* Careful! The widths should be exact. Fields must be separated */
+	if (sizeof(off_t) > 4 && fh->size > (off_t)MAX10CHARS) {
+		bb_error_msg_and_die("'%s' is bigger than ar can handle", fh->name);
+	}
+	fdprintf(handle->src_fd, "%-16.16s%-12lu%-6u%-6u%-8o%-10"OFF_FMT"u`\n",
+			fh->name,
+			(sizeof(time_t) > 4 && fh->mtime > MAX11CHARS) ? (long)0 : (long)fh->mtime,
+			fh->uid > 99999 ? 0 : (int)fh->uid,
+			fh->gid > 99999 ? 0 : (int)fh->gid,
+			(int)fh->mode & 07777777,
+			fh->size
+	);
+
+	handle->offset += AR_HEADER_LEN;
+}
+
+/*
+ * when replacing files in an existing archive, copy from the
+ * original archive those files that are to be left intact
+ */
+static void FAST_FUNC copy_data(archive_handle_t *handle)
+{
+	archive_handle_t *out_handle = handle->ar__out;
+	struct file_header_t *fh = handle->file_header;
+
+	out_handle->file_header = fh;
+	output_ar_header(out_handle);
+
+	bb_copyfd_exact_size(handle->src_fd, out_handle->src_fd, fh->size);
+	out_handle->offset += fh->size;
+}
+
+static int write_ar_header(archive_handle_t *handle)
+{
+	char *fn;
+	char fn_h[17]; /* 15 + "/" + NUL */
+	struct stat st;
+	int fd;
+
+	fn = llist_pop(&handle->accept);
+	if (!fn)
+		return -1;
+
+	xstat(fn, &st);
+
+	handle->file_header->mtime = st.st_mtime;
+	handle->file_header->uid = st.st_uid;
+	handle->file_header->gid = st.st_gid;
+	handle->file_header->mode = st.st_mode;
+	handle->file_header->size = st.st_size;
+	handle->file_header->name = fn_h;
+//TODO: if ENABLE_FEATURE_AR_LONG_FILENAMES...
+	sprintf(fn_h, "%.15s/", bb_basename(fn));
+
+	output_ar_header(handle);
+
+	fd = xopen(fn, O_RDONLY);
+	bb_copyfd_exact_size(fd, handle->src_fd, st.st_size);
+	close(fd);
+	handle->offset += st.st_size;
+
+	return 0;
+}
+
+static int write_ar_archive(archive_handle_t *handle)
+{
+	struct stat st;
+	archive_handle_t *out_handle;
+
+	xfstat(handle->src_fd, &st, handle->ar__name);
+
+	/* if archive exists, create a new handle for output.
+	 * we create it in place of the old one.
+	 */
+	if (st.st_size != 0) {
+		out_handle = init_handle();
+		xunlink(handle->ar__name);
+		out_handle->src_fd = xopen(handle->ar__name, O_WRONLY | O_CREAT | O_TRUNC);
+		out_handle->accept = handle->accept;
+	} else {
+		out_handle = handle;
+	}
+
+	handle->ar__out = out_handle;
+
+	xwrite(out_handle->src_fd, AR_MAGIC "\n", AR_MAGIC_LEN + 1);
+	out_handle->offset += AR_MAGIC_LEN + 1;
+
+	/* skip to the end of the archive if we have to append stuff */
+	if (st.st_size != 0) {
+		handle->filter = filter_replaceable;
+		handle->action_data = copy_data;
+		unpack_ar_archive(handle);
+	}
+
+	while (write_ar_header(out_handle) == 0)
+		continue;
+
+	/* optional, since we exit right after we return */
+	if (ENABLE_FEATURE_CLEAN_UP) {
+		close(handle->src_fd);
+		if (out_handle->src_fd != handle->src_fd)
+			close(out_handle->src_fd);
+	}
+
+	return EXIT_SUCCESS;
+}
+#endif /* FEATURE_AR_CREATE */
+
+static void FAST_FUNC header_verbose_list_ar(const file_header_t *file_header)
+{
+	const char *mode = bb_mode_string(file_header->mode);
+	char *mtime;
+
+	mtime = ctime(&file_header->mtime);
+	mtime[16] = ' ';
+	memmove(&mtime[17], &mtime[20], 4);
+	mtime[21] = '\0';
+	printf("%s %u/%u%7"OFF_FMT"u %s %s\n", &mode[1],
+			(int)file_header->uid, (int)file_header->gid,
+			file_header->size,
+			&mtime[4], file_header->name
+	);
+}
+
+#define AR_OPT_VERBOSE          (1 << 0)
+#define AR_OPT_PRESERVE_DATE    (1 << 1)
+/* "ar r" implies create, but warns about it. c suppresses warning.
+ * bbox accepts but ignores it: */
+#define AR_OPT_CREATE           (1 << 2)
+
+#define AR_CMD_PRINT            (1 << 3)
+#define FIRST_CMD               AR_CMD_PRINT
+#define AR_CMD_LIST             (1 << 4)
+#define AR_CMD_EXTRACT          (1 << 5)
+#define AR_CMD_INSERT           (1 << 6)
+
+int ar_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int ar_main(int argc UNUSED_PARAM, char **argv)
+{
+	archive_handle_t *archive_handle;
+	unsigned opt, t;
+
+	archive_handle = init_handle();
+
+	/* --: prepend '-' to the first argument if required */
+	/* -1: at least one param is reqd */
+	/* one of p,t,x[,r] is required */
+	opt_complementary = "--:-1:p:t:x"IF_FEATURE_AR_CREATE(":r");
+	opt = getopt32(argv, "voc""ptx"IF_FEATURE_AR_CREATE("r"));
+	argv += optind;
+
+	t = opt / FIRST_CMD;
+	if (t & (t-1)) /* more than one of p,t,x[,r] are specified */
+		bb_show_usage();
+
+	if (opt & AR_CMD_PRINT) {
+		archive_handle->action_data = data_extract_to_stdout;
+	}
+	if (opt & AR_CMD_LIST) {
+		archive_handle->action_header = header_list;
+	}
+	if (opt & AR_CMD_EXTRACT) {
+		archive_handle->action_data = data_extract_all;
+	}
+	if (opt & AR_OPT_PRESERVE_DATE) {
+		archive_handle->ah_flags |= ARCHIVE_RESTORE_DATE;
+	}
+	if (opt & AR_OPT_VERBOSE) {
+		archive_handle->action_header = header_verbose_list_ar;
+	}
+#if ENABLE_FEATURE_AR_CREATE
+	archive_handle->ar__name = *argv;
+#endif
+	archive_handle->src_fd = xopen(*argv++,
+			(opt & AR_CMD_INSERT)
+				? O_RDWR | O_CREAT
+				: O_RDONLY
+	);
+
+	if (*argv)
+		archive_handle->filter = filter_accept_list;
+	while (*argv) {
+		llist_add_to_end(&archive_handle->accept, *argv++);
+	}
+
+#if ENABLE_FEATURE_AR_CREATE
+	if (opt & AR_CMD_INSERT)
+		return write_ar_archive(archive_handle);
+#endif
+
+	unpack_ar_archive(archive_handle);
+
+	return EXIT_SUCCESS;
+}
diff --git a/busybox-1.19.3/archival/bbunzip.c b/busybox-1.19.3/archival/bbunzip.c
new file mode 100644
index 0000000..bb1ec0e
--- /dev/null
+++ b/busybox-1.19.3/archival/bbunzip.c
@@ -0,0 +1,472 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Common code for gunzip-like applets
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+#include "libbb.h"
+#include "archive.h"
+
+enum {
+	OPT_STDOUT     = 1 << 0,
+	OPT_FORCE      = 1 << 1,
+	/* only some decompressors: */
+	OPT_VERBOSE    = 1 << 2,
+	OPT_DECOMPRESS = 1 << 3,
+	OPT_TEST       = 1 << 4,
+};
+
+static
+int open_to_or_warn(int to_fd, const char *filename, int flags, int mode)
+{
+	int fd = open3_or_warn(filename, flags, mode);
+	if (fd < 0) {
+		return 1;
+	}
+	xmove_fd(fd, to_fd);
+	return 0;
+}
+
+char* FAST_FUNC append_ext(char *filename, const char *expected_ext)
+{
+	return xasprintf("%s.%s", filename, expected_ext);
+}
+
+int FAST_FUNC bbunpack(char **argv,
+	IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(unpack_info_t *info),
+	char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext),
+	const char *expected_ext
+)
+{
+	struct stat stat_buf;
+	IF_DESKTOP(long long) int status;
+	char *filename, *new_name;
+	smallint exitcode = 0;
+	unpack_info_t info;
+
+	do {
+		/* NB: new_name is *maybe* malloc'ed! */
+		new_name = NULL;
+		filename = *argv; /* can be NULL - 'streaming' bunzip2 */
+
+		if (filename && LONE_DASH(filename))
+			filename = NULL;
+
+		/* Open src */
+		if (filename) {
+			if (stat(filename, &stat_buf) != 0) {
+				bb_simple_perror_msg(filename);
+ err:
+				exitcode = 1;
+				goto free_name;
+			}
+			if (open_to_or_warn(STDIN_FILENO, filename, O_RDONLY, 0))
+				goto err;
+		}
+
+		/* Special cases: test, stdout */
+		if (option_mask32 & (OPT_STDOUT|OPT_TEST)) {
+			if (option_mask32 & OPT_TEST)
+				if (open_to_or_warn(STDOUT_FILENO, bb_dev_null, O_WRONLY, 0))
+					goto err;
+			filename = NULL;
+		}
+
+		/* Open dst if we are going to unpack to file */
+		if (filename) {
+			new_name = make_new_name(filename, expected_ext);
+			if (!new_name) {
+				bb_error_msg("%s: unknown suffix - ignored", filename);
+				goto err;
+			}
+
+			/* -f: overwrite existing output files */
+			if (option_mask32 & OPT_FORCE) {
+				unlink(new_name);
+			}
+
+			/* O_EXCL: "real" bunzip2 doesn't overwrite files */
+			/* GNU gunzip does not bail out, but goes to next file */
+			if (open_to_or_warn(STDOUT_FILENO, new_name, O_WRONLY | O_CREAT | O_EXCL,
+					stat_buf.st_mode))
+				goto err;
+		}
+
+		/* Check that the input is sane */
+		if (isatty(STDIN_FILENO) && (option_mask32 & OPT_FORCE) == 0) {
+			bb_error_msg_and_die("compressed data not read from terminal, "
+					"use -f to force it");
+		}
+
+		/* memset(&info, 0, sizeof(info)); */
+		info.mtime = 0; /* so far it has one member only */
+		status = unpacker(&info);
+		if (status < 0)
+			exitcode = 1;
+		xclose(STDOUT_FILENO); /* with error check! */
+
+		if (filename) {
+			char *del = new_name;
+			if (status >= 0) {
+				/* TODO: restore other things? */
+				if (info.mtime) {
+					struct timeval times[2];
+
+					times[1].tv_sec = times[0].tv_sec = info.mtime;
+					times[1].tv_usec = times[0].tv_usec = 0;
+					/* Note: we closed it first.
+					 * On some systems calling utimes
+					 * then closing resets the mtime
+					 * back to current time. */
+					utimes(new_name, times); /* ignoring errors */
+				}
+
+				/* Delete _compressed_ file */
+				del = filename;
+				/* restore extension (unless tgz -> tar case) */
+				if (new_name == filename)
+					filename[strlen(filename)] = '.';
+			}
+			xunlink(del);
+
+#if 0 /* Currently buggy - wrong name: "a.gz: 261% - replaced with a.gz" */
+			/* Extreme bloat for gunzip compat */
+			if (ENABLE_DESKTOP && (option_mask32 & OPT_VERBOSE) && status >= 0) {
+				fprintf(stderr, "%s: %u%% - replaced with %s\n",
+					filename, (unsigned)(stat_buf.st_size*100 / (status+1)), new_name);
+			}
+#endif
+
+ free_name:
+			if (new_name != filename)
+				free(new_name);
+		}
+	} while (*argv && *++argv);
+
+	return exitcode;
+}
+
+#if ENABLE_UNCOMPRESS || ENABLE_BUNZIP2 || ENABLE_UNLZMA || ENABLE_UNXZ
+static
+char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext)
+{
+	char *extension = strrchr(filename, '.');
+	if (!extension || strcmp(extension + 1, expected_ext) != 0) {
+		/* Mimic GNU gunzip - "real" bunzip2 tries to */
+		/* unpack file anyway, to file.out */
+		return NULL;
+	}
+	*extension = '\0';
+	return filename;
+}
+#endif
+
+
+/*
+ * Uncompress applet for busybox (c) 2002 Glenn McGrath
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+//usage:#define uncompress_trivial_usage
+//usage:       "[-cf] [FILE]..."
+//usage:#define uncompress_full_usage "\n\n"
+//usage:       "Decompress .Z file[s]\n"
+//usage:     "\n	-c	Write to stdout"
+//usage:     "\n	-f	Overwrite"
+
+#if ENABLE_UNCOMPRESS
+static
+IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(unpack_info_t *info UNUSED_PARAM)
+{
+	IF_DESKTOP(long long) int status = -1;
+
+	if ((xread_char(STDIN_FILENO) != 0x1f) || (xread_char(STDIN_FILENO) != 0x9d)) {
+		bb_error_msg("invalid magic");
+	} else {
+		status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO);
+	}
+	return status;
+}
+int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int uncompress_main(int argc UNUSED_PARAM, char **argv)
+{
+	getopt32(argv, "cf");
+	argv += optind;
+
+	return bbunpack(argv, unpack_uncompress, make_new_name_generic, "Z");
+}
+#endif
+
+
+/*
+ * Gzip implementation for busybox
+ *
+ * Based on GNU gzip v1.2.4 Copyright (C) 1992-1993 Jean-loup Gailly.
+ *
+ * Originally adjusted for busybox by Sven Rudolph <sr1@inf.tu-dresden.de>
+ * based on gzip sources
+ *
+ * Adjusted further by Erik Andersen <andersen@codepoet.org> to support files as
+ * well as stdin/stdout, and to generally behave itself wrt command line
+ * handling.
+ *
+ * General cleanup to better adhere to the style guide and make use of standard
+ * busybox functions by Glenn McGrath
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ *
+ * gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
+ * Copyright (C) 1992-1993 Jean-loup Gailly
+ * The unzip code was written and put in the public domain by Mark Adler.
+ * Portions of the lzw code are derived from the public domain 'compress'
+ * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
+ * Ken Turkowski, Dave Mack and Peter Jannesen.
+ *
+ * See the license_msg below and the file COPYING for the software license.
+ * See the file algorithm.doc for the compression algorithms and file formats.
+ */
+
+//usage:#define gunzip_trivial_usage
+//usage:       "[-cft] [FILE]..."
+//usage:#define gunzip_full_usage "\n\n"
+//usage:       "Decompress FILEs (or stdin)\n"
+//usage:     "\n	-c	Write to stdout"
+//usage:     "\n	-f	Force"
+//usage:     "\n	-t	Test file integrity"
+//usage:
+//usage:#define gunzip_example_usage
+//usage:       "$ ls -la /tmp/BusyBox*\n"
+//usage:       "-rw-rw-r--    1 andersen andersen   557009 Apr 11 10:55 /tmp/BusyBox-0.43.tar.gz\n"
+//usage:       "$ gunzip /tmp/BusyBox-0.43.tar.gz\n"
+//usage:       "$ ls -la /tmp/BusyBox*\n"
+//usage:       "-rw-rw-r--    1 andersen andersen  1761280 Apr 14 17:47 /tmp/BusyBox-0.43.tar\n"
+//usage:
+//usage:#define zcat_trivial_usage
+//usage:       "FILE"
+//usage:#define zcat_full_usage "\n\n"
+//usage:       "Decompress to stdout"
+
+#if ENABLE_GUNZIP
+static
+char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UNUSED_PARAM)
+{
+	char *extension = strrchr(filename, '.');
+
+	if (!extension)
+		return NULL;
+
+	extension++;
+	if (strcmp(extension, "tgz" + 1) == 0
+#if ENABLE_FEATURE_SEAMLESS_Z
+	 || (extension[0] == 'Z' && extension[1] == '\0')
+#endif
+	) {
+		extension[-1] = '\0';
+	} else if (strcmp(extension, "tgz") == 0) {
+		filename = xstrdup(filename);
+		extension = strrchr(filename, '.');
+		extension[2] = 'a';
+		extension[3] = 'r';
+	} else {
+		return NULL;
+	}
+	return filename;
+}
+static
+IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(unpack_info_t *info)
+{
+	IF_DESKTOP(long long) int status = -1;
+
+	/* do the decompression, and cleanup */
+	if (xread_char(STDIN_FILENO) == 0x1f) {
+		unsigned char magic2;
+
+		magic2 = xread_char(STDIN_FILENO);
+		if (ENABLE_FEATURE_SEAMLESS_Z && magic2 == 0x9d) {
+			status = unpack_Z_stream(STDIN_FILENO, STDOUT_FILENO);
+		} else if (magic2 == 0x8b) {
+			status = unpack_gz_stream_with_info(STDIN_FILENO, STDOUT_FILENO, info);
+		} else {
+			goto bad_magic;
+		}
+		if (status < 0) {
+			bb_error_msg("error inflating");
+		}
+	} else {
+ bad_magic:
+		bb_error_msg("invalid magic");
+		/* status is still == -1 */
+	}
+	return status;
+}
+/*
+ * Linux kernel build uses gzip -d -n. We accept and ignore it.
+ * Man page says:
+ * -n --no-name
+ * gzip: do not save the original file name and time stamp.
+ * (The original name is always saved if the name had to be truncated.)
+ * gunzip: do not restore the original file name/time even if present
+ * (remove only the gzip suffix from the compressed file name).
+ * This option is the default when decompressing.
+ * -N --name
+ * gzip: always save the original file name and time stamp (this is the default)
+ * gunzip: restore the original file name and time stamp if present.
+ */
+int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int gunzip_main(int argc UNUSED_PARAM, char **argv)
+{
+	getopt32(argv, "cfvdtn");
+	argv += optind;
+	/* if called as zcat */
+	if (applet_name[1] == 'c')
+		option_mask32 |= OPT_STDOUT;
+
+	return bbunpack(argv, unpack_gunzip, make_new_name_gunzip, /*unused:*/ NULL);
+}
+#endif
+
+
+/*
+ * Modified for busybox by Glenn McGrath
+ * Added support output to stdout by Thomas Lundquist <thomasez@zelow.no>
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+//usage:#define bunzip2_trivial_usage
+//usage:       "[-cf] [FILE]..."
+//usage:#define bunzip2_full_usage "\n\n"
+//usage:       "Decompress FILEs (or stdin)\n"
+//usage:     "\n	-c	Write to stdout"
+//usage:     "\n	-f	Force"
+//usage:#define bzcat_trivial_usage
+//usage:       "FILE"
+//usage:#define bzcat_full_usage "\n\n"
+//usage:       "Decompress to stdout"
+//applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP))
+//applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat))
+#if ENABLE_BUNZIP2
+static
+IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(unpack_info_t *info UNUSED_PARAM)
+{
+	return unpack_bz2_stream_prime(STDIN_FILENO, STDOUT_FILENO);
+}
+int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int bunzip2_main(int argc UNUSED_PARAM, char **argv)
+{
+	getopt32(argv, "cfvdt");
+	argv += optind;
+	if (applet_name[2] == 'c') /* bzcat */
+		option_mask32 |= OPT_STDOUT;
+
+	return bbunpack(argv, unpack_bunzip2, make_new_name_generic, "bz2");
+}
+#endif
+
+
+/*
+ * Small lzma deflate implementation.
+ * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
+ *
+ * Based on bunzip.c from busybox
+ *
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+
+//usage:#define unlzma_trivial_usage
+//usage:       "[-cf] [FILE]..."
+//usage:#define unlzma_full_usage "\n\n"
+//usage:       "Decompress FILE (or stdin)\n"
+//usage:     "\n	-c	Write to stdout"
+//usage:     "\n	-f	Force"
+//usage:
+//usage:#define lzma_trivial_usage
+//usage:       "-d [-cf] [FILE]..."
+//usage:#define lzma_full_usage "\n\n"
+//usage:       "Decompress FILE (or stdin)\n"
+//usage:     "\n	-d	Decompress"
+//usage:     "\n	-c	Write to stdout"
+//usage:     "\n	-f	Force"
+//usage:
+//usage:#define lzcat_trivial_usage
+//usage:       "FILE"
+//usage:#define lzcat_full_usage "\n\n"
+//usage:       "Decompress to stdout"
+//usage:
+//usage:#define unxz_trivial_usage
+//usage:       "[-cf] [FILE]..."
+//usage:#define unxz_full_usage "\n\n"
+//usage:       "Decompress FILE (or stdin)\n"
+//usage:     "\n	-c	Write to stdout"
+//usage:     "\n	-f	Force"
+//usage:
+//usage:#define xz_trivial_usage
+//usage:       "-d [-cf] [FILE]..."
+//usage:#define xz_full_usage "\n\n"
+//usage:       "Decompress FILE (or stdin)\n"
+//usage:     "\n	-d	Decompress"
+//usage:     "\n	-c	Write to stdout"
+//usage:     "\n	-f	Force"
+//usage:
+//usage:#define xzcat_trivial_usage
+//usage:       "FILE"
+//usage:#define xzcat_full_usage "\n\n"
+//usage:       "Decompress to stdout"
+
+#if ENABLE_UNLZMA
+static
+IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(unpack_info_t *info UNUSED_PARAM)
+{
+	return unpack_lzma_stream(STDIN_FILENO, STDOUT_FILENO);
+}
+int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int unlzma_main(int argc UNUSED_PARAM, char **argv)
+{
+	IF_LZMA(int opts =) getopt32(argv, "cfvdt");
+# if ENABLE_LZMA
+	/* lzma without -d or -t? */
+	if (applet_name[2] == 'm' && !(opts & (OPT_DECOMPRESS|OPT_TEST)))
+		bb_show_usage();
+# endif
+	/* lzcat? */
+	if (applet_name[2] == 'c')
+		option_mask32 |= OPT_STDOUT;
+
+	argv += optind;
+	return bbunpack(argv, unpack_unlzma, make_new_name_generic, "lzma");
+}
+#endif
+
+
+#if ENABLE_UNXZ
+static
+IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(unpack_info_t *info UNUSED_PARAM)
+{
+	struct {
+		uint32_t v1;
+		uint16_t v2;
+	} magic;
+	xread(STDIN_FILENO, &magic, 6);
+	if (magic.v1 != XZ_MAGIC1a || magic.v2 != XZ_MAGIC2a) {
+		bb_error_msg("invalid magic");
+		return -1;
+	}
+	return unpack_xz_stream(STDIN_FILENO, STDOUT_FILENO);
+}
+int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int unxz_main(int argc UNUSED_PARAM, char **argv)
+{
+	IF_XZ(int opts =) getopt32(argv, "cfvdt");
+# if ENABLE_XZ
+	/* xz without -d or -t? */
+	if (applet_name[2] == '\0' && !(opts & (OPT_DECOMPRESS|OPT_TEST)))
+		bb_show_usage();
+# endif
+	/* xzcat? */
+	if (applet_name[2] == 'c')
+		option_mask32 |= OPT_STDOUT;
+
+	argv += optind;
+	return bbunpack(argv, unpack_unxz, make_new_name_generic, "xz");
+}
+#endif
diff --git a/busybox-1.19.3/archival/bbunzip_test.sh b/busybox-1.19.3/archival/bbunzip_test.sh
new file mode 100644
index 0000000..b8e31bf
--- /dev/null
+++ b/busybox-1.19.3/archival/bbunzip_test.sh
@@ -0,0 +1,61 @@
+#!/bin/sh
+# Test that concatenated gz files are unpacking correctly.
+# It also tests that unpacking in general is working right.
+# Since zip code has many corner cases, run it for a few hours
+# to get a decent coverage (200000 tests or more).
+
+gzip="gzip"
+gunzip="../busybox gunzip"
+# Or the other way around:
+#gzip="../busybox gzip"
+#gunzip="gunzip"
+
+c=0
+i=$PID
+while true; do
+    c=$((c+1))
+
+    # RANDOM is not very random on some shells. Spice it up.
+    # 100003 is prime
+    len1=$(( (((RANDOM*RANDOM)^i) & 0x7ffffff) % 100003 ))
+    i=$((i * 1664525 + 1013904223))
+    len2=$(( (((RANDOM*RANDOM)^i) & 0x7ffffff) % 100003 ))
+
+    # Just using urandom will make gzip use method 0 (store) -
+    # not good for test coverage!
+    cat /dev/urandom | while true; do read junk; echo "junk $c $i $junk"; done \
+    | dd bs=$len1 count=1 >z1 2>/dev/null
+    cat /dev/urandom | while true; do read junk; echo "junk $c $i $junk"; done \
+    | dd bs=$len2 count=1 >z2 2>/dev/null
+
+    $gzip <z1 >zz.gz
+    $gzip <z2 >>zz.gz
+    $gunzip -c zz.gz >z9 || {
+	echo "Exitcode $?"
+	exit
+    }
+    sum=`cat z1 z2 | md5sum`
+    sum9=`md5sum <z9`
+    test "$sum" == "$sum9" || {
+	echo "md5sums don't match"
+	exit
+    }
+    echo "Test $c ok: len1=$len1 len2=$len2 sum=$sum"
+
+    sum=`cat z1 z2 z1 z2 | md5sum`
+    rm z1.gz z2.gz 2>/dev/null
+    $gzip z1
+    $gzip z2
+    cat z1.gz z2.gz z1.gz z2.gz >zz.gz
+    $gunzip -c zz.gz >z9 || {
+	echo "Exitcode $? (2)"
+	exit
+    }
+    sum9=`md5sum <z9`
+    test "$sum" == "$sum9" || {
+	echo "md5sums don't match (1)"
+	exit
+    }
+
+    echo "Test $c ok: len1=$len1 len2=$len2 sum=$sum (2)"
+done
diff --git a/busybox-1.19.3/archival/bbunzip_test2.sh b/busybox-1.19.3/archival/bbunzip_test2.sh
new file mode 100644
index 0000000..5b7e83e
--- /dev/null
+++ b/busybox-1.19.3/archival/bbunzip_test2.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+# Leak test for gunzip. Watch top for growing process size.
+
+# Just using urandom will make gzip use method 0 (store) -
+# not good for test coverage!
+
+cat /dev/urandom \
+| while true; do read junk; echo "junk $RANDOM $junk"; done \
+| ../busybox gzip \
+| ../busybox gunzip -c >/dev/null
diff --git a/busybox-1.19.3/archival/bbunzip_test3.sh b/busybox-1.19.3/archival/bbunzip_test3.sh
new file mode 100644
index 0000000..2dc4afd
--- /dev/null
+++ b/busybox-1.19.3/archival/bbunzip_test3.sh
@@ -0,0 +1,23 @@
+#!/bin/sh
+# Leak test for gunzip. Watch top for growing process size.
+# In this case we look for leaks in "concatenated .gz" code -
+# we feed gunzip with a stream of .gz files.
+
+i=$PID
+c=0
+while true; do
+    c=$((c + 1))
+    echo "Block# $c" >&2
+    # RANDOM is not very random on some shells. Spice it up.
+    i=$((i * 1664525 + 1013904223))
+    # 100003 is prime
+    len=$(( (((RANDOM*RANDOM)^i) & 0x7ffffff) % 100003 ))
+
+    # Just using urandom will make gzip use method 0 (store) -
+    # not good for test coverage!
+    cat /dev/urandom \
+    | while true; do read junk; echo "junk $c $i $junk"; done \
+    | dd bs=$len count=1 2>/dev/null \
+    | gzip >xxx.gz
+    cat xxx.gz xxx.gz xxx.gz xxx.gz xxx.gz xxx.gz xxx.gz xxx.gz
+done | ../busybox gunzip -c >/dev/null
diff --git a/busybox-1.19.3/archival/bzip2.c b/busybox-1.19.3/archival/bzip2.c
new file mode 100644
index 0000000..e39d7f7
--- /dev/null
+++ b/busybox-1.19.3/archival/bzip2.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright (C) 2007 Denys Vlasenko <vda.linux@googlemail.com>
+ *
+ * This file uses bzip2 library code which is written
+ * by Julian Seward <jseward@bzip.org>.
+ * See README and LICENSE files in bz/ directory for more information
+ * about bzip2 library code.
+ */
+
+//usage:#define bzip2_trivial_usage
+//usage:       "[OPTIONS] [FILE]..."
+//usage:#define bzip2_full_usage "\n\n"
+//usage:       "Compress FILEs (or stdin) with bzip2 algorithm\n"
+//usage:     "\n	-1..9	Compression level"
+//usage:     "\n	-d	Decompress"
+//usage:     "\n	-c	Write to stdout"
+//usage:     "\n	-f	Force"
+
+#include "libbb.h"
+#include "archive.h"
+
+#define CONFIG_BZIP2_FEATURE_SPEED 1
+
+/* Speed test:
+ * Compiled with gcc 4.2.1, run on Athlon 64 1800 MHz (512K L2 cache).
+ * Stock bzip2 is 26.4% slower than bbox bzip2 at SPEED 1
+ * (time to compress gcc-4.2.1.tar is 126.4% compared to bbox).
+ * At SPEED 5 difference is 32.7%.
+ *
+ * Test run of all CONFIG_BZIP2_FEATURE_SPEED values on a 11Mb text file:
+ *     Size   Time (3 runs)
+ * 0:  10828  4.145 4.146 4.148
+ * 1:  11097  3.845 3.860 3.861
+ * 2:  11392  3.763 3.767 3.768
+ * 3:  11892  3.722 3.724 3.727
+ * 4:  12740  3.637 3.640 3.644
+ * 5:  17273  3.497 3.509 3.509
+ */
+
+
+#define BZ_DEBUG 0
+/* Takes ~300 bytes, detects corruption caused by bad RAM etc */
+#define BZ_LIGHT_DEBUG 0
+
+#include "libarchive/bz/bzlib.h"
+
+#include "libarchive/bz/bzlib_private.h"
+
+#include "libarchive/bz/blocksort.c"
+#include "libarchive/bz/bzlib.c"
+#include "libarchive/bz/compress.c"
+#include "libarchive/bz/huffman.c"
+
+/* No point in being shy and having very small buffer here.
+ * bzip2 internal buffers are much bigger anyway, hundreds of kbytes.
+ * If iobuf is several pages long, malloc() may use mmap,
+ * making iobuf is page aligned and thus (maybe) have one memcpy less
+ * if kernel is clever enough.
+ */
+enum {
+	IOBUF_SIZE = 8 * 1024
+};
+
+static uint8_t level;
+
+/* NB: compressStream() has to return -1 on errors, not die.
+ * bbunpack() will correctly clean up in this case
+ * (delete incomplete .bz2 file)
+ */
+
+/* Returns:
+ * -1 on errors
+ * total written bytes so far otherwise
+ */
+static
+IF_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, void *wbuf)
+{
+	int n, n2, ret;
+
+	strm->avail_in = rlen;
+	strm->next_in = rbuf;
+	while (1) {
+		strm->avail_out = IOBUF_SIZE;
+		strm->next_out = wbuf;
+
+		ret = BZ2_bzCompress(strm, rlen ? BZ_RUN : BZ_FINISH);
+		if (ret != BZ_RUN_OK /* BZ_RUNning */
+		 && ret != BZ_FINISH_OK /* BZ_FINISHing, but not done yet */
+		 && ret != BZ_STREAM_END /* BZ_FINISHed */
+		) {
+			bb_error_msg_and_die("internal error %d", ret);
+		}
+
+		n = IOBUF_SIZE - strm->avail_out;
+		if (n) {
+			n2 = full_write(STDOUT_FILENO, wbuf, n);
+			if (n2 != n) {
+				if (n2 >= 0)
+					errno = 0; /* prevent bogus error message */
+				bb_perror_msg(n2 >= 0 ? "short write" : bb_msg_write_error);
+				return -1;
+			}
+		}
+
+		if (ret == BZ_STREAM_END)
+			break;
+		if (rlen && strm->avail_in == 0)
+			break;
+	}
+	return 0 IF_DESKTOP( + strm->total_out );
+}
+
+static
+IF_DESKTOP(long long) int FAST_FUNC compressStream(unpack_info_t *info UNUSED_PARAM)
+{
+	IF_DESKTOP(long long) int total;
+	ssize_t count;
+	bz_stream bzs; /* it's small */
+#define strm (&bzs)
+	char *iobuf;
+#define rbuf iobuf
+#define wbuf (iobuf + IOBUF_SIZE)
+
+	iobuf = xmalloc(2 * IOBUF_SIZE);
+	BZ2_bzCompressInit(strm, level);
+
+	while (1) {
+		count = full_read(STDIN_FILENO, rbuf, IOBUF_SIZE);
+		if (count < 0) {
+			bb_perror_msg(bb_msg_read_error);
+			total = -1;
+			break;
+		}
+		/* if count == 0, bz_write finalizes compression */
+		total = bz_write(strm, rbuf, count, wbuf);
+		if (count == 0 || total < 0)
+			break;
+	}
+
+	/* Can't be conditional on ENABLE_FEATURE_CLEAN_UP -
+	 * we are called repeatedly
+	 */
+	BZ2_bzCompressEnd(strm);
+	free(iobuf);
+
+	return total;
+}
+
+int bzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int bzip2_main(int argc UNUSED_PARAM, char **argv)
+{
+	unsigned opt;
+
+	/* standard bzip2 flags
+	 * -d --decompress force decompression
+	 * -z --compress force compression
+	 * -k --keep     keep (don't delete) input files
+	 * -f --force    overwrite existing output files
+	 * -t --test     test compressed file integrity
+	 * -c --stdout   output to standard out
+	 * -q --quiet    suppress noncritical error messages
+	 * -v --verbose  be verbose (a 2nd -v gives more)
+	 * -s --small    use less memory (at most 2500k)
+	 * -1 .. -9      set block size to 100k .. 900k
+	 * --fast        alias for -1
+	 * --best        alias for -9
+	 */
+
+	opt_complementary = "s2"; /* -s means -2 (compatibility) */
+	/* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */
+	opt = getopt32(argv, "cfv" IF_BUNZIP2("dt") "123456789qzs");
+#if ENABLE_BUNZIP2 /* bunzip2_main may not be visible... */
+	if (opt & 0x18) // -d and/or -t
+		return bunzip2_main(argc, argv);
+	opt >>= 5;
+#else
+	opt >>= 3;
+#endif
+	opt = (uint8_t)opt; /* isolate bits for -1..-8 */
+	opt |= 0x100; /* if nothing else, assume -9 */
+	level = 1;
+	while (!(opt & 1)) {
+		level++;
+		opt >>= 1;
+	}
+
+	argv += optind;
+	option_mask32 &= 0x7; /* ignore all except -cfv */
+	return bbunpack(argv, compressStream, append_ext, "bz2");
+}
diff --git a/busybox-1.19.3/archival/cpio.c b/busybox-1.19.3/archival/cpio.c
new file mode 100644
index 0000000..9674a04
--- /dev/null
+++ b/busybox-1.19.3/archival/cpio.c
@@ -0,0 +1,458 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Mini cpio implementation for busybox
+ *
+ * Copyright (C) 2001 by Glenn McGrath
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ *
+ * Limitations:
+ * Doesn't check CRC's
+ * Only supports new ASCII and CRC formats
+ *
+ */
+#include "libbb.h"
+#include "archive.h"
+
+//usage:#define cpio_trivial_usage
+//usage:       "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]")
+//usage:       " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]")
+//usage:       " [EXTR_FILE]..."
+//usage:#define cpio_full_usage "\n\n"
+//usage:       "Extract or list files from a cpio archive"
+//usage:	IF_FEATURE_CPIO_O(", or"
+//usage:     "\ncreate an archive" IF_FEATURE_CPIO_P(" (-o) or copy files (-p)")
+//usage:		" using file list on stdin"
+//usage:	)
+//usage:     "\n"
+//usage:     "\nMain operation mode:"
+//usage:     "\n	-t	List"
+//usage:     "\n	-i	Extract EXTR_FILEs (or all)"
+//usage:	IF_FEATURE_CPIO_O(
+//usage:     "\n	-o	Create (requires -H newc)"
+//usage:	)
+//usage:	IF_FEATURE_CPIO_P(
+//usage:     "\n	-p DIR	Copy files to DIR"
+//usage:	)
+//usage:     "\n	-d	Make leading directories"
+//usage:     "\n	-m	Preserve mtime"
+//usage:     "\n	-v	Verbose"
+//usage:     "\n	-u	Overwrite"
+//usage:     "\n	-F FILE	Input (-t,-i,-p) or output (-o) file"
+//usage:	IF_FEATURE_CPIO_O(
+//usage:     "\n	-H newc	Archive format"
+//usage:	)
+
+/* GNU cpio 2.9 --help (abridged):
+
+ Modes:
+  -t, --list                 List the archive
+  -i, --extract              Extract files from an archive
+  -o, --create               Create the archive
+  -p, --pass-through         Copy-pass mode
+
+ Options valid in any mode:
+      --block-size=SIZE      I/O block size = SIZE * 512 bytes
+  -B                         I/O block size = 5120 bytes
+  -c                         Use the old portable (ASCII) archive format
+  -C, --io-size=NUMBER       I/O block size in bytes
+  -f, --nonmatching          Only copy files that do not match given pattern
+  -F, --file=FILE            Use FILE instead of standard input or output
+  -H, --format=FORMAT        Use given archive FORMAT
+  -M, --message=STRING       Print STRING when the end of a volume of the
+                             backup media is reached
+  -n, --numeric-uid-gid      If -v, show numeric UID and GID
+      --quiet                Do not print the number of blocks copied
+      --rsh-command=COMMAND  Use remote COMMAND instead of rsh
+  -v, --verbose              Verbosely list the files processed
+  -V, --dot                  Print a "." for each file processed
+  -W, --warning=FLAG         Control warning display: 'none','truncate','all';
+                             multiple options accumulate
+
+ Options valid only in --extract mode:
+  -b, --swap                 Swap both halfwords of words and bytes of
+                             halfwords in the data (equivalent to -sS)
+  -r, --rename               Interactively rename files
+  -s, --swap-bytes           Swap the bytes of each halfword in the files
+  -S, --swap-halfwords       Swap the halfwords of each word (4 bytes)
+      --to-stdout            Extract files to standard output
+  -E, --pattern-file=FILE    Read additional patterns specifying filenames to
+                             extract or list from FILE
+      --only-verify-crc      Verify CRC's, don't actually extract the files
+
+ Options valid only in --create mode:
+  -A, --append               Append to an existing archive
+  -O FILE                    File to use instead of standard output
+
+ Options valid only in --pass-through mode:
+  -l, --link                 Link files instead of copying them, when possible
+
+ Options valid in --extract and --create modes:
+      --absolute-filenames   Do not strip file system prefix components from
+                             the file names
+      --no-absolute-filenames Create all files relative to the current dir
+
+ Options valid in --create and --pass-through modes:
+  -0, --null                 A list of filenames is terminated by a NUL
+  -a, --reset-access-time    Reset the access times of files after reading them
+  -I FILE                    File to use instead of standard input
+  -L, --dereference          Dereference symbolic links (copy the files
+                             that they point to instead of copying the links)
+  -R, --owner=[USER][:.][GROUP] Set owner of created files
+
+ Options valid in --extract and --pass-through modes:
+  -d, --make-directories     Create leading directories where needed
+  -m, --preserve-modification-time  Retain mtime when creating files
+      --no-preserve-owner    Do not change the ownership of the files
+      --sparse               Write files with blocks of zeros as sparse files
+  -u, --unconditional        Replace all files unconditionally
+ */
+
+enum {
+	OPT_EXTRACT            = (1 << 0),
+	OPT_TEST               = (1 << 1),
+	OPT_NUL_TERMINATED     = (1 << 2),
+	OPT_UNCONDITIONAL      = (1 << 3),
+	OPT_VERBOSE            = (1 << 4),
+	OPT_CREATE_LEADING_DIR = (1 << 5),
+	OPT_PRESERVE_MTIME     = (1 << 6),
+	OPT_DEREF              = (1 << 7),
+	OPT_FILE               = (1 << 8),
+	OPTBIT_FILE = 8,
+	IF_FEATURE_CPIO_O(OPTBIT_CREATE     ,)
+	IF_FEATURE_CPIO_O(OPTBIT_FORMAT     ,)
+	IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,)
+	IF_LONG_OPTS(     OPTBIT_QUIET      ,)
+	IF_LONG_OPTS(     OPTBIT_2STDOUT    ,)
+	OPT_CREATE             = IF_FEATURE_CPIO_O((1 << OPTBIT_CREATE     )) + 0,
+	OPT_FORMAT             = IF_FEATURE_CPIO_O((1 << OPTBIT_FORMAT     )) + 0,
+	OPT_PASSTHROUGH        = IF_FEATURE_CPIO_P((1 << OPTBIT_PASSTHROUGH)) + 0,
+	OPT_QUIET              = IF_LONG_OPTS(     (1 << OPTBIT_QUIET      )) + 0,
+	OPT_2STDOUT            = IF_LONG_OPTS(     (1 << OPTBIT_2STDOUT    )) + 0,
+};
+
+#define OPTION_STR "it0uvdmLF:"
+
+#if ENABLE_FEATURE_CPIO_O
+static off_t cpio_pad4(off_t size)
+{
+	int i;
+
+	i = (- size) & 3;
+	size += i;
+	while (--i >= 0)
+		bb_putchar('\0');
+	return size;
+}
+
+/* Return value will become exit code.
+ * It's ok to exit instead of return. */
+static NOINLINE int cpio_o(void)
+{
+	static const char trailer[] ALIGN1 = "TRAILER!!!";
+	struct name_s {
+		struct name_s *next;
+		char name[1];
+	};
+	struct inodes_s {
+		struct inodes_s *next;
+		struct name_s *names;
+		struct stat st;
+	};
+
+	struct inodes_s *links = NULL;
+	off_t bytes = 0; /* output bytes count */
+
+	while (1) {
+		const char *name;
+		char *line;
+		struct stat st;
+
+		line = (option_mask32 & OPT_NUL_TERMINATED)
+				? bb_get_chunk_from_file(stdin, NULL)
+				: xmalloc_fgetline(stdin);
+
+		if (line) {
+			/* Strip leading "./[./]..." from the filename */
+			name = line;
+			while (name[0] == '.' && name[1] == '/') {
+				while (*++name == '/')
+					continue;
+			}
+			if (!*name) { /* line is empty */
+				free(line);
+				continue;
+			}
+			if ((option_mask32 & OPT_DEREF)
+					? stat(name, &st)
+					: lstat(name, &st)
+			) {
+ abort_cpio_o:
+				bb_simple_perror_msg_and_die(name);
+			}
+
+			if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode)))
+				st.st_size = 0; /* paranoia */
+
+			/* Store hardlinks for later processing, dont output them */
+			if (!S_ISDIR(st.st_mode) && st.st_nlink > 1) {
+				struct name_s *n;
+				struct inodes_s *l;
+
+				/* Do we have this hardlink remembered? */
+				l = links;
+				while (1) {
+					if (l == NULL) {
+						/* Not found: add new item to "links" list */
+						l = xzalloc(sizeof(*l));
+						l->st = st;
+						l->next = links;
+						links = l;
+						break;
+					}
+					if (l->st.st_ino == st.st_ino) {
+						/* found */
+						break;
+					}
+					l = l->next;
+				}
+				/* Add new name to "l->names" list */
+				n = xmalloc(sizeof(*n) + strlen(name));
+				strcpy(n->name, name);
+				n->next = l->names;
+				l->names = n;
+
+				free(line);
+				continue;
+			}
+
+		} else { /* line == NULL: EOF */
+ next_link:
+			if (links) {
+				/* Output hardlink's data */
+				st = links->st;
+				name = links->names->name;
+				links->names = links->names->next;
+				/* GNU cpio is reported to emit file data
+				 * only for the last instance. Mimic that. */
+				if (links->names == NULL)
+					links = links->next;
+				else
+					st.st_size = 0;
+				/* NB: we leak links->names and/or links,
+				 * this is intended (we exit soon anyway) */
+			} else {
+				/* If no (more) hardlinks to output,
+				 * output "trailer" entry */
+				name = trailer;
+				/* st.st_size == 0 is a must, but for uniformity
+				 * in the output, we zero out everything */
+				memset(&st, 0, sizeof(st));
+				/* st.st_nlink = 1; - GNU cpio does this */
+			}
+		}
+
+		bytes += printf("070701"
+		                "%08X%08X%08X%08X%08X%08X%08X"
+		                "%08X%08X%08X%08X" /* GNU cpio uses uppercase hex */
+				/* strlen+1: */ "%08X"
+				/* chksum: */   "00000000" /* (only for "070702" files) */
+				/* name,NUL: */ "%s%c",
+		                (unsigned)(uint32_t) st.st_ino,
+		                (unsigned)(uint32_t) st.st_mode,
+		                (unsigned)(uint32_t) st.st_uid,
+		                (unsigned)(uint32_t) st.st_gid,
+		                (unsigned)(uint32_t) st.st_nlink,
+		                (unsigned)(uint32_t) st.st_mtime,
+		                (unsigned)(uint32_t) st.st_size,
+		                (unsigned)(uint32_t) major(st.st_dev),
+		                (unsigned)(uint32_t) minor(st.st_dev),
+		                (unsigned)(uint32_t) major(st.st_rdev),
+		                (unsigned)(uint32_t) minor(st.st_rdev),
+		                (unsigned)(strlen(name) + 1),
+		                name, '\0');
+		bytes = cpio_pad4(bytes);
+
+		if (st.st_size) {
+			if (S_ISLNK(st.st_mode)) {
+				char *lpath = xmalloc_readlink_or_warn(name);
+				if (!lpath)
+					goto abort_cpio_o;
+				bytes += printf("%s", lpath);
+				free(lpath);
+			} else { /* S_ISREG */
+				int fd = xopen(name, O_RDONLY);
+				fflush_all();
+				/* We must abort if file got shorter too! */
+				bb_copyfd_exact_size(fd, STDOUT_FILENO, st.st_size);
+				bytes += st.st_size;
+				close(fd);
+			}
+			bytes = cpio_pad4(bytes);
+		}
+
+		if (!line) {
+			if (name != trailer)
+				goto next_link;
+			/* TODO: GNU cpio pads trailer to 512 bytes, do we want that? */
+			return EXIT_SUCCESS;
+		}
+
+		free(line);
+	} /* end of "while (1)" */
+}
+#endif
+
+int cpio_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int cpio_main(int argc UNUSED_PARAM, char **argv)
+{
+	archive_handle_t *archive_handle;
+	char *cpio_filename;
+	IF_FEATURE_CPIO_O(const char *cpio_fmt = "";)
+	unsigned opt;
+
+#if ENABLE_LONG_OPTS
+	applet_long_options =
+		"extract\0"      No_argument       "i"
+		"list\0"         No_argument       "t"
+#if ENABLE_FEATURE_CPIO_O
+		"create\0"       No_argument       "o"
+		"format\0"       Required_argument "H"
+#if ENABLE_FEATURE_CPIO_P
+		"pass-through\0" No_argument       "p"
+#endif
+#endif
+		"verbose\0"      No_argument       "v"
+		"quiet\0"        No_argument       "\xff"
+		"to-stdout\0"    No_argument       "\xfe"
+		;
+#endif
+
+	archive_handle = init_handle();
+	/* archive_handle->src_fd = STDIN_FILENO; - done by init_handle */
+	archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER;
+
+	/* As of now we do not enforce this: */
+	/* -i,-t,-o,-p are mutually exclusive */
+	/* -u,-d,-m make sense only with -i or -p */
+	/* -L makes sense only with -o or -p */
+
+#if !ENABLE_FEATURE_CPIO_O
+	opt = getopt32(argv, OPTION_STR, &cpio_filename);
+	argv += optind;
+	if (opt & OPT_FILE) { /* -F */
+		xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO);
+	}
+#else
+	opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt);
+	argv += optind;
+	if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */
+		xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO);
+	}
+	if (opt & OPT_PASSTHROUGH) {
+		pid_t pid;
+		struct fd_pair pp;
+
+		if (argv[0] == NULL)
+			bb_show_usage();
+		if (opt & OPT_CREATE_LEADING_DIR)
+			mkdir(argv[0], 0777);
+		/* Crude existence check:
+		 * close(xopen(argv[0], O_RDONLY | O_DIRECTORY));
+		 * We can also xopen, fstat, IS_DIR, later fchdir.
+		 * This would check for existence earlier and cleaner.
+		 * As it stands now, if we fail xchdir later,
+		 * child dies on EPIPE, unless it caught
+		 * a diffrerent problem earlier.
+		 * This is good enough for now.
+		 */
+#if !BB_MMU
+		pp.rd = 3;
+		pp.wr = 4;
+		if (!re_execed) {
+			close(3);
+			close(4);
+			xpiped_pair(pp);
+		}
+#else
+		xpiped_pair(pp);
+#endif
+		pid = fork_or_rexec(argv - optind);
+		if (pid == 0) { /* child */
+			close(pp.rd);
+			xmove_fd(pp.wr, STDOUT_FILENO);
+			goto dump;
+		}
+		/* parent */
+		xchdir(*argv++);
+		close(pp.wr);
+		xmove_fd(pp.rd, STDIN_FILENO);
+		//opt &= ~OPT_PASSTHROUGH;
+		opt |= OPT_EXTRACT;
+		goto skip;
+	}
+	/* -o */
+	if (opt & OPT_CREATE) {
+		if (cpio_fmt[0] != 'n') /* we _require_ "-H newc" */
+			bb_show_usage();
+		if (opt & OPT_FILE) {
+			xmove_fd(xopen(cpio_filename, O_WRONLY | O_CREAT | O_TRUNC), STDOUT_FILENO);
+		}
+ dump:
+		return cpio_o();
+	}
+ skip:
+#endif
+
+	/* One of either extract or test options must be given */
+	if ((opt & (OPT_TEST | OPT_EXTRACT)) == 0) {
+		bb_show_usage();
+	}
+
+	if (opt & OPT_TEST) {
+		/* if both extract and test options are given, ignore extract option */
+		opt &= ~OPT_EXTRACT;
+		archive_handle->action_header = header_list;
+	}
+	if (opt & OPT_EXTRACT) {
+		archive_handle->action_data = data_extract_all;
+		if (opt & OPT_2STDOUT)
+			archive_handle->action_data = data_extract_to_stdout;
+	}
+	if (opt & OPT_UNCONDITIONAL) {
+		archive_handle->ah_flags |= ARCHIVE_UNLINK_OLD;
+		archive_handle->ah_flags &= ~ARCHIVE_EXTRACT_NEWER;
+	}
+	if (opt & OPT_VERBOSE) {
+		if (archive_handle->action_header == header_list) {
+			archive_handle->action_header = header_verbose_list;
+		} else {
+			archive_handle->action_header = header_list;
+		}
+	}
+	if (opt & OPT_CREATE_LEADING_DIR) {
+		archive_handle->ah_flags |= ARCHIVE_CREATE_LEADING_DIRS;
+	}
+	if (opt & OPT_PRESERVE_MTIME) {
+		archive_handle->ah_flags |= ARCHIVE_RESTORE_DATE;
+	}
+
+	while (*argv) {
+		archive_handle->filter = filter_accept_list;
+		llist_add_to(&archive_handle->accept, *argv);
+		argv++;
+	}
+
+	/* see get_header_cpio */
+	archive_handle->cpio__blocks = (off_t)-1;
+	while (get_header_cpio(archive_handle) == EXIT_SUCCESS)
+		continue;
+
+	if (archive_handle->cpio__blocks != (off_t)-1
+	 && !(opt & OPT_QUIET)
+	) {
+		fprintf(stderr, "%"OFF_FMT"u blocks\n", archive_handle->cpio__blocks);
+	}
+
+	return EXIT_SUCCESS;
+}
diff --git a/busybox-1.19.3/archival/dpkg.c b/busybox-1.19.3/archival/dpkg.c
new file mode 100644
index 0000000..2a6a7b3
--- /dev/null
+++ b/busybox-1.19.3/archival/dpkg.c
@@ -0,0 +1,1920 @@
+/* vi: set sw=4 ts=4: */
+/*
+ *  mini dpkg implementation for busybox.
+ *  this is not meant as a replacement for dpkg
+ *
+ *  written by glenn mcgrath with the help of others
+ *  copyright (c) 2001 by glenn mcgrath
+ *
+ *  parts of the version comparison code is plucked from the real dpkg
+ *  application which is licensed GPLv2 and
+ *  copyright (c) 1995 Ian Jackson <ian@chiark.greenend.org.uk>
+ *
+ *  started life as a busybox implementation of udpkg
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+/*
+ * known difference between busybox dpkg and the official dpkg that i don't
+ * consider important, its worth keeping a note of differences anyway, just to
+ * make it easier to maintain.
+ *  - the first value for the confflile: field isnt placed on a new line.
+ *  - when installing a package the status: field is placed at the end of the
+ *      section, rather than just after the package: field.
+ *
+ * bugs that need to be fixed
+ *  - (unknown, please let me know when you find any)
+ *
+ */
+
+//usage:#define dpkg_trivial_usage
+//usage:       "[-ilCPru] [-F OPT] PACKAGE"
+//usage:#define dpkg_full_usage "\n\n"
+//usage:       "Install, remove and manage Debian packages\n"
+//usage:	IF_LONG_OPTS(
+//usage:     "\n	-i,--install	Install the package"
+//usage:     "\n	-l,--list	List of installed packages"
+//usage:     "\n	--configure	Configure an unpackaged package"
+//usage:     "\n	-P,--purge	Purge all files of a package"
+//usage:     "\n	-r,--remove	Remove all but the configuration files for a package"
+//usage:     "\n	--unpack	Unpack a package, but don't configure it"
+//usage:     "\n	--force-depends	Ignore dependency problems"
+//usage:     "\n	--force-confnew	Overwrite existing config files when installing"
+//usage:     "\n	--force-confold	Keep old config files when installing"
+//usage:	)
+//usage:	IF_NOT_LONG_OPTS(
+//usage:     "\n	-i		Install the package"
+//usage:     "\n	-l		List of installed packages"
+//usage:     "\n	-C		Configure an unpackaged package"
+//usage:     "\n	-P		Purge all files of a package"
+//usage:     "\n	-r		Remove all but the configuration files for a package"
+//usage:     "\n	-u		Unpack a package, but don't configure it"
+//usage:     "\n	-F depends	Ignore dependency problems"
+//usage:     "\n	-F confnew	Overwrite existing config files when installing"
+//usage:     "\n	-F confold	Keep old config files when installing"
+//usage:	)
+
+#include "libbb.h"
+#include <fnmatch.h>
+#include "archive.h"
+
+/* note: if you vary hash_prime sizes be aware,
+ * 1) tweaking these will have a big effect on how much memory this program uses.
+ * 2) for computational efficiency these hash tables should be at least 20%
+ *    larger than the maximum number of elements stored in it.
+ * 3) all _hash_prime's must be a prime number or chaos is assured, if your looking
+ *    for a prime, try http://www.utm.edu/research/primes/lists/small/10000.txt
+ * 4) if you go bigger than 15 bits you may get into trouble (untested) as its
+ *    sometimes cast to an unsigned, if you go to 16 bit you will overlap
+ *    int's and chaos is assured, 16381 is the max prime for 14 bit field
+ */
+
+/* NAME_HASH_PRIME, Stores package names and versions,
+ * I estimate it should be at least 50% bigger than PACKAGE_HASH_PRIME,
+ * as there a lot of duplicate version numbers */
+#define NAME_HASH_PRIME 16381
+
+/* PACKAGE_HASH_PRIME, Maximum number of unique packages,
+ * It must not be smaller than STATUS_HASH_PRIME,
+ * Currently only packages from status_hashtable are stored in here, but in
+ * future this may be used to store packages not only from a status file,
+ * but an available_hashtable, and even multiple packages files.
+ * Package can be stored more than once if they have different versions.
+ * e.g. The same package may have different versions in the status file
+ *      and available file */
+#define PACKAGE_HASH_PRIME 10007
+typedef struct edge_s {
+	unsigned operator:4; /* was:3 */
+	unsigned type:4;
+	unsigned name:16; /* was:14 */
+	unsigned version:16; /* was:14 */
+} edge_t;
+
+typedef struct common_node_s {
+	unsigned name:16; /* was:14 */
+	unsigned version:16; /* was:14 */
+	unsigned num_of_edges:16; /* was:14 */
+	edge_t **edge;
+} common_node_t;
+
+/* Currently it doesnt store packages that have state-status of not-installed
+ * So it only really has to be the size of the maximum number of packages
+ * likely to be installed at any one time, so there is a bit of leeway here */
+#define STATUS_HASH_PRIME 8191
+typedef struct status_node_s {
+	unsigned package:16; /* was:14 */       /* has to fit PACKAGE_HASH_PRIME */
+	unsigned status:16; /* was:14 */        /* has to fit STATUS_HASH_PRIME */
+} status_node_t;
+
+
+/* Globals */
+struct globals {
+	char          *name_hashtable[NAME_HASH_PRIME + 1];
+	common_node_t *package_hashtable[PACKAGE_HASH_PRIME + 1];
+	status_node_t *status_hashtable[STATUS_HASH_PRIME + 1];
+};
+#define G (*ptr_to_globals)
+#define name_hashtable    (G.name_hashtable   )
+#define package_hashtable (G.package_hashtable)
+#define status_hashtable  (G.status_hashtable )
+#define INIT_G() do { \
+	SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); \
+} while (0)
+
+
+/* Even numbers are for 'extras', like ored dependencies or null */
+enum edge_type_e {
+	EDGE_NULL = 0,
+	EDGE_PRE_DEPENDS = 1,
+	EDGE_OR_PRE_DEPENDS = 2,
+	EDGE_DEPENDS = 3,
+	EDGE_OR_DEPENDS = 4,
+	EDGE_REPLACES = 5,
+	EDGE_PROVIDES = 7,
+	EDGE_CONFLICTS = 9,
+	EDGE_SUGGESTS = 11,
+	EDGE_RECOMMENDS = 13,
+	EDGE_ENHANCES = 15
+};
+enum operator_e {
+	VER_NULL = 0,
+	VER_EQUAL = 1,
+	VER_LESS = 2,
+	VER_LESS_EQUAL = 3,
+	VER_MORE = 4,
+	VER_MORE_EQUAL = 5,
+	VER_ANY = 6
+};
+
+typedef struct deb_file_s {
+	char *control_file;
+	char *filename;
+	unsigned package:16; /* was:14 */
+} deb_file_t;
+
+
+static void make_hash(const char *key, unsigned *start, unsigned *decrement, const int hash_prime)
+{
+	unsigned long hash_num = key[0];
+	int len = strlen(key);
+	int i;
+
+	/* Maybe i should have uses a "proper" hashing algorithm here instead
+	 * of making one up myself, seems to be working ok though. */
+	for (i = 1; i < len; i++) {
+		/* shifts the ascii based value and adds it to previous value
+		 * shift amount is mod 24 because long int is 32 bit and data
+		 * to be shifted is 8, don't want to shift data to where it has
+		 * no effect */
+		hash_num += (key[i] + key[i-1]) << ((key[i] * i) % 24);
+	}
+	*start = (unsigned) hash_num % hash_prime;
+	*decrement = (unsigned) 1 + (hash_num % (hash_prime - 1));
+}
+
+/* this adds the key to the hash table */
+static int search_name_hashtable(const char *key)
+{
+	unsigned probe_address;
+	unsigned probe_decrement;
+
+	make_hash(key, &probe_address, &probe_decrement, NAME_HASH_PRIME);
+	while (name_hashtable[probe_address] != NULL) {
+		if (strcmp(name_hashtable[probe_address], key) == 0) {
+			return probe_address;
+		}
+		probe_address -= probe_decrement;
+		if ((int)probe_address < 0) {
+			probe_address += NAME_HASH_PRIME;
+		}
+	}
+	name_hashtable[probe_address] = xstrdup(key);
+	return probe_address;
+}
+
+/* this DOESNT add the key to the hashtable
+ * TODO make it consistent with search_name_hashtable
+ */
+static unsigned search_status_hashtable(const char *key)
+{
+	unsigned probe_address;
+	unsigned probe_decrement;
+
+	make_hash(key, &probe_address, &probe_decrement, STATUS_HASH_PRIME);
+	while (status_hashtable[probe_address] != NULL) {
+		if (strcmp(key, name_hashtable[package_hashtable[status_hashtable[probe_address]->package]->name]) == 0) {
+			break;
+		}
+		probe_address -= probe_decrement;
+		if ((int)probe_address < 0) {
+			probe_address += STATUS_HASH_PRIME;
+		}
+	}
+	return probe_address;
+}
+
+static int order(char x)
+{
+	return (x == '~' ? -1
+		: x == '\0' ? 0
+		: isdigit(x) ? 0
+		: isalpha(x) ? x
+		: (unsigned char)x + 256
+	);
+}
+
+/* This code is taken from dpkg and modified slightly to work with busybox */
+static int version_compare_part(const char *val, const char *ref)
+{
+	if (!val) val = "";
+	if (!ref) ref = "";
+
+	while (*val || *ref) {
+		int first_diff;
+
+		while ((*val && !isdigit(*val)) || (*ref && !isdigit(*ref))) {
+			int vc = order(*val);
+			int rc = order(*ref);
+			if (vc != rc)
+				return vc - rc;
+			val++;
+			ref++;
+		}
+
+		while (*val == '0')
+			val++;
+		while (*ref == '0')
+			ref++;
+
+		first_diff = 0;
+		while (isdigit(*val) && isdigit(*ref)) {
+			if (first_diff == 0)
+				first_diff = *val - *ref;
+			val++;
+			ref++;
+		}
+		if (isdigit(*val))
+			return 1;
+		if (isdigit(*ref))
+			return -1;
+		if (first_diff)
+			return first_diff;
+	}
+	return 0;
+}
+
+/* if ver1 < ver2 return -1,
+ * if ver1 = ver2 return 0,
+ * if ver1 > ver2 return 1,
+ */
+static int version_compare(const unsigned ver1, const unsigned ver2)
+{
+	char *ch_ver1 = name_hashtable[ver1];
+	char *ch_ver2 = name_hashtable[ver2];
+	unsigned epoch1 = 0, epoch2 = 0;
+	char *colon;
+	char *deb_ver1, *deb_ver2;
+	char *upstream_ver1;
+	char *upstream_ver2;
+	int result;
+
+	/* Compare epoch */
+	colon = strchr(ch_ver1, ':');
+	if (colon) {
+		epoch1 = atoi(ch_ver1);
+		ch_ver1 = colon + 1;
+	}
+	colon = strchr(ch_ver2, ':');
+	if (colon) {
+		epoch2 = atoi(ch_ver2);
+		ch_ver2 = colon + 1;
+	}
+	if (epoch1 < epoch2) {
+		return -1;
+	}
+	if (epoch1 > epoch2) {
+		return 1;
+	}
+
+	/* Compare upstream version */
+	upstream_ver1 = xstrdup(ch_ver1);
+	upstream_ver2 = xstrdup(ch_ver2);
+
+	/* Chop off debian version, and store for later use */
+	deb_ver1 = strrchr(upstream_ver1, '-');
+	deb_ver2 = strrchr(upstream_ver2, '-');
+	if (deb_ver1) {
+		*deb_ver1++ = '\0';
+	}
+	if (deb_ver2) {
+		*deb_ver2++ = '\0';
+	}
+	result = version_compare_part(upstream_ver1, upstream_ver2);
+	if (result == 0) {
+		/* Compare debian versions */
+		result = version_compare_part(deb_ver1, deb_ver2);
+	}
+
+	free(upstream_ver1);
+	free(upstream_ver2);
+	return result;
+}
+
+static int test_version(const unsigned version1, const unsigned version2, const unsigned operator)
+{
+	const int version_result = version_compare(version1, version2);
+	switch (operator) {
+	case VER_ANY:
+		return TRUE;
+	case VER_EQUAL:
+		return (version_result == 0);
+	case VER_LESS:
+		return (version_result < 0);
+	case VER_LESS_EQUAL:
+		return (version_result <= 0);
+	case VER_MORE:
+		return (version_result > 0);
+	case VER_MORE_EQUAL:
+		return (version_result >= 0);
+	}
+	return FALSE;
+}
+
+static int search_package_hashtable(const unsigned name, const unsigned version, const unsigned operator)
+{
+	unsigned probe_address;
+	unsigned probe_decrement;
+
+	make_hash(name_hashtable[name], &probe_address, &probe_decrement, PACKAGE_HASH_PRIME);
+	while (package_hashtable[probe_address] != NULL) {
+		if (package_hashtable[probe_address]->name == name) {
+			if (operator == VER_ANY) {
+				return probe_address;
+			}
+			if (test_version(package_hashtable[probe_address]->version, version, operator)) {
+				return probe_address;
+			}
+		}
+		probe_address -= probe_decrement;
+		if ((int)probe_address < 0) {
+			probe_address += PACKAGE_HASH_PRIME;
+		}
+	}
+	return probe_address;
+}
+
+/*
+ * This function searches through the entire package_hashtable looking
+ * for a package which provides "needle". It returns the index into
+ * the package_hashtable for the providing package.
+ *
+ * needle is the index into name_hashtable of the package we are
+ * looking for.
+ *
+ * start_at is the index in the package_hashtable to start looking
+ * at. If start_at is -1 then start at the beginning. This is to allow
+ * for repeated searches since more than one package might provide
+ * needle.
+ *
+ * FIXME: I don't think this is very efficient, but I thought I'd keep
+ * it simple for now until it proves to be a problem.
+ */
+static int search_for_provides(int needle, int start_at)
+{
+	int i, j;
+	common_node_t *p;
+	for (i = start_at + 1; i < PACKAGE_HASH_PRIME; i++) {
+		p = package_hashtable[i];
+		if (p == NULL)
+			continue;
+		for (j = 0; j < p->num_of_edges; j++)
+			if (p->edge[j]->type == EDGE_PROVIDES && p->edge[j]->name == needle)
+				return i;
+	}
+	return -1;
+}
+
+/*
+ * Add an edge to a node
+ */
+static void add_edge_to_node(common_node_t *node, edge_t *edge)
+{
+	node->edge = xrealloc_vector(node->edge, 2, node->num_of_edges);
+	node->edge[node->num_of_edges++] = edge;
+}
+
+/*
+ * Create one new node and one new edge for every dependency.
+ *
+ * Dependencies which contain multiple alternatives are represented as
+ * an EDGE_OR_PRE_DEPENDS or EDGE_OR_DEPENDS node, followed by a
+ * number of EDGE_PRE_DEPENDS or EDGE_DEPENDS nodes. The name field of
+ * the OR edge contains the full dependency string while the version
+ * field contains the number of EDGE nodes which follow as part of
+ * this alternative.
+ */
+static void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned edge_type)
+{
+	char *line = xstrdup(whole_line);
+	char *line2;
+	char *line_ptr1 = NULL;
+	char *line_ptr2 = NULL;
+	char *field;
+	char *field2;
+	char *version;
+	edge_t *edge;
+	edge_t *or_edge;
+	int offset_ch;
+
+	field = strtok_r(line, ",", &line_ptr1);
+	do {
+		/* skip leading spaces */
+		field += strspn(field, " ");
+		line2 = xstrdup(field);
+		field2 = strtok_r(line2, "|", &line_ptr2);
+		or_edge = NULL;
+		if ((edge_type == EDGE_DEPENDS || edge_type == EDGE_PRE_DEPENDS)
+		 && (strcmp(field, field2) != 0)
+		) {
+			or_edge = xzalloc(sizeof(edge_t));
+			or_edge->type = edge_type + 1;
+			or_edge->name = search_name_hashtable(field);
+			//or_edge->version = 0; // tracks the number of alternatives
+			add_edge_to_node(parent_node, or_edge);
+		}
+
+		do {
+			edge = xmalloc(sizeof(edge_t));
+			edge->type = edge_type;
+
+			/* Skip any extra leading spaces */
+			field2 += strspn(field2, " ");
+
+			/* Get dependency version info */
+			version = strchr(field2, '(');
+			if (version == NULL) {
+				edge->operator = VER_ANY;
+				/* Get the versions hash number, adding it if the number isnt already in there */
+				edge->version = search_name_hashtable("ANY");
+			} else {
+				/* Skip leading ' ' or '(' */
+				version += strspn(version, " (");
+				/* Calculate length of any operator characters */
+				offset_ch = strspn(version, "<=>");
+				/* Determine operator */
+				if (offset_ch > 0) {
+					if (strncmp(version, "=", offset_ch) == 0) {
+						edge->operator = VER_EQUAL;
+					} else if (strncmp(version, "<<", offset_ch) == 0) {
+						edge->operator = VER_LESS;
+					} else if (strncmp(version, "<=", offset_ch) == 0) {
+						edge->operator = VER_LESS_EQUAL;
+					} else if (strncmp(version, ">>", offset_ch) == 0) {
+						edge->operator = VER_MORE;
+					} else if (strncmp(version, ">=", offset_ch) == 0) {
+						edge->operator = VER_MORE_EQUAL;
+					} else {
+						bb_error_msg_and_die("illegal operator");
+					}
+				}
+				/* skip to start of version numbers */
+				version += offset_ch;
+				version += strspn(version, " ");
+
+				/* Truncate version at trailing ' ' or ')' */
+				version[strcspn(version, " )")] = '\0';
+				/* Get the versions hash number, adding it if the number isnt already in there */
+				edge->version = search_name_hashtable(version);
+			}
+
+			/* Get the dependency name */
+			field2[strcspn(field2, " (")] = '\0';
+			edge->name = search_name_hashtable(field2);
+
+			if (or_edge)
+				or_edge->version++;
+
+			add_edge_to_node(parent_node, edge);
+			field2 = strtok_r(NULL, "|", &line_ptr2);
+		} while (field2 != NULL);
+
+		free(line2);
+		field = strtok_r(NULL, ",", &line_ptr1);
+	} while (field != NULL);
+
+	free(line);
+}
+
+static void free_package(common_node_t *node)
+{
+	unsigned i;
+	if (node) {
+		for (i = 0; i < node->num_of_edges; i++) {
+			free(node->edge[i]);
+		}
+		free(node->edge);
+		free(node);
+	}
+}
+
+/*
+ * Gets the next package field from package_buffer, separated into the field name
+ * and field value, it returns the int offset to the first character of the next field
+ */
+static int read_package_field(const char *package_buffer, char **field_name, char **field_value)
+{
+	int offset_name_start = 0;
+	int offset_name_end = 0;
+	int offset_value_start = 0;
+	int offset_value_end = 0;
+	int offset = 0;
+	int next_offset;
+	int name_length;
+	int value_length;
+	int exit_flag = FALSE;
+
+	if (package_buffer == NULL) {
+		*field_name = NULL;
+		*field_value = NULL;
+		return -1;
+	}
+	while (1) {
+		next_offset = offset + 1;
+		switch (package_buffer[offset]) {
+			case '\0':
+				exit_flag = TRUE;
+				break;
+			case ':':
+				if (offset_name_end == 0) {
+					offset_name_end = offset;
+					offset_value_start = next_offset;
+				}
+				/* TODO: Name might still have trailing spaces if ':' isnt
+				 * immediately after name */
+				break;
+			case '\n':
+				/* TODO: The char next_offset may be out of bounds */
+				if (package_buffer[next_offset] != ' ') {
+					exit_flag = TRUE;
+					break;
+				}
+			case '\t':
+			case ' ':
+				/* increment the value start point if its a just filler */
+				if (offset_name_start == offset) {
+					offset_name_start++;
+				}
+				if (offset_value_start == offset) {
+					offset_value_start++;
+				}
+				break;
+		}
+		if (exit_flag) {
+			/* Check that the names are valid */
+			offset_value_end = offset;
+			name_length = offset_name_end - offset_name_start;
+			value_length = offset_value_end - offset_value_start;
+			if (name_length == 0) {
+				break;
+			}
+			if ((name_length > 0) && (value_length > 0)) {
+				break;
+			}
+
+			/* If not valid, start fresh with next field */
+			exit_flag = FALSE;
+			offset_name_start = offset + 1;
+			offset_name_end = 0;
+			offset_value_start = offset + 1;
+			offset_value_end = offset + 1;
+			offset++;
+		}
+		offset++;
+	}
+	*field_name = NULL;
+	if (name_length) {
+		*field_name = xstrndup(&package_buffer[offset_name_start], name_length);
+	}
+	*field_value = NULL;
+	if (value_length > 0) {
+		*field_value = xstrndup(&package_buffer[offset_value_start], value_length);
+	}
+	return next_offset;
+}
+
+static unsigned fill_package_struct(char *control_buffer)
+{
+	static const char field_names[] ALIGN1 =
+		"Package\0""Version\0"
+		"Pre-Depends\0""Depends\0""Replaces\0""Provides\0"
+		"Conflicts\0""Suggests\0""Recommends\0""Enhances\0";
+
+	common_node_t *new_node = xzalloc(sizeof(common_node_t));
+	char *field_name;
+	char *field_value;
+	int field_start = 0;
+	int num = -1;
+	int buffer_length = strlen(control_buffer);
+
+	new_node->version = search_name_hashtable("unknown");
+	while (field_start < buffer_length) {
+		unsigned field_num;
+
+		field_start += read_package_field(&control_buffer[field_start],
+				&field_name, &field_value);
+
+		if (field_name == NULL) {
+			goto fill_package_struct_cleanup;
+		}
+
+		field_num = index_in_strings(field_names, field_name);
+		switch (field_num) {
+		case 0: /* Package */
+			new_node->name = search_name_hashtable(field_value);
+			break;
+		case 1: /* Version */
+			new_node->version = search_name_hashtable(field_value);
+			break;
+		case 2: /* Pre-Depends */
+			add_split_dependencies(new_node, field_value, EDGE_PRE_DEPENDS);
+			break;
+		case 3: /* Depends */
+			add_split_dependencies(new_node, field_value, EDGE_DEPENDS);
+			break;
+		case 4: /* Replaces */
+			add_split_dependencies(new_node, field_value, EDGE_REPLACES);
+			break;
+		case 5: /* Provides */
+			add_split_dependencies(new_node, field_value, EDGE_PROVIDES);
+			break;
+		case 6: /* Conflicts */
+			add_split_dependencies(new_node, field_value, EDGE_CONFLICTS);
+			break;
+		case 7: /* Suggests */
+			add_split_dependencies(new_node, field_value, EDGE_SUGGESTS);
+			break;
+		case 8: /* Recommends */
+			add_split_dependencies(new_node, field_value, EDGE_RECOMMENDS);
+			break;
+		case 9: /* Enhances */
+			add_split_dependencies(new_node, field_value, EDGE_ENHANCES);
+			break;
+		}
+ fill_package_struct_cleanup:
+		free(field_name);
+		free(field_value);
+	}
+
+	if (new_node->version == search_name_hashtable("unknown")) {
+		free_package(new_node);
+		return -1;
+	}
+	num = search_package_hashtable(new_node->name, new_node->version, VER_EQUAL);
+	free_package(package_hashtable[num]);
+	package_hashtable[num] = new_node;
+	return num;
+}
+
+/* if num = 1, it returns the want status, 2 returns flag, 3 returns status */
+static unsigned get_status(const unsigned status_node, const int num)
+{
+	char *status_string = name_hashtable[status_hashtable[status_node]->status];
+	char *state_sub_string;
+	unsigned state_sub_num;
+	int len;
+	int i;
+
+	/* set tmp_string to point to the start of the word number */
+	for (i = 1; i < num; i++) {
+		/* skip past a word */
+		status_string += strcspn(status_string, " ");
+		/* skip past the separating spaces */
+		status_string += strspn(status_string, " ");
+	}
+	len = strcspn(status_string, " \n");
+	state_sub_string = xstrndup(status_string, len);
+	state_sub_num = search_name_hashtable(state_sub_string);
+	free(state_sub_string);
+	return state_sub_num;
+}
+
+static void set_status(const unsigned status_node_num, const char *new_value, const int position)
+{
+	const unsigned new_value_num = search_name_hashtable(new_value);
+	unsigned want = get_status(status_node_num, 1);
+	unsigned flag = get_status(status_node_num, 2);
+	unsigned status = get_status(status_node_num, 3);
+	char *new_status;
+
+	switch (position) {
+		case 1:
+			want = new_value_num;
+			break;
+		case 2:
+			flag = new_value_num;
+			break;
+		case 3:
+			status = new_value_num;
+			break;
+		default:
+			bb_error_msg_and_die("DEBUG ONLY: this shouldnt happen");
+	}
+
+	new_status = xasprintf("%s %s %s", name_hashtable[want], name_hashtable[flag], name_hashtable[status]);
+	status_hashtable[status_node_num]->status = search_name_hashtable(new_status);
+	free(new_status);
+}
+
+static const char *describe_status(int status_num)
+{
+	int status_want, status_state;
+	if (status_hashtable[status_num] == NULL || status_hashtable[status_num]->status == 0)
+		return "is not installed or flagged to be installed";
+
+	status_want = get_status(status_num, 1);
+	status_state = get_status(status_num, 3);
+
+	if (status_state == search_name_hashtable("installed")) {
+		if (status_want == search_name_hashtable("install"))
+			return "is installed";
+		if (status_want == search_name_hashtable("deinstall"))
+			return "is marked to be removed";
+		if (status_want == search_name_hashtable("purge"))
+			return "is marked to be purged";
+	}
+	if (status_want == search_name_hashtable("unknown"))
+		return "is in an indeterminate state";
+	if (status_want == search_name_hashtable("install"))
+		return "is marked to be installed";
+
+	return "is not installed or flagged to be installed";
+}
+
+static void index_status_file(const char *filename)
+{
+	FILE *status_file;
+	char *control_buffer;
+	char *status_line;
+	status_node_t *status_node = NULL;
+	unsigned status_num;
+
+	status_file = xfopen_for_read(filename);
+	while ((control_buffer = xmalloc_fgetline_str(status_file, "\n\n")) != NULL) {
+		const unsigned package_num = fill_package_struct(control_buffer);
+		if (package_num != -1) {
+			status_node = xmalloc(sizeof(status_node_t));
+			/* fill_package_struct doesnt handle the status field */
+			status_line = strstr(control_buffer, "Status:");
+			if (status_line != NULL) {
+				status_line += 7;
+				status_line += strspn(status_line, " \n\t");
+				status_line = xstrndup(status_line, strcspn(status_line, "\n"));
+				status_node->status = search_name_hashtable(status_line);
+				free(status_line);
+			}
+			status_node->package = package_num;
+			status_num = search_status_hashtable(name_hashtable[package_hashtable[status_node->package]->name]);
+			status_hashtable[status_num] = status_node;
+		}
+		free(control_buffer);
+	}
+	fclose(status_file);
+}
+
+static void write_buffer_no_status(FILE *new_status_file, const char *control_buffer)
+{
+	char *name;
+	char *value;
+	int start = 0;
+	while (1) {
+		start += read_package_field(&control_buffer[start], &name, &value);
+		if (name == NULL) {
+			break;
+		}
+		if (strcmp(name, "Status") != 0) {
+			fprintf(new_status_file, "%s: %s\n", name, value);
+		}
+	}
+}
+
+/* This could do with a cleanup */
+static void write_status_file(deb_file_t **deb_file)
+{
+	FILE *old_status_file = xfopen_for_read("/var/lib/dpkg/status");
+	FILE *new_status_file = xfopen_for_write("/var/lib/dpkg/status.udeb");
+	char *package_name;
+	char *status_from_file;
+	char *control_buffer = NULL;
+	char *tmp_string;
+	int status_num;
+	int field_start = 0;
+	int write_flag;
+	int i = 0;
+
+	/* Update previously known packages */
+	while ((control_buffer = xmalloc_fgetline_str(old_status_file, "\n\n")) != NULL) {
+		tmp_string = strstr(control_buffer, "Package:");
+		if (tmp_string == NULL) {
+			continue;
+		}
+
+		tmp_string += 8;
+		tmp_string += strspn(tmp_string, " \n\t");
+		package_name = xstrndup(tmp_string, strcspn(tmp_string, "\n"));
+		write_flag = FALSE;
+		tmp_string = strstr(control_buffer, "Status:");
+		if (tmp_string != NULL) {
+			/* Separate the status value from the control buffer */
+			tmp_string += 7;
+			tmp_string += strspn(tmp_string, " \n\t");
+			status_from_file = xstrndup(tmp_string, strcspn(tmp_string, "\n"));
+		} else {
+			status_from_file = NULL;
+		}
+
+		/* Find this package in the status hashtable */
+		status_num = search_status_hashtable(package_name);
+		if (status_hashtable[status_num] != NULL) {
+			const char *status_from_hashtable = name_hashtable[status_hashtable[status_num]->status];
+			if (strcmp(status_from_file, status_from_hashtable) != 0) {
+				/* New status isnt exactly the same as old status */
+				const int state_status = get_status(status_num, 3);
+				if ((strcmp("installed", name_hashtable[state_status]) == 0)
+				 || (strcmp("unpacked", name_hashtable[state_status]) == 0)
+				) {
+					/* We need to add the control file from the package */
+					i = 0;
+					while (deb_file[i] != NULL) {
+						if (strcmp(package_name, name_hashtable[package_hashtable[deb_file[i]->package]->name]) == 0) {
+							/* Write a status file entry with a modified status */
+							/* remove trailing \n's */
+							write_buffer_no_status(new_status_file, deb_file[i]->control_file);
+							set_status(status_num, "ok", 2);
+							fprintf(new_status_file, "Status: %s\n\n",
+									name_hashtable[status_hashtable[status_num]->status]);
+							write_flag = TRUE;
+							break;
+						}
+						i++;
+					}
+					/* This is temperary, debugging only */
+					if (deb_file[i] == NULL) {
+						bb_error_msg_and_die("ALERT: cannot find a control file, "
+							"your status file may be broken, status may be "
+							"incorrect for %s", package_name);
+					}
+				}
+				else if (strcmp("not-installed", name_hashtable[state_status]) == 0) {
+					/* Only write the Package, Status, Priority and Section lines */
+					fprintf(new_status_file, "Package: %s\n", package_name);
+					fprintf(new_status_file, "Status: %s\n", status_from_hashtable);
+
+					while (1) {
+						char *field_name;
+						char *field_value;
+						field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value);
+						if (field_name == NULL) {
+							break;
+						}
+						if ((strcmp(field_name, "Priority") == 0)
+						 || (strcmp(field_name, "Section") == 0)
+						) {
+							fprintf(new_status_file, "%s: %s\n", field_name, field_value);
+						}
+					}
+					write_flag = TRUE;
+					fputs("\n", new_status_file);
+				}
+				else if (strcmp("config-files", name_hashtable[state_status]) == 0) {
+					/* only change the status line */
+					while (1) {
+						char *field_name;
+						char *field_value;
+						field_start += read_package_field(&control_buffer[field_start], &field_name, &field_value);
+						if (field_name == NULL) {
+							break;
+						}
+						/* Setup start point for next field */
+						if (strcmp(field_name, "Status") == 0) {
+							fprintf(new_status_file, "Status: %s\n", status_from_hashtable);
+						} else {
+							fprintf(new_status_file, "%s: %s\n", field_name, field_value);
+						}
+					}
+					write_flag = TRUE;
+					fputs("\n", new_status_file);
+				}
+			}
+		}
+		/* If the package from the status file wasnt handle above, do it now*/
+		if (!write_flag) {
+			fprintf(new_status_file, "%s\n\n", control_buffer);
+		}
+
+		free(status_from_file);
+		free(package_name);
+		free(control_buffer);
+	}
+
+	/* Write any new packages */
+	for (i = 0; deb_file[i] != NULL; i++) {
+		status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[i]->package]->name]);
+		if (strcmp("reinstreq", name_hashtable[get_status(status_num, 2)]) == 0) {
+			write_buffer_no_status(new_status_file, deb_file[i]->control_file);
+			set_status(status_num, "ok", 2);
+			fprintf(new_status_file, "Status: %s\n\n", name_hashtable[status_hashtable[status_num]->status]);
+		}
+	}
+	fclose(old_status_file);
+	fclose(new_status_file);
+
+	/* Create a separate backfile to dpkg */
+	if (rename("/var/lib/dpkg/status", "/var/lib/dpkg/status.udeb.bak") == -1) {
+		if (errno != ENOENT)
+			bb_error_msg_and_die("can't create backup status file");
+		/* Its ok if renaming the status file fails because status
+		 * file doesnt exist, maybe we are starting from scratch */
+		bb_error_msg("no status file found, creating new one");
+	}
+
+	xrename("/var/lib/dpkg/status.udeb", "/var/lib/dpkg/status");
+}
+
+/* This function returns TRUE if the given package can satisfy a
+ * dependency of type depend_type.
+ *
+ * A pre-depends is satisfied only if a package is already installed,
+ * which a regular depends can be satisfied by a package which we want
+ * to install.
+ */
+static int package_satisfies_dependency(int package, int depend_type)
+{
+	int status_num = search_status_hashtable(name_hashtable[package_hashtable[package]->name]);
+
+	/* status could be unknown if package is a pure virtual
+	 * provides which cannot satisfy any dependency by itself.
+	 */
+	if (status_hashtable[status_num] == NULL)
+		return 0;
+
+	switch (depend_type) {
+	case EDGE_PRE_DEPENDS: return get_status(status_num, 3) == search_name_hashtable("installed");
+	case EDGE_DEPENDS:     return get_status(status_num, 1) == search_name_hashtable("install");
+	}
+	return 0;
+}
+
+static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count - ?? */)
+{
+	int *conflicts = NULL;
+	int conflicts_num = 0;
+	int i = deb_start;
+	int j;
+
+	/* Check for conflicts
+	 * TODO: TEST if conflicts with other packages to be installed
+	 *
+	 * Add install packages and the packages they provide
+	 * to the list of files to check conflicts for
+	 */
+
+	/* Create array of package numbers to check against
+	 * installed package for conflicts*/
+	while (deb_file[i] != NULL) {
+		const unsigned package_num = deb_file[i]->package;
+		conflicts = xrealloc_vector(conflicts, 2, conflicts_num);
+		conflicts[conflicts_num] = package_num;
+		conflicts_num++;
+		/* add provides to conflicts list */
+		for (j = 0; j < package_hashtable[package_num]->num_of_edges; j++) {
+			if (package_hashtable[package_num]->edge[j]->type == EDGE_PROVIDES) {
+				const int conflicts_package_num = search_package_hashtable(
+					package_hashtable[package_num]->edge[j]->name,
+					package_hashtable[package_num]->edge[j]->version,
+					package_hashtable[package_num]->edge[j]->operator);
+				if (package_hashtable[conflicts_package_num] == NULL) {
+					/* create a new package */
+					common_node_t *new_node = xzalloc(sizeof(common_node_t));
+					new_node->name = package_hashtable[package_num]->edge[j]->name;
+					new_node->version = package_hashtable[package_num]->edge[j]->version;
+					package_hashtable[conflicts_package_num] = new_node;
+				}
+				conflicts = xrealloc_vector(conflicts, 2, conflicts_num);
+				conflicts[conflicts_num] = conflicts_package_num;
+				conflicts_num++;
+			}
+		}
+		i++;
+	}
+
+	/* Check conflicts */
+	i = 0;
+	while (deb_file[i] != NULL) {
+		const common_node_t *package_node = package_hashtable[deb_file[i]->package];
+		int status_num = 0;
+		status_num = search_status_hashtable(name_hashtable[package_node->name]);
+
+		if (get_status(status_num, 3) == search_name_hashtable("installed")) {
+			i++;
+			continue;
+		}
+
+		for (j = 0; j < package_node->num_of_edges; j++) {
+			const edge_t *package_edge = package_node->edge[j];
+
+			if (package_edge->type == EDGE_CONFLICTS) {
+				const unsigned package_num =
+					search_package_hashtable(package_edge->name,
+								 package_edge->version,
+								 package_edge->operator);
+				int result = 0;
+				if (package_hashtable[package_num] != NULL) {
+					status_num = search_status_hashtable(name_hashtable[package_hashtable[package_num]->name]);
+
+					if (get_status(status_num, 1) == search_name_hashtable("install")) {
+						result = test_version(package_hashtable[deb_file[i]->package]->version,
+							package_edge->version, package_edge->operator);
+					}
+				}
+
+				if (result) {
+					bb_error_msg_and_die("package %s conflicts with %s",
+						name_hashtable[package_node->name],
+						name_hashtable[package_edge->name]);
+				}
+			}
+		}
+		i++;
+	}
+
+
+	/* Check dependendcies */
+	for (i = 0; i < PACKAGE_HASH_PRIME; i++) {
+		int status_num = 0;
+		int number_of_alternatives = 0;
+		const edge_t * root_of_alternatives = NULL;
+		const common_node_t *package_node = package_hashtable[i];
+
+		/* If the package node does not exist then this
+		 * package is a virtual one. In which case there are
+		 * no dependencies to check.
+		 */
+		if (package_node == NULL) continue;
+
+		status_num = search_status_hashtable(name_hashtable[package_node->name]);
+
+		/* If there is no status then this package is a
+		 * virtual one provided by something else. In which
+		 * case there are no dependencies to check.
+		 */
+		if (status_hashtable[status_num] == NULL) continue;
+
+		/* If we don't want this package installed then we may
+		 * as well ignore it's dependencies.
+		 */
+		if (get_status(status_num, 1) != search_name_hashtable("install")) {
+			continue;
+		}
+
+		/* This code is tested only for EDGE_DEPENDS, since I
+		 * have no suitable pre-depends available. There is no
+		 * reason that it shouldn't work though :-)
+		 */
+		for (j = 0; j < package_node->num_of_edges; j++) {
+			const edge_t *package_edge = package_node->edge[j];
+			unsigned package_num;
+
+			if (package_edge->type == EDGE_OR_PRE_DEPENDS
+			 || package_edge->type == EDGE_OR_DEPENDS
+			) {
+				/* start an EDGE_OR_ list */
+				number_of_alternatives = package_edge->version;
+				root_of_alternatives = package_edge;
+				continue;
+			}
+			if (number_of_alternatives == 0) {  /* not in the middle of an EDGE_OR_ list */
+				number_of_alternatives = 1;
+				root_of_alternatives = NULL;
+			}
+
+			package_num = search_package_hashtable(package_edge->name, package_edge->version, package_edge->operator);
+
+			if (package_edge->type == EDGE_PRE_DEPENDS
+			 || package_edge->type == EDGE_DEPENDS
+			) {
+				int result=1;
+				status_num = 0;
+
+				/* If we are inside an alternative then check
+				 * this edge is the right type.
+				 *
+				 * EDGE_DEPENDS == OR_DEPENDS -1
+				 * EDGE_PRE_DEPENDS == OR_PRE_DEPENDS -1
+				 */
+				if (root_of_alternatives && package_edge->type != root_of_alternatives->type - 1)
+					bb_error_msg_and_die("fatal error, package dependencies corrupt: %d != %d - 1",
+							     package_edge->type, root_of_alternatives->type);
+
+				if (package_hashtable[package_num] != NULL)
+					result = !package_satisfies_dependency(package_num, package_edge->type);
+
+				if (result) { /* check for other package which provide what we are looking for */
+					int provider = -1;
+
+					while ((provider = search_for_provides(package_edge->name, provider)) > -1) {
+						if (package_hashtable[provider] == NULL) {
+							puts("Have a provider but no package information for it");
+							continue;
+						}
+						result = !package_satisfies_dependency(provider, package_edge->type);
+
+						if (result == 0)
+							break;
+					}
+				}
+
+				/* It must be already installed, or to be installed */
+				number_of_alternatives--;
+				if (result && number_of_alternatives == 0) {
+					if (root_of_alternatives)
+						bb_error_msg_and_die(
+							"package %s %sdepends on %s, "
+							"which cannot be satisfied",
+							name_hashtable[package_node->name],
+							package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",
+							name_hashtable[root_of_alternatives->name]);
+					bb_error_msg_and_die(
+						"package %s %sdepends on %s, which %s\n",
+						name_hashtable[package_node->name],
+						package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "",
+						name_hashtable[package_edge->name],
+						describe_status(status_num));
+				}
+				if (result == 0 && number_of_alternatives) {
+					/* we've found a package which
+					 * satisfies the dependency,
+					 * so skip over the rest of
+					 * the alternatives.
+					 */
+					j += number_of_alternatives;
+					number_of_alternatives = 0;
+				}
+			}
+		}
+	}
+	free(conflicts);
+	return TRUE;
+}
+
+static char **create_list(const char *filename)
+{
+	FILE *list_stream;
+	char **file_list;
+	char *line;
+	int count;
+
+	/* don't use [xw]fopen here, handle error ourself */
+	list_stream = fopen_for_read(filename);
+	if (list_stream == NULL) {
+		return NULL;
+	}
+
+	file_list = NULL;
+	count = 0;
+	while ((line = xmalloc_fgetline(list_stream)) != NULL) {
+		file_list = xrealloc_vector(file_list, 2, count);
+		file_list[count++] = line;
+		/*file_list[count] = NULL; - xrealloc_vector did it */
+	}
+	fclose(list_stream);
+
+	return file_list;
+}
+
+/* maybe i should try and hook this into remove_file.c somehow */
+static int remove_file_array(char **remove_names, char **exclude_names)
+{
+	struct stat path_stat;
+	int remove_flag = 1; /* not removed anything yet */
+	int i, j;
+
+	if (remove_names == NULL) {
+		return 0;
+	}
+	for (i = 0; remove_names[i] != NULL; i++) {
+		if (exclude_names != NULL) {
+			for (j = 0; exclude_names[j] != NULL; j++) {
+				if (strcmp(remove_names[i], exclude_names[j]) == 0) {
+					goto skip;
+				}
+			}
+		}
+		/* TODO: why we are checking lstat? we can just try rm/rmdir */
+		if (lstat(remove_names[i], &path_stat) < 0) {
+			continue;
+		}
+		if (S_ISDIR(path_stat.st_mode)) {
+			remove_flag &= rmdir(remove_names[i]); /* 0 if no error */
+		} else {
+			remove_flag &= unlink(remove_names[i]); /* 0 if no error */
+		}
+ skip:
+		continue;
+	}
+	return (remove_flag == 0);
+}
+
+static void run_package_script_or_die(const char *package_name, const char *script_type)
+{
+	char *script_path;
+	int result;
+
+	script_path = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, script_type);
+
+	/* If the file doesnt exist is isnt fatal */
+	result = access(script_path, F_OK) ? EXIT_SUCCESS : system(script_path);
+	free(script_path);
+	if (result)
+		bb_error_msg_and_die("%s failed, exit code %d", script_type, result);
+}
+
+/*
+The policy manual defines what scripts get called when and with
+what arguments. I realize that busybox does not support all of
+these scenarios, but it does support some of them; it does not,
+however, run them with any parameters in run_package_script_or_die().
+Here are the scripts:
+
+preinst install
+preinst install <old_version>
+preinst upgrade <old_version>
+preinst abort_upgrade <new_version>
+postinst configure <most_recent_version>
+postinst abort-upgade <new_version>
+postinst abort-remove
+postinst abort-remove in-favour <package> <version>
+postinst abort-deconfigure in-favor <failed_install_package> removing <conflicting_package> <version>
+prerm remove
+prerm upgrade <new_version>
+prerm failed-upgrade <old_version>
+prerm remove in-favor <package> <new_version>
+prerm deconfigure in-favour <package> <version> removing <package> <version>
+postrm remove
+postrm purge
+postrm upgrade <new_version>
+postrm failed-upgrade <old_version>
+postrm abort-install
+postrm abort-install <old_version>
+postrm abort-upgrade <old_version>
+postrm disappear <overwriter> <version>
+*/
+static const char *const all_control_files[] = {
+	"preinst", "postinst", "prerm", "postrm",
+	"list", "md5sums", "shlibs", "conffiles",
+	"config", "templates"
+};
+
+static char **all_control_list(const char *package_name)
+{
+	unsigned i = 0;
+	char **remove_files;
+
+	/* Create a list of all /var/lib/dpkg/info/<package> files */
+	remove_files = xzalloc(sizeof(all_control_files) + sizeof(char*));
+	while (i < ARRAY_SIZE(all_control_files)) {
+		remove_files[i] = xasprintf("/var/lib/dpkg/info/%s.%s",
+				package_name, all_control_files[i]);
+		i++;
+	}
+
+	return remove_files;
+}
+
+static void free_array(char **array)
+{
+	if (array) {
+		unsigned i = 0;
+		while (array[i]) {
+			free(array[i]);
+			i++;
+		}
+		free(array);
+	}
+}
+
+/* This function lists information on the installed packages. It loops through
+ * the status_hashtable to retrieve the info. This results in smaller code than
+ * scanning the status file. The resulting list, however, is unsorted.
+ */
+static void list_packages(const char *pattern)
+{
+	int i;
+
+	puts("    Name           Version");
+	puts("+++-==============-==============");
+
+	/* go through status hash, dereference package hash and finally strings */
+	for (i = 0; i < STATUS_HASH_PRIME+1; i++) {
+		if (status_hashtable[i]) {
+			const char *stat_str;  /* status string */
+			const char *name_str;  /* package name */
+			const char *vers_str;  /* version */
+			char  s1, s2;          /* status abbreviations */
+			int   spccnt;          /* space count */
+			int   j;
+
+			stat_str = name_hashtable[status_hashtable[i]->status];
+			name_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->name];
+			vers_str = name_hashtable[package_hashtable[status_hashtable[i]->package]->version];
+
+			if (pattern && fnmatch(pattern, name_str, 0) != 0)
+				continue;
+
+			/* get abbreviation for status field 1 */
+			s1 = stat_str[0] == 'i' ? 'i' : 'r';
+
+			/* get abbreviation for status field 2 */
+			for (j = 0, spccnt = 0; stat_str[j] && spccnt < 2; j++) {
+				if (stat_str[j] == ' ') spccnt++;
+			}
+			s2 = stat_str[j];
+
+			/* print out the line formatted like Debian dpkg */
+			printf("%c%c  %-14s %s\n", s1, s2, name_str, vers_str);
+		}
+	}
+}
+
+static void remove_package(const unsigned package_num, int noisy)
+{
+	const char *package_name = name_hashtable[package_hashtable[package_num]->name];
+	const char *package_version = name_hashtable[package_hashtable[package_num]->version];
+	const unsigned status_num = search_status_hashtable(package_name);
+	const int package_name_length = strlen(package_name);
+	char **remove_files;
+	char **exclude_files;
+	char list_name[package_name_length + 25];
+	char conffile_name[package_name_length + 30];
+
+	if (noisy)
+		printf("Removing %s (%s)...\n", package_name, package_version);
+
+	/* Run prerm script */
+	run_package_script_or_die(package_name, "prerm");
+
+	/* Create a list of files to remove, and a separate list of those to keep */
+	sprintf(list_name, "/var/lib/dpkg/info/%s.%s", package_name, "list");
+	remove_files = create_list(list_name);
+
+	sprintf(conffile_name, "/var/lib/dpkg/info/%s.%s", package_name, "conffiles");
+	exclude_files = create_list(conffile_name);
+
+	/* Some directories can't be removed straight away, so do multiple passes */
+	while (remove_file_array(remove_files, exclude_files))
+		continue;
+	free_array(exclude_files);
+	free_array(remove_files);
+
+	/* Create a list of files in /var/lib/dpkg/info/<package>.* to keep */
+	exclude_files = xzalloc(sizeof(exclude_files[0]) * 3);
+	exclude_files[0] = xstrdup(conffile_name);
+	exclude_files[1] = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, "postrm");
+
+	/* Create a list of all /var/lib/dpkg/info/<package> files */
+	remove_files = all_control_list(package_name);
+
+	remove_file_array(remove_files, exclude_files);
+	free_array(remove_files);
+	free_array(exclude_files);
+
+	/* rename <package>.conffiles to <package>.list
+	 * The conffiles control file isn't required in Debian packages, so don't
+	 * error out if it's missing.  */
+	rename(conffile_name, list_name);
+
+	/* Change package status */
+	set_status(status_num, "config-files", 3);
+}
+
+static void purge_package(const unsigned package_num)
+{
+	const char *package_name = name_hashtable[package_hashtable[package_num]->name];
+	const char *package_version = name_hashtable[package_hashtable[package_num]->version];
+	const unsigned status_num = search_status_hashtable(package_name);
+	char **remove_files;
+	char **exclude_files;
+	char list_name[strlen(package_name) + 25];
+
+	printf("Purging %s (%s)...\n", package_name, package_version);
+
+	/* Run prerm script */
+	run_package_script_or_die(package_name, "prerm");
+
+	/* Create a list of files to remove */
+	sprintf(list_name, "/var/lib/dpkg/info/%s.%s", package_name, "list");
+	remove_files = create_list(list_name);
+
+	/* Some directories cant be removed straight away, so do multiple passes */
+	while (remove_file_array(remove_files, NULL))
+		continue;
+	free_array(remove_files);
+
+	/* Create a list of all /var/lib/dpkg/info/<package> files */
+	remove_files = all_control_list(package_name);
+
+	/* Delete all of them except the postrm script */
+	exclude_files = xzalloc(sizeof(exclude_files[0]) * 2);
+	exclude_files[0] = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, "postrm");
+	remove_file_array(remove_files, exclude_files);
+	free_array(exclude_files);
+
+	/* Run and remove postrm script */
+	run_package_script_or_die(package_name, "postrm");
+	remove_file_array(remove_files, NULL);
+
+	free_array(remove_files);
+
+	/* Change package status */
+	set_status(status_num, "not-installed", 3);
+}
+
+static archive_handle_t *init_archive_deb_ar(const char *filename)
+{
+	archive_handle_t *ar_handle;
+
+	/* Setup an ar archive handle that refers to the gzip sub archive */
+	ar_handle = init_handle();
+	ar_handle->filter = filter_accept_list_reassign;
+	ar_handle->src_fd = xopen(filename, O_RDONLY);
+
+	return ar_handle;
+}
+
+static void init_archive_deb_control(archive_handle_t *ar_handle)
+{
+	archive_handle_t *tar_handle;
+
+	/* Setup the tar archive handle */
+	tar_handle = init_handle();
+	tar_handle->src_fd = ar_handle->src_fd;
+
+	/* We don't care about data.tar.* or debian-binary, just control.tar.* */
+#if ENABLE_FEATURE_SEAMLESS_GZ
+	llist_add_to(&(ar_handle->accept), (char*)"control.tar.gz");
+#endif
+#if ENABLE_FEATURE_SEAMLESS_BZ2
+	llist_add_to(&(ar_handle->accept), (char*)"control.tar.bz2");
+#endif
+
+	/* Assign the tar handle as a subarchive of the ar handle */
+	ar_handle->dpkg__sub_archive = tar_handle;
+}
+
+static void init_archive_deb_data(archive_handle_t *ar_handle)
+{
+	archive_handle_t *tar_handle;
+
+	/* Setup the tar archive handle */
+	tar_handle = init_handle();
+	tar_handle->src_fd = ar_handle->src_fd;
+
+	/* We don't care about control.tar.* or debian-binary, just data.tar.* */
+#if ENABLE_FEATURE_SEAMLESS_GZ
+	llist_add_to(&(ar_handle->accept), (char*)"data.tar.gz");
+#endif
+#if ENABLE_FEATURE_SEAMLESS_BZ2
+	llist_add_to(&(ar_handle->accept), (char*)"data.tar.bz2");
+#endif
+
+	/* Assign the tar handle as a subarchive of the ar handle */
+	ar_handle->dpkg__sub_archive = tar_handle;
+}
+
+static void FAST_FUNC data_extract_to_buffer(archive_handle_t *archive_handle)
+{
+	unsigned size = archive_handle->file_header->size;
+
+	archive_handle->dpkg__buffer = xzalloc(size + 1);
+	xread(archive_handle->src_fd, archive_handle->dpkg__buffer, size);
+}
+
+static char *deb_extract_control_file_to_buffer(archive_handle_t *ar_handle, llist_t *myaccept)
+{
+	ar_handle->dpkg__sub_archive->action_data = data_extract_to_buffer;
+	ar_handle->dpkg__sub_archive->accept = myaccept;
+	ar_handle->dpkg__sub_archive->filter = filter_accept_list;
+
+	unpack_ar_archive(ar_handle);
+	close(ar_handle->src_fd);
+
+	return ar_handle->dpkg__sub_archive->dpkg__buffer;
+}
+
+static void append_control_file_to_llist(const char *package_name, const char *control_name, llist_t **ll)
+{
+	FILE *fp;
+	char *filename, *line;
+
+	filename = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, control_name);
+	fp = fopen_for_read(filename);
+	free(filename);
+	if (fp != NULL) {
+		while ((line = xmalloc_fgetline(fp)) != NULL)
+			llist_add_to(ll, line);
+		fclose(fp);
+	}
+}
+
+static char FAST_FUNC filter_rename_config(archive_handle_t *archive_handle)
+{
+	int fd;
+	char *name_ptr = archive_handle->file_header->name + 1;
+
+	/* Is this file marked as config file? */
+	if (!find_list_entry(archive_handle->accept, name_ptr))
+		return EXIT_SUCCESS; /* no */
+
+	fd = open(name_ptr, O_RDONLY);
+	if (fd >= 0) {
+		md5_ctx_t md5;
+		char *md5line, *buf;
+		int count;
+
+		/* Calculate MD5 of existing file */
+		buf = xmalloc(4096);
+		md5_begin(&md5);
+		while ((count = safe_read(fd, buf, 4096)) > 0)
+			md5_hash(&md5, buf, count);
+		md5_end(&md5, buf); /* using buf as result storage */
+		close(fd);
+
+		md5line = xmalloc(16 * 2 + 2 + strlen(name_ptr) + 1);
+		sprintf(bin2hex(md5line, buf, 16), "  %s", name_ptr);
+		free(buf);
+
+		/* Is it changed after install? */
+		if (find_list_entry(archive_handle->accept, md5line) == NULL) {
+			printf("Warning: Creating %s as %s.dpkg-new\n", name_ptr, name_ptr);
+			archive_handle->file_header->name = xasprintf("%s.dpkg-new", archive_handle->file_header->name);
+		}
+		free(md5line);
+	}
+	return EXIT_SUCCESS;
+}
+
+static void FAST_FUNC data_extract_all_prefix(archive_handle_t *archive_handle)
+{
+	char *name_ptr = archive_handle->file_header->name;
+
+	/* Skip all leading "/" */
+	while (*name_ptr == '/')
+		name_ptr++;
+	/* Skip all leading "./" and "../" */
+	while (name_ptr[0] == '.') {
+		if (name_ptr[1] == '.')
+			name_ptr++;
+		if (name_ptr[1] != '/')
+			break;
+		name_ptr += 2;
+	}
+
+	if (name_ptr[0] != '\0') {
+		archive_handle->file_header->name = xasprintf("%s%s", archive_handle->dpkg__buffer, name_ptr);
+		data_extract_all(archive_handle);
+		if (fnmatch("*.dpkg-new", archive_handle->file_header->name, 0) == 0) {
+			/* remove .dpkg-new suffix */
+			archive_handle->file_header->name[strlen(archive_handle->file_header->name) - 9] = '\0';
+		}
+	}
+}
+
+enum {
+	/* Commands */
+	OPT_configure            = (1 << 0),
+	OPT_install              = (1 << 1),
+	OPT_list_installed       = (1 << 2),
+	OPT_purge                = (1 << 3),
+	OPT_remove               = (1 << 4),
+	OPT_unpack               = (1 << 5),
+	OPTMASK_cmd              = (1 << 6) - 1,
+	/* Options */
+	OPT_force                = (1 << 6),
+	OPT_force_ignore_depends = (1 << 7),
+	OPT_force_confnew        = (1 << 8),
+	OPT_force_confold        = (1 << 9),
+};
+
+static void unpack_package(deb_file_t *deb_file)
+{
+	const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];
+	const unsigned status_num = search_status_hashtable(package_name);
+	const unsigned status_package_num = status_hashtable[status_num]->package;
+	char *info_prefix;
+	char *list_filename;
+	archive_handle_t *archive_handle;
+	FILE *out_stream;
+	llist_t *accept_list;
+	llist_t *conffile_list;
+	int i;
+
+	/* If existing version, remove it first */
+	conffile_list = NULL;
+	if (strcmp(name_hashtable[get_status(status_num, 3)], "installed") == 0) {
+		/* Package is already installed, remove old version first */
+		printf("Preparing to replace %s %s (using %s)...\n", package_name,
+			name_hashtable[package_hashtable[status_package_num]->version],
+			deb_file->filename);
+
+		/* Read md5sums from old package */
+		if (!(option_mask32 & OPT_force_confold))
+			append_control_file_to_llist(package_name, "md5sums", &conffile_list);
+
+		remove_package(status_package_num, 0);
+	} else {
+		printf("Unpacking %s (from %s)...\n", package_name, deb_file->filename);
+	}
+
+	/* Extract control.tar.gz to /var/lib/dpkg/info/<package>.filename */
+	info_prefix = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, "");
+	archive_handle = init_archive_deb_ar(deb_file->filename);
+	init_archive_deb_control(archive_handle);
+
+	accept_list = NULL;
+	i = 0;
+	while (i < ARRAY_SIZE(all_control_files)) {
+		char *c = xasprintf("./%s", all_control_files[i]);
+		llist_add_to(&accept_list, c);
+		i++;
+	}
+	archive_handle->dpkg__sub_archive->accept = accept_list;
+	archive_handle->dpkg__sub_archive->filter = filter_accept_list;
+	archive_handle->dpkg__sub_archive->action_data = data_extract_all_prefix;
+	archive_handle->dpkg__sub_archive->dpkg__buffer = info_prefix;
+	archive_handle->dpkg__sub_archive->ah_flags |= ARCHIVE_UNLINK_OLD;
+	unpack_ar_archive(archive_handle);
+
+	/* Run the preinst prior to extracting */
+	run_package_script_or_die(package_name, "preinst");
+
+	/* Don't overwrite existing config files */
+	if (!(option_mask32 & OPT_force_confnew))
+		append_control_file_to_llist(package_name, "conffiles", &conffile_list);
+
+	/* Extract data.tar.gz to the root directory */
+	archive_handle = init_archive_deb_ar(deb_file->filename);
+	init_archive_deb_data(archive_handle);
+	archive_handle->dpkg__sub_archive->accept = conffile_list;
+	archive_handle->dpkg__sub_archive->filter = filter_rename_config;
+	archive_handle->dpkg__sub_archive->action_data = data_extract_all_prefix;
+	archive_handle->dpkg__sub_archive->dpkg__buffer = (char*)"/"; /* huh? */
+	archive_handle->dpkg__sub_archive->ah_flags |= ARCHIVE_UNLINK_OLD;
+	unpack_ar_archive(archive_handle);
+
+	/* Create the list file */
+	list_filename = xasprintf("/var/lib/dpkg/info/%s.%s", package_name, "list");
+	out_stream = xfopen_for_write(list_filename);
+	while (archive_handle->dpkg__sub_archive->passed) {
+		/* the leading . has been stripped by data_extract_all_prefix already */
+		fputs(archive_handle->dpkg__sub_archive->passed->data, out_stream);
+		fputc('\n', out_stream);
+		archive_handle->dpkg__sub_archive->passed = archive_handle->dpkg__sub_archive->passed->link;
+	}
+	fclose(out_stream);
+
+	/* change status */
+	set_status(status_num, "install", 1);
+	set_status(status_num, "unpacked", 3);
+
+	free(info_prefix);
+	free(list_filename);
+}
+
+static void configure_package(deb_file_t *deb_file)
+{
+	const char *package_name = name_hashtable[package_hashtable[deb_file->package]->name];
+	const char *package_version = name_hashtable[package_hashtable[deb_file->package]->version];
+	const int status_num = search_status_hashtable(package_name);
+
+	printf("Setting up %s (%s)...\n", package_name, package_version);
+
+	/* Run the postinst script */
+	/* TODO: handle failure gracefully */
+	run_package_script_or_die(package_name, "postinst");
+
+	/* Change status to reflect success */
+	set_status(status_num, "install", 1);
+	set_status(status_num, "installed", 3);
+}
+
+int dpkg_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int dpkg_main(int argc UNUSED_PARAM, char **argv)
+{
+	deb_file_t **deb_file = NULL;
+	status_node_t *status_node;
+	char *str_f;
+	int opt;
+	int package_num;
+	int deb_count = 0;
+	int state_status;
+	int status_num;
+	int i;
+#if ENABLE_LONG_OPTS
+	static const char dpkg_longopts[] ALIGN1 =
+// FIXME: we use -C non-compatibly, should be:
+// "-C|--audit Check for broken package(s)"
+		"configure\0"      No_argument        "C"
+		"force\0"          Required_argument  "F"
+		"install\0"        No_argument        "i"
+		"list\0"           No_argument        "l"
+		"purge\0"          No_argument        "P"
+		"remove\0"         No_argument        "r"
+		"unpack\0"         No_argument        "u"
+		"force-depends\0"  No_argument        "\xff"
+		"force-confnew\0"  No_argument        "\xfe"
+		"force-confold\0"  No_argument        "\xfd"
+		;
+#endif
+
+	INIT_G();
+
+	IF_LONG_OPTS(applet_long_options = dpkg_longopts);
+	opt = getopt32(argv, "CilPruF:", &str_f);
+	argv += optind;
+	//if (opt & OPT_configure) ... // -C
+	if (opt & OPT_force) { // -F (--force in official dpkg)
+		if (strcmp(str_f, "depends") == 0)
+			opt |= OPT_force_ignore_depends;
+		else if (strcmp(str_f, "confnew") == 0)
+			opt |= OPT_force_confnew;
+		else if (strcmp(str_f, "confold") == 0)
+			opt |= OPT_force_confold;
+		else
+			bb_show_usage();
+		option_mask32 = opt;
+	}
+	//if (opt & OPT_install) ... // -i
+	//if (opt & OPT_list_installed) ... // -l
+	//if (opt & OPT_purge) ... // -P
+	//if (opt & OPT_remove) ... // -r
+	//if (opt & OPT_unpack) ... // -u (--unpack in official dpkg)
+	if (!(opt & OPTMASK_cmd) /* no cmd */
+	 || ((opt & OPTMASK_cmd) & ((opt & OPTMASK_cmd)-1)) /* more than one cmd */
+	) {
+		bb_show_usage();
+	}
+
+/*	puts("(Reading database ... xxxxx files and directories installed.)"); */
+	index_status_file("/var/lib/dpkg/status");
+
+	/* if the list action was given print the installed packages and exit */
+	if (opt & OPT_list_installed) {
+		list_packages(argv[0]); /* param can be NULL */
+		return EXIT_SUCCESS;
+	}
+
+	/* Read arguments and store relevant info in structs */
+	while (*argv) {
+		/* deb_count = nb_elem - 1 and we need nb_elem + 1 to allocate terminal node [NULL pointer] */
+		deb_file = xrealloc_vector(deb_file, 2, deb_count);
+		deb_file[deb_count] = xzalloc(sizeof(deb_file[0][0]));
+		if (opt & (OPT_install | OPT_unpack)) {
+			/* -i/-u: require filename */
+			archive_handle_t *archive_handle;
+			llist_t *control_list = NULL;
+
+			/* Extract the control file */
+			llist_add_to(&control_list, (char*)"./control");
+			archive_handle = init_archive_deb_ar(argv[0]);
+			init_archive_deb_control(archive_handle);
+			deb_file[deb_count]->control_file = deb_extract_control_file_to_buffer(archive_handle, control_list);
+			if (deb_file[deb_count]->control_file == NULL) {
+				bb_error_msg_and_die("can't extract control file");
+			}
+			deb_file[deb_count]->filename = xstrdup(argv[0]);
+			package_num = fill_package_struct(deb_file[deb_count]->control_file);
+
+			if (package_num == -1) {
+				bb_error_msg("invalid control file in %s", argv[0]);
+				argv++;
+				continue;
+			}
+			deb_file[deb_count]->package = (unsigned) package_num;
+
+			/* Add the package to the status hashtable */
+			if (opt & (OPT_unpack | OPT_install)) {
+				/* Try and find a currently installed version of this package */
+				status_num = search_status_hashtable(name_hashtable[package_hashtable[deb_file[deb_count]->package]->name]);
+				/* If no previous entry was found initialise a new entry */
+				if (status_hashtable[status_num] == NULL
+				 || status_hashtable[status_num]->status == 0
+				) {
+					status_node = xmalloc(sizeof(status_node_t));
+					status_node->package = deb_file[deb_count]->package;
+					/* reinstreq isnt changed to "ok" until the package control info
+					 * is written to the status file*/
+					status_node->status = search_name_hashtable("install reinstreq not-installed");
+					status_hashtable[status_num] = status_node;
+				} else {
+					set_status(status_num, "install", 1);
+					set_status(status_num, "reinstreq", 2);
+				}
+			}
+		} else if (opt & (OPT_configure | OPT_purge | OPT_remove)) {
+			/* -C/-p/-r: require package name */
+			deb_file[deb_count]->package = search_package_hashtable(
+					search_name_hashtable(argv[0]),
+					search_name_hashtable("ANY"), VER_ANY);
+			if (package_hashtable[deb_file[deb_count]->package] == NULL) {
+				bb_error_msg_and_die("package %s is uninstalled or unknown", argv[0]);
+			}
+			package_num = deb_file[deb_count]->package;
+			status_num = search_status_hashtable(name_hashtable[package_hashtable[package_num]->name]);
+			state_status = get_status(status_num, 3);
+
+			/* check package status is "installed" */
+			if (opt & OPT_remove) {
+				if (strcmp(name_hashtable[state_status], "not-installed") == 0
+				 || strcmp(name_hashtable[state_status], "config-files") == 0
+				) {
+					bb_error_msg_and_die("%s is already removed", name_hashtable[package_hashtable[package_num]->name]);
+				}
+				set_status(status_num, "deinstall", 1);
+			} else if (opt & OPT_purge) {
+				/* if package status is "conf-files" then its ok */
+				if (strcmp(name_hashtable[state_status], "not-installed") == 0) {
+					bb_error_msg_and_die("%s is already purged", name_hashtable[package_hashtable[package_num]->name]);
+				}
+				set_status(status_num, "purge", 1);
+			}
+		}
+		deb_count++;
+		argv++;
+	}
+	if (!deb_count)
+		bb_error_msg_and_die("no package files specified");
+	deb_file[deb_count] = NULL;
+
+	/* Check that the deb file arguments are installable */
+	if (!(opt & OPT_force_ignore_depends)) {
+		if (!check_deps(deb_file, 0 /*, deb_count*/)) {
+			bb_error_msg_and_die("dependency check failed");
+		}
+	}
+
+	/* TODO: install or remove packages in the correct dependency order */
+	for (i = 0; i < deb_count; i++) {
+		/* Remove or purge packages */
+		if (opt & OPT_remove) {
+			remove_package(deb_file[i]->package, 1);
+		}
+		else if (opt & OPT_purge) {
+			purge_package(deb_file[i]->package);
+		}
+		else if (opt & OPT_unpack) {
+			unpack_package(deb_file[i]);
+		}
+		else if (opt & OPT_install) {
+			unpack_package(deb_file[i]);
+			/* package is configured in second pass below */
+		}
+		else if (opt & OPT_configure) {
+			configure_package(deb_file[i]);
+		}
+	}
+	/* configure installed packages */
+	if (opt & OPT_install) {
+		for (i = 0; i < deb_count; i++)
+			configure_package(deb_file[i]);
+	}
+
+	write_status_file(deb_file);
+
+	if (ENABLE_FEATURE_CLEAN_UP) {
+		for (i = 0; i < deb_count; i++) {
+			free(deb_file[i]->control_file);
+			free(deb_file[i]->filename);
+			free(deb_file[i]);
+		}
+
+		free(deb_file);
+
+		for (i = 0; i < NAME_HASH_PRIME; i++) {
+			free(name_hashtable[i]);
+		}
+
+		for (i = 0; i < PACKAGE_HASH_PRIME; i++) {
+			free_package(package_hashtable[i]);
+		}
+
+		for (i = 0; i < STATUS_HASH_PRIME; i++) {
+			free(status_hashtable[i]);
+		}
+
+		free(status_hashtable);
+		free(package_hashtable);
+		free(name_hashtable);
+	}
+
+	return EXIT_SUCCESS;
+}
diff --git a/busybox-1.19.3/archival/dpkg_deb.c b/busybox-1.19.3/archival/dpkg_deb.c
new file mode 100644
index 0000000..5d814d7
--- /dev/null
+++ b/busybox-1.19.3/archival/dpkg_deb.c
@@ -0,0 +1,121 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * dpkg-deb packs, unpacks and provides information about Debian archives.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+//usage:#define dpkg_deb_trivial_usage
+//usage:       "[-cefxX] FILE [argument"
+//usage:#define dpkg_deb_full_usage "\n\n"
+//usage:       "Perform actions on Debian packages (.debs)\n"
+//usage:     "\n	-c	List contents of filesystem tree"
+//usage:     "\n	-e	Extract control files to [argument] directory"
+//usage:     "\n	-f	Display control field name starting with [argument]"
+//usage:     "\n	-x	Extract packages filesystem tree to directory"
+//usage:     "\n	-X	Verbose extract"
+//usage:
+//usage:#define dpkg_deb_example_usage
+//usage:       "$ dpkg-deb -X ./busybox_0.48-1_i386.deb /tmp\n"
+
+#include "libbb.h"
+#include "archive.h"
+
+#define DPKG_DEB_OPT_CONTENTS         1
+#define DPKG_DEB_OPT_CONTROL          2
+#define DPKG_DEB_OPT_FIELD            4
+#define DPKG_DEB_OPT_EXTRACT          8
+#define DPKG_DEB_OPT_EXTRACT_VERBOSE 16
+
+int dpkg_deb_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int dpkg_deb_main(int argc, char **argv)
+{
+	archive_handle_t *ar_archive;
+	archive_handle_t *tar_archive;
+	llist_t *control_tar_llist = NULL;
+	unsigned opt;
+	const char *extract_dir;
+	int need_args;
+
+	/* Setup the tar archive handle */
+	tar_archive = init_handle();
+
+	/* Setup an ar archive handle that refers to the gzip sub archive */
+	ar_archive = init_handle();
+	ar_archive->dpkg__sub_archive = tar_archive;
+	ar_archive->filter = filter_accept_list_reassign;
+
+#if ENABLE_FEATURE_SEAMLESS_GZ
+	llist_add_to(&ar_archive->accept, (char*)"data.tar.gz");
+	llist_add_to(&control_tar_llist, (char*)"control.tar.gz");
+#endif
+#if ENABLE_FEATURE_SEAMLESS_BZ2
+	llist_add_to(&ar_archive->accept, (char*)"data.tar.bz2");
+	llist_add_to(&control_tar_llist, (char*)"control.tar.bz2");
+#endif
+#if ENABLE_FEATURE_SEAMLESS_LZMA
+	llist_add_to(&ar_archive->accept, (char*)"data.tar.lzma");
+	llist_add_to(&control_tar_llist, (char*)"control.tar.lzma");
+#endif
+
+	opt_complementary = "c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX";
+	opt = getopt32(argv, "cefXx");
+	argv += optind;
+	argc -= optind;
+
+	if (opt & DPKG_DEB_OPT_CONTENTS) {
+		tar_archive->action_header = header_verbose_list;
+	}
+	extract_dir = NULL;
+	need_args = 1;
+	if (opt & DPKG_DEB_OPT_CONTROL) {
+		ar_archive->accept = control_tar_llist;
+		tar_archive->action_data = data_extract_all;
+		if (1 == argc) {
+			extract_dir = "./DEBIAN";
+		} else {
+			need_args++;
+		}
+	}
+	if (opt & DPKG_DEB_OPT_FIELD) {
+		/* Print the entire control file
+		 * it should accept a second argument which specifies a
+		 * specific field to print */
+		ar_archive->accept = control_tar_llist;
+		llist_add_to(&(tar_archive->accept), (char*)"./control");
+		tar_archive->filter = filter_accept_list;
+		tar_archive->action_data = data_extract_to_stdout;
+	}
+	if (opt & DPKG_DEB_OPT_EXTRACT) {
+		tar_archive->action_header = header_list;
+	}
+	if (opt & (DPKG_DEB_OPT_EXTRACT_VERBOSE | DPKG_DEB_OPT_EXTRACT)) {
+		tar_archive->action_data = data_extract_all;
+		need_args = 2;
+	}
+
+	if (need_args != argc) {
+		bb_show_usage();
+	}
+
+	tar_archive->src_fd = ar_archive->src_fd = xopen(argv[0], O_RDONLY);
+
+	/* Work out where to extract the files */
+	/* 2nd argument is a dir name */
+	if (argv[1]) {
+		extract_dir = argv[1];
+	}
+	if (extract_dir) {
+		mkdir(extract_dir, 0777); /* bb_make_directory(extract_dir, 0777, 0) */
+		xchdir(extract_dir);
+	}
+
+	/* Do it */
+	unpack_ar_archive(ar_archive);
+
+	/* Cleanup */
+	if (ENABLE_FEATURE_CLEAN_UP)
+		close(ar_archive->src_fd);
+
+	return EXIT_SUCCESS;
+}
diff --git a/busybox-1.19.3/archival/gzip.c b/busybox-1.19.3/archival/gzip.c
new file mode 100644
index 0000000..403eb4d
--- /dev/null
+++ b/busybox-1.19.3/archival/gzip.c
@@ -0,0 +1,2120 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Gzip implementation for busybox
+ *
+ * Based on GNU gzip Copyright (C) 1992-1993 Jean-loup Gailly.
+ *
+ * Originally adjusted for busybox by Charles P. Wright <cpw@unix.asb.com>
+ * "this is a stripped down version of gzip I put into busybox, it does
+ * only standard in to standard out with -9 compression.  It also requires
+ * the zcat module for some important functions."
+ *
+ * Adjusted further by Erik Andersen <andersen@codepoet.org> to support
+ * files as well as stdin/stdout, and to generally behave itself wrt
+ * command line handling.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+/* big objects in bss:
+ * 00000020 b bl_count
+ * 00000074 b base_length
+ * 00000078 b base_dist
+ * 00000078 b static_dtree
+ * 0000009c b bl_tree
+ * 000000f4 b dyn_dtree
+ * 00000100 b length_code
+ * 00000200 b dist_code
+ * 0000023d b depth
+ * 00000400 b flag_buf
+ * 0000047a b heap
+ * 00000480 b static_ltree
+ * 000008f4 b dyn_ltree
+ */
+
+/* TODO: full support for -v for DESKTOP
+ * "/usr/bin/gzip -v a bogus aa" should say:
+a:       85.1% -- replaced with a.gz
+gzip: bogus: No such file or directory
+aa:      85.1% -- replaced with aa.gz
+*/
+
+//usage:#define gzip_trivial_usage
+//usage:       "[-cfd] [FILE]..."
+//usage:#define gzip_full_usage "\n\n"
+//usage:       "Compress FILEs (or stdin)\n"
+//usage:     "\n	-d	Decompress"
+//usage:     "\n	-c	Write to stdout"
+//usage:     "\n	-f	Force"
+//usage:
+//usage:#define gzip_example_usage
+//usage:       "$ ls -la /tmp/busybox*\n"
+//usage:       "-rw-rw-r--    1 andersen andersen  1761280 Apr 14 17:47 /tmp/busybox.tar\n"
+//usage:       "$ gzip /tmp/busybox.tar\n"
+//usage:       "$ ls -la /tmp/busybox*\n"
+//usage:       "-rw-rw-r--    1 andersen andersen   554058 Apr 14 17:49 /tmp/busybox.tar.gz\n"
+
+#include "libbb.h"
+#include "archive.h"
+
+
+/* ===========================================================================
+ */
+//#define DEBUG 1
+/* Diagnostic functions */
+#ifdef DEBUG
+#  define Assert(cond,msg) { if (!(cond)) bb_error_msg(msg); }
+#  define Trace(x) fprintf x
+#  define Tracev(x) {if (verbose) fprintf x; }
+#  define Tracevv(x) {if (verbose > 1) fprintf x; }
+#  define Tracec(c,x) {if (verbose && (c)) fprintf x; }
+#  define Tracecv(c,x) {if (verbose > 1 && (c)) fprintf x; }
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+
+/* ===========================================================================
+ */
+#define SMALL_MEM
+
+#ifndef INBUFSIZ
+#  ifdef SMALL_MEM
+#    define INBUFSIZ  0x2000	/* input buffer size */
+#  else
+#    define INBUFSIZ  0x8000	/* input buffer size */
+#  endif
+#endif
+
+#ifndef OUTBUFSIZ
+#  ifdef SMALL_MEM
+#    define OUTBUFSIZ   8192	/* output buffer size */
+#  else
+#    define OUTBUFSIZ  16384	/* output buffer size */
+#  endif
+#endif
+
+#ifndef DIST_BUFSIZE
+#  ifdef SMALL_MEM
+#    define DIST_BUFSIZE 0x2000	/* buffer for distances, see trees.c */
+#  else
+#    define DIST_BUFSIZE 0x8000	/* buffer for distances, see trees.c */
+#  endif
+#endif
+
+/* gzip flag byte */
+#define ASCII_FLAG   0x01	/* bit 0 set: file probably ascii text */
+#define CONTINUATION 0x02	/* bit 1 set: continuation of multi-part gzip file */
+#define EXTRA_FIELD  0x04	/* bit 2 set: extra field present */
+#define ORIG_NAME    0x08	/* bit 3 set: original file name present */
+#define COMMENT      0x10	/* bit 4 set: file comment present */
+#define RESERVED     0xC0	/* bit 6,7:   reserved */
+
+/* internal file attribute */
+#define UNKNOWN 0xffff
+#define BINARY  0
+#define ASCII   1
+
+#ifndef WSIZE
+#  define WSIZE 0x8000  /* window size--must be a power of two, and */
+#endif                  /*  at least 32K for zip's deflate method */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST  (WSIZE-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+#ifndef MAX_PATH_LEN
+#  define MAX_PATH_LEN   1024	/* max pathname length */
+#endif
+
+#define seekable()    0	/* force sequential output */
+#define translate_eol 0	/* no option -a yet */
+
+#ifndef BITS
+#  define BITS 16
+#endif
+#define INIT_BITS 9		/* Initial number of bits per code */
+
+#define BIT_MASK    0x1f	/* Mask for 'number of compression bits' */
+/* Mask 0x20 is reserved to mean a fourth header byte, and 0x40 is free.
+ * It's a pity that old uncompress does not check bit 0x20. That makes
+ * extension of the format actually undesirable because old compress
+ * would just crash on the new format instead of giving a meaningful
+ * error message. It does check the number of bits, but it's more
+ * helpful to say "unsupported format, get a new version" than
+ * "can only handle 16 bits".
+ */
+
+#ifdef MAX_EXT_CHARS
+#  define MAX_SUFFIX  MAX_EXT_CHARS
+#else
+#  define MAX_SUFFIX  30
+#endif
+
+
+/* ===========================================================================
+ * Compile with MEDIUM_MEM to reduce the memory requirements or
+ * with SMALL_MEM to use as little memory as possible. Use BIG_MEM if the
+ * entire input file can be held in memory (not possible on 16 bit systems).
+ * Warning: defining these symbols affects HASH_BITS (see below) and thus
+ * affects the compression ratio. The compressed output
+ * is still correct, and might even be smaller in some cases.
+ */
+
+#ifdef SMALL_MEM
+#   define HASH_BITS  13	/* Number of bits used to hash strings */
+#endif
+#ifdef MEDIUM_MEM
+#   define HASH_BITS  14
+#endif
+#ifndef HASH_BITS
+#   define HASH_BITS  15
+   /* For portability to 16 bit machines, do not use values above 15. */
+#endif
+
+#define HASH_SIZE (unsigned)(1<<HASH_BITS)
+#define HASH_MASK (HASH_SIZE-1)
+#define WMASK     (WSIZE-1)
+/* HASH_SIZE and WSIZE must be powers of two */
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+
+/* ===========================================================================
+ * These types are not really 'char', 'short' and 'long'
+ */
+typedef uint8_t uch;
+typedef uint16_t ush;
+typedef uint32_t ulg;
+typedef int32_t lng;
+
+typedef ush Pos;
+typedef unsigned IPos;
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+enum {
+	WINDOW_SIZE = 2 * WSIZE,
+/* window size, 2*WSIZE except for MMAP or BIG_MEM, where it is the
+ * input file length plus MIN_LOOKAHEAD.
+ */
+
+	max_chain_length = 4096,
+/* To speed up deflation, hash chains are never searched beyond this length.
+ * A higher limit improves compression ratio but degrades the speed.
+ */
+
+	max_lazy_match = 258,
+/* Attempt to find a better match only when the current match is strictly
+ * smaller than this value. This mechanism is used only for compression
+ * levels >= 4.
+ */
+
+	max_insert_length = max_lazy_match,
+/* Insert new strings in the hash table only if the match length
+ * is not greater than this length. This saves time but degrades compression.
+ * max_insert_length is used only for compression levels <= 3.
+ */
+
+	good_match = 32,
+/* Use a faster search when the previous match is longer than this */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+
+	nice_match = 258,	/* Stop searching when current match exceeds this */
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+};
+
+
+struct globals {
+
+	lng block_start;
+
+/* window position at the beginning of the current output block. Gets
+ * negative when the window is moved backwards.
+ */
+	unsigned ins_h;	/* hash index of string to be inserted */
+
+#define H_SHIFT  ((HASH_BITS+MIN_MATCH-1) / MIN_MATCH)
+/* Number of bits by which ins_h and del_h must be shifted at each
+ * input step. It must be such that after MIN_MATCH steps, the oldest
+ * byte no longer takes part in the hash key, that is:
+ * H_SHIFT * MIN_MATCH >= HASH_BITS
+ */
+
+	unsigned prev_length;
+
+/* Length of the best match at previous step. Matches not greater than this
+ * are discarded. This is used in the lazy match evaluation.
+ */
+
+	unsigned strstart;	/* start of string to insert */
+	unsigned match_start;	/* start of matching string */
+	unsigned lookahead;	/* number of valid bytes ahead in window */
+
+/* ===========================================================================
+ */
+#define DECLARE(type, array, size) \
+	type * array
+#define ALLOC(type, array, size) \
+	array = xzalloc((size_t)(((size)+1L)/2) * 2*sizeof(type))
+#define FREE(array) \
+	do { free(array); array = NULL; } while (0)
+
+	/* global buffers */
+
+	/* buffer for literals or lengths */
+	/* DECLARE(uch, l_buf, LIT_BUFSIZE); */
+	DECLARE(uch, l_buf, INBUFSIZ);
+
+	DECLARE(ush, d_buf, DIST_BUFSIZE);
+	DECLARE(uch, outbuf, OUTBUFSIZ);
+
+/* Sliding window. Input bytes are read into the second half of the window,
+ * and move to the first half later to keep a dictionary of at least WSIZE
+ * bytes. With this organization, matches are limited to a distance of
+ * WSIZE-MAX_MATCH bytes, but this ensures that IO is always
+ * performed with a length multiple of the block size. Also, it limits
+ * the window size to 64K, which is quite useful on MSDOS.
+ * To do: limit the window size to WSIZE+BSZ if SMALL_MEM (the code would
+ * be less efficient).
+ */
+	DECLARE(uch, window, 2L * WSIZE);
+
+/* Link to older string with same hash index. To limit the size of this
+ * array to 64K, this link is maintained only for the last 32K strings.
+ * An index in this array is thus a window index modulo 32K.
+ */
+	/* DECLARE(Pos, prev, WSIZE); */
+	DECLARE(ush, prev, 1L << BITS);
+
+/* Heads of the hash chains or 0. */
+	/* DECLARE(Pos, head, 1<<HASH_BITS); */
+#define head (G1.prev + WSIZE) /* hash head (see deflate.c) */
+
+/* number of input bytes */
+	ulg isize;		/* only 32 bits stored in .gz file */
+
+/* bbox always use stdin/stdout */
+#define ifd STDIN_FILENO	/* input file descriptor */
+#define ofd STDOUT_FILENO	/* output file descriptor */
+
+#ifdef DEBUG
+	unsigned insize;	/* valid bytes in l_buf */
+#endif
+	unsigned outcnt;	/* bytes in output buffer */
+
+	smallint eofile;	/* flag set at end of input file */
+
+/* ===========================================================================
+ * Local data used by the "bit string" routines.
+ */
+
+	unsigned short bi_buf;
+
+/* Output buffer. bits are inserted starting at the bottom (least significant
+ * bits).
+ */
+
+#undef BUF_SIZE
+#define BUF_SIZE (8 * sizeof(G1.bi_buf))
+/* Number of bits used within bi_buf. (bi_buf might be implemented on
+ * more than 16 bits on some systems.)
+ */
+
+	int bi_valid;
+
+/* Current input function. Set to mem_read for in-memory compression */
+
+#ifdef DEBUG
+	ulg bits_sent;			/* bit length of the compressed data */
+#endif
+
+	/*uint32_t *crc_32_tab;*/
+	uint32_t crc;	/* shift register contents */
+};
+
+#define G1 (*(ptr_to_globals - 1))
+
+
+/* ===========================================================================
+ * Write the output buffer outbuf[0..outcnt-1] and update bytes_out.
+ * (used for the compressed data only)
+ */
+static void flush_outbuf(void)
+{
+	if (G1.outcnt == 0)
+		return;
+
+	xwrite(ofd, (char *) G1.outbuf, G1.outcnt);
+	G1.outcnt = 0;
+}
+
+
+/* ===========================================================================
+ */
+/* put_8bit is used for the compressed output */
+#define put_8bit(c) \
+do { \
+	G1.outbuf[G1.outcnt++] = (c); \
+	if (G1.outcnt == OUTBUFSIZ) flush_outbuf(); \
+} while (0)
+
+/* Output a 16 bit value, lsb first */
+static void put_16bit(ush w)
+{
+	if (G1.outcnt < OUTBUFSIZ - 2) {
+		G1.outbuf[G1.outcnt++] = w;
+		G1.outbuf[G1.outcnt++] = w >> 8;
+	} else {
+		put_8bit(w);
+		put_8bit(w >> 8);
+	}
+}
+
+static void put_32bit(ulg n)
+{
+	put_16bit(n);
+	put_16bit(n >> 16);
+}
+
+/* ===========================================================================
+ * Run a set of bytes through the crc shift register.  If s is a NULL
+ * pointer, then initialize the crc shift register contents instead.
+ * Return the current crc in either case.
+ */
+static void updcrc(uch * s, unsigned n)
+{
+	G1.crc = crc32_block_endian0(G1.crc, s, n, global_crc32_table /*G1.crc_32_tab*/);
+}
+
+
+/* ===========================================================================
+ * Read a new buffer from the current input file, perform end-of-line
+ * translation, and update the crc and input file size.
+ * IN assertion: size >= 2 (for end-of-line translation)
+ */
+static unsigned file_read(void *buf, unsigned size)
+{
+	unsigned len;
+
+	Assert(G1.insize == 0, "l_buf not empty");
+
+	len = safe_read(ifd, buf, size);
+	if (len == (unsigned)(-1) || len == 0)
+		return len;
+
+	updcrc(buf, len);
+	G1.isize += len;
+	return len;
+}
+
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+static void send_bits(int value, int length)
+{
+#ifdef DEBUG
+	Tracev((stderr, " l %2d v %4x ", length, value));
+	Assert(length > 0 && length <= 15, "invalid length");
+	G1.bits_sent += length;
+#endif
+	/* If not enough room in bi_buf, use (valid) bits from bi_buf and
+	 * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+	 * unused bits in value.
+	 */
+	if (G1.bi_valid > (int) BUF_SIZE - length) {
+		G1.bi_buf |= (value << G1.bi_valid);
+		put_16bit(G1.bi_buf);
+		G1.bi_buf = (ush) value >> (BUF_SIZE - G1.bi_valid);
+		G1.bi_valid += length - BUF_SIZE;
+	} else {
+		G1.bi_buf |= value << G1.bi_valid;
+		G1.bi_valid += length;
+	}
+}
+
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+static unsigned bi_reverse(unsigned code, int len)
+{
+	unsigned res = 0;
+
+	while (1) {
+		res |= code & 1;
+		if (--len <= 0) return res;
+		code >>= 1;
+		res <<= 1;
+	}
+}
+
+
+/* ===========================================================================
+ * Write out any remaining bits in an incomplete byte.
+ */
+static void bi_windup(void)
+{
+	if (G1.bi_valid > 8) {
+		put_16bit(G1.bi_buf);
+	} else if (G1.bi_valid > 0) {
+		put_8bit(G1.bi_buf);
+	}
+	G1.bi_buf = 0;
+	G1.bi_valid = 0;
+#ifdef DEBUG
+	G1.bits_sent = (G1.bits_sent + 7) & ~7;
+#endif
+}
+
+
+/* ===========================================================================
+ * Copy a stored block to the zip file, storing first the length and its
+ * one's complement if requested.
+ */
+static void copy_block(char *buf, unsigned len, int header)
+{
+	bi_windup();		/* align on byte boundary */
+
+	if (header) {
+		put_16bit(len);
+		put_16bit(~len);
+#ifdef DEBUG
+		G1.bits_sent += 2 * 16;
+#endif
+	}
+#ifdef DEBUG
+	G1.bits_sent += (ulg) len << 3;
+#endif
+	while (len--) {
+		put_8bit(*buf++);
+	}
+}
+
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead, and sets eofile if end of input file.
+ * IN assertion: lookahead < MIN_LOOKAHEAD && strstart + lookahead > 0
+ * OUT assertions: at least one byte has been read, or eofile is set;
+ *    file reads are performed for at least two bytes (required for the
+ *    translate_eol option).
+ */
+static void fill_window(void)
+{
+	unsigned n, m;
+	unsigned more =	WINDOW_SIZE - G1.lookahead - G1.strstart;
+	/* Amount of free space at the end of the window. */
+
+	/* If the window is almost full and there is insufficient lookahead,
+	 * move the upper half to the lower one to make room in the upper half.
+	 */
+	if (more == (unsigned) -1) {
+		/* Very unlikely, but possible on 16 bit machine if strstart == 0
+		 * and lookahead == 1 (input done one byte at time)
+		 */
+		more--;
+	} else if (G1.strstart >= WSIZE + MAX_DIST) {
+		/* By the IN assertion, the window is not empty so we can't confuse
+		 * more == 0 with more == 64K on a 16 bit machine.
+		 */
+		Assert(WINDOW_SIZE == 2 * WSIZE, "no sliding with BIG_MEM");
+
+		memcpy(G1.window, G1.window + WSIZE, WSIZE);
+		G1.match_start -= WSIZE;
+		G1.strstart -= WSIZE;	/* we now have strstart >= MAX_DIST: */
+
+		G1.block_start -= WSIZE;
+
+		for (n = 0; n < HASH_SIZE; n++) {
+			m = head[n];
+			head[n] = (Pos) (m >= WSIZE ? m - WSIZE : 0);
+		}
+		for (n = 0; n < WSIZE; n++) {
+			m = G1.prev[n];
+			G1.prev[n] = (Pos) (m >= WSIZE ? m - WSIZE : 0);
+			/* If n is not on any hash chain, prev[n] is garbage but
+			 * its value will never be used.
+			 */
+		}
+		more += WSIZE;
+	}
+	/* At this point, more >= 2 */
+	if (!G1.eofile) {
+		n = file_read(G1.window + G1.strstart + G1.lookahead, more);
+		if (n == 0 || n == (unsigned) -1) {
+			G1.eofile = 1;
+		} else {
+			G1.lookahead += n;
+		}
+	}
+}
+
+
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ */
+
+/* For MSDOS, OS/2 and 386 Unix, an optimized version is in match.asm or
+ * match.s. The code is functionally equivalent, so you can use the C version
+ * if desired.
+ */
+static int longest_match(IPos cur_match)
+{
+	unsigned chain_length = max_chain_length;	/* max hash chain length */
+	uch *scan = G1.window + G1.strstart;	/* current string */
+	uch *match;	/* matched string */
+	int len;	/* length of current match */
+	int best_len = G1.prev_length;	/* best match length so far */
+	IPos limit = G1.strstart > (IPos) MAX_DIST ? G1.strstart - (IPos) MAX_DIST : 0;
+	/* Stop when cur_match becomes <= limit. To simplify the code,
+	 * we prevent matches with the string of window index 0.
+	 */
+
+/* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+ * It is easy to get rid of this optimization if necessary.
+ */
+#if HASH_BITS < 8 || MAX_MATCH != 258
+#  error Code too clever
+#endif
+	uch *strend = G1.window + G1.strstart + MAX_MATCH;
+	uch scan_end1 = scan[best_len - 1];
+	uch scan_end = scan[best_len];
+
+	/* Do not waste too much time if we already have a good match: */
+	if (G1.prev_length >= good_match) {
+		chain_length >>= 2;
+	}
+	Assert(G1.strstart <= WINDOW_SIZE - MIN_LOOKAHEAD, "insufficient lookahead");
+
+	do {
+		Assert(cur_match < G1.strstart, "no future");
+		match = G1.window + cur_match;
+
+		/* Skip to next match if the match length cannot increase
+		 * or if the match length is less than 2:
+		 */
+		if (match[best_len] != scan_end
+		 || match[best_len - 1] != scan_end1
+		 || *match != *scan || *++match != scan[1]
+		) {
+			continue;
+		}
+
+		/* The check at best_len-1 can be removed because it will be made
+		 * again later. (This heuristic is not always a win.)
+		 * It is not necessary to compare scan[2] and match[2] since they
+		 * are always equal when the other bytes match, given that
+		 * the hash keys are equal and that HASH_BITS >= 8.
+		 */
+		scan += 2, match++;
+
+		/* We check for insufficient lookahead only every 8th comparison;
+		 * the 256th check will be made at strstart+258.
+		 */
+		do {
+		} while (*++scan == *++match && *++scan == *++match &&
+				 *++scan == *++match && *++scan == *++match &&
+				 *++scan == *++match && *++scan == *++match &&
+				 *++scan == *++match && *++scan == *++match && scan < strend);
+
+		len = MAX_MATCH - (int) (strend - scan);
+		scan = strend - MAX_MATCH;
+
+		if (len > best_len) {
+			G1.match_start = cur_match;
+			best_len = len;
+			if (len >= nice_match)
+				break;
+			scan_end1 = scan[best_len - 1];
+			scan_end = scan[best_len];
+		}
+	} while ((cur_match = G1.prev[cur_match & WMASK]) > limit
+			 && --chain_length != 0);
+
+	return best_len;
+}
+
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+static void check_match(IPos start, IPos match, int length)
+{
+	/* check that the match is indeed a match */
+	if (memcmp(G1.window + match, G1.window + start, length) != 0) {
+		bb_error_msg(" start %d, match %d, length %d", start, match, length);
+		bb_error_msg("invalid match");
+	}
+	if (verbose > 1) {
+		bb_error_msg("\\[%d,%d]", start - match, length);
+		do {
+			bb_putchar_stderr(G1.window[start++]);
+		} while (--length != 0);
+	}
+}
+#else
+#  define check_match(start, match, length) ((void)0)
+#endif
+
+
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1992-1993 Jean-loup Gailly
+ * This is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License, see the file COPYING.
+ */
+
+/*  PURPOSE
+ *      Encode various sets of source values using variable-length
+ *      binary code trees.
+ *
+ *  DISCUSSION
+ *      The PKZIP "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in the ZIP file in a compressed form
+ *      which is itself a Huffman encoding of the lengths of
+ *      all the code strings (in ascending order by source values).
+ *      The actual code strings are reconstructed from the lengths in
+ *      the UNZIP process, as described in the "application note"
+ *      (APPNOTE.TXT) distributed as part of PKWARE's PKZIP program.
+ *
+ *  REFERENCES
+ *      Lynch, Thomas J.
+ *          Data Compression:  Techniques and Applications, pp. 53-55.
+ *          Lifetime Learning Publications, 1985.  ISBN 0-534-03418-7.
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ *
+ *  INTERFACE
+ *      void ct_init()
+ *          Allocate the match buffer, initialize the various tables [and save
+ *          the location of the internal file attribute (ascii/binary) and
+ *          method (DEFLATE/STORE) -- deleted in bbox]
+ *
+ *      void ct_tally(int dist, int lc);
+ *          Save the match info and tally the frequency counts.
+ *
+ *      ulg flush_block(char *buf, ulg stored_len, int eof)
+ *          Determine the best encoding for the current block: dynamic trees,
+ *          static trees or store, and output the encoded block to the zip
+ *          file. Returns the total compressed length for the file so far.
+ */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+/* extra bits for each length code */
+static const uint8_t extra_lbits[LENGTH_CODES] ALIGN1 = {
+	0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4,
+	4, 4, 5, 5, 5, 5, 0
+};
+
+/* extra bits for each distance code */
+static const uint8_t extra_dbits[D_CODES] ALIGN1 = {
+	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9,
+	10, 10, 11, 11, 12, 12, 13, 13
+};
+
+/* extra bits for each bit length code */
+static const uint8_t extra_blbits[BL_CODES] ALIGN1 = {
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7 };
+
+/* number of codes at each bit length for an optimal tree */
+static const uint8_t bl_order[BL_CODES] ALIGN1 = {
+	16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 };
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#ifndef LIT_BUFSIZE
+#  ifdef SMALL_MEM
+#    define LIT_BUFSIZE  0x2000
+#  else
+#  ifdef MEDIUM_MEM
+#    define LIT_BUFSIZE  0x4000
+#  else
+#    define LIT_BUFSIZE  0x8000
+#  endif
+#  endif
+#endif
+#ifndef DIST_BUFSIZE
+#  define DIST_BUFSIZE  LIT_BUFSIZE
+#endif
+/* Sizes of match buffers for literals/lengths and distances.  There are
+ * 4 reasons for limiting LIT_BUFSIZE to 64K:
+ *   - frequencies can be kept in 16 bit counters
+ *   - if compression is not successful for the first block, all input data is
+ *     still in the window so we can still emit a stored block even when input
+ *     comes from standard input.  (This can also be done for all blocks if
+ *     LIT_BUFSIZE is not greater than 32K.)
+ *   - if compression is not successful for a file smaller than 64K, we can
+ *     even emit a stored file instead of a stored block (saving 5 bytes).
+ *   - creating new Huffman trees less frequently may not provide fast
+ *     adaptation to changes in the input data statistics. (Take for
+ *     example a binary file with poorly compressible code followed by
+ *     a highly compressible string table.) Smaller buffer sizes give
+ *     fast adaptation but have of course the overhead of transmitting trees
+ *     more frequently.
+ *   - I can't count above 4
+ * The current code is general and allows DIST_BUFSIZE < LIT_BUFSIZE (to save
+ * memory at the expense of compression). Some optimizations would be possible
+ * if we rely on DIST_BUFSIZE == LIT_BUFSIZE.
+ */
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+/* ===========================================================================
+*/
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data {
+	union {
+		ush freq;		/* frequency count */
+		ush code;		/* bit string */
+	} fc;
+	union {
+		ush dad;		/* father node in Huffman tree */
+		ush len;		/* length of bit string */
+	} dl;
+} ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+#define HEAP_SIZE (2*L_CODES + 1)
+/* maximum heap size */
+
+typedef struct tree_desc {
+	ct_data *dyn_tree;	/* the dynamic tree */
+	ct_data *static_tree;	/* corresponding static tree or NULL */
+	const uint8_t *extra_bits;	/* extra bits for each code or NULL */
+	int extra_base;		/* base index for extra_bits */
+	int elems;			/* max number of elements in the tree */
+	int max_length;		/* max bit length for the codes */
+	int max_code;		/* largest code with non zero frequency */
+} tree_desc;
+
+struct globals2 {
+
+	ush heap[HEAP_SIZE];     /* heap used to build the Huffman trees */
+	int heap_len;            /* number of elements in the heap */
+	int heap_max;            /* element of largest frequency */
+
+/* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ * The same heap array is used to build all trees.
+ */
+
+	ct_data dyn_ltree[HEAP_SIZE];	/* literal and length tree */
+	ct_data dyn_dtree[2 * D_CODES + 1];	/* distance tree */
+
+	ct_data static_ltree[L_CODES + 2];
+
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see ct_init
+ * below).
+ */
+
+	ct_data static_dtree[D_CODES];
+
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+	ct_data bl_tree[2 * BL_CODES + 1];
+
+/* Huffman tree for the bit lengths */
+
+	tree_desc l_desc;
+	tree_desc d_desc;
+	tree_desc bl_desc;
+
+	ush bl_count[MAX_BITS + 1];
+
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+	uch depth[2 * L_CODES + 1];
+
+/* Depth of each subtree used as tie breaker for trees of equal frequency */
+
+	uch length_code[MAX_MATCH - MIN_MATCH + 1];
+
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+	uch dist_code[512];
+
+/* distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+	int base_length[LENGTH_CODES];
+
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+	int base_dist[D_CODES];
+
+/* First normalized distance for each code (0 = distance of 1) */
+
+	uch flag_buf[LIT_BUFSIZE / 8];
+
+/* flag_buf is a bit array distinguishing literals from lengths in
+ * l_buf, thus indicating the presence or absence of a distance.
+ */
+
+	unsigned last_lit;       /* running index in l_buf */
+	unsigned last_dist;      /* running index in d_buf */
+	unsigned last_flags;     /* running index in flag_buf */
+	uch flags;               /* current flags not yet saved in flag_buf */
+	uch flag_bit;            /* current bit used in flags */
+
+/* bits are filled in flags starting at bit 0 (least significant).
+ * Note: these flags are overkill in the current code since we don't
+ * take advantage of DIST_BUFSIZE == LIT_BUFSIZE.
+ */
+
+	ulg opt_len;             /* bit length of current block with optimal trees */
+	ulg static_len;          /* bit length of current block with static trees */
+
+	ulg compressed_len;      /* total bit length of compressed file */
+};
+
+#define G2ptr ((struct globals2*)(ptr_to_globals))
+#define G2 (*G2ptr)
+
+
+/* ===========================================================================
+ */
+static void gen_codes(ct_data * tree, int max_code);
+static void build_tree(tree_desc * desc);
+static void scan_tree(ct_data * tree, int max_code);
+static void send_tree(ct_data * tree, int max_code);
+static int build_bl_tree(void);
+static void send_all_trees(int lcodes, int dcodes, int blcodes);
+static void compress_block(ct_data * ltree, ct_data * dtree);
+
+
+#ifndef DEBUG
+/* Send a code of the given tree. c and tree must not have side effects */
+#  define SEND_CODE(c, tree) send_bits(tree[c].Code, tree[c].Len)
+#else
+#  define SEND_CODE(c, tree) \
+{ \
+	if (verbose > 1) bb_error_msg("\ncd %3d ", (c)); \
+	send_bits(tree[c].Code, tree[c].Len); \
+}
+#endif
+
+#define D_CODE(dist) \
+	((dist) < 256 ? G2.dist_code[dist] : G2.dist_code[256 + ((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. dist_code[256] and dist_code[257] are never
+ * used.
+ * The arguments must not have side effects.
+ */
+
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+static void init_block(void)
+{
+	int n; /* iterates over tree elements */
+
+	/* Initialize the trees. */
+	for (n = 0; n < L_CODES; n++)
+		G2.dyn_ltree[n].Freq = 0;
+	for (n = 0; n < D_CODES; n++)
+		G2.dyn_dtree[n].Freq = 0;
+	for (n = 0; n < BL_CODES; n++)
+		G2.bl_tree[n].Freq = 0;
+
+	G2.dyn_ltree[END_BLOCK].Freq = 1;
+	G2.opt_len = G2.static_len = 0;
+	G2.last_lit = G2.last_dist = G2.last_flags = 0;
+	G2.flags = 0;
+	G2.flag_bit = 1;
+}
+
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+
+/* Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length. */
+#define SMALLER(tree, n, m) \
+	(tree[n].Freq < tree[m].Freq \
+	|| (tree[n].Freq == tree[m].Freq && G2.depth[n] <= G2.depth[m]))
+
+static void pqdownheap(ct_data * tree, int k)
+{
+	int v = G2.heap[k];
+	int j = k << 1;		/* left son of k */
+
+	while (j <= G2.heap_len) {
+		/* Set j to the smallest of the two sons: */
+		if (j < G2.heap_len && SMALLER(tree, G2.heap[j + 1], G2.heap[j]))
+			j++;
+
+		/* Exit if v is smaller than both sons */
+		if (SMALLER(tree, v, G2.heap[j]))
+			break;
+
+		/* Exchange v with the smallest son */
+		G2.heap[k] = G2.heap[j];
+		k = j;
+
+		/* And continue down the tree, setting j to the left son of k */
+		j <<= 1;
+	}
+	G2.heap[k] = v;
+}
+
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+static void gen_bitlen(tree_desc * desc)
+{
+	ct_data *tree = desc->dyn_tree;
+	const uint8_t *extra = desc->extra_bits;
+	int base = desc->extra_base;
+	int max_code = desc->max_code;
+	int max_length = desc->max_length;
+	ct_data *stree = desc->static_tree;
+	int h;				/* heap index */
+	int n, m;			/* iterate over the tree elements */
+	int bits;			/* bit length */
+	int xbits;			/* extra bits */
+	ush f;				/* frequency */
+	int overflow = 0;	/* number of elements with bit length too large */
+
+	for (bits = 0; bits <= MAX_BITS; bits++)
+		G2.bl_count[bits] = 0;
+
+	/* In a first pass, compute the optimal bit lengths (which may
+	 * overflow in the case of the bit length tree).
+	 */
+	tree[G2.heap[G2.heap_max]].Len = 0;	/* root of the heap */
+
+	for (h = G2.heap_max + 1; h < HEAP_SIZE; h++) {
+		n = G2.heap[h];
+		bits = tree[tree[n].Dad].Len + 1;
+		if (bits > max_length) {
+			bits = max_length;
+			overflow++;
+		}
+		tree[n].Len = (ush) bits;
+		/* We overwrite tree[n].Dad which is no longer needed */
+
+		if (n > max_code)
+			continue;	/* not a leaf node */
+
+		G2.bl_count[bits]++;
+		xbits = 0;
+		if (n >= base)
+			xbits = extra[n - base];
+		f = tree[n].Freq;
+		G2.opt_len += (ulg) f *(bits + xbits);
+
+		if (stree)
+			G2.static_len += (ulg) f * (stree[n].Len + xbits);
+	}
+	if (overflow == 0)
+		return;
+
+	Trace((stderr, "\nbit length overflow\n"));
+	/* This happens for example on obj2 and pic of the Calgary corpus */
+
+	/* Find the first bit length which could increase: */
+	do {
+		bits = max_length - 1;
+		while (G2.bl_count[bits] == 0)
+			bits--;
+		G2.bl_count[bits]--;	/* move one leaf down the tree */
+		G2.bl_count[bits + 1] += 2;	/* move one overflow item as its brother */
+		G2.bl_count[max_length]--;
+		/* The brother of the overflow item also moves one step up,
+		 * but this does not affect bl_count[max_length]
+		 */
+		overflow -= 2;
+	} while (overflow > 0);
+
+	/* Now recompute all bit lengths, scanning in increasing frequency.
+	 * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+	 * lengths instead of fixing only the wrong ones. This idea is taken
+	 * from 'ar' written by Haruhiko Okumura.)
+	 */
+	for (bits = max_length; bits != 0; bits--) {
+		n = G2.bl_count[bits];
+		while (n != 0) {
+			m = G2.heap[--h];
+			if (m > max_code)
+				continue;
+			if (tree[m].Len != (unsigned) bits) {
+				Trace((stderr, "code %d bits %d->%d\n", m, tree[m].Len, bits));
+				G2.opt_len += ((int32_t) bits - tree[m].Len) * tree[m].Freq;
+				tree[m].Len = bits;
+			}
+			n--;
+		}
+	}
+}
+
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+static void gen_codes(ct_data * tree, int max_code)
+{
+	ush next_code[MAX_BITS + 1];	/* next code value for each bit length */
+	ush code = 0;		/* running code value */
+	int bits;			/* bit index */
+	int n;				/* code index */
+
+	/* The distribution counts are first used to generate the code values
+	 * without bit reversal.
+	 */
+	for (bits = 1; bits <= MAX_BITS; bits++) {
+		next_code[bits] = code = (code + G2.bl_count[bits - 1]) << 1;
+	}
+	/* Check that the bit counts in bl_count are consistent. The last code
+	 * must be all ones.
+	 */
+	Assert(code + G2.bl_count[MAX_BITS] - 1 == (1 << MAX_BITS) - 1,
+		   "inconsistent bit counts");
+	Tracev((stderr, "\ngen_codes: max_code %d ", max_code));
+
+	for (n = 0; n <= max_code; n++) {
+		int len = tree[n].Len;
+
+		if (len == 0)
+			continue;
+		/* Now reverse the bits */
+		tree[n].Code = bi_reverse(next_code[len]++, len);
+
+		Tracec(tree != G2.static_ltree,
+			   (stderr, "\nn %3d %c l %2d c %4x (%x) ", n,
+				(n > ' ' ? n : ' '), len, tree[n].Code,
+				next_code[len] - 1));
+	}
+}
+
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+
+/* Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len. */
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+#define PQREMOVE(tree, top) \
+do { \
+	top = G2.heap[SMALLEST]; \
+	G2.heap[SMALLEST] = G2.heap[G2.heap_len--]; \
+	pqdownheap(tree, SMALLEST); \
+} while (0)
+
+static void build_tree(tree_desc * desc)
+{
+	ct_data *tree = desc->dyn_tree;
+	ct_data *stree = desc->static_tree;
+	int elems = desc->elems;
+	int n, m;			/* iterate over heap elements */
+	int max_code = -1;	/* largest code with non zero frequency */
+	int node = elems;	/* next internal node of the tree */
+
+	/* Construct the initial heap, with least frequent element in
+	 * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+	 * heap[0] is not used.
+	 */
+	G2.heap_len = 0;
+	G2.heap_max = HEAP_SIZE;
+
+	for (n = 0; n < elems; n++) {
+		if (tree[n].Freq != 0) {
+			G2.heap[++G2.heap_len] = max_code = n;
+			G2.depth[n] = 0;
+		} else {
+			tree[n].Len = 0;
+		}
+	}
+
+	/* The pkzip format requires that at least one distance code exists,
+	 * and that at least one bit should be sent even if there is only one
+	 * possible code. So to avoid special checks later on we force at least
+	 * two codes of non zero frequency.
+	 */
+	while (G2.heap_len < 2) {
+		int new = G2.heap[++G2.heap_len] = (max_code < 2 ? ++max_code : 0);
+
+		tree[new].Freq = 1;
+		G2.depth[new] = 0;
+		G2.opt_len--;
+		if (stree)
+			G2.static_len -= stree[new].Len;
+		/* new is 0 or 1 so it does not have extra bits */
+	}
+	desc->max_code = max_code;
+
+	/* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+	 * establish sub-heaps of increasing lengths:
+	 */
+	for (n = G2.heap_len / 2; n >= 1; n--)
+		pqdownheap(tree, n);
+
+	/* Construct the Huffman tree by repeatedly combining the least two
+	 * frequent nodes.
+	 */
+	do {
+		PQREMOVE(tree, n);	/* n = node of least frequency */
+		m = G2.heap[SMALLEST];	/* m = node of next least frequency */
+
+		G2.heap[--G2.heap_max] = n;	/* keep the nodes sorted by frequency */
+		G2.heap[--G2.heap_max] = m;
+
+		/* Create a new node father of n and m */
+		tree[node].Freq = tree[n].Freq + tree[m].Freq;
+		G2.depth[node] = MAX(G2.depth[n], G2.depth[m]) + 1;
+		tree[n].Dad = tree[m].Dad = (ush) node;
+#ifdef DUMP_BL_TREE
+		if (tree == G2.bl_tree) {
+			bb_error_msg("\nnode %d(%d), sons %d(%d) %d(%d)",
+					node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+		}
+#endif
+		/* and insert the new node in the heap */
+		G2.heap[SMALLEST] = node++;
+		pqdownheap(tree, SMALLEST);
+
+	} while (G2.heap_len >= 2);
+
+	G2.heap[--G2.heap_max] = G2.heap[SMALLEST];
+
+	/* At this point, the fields freq and dad are set. We can now
+	 * generate the bit lengths.
+	 */
+	gen_bitlen((tree_desc *) desc);
+
+	/* The field len is now set, we can generate the bit codes */
+	gen_codes((ct_data *) tree, max_code);
+}
+
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree. Updates opt_len to take into account the repeat
+ * counts. (The contribution of the bit length codes will be added later
+ * during the construction of bl_tree.)
+ */
+static void scan_tree(ct_data * tree, int max_code)
+{
+	int n;				/* iterates over all tree elements */
+	int prevlen = -1;	/* last emitted length */
+	int curlen;			/* length of current code */
+	int nextlen = tree[0].Len;	/* length of next code */
+	int count = 0;		/* repeat count of the current code */
+	int max_count = 7;	/* max repeat count */
+	int min_count = 4;	/* min repeat count */
+
+	if (nextlen == 0) {
+		max_count = 138;
+		min_count = 3;
+	}
+	tree[max_code + 1].Len = 0xffff; /* guard */
+
+	for (n = 0; n <= max_code; n++) {
+		curlen = nextlen;
+		nextlen = tree[n + 1].Len;
+		if (++count < max_count && curlen == nextlen)
+			continue;
+
+		if (count < min_count) {
+			G2.bl_tree[curlen].Freq += count;
+		} else if (curlen != 0) {
+			if (curlen != prevlen)
+				G2.bl_tree[curlen].Freq++;
+			G2.bl_tree[REP_3_6].Freq++;
+		} else if (count <= 10) {
+			G2.bl_tree[REPZ_3_10].Freq++;
+		} else {
+			G2.bl_tree[REPZ_11_138].Freq++;
+		}
+		count = 0;
+		prevlen = curlen;
+
+		max_count = 7;
+		min_count = 4;
+		if (nextlen == 0) {
+			max_count = 138;
+			min_count = 3;
+		} else if (curlen == nextlen) {
+			max_count = 6;
+			min_count = 3;
+		}
+	}
+}
+
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+static void send_tree(ct_data * tree, int max_code)
+{
+	int n;				/* iterates over all tree elements */
+	int prevlen = -1;	/* last emitted length */
+	int curlen;			/* length of current code */
+	int nextlen = tree[0].Len;	/* length of next code */
+	int count = 0;		/* repeat count of the current code */
+	int max_count = 7;	/* max repeat count */
+	int min_count = 4;	/* min repeat count */
+
+/* tree[max_code+1].Len = -1; *//* guard already set */
+	if (nextlen == 0)
+		max_count = 138, min_count = 3;
+
+	for (n = 0; n <= max_code; n++) {
+		curlen = nextlen;
+		nextlen = tree[n + 1].Len;
+		if (++count < max_count && curlen == nextlen) {
+			continue;
+		} else if (count < min_count) {
+			do {
+				SEND_CODE(curlen, G2.bl_tree);
+			} while (--count);
+		} else if (curlen != 0) {
+			if (curlen != prevlen) {
+				SEND_CODE(curlen, G2.bl_tree);
+				count--;
+			}
+			Assert(count >= 3 && count <= 6, " 3_6?");
+			SEND_CODE(REP_3_6, G2.bl_tree);
+			send_bits(count - 3, 2);
+		} else if (count <= 10) {
+			SEND_CODE(REPZ_3_10, G2.bl_tree);
+			send_bits(count - 3, 3);
+		} else {
+			SEND_CODE(REPZ_11_138, G2.bl_tree);
+			send_bits(count - 11, 7);
+		}
+		count = 0;
+		prevlen = curlen;
+		if (nextlen == 0) {
+			max_count = 138;
+			min_count = 3;
+		} else if (curlen == nextlen) {
+			max_count = 6;
+			min_count = 3;
+		} else {
+			max_count = 7;
+			min_count = 4;
+		}
+	}
+}
+
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+static int build_bl_tree(void)
+{
+	int max_blindex;	/* index of last bit length code of non zero freq */
+
+	/* Determine the bit length frequencies for literal and distance trees */
+	scan_tree(G2.dyn_ltree, G2.l_desc.max_code);
+	scan_tree(G2.dyn_dtree, G2.d_desc.max_code);
+
+	/* Build the bit length tree: */
+	build_tree(&G2.bl_desc);
+	/* opt_len now includes the length of the tree representations, except
+	 * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+	 */
+
+	/* Determine the number of bit length codes to send. The pkzip format
+	 * requires that at least 4 bit length codes be sent. (appnote.txt says
+	 * 3 but the actual value used is 4.)
+	 */
+	for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
+		if (G2.bl_tree[bl_order[max_blindex]].Len != 0)
+			break;
+	}
+	/* Update opt_len to include the bit length tree and counts */
+	G2.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
+	Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", G2.opt_len, G2.static_len));
+
+	return max_blindex;
+}
+
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+static void send_all_trees(int lcodes, int dcodes, int blcodes)
+{
+	int rank;			/* index in bl_order */
+
+	Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+	Assert(lcodes <= L_CODES && dcodes <= D_CODES
+		   && blcodes <= BL_CODES, "too many codes");
+	Tracev((stderr, "\nbl counts: "));
+	send_bits(lcodes - 257, 5);	/* not +255 as stated in appnote.txt */
+	send_bits(dcodes - 1, 5);
+	send_bits(blcodes - 4, 4);	/* not -3 as stated in appnote.txt */
+	for (rank = 0; rank < blcodes; rank++) {
+		Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+		send_bits(G2.bl_tree[bl_order[rank]].Len, 3);
+	}
+	Tracev((stderr, "\nbl tree: sent %ld", G1.bits_sent));
+
+	send_tree((ct_data *) G2.dyn_ltree, lcodes - 1);	/* send the literal tree */
+	Tracev((stderr, "\nlit tree: sent %ld", G1.bits_sent));
+
+	send_tree((ct_data *) G2.dyn_dtree, dcodes - 1);	/* send the distance tree */
+	Tracev((stderr, "\ndist tree: sent %ld", G1.bits_sent));
+}
+
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+static int ct_tally(int dist, int lc)
+{
+	G1.l_buf[G2.last_lit++] = lc;
+	if (dist == 0) {
+		/* lc is the unmatched char */
+		G2.dyn_ltree[lc].Freq++;
+	} else {
+		/* Here, lc is the match length - MIN_MATCH */
+		dist--;			/* dist = match distance - 1 */
+		Assert((ush) dist < (ush) MAX_DIST
+		 && (ush) lc <= (ush) (MAX_MATCH - MIN_MATCH)
+		 && (ush) D_CODE(dist) < (ush) D_CODES, "ct_tally: bad match"
+		);
+
+		G2.dyn_ltree[G2.length_code[lc] + LITERALS + 1].Freq++;
+		G2.dyn_dtree[D_CODE(dist)].Freq++;
+
+		G1.d_buf[G2.last_dist++] = dist;
+		G2.flags |= G2.flag_bit;
+	}
+	G2.flag_bit <<= 1;
+
+	/* Output the flags if they fill a byte: */
+	if ((G2.last_lit & 7) == 0) {
+		G2.flag_buf[G2.last_flags++] = G2.flags;
+		G2.flags = 0;
+		G2.flag_bit = 1;
+	}
+	/* Try to guess if it is profitable to stop the current block here */
+	if ((G2.last_lit & 0xfff) == 0) {
+		/* Compute an upper bound for the compressed length */
+		ulg out_length = G2.last_lit * 8L;
+		ulg in_length = (ulg) G1.strstart - G1.block_start;
+		int dcode;
+
+		for (dcode = 0; dcode < D_CODES; dcode++) {
+			out_length += G2.dyn_dtree[dcode].Freq * (5L + extra_dbits[dcode]);
+		}
+		out_length >>= 3;
+		Trace((stderr,
+			   "\nlast_lit %u, last_dist %u, in %ld, out ~%ld(%ld%%) ",
+			   G2.last_lit, G2.last_dist, in_length, out_length,
+			   100L - out_length * 100L / in_length));
+		if (G2.last_dist < G2.last_lit / 2 && out_length < in_length / 2)
+			return 1;
+	}
+	return (G2.last_lit == LIT_BUFSIZE - 1 || G2.last_dist == DIST_BUFSIZE);
+	/* We avoid equality with LIT_BUFSIZE because of wraparound at 64K
+	 * on 16 bit machines and because stored blocks are restricted to
+	 * 64K-1 bytes.
+	 */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+static void compress_block(ct_data * ltree, ct_data * dtree)
+{
+	unsigned dist;          /* distance of matched string */
+	int lc;                 /* match length or unmatched char (if dist == 0) */
+	unsigned lx = 0;        /* running index in l_buf */
+	unsigned dx = 0;        /* running index in d_buf */
+	unsigned fx = 0;        /* running index in flag_buf */
+	uch flag = 0;           /* current flags */
+	unsigned code;          /* the code to send */
+	int extra;              /* number of extra bits to send */
+
+	if (G2.last_lit != 0) do {
+		if ((lx & 7) == 0)
+			flag = G2.flag_buf[fx++];
+		lc = G1.l_buf[lx++];
+		if ((flag & 1) == 0) {
+			SEND_CODE(lc, ltree);	/* send a literal byte */
+			Tracecv(lc > ' ', (stderr, " '%c' ", lc));
+		} else {
+			/* Here, lc is the match length - MIN_MATCH */
+			code = G2.length_code[lc];
+			SEND_CODE(code + LITERALS + 1, ltree);	/* send the length code */
+			extra = extra_lbits[code];
+			if (extra != 0) {
+				lc -= G2.base_length[code];
+				send_bits(lc, extra);	/* send the extra length bits */
+			}
+			dist = G1.d_buf[dx++];
+			/* Here, dist is the match distance - 1 */
+			code = D_CODE(dist);
+			Assert(code < D_CODES, "bad d_code");
+
+			SEND_CODE(code, dtree);	/* send the distance code */
+			extra = extra_dbits[code];
+			if (extra != 0) {
+				dist -= G2.base_dist[code];
+				send_bits(dist, extra);	/* send the extra distance bits */
+			}
+		}			/* literal or match pair ? */
+		flag >>= 1;
+	} while (lx < G2.last_lit);
+
+	SEND_CODE(END_BLOCK, ltree);
+}
+
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file. This function
+ * returns the total compressed length for the file so far.
+ */
+static ulg flush_block(char *buf, ulg stored_len, int eof)
+{
+	ulg opt_lenb, static_lenb;      /* opt_len and static_len in bytes */
+	int max_blindex;                /* index of last bit length code of non zero freq */
+
+	G2.flag_buf[G2.last_flags] = G2.flags;   /* Save the flags for the last 8 items */
+
+	/* Construct the literal and distance trees */
+	build_tree(&G2.l_desc);
+	Tracev((stderr, "\nlit data: dyn %ld, stat %ld", G2.opt_len, G2.static_len));
+
+	build_tree(&G2.d_desc);
+	Tracev((stderr, "\ndist data: dyn %ld, stat %ld", G2.opt_len, G2.static_len));
+	/* At this point, opt_len and static_len are the total bit lengths of
+	 * the compressed block data, excluding the tree representations.
+	 */
+
+	/* Build the bit length tree for the above two trees, and get the index
+	 * in bl_order of the last bit length code to send.
+	 */
+	max_blindex = build_bl_tree();
+
+	/* Determine the best encoding. Compute first the block length in bytes */
+	opt_lenb = (G2.opt_len + 3 + 7) >> 3;
+	static_lenb = (G2.static_len + 3 + 7) >> 3;
+
+	Trace((stderr,
+		   "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u dist %u ",
+		   opt_lenb, G2.opt_len, static_lenb, G2.static_len, stored_len,
+		   G2.last_lit, G2.last_dist));
+
+	if (static_lenb <= opt_lenb)
+		opt_lenb = static_lenb;
+
+	/* If compression failed and this is the first and last block,
+	 * and if the zip file can be seeked (to rewrite the local header),
+	 * the whole file is transformed into a stored file:
+	 */
+	if (stored_len <= opt_lenb && eof && G2.compressed_len == 0L && seekable()) {
+		/* Since LIT_BUFSIZE <= 2*WSIZE, the input data must be there: */
+		if (buf == NULL)
+			bb_error_msg("block vanished");
+
+		copy_block(buf, (unsigned) stored_len, 0);	/* without header */
+		G2.compressed_len = stored_len << 3;
+
+	} else if (stored_len + 4 <= opt_lenb && buf != NULL) {
+		/* 4: two words for the lengths */
+		/* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+		 * Otherwise we can't have processed more than WSIZE input bytes since
+		 * the last block flush, because compression would have been
+		 * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+		 * transform a block into a stored block.
+		 */
+		send_bits((STORED_BLOCK << 1) + eof, 3);	/* send block type */
+		G2.compressed_len = (G2.compressed_len + 3 + 7) & ~7L;
+		G2.compressed_len += (stored_len + 4) << 3;
+
+		copy_block(buf, (unsigned) stored_len, 1);	/* with header */
+
+	} else if (static_lenb == opt_lenb) {
+		send_bits((STATIC_TREES << 1) + eof, 3);
+		compress_block((ct_data *) G2.static_ltree, (ct_data *) G2.static_dtree);
+		G2.compressed_len += 3 + G2.static_len;
+	} else {
+		send_bits((DYN_TREES << 1) + eof, 3);
+		send_all_trees(G2.l_desc.max_code + 1, G2.d_desc.max_code + 1,
+					   max_blindex + 1);
+		compress_block((ct_data *) G2.dyn_ltree, (ct_data *) G2.dyn_dtree);
+		G2.compressed_len += 3 + G2.opt_len;
+	}
+	Assert(G2.compressed_len == G1.bits_sent, "bad compressed size");
+	init_block();
+
+	if (eof) {
+		bi_windup();
+		G2.compressed_len += 7;	/* align on byte boundary */
+	}
+	Tracev((stderr, "\ncomprlen %lu(%lu) ", G2.compressed_len >> 3,
+			G2.compressed_len - 7 * eof));
+
+	return G2.compressed_len >> 3;
+}
+
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(h, c) (h = (((h)<<H_SHIFT) ^ (c)) & HASH_MASK)
+
+
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ *
+ * Processes a new input file and return its compressed length. Sets
+ * the compressed length, crc, deflate flags and internal file
+ * attributes.
+ */
+
+/* Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match. */
+#define FLUSH_BLOCK(eof) \
+	flush_block( \
+		G1.block_start >= 0L \
+			? (char*)&G1.window[(unsigned)G1.block_start] \
+			: (char*)NULL, \
+		(ulg)G1.strstart - G1.block_start, \
+		(eof) \
+	)
+
+/* Insert string s in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * IN  assertion: all calls to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of s are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file). */
+#define INSERT_STRING(s, match_head) \
+do { \
+	UPDATE_HASH(G1.ins_h, G1.window[(s) + MIN_MATCH-1]); \
+	G1.prev[(s) & WMASK] = match_head = head[G1.ins_h]; \
+	head[G1.ins_h] = (s); \
+} while (0)
+
+static ulg deflate(void)
+{
+	IPos hash_head;		/* head of hash chain */
+	IPos prev_match;	/* previous match */
+	int flush;			/* set if current block must be flushed */
+	int match_available = 0;	/* set if previous match exists */
+	unsigned match_length = MIN_MATCH - 1;	/* length of best match */
+
+	/* Process the input block. */
+	while (G1.lookahead != 0) {
+		/* Insert the string window[strstart .. strstart+2] in the
+		 * dictionary, and set hash_head to the head of the hash chain:
+		 */
+		INSERT_STRING(G1.strstart, hash_head);
+
+		/* Find the longest match, discarding those <= prev_length.
+		 */
+		G1.prev_length = match_length;
+		prev_match = G1.match_start;
+		match_length = MIN_MATCH - 1;
+
+		if (hash_head != 0 && G1.prev_length < max_lazy_match
+		 && G1.strstart - hash_head <= MAX_DIST
+		) {
+			/* To simplify the code, we prevent matches with the string
+			 * of window index 0 (in particular we have to avoid a match
+			 * of the string with itself at the start of the input file).
+			 */
+			match_length = longest_match(hash_head);
+			/* longest_match() sets match_start */
+			if (match_length > G1.lookahead)
+				match_length = G1.lookahead;
+
+			/* Ignore a length 3 match if it is too distant: */
+			if (match_length == MIN_MATCH && G1.strstart - G1.match_start > TOO_FAR) {
+				/* If prev_match is also MIN_MATCH, G1.match_start is garbage
+				 * but we will ignore the current match anyway.
+				 */
+				match_length--;
+			}
+		}
+		/* If there was a match at the previous step and the current
+		 * match is not better, output the previous match:
+		 */
+		if (G1.prev_length >= MIN_MATCH && match_length <= G1.prev_length) {
+			check_match(G1.strstart - 1, prev_match, G1.prev_length);
+			flush = ct_tally(G1.strstart - 1 - prev_match, G1.prev_length - MIN_MATCH);
+
+			/* Insert in hash table all strings up to the end of the match.
+			 * strstart-1 and strstart are already inserted.
+			 */
+			G1.lookahead -= G1.prev_length - 1;
+			G1.prev_length -= 2;
+			do {
+				G1.strstart++;
+				INSERT_STRING(G1.strstart, hash_head);
+				/* strstart never exceeds WSIZE-MAX_MATCH, so there are
+				 * always MIN_MATCH bytes ahead. If lookahead < MIN_MATCH
+				 * these bytes are garbage, but it does not matter since the
+				 * next lookahead bytes will always be emitted as literals.
+				 */
+			} while (--G1.prev_length != 0);
+			match_available = 0;
+			match_length = MIN_MATCH - 1;
+			G1.strstart++;
+			if (flush) {
+				FLUSH_BLOCK(0);
+				G1.block_start = G1.strstart;
+			}
+		} else if (match_available) {
+			/* If there was no match at the previous position, output a
+			 * single literal. If there was a match but the current match
+			 * is longer, truncate the previous match to a single literal.
+			 */
+			Tracevv((stderr, "%c", G1.window[G1.strstart - 1]));
+			if (ct_tally(0, G1.window[G1.strstart - 1])) {
+				FLUSH_BLOCK(0);
+				G1.block_start = G1.strstart;
+			}
+			G1.strstart++;
+			G1.lookahead--;
+		} else {
+			/* There is no previous match to compare with, wait for
+			 * the next step to decide.
+			 */
+			match_available = 1;
+			G1.strstart++;
+			G1.lookahead--;
+		}
+		Assert(G1.strstart <= G1.isize && lookahead <= G1.isize, "a bit too far");
+
+		/* Make sure that we always have enough lookahead, except
+		 * at the end of the input file. We need MAX_MATCH bytes
+		 * for the next match, plus MIN_MATCH bytes to insert the
+		 * string following the next match.
+		 */
+		while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile)
+			fill_window();
+	}
+	if (match_available)
+		ct_tally(0, G1.window[G1.strstart - 1]);
+
+	return FLUSH_BLOCK(1);	/* eof */
+}
+
+
+/* ===========================================================================
+ * Initialize the bit string routines.
+ */
+static void bi_init(void)
+{
+	G1.bi_buf = 0;
+	G1.bi_valid = 0;
+#ifdef DEBUG
+	G1.bits_sent = 0L;
+#endif
+}
+
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new file
+ */
+static void lm_init(ush * flagsp)
+{
+	unsigned j;
+
+	/* Initialize the hash table. */
+	memset(head, 0, HASH_SIZE * sizeof(*head));
+	/* prev will be initialized on the fly */
+
+	/* speed options for the general purpose bit flag */
+	*flagsp |= 2;	/* FAST 4, SLOW 2 */
+	/* ??? reduce max_chain_length for binary files */
+
+	G1.strstart = 0;
+	G1.block_start = 0L;
+
+	G1.lookahead = file_read(G1.window,
+			sizeof(int) <= 2 ? (unsigned) WSIZE : 2 * WSIZE);
+
+	if (G1.lookahead == 0 || G1.lookahead == (unsigned) -1) {
+		G1.eofile = 1;
+		G1.lookahead = 0;
+		return;
+	}
+	G1.eofile = 0;
+	/* Make sure that we always have enough lookahead. This is important
+	 * if input comes from a device such as a tty.
+	 */
+	while (G1.lookahead < MIN_LOOKAHEAD && !G1.eofile)
+		fill_window();
+
+	G1.ins_h = 0;
+	for (j = 0; j < MIN_MATCH - 1; j++)
+		UPDATE_HASH(G1.ins_h, G1.window[j]);
+	/* If lookahead < MIN_MATCH, ins_h is garbage, but this is
+	 * not important since only literal bytes will be emitted.
+	 */
+}
+
+
+/* ===========================================================================
+ * Allocate the match buffer, initialize the various tables and save the
+ * location of the internal file attribute (ascii/binary) and method
+ * (DEFLATE/STORE).
+ * One callsite in zip()
+ */
+static void ct_init(void)
+{
+	int n;				/* iterates over tree elements */
+	int length;			/* length value */
+	int code;			/* code value */
+	int dist;			/* distance index */
+
+	G2.compressed_len = 0L;
+
+#ifdef NOT_NEEDED
+	if (G2.static_dtree[0].Len != 0)
+		return;			/* ct_init already called */
+#endif
+
+	/* Initialize the mapping length (0..255) -> length code (0..28) */
+	length = 0;
+	for (code = 0; code < LENGTH_CODES - 1; code++) {
+		G2.base_length[code] = length;
+		for (n = 0; n < (1 << extra_lbits[code]); n++) {
+			G2.length_code[length++] = code;
+		}
+	}
+	Assert(length == 256, "ct_init: length != 256");
+	/* Note that the length 255 (match length 258) can be represented
+	 * in two different ways: code 284 + 5 bits or code 285, so we
+	 * overwrite length_code[255] to use the best encoding:
+	 */
+	G2.length_code[length - 1] = code;
+
+	/* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+	dist = 0;
+	for (code = 0; code < 16; code++) {
+		G2.base_dist[code] = dist;
+		for (n = 0; n < (1 << extra_dbits[code]); n++) {
+			G2.dist_code[dist++] = code;
+		}
+	}
+	Assert(dist == 256, "ct_init: dist != 256");
+	dist >>= 7;			/* from now on, all distances are divided by 128 */
+	for (; code < D_CODES; code++) {
+		G2.base_dist[code] = dist << 7;
+		for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) {
+			G2.dist_code[256 + dist++] = code;
+		}
+	}
+	Assert(dist == 256, "ct_init: 256+dist != 512");
+
+	/* Construct the codes of the static literal tree */
+	/* already zeroed - it's in bss
+	for (n = 0; n <= MAX_BITS; n++)
+		G2.bl_count[n] = 0; */
+
+	n = 0;
+	while (n <= 143) {
+		G2.static_ltree[n++].Len = 8;
+		G2.bl_count[8]++;
+	}
+	while (n <= 255) {
+		G2.static_ltree[n++].Len = 9;
+		G2.bl_count[9]++;
+	}
+	while (n <= 279) {
+		G2.static_ltree[n++].Len = 7;
+		G2.bl_count[7]++;
+	}
+	while (n <= 287) {
+		G2.static_ltree[n++].Len = 8;
+		G2.bl_count[8]++;
+	}
+	/* Codes 286 and 287 do not exist, but we must include them in the
+	 * tree construction to get a canonical Huffman tree (longest code
+	 * all ones)
+	 */
+	gen_codes((ct_data *) G2.static_ltree, L_CODES + 1);
+
+	/* The static distance tree is trivial: */
+	for (n = 0; n < D_CODES; n++) {
+		G2.static_dtree[n].Len = 5;
+		G2.static_dtree[n].Code = bi_reverse(n, 5);
+	}
+
+	/* Initialize the first block of the first file: */
+	init_block();
+}
+
+
+/* ===========================================================================
+ * Deflate in to out.
+ * IN assertions: the input and output buffers are cleared.
+ */
+
+static void zip(ulg time_stamp)
+{
+	ush deflate_flags = 0;  /* pkzip -es, -en or -ex equivalent */
+
+	G1.outcnt = 0;
+
+	/* Write the header to the gzip file. See algorithm.doc for the format */
+	/* magic header for gzip files: 1F 8B */
+	/* compression method: 8 (DEFLATED) */
+	/* general flags: 0 */
+	put_32bit(0x00088b1f);
+	put_32bit(time_stamp);
+
+	/* Write deflated file to zip file */
+	G1.crc = ~0;
+
+	bi_init();
+	ct_init();
+	lm_init(&deflate_flags);
+
+	put_8bit(deflate_flags);	/* extra flags */
+	put_8bit(3);	/* OS identifier = 3 (Unix) */
+
+	deflate();
+
+	/* Write the crc and uncompressed size */
+	put_32bit(~G1.crc);
+	put_32bit(G1.isize);
+
+	flush_outbuf();
+}
+
+
+/* ======================================================================== */
+static
+IF_DESKTOP(long long) int FAST_FUNC pack_gzip(unpack_info_t *info UNUSED_PARAM)
+{
+	struct stat s;
+
+	/* Clear input and output buffers */
+	G1.outcnt = 0;
+#ifdef DEBUG
+	G1.insize = 0;
+#endif
+	G1.isize = 0;
+
+	/* Reinit G2.xxx */
+	memset(&G2, 0, sizeof(G2));
+	G2.l_desc.dyn_tree     = G2.dyn_ltree;
+	G2.l_desc.static_tree  = G2.static_ltree;
+	G2.l_desc.extra_bits   = extra_lbits;
+	G2.l_desc.extra_base   = LITERALS + 1;
+	G2.l_desc.elems        = L_CODES;
+	G2.l_desc.max_length   = MAX_BITS;
+	//G2.l_desc.max_code     = 0;
+	G2.d_desc.dyn_tree     = G2.dyn_dtree;
+	G2.d_desc.static_tree  = G2.static_dtree;
+	G2.d_desc.extra_bits   = extra_dbits;
+	//G2.d_desc.extra_base   = 0;
+	G2.d_desc.elems        = D_CODES;
+	G2.d_desc.max_length   = MAX_BITS;
+	//G2.d_desc.max_code     = 0;
+	G2.bl_desc.dyn_tree    = G2.bl_tree;
+	//G2.bl_desc.static_tree = NULL;
+	G2.bl_desc.extra_bits  = extra_blbits,
+	//G2.bl_desc.extra_base  = 0;
+	G2.bl_desc.elems       = BL_CODES;
+	G2.bl_desc.max_length  = MAX_BL_BITS;
+	//G2.bl_desc.max_code    = 0;
+
+	s.st_ctime = 0;
+	fstat(STDIN_FILENO, &s);
+	zip(s.st_ctime);
+	return 0;
+}
+
+#if ENABLE_FEATURE_GZIP_LONG_OPTIONS
+static const char gzip_longopts[] ALIGN1 =
+	"stdout\0"              No_argument       "c"
+	"to-stdout\0"           No_argument       "c"
+	"force\0"               No_argument       "f"
+	"verbose\0"             No_argument       "v"
+#if ENABLE_GUNZIP
+	"decompress\0"          No_argument       "d"
+	"uncompress\0"          No_argument       "d"
+	"test\0"                No_argument       "t"
+#endif
+	"quiet\0"               No_argument       "q"
+	"fast\0"                No_argument       "1"
+	"best\0"                No_argument       "9"
+	;
+#endif
+
+/*
+ * Linux kernel build uses gzip -d -n. We accept and ignore -n.
+ * Man page says:
+ * -n --no-name
+ * gzip: do not save the original file name and time stamp.
+ * (The original name is always saved if the name had to be truncated.)
+ * gunzip: do not restore the original file name/time even if present
+ * (remove only the gzip suffix from the compressed file name).
+ * This option is the default when decompressing.
+ * -N --name
+ * gzip: always save the original file name and time stamp (this is the default)
+ * gunzip: restore the original file name and time stamp if present.
+ */
+
+int gzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+#if ENABLE_GUNZIP
+int gzip_main(int argc, char **argv)
+#else
+int gzip_main(int argc UNUSED_PARAM, char **argv)
+#endif
+{
+	unsigned opt;
+
+#if ENABLE_FEATURE_GZIP_LONG_OPTIONS
+	applet_long_options = gzip_longopts;
+#endif
+	/* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */
+	opt = getopt32(argv, "cfv" IF_GUNZIP("dt") "q123456789n");
+#if ENABLE_GUNZIP /* gunzip_main may not be visible... */
+	if (opt & 0x18) // -d and/or -t
+		return gunzip_main(argc, argv);
+#endif
+	option_mask32 &= 0x7; /* ignore -q, -0..9 */
+	//if (opt & 0x1) // -c
+	//if (opt & 0x2) // -f
+	//if (opt & 0x4) // -v
+	argv += optind;
+
+	SET_PTR_TO_GLOBALS((char *)xzalloc(sizeof(struct globals)+sizeof(struct globals2))
+			+ sizeof(struct globals));
+
+	/* Allocate all global buffers (for DYN_ALLOC option) */
+	ALLOC(uch, G1.l_buf, INBUFSIZ);
+	ALLOC(uch, G1.outbuf, OUTBUFSIZ);
+	ALLOC(ush, G1.d_buf, DIST_BUFSIZE);
+	ALLOC(uch, G1.window, 2L * WSIZE);
+	ALLOC(ush, G1.prev, 1L << BITS);
+
+	/* Initialize the CRC32 table */
+	global_crc32_table = crc32_filltable(NULL, 0);
+
+	return bbunpack(argv, pack_gzip, append_ext, "gz");
+}
diff --git a/busybox-1.19.3/archival/libarchive/Kbuild.src b/busybox-1.19.3/archival/libarchive/Kbuild.src
new file mode 100644
index 0000000..b0bc4e5
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/Kbuild.src
@@ -0,0 +1,64 @@
+# Makefile for busybox
+#
+# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
+#
+# Licensed under GPLv2 or later, see file LICENSE in this source tree.
+
+lib-y:=
+
+COMMON_FILES:= \
+\
+	data_skip.o \
+	data_extract_all.o \
+	data_extract_to_stdout.o \
+\
+	filter_accept_all.o \
+	filter_accept_list.o \
+	filter_accept_reject_list.o \
+\
+	header_skip.o \
+	header_list.o \
+	header_verbose_list.o \
+\
+	seek_by_read.o \
+	seek_by_jump.o \
+\
+	data_align.o \
+	find_list_entry.o \
+	init_handle.o
+
+DPKG_FILES:= \
+	get_header_ar.o \
+	unpack_ar_archive.o \
+	get_header_tar.o \
+	filter_accept_list_reassign.o
+
+INSERT
+
+lib-$(CONFIG_AR)                        += get_header_ar.o unpack_ar_archive.o
+lib-$(CONFIG_BUNZIP2)                   += decompress_bunzip2.o
+lib-$(CONFIG_UNLZMA)                    += decompress_unlzma.o
+lib-$(CONFIG_UNXZ)                      += decompress_unxz.o
+lib-$(CONFIG_CPIO)                      += get_header_cpio.o
+lib-$(CONFIG_DPKG)                      += $(DPKG_FILES)
+lib-$(CONFIG_DPKG_DEB)                  += $(DPKG_FILES)
+lib-$(CONFIG_GUNZIP)                    += decompress_unzip.o
+lib-$(CONFIG_RPM2CPIO)                  += decompress_unzip.o get_header_cpio.o
+lib-$(CONFIG_RPM)                       += open_transformer.o decompress_unzip.o get_header_cpio.o
+lib-$(CONFIG_TAR)                       += get_header_tar.o
+lib-$(CONFIG_UNCOMPRESS)                += decompress_uncompress.o
+lib-$(CONFIG_UNZIP)                     += decompress_unzip.o
+lib-$(CONFIG_LZOP)                      += lzo1x_1.o lzo1x_1o.o lzo1x_d.o
+lib-$(CONFIG_LZOP_COMPR_HIGH)           += lzo1x_9x.o
+lib-$(CONFIG_FEATURE_SEAMLESS_Z)        += open_transformer.o decompress_uncompress.o
+lib-$(CONFIG_FEATURE_SEAMLESS_GZ)       += open_transformer.o decompress_unzip.o get_header_tar_gz.o
+lib-$(CONFIG_FEATURE_SEAMLESS_BZ2)      += open_transformer.o decompress_bunzip2.o get_header_tar_bz2.o
+lib-$(CONFIG_FEATURE_SEAMLESS_LZMA)     += open_transformer.o decompress_unlzma.o get_header_tar_lzma.o
+lib-$(CONFIG_FEATURE_SEAMLESS_XZ)       += open_transformer.o decompress_unxz.o
+lib-$(CONFIG_FEATURE_COMPRESS_USAGE)    += decompress_bunzip2.o
+lib-$(CONFIG_FEATURE_COMPRESS_BBCONFIG) += decompress_bunzip2.o
+lib-$(CONFIG_FEATURE_TAR_TO_COMMAND)    += data_extract_to_command.o
+
+ifneq ($(lib-y),)
+lib-y += $(COMMON_FILES)
+endif
diff --git a/busybox-1.19.3/archival/libarchive/bz/LICENSE b/busybox-1.19.3/archival/libarchive/bz/LICENSE
new file mode 100644
index 0000000..da43465
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/bz/LICENSE
@@ -0,0 +1,44 @@
+bzip2 applet in busybox is based on lightly-modified source
+of bzip2 version 1.0.4. bzip2 source is distributed
+under the following conditions (copied verbatim from LICENSE file)
+===========================================================
+
+
+This program, "bzip2", the associated library "libbzip2", and all
+documentation, are copyright (C) 1996-2006 Julian R Seward.  All
+rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. The origin of this software must not be misrepresented; you must
+   not claim that you wrote the original software.  If you use this
+   software in a product, an acknowledgment in the product
+   documentation would be appreciated but is not required.
+
+3. Altered source versions must be plainly marked as such, and must
+   not be misrepresented as being the original software.
+
+4. The name of the author may not be used to endorse or promote
+   products derived from this software without specific prior written
+   permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+
+Julian Seward, Cambridge, UK.
+jseward@bzip.org
+bzip2/libbzip2 version 1.0.4 of 20 December 2006
diff --git a/busybox-1.19.3/archival/libarchive/bz/README b/busybox-1.19.3/archival/libarchive/bz/README
new file mode 100644
index 0000000..fffd47b
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/bz/README
@@ -0,0 +1,90 @@
+This file is an abridged version of README from bzip2 1.0.4
+Build instructions (which are not relevant to busyboxed bzip2)
+are removed.
+===========================================================
+
+
+This is the README for bzip2/libzip2.
+This version is fully compatible with the previous public releases.
+
+------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.4 of 20 December 2006
+Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in this file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------
+
+Please read and be aware of the following:
+
+
+WARNING:
+
+   This program and library (attempts to) compress data by
+   performing several non-trivial transformations on it.
+   Unless you are 100% familiar with *all* the algorithms
+   contained herein, and with the consequences of modifying them,
+   you should NOT meddle with the compression or decompression
+   machinery.  Incorrect changes can and very likely *will*
+   lead to disastrous loss of data.
+
+
+DISCLAIMER:
+
+   I TAKE NO RESPONSIBILITY FOR ANY LOSS OF DATA ARISING FROM THE
+   USE OF THIS PROGRAM/LIBRARY, HOWSOEVER CAUSED.
+
+   Every compression of a file implies an assumption that the
+   compressed file can be decompressed to reproduce the original.
+   Great efforts in design, coding and testing have been made to
+   ensure that this program works correctly.  However, the complexity
+   of the algorithms, and, in particular, the presence of various
+   special cases in the code which occur with very low but non-zero
+   probability make it impossible to rule out the possibility of bugs
+   remaining in the program.  DO NOT COMPRESS ANY DATA WITH THIS
+   PROGRAM UNLESS YOU ARE PREPARED TO ACCEPT THE POSSIBILITY, HOWEVER
+   SMALL, THAT THE DATA WILL NOT BE RECOVERABLE.
+
+   That is not to say this program is inherently unreliable.
+   Indeed, I very much hope the opposite is true.  bzip2/libbzip2
+   has been carefully constructed and extensively tested.
+
+
+PATENTS:
+
+   To the best of my knowledge, bzip2/libbzip2 does not use any
+   patented algorithms.  However, I do not have the resources
+   to carry out a patent search.  Therefore I cannot give any
+   guarantee of the above statement.
+
+
+I hope you find bzip2 useful.  Feel free to contact me at
+   jseward@bzip.org
+if you have any suggestions or queries.  Many people mailed me with
+comments, suggestions and patches after the releases of bzip-0.15,
+bzip-0.21, and bzip2 versions 0.1pl2, 0.9.0, 0.9.5, 1.0.0, 1.0.1,
+1.0.2 and 1.0.3, and the changes in bzip2 are largely a result of this
+feedback.  I thank you for your comments.
+
+bzip2's "home" is http://www.bzip.org/
+
+Julian Seward
+jseward@bzip.org
+Cambridge, UK.
+
+18     July 1996 (version 0.15)
+25   August 1996 (version 0.21)
+ 7   August 1997 (bzip2, version 0.1)
+29   August 1997 (bzip2, version 0.1pl2)
+23   August 1998 (bzip2, version 0.9.0)
+ 8     June 1999 (bzip2, version 0.9.5)
+ 4     Sept 1999 (bzip2, version 0.9.5d)
+ 5      May 2000 (bzip2, version 1.0pre8)
+30 December 2001 (bzip2, version 1.0.2pre1)
+15 February 2005 (bzip2, version 1.0.3)
+20 December 2006 (bzip2, version 1.0.4)
diff --git a/busybox-1.19.3/archival/libarchive/bz/blocksort.c b/busybox-1.19.3/archival/libarchive/bz/blocksort.c
new file mode 100644
index 0000000..f70c370
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/bz/blocksort.c
@@ -0,0 +1,1072 @@
+/*
+ * bzip2 is written by Julian Seward <jseward@bzip.org>.
+ * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>.
+ * See README and LICENSE files in this directory for more information.
+ */
+
+/*-------------------------------------------------------------*/
+/*--- Block sorting machinery                               ---*/
+/*---                                           blocksort.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.4 of 20 December 2006
+Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in the
+README file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------ */
+
+/* #include "bzlib_private.h" */
+
+#define mswap(zz1, zz2) \
+{ \
+	int32_t zztmp = zz1; \
+	zz1 = zz2; \
+	zz2 = zztmp; \
+}
+
+static
+/* No measurable speed gain with inlining */
+/* ALWAYS_INLINE */
+void mvswap(uint32_t* ptr, int32_t zzp1, int32_t zzp2, int32_t zzn)
+{
+	while (zzn > 0) {
+		mswap(ptr[zzp1], ptr[zzp2]);
+		zzp1++;
+		zzp2++;
+		zzn--;
+	}
+}
+
+static
+ALWAYS_INLINE
+int32_t mmin(int32_t a, int32_t b)
+{
+	return (a < b) ? a : b;
+}
+
+
+/*---------------------------------------------*/
+/*--- Fallback O(N log(N)^2) sorting        ---*/
+/*--- algorithm, for repetitive blocks      ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+inline
+void fallbackSimpleSort(uint32_t* fmap,
+		uint32_t* eclass,
+		int32_t   lo,
+		int32_t   hi)
+{
+	int32_t i, j, tmp;
+	uint32_t ec_tmp;
+
+	if (lo == hi) return;
+
+	if (hi - lo > 3) {
+		for (i = hi-4; i >= lo; i--) {
+			tmp = fmap[i];
+			ec_tmp = eclass[tmp];
+			for (j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4)
+				fmap[j-4] = fmap[j];
+			fmap[j-4] = tmp;
+		}
+	}
+
+	for (i = hi-1; i >= lo; i--) {
+		tmp = fmap[i];
+		ec_tmp = eclass[tmp];
+		for (j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++)
+			fmap[j-1] = fmap[j];
+		fmap[j-1] = tmp;
+	}
+}
+
+
+/*---------------------------------------------*/
+#define fpush(lz,hz) { \
+	stackLo[sp] = lz; \
+	stackHi[sp] = hz; \
+	sp++; \
+}
+
+#define fpop(lz,hz) { \
+	sp--; \
+	lz = stackLo[sp]; \
+	hz = stackHi[sp]; \
+}
+
+#define FALLBACK_QSORT_SMALL_THRESH 10
+#define FALLBACK_QSORT_STACK_SIZE   100
+
+static
+void fallbackQSort3(uint32_t* fmap,
+		uint32_t* eclass,
+		int32_t   loSt,
+		int32_t   hiSt)
+{
+	int32_t unLo, unHi, ltLo, gtHi, n, m;
+	int32_t sp, lo, hi;
+	uint32_t med, r, r3;
+	int32_t stackLo[FALLBACK_QSORT_STACK_SIZE];
+	int32_t stackHi[FALLBACK_QSORT_STACK_SIZE];
+
+	r = 0;
+
+	sp = 0;
+	fpush(loSt, hiSt);
+
+	while (sp > 0) {
+		AssertH(sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004);
+
+		fpop(lo, hi);
+		if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) {
+			fallbackSimpleSort(fmap, eclass, lo, hi);
+			continue;
+		}
+
+		/* Random partitioning.  Median of 3 sometimes fails to
+		 * avoid bad cases.  Median of 9 seems to help but
+		 * looks rather expensive.  This too seems to work but
+		 * is cheaper.  Guidance for the magic constants
+		 * 7621 and 32768 is taken from Sedgewick's algorithms
+		 * book, chapter 35.
+		 */
+		r = ((r * 7621) + 1) % 32768;
+		r3 = r % 3;
+		if (r3 == 0)
+			med = eclass[fmap[lo]];
+		else if (r3 == 1)
+			med = eclass[fmap[(lo+hi)>>1]];
+		else
+			med = eclass[fmap[hi]];
+
+		unLo = ltLo = lo;
+		unHi = gtHi = hi;
+
+		while (1) {
+			while (1) {
+				if (unLo > unHi) break;
+				n = (int32_t)eclass[fmap[unLo]] - (int32_t)med;
+				if (n == 0) {
+					mswap(fmap[unLo], fmap[ltLo]);
+					ltLo++;
+					unLo++;
+					continue;
+				};
+				if (n > 0) break;
+				unLo++;
+			}
+			while (1) {
+				if (unLo > unHi) break;
+				n = (int32_t)eclass[fmap[unHi]] - (int32_t)med;
+				if (n == 0) {
+					mswap(fmap[unHi], fmap[gtHi]);
+					gtHi--; unHi--;
+					continue;
+				};
+				if (n < 0) break;
+				unHi--;
+			}
+			if (unLo > unHi) break;
+			mswap(fmap[unLo], fmap[unHi]); unLo++; unHi--;
+		}
+
+		AssertD(unHi == unLo-1, "fallbackQSort3(2)");
+
+		if (gtHi < ltLo) continue;
+
+		n = mmin(ltLo-lo, unLo-ltLo); mvswap(fmap, lo, unLo-n, n);
+		m = mmin(hi-gtHi, gtHi-unHi); mvswap(fmap, unLo, hi-m+1, m);
+
+		n = lo + unLo - ltLo - 1;
+		m = hi - (gtHi - unHi) + 1;
+
+		if (n - lo > hi - m) {
+			fpush(lo, n);
+			fpush(m, hi);
+		} else {
+			fpush(m, hi);
+			fpush(lo, n);
+		}
+	}
+}
+
+#undef fpush
+#undef fpop
+#undef FALLBACK_QSORT_SMALL_THRESH
+#undef FALLBACK_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+ *	nblock > 0
+ *	eclass exists for [0 .. nblock-1]
+ *	((uint8_t*)eclass) [0 .. nblock-1] holds block
+ *	ptr exists for [0 .. nblock-1]
+ *
+ * Post:
+ *	((uint8_t*)eclass) [0 .. nblock-1] holds block
+ *	All other areas of eclass destroyed
+ *	fmap [0 .. nblock-1] holds sorted order
+ *	bhtab[0 .. 2+(nblock/32)] destroyed
+*/
+
+#define       SET_BH(zz)  bhtab[(zz) >> 5] |= (1 << ((zz) & 31))
+#define     CLEAR_BH(zz)  bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31))
+#define     ISSET_BH(zz)  (bhtab[(zz) >> 5] & (1 << ((zz) & 31)))
+#define      WORD_BH(zz)  bhtab[(zz) >> 5]
+#define UNALIGNED_BH(zz)  ((zz) & 0x01f)
+
+static
+void fallbackSort(uint32_t* fmap,
+		uint32_t* eclass,
+		uint32_t* bhtab,
+		int32_t   nblock)
+{
+	int32_t ftab[257];
+	int32_t ftabCopy[256];
+	int32_t H, i, j, k, l, r, cc, cc1;
+	int32_t nNotDone;
+	int32_t nBhtab;
+	uint8_t* eclass8 = (uint8_t*)eclass;
+
+	/*
+	 * Initial 1-char radix sort to generate
+	 * initial fmap and initial BH bits.
+	 */
+	for (i = 0; i < 257;    i++) ftab[i] = 0;
+	for (i = 0; i < nblock; i++) ftab[eclass8[i]]++;
+	for (i = 0; i < 256;    i++) ftabCopy[i] = ftab[i];
+
+	j = ftab[0];  /* bbox: optimized */
+	for (i = 1; i < 257;    i++) {
+		j += ftab[i];
+		ftab[i] = j;
+	}
+
+	for (i = 0; i < nblock; i++) {
+		j = eclass8[i];
+		k = ftab[j] - 1;
+		ftab[j] = k;
+		fmap[k] = i;
+	}
+
+	nBhtab = 2 + ((uint32_t)nblock / 32); /* bbox: unsigned div is easier */
+	for (i = 0; i < nBhtab; i++) bhtab[i] = 0;
+	for (i = 0; i < 256; i++) SET_BH(ftab[i]);
+
+	/*
+	 * Inductively refine the buckets.  Kind-of an
+	 * "exponential radix sort" (!), inspired by the
+	 * Manber-Myers suffix array construction algorithm.
+	 */
+
+	/*-- set sentinel bits for block-end detection --*/
+	for (i = 0; i < 32; i++) {
+		SET_BH(nblock + 2*i);
+		CLEAR_BH(nblock + 2*i + 1);
+	}
+
+	/*-- the log(N) loop --*/
+	H = 1;
+	while (1) {
+		j = 0;
+		for (i = 0; i < nblock; i++) {
+			if (ISSET_BH(i))
+				j = i;
+			k = fmap[i] - H;
+			if (k < 0)
+				k += nblock;
+			eclass[k] = j;
+		}
+
+		nNotDone = 0;
+		r = -1;
+		while (1) {
+
+		/*-- find the next non-singleton bucket --*/
+			k = r + 1;
+			while (ISSET_BH(k) && UNALIGNED_BH(k))
+				k++;
+			if (ISSET_BH(k)) {
+				while (WORD_BH(k) == 0xffffffff) k += 32;
+				while (ISSET_BH(k)) k++;
+			}
+			l = k - 1;
+			if (l >= nblock)
+				break;
+			while (!ISSET_BH(k) && UNALIGNED_BH(k))
+				k++;
+			if (!ISSET_BH(k)) {
+				while (WORD_BH(k) == 0x00000000) k += 32;
+				while (!ISSET_BH(k)) k++;
+			}
+			r = k - 1;
+			if (r >= nblock)
+				break;
+
+			/*-- now [l, r] bracket current bucket --*/
+			if (r > l) {
+				nNotDone += (r - l + 1);
+				fallbackQSort3(fmap, eclass, l, r);
+
+				/*-- scan bucket and generate header bits-- */
+				cc = -1;
+				for (i = l; i <= r; i++) {
+					cc1 = eclass[fmap[i]];
+					if (cc != cc1) {
+						SET_BH(i);
+						cc = cc1;
+					};
+				}
+			}
+		}
+
+		H *= 2;
+		if (H > nblock || nNotDone == 0)
+			break;
+	}
+
+	/*
+	 * Reconstruct the original block in
+	 * eclass8 [0 .. nblock-1], since the
+	 * previous phase destroyed it.
+	 */
+	j = 0;
+	for (i = 0; i < nblock; i++) {
+		while (ftabCopy[j] == 0)
+			j++;
+		ftabCopy[j]--;
+		eclass8[fmap[i]] = (uint8_t)j;
+	}
+	AssertH(j < 256, 1005);
+}
+
+#undef       SET_BH
+#undef     CLEAR_BH
+#undef     ISSET_BH
+#undef      WORD_BH
+#undef UNALIGNED_BH
+
+
+/*---------------------------------------------*/
+/*--- The main, O(N^2 log(N)) sorting       ---*/
+/*--- algorithm.  Faster for "normal"       ---*/
+/*--- non-repetitive blocks.                ---*/
+/*---------------------------------------------*/
+
+/*---------------------------------------------*/
+static
+NOINLINE
+int mainGtU(
+		uint32_t  i1,
+		uint32_t  i2,
+		uint8_t*  block,
+		uint16_t* quadrant,
+		uint32_t  nblock,
+		int32_t*  budget)
+{
+	int32_t  k;
+	uint8_t  c1, c2;
+	uint16_t s1, s2;
+
+/* Loop unrolling here is actually very useful
+ * (generated code is much simpler),
+ * code size increase is only 270 bytes (i386)
+ * but speeds up compression 10% overall
+ */
+
+#if CONFIG_BZIP2_FEATURE_SPEED >= 1
+
+#define TIMES_8(code) \
+	code; code; code; code; \
+	code; code; code; code;
+#define TIMES_12(code) \
+	code; code; code; code; \
+	code; code; code; code; \
+	code; code; code; code;
+
+#else
+
+#define TIMES_8(code) \
+{ \
+	int nn = 8; \
+	do { \
+		code; \
+	} while (--nn); \
+}
+#define TIMES_12(code) \
+{ \
+	int nn = 12; \
+	do { \
+		code; \
+	} while (--nn); \
+}
+
+#endif
+
+	AssertD(i1 != i2, "mainGtU");
+	TIMES_12(
+		c1 = block[i1]; c2 = block[i2];
+		if (c1 != c2) return (c1 > c2);
+		i1++; i2++;
+	)
+
+	k = nblock + 8;
+
+	do {
+		TIMES_8(
+			c1 = block[i1]; c2 = block[i2];
+			if (c1 != c2) return (c1 > c2);
+			s1 = quadrant[i1]; s2 = quadrant[i2];
+			if (s1 != s2) return (s1 > s2);
+			i1++; i2++;
+		)
+
+		if (i1 >= nblock) i1 -= nblock;
+		if (i2 >= nblock) i2 -= nblock;
+
+		(*budget)--;
+		k -= 8;
+	} while (k >= 0);
+
+	return False;
+}
+#undef TIMES_8
+#undef TIMES_12
+
+/*---------------------------------------------*/
+/*
+ * Knuth's increments seem to work better
+ * than Incerpi-Sedgewick here.  Possibly
+ * because the number of elems to sort is
+ * usually small, typically <= 20.
+ */
+static
+const int32_t incs[14] = {
+	1, 4, 13, 40, 121, 364, 1093, 3280,
+	9841, 29524, 88573, 265720,
+	797161, 2391484
+};
+
+static
+void mainSimpleSort(uint32_t* ptr,
+		uint8_t*  block,
+		uint16_t* quadrant,
+		int32_t   nblock,
+		int32_t   lo,
+		int32_t   hi,
+		int32_t   d,
+		int32_t*  budget)
+{
+	int32_t i, j, h, bigN, hp;
+	uint32_t v;
+
+	bigN = hi - lo + 1;
+	if (bigN < 2) return;
+
+	hp = 0;
+	while (incs[hp] < bigN) hp++;
+	hp--;
+
+	for (; hp >= 0; hp--) {
+		h = incs[hp];
+
+		i = lo + h;
+		while (1) {
+			/*-- copy 1 --*/
+			if (i > hi) break;
+			v = ptr[i];
+			j = i;
+			while (mainGtU(ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) {
+				ptr[j] = ptr[j-h];
+				j = j - h;
+				if (j <= (lo + h - 1)) break;
+			}
+			ptr[j] = v;
+			i++;
+
+/* 1.5% overall speedup, +290 bytes */
+#if CONFIG_BZIP2_FEATURE_SPEED >= 3
+			/*-- copy 2 --*/
+			if (i > hi) break;
+			v = ptr[i];
+			j = i;
+			while (mainGtU(ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) {
+				ptr[j] = ptr[j-h];
+				j = j - h;
+				if (j <= (lo + h - 1)) break;
+			}
+			ptr[j] = v;
+			i++;
+
+			/*-- copy 3 --*/
+			if (i > hi) break;
+			v = ptr[i];
+			j = i;
+			while (mainGtU(ptr[j-h]+d, v+d, block, quadrant, nblock, budget)) {
+				ptr[j] = ptr[j-h];
+				j = j - h;
+				if (j <= (lo + h - 1)) break;
+			}
+			ptr[j] = v;
+			i++;
+#endif
+			if (*budget < 0) return;
+		}
+	}
+}
+
+
+/*---------------------------------------------*/
+/*
+ * The following is an implementation of
+ * an elegant 3-way quicksort for strings,
+ * described in a paper "Fast Algorithms for
+ * Sorting and Searching Strings", by Robert
+ * Sedgewick and Jon L. Bentley.
+ */
+
+static
+ALWAYS_INLINE
+uint8_t mmed3(uint8_t a, uint8_t b, uint8_t c)
+{
+	uint8_t t;
+	if (a > b) {
+		t = a;
+		a = b;
+		b = t;
+	};
+	/* here b >= a */
+	if (b > c) {
+		b = c;
+		if (a > b)
+			b = a;
+	}
+	return b;
+}
+
+#define mpush(lz,hz,dz) \
+{ \
+	stackLo[sp] = lz; \
+	stackHi[sp] = hz; \
+	stackD [sp] = dz; \
+	sp++; \
+}
+
+#define mpop(lz,hz,dz) \
+{ \
+	sp--; \
+	lz = stackLo[sp]; \
+	hz = stackHi[sp]; \
+	dz = stackD [sp]; \
+}
+
+#define mnextsize(az) (nextHi[az] - nextLo[az])
+
+#define mnextswap(az,bz) \
+{ \
+	int32_t tz; \
+	tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \
+	tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \
+	tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; \
+}
+
+#define MAIN_QSORT_SMALL_THRESH 20
+#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT)
+#define MAIN_QSORT_STACK_SIZE   100
+
+static NOINLINE
+void mainQSort3(uint32_t* ptr,
+		uint8_t*  block,
+		uint16_t* quadrant,
+		int32_t   nblock,
+		int32_t   loSt,
+		int32_t   hiSt,
+		int32_t   dSt,
+		int32_t*  budget)
+{
+	int32_t unLo, unHi, ltLo, gtHi, n, m, med;
+	int32_t sp, lo, hi, d;
+
+	int32_t stackLo[MAIN_QSORT_STACK_SIZE];
+	int32_t stackHi[MAIN_QSORT_STACK_SIZE];
+	int32_t stackD [MAIN_QSORT_STACK_SIZE];
+
+	int32_t nextLo[3];
+	int32_t nextHi[3];
+	int32_t nextD [3];
+
+	sp = 0;
+	mpush(loSt, hiSt, dSt);
+
+	while (sp > 0) {
+		AssertH(sp < MAIN_QSORT_STACK_SIZE - 2, 1001);
+
+		mpop(lo, hi, d);
+		if (hi - lo < MAIN_QSORT_SMALL_THRESH
+		 || d > MAIN_QSORT_DEPTH_THRESH
+		) {
+			mainSimpleSort(ptr, block, quadrant, nblock, lo, hi, d, budget);
+			if (*budget < 0)
+				return;
+			continue;
+		}
+		med = (int32_t)	mmed3(block[ptr[lo          ] + d],
+		                      block[ptr[hi          ] + d],
+		                      block[ptr[(lo+hi) >> 1] + d]);
+
+		unLo = ltLo = lo;
+		unHi = gtHi = hi;
+
+		while (1) {
+			while (1) {
+				if (unLo > unHi)
+					break;
+				n = ((int32_t)block[ptr[unLo]+d]) - med;
+				if (n == 0) {
+					mswap(ptr[unLo], ptr[ltLo]);
+					ltLo++;
+					unLo++;
+					continue;
+				};
+				if (n >  0) break;
+				unLo++;
+			}
+			while (1) {
+				if (unLo > unHi)
+					break;
+				n = ((int32_t)block[ptr[unHi]+d]) - med;
+				if (n == 0) {
+					mswap(ptr[unHi], ptr[gtHi]);
+					gtHi--;
+					unHi--;
+					continue;
+				};
+				if (n <  0) break;
+				unHi--;
+			}
+			if (unLo > unHi)
+				break;
+			mswap(ptr[unLo], ptr[unHi]);
+			unLo++;
+			unHi--;
+		}
+
+		AssertD(unHi == unLo-1, "mainQSort3(2)");
+
+		if (gtHi < ltLo) {
+			mpush(lo, hi, d + 1);
+			continue;
+		}
+
+		n = mmin(ltLo-lo, unLo-ltLo); mvswap(ptr, lo, unLo-n, n);
+		m = mmin(hi-gtHi, gtHi-unHi); mvswap(ptr, unLo, hi-m+1, m);
+
+		n = lo + unLo - ltLo - 1;
+		m = hi - (gtHi - unHi) + 1;
+
+		nextLo[0] = lo;  nextHi[0] = n;   nextD[0] = d;
+		nextLo[1] = m;   nextHi[1] = hi;  nextD[1] = d;
+		nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1;
+
+		if (mnextsize(0) < mnextsize(1)) mnextswap(0, 1);
+		if (mnextsize(1) < mnextsize(2)) mnextswap(1, 2);
+		if (mnextsize(0) < mnextsize(1)) mnextswap(0, 1);
+
+		AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)");
+		AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)");
+
+		mpush(nextLo[0], nextHi[0], nextD[0]);
+		mpush(nextLo[1], nextHi[1], nextD[1]);
+		mpush(nextLo[2], nextHi[2], nextD[2]);
+	}
+}
+
+#undef mpush
+#undef mpop
+#undef mnextsize
+#undef mnextswap
+#undef MAIN_QSORT_SMALL_THRESH
+#undef MAIN_QSORT_DEPTH_THRESH
+#undef MAIN_QSORT_STACK_SIZE
+
+
+/*---------------------------------------------*/
+/* Pre:
+ *	nblock > N_OVERSHOOT
+ *	block32 exists for [0 .. nblock-1 +N_OVERSHOOT]
+ *	((uint8_t*)block32) [0 .. nblock-1] holds block
+ *	ptr exists for [0 .. nblock-1]
+ *
+ * Post:
+ *	((uint8_t*)block32) [0 .. nblock-1] holds block
+ *	All other areas of block32 destroyed
+ *	ftab[0 .. 65536] destroyed
+ *	ptr [0 .. nblock-1] holds sorted order
+ *	if (*budget < 0), sorting was abandoned
+ */
+
+#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8])
+#define SETMASK (1 << 21)
+#define CLEARMASK (~(SETMASK))
+
+static NOINLINE
+void mainSort(EState* state,
+		uint32_t* ptr,
+		uint8_t*  block,
+		uint16_t* quadrant,
+		uint32_t* ftab,
+		int32_t   nblock,
+		int32_t*  budget)
+{
+	int32_t  i, j, k, ss, sb;
+	uint8_t  c1;
+	int32_t  numQSorted;
+	uint16_t s;
+	Bool     bigDone[256];
+	/* bbox: moved to EState to save stack
+	int32_t  runningOrder[256];
+	int32_t  copyStart[256];
+	int32_t  copyEnd  [256];
+	*/
+#define runningOrder (state->mainSort__runningOrder)
+#define copyStart    (state->mainSort__copyStart)
+#define copyEnd      (state->mainSort__copyEnd)
+
+	/*-- set up the 2-byte frequency table --*/
+	/* was: for (i = 65536; i >= 0; i--) ftab[i] = 0; */
+	memset(ftab, 0, 65537 * sizeof(ftab[0]));
+
+	j = block[0] << 8;
+	i = nblock - 1;
+/* 3%, +300 bytes */
+#if CONFIG_BZIP2_FEATURE_SPEED >= 2
+	for (; i >= 3; i -= 4) {
+		quadrant[i] = 0;
+		j = (j >> 8) | (((uint16_t)block[i]) << 8);
+		ftab[j]++;
+		quadrant[i-1] = 0;
+		j = (j >> 8) | (((uint16_t)block[i-1]) << 8);
+		ftab[j]++;
+		quadrant[i-2] = 0;
+		j = (j >> 8) | (((uint16_t)block[i-2]) << 8);
+		ftab[j]++;
+		quadrant[i-3] = 0;
+		j = (j >> 8) | (((uint16_t)block[i-3]) << 8);
+		ftab[j]++;
+	}
+#endif
+	for (; i >= 0; i--) {
+		quadrant[i] = 0;
+		j = (j >> 8) | (((uint16_t)block[i]) << 8);
+		ftab[j]++;
+	}
+
+	/*-- (emphasises close relationship of block & quadrant) --*/
+	for (i = 0; i < BZ_N_OVERSHOOT; i++) {
+		block   [nblock+i] = block[i];
+		quadrant[nblock+i] = 0;
+	}
+
+	/*-- Complete the initial radix sort --*/
+	j = ftab[0]; /* bbox: optimized */
+	for (i = 1; i <= 65536; i++) {
+		j += ftab[i];
+		ftab[i] = j;
+	}
+
+	s = block[0] << 8;
+	i = nblock - 1;
+#if CONFIG_BZIP2_FEATURE_SPEED >= 2
+	for (; i >= 3; i -= 4) {
+		s = (s >> 8) | (block[i] << 8);
+		j = ftab[s] - 1;
+		ftab[s] = j;
+		ptr[j] = i;
+		s = (s >> 8) | (block[i-1] << 8);
+		j = ftab[s] - 1;
+		ftab[s] = j;
+		ptr[j] = i-1;
+		s = (s >> 8) | (block[i-2] << 8);
+		j = ftab[s] - 1;
+		ftab[s] = j;
+		ptr[j] = i-2;
+		s = (s >> 8) | (block[i-3] << 8);
+		j = ftab[s] - 1;
+		ftab[s] = j;
+		ptr[j] = i-3;
+	}
+#endif
+	for (; i >= 0; i--) {
+		s = (s >> 8) | (block[i] << 8);
+		j = ftab[s] - 1;
+		ftab[s] = j;
+		ptr[j] = i;
+	}
+
+	/*
+	 * Now ftab contains the first loc of every small bucket.
+	 * Calculate the running order, from smallest to largest
+	 * big bucket.
+	 */
+	for (i = 0; i <= 255; i++) {
+		bigDone     [i] = False;
+		runningOrder[i] = i;
+	}
+
+	{
+		int32_t vv;
+		/* bbox: was: int32_t h = 1; */
+		/* do h = 3 * h + 1; while (h <= 256); */
+		uint32_t h = 364;
+
+		do {
+			/*h = h / 3;*/
+			h = (h * 171) >> 9; /* bbox: fast h/3 */
+			for (i = h; i <= 255; i++) {
+				vv = runningOrder[i];
+				j = i;
+				while (BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv)) {
+					runningOrder[j] = runningOrder[j-h];
+					j = j - h;
+					if (j <= (h - 1))
+						goto zero;
+				}
+ zero:
+				runningOrder[j] = vv;
+			}
+		} while (h != 1);
+	}
+
+	/*
+	 * The main sorting loop.
+	 */
+
+	numQSorted = 0;
+
+	for (i = 0; i <= 255; i++) {
+
+		/*
+		 * Process big buckets, starting with the least full.
+		 * Basically this is a 3-step process in which we call
+		 * mainQSort3 to sort the small buckets [ss, j], but
+		 * also make a big effort to avoid the calls if we can.
+		 */
+		ss = runningOrder[i];
+
+		/*
+		 * Step 1:
+		 * Complete the big bucket [ss] by quicksorting
+		 * any unsorted small buckets [ss, j], for j != ss.
+		 * Hopefully previous pointer-scanning phases have already
+		 * completed many of the small buckets [ss, j], so
+		 * we don't have to sort them at all.
+		 */
+		for (j = 0; j <= 255; j++) {
+			if (j != ss) {
+				sb = (ss << 8) + j;
+				if (!(ftab[sb] & SETMASK)) {
+					int32_t lo =  ftab[sb]   & CLEARMASK;
+					int32_t hi = (ftab[sb+1] & CLEARMASK) - 1;
+					if (hi > lo) {
+						mainQSort3(
+							ptr, block, quadrant, nblock,
+							lo, hi, BZ_N_RADIX, budget
+						);
+						if (*budget < 0) return;
+						numQSorted += (hi - lo + 1);
+					}
+				}
+				ftab[sb] |= SETMASK;
+			}
+		}
+
+		AssertH(!bigDone[ss], 1006);
+
+		/*
+		 * Step 2:
+		 * Now scan this big bucket [ss] so as to synthesise the
+		 * sorted order for small buckets [t, ss] for all t,
+		 * including, magically, the bucket [ss,ss] too.
+		 * This will avoid doing Real Work in subsequent Step 1's.
+		 */
+		{
+			for (j = 0; j <= 255; j++) {
+				copyStart[j] =  ftab[(j << 8) + ss]     & CLEARMASK;
+				copyEnd  [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1;
+			}
+			for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) {
+				k = ptr[j] - 1;
+				if (k < 0)
+					k += nblock;
+				c1 = block[k];
+				if (!bigDone[c1])
+					ptr[copyStart[c1]++] = k;
+			}
+			for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) {
+				k = ptr[j]-1;
+				if (k < 0)
+					k += nblock;
+				c1 = block[k];
+				if (!bigDone[c1])
+					ptr[copyEnd[c1]--] = k;
+			}
+		}
+
+		/* Extremely rare case missing in bzip2-1.0.0 and 1.0.1.
+		 * Necessity for this case is demonstrated by compressing
+		 * a sequence of approximately 48.5 million of character
+		 * 251; 1.0.0/1.0.1 will then die here. */
+		AssertH((copyStart[ss]-1 == copyEnd[ss]) \
+		     || (copyStart[ss] == 0 && copyEnd[ss] == nblock-1), 1007);
+
+		for (j = 0; j <= 255; j++)
+			ftab[(j << 8) + ss] |= SETMASK;
+
+		/*
+		 * Step 3:
+		 * The [ss] big bucket is now done.  Record this fact,
+		 * and update the quadrant descriptors.  Remember to
+		 * update quadrants in the overshoot area too, if
+		 * necessary.  The "if (i < 255)" test merely skips
+		 * this updating for the last bucket processed, since
+		 * updating for the last bucket is pointless.
+		 *
+		 * The quadrant array provides a way to incrementally
+		 * cache sort orderings, as they appear, so as to
+		 * make subsequent comparisons in fullGtU() complete
+		 * faster.  For repetitive blocks this makes a big
+		 * difference (but not big enough to be able to avoid
+		 * the fallback sorting mechanism, exponential radix sort).
+		 *
+		 * The precise meaning is: at all times:
+		 *
+		 *	for 0 <= i < nblock and 0 <= j <= nblock
+		 *
+		 *	if block[i] != block[j],
+		 *
+		 *		then the relative values of quadrant[i] and
+		 *			  quadrant[j] are meaningless.
+		 *
+		 *		else {
+		 *			if quadrant[i] < quadrant[j]
+		 *				then the string starting at i lexicographically
+		 *				precedes the string starting at j
+		 *
+		 *			else if quadrant[i] > quadrant[j]
+		 *				then the string starting at j lexicographically
+		 *				precedes the string starting at i
+		 *
+		 *			else
+		 *				the relative ordering of the strings starting
+		 *				at i and j has not yet been determined.
+		 *		}
+		 */
+		bigDone[ss] = True;
+
+		if (i < 255) {
+			int32_t bbStart = ftab[ss << 8] & CLEARMASK;
+			int32_t bbSize  = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart;
+			int32_t shifts  = 0;
+
+			while ((bbSize >> shifts) > 65534) shifts++;
+
+			for (j = bbSize-1; j >= 0; j--) {
+				int32_t a2update   = ptr[bbStart + j];
+				uint16_t qVal      = (uint16_t)(j >> shifts);
+				quadrant[a2update] = qVal;
+				if (a2update < BZ_N_OVERSHOOT)
+					quadrant[a2update + nblock] = qVal;
+			}
+			AssertH(((bbSize-1) >> shifts) <= 65535, 1002);
+		}
+	}
+#undef runningOrder
+#undef copyStart
+#undef copyEnd
+}
+
+#undef BIGFREQ
+#undef SETMASK
+#undef CLEARMASK
+
+
+/*---------------------------------------------*/
+/* Pre:
+ *	nblock > 0
+ *	arr2 exists for [0 .. nblock-1 +N_OVERSHOOT]
+ *	  ((uint8_t*)arr2)[0 .. nblock-1] holds block
+ *	arr1 exists for [0 .. nblock-1]
+ *
+ * Post:
+ *	((uint8_t*)arr2) [0 .. nblock-1] holds block
+ *	All other areas of block destroyed
+ *	ftab[0 .. 65536] destroyed
+ *	arr1[0 .. nblock-1] holds sorted order
+ */
+static NOINLINE
+void BZ2_blockSort(EState* s)
+{
+	/* In original bzip2 1.0.4, it's a parameter, but 30
+	 * (which was the default) should work ok. */
+	enum { wfact = 30 };
+
+	uint32_t* ptr    = s->ptr;
+	uint8_t*  block  = s->block;
+	uint32_t* ftab   = s->ftab;
+	int32_t   nblock = s->nblock;
+	uint16_t* quadrant;
+	int32_t   budget;
+	int32_t   i;
+
+	if (nblock < 10000) {
+		fallbackSort(s->arr1, s->arr2, ftab, nblock);
+	} else {
+		/* Calculate the location for quadrant, remembering to get
+		 * the alignment right.  Assumes that &(block[0]) is at least
+		 * 2-byte aligned -- this should be ok since block is really
+		 * the first section of arr2.
+		 */
+		i = nblock + BZ_N_OVERSHOOT;
+		if (i & 1) i++;
+		quadrant = (uint16_t*)(&(block[i]));
+
+		/* (wfact-1) / 3 puts the default-factor-30
+		 * transition point at very roughly the same place as
+		 * with v0.1 and v0.9.0.
+		 * Not that it particularly matters any more, since the
+		 * resulting compressed stream is now the same regardless
+		 * of whether or not we use the main sort or fallback sort.
+		 */
+		budget = nblock * ((wfact-1) / 3);
+
+		mainSort(s, ptr, block, quadrant, ftab, nblock, &budget);
+		if (budget < 0) {
+			fallbackSort(s->arr1, s->arr2, ftab, nblock);
+		}
+	}
+
+	s->origPtr = -1;
+	for (i = 0; i < s->nblock; i++)
+		if (ptr[i] == 0) {
+			s->origPtr = i;
+			break;
+		};
+
+	AssertH(s->origPtr != -1, 1003);
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                       blocksort.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/busybox-1.19.3/archival/libarchive/bz/bzlib.c b/busybox-1.19.3/archival/libarchive/bz/bzlib.c
new file mode 100644
index 0000000..5f7db74
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/bz/bzlib.c
@@ -0,0 +1,429 @@
+/*
+ * bzip2 is written by Julian Seward <jseward@bzip.org>.
+ * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>.
+ * See README and LICENSE files in this directory for more information.
+ */
+
+/*-------------------------------------------------------------*/
+/*--- Library top-level functions.                          ---*/
+/*---                                               bzlib.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.4 of 20 December 2006
+Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in the
+README file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------ */
+
+/* CHANGES
+ * 0.9.0    -- original version.
+ * 0.9.0a/b -- no changes in this file.
+ * 0.9.0c   -- made zero-length BZ_FLUSH work correctly in bzCompress().
+ *             fixed bzWrite/bzRead to ignore zero-length requests.
+ *             fixed bzread to correctly handle read requests after EOF.
+ *             wrong parameter order in call to bzDecompressInit in
+ *             bzBuffToBuffDecompress.  Fixed.
+ */
+
+/* #include "bzlib_private.h" */
+
+/*---------------------------------------------------*/
+/*--- Compression stuff                           ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+#if BZ_LIGHT_DEBUG
+static
+void bz_assert_fail(int errcode)
+{
+	/* if (errcode == 1007) bb_error_msg_and_die("probably bad RAM"); */
+	bb_error_msg_and_die("internal error %d", errcode);
+}
+#endif
+
+/*---------------------------------------------------*/
+static
+void prepare_new_block(EState* s)
+{
+	int i;
+	s->nblock = 0;
+	s->numZ = 0;
+	s->state_out_pos = 0;
+	BZ_INITIALISE_CRC(s->blockCRC);
+	/* inlined memset would be nice to have here */
+	for (i = 0; i < 256; i++)
+		s->inUse[i] = 0;
+	s->blockNo++;
+}
+
+
+/*---------------------------------------------------*/
+static
+ALWAYS_INLINE
+void init_RL(EState* s)
+{
+	s->state_in_ch = 256;
+	s->state_in_len = 0;
+}
+
+
+static
+int isempty_RL(EState* s)
+{
+	return (s->state_in_ch >= 256 || s->state_in_len <= 0);
+}
+
+
+/*---------------------------------------------------*/
+static
+void BZ2_bzCompressInit(bz_stream *strm, int blockSize100k)
+{
+	int32_t n;
+	EState* s;
+
+	s = xzalloc(sizeof(EState));
+	s->strm = strm;
+
+	n        = 100000 * blockSize100k;
+	s->arr1  = xmalloc(n                    * sizeof(uint32_t));
+	s->mtfv  = (uint16_t*)s->arr1;
+	s->ptr   = (uint32_t*)s->arr1;
+	s->arr2  = xmalloc((n + BZ_N_OVERSHOOT) * sizeof(uint32_t));
+	s->block = (uint8_t*)s->arr2;
+	s->ftab  = xmalloc(65537                * sizeof(uint32_t));
+
+	s->crc32table = crc32_filltable(NULL, 1);
+
+	s->state             = BZ_S_INPUT;
+	s->mode              = BZ_M_RUNNING;
+	s->blockSize100k     = blockSize100k;
+	s->nblockMAX         = n - 19;
+
+	strm->state          = s;
+	/*strm->total_in     = 0;*/
+	strm->total_out      = 0;
+	init_RL(s);
+	prepare_new_block(s);
+}
+
+
+/*---------------------------------------------------*/
+static
+void add_pair_to_block(EState* s)
+{
+	int32_t i;
+	uint8_t ch = (uint8_t)(s->state_in_ch);
+	for (i = 0; i < s->state_in_len; i++) {
+		BZ_UPDATE_CRC(s, s->blockCRC, ch);
+	}
+	s->inUse[s->state_in_ch] = 1;
+	switch (s->state_in_len) {
+		case 3:
+			s->block[s->nblock] = (uint8_t)ch; s->nblock++;
+			/* fall through */
+		case 2:
+			s->block[s->nblock] = (uint8_t)ch; s->nblock++;
+			/* fall through */
+		case 1:
+			s->block[s->nblock] = (uint8_t)ch; s->nblock++;
+			break;
+		default:
+			s->inUse[s->state_in_len - 4] = 1;
+			s->block[s->nblock] = (uint8_t)ch; s->nblock++;
+			s->block[s->nblock] = (uint8_t)ch; s->nblock++;
+			s->block[s->nblock] = (uint8_t)ch; s->nblock++;
+			s->block[s->nblock] = (uint8_t)ch; s->nblock++;
+			s->block[s->nblock] = (uint8_t)(s->state_in_len - 4);
+			s->nblock++;
+			break;
+	}
+}
+
+
+/*---------------------------------------------------*/
+static
+void flush_RL(EState* s)
+{
+	if (s->state_in_ch < 256) add_pair_to_block(s);
+	init_RL(s);
+}
+
+
+/*---------------------------------------------------*/
+#define ADD_CHAR_TO_BLOCK(zs, zchh0) \
+{ \
+	uint32_t zchh = (uint32_t)(zchh0); \
+	/*-- fast track the common case --*/ \
+	if (zchh != zs->state_in_ch && zs->state_in_len == 1) { \
+		uint8_t ch = (uint8_t)(zs->state_in_ch); \
+		BZ_UPDATE_CRC(zs, zs->blockCRC, ch); \
+		zs->inUse[zs->state_in_ch] = 1; \
+		zs->block[zs->nblock] = (uint8_t)ch; \
+		zs->nblock++; \
+		zs->state_in_ch = zchh; \
+	} \
+	else \
+	/*-- general, uncommon cases --*/ \
+	if (zchh != zs->state_in_ch || zs->state_in_len == 255) { \
+		if (zs->state_in_ch < 256) \
+			add_pair_to_block(zs); \
+		zs->state_in_ch = zchh; \
+		zs->state_in_len = 1; \
+	} else { \
+		zs->state_in_len++; \
+	} \
+}
+
+
+/*---------------------------------------------------*/
+static
+void /*Bool*/ copy_input_until_stop(EState* s)
+{
+	/*Bool progress_in = False;*/
+
+#ifdef SAME_CODE_AS_BELOW
+	if (s->mode == BZ_M_RUNNING) {
+		/*-- fast track the common case --*/
+		while (1) {
+			/*-- no input? --*/
+			if (s->strm->avail_in == 0) break;
+			/*-- block full? --*/
+			if (s->nblock >= s->nblockMAX) break;
+			/*progress_in = True;*/
+			ADD_CHAR_TO_BLOCK(s, (uint32_t)(*(uint8_t*)(s->strm->next_in)));
+			s->strm->next_in++;
+			s->strm->avail_in--;
+			/*s->strm->total_in++;*/
+		}
+	} else
+#endif
+	{
+		/*-- general, uncommon case --*/
+		while (1) {
+			/*-- no input? --*/
+			if (s->strm->avail_in == 0) break;
+			/*-- block full? --*/
+			if (s->nblock >= s->nblockMAX) break;
+		//#	/*-- flush/finish end? --*/
+		//#	if (s->avail_in_expect == 0) break;
+			/*progress_in = True;*/
+			ADD_CHAR_TO_BLOCK(s, *(uint8_t*)(s->strm->next_in));
+			s->strm->next_in++;
+			s->strm->avail_in--;
+			/*s->strm->total_in++;*/
+		//#	s->avail_in_expect--;
+		}
+	}
+	/*return progress_in;*/
+}
+
+
+/*---------------------------------------------------*/
+static
+void /*Bool*/ copy_output_until_stop(EState* s)
+{
+	/*Bool progress_out = False;*/
+
+	while (1) {
+		/*-- no output space? --*/
+		if (s->strm->avail_out == 0) break;
+
+		/*-- block done? --*/
+		if (s->state_out_pos >= s->numZ) break;
+
+		/*progress_out = True;*/
+		*(s->strm->next_out) = s->zbits[s->state_out_pos];
+		s->state_out_pos++;
+		s->strm->avail_out--;
+		s->strm->next_out++;
+		s->strm->total_out++;
+	}
+	/*return progress_out;*/
+}
+
+
+/*---------------------------------------------------*/
+static
+void /*Bool*/ handle_compress(bz_stream *strm)
+{
+	/*Bool progress_in  = False;*/
+	/*Bool progress_out = False;*/
+	EState* s = strm->state;
+
+	while (1) {
+		if (s->state == BZ_S_OUTPUT) {
+			/*progress_out |=*/ copy_output_until_stop(s);
+			if (s->state_out_pos < s->numZ) break;
+			if (s->mode == BZ_M_FINISHING
+			//# && s->avail_in_expect == 0
+			 && s->strm->avail_in == 0
+			 && isempty_RL(s))
+				break;
+			prepare_new_block(s);
+			s->state = BZ_S_INPUT;
+#ifdef FLUSH_IS_UNUSED
+			if (s->mode == BZ_M_FLUSHING
+			 && s->avail_in_expect == 0
+			 && isempty_RL(s))
+				break;
+#endif
+		}
+
+		if (s->state == BZ_S_INPUT) {
+			/*progress_in |=*/ copy_input_until_stop(s);
+			//#if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) {
+			if (s->mode != BZ_M_RUNNING && s->strm->avail_in == 0) {
+				flush_RL(s);
+				BZ2_compressBlock(s, (s->mode == BZ_M_FINISHING));
+				s->state = BZ_S_OUTPUT;
+			} else
+			if (s->nblock >= s->nblockMAX) {
+				BZ2_compressBlock(s, 0);
+				s->state = BZ_S_OUTPUT;
+			} else
+			if (s->strm->avail_in == 0) {
+				break;
+			}
+		}
+	}
+
+	/*return progress_in || progress_out;*/
+}
+
+
+/*---------------------------------------------------*/
+static
+int BZ2_bzCompress(bz_stream *strm, int action)
+{
+	/*Bool progress;*/
+	EState* s;
+
+	s = strm->state;
+
+	switch (s->mode) {
+		case BZ_M_RUNNING:
+			if (action == BZ_RUN) {
+				/*progress =*/ handle_compress(strm);
+				/*return progress ? BZ_RUN_OK : BZ_PARAM_ERROR;*/
+				return BZ_RUN_OK;
+			}
+#ifdef FLUSH_IS_UNUSED
+			else
+			if (action == BZ_FLUSH) {
+				//#s->avail_in_expect = strm->avail_in;
+				s->mode = BZ_M_FLUSHING;
+				goto case_BZ_M_FLUSHING;
+			}
+#endif
+			else
+			/*if (action == BZ_FINISH)*/ {
+				//#s->avail_in_expect = strm->avail_in;
+				s->mode = BZ_M_FINISHING;
+				goto case_BZ_M_FINISHING;
+			}
+
+#ifdef FLUSH_IS_UNUSED
+ case_BZ_M_FLUSHING:
+		case BZ_M_FLUSHING:
+			/*if (s->avail_in_expect != s->strm->avail_in)
+				return BZ_SEQUENCE_ERROR;*/
+			/*progress =*/ handle_compress(strm);
+			if (s->avail_in_expect > 0 || !isempty_RL(s) || s->state_out_pos < s->numZ)
+				return BZ_FLUSH_OK;
+			s->mode = BZ_M_RUNNING;
+			return BZ_RUN_OK;
+#endif
+
+ case_BZ_M_FINISHING:
+		/*case BZ_M_FINISHING:*/
+		default:
+			/*if (s->avail_in_expect != s->strm->avail_in)
+				return BZ_SEQUENCE_ERROR;*/
+			/*progress =*/ handle_compress(strm);
+			/*if (!progress) return BZ_SEQUENCE_ERROR;*/
+			//#if (s->avail_in_expect > 0 || !isempty_RL(s) || s->state_out_pos < s->numZ)
+			//#	return BZ_FINISH_OK;
+			if (s->strm->avail_in > 0 || !isempty_RL(s) || s->state_out_pos < s->numZ)
+				return BZ_FINISH_OK;
+			/*s->mode = BZ_M_IDLE;*/
+			return BZ_STREAM_END;
+	}
+	/* return BZ_OK; --not reached--*/
+}
+
+
+/*---------------------------------------------------*/
+static
+void BZ2_bzCompressEnd(bz_stream *strm)
+{
+	EState* s;
+
+	s = strm->state;
+	free(s->arr1);
+	free(s->arr2);
+	free(s->ftab);
+	free(s->crc32table);
+	free(s);
+}
+
+
+/*---------------------------------------------------*/
+/*--- Misc convenience stuff                      ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+#ifdef EXAMPLE_CODE_FOR_MEM_TO_MEM_COMPRESSION
+static
+int BZ2_bzBuffToBuffCompress(char* dest,
+		unsigned int* destLen,
+		char*         source,
+		unsigned int  sourceLen,
+		int           blockSize100k)
+{
+	bz_stream strm;
+	int ret;
+
+	if (dest == NULL || destLen == NULL
+	 || source == NULL
+	 || blockSize100k < 1 || blockSize100k > 9
+	) {
+		return BZ_PARAM_ERROR;
+	}
+
+	BZ2_bzCompressInit(&strm, blockSize100k);
+
+	strm.next_in = source;
+	strm.next_out = dest;
+	strm.avail_in = sourceLen;
+	strm.avail_out = *destLen;
+
+	ret = BZ2_bzCompress(&strm, BZ_FINISH);
+	if (ret == BZ_FINISH_OK) goto output_overflow;
+	if (ret != BZ_STREAM_END) goto errhandler;
+
+	/* normal termination */
+	*destLen -= strm.avail_out;
+	BZ2_bzCompressEnd(&strm);
+	return BZ_OK;
+
+ output_overflow:
+	BZ2_bzCompressEnd(&strm);
+	return BZ_OUTBUFF_FULL;
+
+ errhandler:
+	BZ2_bzCompressEnd(&strm);
+	return ret;
+}
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/busybox-1.19.3/archival/libarchive/bz/bzlib.h b/busybox-1.19.3/archival/libarchive/bz/bzlib.h
new file mode 100644
index 0000000..1bb811c
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/bz/bzlib.h
@@ -0,0 +1,65 @@
+/*
+ * bzip2 is written by Julian Seward <jseward@bzip.org>.
+ * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>.
+ * See README and LICENSE files in this directory for more information.
+ */
+
+/*-------------------------------------------------------------*/
+/*--- Public header file for the library.                   ---*/
+/*---                                               bzlib.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.4 of 20 December 2006
+Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in the
+README file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------ */
+
+#define BZ_RUN               0
+#define BZ_FLUSH             1
+#define BZ_FINISH            2
+
+#define BZ_OK                0
+#define BZ_RUN_OK            1
+#define BZ_FLUSH_OK          2
+#define BZ_FINISH_OK         3
+#define BZ_STREAM_END        4
+#define BZ_SEQUENCE_ERROR    (-1)
+#define BZ_PARAM_ERROR       (-2)
+#define BZ_MEM_ERROR         (-3)
+#define BZ_DATA_ERROR        (-4)
+#define BZ_DATA_ERROR_MAGIC  (-5)
+#define BZ_IO_ERROR          (-6)
+#define BZ_UNEXPECTED_EOF    (-7)
+#define BZ_OUTBUFF_FULL      (-8)
+#define BZ_CONFIG_ERROR      (-9)
+
+typedef struct bz_stream {
+	void *state;
+	char *next_in;
+	char *next_out;
+	unsigned avail_in;
+	unsigned avail_out;
+	/*unsigned long long total_in;*/
+	unsigned long long total_out;
+} bz_stream;
+
+/*-- Core (low-level) library functions --*/
+
+static void BZ2_bzCompressInit(bz_stream *strm, int blockSize100k);
+static int BZ2_bzCompress(bz_stream *strm, int action);
+#if ENABLE_FEATURE_CLEAN_UP
+static void BZ2_bzCompressEnd(bz_stream *strm);
+#endif
+
+/*-------------------------------------------------------------*/
+/*--- end                                           bzlib.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/busybox-1.19.3/archival/libarchive/bz/bzlib_private.h b/busybox-1.19.3/archival/libarchive/bz/bzlib_private.h
new file mode 100644
index 0000000..6430ce4
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/bz/bzlib_private.h
@@ -0,0 +1,219 @@
+/*
+ * bzip2 is written by Julian Seward <jseward@bzip.org>.
+ * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>.
+ * See README and LICENSE files in this directory for more information.
+ */
+
+/*-------------------------------------------------------------*/
+/*--- Private header file for the library.                  ---*/
+/*---                                       bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.4 of 20 December 2006
+Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in the
+README file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------ */
+
+/* #include "bzlib.h" */
+
+/*-- General stuff. --*/
+
+typedef unsigned char Bool;
+
+#define True  ((Bool)1)
+#define False ((Bool)0)
+
+#if BZ_LIGHT_DEBUG
+static void bz_assert_fail(int errcode) NORETURN;
+#define AssertH(cond, errcode) \
+do { \
+	if (!(cond)) \
+		bz_assert_fail(errcode); \
+} while (0)
+#else
+#define AssertH(cond, msg) do { } while (0)
+#endif
+
+#if BZ_DEBUG
+#define AssertD(cond, msg) \
+do { \
+	if (!(cond)) \
+		bb_error_msg_and_die("(debug build): internal error %s", msg); \
+} while (0)
+#else
+#define AssertD(cond, msg) do { } while (0)
+#endif
+
+
+/*-- Header bytes. --*/
+
+#define BZ_HDR_B 0x42   /* 'B' */
+#define BZ_HDR_Z 0x5a   /* 'Z' */
+#define BZ_HDR_h 0x68   /* 'h' */
+#define BZ_HDR_0 0x30   /* '0' */
+
+#define BZ_HDR_BZh0 0x425a6830
+
+/*-- Constants for the back end. --*/
+
+#define BZ_MAX_ALPHA_SIZE 258
+#define BZ_MAX_CODE_LEN    23
+
+#define BZ_RUNA 0
+#define BZ_RUNB 1
+
+#define BZ_N_GROUPS 6
+#define BZ_G_SIZE   50
+#define BZ_N_ITERS  4
+
+#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
+
+
+/*-- Stuff for doing CRCs. --*/
+
+#define BZ_INITIALISE_CRC(crcVar) \
+{ \
+	crcVar = 0xffffffffL; \
+}
+
+#define BZ_FINALISE_CRC(crcVar) \
+{ \
+	crcVar = ~(crcVar); \
+}
+
+#define BZ_UPDATE_CRC(s, crcVar, cha) \
+{ \
+	crcVar = (crcVar << 8) ^ s->crc32table[(crcVar >> 24) ^ ((uint8_t)cha)]; \
+}
+
+
+/*-- States and modes for compression. --*/
+
+#define BZ_M_IDLE      1
+#define BZ_M_RUNNING   2
+#define BZ_M_FLUSHING  3
+#define BZ_M_FINISHING 4
+
+#define BZ_S_OUTPUT    1
+#define BZ_S_INPUT     2
+
+#define BZ_N_RADIX 2
+#define BZ_N_QSORT 12
+#define BZ_N_SHELL 18
+#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
+
+
+/*-- Structure holding all the compression-side stuff. --*/
+
+typedef struct EState {
+	/* pointer back to the struct bz_stream */
+	bz_stream *strm;
+
+	/* mode this stream is in, and whether inputting */
+	/* or outputting data */
+	int32_t  mode;
+	int32_t  state;
+
+	/* remembers avail_in when flush/finish requested */
+/* bbox: not needed, strm->avail_in always has the same value */
+/* commented out with '//#' throughout the code */
+	/* uint32_t avail_in_expect; */
+
+	/* for doing the block sorting */
+	int32_t  origPtr;
+	uint32_t *arr1;
+	uint32_t *arr2;
+	uint32_t *ftab;
+
+	/* aliases for arr1 and arr2 */
+	uint32_t *ptr;
+	uint8_t  *block;
+	uint16_t *mtfv;
+	uint8_t  *zbits;
+
+	/* guess what */
+	uint32_t *crc32table;
+
+	/* run-length-encoding of the input */
+	uint32_t state_in_ch;
+	int32_t  state_in_len;
+
+	/* input and output limits and current posns */
+	int32_t  nblock;
+	int32_t  nblockMAX;
+	int32_t  numZ;
+	int32_t  state_out_pos;
+
+	/* the buffer for bit stream creation */
+	uint32_t bsBuff;
+	int32_t  bsLive;
+
+	/* block and combined CRCs */
+	uint32_t blockCRC;
+	uint32_t combinedCRC;
+
+	/* misc administratium */
+	int32_t  blockNo;
+	int32_t  blockSize100k;
+
+	/* stuff for coding the MTF values */
+	int32_t  nMTF;
+
+	/* map of bytes used in block */
+	int32_t  nInUse;
+	Bool     inUse[256] ALIGNED(sizeof(long));
+	uint8_t  unseqToSeq[256];
+
+	/* stuff for coding the MTF values */
+	int32_t  mtfFreq    [BZ_MAX_ALPHA_SIZE];
+	uint8_t  selector   [BZ_MAX_SELECTORS];
+	uint8_t  selectorMtf[BZ_MAX_SELECTORS];
+
+	uint8_t  len[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+
+	/* stack-saving measures: these can be local, but they are too big */
+	int32_t  sendMTFValues__code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+	int32_t  sendMTFValues__rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+#if CONFIG_BZIP2_FEATURE_SPEED >= 5
+	/* second dimension: only 3 needed; 4 makes index calculations faster */
+	uint32_t sendMTFValues__len_pack[BZ_MAX_ALPHA_SIZE][4];
+#endif
+	int32_t  BZ2_hbMakeCodeLengths__heap  [BZ_MAX_ALPHA_SIZE + 2];
+	int32_t  BZ2_hbMakeCodeLengths__weight[BZ_MAX_ALPHA_SIZE * 2];
+	int32_t  BZ2_hbMakeCodeLengths__parent[BZ_MAX_ALPHA_SIZE * 2];
+
+	int32_t  mainSort__runningOrder[256];
+	int32_t  mainSort__copyStart[256];
+	int32_t  mainSort__copyEnd[256];
+} EState;
+
+
+/*-- compression. --*/
+
+static void
+BZ2_blockSort(EState*);
+
+static void
+BZ2_compressBlock(EState*, int);
+
+static void
+BZ2_bsInitWrite(EState*);
+
+static void
+BZ2_hbAssignCodes(int32_t*, uint8_t*, int32_t, int32_t, int32_t);
+
+static void
+BZ2_hbMakeCodeLengths(EState*, uint8_t*, int32_t*, int32_t, int32_t);
+
+/*-------------------------------------------------------------*/
+/*--- end                                   bzlib_private.h ---*/
+/*-------------------------------------------------------------*/
diff --git a/busybox-1.19.3/archival/libarchive/bz/compress.c b/busybox-1.19.3/archival/libarchive/bz/compress.c
new file mode 100644
index 0000000..f936717
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/bz/compress.c
@@ -0,0 +1,680 @@
+/*
+ * bzip2 is written by Julian Seward <jseward@bzip.org>.
+ * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>.
+ * See README and LICENSE files in this directory for more information.
+ */
+
+/*-------------------------------------------------------------*/
+/*--- Compression machinery (not incl block sorting)        ---*/
+/*---                                            compress.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.4 of 20 December 2006
+Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in the
+README file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------ */
+
+/* CHANGES
+ * 0.9.0    -- original version.
+ * 0.9.0a/b -- no changes in this file.
+ * 0.9.0c   -- changed setting of nGroups in sendMTFValues()
+ *             so as to do a bit better on small files
+*/
+
+/* #include "bzlib_private.h" */
+
+/*---------------------------------------------------*/
+/*--- Bit stream I/O                              ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void BZ2_bsInitWrite(EState* s)
+{
+	s->bsLive = 0;
+	s->bsBuff = 0;
+}
+
+
+/*---------------------------------------------------*/
+static NOINLINE
+void bsFinishWrite(EState* s)
+{
+	while (s->bsLive > 0) {
+		s->zbits[s->numZ] = (uint8_t)(s->bsBuff >> 24);
+		s->numZ++;
+		s->bsBuff <<= 8;
+		s->bsLive -= 8;
+	}
+}
+
+
+/*---------------------------------------------------*/
+static
+/* Helps only on level 5, on other levels hurts. ? */
+#if CONFIG_BZIP2_FEATURE_SPEED >= 5
+ALWAYS_INLINE
+#endif
+void bsW(EState* s, int32_t n, uint32_t v)
+{
+	while (s->bsLive >= 8) {
+		s->zbits[s->numZ] = (uint8_t)(s->bsBuff >> 24);
+		s->numZ++;
+		s->bsBuff <<= 8;
+		s->bsLive -= 8;
+	}
+	s->bsBuff |= (v << (32 - s->bsLive - n));
+	s->bsLive += n;
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutU32(EState* s, unsigned u)
+{
+	bsW(s, 8, (u >> 24) & 0xff);
+	bsW(s, 8, (u >> 16) & 0xff);
+	bsW(s, 8, (u >>  8) & 0xff);
+	bsW(s, 8,  u        & 0xff);
+}
+
+
+/*---------------------------------------------------*/
+static
+void bsPutU16(EState* s, unsigned u)
+{
+	bsW(s, 8, (u >>  8) & 0xff);
+	bsW(s, 8,  u        & 0xff);
+}
+
+
+/*---------------------------------------------------*/
+/*--- The back end proper                         ---*/
+/*---------------------------------------------------*/
+
+/*---------------------------------------------------*/
+static
+void makeMaps_e(EState* s)
+{
+	int i;
+	s->nInUse = 0;
+	for (i = 0; i < 256; i++) {
+		if (s->inUse[i]) {
+			s->unseqToSeq[i] = s->nInUse;
+			s->nInUse++;
+		}
+	}
+}
+
+
+/*---------------------------------------------------*/
+static NOINLINE
+void generateMTFValues(EState* s)
+{
+	uint8_t yy[256];
+	int32_t i, j;
+	int32_t zPend;
+	int32_t wr;
+	int32_t EOB;
+
+	/*
+	 * After sorting (eg, here),
+	 * s->arr1[0 .. s->nblock-1] holds sorted order,
+	 * and
+	 * ((uint8_t*)s->arr2)[0 .. s->nblock-1]
+	 * holds the original block data.
+	 *
+	 * The first thing to do is generate the MTF values,
+	 * and put them in ((uint16_t*)s->arr1)[0 .. s->nblock-1].
+	 *
+	 * Because there are strictly fewer or equal MTF values
+	 * than block values, ptr values in this area are overwritten
+	 * with MTF values only when they are no longer needed.
+	 *
+	 * The final compressed bitstream is generated into the
+	 * area starting at &((uint8_t*)s->arr2)[s->nblock]
+	 *
+	 * These storage aliases are set up in bzCompressInit(),
+	 * except for the last one, which is arranged in
+	 * compressBlock().
+	 */
+	uint32_t* ptr   = s->ptr;
+	uint8_t*  block = s->block;
+	uint16_t* mtfv  = s->mtfv;
+
+	makeMaps_e(s);
+	EOB = s->nInUse+1;
+
+	for (i = 0; i <= EOB; i++)
+		s->mtfFreq[i] = 0;
+
+	wr = 0;
+	zPend = 0;
+	for (i = 0; i < s->nInUse; i++)
+		yy[i] = (uint8_t) i;
+
+	for (i = 0; i < s->nblock; i++) {
+		uint8_t ll_i;
+		AssertD(wr <= i, "generateMTFValues(1)");
+		j = ptr[i] - 1;
+		if (j < 0)
+			j += s->nblock;
+		ll_i = s->unseqToSeq[block[j]];
+		AssertD(ll_i < s->nInUse, "generateMTFValues(2a)");
+
+		if (yy[0] == ll_i) {
+			zPend++;
+		} else {
+			if (zPend > 0) {
+				zPend--;
+				while (1) {
+					if (zPend & 1) {
+						mtfv[wr] = BZ_RUNB; wr++;
+						s->mtfFreq[BZ_RUNB]++;
+					} else {
+						mtfv[wr] = BZ_RUNA; wr++;
+						s->mtfFreq[BZ_RUNA]++;
+					}
+					if (zPend < 2) break;
+					zPend = (uint32_t)(zPend - 2) / 2;
+					/* bbox: unsigned div is easier */
+				};
+				zPend = 0;
+			}
+			{
+				register uint8_t  rtmp;
+				register uint8_t* ryy_j;
+				register uint8_t  rll_i;
+				rtmp  = yy[1];
+				yy[1] = yy[0];
+				ryy_j = &(yy[1]);
+				rll_i = ll_i;
+				while (rll_i != rtmp) {
+					register uint8_t rtmp2;
+					ryy_j++;
+					rtmp2  = rtmp;
+					rtmp   = *ryy_j;
+					*ryy_j = rtmp2;
+				};
+				yy[0] = rtmp;
+				j = ryy_j - &(yy[0]);
+				mtfv[wr] = j+1;
+				wr++;
+				s->mtfFreq[j+1]++;
+			}
+		}
+	}
+
+	if (zPend > 0) {
+		zPend--;
+		while (1) {
+			if (zPend & 1) {
+				mtfv[wr] = BZ_RUNB;
+				wr++;
+				s->mtfFreq[BZ_RUNB]++;
+			} else {
+				mtfv[wr] = BZ_RUNA;
+				wr++;
+				s->mtfFreq[BZ_RUNA]++;
+			}
+			if (zPend < 2)
+				break;
+			zPend = (uint32_t)(zPend - 2) / 2;
+			/* bbox: unsigned div is easier */
+		};
+		zPend = 0;
+	}
+
+	mtfv[wr] = EOB;
+	wr++;
+	s->mtfFreq[EOB]++;
+
+	s->nMTF = wr;
+}
+
+
+/*---------------------------------------------------*/
+#define BZ_LESSER_ICOST  0
+#define BZ_GREATER_ICOST 15
+
+static NOINLINE
+void sendMTFValues(EState* s)
+{
+	int32_t v, t, i, j, gs, ge, totc, bt, bc, iter;
+	int32_t nSelectors, alphaSize, minLen, maxLen, selCtr;
+	int32_t nGroups;
+
+	/*
+	 * uint8_t len[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+	 * is a global since the decoder also needs it.
+	 *
+	 * int32_t  code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+	 * int32_t  rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
+	 * are also globals only used in this proc.
+	 * Made global to keep stack frame size small.
+	 */
+#define code     sendMTFValues__code
+#define rfreq    sendMTFValues__rfreq
+#define len_pack sendMTFValues__len_pack
+
+	uint16_t cost[BZ_N_GROUPS];
+	int32_t  fave[BZ_N_GROUPS];
+
+	uint16_t* mtfv = s->mtfv;
+
+	alphaSize = s->nInUse + 2;
+	for (t = 0; t < BZ_N_GROUPS; t++)
+		for (v = 0; v < alphaSize; v++)
+			s->len[t][v] = BZ_GREATER_ICOST;
+
+	/*--- Decide how many coding tables to use ---*/
+	AssertH(s->nMTF > 0, 3001);
+	if (s->nMTF < 200)  nGroups = 2; else
+	if (s->nMTF < 600)  nGroups = 3; else
+	if (s->nMTF < 1200) nGroups = 4; else
+	if (s->nMTF < 2400) nGroups = 5; else
+	nGroups = 6;
+
+	/*--- Generate an initial set of coding tables ---*/
+	{
+		int32_t nPart, remF, tFreq, aFreq;
+
+		nPart = nGroups;
+		remF  = s->nMTF;
+		gs = 0;
+		while (nPart > 0) {
+			tFreq = remF / nPart;
+			ge = gs - 1;
+			aFreq = 0;
+			while (aFreq < tFreq && ge < alphaSize-1) {
+				ge++;
+				aFreq += s->mtfFreq[ge];
+			}
+
+			if (ge > gs
+			 && nPart != nGroups && nPart != 1
+			 && ((nGroups - nPart) % 2 == 1) /* bbox: can this be replaced by x & 1? */
+			) {
+				aFreq -= s->mtfFreq[ge];
+				ge--;
+			}
+
+			for (v = 0; v < alphaSize; v++)
+				if (v >= gs && v <= ge)
+					s->len[nPart-1][v] = BZ_LESSER_ICOST;
+				else
+					s->len[nPart-1][v] = BZ_GREATER_ICOST;
+
+			nPart--;
+			gs = ge + 1;
+			remF -= aFreq;
+		}
+	}
+
+	/*
+	 * Iterate up to BZ_N_ITERS times to improve the tables.
+	 */
+	for (iter = 0; iter < BZ_N_ITERS; iter++) {
+		for (t = 0; t < nGroups; t++)
+			fave[t] = 0;
+
+		for (t = 0; t < nGroups; t++)
+			for (v = 0; v < alphaSize; v++)
+				s->rfreq[t][v] = 0;
+
+#if CONFIG_BZIP2_FEATURE_SPEED >= 5
+		/*
+		 * Set up an auxiliary length table which is used to fast-track
+		 * the common case (nGroups == 6).
+		 */
+		if (nGroups == 6) {
+			for (v = 0; v < alphaSize; v++) {
+				s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
+				s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
+				s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
+			}
+		}
+#endif
+		nSelectors = 0;
+		totc = 0;
+		gs = 0;
+		while (1) {
+			/*--- Set group start & end marks. --*/
+			if (gs >= s->nMTF)
+				break;
+			ge = gs + BZ_G_SIZE - 1;
+			if (ge >= s->nMTF)
+				ge = s->nMTF-1;
+
+			/*
+			 * Calculate the cost of this group as coded
+			 * by each of the coding tables.
+			 */
+			for (t = 0; t < nGroups; t++)
+				cost[t] = 0;
+#if CONFIG_BZIP2_FEATURE_SPEED >= 5
+			if (nGroups == 6 && 50 == ge-gs+1) {
+				/*--- fast track the common case ---*/
+				register uint32_t cost01, cost23, cost45;
+				register uint16_t icv;
+				cost01 = cost23 = cost45 = 0;
+#define BZ_ITER(nn) \
+	icv = mtfv[gs+(nn)]; \
+	cost01 += s->len_pack[icv][0]; \
+	cost23 += s->len_pack[icv][1]; \
+	cost45 += s->len_pack[icv][2];
+				BZ_ITER(0);  BZ_ITER(1);  BZ_ITER(2);  BZ_ITER(3);  BZ_ITER(4);
+				BZ_ITER(5);  BZ_ITER(6);  BZ_ITER(7);  BZ_ITER(8);  BZ_ITER(9);
+				BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
+				BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
+				BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
+				BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
+				BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
+				BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
+				BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
+				BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
+#undef BZ_ITER
+				cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
+				cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
+				cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
+
+			} else
+#endif
+			{
+				/*--- slow version which correctly handles all situations ---*/
+				for (i = gs; i <= ge; i++) {
+					uint16_t icv = mtfv[i];
+					for (t = 0; t < nGroups; t++)
+						cost[t] += s->len[t][icv];
+				}
+			}
+			/*
+			 * Find the coding table which is best for this group,
+			 * and record its identity in the selector table.
+			 */
+			/*bc = 999999999;*/
+			/*bt = -1;*/
+			bc = cost[0];
+			bt = 0;
+			for (t = 1 /*0*/; t < nGroups; t++) {
+				if (cost[t] < bc) {
+					bc = cost[t];
+					bt = t;
+				}
+			}
+			totc += bc;
+			fave[bt]++;
+			s->selector[nSelectors] = bt;
+			nSelectors++;
+
+			/*
+			 * Increment the symbol frequencies for the selected table.
+			 */
+/* 1% faster compress. +800 bytes */
+#if CONFIG_BZIP2_FEATURE_SPEED >= 4
+			if (nGroups == 6 && 50 == ge-gs+1) {
+				/*--- fast track the common case ---*/
+#define BZ_ITUR(nn) s->rfreq[bt][mtfv[gs + (nn)]]++
+				BZ_ITUR(0);  BZ_ITUR(1);  BZ_ITUR(2);  BZ_ITUR(3);  BZ_ITUR(4);
+				BZ_ITUR(5);  BZ_ITUR(6);  BZ_ITUR(7);  BZ_ITUR(8);  BZ_ITUR(9);
+				BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
+				BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
+				BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
+				BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
+				BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
+				BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
+				BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
+				BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
+#undef BZ_ITUR
+				gs = ge + 1;
+			} else
+#endif
+			{
+				/*--- slow version which correctly handles all situations ---*/
+				while (gs <= ge) {
+					s->rfreq[bt][mtfv[gs]]++;
+					gs++;
+				}
+				/* already is: gs = ge + 1; */
+			}
+		}
+
+		/*
+		 * Recompute the tables based on the accumulated frequencies.
+		 */
+		/* maxLen was changed from 20 to 17 in bzip2-1.0.3.  See
+		 * comment in huffman.c for details. */
+		for (t = 0; t < nGroups; t++)
+			BZ2_hbMakeCodeLengths(s, &(s->len[t][0]), &(s->rfreq[t][0]), alphaSize, 17 /*20*/);
+	}
+
+	AssertH(nGroups < 8, 3002);
+	AssertH(nSelectors < 32768 && nSelectors <= (2 + (900000 / BZ_G_SIZE)), 3003);
+
+	/*--- Compute MTF values for the selectors. ---*/
+	{
+		uint8_t pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
+
+		for (i = 0; i < nGroups; i++)
+			pos[i] = i;
+		for (i = 0; i < nSelectors; i++) {
+			ll_i = s->selector[i];
+			j = 0;
+			tmp = pos[j];
+			while (ll_i != tmp) {
+				j++;
+				tmp2 = tmp;
+				tmp = pos[j];
+				pos[j] = tmp2;
+			};
+			pos[0] = tmp;
+			s->selectorMtf[i] = j;
+		}
+	};
+
+	/*--- Assign actual codes for the tables. --*/
+	for (t = 0; t < nGroups; t++) {
+		minLen = 32;
+		maxLen = 0;
+		for (i = 0; i < alphaSize; i++) {
+			if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
+			if (s->len[t][i] < minLen) minLen = s->len[t][i];
+		}
+		AssertH(!(maxLen > 17 /*20*/), 3004);
+		AssertH(!(minLen < 1), 3005);
+		BZ2_hbAssignCodes(&(s->code[t][0]), &(s->len[t][0]), minLen, maxLen, alphaSize);
+	}
+
+	/*--- Transmit the mapping table. ---*/
+	{
+		/* bbox: optimized a bit more than in bzip2 */
+		int inUse16 = 0;
+		for (i = 0; i < 16; i++) {
+			if (sizeof(long) <= 4) {
+				inUse16 = inUse16*2 +
+					((*(uint32_t*)&(s->inUse[i * 16 + 0])
+					| *(uint32_t*)&(s->inUse[i * 16 + 4])
+					| *(uint32_t*)&(s->inUse[i * 16 + 8])
+					| *(uint32_t*)&(s->inUse[i * 16 + 12])) != 0);
+			} else { /* Our CPU can do better */
+				inUse16 = inUse16*2 +
+					((*(uint64_t*)&(s->inUse[i * 16 + 0])
+					| *(uint64_t*)&(s->inUse[i * 16 + 8])) != 0);
+			}
+		}
+
+		bsW(s, 16, inUse16);
+
+		inUse16 <<= (sizeof(int)*8 - 16); /* move 15th bit into sign bit */
+		for (i = 0; i < 16; i++) {
+			if (inUse16 < 0) {
+				unsigned v16 = 0;
+				for (j = 0; j < 16; j++)
+					v16 = v16*2 + s->inUse[i * 16 + j];
+				bsW(s, 16, v16);
+			}
+			inUse16 <<= 1;
+		}
+	}
+
+	/*--- Now the selectors. ---*/
+	bsW(s, 3, nGroups);
+	bsW(s, 15, nSelectors);
+	for (i = 0; i < nSelectors; i++) {
+		for (j = 0; j < s->selectorMtf[i]; j++)
+			bsW(s, 1, 1);
+		bsW(s, 1, 0);
+	}
+
+	/*--- Now the coding tables. ---*/
+	for (t = 0; t < nGroups; t++) {
+		int32_t curr = s->len[t][0];
+		bsW(s, 5, curr);
+		for (i = 0; i < alphaSize; i++) {
+			while (curr < s->len[t][i]) { bsW(s, 2, 2); curr++; /* 10 */ };
+			while (curr > s->len[t][i]) { bsW(s, 2, 3); curr--; /* 11 */ };
+			bsW(s, 1, 0);
+		}
+	}
+
+	/*--- And finally, the block data proper ---*/
+	selCtr = 0;
+	gs = 0;
+	while (1) {
+		if (gs >= s->nMTF)
+			break;
+		ge = gs + BZ_G_SIZE - 1;
+		if (ge >= s->nMTF)
+			ge = s->nMTF-1;
+		AssertH(s->selector[selCtr] < nGroups, 3006);
+
+/* Costs 1300 bytes and is _slower_ (on Intel Core 2) */
+#if 0
+		if (nGroups == 6 && 50 == ge-gs+1) {
+			/*--- fast track the common case ---*/
+			uint16_t mtfv_i;
+			uint8_t* s_len_sel_selCtr  = &(s->len[s->selector[selCtr]][0]);
+			int32_t* s_code_sel_selCtr = &(s->code[s->selector[selCtr]][0]);
+#define BZ_ITAH(nn) \
+	mtfv_i = mtfv[gs+(nn)]; \
+	bsW(s, s_len_sel_selCtr[mtfv_i], s_code_sel_selCtr[mtfv_i])
+			BZ_ITAH(0);  BZ_ITAH(1);  BZ_ITAH(2);  BZ_ITAH(3);  BZ_ITAH(4);
+			BZ_ITAH(5);  BZ_ITAH(6);  BZ_ITAH(7);  BZ_ITAH(8);  BZ_ITAH(9);
+			BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
+			BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
+			BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
+			BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
+			BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
+			BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
+			BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
+			BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
+#undef BZ_ITAH
+			gs = ge+1;
+		} else
+#endif
+		{
+			/*--- slow version which correctly handles all situations ---*/
+			/* code is bit bigger, but moves multiply out of the loop */
+			uint8_t* s_len_sel_selCtr  = &(s->len [s->selector[selCtr]][0]);
+			int32_t* s_code_sel_selCtr = &(s->code[s->selector[selCtr]][0]);
+			while (gs <= ge) {
+				bsW(s,
+					s_len_sel_selCtr[mtfv[gs]],
+					s_code_sel_selCtr[mtfv[gs]]
+				);
+				gs++;
+			}
+			/* already is: gs = ge+1; */
+		}
+		selCtr++;
+	}
+	AssertH(selCtr == nSelectors, 3007);
+#undef code
+#undef rfreq
+#undef len_pack
+}
+
+
+/*---------------------------------------------------*/
+static
+void BZ2_compressBlock(EState* s, int is_last_block)
+{
+	if (s->nblock > 0) {
+		BZ_FINALISE_CRC(s->blockCRC);
+		s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
+		s->combinedCRC ^= s->blockCRC;
+		if (s->blockNo > 1)
+			s->numZ = 0;
+
+		BZ2_blockSort(s);
+	}
+
+	s->zbits = &((uint8_t*)s->arr2)[s->nblock];
+
+	/*-- If this is the first block, create the stream header. --*/
+	if (s->blockNo == 1) {
+		BZ2_bsInitWrite(s);
+		/*bsPutU8(s, BZ_HDR_B);*/
+		/*bsPutU8(s, BZ_HDR_Z);*/
+		/*bsPutU8(s, BZ_HDR_h);*/
+		/*bsPutU8(s, BZ_HDR_0 + s->blockSize100k);*/
+		bsPutU32(s, BZ_HDR_BZh0 + s->blockSize100k);
+	}
+
+	if (s->nblock > 0) {
+		/*bsPutU8(s, 0x31);*/
+		/*bsPutU8(s, 0x41);*/
+		/*bsPutU8(s, 0x59);*/
+		/*bsPutU8(s, 0x26);*/
+		bsPutU32(s, 0x31415926);
+		/*bsPutU8(s, 0x53);*/
+		/*bsPutU8(s, 0x59);*/
+		bsPutU16(s, 0x5359);
+
+		/*-- Now the block's CRC, so it is in a known place. --*/
+		bsPutU32(s, s->blockCRC);
+
+		/*
+		 * Now a single bit indicating (non-)randomisation.
+		 * As of version 0.9.5, we use a better sorting algorithm
+		 * which makes randomisation unnecessary.  So always set
+		 * the randomised bit to 'no'.  Of course, the decoder
+		 * still needs to be able to handle randomised blocks
+		 * so as to maintain backwards compatibility with
+		 * older versions of bzip2.
+		 */
+		bsW(s, 1, 0);
+
+		bsW(s, 24, s->origPtr);
+		generateMTFValues(s);
+		sendMTFValues(s);
+	}
+
+	/*-- If this is the last block, add the stream trailer. --*/
+	if (is_last_block) {
+		/*bsPutU8(s, 0x17);*/
+		/*bsPutU8(s, 0x72);*/
+		/*bsPutU8(s, 0x45);*/
+		/*bsPutU8(s, 0x38);*/
+		bsPutU32(s, 0x17724538);
+		/*bsPutU8(s, 0x50);*/
+		/*bsPutU8(s, 0x90);*/
+		bsPutU16(s, 0x5090);
+		bsPutU32(s, s->combinedCRC);
+		bsFinishWrite(s);
+	}
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                        compress.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/busybox-1.19.3/archival/libarchive/bz/huffman.c b/busybox-1.19.3/archival/libarchive/bz/huffman.c
new file mode 100644
index 0000000..676b1af
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/bz/huffman.c
@@ -0,0 +1,229 @@
+/*
+ * bzip2 is written by Julian Seward <jseward@bzip.org>.
+ * Adapted for busybox by Denys Vlasenko <vda.linux@googlemail.com>.
+ * See README and LICENSE files in this directory for more information.
+ */
+
+/*-------------------------------------------------------------*/
+/*--- Huffman coding low-level stuff                        ---*/
+/*---                                             huffman.c ---*/
+/*-------------------------------------------------------------*/
+
+/* ------------------------------------------------------------------
+This file is part of bzip2/libbzip2, a program and library for
+lossless, block-sorting data compression.
+
+bzip2/libbzip2 version 1.0.4 of 20 December 2006
+Copyright (C) 1996-2006 Julian Seward <jseward@bzip.org>
+
+Please read the WARNING, DISCLAIMER and PATENTS sections in the
+README file.
+
+This program is released under the terms of the license contained
+in the file LICENSE.
+------------------------------------------------------------------ */
+
+/* #include "bzlib_private.h" */
+
+/*---------------------------------------------------*/
+#define WEIGHTOF(zz0)  ((zz0) & 0xffffff00)
+#define DEPTHOF(zz1)   ((zz1) & 0x000000ff)
+#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
+
+#define ADDWEIGHTS(zw1,zw2) \
+	(WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
+	(1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
+
+#define UPHEAP(z) \
+{ \
+	int32_t zz, tmp; \
+	zz = z; \
+	tmp = heap[zz]; \
+	while (weight[tmp] < weight[heap[zz >> 1]]) { \
+		heap[zz] = heap[zz >> 1]; \
+		zz >>= 1; \
+	} \
+	heap[zz] = tmp; \
+}
+
+
+/* 90 bytes, 0.3% of overall compress speed */
+#if CONFIG_BZIP2_FEATURE_SPEED >= 1
+
+/* macro works better than inline (gcc 4.2.1) */
+#define DOWNHEAP1(heap, weight, Heap) \
+{ \
+	int32_t zz, yy, tmp; \
+	zz = 1; \
+	tmp = heap[zz]; \
+	while (1) { \
+		yy = zz << 1; \
+		if (yy > nHeap) \
+			break; \
+		if (yy < nHeap \
+		 && weight[heap[yy+1]] < weight[heap[yy]]) \
+			yy++; \
+		if (weight[tmp] < weight[heap[yy]]) \
+			break; \
+		heap[zz] = heap[yy]; \
+		zz = yy; \
+	} \
+	heap[zz] = tmp; \
+}
+
+#else
+
+static
+void DOWNHEAP1(int32_t *heap, int32_t *weight, int32_t nHeap)
+{
+	int32_t zz, yy, tmp;
+	zz = 1;
+	tmp = heap[zz];
+	while (1) {
+		yy = zz << 1;
+		if (yy > nHeap)
+			break;
+		if (yy < nHeap
+		 && weight[heap[yy + 1]] < weight[heap[yy]])
+			yy++;
+		if (weight[tmp] < weight[heap[yy]])
+			break;
+		heap[zz] = heap[yy];
+		zz = yy;
+	}
+	heap[zz] = tmp;
+}
+
+#endif
+
+/*---------------------------------------------------*/
+static
+void BZ2_hbMakeCodeLengths(EState *s,
+		uint8_t *len,
+		int32_t *freq,
+		int32_t alphaSize,
+		int32_t maxLen)
+{
+	/*
+	 * Nodes and heap entries run from 1.  Entry 0
+	 * for both the heap and nodes is a sentinel.
+	 */
+	int32_t nNodes, nHeap, n1, n2, i, j, k;
+	Bool  tooLong;
+
+	/* bbox: moved to EState to save stack
+	int32_t heap  [BZ_MAX_ALPHA_SIZE + 2];
+	int32_t weight[BZ_MAX_ALPHA_SIZE * 2];
+	int32_t parent[BZ_MAX_ALPHA_SIZE * 2];
+	*/
+#define heap   (s->BZ2_hbMakeCodeLengths__heap)
+#define weight (s->BZ2_hbMakeCodeLengths__weight)
+#define parent (s->BZ2_hbMakeCodeLengths__parent)
+
+	for (i = 0; i < alphaSize; i++)
+		weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
+
+	while (1) {
+		nNodes = alphaSize;
+		nHeap = 0;
+
+		heap[0] = 0;
+		weight[0] = 0;
+		parent[0] = -2;
+
+		for (i = 1; i <= alphaSize; i++) {
+			parent[i] = -1;
+			nHeap++;
+			heap[nHeap] = i;
+			UPHEAP(nHeap);
+		}
+
+		AssertH(nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001);
+
+		while (nHeap > 1) {
+			n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP1(heap, weight, nHeap);
+			n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP1(heap, weight, nHeap);
+			nNodes++;
+			parent[n1] = parent[n2] = nNodes;
+			weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
+			parent[nNodes] = -1;
+			nHeap++;
+			heap[nHeap] = nNodes;
+			UPHEAP(nHeap);
+		}
+
+		AssertH(nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002);
+
+		tooLong = False;
+		for (i = 1; i <= alphaSize; i++) {
+			j = 0;
+			k = i;
+			while (parent[k] >= 0) {
+				k = parent[k];
+				j++;
+			}
+			len[i-1] = j;
+			if (j > maxLen)
+				tooLong = True;
+		}
+
+		if (!tooLong)
+			break;
+
+		/* 17 Oct 04: keep-going condition for the following loop used
+		to be 'i < alphaSize', which missed the last element,
+		theoretically leading to the possibility of the compressor
+		looping.  However, this count-scaling step is only needed if
+		one of the generated Huffman code words is longer than
+		maxLen, which up to and including version 1.0.2 was 20 bits,
+		which is extremely unlikely.  In version 1.0.3 maxLen was
+		changed to 17 bits, which has minimal effect on compression
+		ratio, but does mean this scaling step is used from time to
+		time, enough to verify that it works.
+
+		This means that bzip2-1.0.3 and later will only produce
+		Huffman codes with a maximum length of 17 bits.  However, in
+		order to preserve backwards compatibility with bitstreams
+		produced by versions pre-1.0.3, the decompressor must still
+		handle lengths of up to 20. */
+
+		for (i = 1; i <= alphaSize; i++) {
+			j = weight[i] >> 8;
+			/* bbox: yes, it is a signed division.
+			 * don't replace with shift! */
+			j = 1 + (j / 2);
+			weight[i] = j << 8;
+		}
+	}
+#undef heap
+#undef weight
+#undef parent
+}
+
+
+/*---------------------------------------------------*/
+static
+void BZ2_hbAssignCodes(int32_t *code,
+		uint8_t *length,
+		int32_t minLen,
+		int32_t maxLen,
+		int32_t alphaSize)
+{
+	int32_t n, vec, i;
+
+	vec = 0;
+	for (n = minLen; n <= maxLen; n++) {
+		for (i = 0; i < alphaSize; i++) {
+			if (length[i] == n) {
+				code[i] = vec;
+				vec++;
+			};
+		}
+		vec <<= 1;
+	}
+}
+
+
+/*-------------------------------------------------------------*/
+/*--- end                                         huffman.c ---*/
+/*-------------------------------------------------------------*/
diff --git a/busybox-1.19.3/archival/libarchive/data_align.c b/busybox-1.19.3/archival/libarchive/data_align.c
new file mode 100644
index 0000000..2e56fa8
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/data_align.c
@@ -0,0 +1,15 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#include "libbb.h"
+#include "archive.h"
+
+void FAST_FUNC data_align(archive_handle_t *archive_handle, unsigned boundary)
+{
+	unsigned skip_amount = (boundary - (archive_handle->offset % boundary)) % boundary;
+
+	archive_handle->seek(archive_handle->src_fd, skip_amount);
+	archive_handle->offset += skip_amount;
+}
diff --git a/busybox-1.19.3/archival/libarchive/data_extract_all.c b/busybox-1.19.3/archival/libarchive/data_extract_all.c
new file mode 100644
index 0000000..1b25c8b
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/data_extract_all.c
@@ -0,0 +1,200 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#include "libbb.h"
+#include "archive.h"
+
+void FAST_FUNC data_extract_all(archive_handle_t *archive_handle)
+{
+	file_header_t *file_header = archive_handle->file_header;
+	int dst_fd;
+	int res;
+
+#if ENABLE_FEATURE_TAR_SELINUX
+	char *sctx = archive_handle->tar__next_file_sctx;
+	if (!sctx)
+		sctx = archive_handle->tar__global_sctx;
+	if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
+		setfscreatecon(sctx);
+		free(archive_handle->tar__next_file_sctx);
+		archive_handle->tar__next_file_sctx = NULL;
+	}
+#endif
+
+	if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) {
+		char *slash = strrchr(file_header->name, '/');
+		if (slash) {
+			*slash = '\0';
+			bb_make_directory(file_header->name, -1, FILEUTILS_RECUR);
+			*slash = '/';
+		}
+	}
+
+	if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) {
+		/* Remove the entry if it exists */
+		if (!S_ISDIR(file_header->mode)) {
+			/* Is it hardlink?
+			 * We encode hard links as regular files of size 0 with a symlink */
+			if (S_ISREG(file_header->mode)
+			 && file_header->link_target
+			 && file_header->size == 0
+			) {
+				/* Ugly special case:
+				 * tar cf t.tar hardlink1 hardlink2 hardlink1
+				 * results in this tarball structure:
+				 * hardlink1
+				 * hardlink2 -> hardlink1
+				 * hardlink1 -> hardlink1 <== !!!
+				 */
+				if (strcmp(file_header->link_target, file_header->name) == 0)
+					goto ret;
+			}
+			/* Proceed with deleting */
+			if (unlink(file_header->name) == -1
+			 && errno != ENOENT
+			) {
+				bb_perror_msg_and_die("can't remove old file %s",
+						file_header->name);
+			}
+		}
+	}
+	else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) {
+		/* Remove the existing entry if its older than the extracted entry */
+		struct stat existing_sb;
+		if (lstat(file_header->name, &existing_sb) == -1) {
+			if (errno != ENOENT) {
+				bb_perror_msg_and_die("can't stat old file");
+			}
+		}
+		else if (existing_sb.st_mtime >= file_header->mtime) {
+			if (!(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
+			 && !S_ISDIR(file_header->mode)
+			) {
+				bb_error_msg("%s not created: newer or "
+					"same age file exists", file_header->name);
+			}
+			data_skip(archive_handle);
+			goto ret;
+		}
+		else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) {
+			bb_perror_msg_and_die("can't remove old file %s",
+					file_header->name);
+		}
+	}
+
+	/* Handle hard links separately
+	 * We encode hard links as regular files of size 0 with a symlink */
+	if (S_ISREG(file_header->mode)
+	 && file_header->link_target
+	 && file_header->size == 0
+	) {
+		/* hard link */
+		res = link(file_header->link_target, file_header->name);
+		if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) {
+			bb_perror_msg("can't create %slink "
+					"from %s to %s", "hard",
+					file_header->name,
+					file_header->link_target);
+		}
+		/* Hardlinks have no separate mode/ownership, skip chown/chmod */
+		goto ret;
+	}
+
+	/* Create the filesystem entry */
+	switch (file_header->mode & S_IFMT) {
+	case S_IFREG: {
+		/* Regular file */
+		int flags = O_WRONLY | O_CREAT | O_EXCL;
+		if (archive_handle->ah_flags & ARCHIVE_O_TRUNC)
+			flags = O_WRONLY | O_CREAT | O_TRUNC;
+		dst_fd = xopen3(file_header->name,
+			flags,
+			file_header->mode
+			);
+		bb_copyfd_exact_size(archive_handle->src_fd, dst_fd, file_header->size);
+		close(dst_fd);
+		break;
+	}
+	case S_IFDIR:
+		res = mkdir(file_header->name, file_header->mode);
+		if ((res == -1)
+		 && (errno != EISDIR) /* btw, Linux doesn't return this */
+		 && (errno != EEXIST)
+		 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
+		) {
+			bb_perror_msg("can't make dir %s", file_header->name);
+		}
+		break;
+	case S_IFLNK:
+		/* Symlink */
+//TODO: what if file_header->link_target == NULL (say, corrupted tarball?)
+		res = symlink(file_header->link_target, file_header->name);
+		if ((res == -1)
+		 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
+		) {
+			bb_perror_msg("can't create %slink "
+				"from %s to %s", "sym",
+				file_header->name,
+				file_header->link_target);
+		}
+		break;
+	case S_IFSOCK:
+	case S_IFBLK:
+	case S_IFCHR:
+	case S_IFIFO:
+		res = mknod(file_header->name, file_header->mode, file_header->device);
+		if ((res == -1)
+		 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)
+		) {
+			bb_perror_msg("can't create node %s", file_header->name);
+		}
+		break;
+	default:
+		bb_error_msg_and_die("unrecognized file type");
+	}
+
+	if (!S_ISLNK(file_header->mode)) {
+		if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_OWNER)) {
+			uid_t uid = file_header->uid;
+			gid_t gid = file_header->gid;
+#if ENABLE_FEATURE_TAR_UNAME_GNAME
+			if (!(archive_handle->ah_flags & ARCHIVE_NUMERIC_OWNER)) {
+				if (file_header->tar__uname) {
+//TODO: cache last name/id pair?
+					struct passwd *pwd = getpwnam(file_header->tar__uname);
+					if (pwd) uid = pwd->pw_uid;
+				}
+				if (file_header->tar__gname) {
+					struct group *grp = getgrnam(file_header->tar__gname);
+					if (grp) gid = grp->gr_gid;
+				}
+			}
+#endif
+			/* GNU tar 1.15.1 uses chown, not lchown */
+			chown(file_header->name, uid, gid);
+		}
+		/* uclibc has no lchmod, glibc is even stranger -
+		 * it has lchmod which seems to do nothing!
+		 * so we use chmod... */
+		if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) {
+			chmod(file_header->name, file_header->mode);
+		}
+		if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) {
+			struct timeval t[2];
+
+			t[1].tv_sec = t[0].tv_sec = file_header->mtime;
+			t[1].tv_usec = t[0].tv_usec = 0;
+			utimes(file_header->name, t);
+		}
+	}
+
+ ret: ;
+#if ENABLE_FEATURE_TAR_SELINUX
+	if (sctx) {
+		/* reset the context after creating an entry */
+		setfscreatecon(NULL);
+	}
+#endif
+}
diff --git a/busybox-1.19.3/archival/libarchive/data_extract_to_command.c b/busybox-1.19.3/archival/libarchive/data_extract_to_command.c
new file mode 100644
index 0000000..0e97704
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/data_extract_to_command.c
@@ -0,0 +1,138 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#include "libbb.h"
+#include "archive.h"
+
+enum {
+	//TAR_FILETYPE,
+	TAR_MODE,
+	TAR_FILENAME,
+	TAR_REALNAME,
+#if ENABLE_FEATURE_TAR_UNAME_GNAME
+	TAR_UNAME,
+	TAR_GNAME,
+#endif
+	TAR_SIZE,
+	TAR_UID,
+	TAR_GID,
+	TAR_MAX,
+};
+
+static const char *const tar_var[] = {
+	// "FILETYPE",
+	"MODE",
+	"FILENAME",
+	"REALNAME",
+#if ENABLE_FEATURE_TAR_UNAME_GNAME
+	"UNAME",
+	"GNAME",
+#endif
+	"SIZE",
+	"UID",
+	"GID",
+};
+
+static void xputenv(char *str)
+{
+	if (putenv(str))
+		bb_error_msg_and_die(bb_msg_memory_exhausted);
+}
+
+static void str2env(char *env[], int idx, const char *str)
+{
+	env[idx] = xasprintf("TAR_%s=%s", tar_var[idx], str);
+	xputenv(env[idx]);
+}
+
+static void dec2env(char *env[], int idx, unsigned long long val)
+{
+	env[idx] = xasprintf("TAR_%s=%llu", tar_var[idx], val);
+	xputenv(env[idx]);
+}
+
+static void oct2env(char *env[], int idx, unsigned long val)
+{
+	env[idx] = xasprintf("TAR_%s=%lo", tar_var[idx], val);
+	xputenv(env[idx]);
+}
+
+void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle)
+{
+	file_header_t *file_header = archive_handle->file_header;
+
+#if 0 /* do we need this? ENABLE_FEATURE_TAR_SELINUX */
+	char *sctx = archive_handle->tar__next_file_sctx;
+	if (!sctx)
+		sctx = archive_handle->tar__global_sctx;
+	if (sctx) { /* setfscreatecon is 4 syscalls, avoid if possible */
+		setfscreatecon(sctx);
+		free(archive_handle->tar__next_file_sctx);
+		archive_handle->tar__next_file_sctx = NULL;
+	}
+#endif
+
+	if ((file_header->mode & S_IFMT) == S_IFREG) {
+		pid_t pid;
+		int p[2], status;
+		char *tar_env[TAR_MAX];
+
+		memset(tar_env, 0, sizeof(tar_env));
+
+		xpipe(p);
+		pid = BB_MMU ? xfork() : xvfork();
+		if (pid == 0) {
+			/* Child */
+			/* str2env(tar_env, TAR_FILETYPE, "f"); - parent should do it once */
+			oct2env(tar_env, TAR_MODE, file_header->mode);
+			str2env(tar_env, TAR_FILENAME, file_header->name);
+			str2env(tar_env, TAR_REALNAME, file_header->name);
+#if ENABLE_FEATURE_TAR_UNAME_GNAME
+			str2env(tar_env, TAR_UNAME, file_header->tar__uname);
+			str2env(tar_env, TAR_GNAME, file_header->tar__gname);
+#endif
+			dec2env(tar_env, TAR_SIZE, file_header->size);
+			dec2env(tar_env, TAR_UID, file_header->uid);
+			dec2env(tar_env, TAR_GID, file_header->gid);
+			close(p[1]);
+			xdup2(p[0], STDIN_FILENO);
+			signal(SIGPIPE, SIG_DFL);
+			execl(archive_handle->tar__to_command_shell,
+				archive_handle->tar__to_command_shell,
+				"-c",
+				archive_handle->tar__to_command,
+				NULL);
+			bb_perror_msg_and_die("can't execute '%s'", archive_handle->tar__to_command_shell);
+		}
+		close(p[0]);
+		/* Our caller is expected to do signal(SIGPIPE, SIG_IGN)
+		 * so that we don't die if child don't read all the input: */
+		bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size);
+		close(p[1]);
+
+		if (safe_waitpid(pid, &status, 0) == -1)
+			bb_perror_msg_and_die("waitpid");
+		if (WIFEXITED(status) && WEXITSTATUS(status))
+			bb_error_msg_and_die("'%s' returned status %d",
+				archive_handle->tar__to_command, WEXITSTATUS(status));
+		if (WIFSIGNALED(status))
+			bb_error_msg_and_die("'%s' terminated on signal %d",
+				archive_handle->tar__to_command, WTERMSIG(status));
+
+		if (!BB_MMU) {
+			int i;
+			for (i = 0; i < TAR_MAX; i++) {
+				if (tar_env[i])
+					bb_unsetenv_and_free(tar_env[i]);
+			}
+		}
+	}
+
+#if 0 /* ENABLE_FEATURE_TAR_SELINUX */
+	if (sctx)
+		/* reset the context after creating an entry */
+		setfscreatecon(NULL);
+#endif
+}
diff --git a/busybox-1.19.3/archival/libarchive/data_extract_to_stdout.c b/busybox-1.19.3/archival/libarchive/data_extract_to_stdout.c
new file mode 100644
index 0000000..91f3f35
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/data_extract_to_stdout.c
@@ -0,0 +1,14 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#include "libbb.h"
+#include "archive.h"
+
+void FAST_FUNC data_extract_to_stdout(archive_handle_t *archive_handle)
+{
+	bb_copyfd_exact_size(archive_handle->src_fd,
+			STDOUT_FILENO,
+			archive_handle->file_header->size);
+}
diff --git a/busybox-1.19.3/archival/libarchive/data_skip.c b/busybox-1.19.3/archival/libarchive/data_skip.c
new file mode 100644
index 0000000..a055424
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/data_skip.c
@@ -0,0 +1,12 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#include "libbb.h"
+#include "archive.h"
+
+void FAST_FUNC data_skip(archive_handle_t *archive_handle)
+{
+	archive_handle->seek(archive_handle->src_fd, archive_handle->file_header->size);
+}
diff --git a/busybox-1.19.3/archival/libarchive/decompress_bunzip2.c b/busybox-1.19.3/archival/libarchive/decompress_bunzip2.c
new file mode 100644
index 0000000..4e46e68
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/decompress_bunzip2.c
@@ -0,0 +1,822 @@
+/* vi: set sw=4 ts=4: */
+/* Small bzip2 deflate implementation, by Rob Landley (rob@landley.net).
+
+   Based on bzip2 decompression code by Julian R Seward (jseward@acm.org),
+   which also acknowledges contributions by Mike Burrows, David Wheeler,
+   Peter Fenwick, Alistair Moffat, Radford Neal, Ian H. Witten,
+   Robert Sedgewick, and Jon L. Bentley.
+
+   Licensed under GPLv2 or later, see file LICENSE in this source tree.
+*/
+
+/*
+	Size and speed optimizations by Manuel Novoa III  (mjn3@codepoet.org).
+
+	More efficient reading of Huffman codes, a streamlined read_bunzip()
+	function, and various other tweaks.  In (limited) tests, approximately
+	20% faster than bzcat on x86 and about 10% faster on arm.
+
+	Note that about 2/3 of the time is spent in read_bunzip() reversing
+	the Burrows-Wheeler transformation.  Much of that time is delay
+	resulting from cache misses.
+
+	(2010 update by vda: profiled "bzcat <84mbyte.bz2 >/dev/null"
+	on x86-64 CPU with L2 > 1M: get_next_block is hotter than read_bunzip:
+	%time seconds   calls function
+	71.01   12.69     444 get_next_block
+	28.65    5.12   93065 read_bunzip
+	00.22    0.04 7736490 get_bits
+	00.11    0.02      47 dealloc_bunzip
+	00.00    0.00   93018 full_write
+	...)
+
+
+	I would ask that anyone benefiting from this work, especially those
+	using it in commercial products, consider making a donation to my local
+	non-profit hospice organization (www.hospiceacadiana.com) in the name of
+	the woman I loved, Toni W. Hagan, who passed away Feb. 12, 2003.
+
+	Manuel
+ */
+
+#include "libbb.h"
+#include "archive.h"
+
+/* Constants for Huffman coding */
+#define MAX_GROUPS          6
+#define GROUP_SIZE          50      /* 64 would have been more efficient */
+#define MAX_HUFCODE_BITS    20      /* Longest Huffman code allowed */
+#define MAX_SYMBOLS         258     /* 256 literals + RUNA + RUNB */
+#define SYMBOL_RUNA         0
+#define SYMBOL_RUNB         1
+
+/* Status return values */
+#define RETVAL_OK                       0
+#define RETVAL_LAST_BLOCK               (-1)
+#define RETVAL_NOT_BZIP_DATA            (-2)
+#define RETVAL_UNEXPECTED_INPUT_EOF     (-3)
+#define RETVAL_SHORT_WRITE              (-4)
+#define RETVAL_DATA_ERROR               (-5)
+#define RETVAL_OUT_OF_MEMORY            (-6)
+#define RETVAL_OBSOLETE_INPUT           (-7)
+
+/* Other housekeeping constants */
+#define IOBUF_SIZE          4096
+
+/* This is what we know about each Huffman coding group */
+struct group_data {
+	/* We have an extra slot at the end of limit[] for a sentinel value. */
+	int limit[MAX_HUFCODE_BITS+1], base[MAX_HUFCODE_BITS], permute[MAX_SYMBOLS];
+	int minLen, maxLen;
+};
+
+/* Structure holding all the housekeeping data, including IO buffers and
+ * memory that persists between calls to bunzip
+ * Found the most used member:
+ *  cat this_file.c | sed -e 's/"/ /g' -e "s/'/ /g" | xargs -n1 \
+ *  | grep 'bd->' | sed 's/^.*bd->/bd->/' | sort | $PAGER
+ * and moved it (inbufBitCount) to offset 0.
+ */
+struct bunzip_data {
+	/* I/O tracking data (file handles, buffers, positions, etc.) */
+	unsigned inbufBitCount, inbufBits;
+	int in_fd, out_fd, inbufCount, inbufPos /*, outbufPos*/;
+	uint8_t *inbuf /*,*outbuf*/;
+
+	/* State for interrupting output loop */
+	int writeCopies, writePos, writeRunCountdown, writeCount;
+	int writeCurrent; /* actually a uint8_t */
+
+	/* The CRC values stored in the block header and calculated from the data */
+	uint32_t headerCRC, totalCRC, writeCRC;
+
+	/* Intermediate buffer and its size (in bytes) */
+	uint32_t *dbuf;
+	unsigned dbufSize;
+
+	/* For I/O error handling */
+	jmp_buf jmpbuf;
+
+	/* Big things go last (register-relative addressing can be larger for big offsets) */
+	uint32_t crc32Table[256];
+	uint8_t selectors[32768];  /* nSelectors=15 bits */
+	struct group_data groups[MAX_GROUPS];  /* Huffman coding tables */
+};
+/* typedef struct bunzip_data bunzip_data; -- done in .h file */
+
+
+/* Return the next nnn bits of input.  All reads from the compressed input
+   are done through this function.  All reads are big endian */
+static unsigned get_bits(bunzip_data *bd, int bits_wanted)
+{
+	unsigned bits = 0;
+	/* Cache bd->inbufBitCount in a CPU register (hopefully): */
+	int bit_count = bd->inbufBitCount;
+
+	/* If we need to get more data from the byte buffer, do so.  (Loop getting
+	   one byte at a time to enforce endianness and avoid unaligned access.) */
+	while (bit_count < bits_wanted) {
+
+		/* If we need to read more data from file into byte buffer, do so */
+		if (bd->inbufPos == bd->inbufCount) {
+			/* if "no input fd" case: in_fd == -1, read fails, we jump */
+			bd->inbufCount = read(bd->in_fd, bd->inbuf, IOBUF_SIZE);
+			if (bd->inbufCount <= 0)
+				longjmp(bd->jmpbuf, RETVAL_UNEXPECTED_INPUT_EOF);
+			bd->inbufPos = 0;
+		}
+
+		/* Avoid 32-bit overflow (dump bit buffer to top of output) */
+		if (bit_count >= 24) {
+			bits = bd->inbufBits & ((1 << bit_count) - 1);
+			bits_wanted -= bit_count;
+			bits <<= bits_wanted;
+			bit_count = 0;
+		}
+
+		/* Grab next 8 bits of input from buffer. */
+		bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++];
+		bit_count += 8;
+	}
+
+	/* Calculate result */
+	bit_count -= bits_wanted;
+	bd->inbufBitCount = bit_count;
+	bits |= (bd->inbufBits >> bit_count) & ((1 << bits_wanted) - 1);
+
+	return bits;
+}
+
+/* Unpacks the next block and sets up for the inverse Burrows-Wheeler step. */
+static int get_next_block(bunzip_data *bd)
+{
+	struct group_data *hufGroup;
+	int dbufCount, dbufSize, groupCount, *base, *limit, selector,
+		i, j, t, runPos, symCount, symTotal, nSelectors, byteCount[256];
+	int runCnt = runCnt; /* for compiler */
+	uint8_t uc, symToByte[256], mtfSymbol[256], *selectors;
+	uint32_t *dbuf;
+	unsigned origPtr;
+
+	dbuf = bd->dbuf;
+	dbufSize = bd->dbufSize;
+	selectors = bd->selectors;
+
+/* In bbox, we are ok with aborting through setjmp which is set up in start_bunzip */
+#if 0
+	/* Reset longjmp I/O error handling */
+	i = setjmp(bd->jmpbuf);
+	if (i) return i;
+#endif
+
+	/* Read in header signature and CRC, then validate signature.
+	   (last block signature means CRC is for whole file, return now) */
+	i = get_bits(bd, 24);
+	j = get_bits(bd, 24);
+	bd->headerCRC = get_bits(bd, 32);
+	if ((i == 0x177245) && (j == 0x385090)) return RETVAL_LAST_BLOCK;
+	if ((i != 0x314159) || (j != 0x265359)) return RETVAL_NOT_BZIP_DATA;
+
+	/* We can add support for blockRandomised if anybody complains.  There was
+	   some code for this in busybox 1.0.0-pre3, but nobody ever noticed that
+	   it didn't actually work. */
+	if (get_bits(bd, 1)) return RETVAL_OBSOLETE_INPUT;
+	origPtr = get_bits(bd, 24);
+	if ((int)origPtr > dbufSize) return RETVAL_DATA_ERROR;
+
+	/* mapping table: if some byte values are never used (encoding things
+	   like ascii text), the compression code removes the gaps to have fewer
+	   symbols to deal with, and writes a sparse bitfield indicating which
+	   values were present.  We make a translation table to convert the symbols
+	   back to the corresponding bytes. */
+	symTotal = 0;
+	i = 0;
+	t = get_bits(bd, 16);
+	do {
+		if (t & (1 << 15)) {
+			unsigned inner_map = get_bits(bd, 16);
+			do {
+				if (inner_map & (1 << 15))
+					symToByte[symTotal++] = i;
+				inner_map <<= 1;
+				i++;
+			} while (i & 15);
+			i -= 16;
+		}
+		t <<= 1;
+		i += 16;
+	} while (i < 256);
+
+	/* How many different Huffman coding groups does this block use? */
+	groupCount = get_bits(bd, 3);
+	if (groupCount < 2 || groupCount > MAX_GROUPS)
+		return RETVAL_DATA_ERROR;
+
+	/* nSelectors: Every GROUP_SIZE many symbols we select a new Huffman coding
+	   group.  Read in the group selector list, which is stored as MTF encoded
+	   bit runs.  (MTF=Move To Front, as each value is used it's moved to the
+	   start of the list.) */
+	for (i = 0; i < groupCount; i++)
+		mtfSymbol[i] = i;
+	nSelectors = get_bits(bd, 15);
+	if (!nSelectors)
+		return RETVAL_DATA_ERROR;
+	for (i = 0; i < nSelectors; i++) {
+		uint8_t tmp_byte;
+		/* Get next value */
+		int n = 0;
+		while (get_bits(bd, 1)) {
+			if (n >= groupCount) return RETVAL_DATA_ERROR;
+			n++;
+		}
+		/* Decode MTF to get the next selector */
+		tmp_byte = mtfSymbol[n];
+		while (--n >= 0)
+			mtfSymbol[n + 1] = mtfSymbol[n];
+		mtfSymbol[0] = selectors[i] = tmp_byte;
+	}
+
+	/* Read the Huffman coding tables for each group, which code for symTotal
+	   literal symbols, plus two run symbols (RUNA, RUNB) */
+	symCount = symTotal + 2;
+	for (j = 0; j < groupCount; j++) {
+		uint8_t length[MAX_SYMBOLS];
+		/* 8 bits is ALMOST enough for temp[], see below */
+		unsigned temp[MAX_HUFCODE_BITS+1];
+		int minLen, maxLen, pp, len_m1;
+
+		/* Read Huffman code lengths for each symbol.  They're stored in
+		   a way similar to mtf; record a starting value for the first symbol,
+		   and an offset from the previous value for every symbol after that.
+		   (Subtracting 1 before the loop and then adding it back at the end is
+		   an optimization that makes the test inside the loop simpler: symbol
+		   length 0 becomes negative, so an unsigned inequality catches it.) */
+		len_m1 = get_bits(bd, 5) - 1;
+		for (i = 0; i < symCount; i++) {
+			for (;;) {
+				int two_bits;
+				if ((unsigned)len_m1 > (MAX_HUFCODE_BITS-1))
+					return RETVAL_DATA_ERROR;
+
+				/* If first bit is 0, stop.  Else second bit indicates whether
+				   to increment or decrement the value.  Optimization: grab 2
+				   bits and unget the second if the first was 0. */
+				two_bits = get_bits(bd, 2);
+				if (two_bits < 2) {
+					bd->inbufBitCount++;
+					break;
+				}
+
+				/* Add one if second bit 1, else subtract 1.  Avoids if/else */
+				len_m1 += (((two_bits+1) & 2) - 1);
+			}
+
+			/* Correct for the initial -1, to get the final symbol length */
+			length[i] = len_m1 + 1;
+		}
+
+		/* Find largest and smallest lengths in this group */
+		minLen = maxLen = length[0];
+		for (i = 1; i < symCount; i++) {
+			if (length[i] > maxLen) maxLen = length[i];
+			else if (length[i] < minLen) minLen = length[i];
+		}
+
+		/* Calculate permute[], base[], and limit[] tables from length[].
+		 *
+		 * permute[] is the lookup table for converting Huffman coded symbols
+		 * into decoded symbols.  base[] is the amount to subtract from the
+		 * value of a Huffman symbol of a given length when using permute[].
+		 *
+		 * limit[] indicates the largest numerical value a symbol with a given
+		 * number of bits can have.  This is how the Huffman codes can vary in
+		 * length: each code with a value>limit[length] needs another bit.
+		 */
+		hufGroup = bd->groups + j;
+		hufGroup->minLen = minLen;
+		hufGroup->maxLen = maxLen;
+
+		/* Note that minLen can't be smaller than 1, so we adjust the base
+		   and limit array pointers so we're not always wasting the first
+		   entry.  We do this again when using them (during symbol decoding). */
+		base = hufGroup->base - 1;
+		limit = hufGroup->limit - 1;
+
+		/* Calculate permute[].  Concurently, initialize temp[] and limit[]. */
+		pp = 0;
+		for (i = minLen; i <= maxLen; i++) {
+			int k;
+			temp[i] = limit[i] = 0;
+			for (k = 0; k < symCount; k++)
+				if (length[k] == i)
+					hufGroup->permute[pp++] = k;
+		}
+
+		/* Count symbols coded for at each bit length */
+		/* NB: in pathological cases, temp[8] can end ip being 256.
+		 * That's why uint8_t is too small for temp[]. */
+		for (i = 0; i < symCount; i++) temp[length[i]]++;
+
+		/* Calculate limit[] (the largest symbol-coding value at each bit
+		 * length, which is (previous limit<<1)+symbols at this level), and
+		 * base[] (number of symbols to ignore at each bit length, which is
+		 * limit minus the cumulative count of symbols coded for already). */
+		pp = t = 0;
+		for (i = minLen; i < maxLen;) {
+			unsigned temp_i = temp[i];
+
+			pp += temp_i;
+
+			/* We read the largest possible symbol size and then unget bits
+			   after determining how many we need, and those extra bits could
+			   be set to anything.  (They're noise from future symbols.)  At
+			   each level we're really only interested in the first few bits,
+			   so here we set all the trailing to-be-ignored bits to 1 so they
+			   don't affect the value>limit[length] comparison. */
+			limit[i] = (pp << (maxLen - i)) - 1;
+			pp <<= 1;
+			t += temp_i;
+			base[++i] = pp - t;
+		}
+		limit[maxLen] = pp + temp[maxLen] - 1;
+		limit[maxLen+1] = INT_MAX; /* Sentinel value for reading next sym. */
+		base[minLen] = 0;
+	}
+
+	/* We've finished reading and digesting the block header.  Now read this
+	   block's Huffman coded symbols from the file and undo the Huffman coding
+	   and run length encoding, saving the result into dbuf[dbufCount++] = uc */
+
+	/* Initialize symbol occurrence counters and symbol Move To Front table */
+	/*memset(byteCount, 0, sizeof(byteCount)); - smaller, but slower */
+	for (i = 0; i < 256; i++) {
+		byteCount[i] = 0;
+		mtfSymbol[i] = (uint8_t)i;
+	}
+
+	/* Loop through compressed symbols. */
+
+	runPos = dbufCount = selector = 0;
+	for (;;) {
+		int nextSym;
+
+		/* Fetch next Huffman coding group from list. */
+		symCount = GROUP_SIZE - 1;
+		if (selector >= nSelectors) return RETVAL_DATA_ERROR;
+		hufGroup = bd->groups + selectors[selector++];
+		base = hufGroup->base - 1;
+		limit = hufGroup->limit - 1;
+
+ continue_this_group:
+		/* Read next Huffman-coded symbol. */
+
+		/* Note: It is far cheaper to read maxLen bits and back up than it is
+		   to read minLen bits and then add additional bit at a time, testing
+		   as we go.  Because there is a trailing last block (with file CRC),
+		   there is no danger of the overread causing an unexpected EOF for a
+		   valid compressed file.
+		 */
+		if (1) {
+			/* As a further optimization, we do the read inline
+			   (falling back to a call to get_bits if the buffer runs dry).
+			 */
+			int new_cnt;
+			while ((new_cnt = bd->inbufBitCount - hufGroup->maxLen) < 0) {
+				/* bd->inbufBitCount < hufGroup->maxLen */
+				if (bd->inbufPos == bd->inbufCount) {
+					nextSym = get_bits(bd, hufGroup->maxLen);
+					goto got_huff_bits;
+				}
+				bd->inbufBits = (bd->inbufBits << 8) | bd->inbuf[bd->inbufPos++];
+				bd->inbufBitCount += 8;
+			};
+			bd->inbufBitCount = new_cnt; /* "bd->inbufBitCount -= hufGroup->maxLen;" */
+			nextSym = (bd->inbufBits >> new_cnt) & ((1 << hufGroup->maxLen) - 1);
+ got_huff_bits: ;
+		} else { /* unoptimized equivalent */
+			nextSym = get_bits(bd, hufGroup->maxLen);
+		}
+		/* Figure how many bits are in next symbol and unget extras */
+		i = hufGroup->minLen;
+		while (nextSym > limit[i]) ++i;
+		j = hufGroup->maxLen - i;
+		if (j < 0)
+			return RETVAL_DATA_ERROR;
+		bd->inbufBitCount += j;
+
+		/* Huffman decode value to get nextSym (with bounds checking) */
+		nextSym = (nextSym >> j) - base[i];
+		if ((unsigned)nextSym >= MAX_SYMBOLS)
+			return RETVAL_DATA_ERROR;
+		nextSym = hufGroup->permute[nextSym];
+
+		/* We have now decoded the symbol, which indicates either a new literal
+		   byte, or a repeated run of the most recent literal byte.  First,
+		   check if nextSym indicates a repeated run, and if so loop collecting
+		   how many times to repeat the last literal. */
+		if ((unsigned)nextSym <= SYMBOL_RUNB) { /* RUNA or RUNB */
+
+			/* If this is the start of a new run, zero out counter */
+			if (runPos == 0) {
+				runPos = 1;
+				runCnt = 0;
+			}
+
+			/* Neat trick that saves 1 symbol: instead of or-ing 0 or 1 at
+			   each bit position, add 1 or 2 instead.  For example,
+			   1011 is 1<<0 + 1<<1 + 2<<2.  1010 is 2<<0 + 2<<1 + 1<<2.
+			   You can make any bit pattern that way using 1 less symbol than
+			   the basic or 0/1 method (except all bits 0, which would use no
+			   symbols, but a run of length 0 doesn't mean anything in this
+			   context).  Thus space is saved. */
+			runCnt += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */
+			if (runPos < dbufSize) runPos <<= 1;
+			goto end_of_huffman_loop;
+		}
+
+		/* When we hit the first non-run symbol after a run, we now know
+		   how many times to repeat the last literal, so append that many
+		   copies to our buffer of decoded symbols (dbuf) now.  (The last
+		   literal used is the one at the head of the mtfSymbol array.) */
+		if (runPos != 0) {
+			uint8_t tmp_byte;
+			if (dbufCount + runCnt >= dbufSize) return RETVAL_DATA_ERROR;
+			tmp_byte = symToByte[mtfSymbol[0]];
+			byteCount[tmp_byte] += runCnt;
+			while (--runCnt >= 0) dbuf[dbufCount++] = (uint32_t)tmp_byte;
+			runPos = 0;
+		}
+
+		/* Is this the terminating symbol? */
+		if (nextSym > symTotal) break;
+
+		/* At this point, nextSym indicates a new literal character.  Subtract
+		   one to get the position in the MTF array at which this literal is
+		   currently to be found.  (Note that the result can't be -1 or 0,
+		   because 0 and 1 are RUNA and RUNB.  But another instance of the
+		   first symbol in the mtf array, position 0, would have been handled
+		   as part of a run above.  Therefore 1 unused mtf position minus
+		   2 non-literal nextSym values equals -1.) */
+		if (dbufCount >= dbufSize) return RETVAL_DATA_ERROR;
+		i = nextSym - 1;
+		uc = mtfSymbol[i];
+
+		/* Adjust the MTF array.  Since we typically expect to move only a
+		 * small number of symbols, and are bound by 256 in any case, using
+		 * memmove here would typically be bigger and slower due to function
+		 * call overhead and other assorted setup costs. */
+		do {
+			mtfSymbol[i] = mtfSymbol[i-1];
+		} while (--i);
+		mtfSymbol[0] = uc;
+		uc = symToByte[uc];
+
+		/* We have our literal byte.  Save it into dbuf. */
+		byteCount[uc]++;
+		dbuf[dbufCount++] = (uint32_t)uc;
+
+		/* Skip group initialization if we're not done with this group.  Done
+		 * this way to avoid compiler warning. */
+ end_of_huffman_loop:
+		if (--symCount >= 0) goto continue_this_group;
+	}
+
+	/* At this point, we've read all the Huffman-coded symbols (and repeated
+	   runs) for this block from the input stream, and decoded them into the
+	   intermediate buffer.  There are dbufCount many decoded bytes in dbuf[].
+	   Now undo the Burrows-Wheeler transform on dbuf.
+	   See http://dogma.net/markn/articles/bwt/bwt.htm
+	 */
+
+	/* Turn byteCount into cumulative occurrence counts of 0 to n-1. */
+	j = 0;
+	for (i = 0; i < 256; i++) {
+		int tmp_count = j + byteCount[i];
+		byteCount[i] = j;
+		j = tmp_count;
+	}
+
+	/* Figure out what order dbuf would be in if we sorted it. */
+	for (i = 0; i < dbufCount; i++) {
+		uint8_t tmp_byte = (uint8_t)dbuf[i];
+		int tmp_count = byteCount[tmp_byte];
+		dbuf[tmp_count] |= (i << 8);
+		byteCount[tmp_byte] = tmp_count + 1;
+	}
+
+	/* Decode first byte by hand to initialize "previous" byte.  Note that it
+	   doesn't get output, and if the first three characters are identical
+	   it doesn't qualify as a run (hence writeRunCountdown=5). */
+	if (dbufCount) {
+		uint32_t tmp;
+		if ((int)origPtr >= dbufCount) return RETVAL_DATA_ERROR;
+		tmp = dbuf[origPtr];
+		bd->writeCurrent = (uint8_t)tmp;
+		bd->writePos = (tmp >> 8);
+		bd->writeRunCountdown = 5;
+	}
+	bd->writeCount = dbufCount;
+
+	return RETVAL_OK;
+}
+
+/* Undo Burrows-Wheeler transform on intermediate buffer to produce output.
+   If start_bunzip was initialized with out_fd=-1, then up to len bytes of
+   data are written to outbuf.  Return value is number of bytes written or
+   error (all errors are negative numbers).  If out_fd!=-1, outbuf and len
+   are ignored, data is written to out_fd and return is RETVAL_OK or error.
+
+   NB: read_bunzip returns < 0 on error, or the number of *unfilled* bytes
+   in outbuf. IOW: on EOF returns len ("all bytes are not filled"), not 0.
+   (Why? This allows to get rid of one local variable)
+*/
+int FAST_FUNC read_bunzip(bunzip_data *bd, char *outbuf, int len)
+{
+	const uint32_t *dbuf;
+	int pos, current, previous;
+	uint32_t CRC;
+
+	/* If we already have error/end indicator, return it */
+	if (bd->writeCount < 0)
+		return bd->writeCount;
+
+	dbuf = bd->dbuf;
+
+	/* Register-cached state (hopefully): */
+	pos = bd->writePos;
+	current = bd->writeCurrent;
+	CRC = bd->writeCRC; /* small loss on x86-32 (not enough regs), win on x86-64 */
+
+	/* We will always have pending decoded data to write into the output
+	   buffer unless this is the very first call (in which case we haven't
+	   Huffman-decoded a block into the intermediate buffer yet). */
+	if (bd->writeCopies) {
+
+ dec_writeCopies:
+		/* Inside the loop, writeCopies means extra copies (beyond 1) */
+		--bd->writeCopies;
+
+		/* Loop outputting bytes */
+		for (;;) {
+
+			/* If the output buffer is full, save cached state and return */
+			if (--len < 0) {
+				/* Unlikely branch.
+				 * Use of "goto" instead of keeping code here
+				 * helps compiler to realize this. */
+				goto outbuf_full;
+			}
+
+			/* Write next byte into output buffer, updating CRC */
+			*outbuf++ = current;
+			CRC = (CRC << 8) ^ bd->crc32Table[(CRC >> 24) ^ current];
+
+			/* Loop now if we're outputting multiple copies of this byte */
+			if (bd->writeCopies) {
+				/* Unlikely branch */
+				/*--bd->writeCopies;*/
+				/*continue;*/
+				/* Same, but (ab)using other existing --writeCopies operation
+				 * (and this if() compiles into just test+branch pair): */
+				goto dec_writeCopies;
+			}
+ decode_next_byte:
+			if (--bd->writeCount < 0)
+				break; /* input block is fully consumed, need next one */
+
+			/* Follow sequence vector to undo Burrows-Wheeler transform */
+			previous = current;
+			pos = dbuf[pos];
+			current = (uint8_t)pos;
+			pos >>= 8;
+
+			/* After 3 consecutive copies of the same byte, the 4th
+			 * is a repeat count.  We count down from 4 instead
+			 * of counting up because testing for non-zero is faster */
+			if (--bd->writeRunCountdown != 0) {
+				if (current != previous)
+					bd->writeRunCountdown = 4;
+			} else {
+				/* Unlikely branch */
+				/* We have a repeated run, this byte indicates the count */
+				bd->writeCopies = current;
+				current = previous;
+				bd->writeRunCountdown = 5;
+
+				/* Sometimes there are just 3 bytes (run length 0) */
+				if (!bd->writeCopies) goto decode_next_byte;
+
+				/* Subtract the 1 copy we'd output anyway to get extras */
+				--bd->writeCopies;
+			}
+		} /* for(;;) */
+
+		/* Decompression of this input block completed successfully */
+		bd->writeCRC = CRC = ~CRC;
+		bd->totalCRC = ((bd->totalCRC << 1) | (bd->totalCRC >> 31)) ^ CRC;
+
+		/* If this block had a CRC error, force file level CRC error */
+		if (CRC != bd->headerCRC) {
+			bd->totalCRC = bd->headerCRC + 1;
+			return RETVAL_LAST_BLOCK;
+		}
+	}
+
+	/* Refill the intermediate buffer by Huffman-decoding next block of input */
+	{
+		int r = get_next_block(bd);
+		if (r) { /* error/end */
+			bd->writeCount = r;
+			return (r != RETVAL_LAST_BLOCK) ? r : len;
+		}
+	}
+
+	CRC = ~0;
+	pos = bd->writePos;
+	current = bd->writeCurrent;
+	goto decode_next_byte;
+
+ outbuf_full:
+	/* Output buffer is full, save cached state and return */
+	bd->writePos = pos;
+	bd->writeCurrent = current;
+	bd->writeCRC = CRC;
+
+	bd->writeCopies++;
+
+	return 0;
+}
+
+/* Allocate the structure, read file header.  If in_fd==-1, inbuf must contain
+   a complete bunzip file (len bytes long).  If in_fd!=-1, inbuf and len are
+   ignored, and data is read from file handle into temporary buffer. */
+
+/* Because bunzip2 is used for help text unpacking, and because bb_show_usage()
+   should work for NOFORK applets too, we must be extremely careful to not leak
+   any allocations! */
+int FAST_FUNC start_bunzip(bunzip_data **bdp, int in_fd,
+		const void *inbuf, int len)
+{
+	bunzip_data *bd;
+	unsigned i;
+	enum {
+		BZh0 = ('B' << 24) + ('Z' << 16) + ('h' << 8) + '0',
+		h0 = ('h' << 8) + '0',
+	};
+
+	/* Figure out how much data to allocate */
+	i = sizeof(bunzip_data);
+	if (in_fd != -1) i += IOBUF_SIZE;
+
+	/* Allocate bunzip_data.  Most fields initialize to zero. */
+	bd = *bdp = xzalloc(i);
+
+	/* Setup input buffer */
+	bd->in_fd = in_fd;
+	if (-1 == in_fd) {
+		/* in this case, bd->inbuf is read-only */
+		bd->inbuf = (void*)inbuf; /* cast away const-ness */
+	} else {
+		bd->inbuf = (uint8_t*)(bd + 1);
+		memcpy(bd->inbuf, inbuf, len);
+	}
+	bd->inbufCount = len;
+
+	/* Init the CRC32 table (big endian) */
+	crc32_filltable(bd->crc32Table, 1);
+
+	/* Setup for I/O error handling via longjmp */
+	i = setjmp(bd->jmpbuf);
+	if (i) return i;
+
+	/* Ensure that file starts with "BZh['1'-'9']." */
+	/* Update: now caller verifies 1st two bytes, makes .gz/.bz2
+	 * integration easier */
+	/* was: */
+	/* i = get_bits(bd, 32); */
+	/* if ((unsigned)(i - BZh0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA; */
+	i = get_bits(bd, 16);
+	if ((unsigned)(i - h0 - 1) >= 9) return RETVAL_NOT_BZIP_DATA;
+
+	/* Fourth byte (ascii '1'-'9') indicates block size in units of 100k of
+	   uncompressed data.  Allocate intermediate buffer for block. */
+	/* bd->dbufSize = 100000 * (i - BZh0); */
+	bd->dbufSize = 100000 * (i - h0);
+
+	/* Cannot use xmalloc - may leak bd in NOFORK case! */
+	bd->dbuf = malloc_or_warn(bd->dbufSize * sizeof(bd->dbuf[0]));
+	if (!bd->dbuf) {
+		free(bd);
+		xfunc_die();
+	}
+	return RETVAL_OK;
+}
+
+void FAST_FUNC dealloc_bunzip(bunzip_data *bd)
+{
+	free(bd->dbuf);
+	free(bd);
+}
+
+
+/* Decompress src_fd to dst_fd.  Stops at end of bzip data, not end of file. */
+IF_DESKTOP(long long) int FAST_FUNC
+unpack_bz2_stream(int src_fd, int dst_fd)
+{
+	IF_DESKTOP(long long total_written = 0;)
+	bunzip_data *bd;
+	char *outbuf;
+	int i;
+	unsigned len;
+
+	outbuf = xmalloc(IOBUF_SIZE);
+	len = 0;
+	while (1) { /* "Process one BZ... stream" loop */
+
+		i = start_bunzip(&bd, src_fd, outbuf + 2, len);
+
+		if (i == 0) {
+			while (1) { /* "Produce some output bytes" loop */
+				i = read_bunzip(bd, outbuf, IOBUF_SIZE);
+				if (i < 0) /* error? */
+					break;
+				i = IOBUF_SIZE - i; /* number of bytes produced */
+				if (i == 0) /* EOF? */
+					break;
+				if (i != full_write(dst_fd, outbuf, i)) {
+					bb_error_msg("short write");
+					i = RETVAL_SHORT_WRITE;
+					goto release_mem;
+				}
+				IF_DESKTOP(total_written += i;)
+			}
+		}
+
+		if (i != RETVAL_LAST_BLOCK) {
+			bb_error_msg("bunzip error %d", i);
+			break;
+		}
+		if (bd->headerCRC != bd->totalCRC) {
+			bb_error_msg("CRC error");
+			break;
+		}
+
+		/* Successfully unpacked one BZ stream */
+		i = RETVAL_OK;
+
+		/* Do we have "BZ..." after last processed byte?
+		 * pbzip2 (parallelized bzip2) produces such files.
+		 */
+		len = bd->inbufCount - bd->inbufPos;
+		memcpy(outbuf, &bd->inbuf[bd->inbufPos], len);
+		if (len < 2) {
+			if (safe_read(src_fd, outbuf + len, 2 - len) != 2 - len)
+				break;
+			len = 2;
+		}
+		if (*(uint16_t*)outbuf != BZIP2_MAGIC) /* "BZ"? */
+			break;
+		dealloc_bunzip(bd);
+		len -= 2;
+	}
+
+ release_mem:
+	dealloc_bunzip(bd);
+	free(outbuf);
+
+	return i ? i : IF_DESKTOP(total_written) + 0;
+}
+
+IF_DESKTOP(long long) int FAST_FUNC
+unpack_bz2_stream_prime(int src_fd, int dst_fd)
+{
+	uint16_t magic2;
+	xread(src_fd, &magic2, 2);
+	if (magic2 != BZIP2_MAGIC) {
+		bb_error_msg_and_die("invalid magic");
+	}
+	return unpack_bz2_stream(src_fd, dst_fd);
+}
+
+#ifdef TESTING
+
+static char *const bunzip_errors[] = {
+	NULL, "Bad file checksum", "Not bzip data",
+	"Unexpected input EOF", "Unexpected output EOF", "Data error",
+	"Out of memory", "Obsolete (pre 0.9.5) bzip format not supported"
+};
+
+/* Dumb little test thing, decompress stdin to stdout */
+int main(int argc, char **argv)
+{
+	int i;
+	char c;
+
+	int i = unpack_bz2_stream_prime(0, 1);
+	if (i < 0)
+		fprintf(stderr, "%s\n", bunzip_errors[-i]);
+	else if (read(STDIN_FILENO, &c, 1))
+		fprintf(stderr, "Trailing garbage ignored\n");
+	return -i;
+}
+#endif
diff --git a/busybox-1.19.3/archival/libarchive/decompress_uncompress.c b/busybox-1.19.3/archival/libarchive/decompress_uncompress.c
new file mode 100644
index 0000000..d1061a2
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/decompress_uncompress.c
@@ -0,0 +1,310 @@
+/* vi: set sw=4 ts=4: */
+/* uncompress for busybox -- (c) 2002 Robert Griebl
+ *
+ * based on the original compress42.c source
+ * (see disclaimer below)
+ */
+
+/* (N)compress42.c - File compression ala IEEE Computer, Mar 1992.
+ *
+ * Authors:
+ *   Spencer W. Thomas   (decvax!harpo!utah-cs!utah-gr!thomas)
+ *   Jim McKie           (decvax!mcvax!jim)
+ *   Steve Davies        (decvax!vax135!petsd!peora!srd)
+ *   Ken Turkowski       (decvax!decwrl!turtlevax!ken)
+ *   James A. Woods      (decvax!ihnp4!ames!jaw)
+ *   Joe Orost           (decvax!vax135!petsd!joe)
+ *   Dave Mack           (csu@alembic.acs.com)
+ *   Peter Jannesen, Network Communication Systems
+ *                       (peter@ncs.nl)
+ *
+ * marc@suse.de : a small security fix for a buffer overflow
+ *
+ * [... History snipped ...]
+ *
+ */
+
+#include "libbb.h"
+#include "archive.h"
+
+
+/* Default input buffer size */
+#define IBUFSIZ 2048
+
+/* Default output buffer size */
+#define OBUFSIZ 2048
+
+/* Defines for third byte of header */
+#define BIT_MASK        0x1f    /* Mask for 'number of compresssion bits'       */
+                                /* Masks 0x20 and 0x40 are free.                */
+                                /* I think 0x20 should mean that there is       */
+                                /* a fourth header byte (for expansion).        */
+#define BLOCK_MODE      0x80    /* Block compression if table is full and       */
+                                /* compression rate is dropping flush tables    */
+                                /* the next two codes should not be changed lightly, as they must not   */
+                                /* lie within the contiguous general code space.                        */
+#define FIRST   257     /* first free entry */
+#define CLEAR   256     /* table clear output code */
+
+#define INIT_BITS 9     /* initial number of bits/code */
+
+
+/* machine variants which require cc -Dmachine:  pdp11, z8000, DOS */
+#define HBITS      17   /* 50% occupancy */
+#define HSIZE      (1<<HBITS)
+#define HMASK      (HSIZE-1)    /* unused */
+#define HPRIME     9941         /* unused */
+#define BITS       16
+#define BITS_STR   "16"
+#undef  MAXSEG_64K              /* unused */
+#define MAXCODE(n) (1L << (n))
+
+#define htabof(i)               htab[i]
+#define codetabof(i)            codetab[i]
+#define tab_prefixof(i)         codetabof(i)
+#define tab_suffixof(i)         ((unsigned char *)(htab))[i]
+#define de_stack                ((unsigned char *)&(htab[HSIZE-1]))
+#define clear_tab_prefixof()    memset(codetab, 0, 256)
+
+/*
+ * Decompress stdin to stdout.  This routine adapts to the codes in the
+ * file building the "string" table on-the-fly; requiring no table to
+ * be stored in the compressed file.
+ */
+
+IF_DESKTOP(long long) int FAST_FUNC
+unpack_Z_stream(int fd_in, int fd_out)
+{
+	IF_DESKTOP(long long total_written = 0;)
+	IF_DESKTOP(long long) int retval = -1;
+	unsigned char *stackp;
+	long code;
+	int finchar;
+	long oldcode;
+	long incode;
+	int inbits;
+	int posbits;
+	int outpos;
+	int insize;
+	int bitmask;
+	long free_ent;
+	long maxcode;
+	long maxmaxcode;
+	int n_bits;
+	int rsize = 0;
+	unsigned char *inbuf; /* were eating insane amounts of stack - */
+	unsigned char *outbuf; /* bad for some embedded targets */
+	unsigned char *htab;
+	unsigned short *codetab;
+
+	/* Hmm, these were statics - why?! */
+	/* user settable max # bits/code */
+	int maxbits; /* = BITS; */
+	/* block compress mode -C compatible with 2.0 */
+	int block_mode; /* = BLOCK_MODE; */
+
+	inbuf = xzalloc(IBUFSIZ + 64);
+	outbuf = xzalloc(OBUFSIZ + 2048);
+	htab = xzalloc(HSIZE);  /* wsn't zeroed out before, maybe can xmalloc? */
+	codetab = xzalloc(HSIZE * sizeof(codetab[0]));
+
+	insize = 0;
+
+	/* xread isn't good here, we have to return - caller may want
+	 * to do some cleanup (e.g. delete incomplete unpacked file etc) */
+	if (full_read(fd_in, inbuf, 1) != 1) {
+		bb_error_msg("short read");
+		goto err;
+	}
+
+	maxbits = inbuf[0] & BIT_MASK;
+	block_mode = inbuf[0] & BLOCK_MODE;
+	maxmaxcode = MAXCODE(maxbits);
+
+	if (maxbits > BITS) {
+		bb_error_msg("compressed with %d bits, can only handle "
+				BITS_STR" bits", maxbits);
+		goto err;
+	}
+
+	n_bits = INIT_BITS;
+	maxcode = MAXCODE(INIT_BITS) - 1;
+	bitmask = (1 << INIT_BITS) - 1;
+	oldcode = -1;
+	finchar = 0;
+	outpos = 0;
+	posbits = 0 << 3;
+
+	free_ent = ((block_mode) ? FIRST : 256);
+
+	/* As above, initialize the first 256 entries in the table. */
+	/*clear_tab_prefixof(); - done by xzalloc */
+
+	for (code = 255; code >= 0; --code) {
+		tab_suffixof(code) = (unsigned char) code;
+	}
+
+	do {
+ resetbuf:
+		{
+			int i;
+			int e;
+			int o;
+
+			o = posbits >> 3;
+			e = insize - o;
+
+			for (i = 0; i < e; ++i)
+				inbuf[i] = inbuf[i + o];
+
+			insize = e;
+			posbits = 0;
+		}
+
+		if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) {
+			rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ);
+			if (rsize < 0)
+				bb_error_msg_and_die(bb_msg_read_error);
+			insize += rsize;
+		}
+
+		inbits = ((rsize > 0) ? (insize - insize % n_bits) << 3 :
+				  (insize << 3) - (n_bits - 1));
+
+		while (inbits > posbits) {
+			if (free_ent > maxcode) {
+				posbits =
+					((posbits - 1) +
+					 ((n_bits << 3) -
+					  (posbits - 1 + (n_bits << 3)) % (n_bits << 3)));
+				++n_bits;
+				if (n_bits == maxbits) {
+					maxcode = maxmaxcode;
+				} else {
+					maxcode = MAXCODE(n_bits) - 1;
+				}
+				bitmask = (1 << n_bits) - 1;
+				goto resetbuf;
+			}
+			{
+				unsigned char *p = &inbuf[posbits >> 3];
+
+				code = ((((long) (p[0])) | ((long) (p[1]) << 8) |
+				         ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask;
+			}
+			posbits += n_bits;
+
+
+			if (oldcode == -1) {
+				if (code >= 256)
+					bb_error_msg_and_die("corrupted data"); /* %ld", code); */
+				oldcode = code;
+				finchar = (int) oldcode;
+				outbuf[outpos++] = (unsigned char) finchar;
+				continue;
+			}
+
+			if (code == CLEAR && block_mode) {
+				clear_tab_prefixof();
+				free_ent = FIRST - 1;
+				posbits =
+					((posbits - 1) +
+					 ((n_bits << 3) -
+					  (posbits - 1 + (n_bits << 3)) % (n_bits << 3)));
+				n_bits = INIT_BITS;
+				maxcode = MAXCODE(INIT_BITS) - 1;
+				bitmask = (1 << INIT_BITS) - 1;
+				goto resetbuf;
+			}
+
+			incode = code;
+			stackp = de_stack;
+
+			/* Special case for KwKwK string. */
+			if (code >= free_ent) {
+				if (code > free_ent) {
+					unsigned char *p;
+
+					posbits -= n_bits;
+					p = &inbuf[posbits >> 3];
+
+					bb_error_msg
+						("insize:%d posbits:%d inbuf:%02X %02X %02X %02X %02X (%d)",
+						 insize, posbits, p[-1], p[0], p[1], p[2], p[3],
+						 (posbits & 07));
+					bb_error_msg("corrupted data");
+					goto err;
+				}
+
+				*--stackp = (unsigned char) finchar;
+				code = oldcode;
+			}
+
+			/* Generate output characters in reverse order */
+			while ((long) code >= (long) 256) {
+				if (stackp <= &htabof(0))
+					bb_error_msg_and_die("corrupted data");
+				*--stackp = tab_suffixof(code);
+				code = tab_prefixof(code);
+			}
+
+			finchar = tab_suffixof(code);
+			*--stackp = (unsigned char) finchar;
+
+			/* And put them out in forward order */
+			{
+				int i;
+
+				i = de_stack - stackp;
+				if (outpos + i >= OBUFSIZ) {
+					do {
+						if (i > OBUFSIZ - outpos) {
+							i = OBUFSIZ - outpos;
+						}
+
+						if (i > 0) {
+							memcpy(outbuf + outpos, stackp, i);
+							outpos += i;
+						}
+
+						if (outpos >= OBUFSIZ) {
+							xwrite(fd_out, outbuf, outpos);
+							IF_DESKTOP(total_written += outpos;)
+							outpos = 0;
+						}
+						stackp += i;
+						i = de_stack - stackp;
+					} while (i > 0);
+				} else {
+					memcpy(outbuf + outpos, stackp, i);
+					outpos += i;
+				}
+			}
+
+			/* Generate the new entry. */
+			code = free_ent;
+			if (code < maxmaxcode) {
+				tab_prefixof(code) = (unsigned short) oldcode;
+				tab_suffixof(code) = (unsigned char) finchar;
+				free_ent = code + 1;
+			}
+
+			/* Remember previous code.  */
+			oldcode = incode;
+		}
+
+	} while (rsize > 0);
+
+	if (outpos > 0) {
+		xwrite(fd_out, outbuf, outpos);
+		IF_DESKTOP(total_written += outpos;)
+	}
+
+	retval = IF_DESKTOP(total_written) + 0;
+ err:
+	free(inbuf);
+	free(outbuf);
+	free(htab);
+	free(codetab);
+	return retval;
+}
diff --git a/busybox-1.19.3/archival/libarchive/decompress_unlzma.c b/busybox-1.19.3/archival/libarchive/decompress_unlzma.c
new file mode 100644
index 0000000..a047143
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/decompress_unlzma.c
@@ -0,0 +1,465 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Small lzma deflate implementation.
+ * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
+ *
+ * Based on LzmaDecode.c from the LZMA SDK 4.22 (http://www.7-zip.org/)
+ * Copyright (C) 1999-2005  Igor Pavlov
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+#include "libbb.h"
+#include "archive.h"
+
+#if ENABLE_FEATURE_LZMA_FAST
+#  define speed_inline ALWAYS_INLINE
+#  define size_inline
+#else
+#  define speed_inline
+#  define size_inline ALWAYS_INLINE
+#endif
+
+
+typedef struct {
+	int fd;
+	uint8_t *ptr;
+
+/* Was keeping rc on stack in unlzma and separately allocating buffer,
+ * but with "buffer 'attached to' allocated rc" code is smaller: */
+	/* uint8_t *buffer; */
+#define RC_BUFFER ((uint8_t*)(rc+1))
+
+	uint8_t *buffer_end;
+
+/* Had provisions for variable buffer, but we don't need it here */
+	/* int buffer_size; */
+#define RC_BUFFER_SIZE 0x10000
+
+	uint32_t code;
+	uint32_t range;
+	uint32_t bound;
+} rc_t;
+
+#define RC_TOP_BITS 24
+#define RC_MOVE_BITS 5
+#define RC_MODEL_TOTAL_BITS 11
+
+
+/* Called twice: once at startup (LZMA_FAST only) and once in rc_normalize() */
+static size_inline void rc_read(rc_t *rc)
+{
+	int buffer_size = safe_read(rc->fd, RC_BUFFER, RC_BUFFER_SIZE);
+//TODO: return -1 instead
+//This will make unlzma delete broken unpacked file on unpack errors
+	if (buffer_size <= 0)
+		bb_error_msg_and_die("unexpected EOF");
+	rc->ptr = RC_BUFFER;
+	rc->buffer_end = RC_BUFFER + buffer_size;
+}
+
+/* Called twice, but one callsite is in speed_inline'd rc_is_bit_1() */
+static void rc_do_normalize(rc_t *rc)
+{
+	if (rc->ptr >= rc->buffer_end)
+		rc_read(rc);
+	rc->range <<= 8;
+	rc->code = (rc->code << 8) | *rc->ptr++;
+}
+
+/* Called once */
+static ALWAYS_INLINE rc_t* rc_init(int fd) /*, int buffer_size) */
+{
+	int i;
+	rc_t *rc;
+
+	rc = xzalloc(sizeof(*rc) + RC_BUFFER_SIZE);
+
+	rc->fd = fd;
+	/* rc->ptr = rc->buffer_end; */
+
+	for (i = 0; i < 5; i++) {
+#if ENABLE_FEATURE_LZMA_FAST
+		if (rc->ptr >= rc->buffer_end)
+			rc_read(rc);
+		rc->code = (rc->code << 8) | *rc->ptr++;
+#else
+		rc_do_normalize(rc);
+#endif
+	}
+	rc->range = 0xFFFFFFFF;
+	return rc;
+}
+
+/* Called once  */
+static ALWAYS_INLINE void rc_free(rc_t *rc)
+{
+	free(rc);
+}
+
+static ALWAYS_INLINE void rc_normalize(rc_t *rc)
+{
+	if (rc->range < (1 << RC_TOP_BITS)) {
+		rc_do_normalize(rc);
+	}
+}
+
+/* rc_is_bit_1 is called 9 times */
+static speed_inline int rc_is_bit_1(rc_t *rc, uint16_t *p)
+{
+	rc_normalize(rc);
+	rc->bound = *p * (rc->range >> RC_MODEL_TOTAL_BITS);
+	if (rc->code < rc->bound) {
+		rc->range = rc->bound;
+		*p += ((1 << RC_MODEL_TOTAL_BITS) - *p) >> RC_MOVE_BITS;
+		return 0;
+	}
+	rc->range -= rc->bound;
+	rc->code -= rc->bound;
+	*p -= *p >> RC_MOVE_BITS;
+	return 1;
+}
+
+/* Called 4 times in unlzma loop */
+static speed_inline int rc_get_bit(rc_t *rc, uint16_t *p, int *symbol)
+{
+	int ret = rc_is_bit_1(rc, p);
+	*symbol = *symbol * 2 + ret;
+	return ret;
+}
+
+/* Called once */
+static ALWAYS_INLINE int rc_direct_bit(rc_t *rc)
+{
+	rc_normalize(rc);
+	rc->range >>= 1;
+	if (rc->code >= rc->range) {
+		rc->code -= rc->range;
+		return 1;
+	}
+	return 0;
+}
+
+/* Called twice */
+static speed_inline void
+rc_bit_tree_decode(rc_t *rc, uint16_t *p, int num_levels, int *symbol)
+{
+	int i = num_levels;
+
+	*symbol = 1;
+	while (i--)
+		rc_get_bit(rc, p + *symbol, symbol);
+	*symbol -= 1 << num_levels;
+}
+
+
+typedef struct {
+	uint8_t pos;
+	uint32_t dict_size;
+	uint64_t dst_size;
+} PACKED lzma_header_t;
+
+
+/* #defines will force compiler to compute/optimize each one with each usage.
+ * Have heart and use enum instead. */
+enum {
+	LZMA_BASE_SIZE = 1846,
+	LZMA_LIT_SIZE  = 768,
+
+	LZMA_NUM_POS_BITS_MAX = 4,
+
+	LZMA_LEN_NUM_LOW_BITS  = 3,
+	LZMA_LEN_NUM_MID_BITS  = 3,
+	LZMA_LEN_NUM_HIGH_BITS = 8,
+
+	LZMA_LEN_CHOICE     = 0,
+	LZMA_LEN_CHOICE_2   = (LZMA_LEN_CHOICE + 1),
+	LZMA_LEN_LOW        = (LZMA_LEN_CHOICE_2 + 1),
+	LZMA_LEN_MID        = (LZMA_LEN_LOW \
+	                      + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_LOW_BITS))),
+	LZMA_LEN_HIGH       = (LZMA_LEN_MID \
+	                      + (1 << (LZMA_NUM_POS_BITS_MAX + LZMA_LEN_NUM_MID_BITS))),
+	LZMA_NUM_LEN_PROBS  = (LZMA_LEN_HIGH + (1 << LZMA_LEN_NUM_HIGH_BITS)),
+
+	LZMA_NUM_STATES     = 12,
+	LZMA_NUM_LIT_STATES = 7,
+
+	LZMA_START_POS_MODEL_INDEX = 4,
+	LZMA_END_POS_MODEL_INDEX   = 14,
+	LZMA_NUM_FULL_DISTANCES    = (1 << (LZMA_END_POS_MODEL_INDEX >> 1)),
+
+	LZMA_NUM_POS_SLOT_BITS = 6,
+	LZMA_NUM_LEN_TO_POS_STATES = 4,
+
+	LZMA_NUM_ALIGN_BITS = 4,
+
+	LZMA_MATCH_MIN_LEN  = 2,
+
+	LZMA_IS_MATCH       = 0,
+	LZMA_IS_REP         = (LZMA_IS_MATCH + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)),
+	LZMA_IS_REP_G0      = (LZMA_IS_REP + LZMA_NUM_STATES),
+	LZMA_IS_REP_G1      = (LZMA_IS_REP_G0 + LZMA_NUM_STATES),
+	LZMA_IS_REP_G2      = (LZMA_IS_REP_G1 + LZMA_NUM_STATES),
+	LZMA_IS_REP_0_LONG  = (LZMA_IS_REP_G2 + LZMA_NUM_STATES),
+	LZMA_POS_SLOT       = (LZMA_IS_REP_0_LONG \
+	                      + (LZMA_NUM_STATES << LZMA_NUM_POS_BITS_MAX)),
+	LZMA_SPEC_POS       = (LZMA_POS_SLOT \
+	                      + (LZMA_NUM_LEN_TO_POS_STATES << LZMA_NUM_POS_SLOT_BITS)),
+	LZMA_ALIGN          = (LZMA_SPEC_POS \
+	                      + LZMA_NUM_FULL_DISTANCES - LZMA_END_POS_MODEL_INDEX),
+	LZMA_LEN_CODER      = (LZMA_ALIGN + (1 << LZMA_NUM_ALIGN_BITS)),
+	LZMA_REP_LEN_CODER  = (LZMA_LEN_CODER + LZMA_NUM_LEN_PROBS),
+	LZMA_LITERAL        = (LZMA_REP_LEN_CODER + LZMA_NUM_LEN_PROBS),
+};
+
+
+IF_DESKTOP(long long) int FAST_FUNC
+unpack_lzma_stream(int src_fd, int dst_fd)
+{
+	IF_DESKTOP(long long total_written = 0;)
+	lzma_header_t header;
+	int lc, pb, lp;
+	uint32_t pos_state_mask;
+	uint32_t literal_pos_mask;
+	uint16_t *p;
+	int num_bits;
+	int num_probs;
+	rc_t *rc;
+	int i;
+	uint8_t *buffer;
+	uint8_t previous_byte = 0;
+	size_t buffer_pos = 0, global_pos = 0;
+	int len = 0;
+	int state = 0;
+	uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1;
+
+	if (full_read(src_fd, &header, sizeof(header)) != sizeof(header)
+	 || header.pos >= (9 * 5 * 5)
+	) {
+		bb_error_msg("bad lzma header");
+		return -1;
+	}
+
+	i = header.pos / 9;
+	lc = header.pos % 9;
+	pb = i / 5;
+	lp = i % 5;
+	pos_state_mask = (1 << pb) - 1;
+	literal_pos_mask = (1 << lp) - 1;
+
+	header.dict_size = SWAP_LE32(header.dict_size);
+	header.dst_size = SWAP_LE64(header.dst_size);
+
+	if (header.dict_size == 0)
+		header.dict_size++;
+
+	buffer = xmalloc(MIN(header.dst_size, header.dict_size));
+
+	num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp));
+	p = xmalloc(num_probs * sizeof(*p));
+	num_probs += LZMA_LITERAL - LZMA_BASE_SIZE;
+	for (i = 0; i < num_probs; i++)
+		p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1;
+
+	rc = rc_init(src_fd); /*, RC_BUFFER_SIZE); */
+
+	while (global_pos + buffer_pos < header.dst_size) {
+		int pos_state = (buffer_pos + global_pos) & pos_state_mask;
+		uint16_t *prob = p + LZMA_IS_MATCH + (state << LZMA_NUM_POS_BITS_MAX) + pos_state;
+
+		if (!rc_is_bit_1(rc, prob)) {
+			static const char next_state[LZMA_NUM_STATES] =
+				{ 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 4, 5 };
+			int mi = 1;
+
+			prob = (p + LZMA_LITERAL
+			        + (LZMA_LIT_SIZE * ((((buffer_pos + global_pos) & literal_pos_mask) << lc)
+			                            + (previous_byte >> (8 - lc))
+			                           )
+			          )
+			);
+
+			if (state >= LZMA_NUM_LIT_STATES) {
+				int match_byte;
+				uint32_t pos = buffer_pos - rep0;
+
+				while (pos >= header.dict_size)
+					pos += header.dict_size;
+				match_byte = buffer[pos];
+				do {
+					int bit;
+
+					match_byte <<= 1;
+					bit = match_byte & 0x100;
+					bit ^= (rc_get_bit(rc, prob + 0x100 + bit + mi, &mi) << 8); /* 0x100 or 0 */
+					if (bit)
+						break;
+				} while (mi < 0x100);
+			}
+			while (mi < 0x100) {
+				rc_get_bit(rc, prob + mi, &mi);
+			}
+
+			state = next_state[state];
+
+			previous_byte = (uint8_t) mi;
+#if ENABLE_FEATURE_LZMA_FAST
+ one_byte1:
+			buffer[buffer_pos++] = previous_byte;
+			if (buffer_pos == header.dict_size) {
+				buffer_pos = 0;
+				global_pos += header.dict_size;
+				if (full_write(dst_fd, buffer, header.dict_size) != (ssize_t)header.dict_size)
+					goto bad;
+				IF_DESKTOP(total_written += header.dict_size;)
+			}
+#else
+			len = 1;
+			goto one_byte2;
+#endif
+		} else {
+			int offset;
+			uint16_t *prob2;
+#define prob_len prob2
+
+			prob2 = p + LZMA_IS_REP + state;
+			if (!rc_is_bit_1(rc, prob2)) {
+				rep3 = rep2;
+				rep2 = rep1;
+				rep1 = rep0;
+				state = state < LZMA_NUM_LIT_STATES ? 0 : 3;
+				prob2 = p + LZMA_LEN_CODER;
+			} else {
+				prob2 += LZMA_IS_REP_G0 - LZMA_IS_REP;
+				if (!rc_is_bit_1(rc, prob2)) {
+					prob2 = (p + LZMA_IS_REP_0_LONG
+					        + (state << LZMA_NUM_POS_BITS_MAX)
+					        + pos_state
+					);
+					if (!rc_is_bit_1(rc, prob2)) {
+#if ENABLE_FEATURE_LZMA_FAST
+						uint32_t pos = buffer_pos - rep0;
+						state = state < LZMA_NUM_LIT_STATES ? 9 : 11;
+						while (pos >= header.dict_size)
+							pos += header.dict_size;
+						previous_byte = buffer[pos];
+						goto one_byte1;
+#else
+						state = state < LZMA_NUM_LIT_STATES ? 9 : 11;
+						len = 1;
+						goto string;
+#endif
+					}
+				} else {
+					uint32_t distance;
+
+					prob2 += LZMA_IS_REP_G1 - LZMA_IS_REP_G0;
+					distance = rep1;
+					if (rc_is_bit_1(rc, prob2)) {
+						prob2 += LZMA_IS_REP_G2 - LZMA_IS_REP_G1;
+						distance = rep2;
+						if (rc_is_bit_1(rc, prob2)) {
+							distance = rep3;
+							rep3 = rep2;
+						}
+						rep2 = rep1;
+					}
+					rep1 = rep0;
+					rep0 = distance;
+				}
+				state = state < LZMA_NUM_LIT_STATES ? 8 : 11;
+				prob2 = p + LZMA_REP_LEN_CODER;
+			}
+
+			prob_len = prob2 + LZMA_LEN_CHOICE;
+			num_bits = LZMA_LEN_NUM_LOW_BITS;
+			if (!rc_is_bit_1(rc, prob_len)) {
+				prob_len += LZMA_LEN_LOW - LZMA_LEN_CHOICE
+				            + (pos_state << LZMA_LEN_NUM_LOW_BITS);
+				offset = 0;
+			} else {
+				prob_len += LZMA_LEN_CHOICE_2 - LZMA_LEN_CHOICE;
+				if (!rc_is_bit_1(rc, prob_len)) {
+					prob_len += LZMA_LEN_MID - LZMA_LEN_CHOICE_2
+					            + (pos_state << LZMA_LEN_NUM_MID_BITS);
+					offset = 1 << LZMA_LEN_NUM_LOW_BITS;
+					num_bits += LZMA_LEN_NUM_MID_BITS - LZMA_LEN_NUM_LOW_BITS;
+				} else {
+					prob_len += LZMA_LEN_HIGH - LZMA_LEN_CHOICE_2;
+					offset = ((1 << LZMA_LEN_NUM_LOW_BITS)
+					          + (1 << LZMA_LEN_NUM_MID_BITS));
+					num_bits += LZMA_LEN_NUM_HIGH_BITS - LZMA_LEN_NUM_LOW_BITS;
+				}
+			}
+			rc_bit_tree_decode(rc, prob_len, num_bits, &len);
+			len += offset;
+
+			if (state < 4) {
+				int pos_slot;
+				uint16_t *prob3;
+
+				state += LZMA_NUM_LIT_STATES;
+				prob3 = p + LZMA_POS_SLOT +
+				       ((len < LZMA_NUM_LEN_TO_POS_STATES ? len :
+				         LZMA_NUM_LEN_TO_POS_STATES - 1)
+				         << LZMA_NUM_POS_SLOT_BITS);
+				rc_bit_tree_decode(rc, prob3,
+					LZMA_NUM_POS_SLOT_BITS, &pos_slot);
+				rep0 = pos_slot;
+				if (pos_slot >= LZMA_START_POS_MODEL_INDEX) {
+					int i2, mi2, num_bits2 = (pos_slot >> 1) - 1;
+					rep0 = 2 | (pos_slot & 1);
+					if (pos_slot < LZMA_END_POS_MODEL_INDEX) {
+						rep0 <<= num_bits2;
+						prob3 = p + LZMA_SPEC_POS + rep0 - pos_slot - 1;
+					} else {
+						for (; num_bits2 != LZMA_NUM_ALIGN_BITS; num_bits2--)
+							rep0 = (rep0 << 1) | rc_direct_bit(rc);
+						rep0 <<= LZMA_NUM_ALIGN_BITS;
+						prob3 = p + LZMA_ALIGN;
+					}
+					i2 = 1;
+					mi2 = 1;
+					while (num_bits2--) {
+						if (rc_get_bit(rc, prob3 + mi2, &mi2))
+							rep0 |= i2;
+						i2 <<= 1;
+					}
+				}
+				if (++rep0 == 0)
+					break;
+			}
+
+			len += LZMA_MATCH_MIN_LEN;
+ IF_NOT_FEATURE_LZMA_FAST(string:)
+			do {
+				uint32_t pos = buffer_pos - rep0;
+				while (pos >= header.dict_size)
+					pos += header.dict_size;
+				previous_byte = buffer[pos];
+ IF_NOT_FEATURE_LZMA_FAST(one_byte2:)
+				buffer[buffer_pos++] = previous_byte;
+				if (buffer_pos == header.dict_size) {
+					buffer_pos = 0;
+					global_pos += header.dict_size;
+					if (full_write(dst_fd, buffer, header.dict_size) != (ssize_t)header.dict_size)
+						goto bad;
+					IF_DESKTOP(total_written += header.dict_size;)
+				}
+				len--;
+			} while (len != 0 && buffer_pos < header.dst_size);
+		}
+	}
+
+	{
+		IF_NOT_DESKTOP(int total_written = 0; /* success */)
+		IF_DESKTOP(total_written += buffer_pos;)
+		if (full_write(dst_fd, buffer, buffer_pos) != (ssize_t)buffer_pos) {
+ bad:
+			total_written = -1; /* failure */
+		}
+		rc_free(rc);
+		free(p);
+		free(buffer);
+		return total_written;
+	}
+}
diff --git a/busybox-1.19.3/archival/libarchive/decompress_unxz.c b/busybox-1.19.3/archival/libarchive/decompress_unxz.c
new file mode 100644
index 0000000..e90dfb0
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/decompress_unxz.c
@@ -0,0 +1,98 @@
+/*
+ * This file uses XZ Embedded library code which is written
+ * by Lasse Collin <lasse.collin@tukaani.org>
+ * and Igor Pavlov <http://7-zip.org/>
+ *
+ * See README file in unxz/ directory for more information.
+ *
+ * This file is:
+ * Copyright (C) 2010 Denys Vlasenko <vda.linux@googlemail.com>
+ * Licensed under GPLv2, see file LICENSE in this source tree.
+ */
+#include "libbb.h"
+#include "archive.h"
+
+#define XZ_FUNC FAST_FUNC
+#define XZ_EXTERN static
+
+#define XZ_DEC_DYNALLOC
+
+/* Skip check (rather than fail) of unsupported hash functions */
+#define XZ_DEC_ANY_CHECK  1
+
+/* We use our own crc32 function */
+#define XZ_INTERNAL_CRC32 0
+static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc)
+{
+	return ~crc32_block_endian0(~crc, buf, size, global_crc32_table);
+}
+
+/* We use arch-optimized unaligned accessors */
+#define get_unaligned_le32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_LE32(v); })
+#define get_unaligned_be32(buf) ({ uint32_t v; move_from_unaligned32(v, buf); SWAP_BE32(v); })
+#define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val))
+#define put_unaligned_be32(val, buf) move_to_unaligned16(buf, SWAP_BE32(val))
+
+#include "unxz/xz_dec_bcj.c"
+#include "unxz/xz_dec_lzma2.c"
+#include "unxz/xz_dec_stream.c"
+
+IF_DESKTOP(long long) int FAST_FUNC
+unpack_xz_stream(int src_fd, int dst_fd)
+{
+	struct xz_buf iobuf;
+	struct xz_dec *state;
+	unsigned char *membuf;
+	IF_DESKTOP(long long) int total = 0;
+
+	if (!global_crc32_table)
+		global_crc32_table = crc32_filltable(NULL, /*endian:*/ 0);
+
+	memset(&iobuf, 0, sizeof(iobuf));
+	/* Preload XZ file signature */
+	membuf = (void*) strcpy(xmalloc(2 * BUFSIZ), HEADER_MAGIC);
+	iobuf.in = membuf;
+	iobuf.in_size = HEADER_MAGIC_SIZE;
+	iobuf.out = membuf + BUFSIZ;
+	iobuf.out_size = BUFSIZ;
+
+	/* Limit memory usage to about 64 MiB. */
+	state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024);
+
+	while (1) {
+		enum xz_ret r;
+
+		if (iobuf.in_pos == iobuf.in_size) {
+			int rd = safe_read(src_fd, membuf, BUFSIZ);
+			if (rd < 0) {
+				bb_error_msg(bb_msg_read_error);
+				total = -1;
+				break;
+			}
+			iobuf.in_size = rd;
+			iobuf.in_pos = 0;
+		}
+//		bb_error_msg(">in pos:%d size:%d out pos:%d size:%d",
+//				iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size);
+		r = xz_dec_run(state, &iobuf);
+//		bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d",
+//				iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r);
+		if (iobuf.out_pos) {
+			xwrite(dst_fd, iobuf.out, iobuf.out_pos);
+			IF_DESKTOP(total += iobuf.out_pos;)
+			iobuf.out_pos = 0;
+		}
+		if (r == XZ_STREAM_END) {
+			break;
+		}
+		if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) {
+			bb_error_msg("corrupted data");
+			total = -1;
+			break;
+		}
+	}
+	xz_dec_end(state);
+	free(membuf);
+
+	return total;
+}
diff --git a/busybox-1.19.3/archival/libarchive/decompress_unzip.c b/busybox-1.19.3/archival/libarchive/decompress_unzip.c
new file mode 100644
index 0000000..a29eef8
--- /dev/null
+++ b/busybox-1.19.3/archival/libarchive/decompress_unzip.c
@@ -0,0 +1,1252 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * gunzip implementation for busybox
+ *
+ * Based on GNU gzip v1.2.4 Copyright (C) 1992-1993 Jean-loup Gailly.
+ *
+ * Originally adjusted for busybox by Sven Rudolph <sr1@inf.tu-dresden.de>
+ * based on gzip sources
+ *
+ * Adjusted further by Erik Andersen <andersen@codepoet.org> to support
+ * files as well as stdin/stdout, and to generally behave itself wrt
+ * command line handling.
+ *
+ * General cleanup to better adhere to the style guide and make use of standard
+ * busybox functions by Glenn McGrath
+ *
+ * read_gz interface + associated hacking by Laurence Anderson
+ *
+ * Fixed huft_build() so decoding end-of-block code does not grab more bits
+ * than necessary (this is required by unzip applet), added inflate_cleanup()
+ * to free leaked bytebuffer memory (used in unzip.c), and some minor style
+ * guide cleanups by Ed Clark
+ *
+ * gzip (GNU zip) -- compress files with zip algorithm and 'compress' interface
+ * Copyright (C) 1992-1993 Jean-loup Gailly
+ * The unzip code was written and put in the public domain by Mark Adler.
+ * Portions of the lzw code are derived from the public domain 'compress'
+ * written by Spencer Thomas, Joe Orost, James Woods, Jim McKie, Steve Davies,
+ * Ken Turkowski, Dave Mack and Peter Jannesen.
+ *
+ * See the file algorithm.doc for the compression algorithms and file formats.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#include <setjmp.h>
+#include "libbb.h"
+#include "archive.h"
+
+typedef struct huft_t {
+	unsigned char e;	/* number of extra bits or operation */
+	unsigned char b;	/* number of bits in this code or subcode */
+	union {
+		unsigned short n;	/* literal, length base, or distance base */
+		struct huft_t *t;	/* pointer to next level of table */
+	} v;
+} huft_t;
+
+enum {
+	/* gunzip_window size--must be a power of two, and
+	 * at least 32K for zip's deflate method */
+	GUNZIP_WSIZE = 0x8000,
+	/* If BMAX needs to be larger than 16, then h and x[] should be ulg. */
+	BMAX = 16,	/* maximum bit length of any code (16 for explode) */
+	N_MAX = 288,	/* maximum number of codes in any set */
+};
+
+
+/* This is somewhat complex-looking arrangement, but it allows
+ * to place decompressor state either in bss or in
+ * malloc'ed space simply by changing #defines below.
+ * Sizes on i386:
+ * text    data     bss     dec     hex
+ * 5256       0     108    5364    14f4 - bss
+ * 4915       0       0    4915    1333 - malloc
+ */
+#define STATE_IN_BSS 0
+#define STATE_IN_MALLOC 1
+
+
+typedef struct state_t {
+	off_t gunzip_bytes_out; /* number of output bytes */
+	uint32_t gunzip_crc;
+
+	int gunzip_src_fd;
+	unsigned gunzip_outbuf_count; /* bytes in output buffer */
+
+	unsigned char *gunzip_window;
+
+	uint32_t *gunzip_crc_table;
+
+	/* bitbuffer */
+	unsigned gunzip_bb; /* bit buffer */
+	unsigned char gunzip_bk; /* bits in bit buffer */
+
+	/* input (compressed) data */
+	unsigned char *bytebuffer;      /* buffer itself */
+	off_t to_read;			/* compressed bytes to read (unzip only, -1 for gunzip) */
+//	unsigned bytebuffer_max;        /* buffer size */
+