]> git.pld-linux.org Git - packages/busybox.git/commitdiff
- outdated
authorJakub Bogusz <qboosh@pld-linux.org>
Sat, 3 Sep 2005 20:02:20 +0000 (20:02 +0000)
committercvs2git <feedback@pld-linux.org>
Sun, 24 Jun 2012 12:13:13 +0000 (12:13 +0000)
Changed files:
    busybox-cvs-20050604.patch -> 1.2

busybox-cvs-20050604.patch [deleted file]

diff --git a/busybox-cvs-20050604.patch b/busybox-cvs-20050604.patch
deleted file mode 100644 (file)
index 5da0ac2..0000000
+++ /dev/null
@@ -1,44250 +0,0 @@
-diff -Nur busybox-1.00/AUTHORS busybox/AUTHORS
---- busybox-1.00/AUTHORS       2004-07-26 20:57:49.000000000 +0200
-+++ busybox/AUTHORS    2005-06-04 08:20:22.000000000 +0200
-@@ -2,12 +2,15 @@
- 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
--incorect, _please_ let me know.
-+incorrect, _please_ let me know.
-  -Erik
- -----------
-+Peter Willis <psyphreak@phreaker.net>
-+    eject
-+
- Emanuele Aina <emanuele.aina@tiscali.it>
-     run-parts
-@@ -29,6 +32,9 @@
- John Beppu <beppu@codepoet.org>
-     du, nslookup, sort
-+David Brownell <dbrownell@users.sourceforge.net>
-+    zcip
-+
- Brian Candler <B.Candler@pobox.com>
-     tiny-ls(ls)
-@@ -69,6 +75,12 @@
- Matt Kraai <kraai@alumni.cmu.edu>
-     documentation, bugfixes, test suite
-+Rob Landley <rob@landley.net>
-+    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).
-+    I've patched lots of other applets, but don't maintain 'em.
-+
- Stephan Linz <linz@li-pro.net>
-     ipcalc, Red Hat equivalence
-@@ -76,13 +88,14 @@
-     tr
- Glenn McGrath <bug1@iinet.net.au>
--    Common unarchving code and unarchiving applets, ifupdown, ftpgetput,
--    nameif, sed, patch, fold, install, uudecode. 
--    Various bugfixes, review and apply numerous patches. 
-+    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, make_directory, parse_mode, dirname, mode_string,
-+    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
-@@ -115,6 +128,9 @@
- Gyepi Sam <gyepi@praxis-sw.com>
-     Remote logging feature for syslogd
-+Rob Sullivan <cogito.ergo.cogito@gmail.com>
-+    comm
-+
- Linus Torvalds <torvalds@transmeta.com>
-     mkswap, fsck.minix, mkfs.minix
-@@ -129,5 +145,6 @@
-     tarcat (since removed), loadkmap, various fixes, Debian maintenance
- Tito Ragusa <farmatito@tiscali.it>
--    devfsd and size optimizations in strings, openvt, chvt, deallocvt, hdparm and fdformat.
-+    devfsd and size optimizations in strings, openvt, chvt, deallocvt, hdparm,
-+    fdformat, lsattr, chattr, id and eject.
-diff -Nur busybox-1.00/Makefile busybox/Makefile
---- busybox-1.00/Makefile      2004-10-08 09:45:08.000000000 +0200
-+++ busybox/Makefile   2005-06-04 08:20:22.000000000 +0200
-@@ -22,7 +22,7 @@
- #--------------------------------------------------------------
- noconfig_targets := menuconfig config oldconfig randconfig \
-       defconfig allyesconfig allnoconfig clean distclean \
--      release tags  
-+      release tags
- ifndef TOPDIR
- TOPDIR=$(CURDIR)/
-@@ -42,13 +42,12 @@
- DIRS:=applets archival archival/libunarchive coreutils console-tools \
-       debianutils editors findutils init miscutils modutils networking \
-       networking/libiproute networking/udhcp procps loginutils shell \
--      sysklogd util-linux libpwdgrp coreutils/libcoreutils libbb
-+      sysklogd util-linux e2fsprogs libpwdgrp coreutils/libcoreutils libbb
- SRC_DIRS:=$(patsubst %,$(top_srcdir)/%,$(DIRS))
- ifeq ($(strip $(CONFIG_SELINUX)),y)
--CFLAGS += -I/usr/include/selinux
--LIBRARIES += -lsecure
-+LIBRARIES += -lselinux
- endif
- CONFIG_CONFIG_IN = $(top_srcdir)/sysdeps/$(TARGET_OS)/Config.in
-@@ -130,7 +129,7 @@
- busybox.links: $(top_srcdir)/applets/busybox.mkll include/config.h $(top_srcdir)/include/applets.h
-       - $(SHELL) $^ >$@
--install: applets/install.sh busybox busybox.links
-+install: $(top_srcdir)/applets/install.sh busybox busybox.links
-       $(SHELL) $< $(PREFIX)
- ifeq ($(strip $(CONFIG_FEATURE_SUID)),y)
-       @echo
-@@ -147,7 +146,7 @@
-       rm -f $(PREFIX)/bin/busybox
-       for i in `cat busybox.links` ; do rm -f $(PREFIX)$$i; done
--install-hardlinks: applets/install.sh busybox busybox.links
-+install-hardlinks: $(top_srcdir)/applets/install.sh busybox busybox.links
-       $(SHELL) $< $(PREFIX) --hardlinks
- check: busybox
-diff -Nur busybox-1.00/TODO busybox/TODO
---- busybox-1.00/TODO  2004-05-01 02:49:49.000000000 +0200
-+++ busybox/TODO       2005-06-04 08:20:22.000000000 +0200
-@@ -2,10 +2,106 @@
- Stuff that needs to be done
------
--tr - missing SuS3 features in busybox 1.0pre10 
-+tr - missing SuS3 features in busybox 1.0pre10
- tr doesnt support [:blank:], [:digit:] or other predefined classes, [=equiv=]
- support is also missing.
- ----
-- 
-+find
-+  doesn't understand () or -exec, and these are actually used out in the real
-+  world.  The "make uninstall" of lots of things (including busybox itself)
-+  breaks because of this, and sometimes even "make install" (like udev).
-+----
-+comm
-+  Perl needs "comm" to build.  It's small and simple, but we haven't got it.
-+---
-+sh
-+  The command shell situation is a big mess.  We have three or four 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.  Unifying the various shells and figuring out a configurable
-+  way of adding the minimal set of bash features a given script uses is a big
-+  job, but it be a big improvement.
-+---
-+gzip
-+  Can't handle compressing multiple files at once.  (I don't mean making a
-+  multiple file archive, I mean compressing more than one file at a time.)
-+  Some global variables aren't re-initialized between runs.
-+---
-+gunzip
-+  same problem as gzip.  "gunzip one.gz two.gz three.gz" doesn't work for
-+  two.gz and three.gz due to global variables not getting reset.
-+---
-+diff
-+  We should have a diff -u command.  We have patch, we should have diff
-+  (we only need to support unified diffs though).
-+---
-+patch
-+  should have -i support, and simple fuzz factor support to apply patches
-+  at an offset shouldn't take up too much space.
-+---
-+man
-+  It would be nice to have a man command.  Not one that handles troff or
-+  anything, just one that can handle preformatted ascii man pages, possibly
-+  compressed.  This could probably be a script in the extras directory that
-+  calls cat/zcatbzcat | more
-+---
-+less
-+  More sucks if you're used to less.  A tiny less implementation would be
-+  very nice.
-+---
-+bzip2
-+  Compression-side support.
-+
-+
-+Architectural issues:
-+
-+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.
-+--
-+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 someday,
-+  if it becomes relevant.
-+---
-+Text buffer support.
-+  Several existing applets and potential additions (sort, vi, less...) read
-+  a whole file into memory and act on it.  There might be an opportunity
-+  for shared code in there that could be moved into libbb...
-+---
-+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 is now capable of replacing most gnu packages for real world use,
-+  such as developing software or in a live CD.  A system built from busybox
-+  (1.00 with updated sort.c), uclibc 0.9.27, gcc, binutils, make, and a few
-+  other development tools (http://www.landley.net/code/firmware has an example
-+  system using autoconf, automake, bison, flex, libtools, m4, zlib,
-+  and groff: dunno what subset of that is actually necessary) is capable of
-+  rebuilding itself, from scratch, under itself.
-+
-+  It would be a good "eating our own dogfood" test if buildroot had the option
-+  of using busybox instead of bzip2, coreutils, file, findutils, gawk, grep,
-+  inetutils, modutils, net-tools, procps, sed, shadow, sysklogd, sysvinit, tar,
-+  util-linux, and vim.  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, diffutils, gzip, less, and patch as well.)
-diff -Nur busybox-1.00/applets/busybox.c busybox/applets/busybox.c
---- busybox-1.00/applets/busybox.c     2004-03-15 09:28:15.000000000 +0100
-+++ busybox/applets/busybox.c  2005-06-04 08:20:20.000000000 +0200
-@@ -144,25 +144,25 @@
-               output_width -= 20;
- #endif
--              fprintf(stderr, "%s\n\n"
--                              "Usage: busybox [function] [arguments]...\n"
--                              "   or: [function] [arguments]...\n\n"
--                              "\tBusyBox is a multi-call binary that combines many common Unix\n"
--                              "\tutilities into a single executable.  Most people will create a\n"
--                              "\tlink to busybox for each function they wish to use, and BusyBox\n"
--                              "\twill act like whatever it was invoked as.\n"
--                              "\nCurrently defined functions:\n", bb_msg_full_version);
-+              printf("%s\n\n"
-+                     "Usage: busybox [function] [arguments]...\n"
-+                     "   or: [function] [arguments]...\n\n"
-+                     "\tBusyBox is a multi-call binary that combines many common Unix\n"
-+                     "\tutilities into a single executable.  Most people will create a\n"
-+                     "\tlink to busybox for each function they wish to use and BusyBox\n"
-+                     "\twill act like whatever it was invoked as!\n"
-+                     "\nCurrently defined functions:\n", bb_msg_full_version);
-               while (a->name != 0) {
-                       col +=
--                              fprintf(stderr, "%s%s", ((col == 0) ? "\t" : ", "),
--                                              (a++)->name);
-+                              printf("%s%s", ((col == 0) ? "\t" : ", "),
-+                                     (a++)->name);
-                       if (col > output_width && a->name != 0) {
--                              fprintf(stderr, ",\n");
-+                              printf(",\n");
-                               col = 0;
-                       }
-               }
--              fprintf(stderr, "\n\n");
-+              printf("\n\n");
-               exit(0);
-       }
-diff -Nur busybox-1.00/archival/ar.c busybox/archival/ar.c
---- busybox-1.00/archival/ar.c 2004-10-07 02:35:59.000000000 +0200
-+++ busybox/archival/ar.c      2005-06-04 08:20:08.000000000 +0200
-@@ -56,19 +56,21 @@
- #define AR_OPT_PRESERVE_DATE  0x08
- #define AR_OPT_VERBOSE                        0x10
- #define AR_OPT_CREATE                 0x20
-+#define AR_OPT_INSERT                 0x40
- extern int ar_main(int argc, char **argv)
- {
-       archive_handle_t *archive_handle;
-       unsigned long opt;
-+      char *msg_unsupported_err = "Archive %s not supported.  Install binutils 'ar'.";
-       char magic[8];
-       archive_handle = init_handle();
-       bb_opt_complementaly = "p~tx:t~px:x~pt";
--      opt = bb_getopt_ulflags(argc, argv, "ptxovc");
-+      opt = bb_getopt_ulflags(argc, argv, "ptxovcr");
--      if ((opt & 0x80000000UL) || (optind == argc)) {
-+      if ((opt & BB_GETOPT_ERROR) || (opt == 0) || (optind == argc)) {
-               bb_show_usage();
-       }
-@@ -88,7 +90,10 @@
-               archive_handle->action_header = header_verbose_list_ar;
-       }
-       if (opt & AR_OPT_CREATE) {
--              bb_error_msg_and_die("Archive creation not supported.  Install binutils 'ar'.");
-+              bb_error_msg_and_die(msg_unsupported_err, "creation");
-+      }
-+      if (opt & AR_OPT_INSERT) {
-+              bb_error_msg_and_die(msg_unsupported_err, "insertion");
-       }
-       archive_handle->src_fd = bb_xopen(argv[optind++], O_RDONLY);
-diff -Nur busybox-1.00/archival/dpkg.c busybox/archival/dpkg.c
---- busybox-1.00/archival/dpkg.c       2004-04-14 19:51:08.000000000 +0200
-+++ busybox/archival/dpkg.c    2005-06-04 08:20:08.000000000 +0200
-@@ -58,7 +58,7 @@
-  * 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
--char *name_hashtable[NAME_HASH_PRIME + 1];
-+static char *name_hashtable[NAME_HASH_PRIME + 1];
- /* PACKAGE_HASH_PRIME, Maximum number of unique packages,
-  * It must not be smaller than STATUS_HASH_PRIME,
-@@ -82,7 +82,7 @@
-       unsigned int num_of_edges:14;
-       edge_t **edge;
- } common_node_t;
--common_node_t *package_hashtable[PACKAGE_HASH_PRIME + 1];
-+static common_node_t *package_hashtable[PACKAGE_HASH_PRIME + 1];
- /* 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
-@@ -92,7 +92,7 @@
-       unsigned int package:14;        /* has to fit PACKAGE_HASH_PRIME */
-       unsigned int status:14;         /* has to fit STATUS_HASH_PRIME */
- } status_node_t;
--status_node_t *status_hashtable[STATUS_HASH_PRIME + 1];
-+static status_node_t *status_hashtable[STATUS_HASH_PRIME + 1];
- /* Even numbers are for 'extras', like ored dependencies or null */
- enum edge_type_e {
-@@ -137,7 +137,7 @@
- } deb_file_t;
--void make_hash(const char *key, unsigned int *start, unsigned int *decrement, const int hash_prime)
-+static void make_hash(const char *key, unsigned int *start, unsigned int *decrement, const int hash_prime)
- {
-       unsigned long int hash_num = key[0];
-       int len = strlen(key);
-@@ -157,7 +157,7 @@
- }
- /* this adds the key to the hash table */
--int search_name_hashtable(const char *key)
-+static int search_name_hashtable(const char *key)
- {
-       unsigned int probe_address = 0;
-       unsigned int probe_decrement = 0;
-@@ -181,7 +181,7 @@
- /* this DOESNT add the key to the hashtable
-  * TODO make it consistent with search_name_hashtable
-  */
--unsigned int search_status_hashtable(const char *key)
-+static unsigned int search_status_hashtable(const char *key)
- {
-       unsigned int probe_address = 0;
-       unsigned int probe_decrement = 0;
-@@ -201,7 +201,7 @@
- }
- /* Need to rethink version comparison, maybe the official dpkg has something i can use ? */
--int version_compare_part(const char *version1, const char *version2)
-+static int version_compare_part(const char *version1, const char *version2)
- {
-       int upstream_len1 = 0;
-       int upstream_len2 = 0;
-@@ -268,7 +268,7 @@
-  * if ver1 = ver2 return 0,
-  * if ver1 > ver2 return 1,
-  */
--int version_compare(const unsigned int ver1, const unsigned int ver2)
-+static int version_compare(const unsigned int ver1, const unsigned int ver2)
- {
-       char *ch_ver1 = name_hashtable[ver1];
-       char *ch_ver2 = name_hashtable[ver2];
-@@ -330,7 +330,7 @@
-       return(version_compare_part(deb_ver1, deb_ver2));
- }
--int test_version(const unsigned int version1, const unsigned int version2, const unsigned int operator)
-+static int test_version(const unsigned int version1, const unsigned int version2, const unsigned int operator)
- {
-       const int version_result = version_compare(version1, version2);
-       switch(operator) {
-@@ -366,7 +366,7 @@
- }
--int search_package_hashtable(const unsigned int name, const unsigned int version, const unsigned int operator)
-+static int search_package_hashtable(const unsigned int name, const unsigned int version, const unsigned int operator)
- {
-       unsigned int probe_address = 0;
-       unsigned int probe_decrement = 0;
-@@ -405,7 +405,7 @@
-  * 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.
-  */
--int search_for_provides(int needle, int start_at) {
-+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++) {
-@@ -421,7 +421,7 @@
- /*
-  * Add an edge to a node
-  */
--void add_edge_to_node(common_node_t *node, edge_t *edge)
-+static void add_edge_to_node(common_node_t *node, edge_t *edge)
- {
-       node->num_of_edges++;
-       node->edge = xrealloc(node->edge, sizeof(edge_t) * (node->num_of_edges + 1));
-@@ -438,7 +438,7 @@
-  * field contains the number of EDGE nodes which follow as part of
-  * this alternative.
-  */
--void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned int edge_type)
-+static void add_split_dependencies(common_node_t *parent_node, const char *whole_line, unsigned int edge_type)
- {
-       char *line = bb_xstrdup(whole_line);
-       char *line2;
-@@ -537,7 +537,7 @@
-       return;
- }
--void free_package(common_node_t *node)
-+static void free_package(common_node_t *node)
- {
-       unsigned short i;
-       if (node) {
-@@ -550,7 +550,7 @@
-       }
- }
--unsigned int fill_package_struct(char *control_buffer)
-+static unsigned int fill_package_struct(char *control_buffer)
- {
-       common_node_t *new_node = (common_node_t *) xcalloc(1, sizeof(common_node_t));
-       const char *field_names[] = { "Package", "Version", "Pre-Depends", "Depends",
-@@ -624,7 +624,7 @@
- }
- /* if num = 1, it returns the want status, 2 returns flag, 3 returns status */
--unsigned int get_status(const unsigned int status_node, const int num)
-+static unsigned int get_status(const unsigned int status_node, const int num)
- {
-       char *status_string = name_hashtable[status_hashtable[status_node]->status];
-       char *state_sub_string;
-@@ -646,7 +646,7 @@
-       return(state_sub_num);
- }
--void set_status(const unsigned int status_node_num, const char *new_value, const int position)
-+static void set_status(const unsigned int status_node_num, const char *new_value, const int position)
- {
-       const unsigned int new_value_len = strlen(new_value);
-       const unsigned int new_value_num = search_name_hashtable(new_value);
-@@ -682,7 +682,7 @@
-       return;
- }
--const char *describe_status(int status_num) {
-+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\n";
-@@ -707,7 +707,7 @@
- }
--void index_status_file(const char *filename)
-+static void index_status_file(const char *filename)
- {
-       FILE *status_file;
-       char *control_buffer;
-@@ -812,7 +812,7 @@
- }
- #endif
--void write_buffer_no_status(FILE *new_status_file, const char *control_buffer)
-+static void write_buffer_no_status(FILE *new_status_file, const char *control_buffer)
- {
-       char *name;
-       char *value;
-@@ -830,7 +830,7 @@
- }
- /* This could do with a cleanup */
--void write_status_file(deb_file_t **deb_file)
-+static void write_status_file(deb_file_t **deb_file)
- {
-       FILE *old_status_file = bb_xfopen("/var/lib/dpkg/status", "r");
-       FILE *new_status_file = bb_xfopen("/var/lib/dpkg/status.udeb", "w");
-@@ -978,7 +978,7 @@
-  * which a regular depends can be satisfied by a package which we want
-  * to install.
-  */
--int package_satisfies_dependency(int package, int depend_type)
-+static int package_satisfies_dependency(int package, int depend_type)
- {
-       int status_num = search_status_hashtable(name_hashtable[package_hashtable[package]->name]);
-@@ -995,7 +995,7 @@
-       return 0;
- }
--int check_deps(deb_file_t **deb_file, int deb_start, int dep_max_count)
-+static int check_deps(deb_file_t **deb_file, int deb_start, int dep_max_count)
- {
-       int *conflicts = NULL;
-       int conflicts_num = 0;
-@@ -1204,7 +1204,7 @@
-       return(TRUE);
- }
--char **create_list(const char *filename)
-+static char **create_list(const char *filename)
- {
-       FILE *list_stream;
-       char **file_list = NULL;
-@@ -1233,7 +1233,7 @@
- }
- /* maybe i should try and hook this into remove_file.c somehow */
--int remove_file_array(char **remove_names, char **exclude_names)
-+static int remove_file_array(char **remove_names, char **exclude_names)
- {
-       struct stat path_stat;
-       int match_flag;
-@@ -1271,7 +1271,7 @@
-       return(remove_flag);
- }
--int run_package_script(const char *package_name, const char *script_type)
-+static int run_package_script(const char *package_name, const char *script_type)
- {
-       struct stat path_stat;
-       char *script_path;
-@@ -1290,10 +1290,10 @@
-       return(result);
- }
--const char *all_control_files[] = {"preinst", "postinst", "prerm", "postrm",
-+static const char *all_control_files[] = {"preinst", "postinst", "prerm", "postrm",
-       "list", "md5sums", "shlibs", "conffiles", "config", "templates", NULL };
--char **all_control_list(const char *package_name)
-+static char **all_control_list(const char *package_name)
- {
-       unsigned short i = 0;
-       char **remove_files;
-@@ -1310,7 +1310,7 @@
-       return(remove_files);
- }
--void free_array(char **array)
-+static void free_array(char **array)
- {
-       if (array) {
-@@ -1327,7 +1327,7 @@
-  * the status_hashtable to retrieve the info. This results in smaller code than
-  * scanning the status file. The resulting list, however, is unsorted.
-  */
--void list_packages(void)
-+static void list_packages(void)
- {
-         int i;
-@@ -1364,7 +1364,7 @@
-     }
- }
--void remove_package(const unsigned int package_num, int noisy)
-+static void remove_package(const unsigned int 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];
-@@ -1418,7 +1418,7 @@
-       set_status(status_num, "config-files", 3);
- }
--void purge_package(const unsigned int package_num)
-+static void purge_package(const unsigned int package_num)
- {
-       const char *package_name = name_hashtable[package_hashtable[package_num]->name];
-       const char *package_version = name_hashtable[package_hashtable[package_num]->version];
-@@ -1614,7 +1614,7 @@
-       free(info_prefix);
- }
--void configure_package(deb_file_t *deb_file)
-+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];
-diff -Nur busybox-1.00/archival/dpkg_deb.c busybox/archival/dpkg_deb.c
---- busybox-1.00/archival/dpkg_deb.c   2004-03-15 09:28:16.000000000 +0100
-+++ busybox/archival/dpkg_deb.c        2005-06-04 08:20:08.000000000 +0200
-@@ -88,7 +88,7 @@
-               argcount = 2;
-       }
--      if ((optind + argcount != argc) || (opt & 0x80000000UL)) {
-+      if ((optind + argcount != argc) || (opt & BB_GETOPT_ERROR)) {
-               bb_show_usage();
-       }
-diff -Nur busybox-1.00/archival/gzip.c busybox/archival/gzip.c
---- busybox-1.00/archival/gzip.c       2004-04-14 19:51:08.000000000 +0200
-+++ busybox/archival/gzip.c    2005-06-04 08:20:08.000000000 +0200
-@@ -51,12 +51,6 @@
- #include <time.h>
- #include "busybox.h"
--#define memzero(s, n)     memset ((void *)(s), 0, (n))
--
--#ifndef RETSIGTYPE
--#  define RETSIGTYPE void
--#endif
--
- typedef unsigned char uch;
- typedef unsigned short ush;
- typedef unsigned long ulg;
-@@ -214,9 +208,6 @@
- static int zip(int in, int out);
- static int file_read(char *buf, unsigned size);
--      /* from gzip.c */
--static RETSIGTYPE abort_gzip(void);
--
-               /* from deflate.c */
- static void lm_init(ush * flags);
- static ulg deflate(void);
-@@ -335,7 +326,7 @@
- /* ========================================================================
-  * Signal and error handler.
-  */
--static void abort_gzip()
-+static void abort_gzip(int ignored)
- {
-       exit(ERROR);
- }
-@@ -350,13 +341,6 @@
-       bytes_in = 0L;
- }
--static void write_bb_error_msg(void)
--{
--      fputc('\n', stderr);
--      bb_perror_nomsg();
--      abort_gzip();
--}
--
- /* ===========================================================================
-  * Does the same as write(), but also handles partial pipe writes and checks
-  * for error return.
-@@ -366,9 +350,7 @@
-       unsigned n;
-       while ((n = write(fd, buf, cnt)) != cnt) {
--              if (n == (unsigned) (-1)) {
--                      write_bb_error_msg();
--              }
-+              if (n == (unsigned) (-1)) bb_error_msg_and_die("can't write");
-               cnt -= n;
-               buf = (void *) ((char *) buf + n);
-       }
-@@ -559,7 +541,7 @@
- /* ===========================================================================
-  * Write out any remaining bits in an incomplete byte.
-  */
--static void bi_windup()
-+static void bi_windup(void)
- {
-       if (bi_valid > 8) {
-               put_short(bi_buf);
-@@ -846,7 +828,7 @@
-       register unsigned j;
-       /* Initialize the hash table. */
--      memzero((char *) head, HASH_SIZE * sizeof(*head));
-+      memset(head, 0, HASH_SIZE * sizeof(*head));
-       /* prev will be initialized on the fly */
-       *flags |= SLOW;
-@@ -996,7 +978,7 @@
-  *    file reads are performed for at least two bytes (required for the
-  *    translate_eol option).
-  */
--static void fill_window()
-+static void fill_window(void)
- {
-       register unsigned n, m;
-       unsigned more =
-@@ -1060,7 +1042,7 @@
-  * evaluation for matches: a match is finally adopted only if there is
-  * no better match at the next window position.
-  */
--static ulg deflate()
-+static ulg deflate(void)
- {
-       IPos hash_head;         /* head of hash chain */
-       IPos prev_match;        /* previous match */
-@@ -1188,8 +1170,6 @@
- typedef struct dirent dir_type;
--typedef RETSIGTYPE(*sig_type) (int);
--
- /* ======================================================================== */
- int gzip_main(int argc, char **argv)
- {
-@@ -1235,16 +1215,16 @@
-       foreground = signal(SIGINT, SIG_IGN) != SIG_IGN;
-       if (foreground) {
--              (void) signal(SIGINT, (sig_type) abort_gzip);
-+              (void) signal(SIGINT, abort_gzip);
-       }
- #ifdef SIGTERM
-       if (signal(SIGTERM, SIG_IGN) != SIG_IGN) {
--              (void) signal(SIGTERM, (sig_type) abort_gzip);
-+              (void) signal(SIGTERM, abort_gzip);
-       }
- #endif
- #ifdef SIGHUP
-       if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
--              (void) signal(SIGHUP, (sig_type) abort_gzip);
-+              (void) signal(SIGHUP, abort_gzip);
-       }
- #endif
-@@ -1271,6 +1251,7 @@
-               for (i = optind; i < argc; i++) {
-                       char *path = NULL;
-+                      clear_bufs();
-                       if (strcmp(argv[i], "-") == 0) {
-                               time_stamp = 0;
-                               ifile_size = -1L;
-@@ -1749,7 +1730,7 @@
- /* ===========================================================================
-  * Initialize a new block.
-  */
--static void init_block()
-+static void init_block(void)
- {
-       int n;                          /* iterates over tree elements */
-@@ -2162,7 +2143,7 @@
-  * Construct the Huffman tree for the bit lengths and return the index in
-  * bl_order of the last bit length code to send.
-  */
--static const int build_bl_tree()
-+static int build_bl_tree(void)
- {
-       int max_blindex;        /* index of last bit length code of non zero freq */
-@@ -2425,7 +2406,7 @@
-  * IN assertion: the fields freq of dyn_ltree are set and the total of all
-  * frequencies does not exceed 64K (to fit in an int on 16 bit machines).
-  */
--static void set_file_type()
-+static void set_file_type(void)
- {
-       int n = 0;
-       unsigned ascii_freq = 0;
-@@ -2538,7 +2519,7 @@
-  * Write the output buffer outbuf[0..outcnt-1] and update bytes_out.
-  * (used for the compressed data only)
-  */
--static void flush_outbuf()
-+static void flush_outbuf(void)
- {
-       if (outcnt == 0)
-               return;
-diff -Nur busybox-1.00/archival/libunarchive/archive_xread_all_eof.c busybox/archival/libunarchive/archive_xread_all_eof.c
---- busybox-1.00/archival/libunarchive/archive_xread_all_eof.c 2003-11-21 23:24:48.000000000 +0100
-+++ busybox/archival/libunarchive/archive_xread_all_eof.c      2005-06-04 08:20:08.000000000 +0200
-@@ -26,7 +26,7 @@
-       size = bb_full_read(archive_handle->src_fd, buf, count);
-       if ((size != 0) && (size != count)) {
--              bb_perror_msg_and_die("Short read, read %d of %d", size, count);
-+              bb_perror_msg_and_die("Short read, read %ld of %ld", (long)size, (long)count);
-       }
-       return(size);
- }
-diff -Nur busybox-1.00/archival/libunarchive/check_header_gzip.c busybox/archival/libunarchive/check_header_gzip.c
---- busybox-1.00/archival/libunarchive/check_header_gzip.c     2003-03-19 10:11:25.000000000 +0100
-+++ busybox/archival/libunarchive/check_header_gzip.c  2005-06-04 08:20:08.000000000 +0200
-@@ -1,6 +1,7 @@
- #include <stdlib.h>
- #include <unistd.h>
- #include "libbb.h"
-+#include "unarchive.h" /* for external decl of check_header_gzip */
- extern void check_header_gzip(int src_fd)
- {
-diff -Nur busybox-1.00/archival/libunarchive/decompress_bunzip2.c busybox/archival/libunarchive/decompress_bunzip2.c
---- busybox-1.00/archival/libunarchive/decompress_bunzip2.c    2004-08-28 02:43:05.000000000 +0200
-+++ busybox/archival/libunarchive/decompress_bunzip2.c 2005-06-04 08:20:08.000000000 +0200
-@@ -134,8 +134,6 @@
- static int get_next_block(bunzip_data *bd)
- {
--      /* Note: Ignore the warning about hufGroup, base and limit being used uninitialized.
--       * They will be initialized on the fist pass of the loop. */
-       struct group_data *hufGroup;
-       int dbufCount,nextSym,dbufSize,groupCount,*base,*limit,selector,
-               i,j,k,t,runPos,symCount,symTotal,nSelectors,byteCount[256];
-@@ -286,16 +284,15 @@
-               mtfSymbol[i]=(unsigned char)i;
-       }
-       /* Loop through compressed symbols. */
--      runPos=dbufCount=symCount=selector=0;
-+      runPos=dbufCount=selector=0;
-       for(;;) {
--              /* Determine which Huffman coding group to use. */
--              if(!(symCount--)) {
--                      symCount=GROUP_SIZE-1;
--                      if(selector>=nSelectors) return RETVAL_DATA_ERROR;
--                      hufGroup=bd->groups+selectors[selector++];
--                      base=hufGroup->base-1;
--                      limit=hufGroup->limit-1;
--              }
-+              /* 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 an additional bit at a time, testing
-@@ -346,7 +343,7 @@
-                          context).  Thus space is saved. */
-                       t += (runPos << nextSym); /* +runPos if RUNA; +2*runPos if RUNB */
-                       runPos <<= 1;
--                      continue;
-+                      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
-@@ -384,6 +381,10 @@
-               /* We have our literal byte.  Save it into dbuf. */
-               byteCount[uc]++;
-               dbuf[dbufCount++] = (unsigned int)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--) 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
-diff -Nur busybox-1.00/archival/libunarchive/decompress_uncompress.c busybox/archival/libunarchive/decompress_uncompress.c
---- busybox-1.00/archival/libunarchive/decompress_uncompress.c 2004-04-14 19:51:08.000000000 +0200
-+++ busybox/archival/libunarchive/decompress_uncompress.c      2005-06-04 08:20:08.000000000 +0200
-@@ -65,23 +65,23 @@
- #define MAXCODE(n)    (1L << (n))
- /* Block compress mode -C compatible with 2.0 */
--int block_mode = BLOCK_MODE;
-+static int block_mode = BLOCK_MODE;
- /* user settable max # bits/code */
--int maxbits = BITS;
-+static int maxbits = BITS;
- /* Exitcode of compress (-1 no file compressed) */
--int exit_code = -1;
-+static int exit_code = -1;
- /* Input buffer */
--unsigned char inbuf[IBUFSIZ + 64];
-+static unsigned char inbuf[IBUFSIZ + 64];
- /* Output buffer */
--unsigned char outbuf[OBUFSIZ + 2048];
-+static unsigned char outbuf[OBUFSIZ + 2048];
--long int htab[HSIZE];
--unsigned short codetab[HSIZE];
-+static long int htab[HSIZE];
-+static unsigned short codetab[HSIZE];
- #define       htabof(i)                               htab[i]
- #define       codetabof(i)                    codetab[i]
-diff -Nur busybox-1.00/archival/libunarchive/decompress_unzip.c busybox/archival/libunarchive/decompress_unzip.c
---- busybox-1.00/archival/libunarchive/decompress_unzip.c      2004-04-25 07:11:13.000000000 +0200
-+++ busybox/archival/libunarchive/decompress_unzip.c   2005-06-04 08:20:08.000000000 +0200
-@@ -151,7 +151,10 @@
-                       /* Leave the first 4 bytes empty so we can always unwind the bitbuffer
-                        * to the front of the bytebuffer, leave 4 bytes free at end of tail
-                        * so we can easily top up buffer in check_trailer_gzip() */
--                      bytebuffer_size = 4 + bb_xread(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8);
-+                      if (!(bytebuffer_size = bb_xread(gunzip_src_fd, &bytebuffer[4], bytebuffer_max - 8))) {
-+                              bb_error_msg_and_die("unexpected end of file");
-+                      }
-+                      bytebuffer_size += 4;
-                       bytebuffer_offset = 4;
-               }
-               bitbuffer |= ((unsigned int) bytebuffer[bytebuffer_offset]) << *current;
-diff -Nur busybox-1.00/archival/rpm.c busybox/archival/rpm.c
---- busybox-1.00/archival/rpm.c        2004-03-15 09:28:16.000000000 +0100
-+++ busybox/archival/rpm.c     2005-06-04 08:20:08.000000000 +0200
-@@ -260,12 +260,16 @@
- int bsearch_rpmtag(const void *key, const void *item)
- {
-       rpm_index **tmp = (rpm_index **) item;
-+      /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ...
-+       * it's ok to ignore it because this isn't a 'real' pointer */
-       return ((int) key - tmp[0]->tag);
- }
- int rpm_getcount(int tag)
- {
-       rpm_index **found;
-+      /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ...
-+       * it's ok to ignore it because tag won't be used as a pointer */
-       found = bsearch((void *) tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
-       if (!found) return 0;
-       else return found[0]->count;
-@@ -274,6 +278,8 @@
- char *rpm_getstring(int tag, int itemindex)
- {
-       rpm_index **found;
-+      /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ...
-+       * it's ok to ignore it because tag won't be used as a pointer */
-       found = bsearch((void *) tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
-       if (!found || itemindex >= found[0]->count) return NULL;
-       if (found[0]->type == RPM_STRING_TYPE || found[0]->type == RPM_I18NSTRING_TYPE || found[0]->type == RPM_STRING_ARRAY_TYPE) {
-@@ -288,6 +294,8 @@
- {
-       rpm_index **found;
-       int n, *tmpint;
-+      /* gcc throws warnings here when sizeof(void*)!=sizeof(int) ...
-+       * it's ok to ignore it because tag won't be used as a pointer */
-       found = bsearch((void *) tag, mytags, tagcount, sizeof(struct rpmtag *), bsearch_rpmtag);
-       if (!found || itemindex >= found[0]->count) return -1;
-       tmpint = (int *) (map + found[0]->offset);
-diff -Nur busybox-1.00/archival/rpm2cpio.c busybox/archival/rpm2cpio.c
---- busybox-1.00/archival/rpm2cpio.c   2004-03-27 11:02:41.000000000 +0100
-+++ busybox/archival/rpm2cpio.c        2005-06-04 08:20:08.000000000 +0200
-@@ -48,7 +48,7 @@
-       uint32_t size; /* Size of store (4 bytes) */
- };
--void skip_header(int rpm_fd)
-+static void skip_header(int rpm_fd)
- {
-       struct rpm_header header;
-diff -Nur busybox-1.00/archival/tar.c busybox/archival/tar.c
---- busybox-1.00/archival/tar.c        2004-08-27 00:18:56.000000000 +0200
-+++ busybox/archival/tar.c     2005-06-04 08:20:08.000000000 +0200
-@@ -724,7 +724,7 @@
-                               );
-       /* Check one and only one context option was given */
--      if(opt & 0x80000000UL) {
-+      if(opt & BB_GETOPT_ERROR) {
-               bb_show_usage();
-       }
- #ifdef CONFIG_FEATURE_TAR_CREATE
-diff -Nur busybox-1.00/coreutils/Config.in busybox/coreutils/Config.in
---- busybox-1.00/coreutils/Config.in   2004-08-11 04:45:47.000000000 +0200
-+++ busybox/coreutils/Config.in        2005-06-04 08:20:13.000000000 +0200
-@@ -59,6 +59,13 @@
-         cmp is used to compare two files and returns the result
-         to standard output.
-+config CONFIG_COMM
-+      bool "comm"
-+      default n
-+      help
-+        comm is used to compare two files line by line and return
-+        a three-column output.
-+
- config CONFIG_CP
-       bool "cp"
-       default n
-@@ -164,6 +171,12 @@
-         a command; without options it displays the current
-         environment.
-+config CONFIG_PRINTENV
-+      bool "printenv"
-+      default n
-+      help
-+        printenv is used to print all or part of environment.
-+
- config CONFIG_EXPR
-       bool "expr"
-       default n
-@@ -329,6 +342,12 @@
-       help
-         mv is used to move or rename files or directories.
-+config CONFIG_NICE
-+      bool "nice"
-+      default n
-+      help
-+        nice runs a program with modified scheduling priority.
-+
- config CONFIG_OD
-       bool "od"
-       default n
-@@ -398,12 +417,45 @@
-       help
-         sort is used to sort lines of text in specified files.
-+config CONFIG_SORT_BIG
-+      bool "  full SuSv3 compliant sort (Support -ktcsbdfiozgM)"
-+      default y
-+      depends on CONFIG_SORT
-+      help
-+        Without this, sort only supports  -r, -u, and an integer version
-+        of -n.  Selecting this adds sort keys, floating point support, and
-+        more.  This adds a little over 3k to a nonstatic build on x86.
-+
-+        The SuSv3 sort standard is available at:
-+        http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html
-+
-+config CONFIG_STAT
-+      bool "stat"
-+      default n
-+      help
-+        display file or filesystem status.
-+
-+config CONFIG_FEATURE_STAT_FORMAT
-+      bool "  Enable custom formats (-c)"
-+      default n
-+      depends on CONFIG_STAT
-+      help
-+        Without this, stat will not support the '-c format' option where 
-+        users can pass a custom format string for output.  This adds about 
-+        7k to a nonstatic build on amd64.
-+
- config CONFIG_STTY
-       bool "stty"
-       default n
-       help
-         stty is used to change and print terminal line settings.
-+config CONFIG_SUM
-+      bool "sum"
-+      default n
-+      help
-+        checksum and count the blocks in a file
-+
- config CONFIG_SYNC
-       bool "sync"
-       default n
-diff -Nur busybox-1.00/coreutils/Makefile.in busybox/coreutils/Makefile.in
---- busybox-1.00/coreutils/Makefile.in 2004-10-08 09:45:14.000000000 +0200
-+++ busybox/coreutils/Makefile.in      2005-06-04 08:20:13.000000000 +0200
-@@ -24,69 +24,74 @@
- srcdir=$(top_srcdir)/coreutils
- COREUTILS-y:=
--COREUTILS-$(CONFIG_BASENAME)  += basename.o
--COREUTILS-$(CONFIG_CAL)       += cal.o
--COREUTILS-$(CONFIG_CAT)       += cat.o
--COREUTILS-$(CONFIG_CHGRP)     += chgrp.o
--COREUTILS-$(CONFIG_CHMOD)     += chmod.o
--COREUTILS-$(CONFIG_CHOWN)     += chown.o
--COREUTILS-$(CONFIG_CHROOT)    += chroot.o
--COREUTILS-$(CONFIG_CMP)       += cmp.o
--COREUTILS-$(CONFIG_CP)        += cp.o
--COREUTILS-$(CONFIG_CUT)       += cut.o
--COREUTILS-$(CONFIG_DATE)      += date.o
--COREUTILS-$(CONFIG_DD)        += dd.o
--COREUTILS-$(CONFIG_DF)        += df.o
--COREUTILS-$(CONFIG_DIRNAME)   += dirname.o
--COREUTILS-$(CONFIG_DOS2UNIX)  += dos2unix.o
--COREUTILS-$(CONFIG_DU)        += du.o
--COREUTILS-$(CONFIG_ECHO)      += echo.o
--COREUTILS-$(CONFIG_ENV)       += env.o
--COREUTILS-$(CONFIG_EXPR)      += expr.o
--COREUTILS-$(CONFIG_FALSE)     += false.o
--COREUTILS-$(CONFIG_FOLD)      += fold.o
--COREUTILS-$(CONFIG_HEAD)      += head.o
--COREUTILS-$(CONFIG_HOSTID)    += hostid.o
--COREUTILS-$(CONFIG_ID)        += id.o
--COREUTILS-$(CONFIG_INSTALL)   += install.o
--COREUTILS-$(CONFIG_LENGTH)    += length.o
--COREUTILS-$(CONFIG_LN)        += ln.o
--COREUTILS-$(CONFIG_LOGNAME)   += logname.o
--COREUTILS-$(CONFIG_LS)        += ls.o
--COREUTILS-$(CONFIG_MD5SUM)    += md5_sha1_sum.o
--COREUTILS-$(CONFIG_MKDIR)     += mkdir.o
--COREUTILS-$(CONFIG_MKFIFO)    += mkfifo.o
--COREUTILS-$(CONFIG_MKNOD)     += mknod.o
--COREUTILS-$(CONFIG_MV)        += mv.o
--COREUTILS-$(CONFIG_OD)        += od.o
--COREUTILS-$(CONFIG_PRINTF)    += printf.o
--COREUTILS-$(CONFIG_PWD)       += pwd.o
--COREUTILS-$(CONFIG_REALPATH)  += realpath.o
--COREUTILS-$(CONFIG_RM)        += rm.o
--COREUTILS-$(CONFIG_RMDIR)     += rmdir.o
--COREUTILS-$(CONFIG_SEQ)       += seq.o
--COREUTILS-$(CONFIG_SHA1SUM)   += md5_sha1_sum.o
--COREUTILS-$(CONFIG_SLEEP)     += sleep.o
--COREUTILS-$(CONFIG_SORT)      += sort.o
--COREUTILS-$(CONFIG_STTY)      += stty.o
--COREUTILS-$(CONFIG_SYNC)      += sync.o
--COREUTILS-$(CONFIG_TAIL)      += tail.o
--COREUTILS-$(CONFIG_TEE)       += tee.o
--COREUTILS-$(CONFIG_TEST)      += test.o
--COREUTILS-$(CONFIG_TOUCH)     += touch.o
--COREUTILS-$(CONFIG_TR)        += tr.o
--COREUTILS-$(CONFIG_TRUE)      += true.o
--COREUTILS-$(CONFIG_TTY)       += tty.o
--COREUTILS-$(CONFIG_UNAME)     += uname.o
--COREUTILS-$(CONFIG_UNIQ)      += uniq.o
--COREUTILS-$(CONFIG_USLEEP)    += usleep.o
--COREUTILS-$(CONFIG_UUDECODE)  += uudecode.o
--COREUTILS-$(CONFIG_UUENCODE)  += uuencode.o
--COREUTILS-$(CONFIG_WATCH)     += watch.o
--COREUTILS-$(CONFIG_WC)        += wc.o
--COREUTILS-$(CONFIG_WHO)       += who.o
--COREUTILS-$(CONFIG_WHOAMI)    += whoami.o
--COREUTILS-$(CONFIG_YES)       += yes.o
-+COREUTILS-$(CONFIG_BASENAME)  += basename.o
-+COREUTILS-$(CONFIG_CAL)       += cal.o
-+COREUTILS-$(CONFIG_CAT)       += cat.o
-+COREUTILS-$(CONFIG_CHGRP)     += chgrp.o
-+COREUTILS-$(CONFIG_CHMOD)     += chmod.o
-+COREUTILS-$(CONFIG_CHOWN)     += chown.o
-+COREUTILS-$(CONFIG_CHROOT)    += chroot.o
-+COREUTILS-$(CONFIG_CMP)       += cmp.o
-+COREUTILS-$(CONFIG_COMM)      += comm.o
-+COREUTILS-$(CONFIG_CP)        += cp.o
-+COREUTILS-$(CONFIG_CUT)       += cut.o
-+COREUTILS-$(CONFIG_DATE)      += date.o
-+COREUTILS-$(CONFIG_DD)        += dd.o
-+COREUTILS-$(CONFIG_DF)        += df.o
-+COREUTILS-$(CONFIG_DIRNAME)   += dirname.o
-+COREUTILS-$(CONFIG_DOS2UNIX)  += dos2unix.o
-+COREUTILS-$(CONFIG_DU)        += du.o
-+COREUTILS-$(CONFIG_ECHO)      += echo.o
-+COREUTILS-$(CONFIG_ENV)       += env.o
-+COREUTILS-$(CONFIG_EXPR)      += expr.o
-+COREUTILS-$(CONFIG_FALSE)     += false.o
-+COREUTILS-$(CONFIG_FOLD)      += fold.o
-+COREUTILS-$(CONFIG_HEAD)      += head.o
-+COREUTILS-$(CONFIG_HOSTID)    += hostid.o
-+COREUTILS-$(CONFIG_ID)        += id.o
-+COREUTILS-$(CONFIG_INSTALL)   += install.o
-+COREUTILS-$(CONFIG_LENGTH)    += length.o
-+COREUTILS-$(CONFIG_LN)        += ln.o
-+COREUTILS-$(CONFIG_LOGNAME)   += logname.o
-+COREUTILS-$(CONFIG_LS)        += ls.o
-+COREUTILS-$(CONFIG_MD5SUM)    += md5_sha1_sum.o
-+COREUTILS-$(CONFIG_MKDIR)     += mkdir.o
-+COREUTILS-$(CONFIG_MKFIFO)    += mkfifo.o
-+COREUTILS-$(CONFIG_MKNOD)     += mknod.o
-+COREUTILS-$(CONFIG_MV)        += mv.o
-+COREUTILS-$(CONFIG_NICE)      += nice.o
-+COREUTILS-$(CONFIG_OD)        += od.o
-+COREUTILS-$(CONFIG_PRINTENV)  += printenv.o
-+COREUTILS-$(CONFIG_PRINTF)    += printf.o
-+COREUTILS-$(CONFIG_PWD)       += pwd.o
-+COREUTILS-$(CONFIG_REALPATH)  += realpath.o
-+COREUTILS-$(CONFIG_RM)        += rm.o
-+COREUTILS-$(CONFIG_RMDIR)     += rmdir.o
-+COREUTILS-$(CONFIG_SEQ)       += seq.o
-+COREUTILS-$(CONFIG_SHA1SUM)   += md5_sha1_sum.o
-+COREUTILS-$(CONFIG_SLEEP)     += sleep.o
-+COREUTILS-$(CONFIG_SORT)      += sort.o
-+COREUTILS-$(CONFIG_STAT)      += stat.o
-+COREUTILS-$(CONFIG_STTY)      += stty.o
-+COREUTILS-$(CONFIG_SUM)       += sum.o
-+COREUTILS-$(CONFIG_SYNC)      += sync.o
-+COREUTILS-$(CONFIG_TAIL)      += tail.o
-+COREUTILS-$(CONFIG_TEE)       += tee.o
-+COREUTILS-$(CONFIG_TEST)      += test.o
-+COREUTILS-$(CONFIG_TOUCH)     += touch.o
-+COREUTILS-$(CONFIG_TR)        += tr.o
-+COREUTILS-$(CONFIG_TRUE)      += true.o
-+COREUTILS-$(CONFIG_TTY)       += tty.o
-+COREUTILS-$(CONFIG_UNAME)     += uname.o
-+COREUTILS-$(CONFIG_UNIQ)      += uniq.o
-+COREUTILS-$(CONFIG_USLEEP)    += usleep.o
-+COREUTILS-$(CONFIG_UUDECODE)  += uudecode.o
-+COREUTILS-$(CONFIG_UUENCODE)  += uuencode.o
-+COREUTILS-$(CONFIG_WATCH)     += watch.o
-+COREUTILS-$(CONFIG_WC)        += wc.o
-+COREUTILS-$(CONFIG_WHO)       += who.o
-+COREUTILS-$(CONFIG_WHOAMI)    += whoami.o
-+COREUTILS-$(CONFIG_YES)       += yes.o
- libraries-y+=$(COREUTILS_DIR)$(COREUTILS_AR)
-@@ -95,4 +100,3 @@
- $(COREUTILS_DIR)%.o: $(srcdir)/%.c
-       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
--
-diff -Nur busybox-1.00/coreutils/comm.c busybox/coreutils/comm.c
---- busybox-1.00/coreutils/comm.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/coreutils/comm.c   2005-06-04 08:20:13.000000000 +0200
-@@ -0,0 +1,144 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * Mini comm implementation for busybox
-+ *
-+ * Copyright (C) 2005 by Robert Sullivan <cogito.ergo.cogito@gmail.com>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include "busybox.h"
-+
-+#define COMM_OPT_1 0x01
-+#define COMM_OPT_2 0x02
-+#define COMM_OPT_3 0x04
-+
-+/* These three variables control behaviour if non-zero */
-+
-+static int only_file_1;
-+static int only_file_2;
-+static int both;
-+
-+/* writeline outputs the input given, appropriately aligned according to class */
-+static void writeline(char *line, int class)
-+{
-+      if (class == 0) {
-+              if (!only_file_1)
-+                      return;
-+      } else if (class == 1) {
-+              if (!only_file_2)
-+                      return;
-+              if (only_file_1)
-+                      putchar('\t');
-+      }
-+      else /*if (class == 2)*/ {
-+              if (!both)
-+                      return;
-+              if (only_file_1)
-+                      putchar('\t');
-+              if (only_file_2)
-+                      putchar('\t');
-+      }
-+      fputs(line, stdout);
-+}
-+
-+/* This is the real core of the program - lines are compared here */
-+static void cmp_files(char **infiles)
-+{
-+#define LINE_LEN 100
-+#define BB_EOF_0 0x1
-+#define BB_EOF_1 0x2
-+      char thisline[2][LINE_LEN];
-+      FILE *streams[2];
-+      int i;
-+
-+      for (i = 0; i < 2; ++i) {
-+              streams[i] = ((infiles[i][0] == '=' && infiles[i][1]) ? stdin : bb_xfopen(infiles[i], "r"));
-+              fgets(thisline[i], LINE_LEN, streams[i]);
-+      }
-+
-+      while (thisline[0] || thisline[1]) {
-+              int order = 0;
-+
-+              i = 0;
-+              if (feof(streams[0])) i |= BB_EOF_0;
-+              if (feof(streams[1])) i |= BB_EOF_1;
-+
-+              if (!thisline[0])
-+                      order = 1;
-+              else if (!thisline[1])
-+                      order = -1;
-+              else {
-+                      int tl0_len, tl1_len;
-+                      tl0_len = strlen(thisline[0]);
-+                      tl1_len = strlen(thisline[1]);
-+                      order = memcmp(thisline[0], thisline[1], tl0_len < tl1_len ? tl0_len : tl1_len);
-+                      if (!order)
-+                              order = tl0_len < tl1_len ? -1 : tl0_len != tl1_len;
-+              }
-+
-+              if (order == 0 && !i)
-+                      writeline(thisline[1], 2);
-+              else if (order > 0 && !(i & BB_EOF_1))
-+                      writeline(thisline[1], 1);
-+              else if (order < 0 && !(i & BB_EOF_0))
-+                      writeline(thisline[0], 0);
-+
-+              if (i & BB_EOF_0 & BB_EOF_1) {
-+                      break;
-+
-+              } else if (i) {
-+                      i = (i & BB_EOF_0 ? 1 : 0);
-+                      while (!feof(streams[i])) {
-+                              if ((order < 0 && i) || (order > 0 && !i))
-+                                      writeline(thisline[i], i);
-+                              fgets(thisline[i], LINE_LEN, streams[i]);
-+                      }
-+                      break;
-+
-+              } else {
-+                      if (order >= 0)
-+                              fgets(thisline[1], LINE_LEN, streams[1]);
-+                      if (order <= 0)
-+                              fgets(thisline[0], LINE_LEN, streams[0]);
-+              }
-+      }
-+
-+      fclose(streams[0]);
-+      fclose(streams[1]);
-+}
-+
-+int comm_main(int argc, char **argv)
-+{
-+      unsigned long flags;
-+
-+      flags = bb_getopt_ulflags(argc, argv, "123");
-+
-+      if (optind + 2 != argc)
-+              bb_show_usage();
-+
-+      only_file_1 = !(flags & COMM_OPT_1);
-+      only_file_2 = !(flags & COMM_OPT_2);
-+      both = !(flags & COMM_OPT_3);
-+
-+      cmp_files(argv + optind);
-+      exit(EXIT_SUCCESS);
-+}
-diff -Nur busybox-1.00/coreutils/cp.c busybox/coreutils/cp.c
---- busybox-1.00/coreutils/cp.c        2004-01-25 06:50:28.000000000 +0100
-+++ busybox/coreutils/cp.c     2005-06-04 08:20:13.000000000 +0200
-@@ -42,7 +42,7 @@
- #include "libcoreutils/coreutils.h"
- /* WARNING!! ORDER IS IMPORTANT!! */
--static const char cp_opts[] = "pdRfiar";
-+static const char cp_opts[] = "pdRfiarPHL";
- extern int cp_main(int argc, char **argv)
- {
-@@ -70,9 +70,23 @@
-       if (flags & 64) {
-               /* Make -r a synonym for -R,
-                * -r was marked as obsolete in SUSv3, but is included for compatability
--               */
-+               */
-               flags |= FILEUTILS_RECUR;
-       }
-+      if (flags & 128) {
-+              /* Make -P a synonym for -d,
-+               * -d is the GNU option while -P is the POSIX 2003 option
-+               */
-+              flags |= FILEUTILS_DEREFERENCE;
-+      }
-+      /* Default behavior of cp is to dereference, so we don't have to do
-+       * anything special when we are given -L.
-+       * The behavior of -H is *almost* like -L, but not quite, so let's
-+       * just ignore it too for fun.
-+      if (flags & 256 || flags & 512) {
-+              ;
-+      }
-+      */
-       flags ^= FILEUTILS_DEREFERENCE;         /* The sense of this flag was reversed. */
-@@ -86,7 +100,7 @@
-       /* If there are only two arguments and...  */
-       if (optind + 2 == argc) {
-               s_flags = cp_mv_stat2(*argv, &source_stat,
--                                                               (flags & FILEUTILS_DEREFERENCE) ? stat : lstat);
-+                                    (flags & FILEUTILS_DEREFERENCE) ? stat : lstat);
-               if ((s_flags < 0) || ((d_flags = cp_mv_stat(last, &dest_stat)) < 0)) {
-                       exit(EXIT_FAILURE);
-               }
-@@ -98,8 +112,8 @@
-                       ((((flags & FILEUTILS_RECUR) >> 1) & s_flags) && !d_flags)
-               ) {
-                       /* ...do a simple copy.  */
--                              dest = last;
--                              goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */
-+                      dest = last;
-+                      goto DO_COPY; /* Note: optind+2==argc implies argv[1]==last below. */
-               }
-       }
-diff -Nur busybox-1.00/coreutils/cut.c busybox/coreutils/cut.c
---- busybox-1.00/coreutils/cut.c       2004-04-14 19:51:09.000000000 +0200
-+++ busybox/coreutils/cut.c    2005-06-04 08:20:13.000000000 +0200
-@@ -300,7 +300,7 @@
-       part = opt & (OPT_BYTE_FLGS|OPT_CHAR_FLGS|OPT_FIELDS_FLGS);
-       if(part == 0)
-               bb_error_msg_and_die("you must specify a list of bytes, characters, or fields");
--      if(opt & 0x80000000UL)
-+      if(opt & BB_GETOPT_ERROR)
-               bb_error_msg_and_die("only one type of list may be specified");
-       parse_lists(sopt);
-       if((opt & (OPT_DELIM_FLGS))) {
-diff -Nur busybox-1.00/coreutils/date.c busybox/coreutils/date.c
---- busybox-1.00/coreutils/date.c      2004-10-11 22:52:16.000000000 +0200
-+++ busybox/coreutils/date.c   2005-06-04 08:20:13.000000000 +0200
-@@ -136,7 +136,6 @@
- {
-       char *date_str = NULL;
-       char *date_fmt = NULL;
--      char *t_buff;
-       int set_time;
-       int utc;
-       int use_arg = 0;
-@@ -166,7 +165,7 @@
-               bb_error_msg_and_die(bb_msg_memory_exhausted);
-       }
-       use_arg = opt & DATE_OPT_DATE;
--      if(opt & 0x80000000UL)
-+      if(opt & BB_GETOPT_ERROR)
-               bb_show_usage();
- #ifdef CONFIG_FEATURE_DATE_ISOFMT
-       if(opt & DATE_OPT_TIMESPEC) {
-@@ -283,10 +282,13 @@
-               date_fmt = "%Y.%m.%d-%H:%M:%S";
-       }
--      /* Print OUTPUT (after ALL that!) */
--      t_buff = xmalloc(201);
--      strftime(t_buff, 200, date_fmt, &tm_time);
--      puts(t_buff);
-+      {
-+              /* Print OUTPUT (after ALL that!) */
-+              RESERVE_CONFIG_BUFFER(t_buff, 201);
-+              strftime(t_buff, 200, date_fmt, &tm_time);
-+              puts(t_buff);
-+              RELEASE_CONFIG_BUFFER(t_buff);
-+      }
-       return EXIT_SUCCESS;
- }
-diff -Nur busybox-1.00/coreutils/expr.c busybox/coreutils/expr.c
---- busybox-1.00/coreutils/expr.c      2004-04-14 19:51:09.000000000 +0200
-+++ busybox/coreutils/expr.c   2005-06-04 08:20:13.000000000 +0200
-@@ -245,10 +245,9 @@
- static VALUE *docolon (VALUE *sv, VALUE *pv)
- {
-       VALUE *v;
--      const char *errmsg;
--      struct re_pattern_buffer re_buffer;
--      struct re_registers re_regs;
--      int len;
-+      regex_t re_buffer;
-+      const int NMATCH = 2;
-+      regmatch_t re_regs[NMATCH];
-       tostring (sv);
-       tostring (pv);
-@@ -260,27 +259,22 @@
-               pv->u.s);
-       }
--      len = strlen (pv->u.s);
-       memset (&re_buffer, 0, sizeof (re_buffer));
--      memset (&re_regs, 0, sizeof (re_regs));
--      re_buffer.allocated = 2 * len;
--      re_buffer.buffer = (unsigned char *) xmalloc (re_buffer.allocated);
--      re_buffer.translate = 0;
--      re_syntax_options = RE_SYNTAX_POSIX_BASIC;
--      errmsg = re_compile_pattern (pv->u.s, len, &re_buffer);
--      if (errmsg) {
--              bb_error_msg_and_die("%s", errmsg);
--      }
--
--      len = re_match (&re_buffer, sv->u.s, strlen (sv->u.s), 0, &re_regs);
--      if (len >= 0) {
-+      memset (re_regs, 0, sizeof (*re_regs));
-+      if( regcomp (&re_buffer, pv->u.s, 0) != 0 )
-+              bb_error_msg_and_die("Invalid regular expression");
-+
-+      /* expr uses an anchored pattern match, so check that there was a
-+       * match and that the match starts at offset 0. */
-+      if (regexec (&re_buffer, sv->u.s, NMATCH, re_regs, 0) != REG_NOMATCH &&
-+                      re_regs[0].rm_so == 0) {
-               /* Were \(...\) used? */
--              if (re_buffer.re_nsub > 0) { /* was (re_regs.start[1] >= 0) */
--                      sv->u.s[re_regs.end[1]] = '\0';
--                      v = str_value (sv->u.s + re_regs.start[1]);
-+              if (re_buffer.re_nsub > 0) {
-+                      sv->u.s[re_regs[1].rm_eo] = '\0';
-+                      v = str_value (sv->u.s + re_regs[1].rm_so);
-               }
-               else
--                      v = int_value (len);
-+                      v = int_value (re_regs[0].rm_eo);
-       }
-       else {
-               /* Match failed -- return the right kind of null.  */
-@@ -289,7 +283,6 @@
-               else
-                       v = int_value (0);
-       }
--      free (re_buffer.buffer);
-       return v;
- }
-diff -Nur busybox-1.00/coreutils/id.c busybox/coreutils/id.c
---- busybox-1.00/coreutils/id.c        2004-09-15 05:04:07.000000000 +0200
-+++ busybox/coreutils/id.c     2005-06-04 08:20:13.000000000 +0200
-@@ -32,8 +32,7 @@
- #include <sys/types.h>
- #ifdef CONFIG_SELINUX
--#include <proc_secure.h>
--#include <flask_util.h>
-+#include <selinux/selinux.h>          /* for is_selinux_enabled() */
- #endif
- #define PRINT_REAL        1
-@@ -61,14 +60,11 @@
-       gid_t gid;
-       unsigned long flags;
-       short status;
--#ifdef CONFIG_SELINUX
--      int is_flask_enabled_flag = is_flask_enabled();
--#endif
-       bb_opt_complementaly = "u~g:g~u";
-       flags = bb_getopt_ulflags(argc, argv, "rnug");
--      if ((flags & 0x80000000UL)
-+      if ((flags & BB_GETOPT_ERROR)
-       /* Don't allow -n -r -nr */
-       || (flags <= 3 && flags > 0) 
-       /* Don't allow more than one username */
-@@ -109,17 +105,26 @@
-       putchar(' ');
-       /* my_getgrgid doesn't exit on failure here */
-       status|=printf_full(gid, my_getgrgid(NULL, gid, 0), 'g');
-+
- #ifdef CONFIG_SELINUX
--      if(is_flask_enabled_flag) {
--              security_id_t mysid = getsecsid();
--              char context[80];
--              int len = sizeof(context);
--              context[0] = '\0';
--              if(security_sid_to_context(mysid, context, &len))
--                      strcpy(context, "unknown");
-+      if ( is_selinux_enabled() ) {
-+                      security_context_t mysid;
-+                      char context[80];
-+                      int len = sizeof(context);
-+
-+                      getcon(&mysid);
-+                      context[0] = '\0';
-+                      if (mysid) {
-+                                      len = strlen(mysid)+1;
-+                                      safe_strncpy(context, mysid, len);
-+                                      freecon(mysid);
-+                      }else{
-+                                      safe_strncpy(context, "unknown",8);
-+                      }
-               bb_printf(" context=%s", context);
-       }
- #endif
-+
-       putchar('\n');
-       bb_fflush_stdout_and_exit(status);
- }
-diff -Nur busybox-1.00/coreutils/install.c busybox/coreutils/install.c
---- busybox-1.00/coreutils/install.c   2004-04-25 07:11:14.000000000 +0200
-+++ busybox/coreutils/install.c        2005-06-04 08:20:13.000000000 +0200
-@@ -69,7 +69,7 @@
-       flags = bb_getopt_ulflags(argc, argv, "cdpsg:m:o:", &gid_str, &mode_str, &uid_str);     /* 'a' must be 2nd */
-       /* Check valid options were given */
--      if(flags & 0x80000000UL) {
-+      if(flags & BB_GETOPT_ERROR) {
-               bb_show_usage();
-       }
-diff -Nur busybox-1.00/coreutils/ln.c busybox/coreutils/ln.c
---- busybox-1.00/coreutils/ln.c        2004-03-15 09:28:20.000000000 +0100
-+++ busybox/coreutils/ln.c     2005-06-04 08:20:13.000000000 +0200
-@@ -21,21 +21,20 @@
-  */
- /* BB_AUDIT SUSv3 compliant */
--/* BB_AUDIT GNU options missing: -b, -d, -F, -i, -S, and -v. */
-+/* BB_AUDIT GNU options missing: -d, -F, -i, and -v. */
- /* http://www.opengroup.org/onlinepubs/007904975/utilities/ln.html */
--/* Mar 16, 2003      Manuel Novoa III   (mjn3@codepoet.org)
-- *
-- * Fixed bug involving -n option.  Essentially, -n was always in effect.
-- */
--
-+#include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
-+#include <errno.h>
- #include "busybox.h"
- #define LN_SYMLINK          1
- #define LN_FORCE            2
- #define LN_NODEREFERENCE    4
-+#define LN_BACKUP           8
-+#define LN_SUFFIX           16
- extern int ln_main(int argc, char **argv)
- {
-@@ -44,10 +43,11 @@
-       char *last;
-       char *src_name;
-       char *src;
-+      char *suffix = "~";
-       struct stat statbuf;
-       int (*link_func)(const char *, const char *);
--      flag = bb_getopt_ulflags(argc, argv, "sfn");
-+      flag = bb_getopt_ulflags(argc, argv, "sfnbS:", &suffix);
-       if (argc == optind) {
-               bb_show_usage();
-@@ -80,7 +80,23 @@
-                       continue;
-               }
--              if (flag & LN_FORCE) {
-+              if (flag & LN_BACKUP) {
-+                              char *backup = NULL;
-+                              bb_xasprintf(&backup, "%s%s", src, suffix);
-+                              if (rename(src, backup) < 0 && errno != ENOENT) {
-+                                              bb_perror_msg(src);
-+                                              status = EXIT_FAILURE;
-+                                              free(backup);
-+                                              continue;
-+                              }
-+                              free(backup);
-+                              /*
-+                               * When the source and dest are both hard links to the same
-+                               * inode, a rename may succeed even though nothing happened.
-+                               * Therefore, always unlink().
-+                               */
-+                              unlink(src);
-+              } else if (flag & LN_FORCE) {
-                       unlink(src);
-               }
-diff -Nur busybox-1.00/coreutils/ls.c busybox/coreutils/ls.c
---- busybox-1.00/coreutils/ls.c        2004-09-24 04:04:13.000000000 +0200
-+++ busybox/coreutils/ls.c     2005-06-04 08:20:13.000000000 +0200
-@@ -64,9 +64,7 @@
- #include <sys/sysmacros.h>     /* major() and minor() */
- #include "busybox.h"
- #ifdef CONFIG_SELINUX
--#include <fs_secure.h>
--#include <flask_util.h>
--#include <ss.h>
-+#include <selinux/selinux.h>   /* for is_selinux_enabled() */
- #endif
- #ifdef CONFIG_FEATURE_LS_TIMESTAMPS
-@@ -182,7 +180,7 @@
-       char *fullname;         /* the dir entry name */
-       struct stat dstat;      /* the file stat info */
- #ifdef CONFIG_SELINUX
--      security_id_t sid;
-+      security_context_t sid;
- #endif
-       struct dnode *next;     /* point at the next node */
- };
-@@ -195,7 +193,7 @@
- static unsigned int all_fmt;
- #ifdef CONFIG_SELINUX
--static int is_flask_enabled_flag;
-+static int selinux_enabled= 0;
- #endif
- #ifdef CONFIG_FEATURE_AUTOWIDTH
-@@ -213,18 +211,19 @@
-       struct stat dstat;
-       struct dnode *cur;
- #ifdef CONFIG_SELINUX
--      security_id_t sid;
-+      security_context_t sid=NULL;
- #endif
-       int rc;
- #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS
-       if (all_fmt & FOLLOW_LINKS) {
- #ifdef CONFIG_SELINUX
--              if(is_flask_enabled_flag)
--                      rc = stat_secure(fullname, &dstat, &sid);
--              else
-+              if (is_selinux_enabled())  {
-+                rc=0; /*  Set the number which means success before hand.  */
-+                rc = getfilecon(fullname,&sid);
-+              }
- #endif
--                      rc = stat(fullname, &dstat);
-+                rc = stat(fullname, &dstat);
-               if(rc)
-               {
-                       bb_perror_msg("%s", fullname);
-@@ -235,11 +234,12 @@
- #endif
-       {
- #ifdef CONFIG_SELINUX
--              if(is_flask_enabled_flag)
--                      rc = lstat_secure(fullname, &dstat, &sid);
--              else
-+              if  (is_selinux_enabled())  {
-+                rc=0; /*  Set the number which means success before hand.  */
-+                rc = lgetfilecon(fullname,&sid);
-+              }
- #endif
--                      rc = lstat(fullname, &dstat);
-+              rc = lstat(fullname, &dstat);
-               if(rc)
-               {
-                       bb_perror_msg("%s", fullname);
-@@ -736,12 +736,16 @@
- #ifdef CONFIG_SELINUX
-               case LIST_CONTEXT:
-                       {
--                              char context[64];
--                              int len = sizeof(context);
--                              if(security_sid_to_context(dn->sid, context, &len))
--                              {
--                                      strcpy(context, "unknown");
--                                      len = 7;
-+                              char context[80];
-+                              int len;
-+                      
-+                              if (dn->sid) {
-+                                /*  I assume sid initilized with NULL  */
-+                                len = strlen(dn->sid)+1;
-+                                safe_strncpy(context, dn->sid, len);
-+                                freecon(dn->sid);
-+                              }else {
-+                                safe_strncpy(context, "unknown",8);
-                               }
-                               printf("%-32s ", context);
-                               column += MAX(33, len);
-@@ -963,10 +967,6 @@
-       char *terminal_width_str = NULL;
- #endif
--#ifdef CONFIG_SELINUX
--      is_flask_enabled_flag = is_flask_enabled();
--#endif
--
-       all_fmt = LIST_SHORT | DISP_NORMAL | STYLE_AUTO
- #ifdef CONFIG_FEATURE_LS_TIMESTAMPS
-               | TIME_MOD
-diff -Nur busybox-1.00/coreutils/md5_sha1_sum.c busybox/coreutils/md5_sha1_sum.c
---- busybox-1.00/coreutils/md5_sha1_sum.c      2004-04-14 19:51:09.000000000 +0200
-+++ busybox/coreutils/md5_sha1_sum.c   2005-06-04 08:20:13.000000000 +0200
-@@ -49,38 +49,25 @@
- static uint8_t *hash_file(const char *filename, uint8_t hash_algo)
- {
--      uint8_t *hash_value_bin;
--      uint8_t *hash_value = NULL;
--      uint8_t hash_length;
--      int src_fd;
--
--      if (strcmp(filename, "-") == 0) {
--              src_fd = STDIN_FILENO;
--      } else {
--              src_fd = open(filename, O_RDONLY);
--      }
--
--      if (hash_algo == HASH_MD5) {
--              hash_length = 16;
--      } else {
--              hash_length = 20;
--      }
--
--      hash_value_bin = xmalloc(hash_length);
--
--      if ((src_fd != -1) && (hash_fd(src_fd, -1, hash_algo, hash_value_bin) != -2)) {
--              hash_value = hash_bin_to_hex(hash_value_bin, hash_length);
--      } else {
-+      int src_fd = strcmp(filename, "-") == 0 ? STDIN_FILENO :
-+              open(filename, O_RDONLY);
-+      if (src_fd == -1) {
-               bb_perror_msg("%s", filename);
-+              return NULL;
-+      } else {
-+              uint8_t *hash_value;
-+              RESERVE_CONFIG_UBUFFER(hash_value_bin, 20);
-+              hash_value = hash_fd(src_fd, -1, hash_algo, hash_value_bin) != -2 ?
-+                      hash_bin_to_hex(hash_value_bin, hash_algo == HASH_MD5 ? 16 : 20) :
-+                      NULL;
-+              RELEASE_CONFIG_BUFFER(hash_value_bin);
-+              close(src_fd);
-+              return hash_value;
-       }
--
--      close(src_fd);
--
--      return(hash_value);
- }
- /* This could become a common function for md5 as well, by using md5_stream */
--extern int hash_files(int argc, char **argv, const uint8_t hash_algo)
-+static int hash_files(int argc, char **argv, const uint8_t hash_algo)
- {
-       int return_value = EXIT_SUCCESS;
-       uint8_t *hash_value;
-diff -Nur busybox-1.00/coreutils/nice.c busybox/coreutils/nice.c
---- busybox-1.00/coreutils/nice.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/coreutils/nice.c   2005-06-04 08:20:13.000000000 +0200
-@@ -0,0 +1,86 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * nice implementation for busybox
-+ *
-+ * Copyright (C) 2005  Manuel Novoa III  <mjn3@codepoet.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <limits.h>
-+#include <errno.h>
-+#include <unistd.h>
-+#include <sys/time.h>
-+#include <sys/resource.h>
-+#include "busybox.h"
-+
-+static inline int int_add_no_wrap(int a, int b)
-+{
-+      int s = a + b;
-+
-+      if (b < 0) {
-+              if (s > a) s = INT_MIN;
-+      } else {
-+              if (s < a) s = INT_MAX;
-+      }
-+
-+      return s;
-+}
-+
-+int nice_main(int argc, char **argv)
-+{
-+      static const char Xetpriority_msg[] = "cannot %cet priority";
-+
-+      int old_priority, adjustment;
-+
-+      errno = 0;                       /* Needed for getpriority error detection. */
-+      old_priority = getpriority(PRIO_PROCESS, 0);
-+      if (errno) {
-+              bb_perror_msg_and_die(Xetpriority_msg, 'g');
-+      }
-+
-+      if (!*++argv) { /* No args, so (GNU) output current nice value. */
-+              bb_printf("%d\n", old_priority);
-+              bb_fflush_stdout_and_exit(EXIT_SUCCESS);
-+      }
-+
-+      adjustment = 10;                        /* Set default adjustment. */
-+
-+      if ((argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) { /* "-n" */
-+              if (argc < 4) {                 /* Missing priority and/or utility! */
-+                      bb_show_usage();
-+              }
-+              adjustment = bb_xgetlarg(argv[1], 10, INT_MIN, INT_MAX);
-+              argv += 2;
-+      }
-+
-+      {  /* Set our priority.  Handle integer wrapping for old + adjust. */
-+              int new_priority = int_add_no_wrap(old_priority, adjustment);
-+
-+              if (setpriority(PRIO_PROCESS, 0, new_priority) < 0) {
-+                      bb_perror_msg_and_die(Xetpriority_msg, 's');
-+              }
-+      }
-+      
-+      execvp(*argv, argv);            /* Now exec the desired program. */
-+
-+      /* The exec failed... */
-+      bb_default_error_retval = (errno == ENOENT) ? 127 : 126; /* SUSv3 */
-+      bb_perror_msg_and_die("%s", *argv);
-+}
-diff -Nur busybox-1.00/coreutils/printenv.c busybox/coreutils/printenv.c
---- busybox-1.00/coreutils/printenv.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/coreutils/printenv.c       2005-06-04 08:20:13.000000000 +0200
-@@ -0,0 +1,53 @@
-+/*
-+ * printenv implementation for busybox
-+ *
-+ * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
-+ * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include "busybox.h"
-+
-+int printenv_main(int argc, char **argv)
-+{
-+      extern char **environ;
-+      int e = 0;
-+
-+      /* no variables specified, show whole env */
-+      if (argc == 1)
-+              while (environ[e])
-+                      puts(environ[e++]);
-+
-+      /* search for specified variables and print them out if found */
-+      else {
-+              int i;
-+              size_t l;
-+              char *arg, *env;
-+
-+              for (i=1; (arg = argv[i]); ++i)
-+                      for (; (env = environ[e]); ++e) {
-+                              l = strlen(arg);
-+                              if (!strncmp(env, arg, l) && env[l] == '=')
-+                                      puts(env + l + 1);
-+                      }
-+      }
-+
-+      bb_fflush_stdout_and_exit(0);
-+}
-diff -Nur busybox-1.00/coreutils/sort.c busybox/coreutils/sort.c
---- busybox-1.00/coreutils/sort.c      2003-03-19 10:11:34.000000000 +0100
-+++ busybox/coreutils/sort.c   2005-06-04 08:20:13.000000000 +0200
-@@ -1,8 +1,8 @@
- /* vi: set sw=4 ts=4: */
- /*
-- * Mini sort implementation for busybox
-+ * SuS3 compliant sort implementation for busybox
-  *
-- * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
-+ * Copyright (C) 2004 by Rob Landley <rob@landley.net>
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -18,83 +18,321 @@
-  * along with this program; if not, write to the Free Software
-  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-  *
-+ * See SuS3 sort standard at:
-+ * http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html
-  */
--/* BB_AUDIT SUSv3 _NOT_ compliant -- a number of options are not supported. */
--/* http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html */
--
--/* Mar 16, 2003      Manuel Novoa III   (mjn3@codepoet.org)
-- *
-- * Now does proper error checking on i/o.  Plus some space savings.
-- */
--
-+#include <ctype.h>
-+#include <math.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-+#include <time.h>
- #include <unistd.h>
- #include "busybox.h"
--#include "libcoreutils/coreutils.h"
--static int compare_ascii(const void *x, const void *y)
-+static int global_flags;
-+
-+/*
-+      sort [-m][-o output][-bdfinru][-t char][-k keydef]... [file...]
-+      sort -c [-bdfinru][-t char][-k keydef][file]
-+*/
-+
-+/* These are sort types */
-+#define FLAG_n                        1               /* Numeric sort */
-+#define FLAG_g                        2               /* Sort using strtod() */
-+#define FLAG_M                        4               /* Sort date */
-+/* ucsz apply to root level only, not keys.  b at root level implies bb */
-+#define FLAG_u                        8               /* Unique */
-+#define FLAG_c                        16              /* Check: no output, exit(!ordered) */
-+#define FLAG_s                        32              /* Stable sort, no ascii fallback at end */
-+#define FLAG_z                        64              /* Input is null terminated, not \n */
-+/* These can be applied to search keys, the previous four can't */
-+#define FLAG_b                        128             /* Ignore leading blanks */
-+#define FLAG_r                        256             /* Reverse */
-+#define FLAG_d                        512             /* Ignore !(isalnum()|isspace()) */
-+#define FLAG_f                        1024    /* Force uppercase */
-+#define FLAG_i                        2048    /* Ignore !isprint() */
-+#define FLAG_bb                       32768   /* Ignore trailing blanks  */
-+
-+
-+#ifdef CONFIG_SORT_BIG
-+static char key_separator;
-+
-+static struct sort_key
- {
--      return strcmp(*(char **)x, *(char **)y);
--}
-+      struct sort_key *next_key;      /* linked list */
-+      unsigned short range[4];        /* start word, start char, end word, end char */
-+      int flags;
-+} *key_list;
--static int compare_numeric(const void *x, const void *y)
-+static char *get_key(char *str, struct sort_key *key, int flags)
- {
--      int z = atoi(*(char **)x) - atoi(*(char **)y);
--      return z ? z : strcmp(*(char **)x, *(char **)y);
-+      int start=0,end,len,i,j;
-+
-+      /* Special case whole string, so we don't have to make a copy */
-+      if(key->range[0]==1 && !key->range[1] && !key->range[2] && !key->range[3]
-+              && !(flags&(FLAG_b&FLAG_d&FLAG_f&FLAG_i&FLAG_bb))) return str;
-+      /* Find start of key on first pass, end on second pass*/
-+      len=strlen(str);
-+
-+      for(j=0;j<2;j++) {
-+              if(!key->range[2*j]) end=len;
-+              /* Loop through fields */
-+              else {
-+                      end=0;
-+                      for(i=1;i<key->range[2*j]+j;i++) {
-+                              /* Skip leading blanks or first separator */
-+                              if(str[end]) {
-+                                      if(key_separator) {
-+                                              if(str[end]==key_separator) end++;
-+                                      } else if(isspace(str[end]))
-+                                              while(isspace(str[end])) end++;
-+                              }
-+                              /* Skip body of key */
-+                              for(;str[end];end++) {
-+                                      if(key_separator) {
-+                                              if(str[end]==key_separator) break;
-+                                      } else if(isspace(str[end])) break;
-+                              }
-+                      }
-+              }
-+              if(!j) start=end;
-+      }
-+      /* Key with explicit separator starts after separator */
-+      if(key_separator && str[start]==key_separator) start++;
-+      /* Strip leading whitespace if necessary */
-+      if(flags&FLAG_b) while(isspace(str[start])) start++;
-+      /* Strip trailing whitespace if necessary */
-+      if(flags&FLAG_bb) while(end>start && isspace(str[end-1])) end--;
-+      /* Handle offsets on start and end */
-+      if(key->range[3]) {
-+              end+=key->range[3]-1;
-+              if(end>len) end=len;
-+      }
-+      if(key->range[1]) {
-+              start+=key->range[1]-1;
-+              if(start>len) start=len;
-+      }
-+      /* Make the copy */
-+      if(end<start) end=start;
-+      str=bb_xstrndup(str+start,end-start);
-+      /* Handle -d */
-+      if(flags&FLAG_d) {
-+              for(start=end=0;str[end];end++)
-+                      if(isspace(str[end]) || isalnum(str[end])) str[start++]=str[end];
-+              str[start]=0;
-+      }
-+      /* Handle -i */
-+      if(flags&FLAG_i) {
-+              for(start=end=0;str[end];end++)
-+                      if(isprint(str[end])) str[start++]=str[end];
-+              str[start]=0;
-+      }
-+      /* Handle -f */
-+      if(flags*FLAG_f) for(i=0;str[i];i++) str[i]=toupper(str[i]);
-+
-+      return str;
- }
--int sort_main(int argc, char **argv)
-+static struct sort_key *add_key(void)
- {
--      FILE *fp;
--      char *line, **lines = NULL;
--      int i, nlines = 0, inc;
--      int (*compare)(const void *, const void *) = compare_ascii;
-+      struct sort_key **pkey=&key_list;
-+      while(*pkey) pkey=&((*pkey)->next_key);
-+      return *pkey=xcalloc(1,sizeof(struct sort_key));
-+}
--      int flags;
-+#define GET_LINE(fp) (global_flags&FLAG_z) ? bb_get_chunk_from_file(fp) \
-+                                                                                 : bb_get_chomped_line_from_file(fp)
-+#else
-+#define GET_LINE(fp)          bb_get_chomped_line_from_file(fp)
-+#endif
--      bb_default_error_retval = 2;
-+/* Iterate through keys list and perform comparisons */
-+static int compare_keys(const void *xarg, const void *yarg)
-+{
-+      int flags=global_flags,retval=0;
-+      char *x,*y;
--      flags = bb_getopt_ulflags(argc, argv, "nru");
--      if (flags & 1) {
--              compare = compare_numeric;
-+#ifdef CONFIG_SORT_BIG
-+      struct sort_key *key;
-+      
-+      for(key=key_list;!retval && key;key=key->next_key) {
-+              flags=(key->flags) ? key->flags : global_flags;
-+              /* Chop out and modify key chunks, handling -dfib */
-+              x=get_key(*(char **)xarg,key,flags);
-+              y=get_key(*(char **)yarg,key,flags);
-+#else
-+      /* This curly bracket serves no purpose but to match the nesting
-+         level of the for() loop we're not using */
-+      {
-+              x=*(char **)xarg;
-+              y=*(char **)yarg;
-+#endif
-+              /* Perform actual comparison */
-+              switch(flags&7) {
-+                      default:
-+                              bb_error_msg_and_die("Unknown sort type.");
-+                              break;
-+                      /* Ascii sort */
-+                      case 0:
-+                              retval=strcmp(x,y);
-+                              break;
-+#ifdef CONFIG_SORT_BIG
-+                      case FLAG_g:
-+                      {
-+                              char *xx,*yy;
-+                              double dx=strtod(x,&xx), dy=strtod(y,&yy);
-+                              /* not numbers < NaN < -infinity < numbers < +infinity) */
-+                              if(x==xx) retval=(y==yy ? 0 : -1);
-+                              else if(y==yy) retval=1;
-+                              else if(isnan(dx)) retval=isnan(dy) ? 0 : -1;
-+                              else if(isnan(dy)) retval=1;
-+                              else if(isinf(dx)) {
-+                                      if(dx<0) retval=((isinf(dy) && dy<0) ? 0 : -1);
-+                                      else retval=((isinf(dy) && dy>0) ? 0 : 1);
-+                              } else if(isinf(dy)) retval=dy<0 ? 1 : -1;
-+                              else retval=dx>dy ? 1 : (dx<dy ? -1 : 0);
-+                              break;
-+                      }
-+                      case FLAG_M:
-+                      {
-+                              struct tm thyme;
-+                              int dx;
-+                              char *xx,*yy;
-+
-+                              xx=strptime(x,"%b",&thyme);
-+                              dx=thyme.tm_mon;
-+                              yy=strptime(y,"%b",&thyme);
-+                              if(!xx) retval=(!yy ? 0 : -1);
-+                              else if(!yy) retval=1;
-+                              else retval=(dx==thyme.tm_mon ? 0 : dx-thyme.tm_mon);
-+                              break;
-+                      }
-+                      /* Full floating point version of -n */
-+                      case FLAG_n:
-+                      {
-+                              double dx=atof(x),dy=atof(y);
-+                              retval=dx>dy ? 1 : (dx<dy ? -1 : 0);
-+                              break;
-+                      }
-+              }
-+              /* Free key copies. */
-+              if(x!=*(char **)xarg) free(x);
-+              if(y!=*(char **)yarg) free(y);
-+              if(retval) break;
-+#else
-+                      /* Integer version of -n for tiny systems */
-+                      case FLAG_n:
-+                              retval=atoi(x)-atoi(y);
-+                              break;
-+              }
-+#endif
-       }
-+      /* Perform fallback sort if necessary */
-+      if(!retval && !(global_flags&FLAG_s))
-+                      retval=strcmp(*(char **)xarg, *(char **)yarg);
-+      return ((flags&FLAG_r)?-1:1)*retval;
-+}
--      argv += optind;
--      if (!*argv) {
--              *--argv = "-";
--      }
-+int sort_main(int argc, char **argv)
-+{
-+      FILE *fp,*outfile=NULL;
-+      int linecount=0,i,flag;
-+      char *line,**lines=NULL,c,*optlist="ngMucszbrdfimS:T:o:k:t:";
--      do {
--              fp = xgetoptfile_sort_uniq(argv, "r");
--              while ((line = bb_get_chomped_line_from_file(fp)) != NULL) {
--                      lines = xrealloc(lines, sizeof(char *) * (nlines + 1));
--                      lines[nlines++] = line;
-+      bb_default_error_retval = 2;
-+      /* Parse command line options */
-+      while((c=getopt(argc,argv,optlist))>0) {
-+              line=index(optlist,c);
-+              if(!line) bb_show_usage();
-+              switch(*line) {
-+#ifdef CONFIG_SORT_BIG
-+                      case 'o':
-+                              if(outfile) bb_error_msg_and_die("Too many -o.");
-+                              outfile=bb_xfopen(optarg,"w");
-+                              break;
-+                      case 't':
-+                              if(key_separator || optarg[1])
-+                                      bb_error_msg_and_die("Too many -t.");
-+                              key_separator=*optarg;
-+                              break;
-+                      /* parse sort key */
-+                      case 'k':
-+                      {
-+                              struct sort_key *key=add_key();
-+                              char *temp, *temp2;
-+
-+                              temp=optarg;
-+                              for(i=0;*temp;) {
-+                                      /* Start of range */
-+                                      key->range[2*i]=(unsigned short)strtol(temp,&temp,10);
-+                                      if(*temp=='.')
-+                                              key->range[(2*i)+1]=(unsigned short)strtol(temp+1,&temp,10);
-+                                      for(;*temp;temp++) {
-+                                              if(*temp==',' && !i++) {
-+                                                      temp++;
-+                                                      break;
-+                                              } /* no else needed: fall through to syntax error
-+                                                       because comma isn't in optlist */
-+                                              temp2=index(optlist,*temp);
-+                                              flag=(1<<(temp2-optlist));
-+                                              if(!temp2 || (flag>FLAG_M && flag<FLAG_b))
-+                                                      bb_error_msg_and_die("Unknown key option.");
-+                                              /* b after , means strip _trailing_ space */
-+                                              if(i && flag==FLAG_b) flag=FLAG_bb;
-+                                              key->flags|=flag;
-+                                      }
-+                              }
-+                              break;
-+                      }
-+#endif
-+                      default:
-+                              global_flags|=(1<<(line-optlist));
-+                              /* global b strips leading and trailing spaces */
-+                              if(global_flags&FLAG_b) global_flags|=FLAG_bb;
-+                              break;
-               }
--              bb_xferror(fp, *argv);
--              bb_fclose_nonstdin(fp);
--      } while (*++argv);
--
--      /* sort it */
--      qsort(lines, nlines, sizeof(char *), compare);
--
--      /* print it */
--      i = 0;
--      --nlines;
--      if ((inc = 1 - (flags & 2)) < 0) {      /* reverse */
--              i = nlines;
-       }
--      flags &= 4;
--
--      while (nlines >= 0) {
--              if (!flags || !nlines || strcmp(lines[i+inc], lines[i])) {
--                      puts(lines[i]);
-+      /* Open input files and read data */
-+      for(i=argv[optind] ? optind : optind-1;argv[i];i++) {
-+              if(i<optind || (*argv[i]=='-' && !argv[i][1])) fp=stdin;
-+              else fp=bb_xfopen(argv[i],"r");
-+              for(;;) {
-+                      line=GET_LINE(fp);
-+                      if(!line) break;
-+                      if(!(linecount&63))
-+                              lines=xrealloc(lines, sizeof(char *)*(linecount+64));
-+                      lines[linecount++]=line;
-               }
--              i += inc;
--              --nlines;
-+              fclose(fp);
-       }
--
-+#ifdef CONFIG_SORT_BIG
-+      /* if no key, perform alphabetic sort */
-+    if(!key_list) add_key()->range[0]=1;
-+      /* handle -c */ 
-+      if(global_flags&FLAG_c) {
-+              int j=(global_flags&FLAG_u) ? -1 : 0;
-+              for(i=1;i<linecount;i++)
-+                      if(compare_keys(&lines[i-1],&lines[i])>j) {
-+                              fprintf(stderr,"Check line %d\n",i);
-+                              return 1;
-+                      }
-+              return 0;
-+      }
-+#endif
-+      /* Perform the actual sort */
-+      qsort(lines,linecount,sizeof(char *),compare_keys);
-+      /* handle -u */
-+      if(global_flags&FLAG_u) {
-+              for(flag=0,i=1;i<linecount;i++) {
-+                      if(!compare_keys(&lines[flag],&lines[i])) free(lines[i]);
-+                      else lines[++flag]=lines[i];
-+              }
-+              if(linecount) linecount=flag+1;
-+      }
-+      /* Print it */
-+      if(!outfile) outfile=stdout;
-+      for(i=0;i<linecount;i++) fprintf(outfile,"%s\n",lines[i]);
-       bb_fflush_stdout_and_exit(EXIT_SUCCESS);
- }
-diff -Nur busybox-1.00/coreutils/stat.c busybox/coreutils/stat.c
---- busybox-1.00/coreutils/stat.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/coreutils/stat.c   2005-06-04 08:20:13.000000000 +0200
-@@ -0,0 +1,564 @@
-+/*
-+ * stat -- display file or file system status
-+ *
-+ * Copyright (C) 2001, 2002, 2003, 2004, 2005 Free Software Foundation.
-+ * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
-+ * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
-+ *
-+ * Written by Michael Meskes
-+ * Taken from coreutils and turned into a busybox applet by Mike Frysinger
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <sys/types.h>
-+#include <pwd.h>
-+#include <grp.h>
-+#include <sys/vfs.h>
-+#include <time.h>
-+#include <getopt.h>
-+#include <sys/stat.h>
-+#include <string.h>
-+#include "busybox.h"
-+
-+/* vars to control behavior */
-+#define OPT_TERSE 2
-+#define OPT_DEREFERNCE 4
-+static long flags;
-+
-+static char const *file_type(struct stat const *st)
-+{
-+      /* See POSIX 1003.1-2001 XCU Table 4-8 lines 17093-17107 
-+       * for some of these formats.
-+       * To keep diagnostics grammatical in English, the 
-+       * returned string must start with a consonant.
-+       */
-+      if (S_ISREG(st->st_mode))  return st->st_size == 0 ? "regular empty file" : "regular file";
-+      if (S_ISDIR(st->st_mode))  return "directory";
-+      if (S_ISBLK(st->st_mode))  return "block special file";
-+      if (S_ISCHR(st->st_mode))  return "character special file";
-+      if (S_ISFIFO(st->st_mode)) return "fifo";
-+      if (S_ISLNK(st->st_mode))  return "symbolic link";
-+      if (S_ISSOCK(st->st_mode)) return "socket";
-+      if (S_TYPEISMQ(st))        return "message queue";
-+      if (S_TYPEISSEM(st))       return "semaphore";
-+      if (S_TYPEISSHM(st))       return "shared memory object";
-+#ifdef S_TYPEISTMO
-+      if (S_TYPEISTMO(st))       return "typed memory object";
-+#endif
-+      return "weird file";
-+}
-+
-+static char const *human_time(time_t t)
-+{
-+      static char *str;
-+      str = ctime(&t);
-+      str[strlen(str)-1] = '\0';
-+      return str;
-+}
-+
-+/* Return the type of the specified file system.
-+ * Some systems have statfvs.f_basetype[FSTYPSZ]. (AIX, HP-UX, and Solaris)
-+ * Others have statfs.f_fstypename[MFSNAMELEN]. (NetBSD 1.5.2)
-+ * Still others have neither and have to get by with f_type (Linux).
-+ */
-+static char const *human_fstype(long f_type)
-+{
-+      int i;
-+      static struct types {
-+              long type;
-+              char *fs;
-+      } humantypes[] = {
-+              { 0xADFF,     "affs" },
-+              { 0x1Cd1,     "devpts" },
-+              { 0x137D,     "ext" },
-+              { 0xEF51,     "ext2" },
-+              { 0xEF53,     "ext2/ext3" },
-+              { 0x3153464a, "jfs" },
-+              { 0x58465342, "xfs" },
-+              { 0xF995E849, "hpfs" },
-+              { 0x9660,     "isofs" },
-+              { 0x4000,     "isofs" },
-+              { 0x4004,     "isofs" },
-+              { 0x137F,     "minix" },
-+              { 0x138F,     "minix (30 char.)" },
-+              { 0x2468,     "minix v2" },
-+              { 0x2478,     "minix v2 (30 char.)" },
-+              { 0x4d44,     "msdos" },
-+              { 0x4006,     "fat" },
-+              { 0x564c,     "novell" },
-+              { 0x6969,     "nfs" },
-+              { 0x9fa0,     "proc" },
-+              { 0x517B,     "smb" },
-+              { 0x012FF7B4, "xenix" },
-+              { 0x012FF7B5, "sysv4" },
-+              { 0x012FF7B6, "sysv2" },
-+              { 0x012FF7B7, "coh" },
-+              { 0x00011954, "ufs" },
-+              { 0x012FD16D, "xia" },
-+              { 0x5346544e, "ntfs" },
-+              { 0x1021994,  "tmpfs" },
-+              { 0x52654973, "reiserfs" },
-+              { 0x28cd3d45, "cramfs" },
-+              { 0x7275,     "romfs" },
-+              { 0x858458f6, "romfs" },
-+              { 0x73717368, "squashfs" },
-+              { 0x62656572, "sysfs" },
-+              { 0, "UNKNOWN" },
-+              { 0, NULL }
-+      };
-+      for (i=0; humantypes[i].type; ++i)
-+              if (humantypes[i].type == f_type)
-+                      return humantypes[i].fs;
-+      return humantypes[i].fs;
-+}
-+
-+#ifdef CONFIG_FEATURE_STAT_FORMAT
-+/* print statfs info */
-+static void print_statfs(char *pformat, size_t buf_len, char m, 
-+                         char const *filename, void const *data)
-+{
-+      struct statfs const *statfsbuf = data;
-+
-+      switch (m) {
-+      case 'n':
-+              strncat(pformat, "s", buf_len);
-+              printf(pformat, filename);
-+              break;
-+      case 'i':
-+              strncat(pformat, "Lx", buf_len);
-+              printf(pformat, statfsbuf->f_fsid);
-+              break;
-+      case 'l':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, statfsbuf->f_namelen);
-+              break;
-+      case 't':
-+              strncat(pformat, "lx", buf_len);
-+              printf(pformat, (unsigned long int) (statfsbuf->f_type));  /* no equiv. */
-+              break;
-+      case 'T':
-+              strncat(pformat, "s", buf_len);
-+              printf(pformat, human_fstype(statfsbuf->f_type));
-+              break;
-+      case 'b':
-+              strncat(pformat, "ld", buf_len);
-+              printf(pformat, (intmax_t) (statfsbuf->f_blocks));
-+              break;
-+      case 'f':
-+              strncat(pformat, "ld", buf_len);
-+              printf(pformat, (intmax_t) (statfsbuf->f_bfree));
-+              break;
-+      case 'a':
-+              strncat(pformat, "ld", buf_len);
-+              printf(pformat, (intmax_t) (statfsbuf->f_bavail));
-+              break;
-+      case 's':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, (unsigned long int) (statfsbuf->f_bsize));
-+              break;
-+      case 'S': {
-+              unsigned long int frsize = statfsbuf->f_frsize;
-+              if (!frsize)
-+                      frsize = statfsbuf->f_bsize;
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, frsize);
-+              break;
-+      }
-+      case 'c':
-+              strncat(pformat, "ld", buf_len);
-+              printf(pformat, (intmax_t) (statfsbuf->f_files));
-+              break;
-+      case 'd':
-+              strncat(pformat, "ld", buf_len);
-+              printf(pformat, (intmax_t) (statfsbuf->f_ffree));
-+              break;
-+      default:
-+              strncat(pformat, "c", buf_len);
-+              printf(pformat, m);
-+              break;
-+      }
-+}
-+
-+/* print stat info */
-+static void print_stat(char *pformat, size_t buf_len, char m, 
-+                       char const *filename, void const *data)
-+{
-+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
-+      struct stat *statbuf = (struct stat *) data;
-+      struct passwd *pw_ent;
-+      struct group *gw_ent;
-+
-+      switch (m) {
-+      case 'n':
-+              strncat(pformat, "s", buf_len);
-+              printf(pformat, filename);
-+              break;
-+      case 'N':
-+              strncat(pformat, "s", buf_len);
-+              if (S_ISLNK(statbuf->st_mode)) {
-+                      char *linkname = xreadlink(filename);
-+                      if (linkname == NULL) {
-+                              bb_perror_msg("cannot read symbolic link '%s'", filename);
-+                              return;
-+                      }
-+                      /*printf("\"%s\" -> \"%s\"", filename, linkname); */
-+                      printf(pformat, filename);
-+                      printf(" -> ");
-+                      printf(pformat, linkname);
-+              } else {
-+                      printf(pformat, filename);
-+              }
-+              break;
-+      case 'd':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, (uintmax_t) statbuf->st_dev);
-+              break;
-+      case 'D':
-+              strncat(pformat, "lx", buf_len);
-+              printf(pformat, (uintmax_t) statbuf->st_dev);
-+              break;
-+      case 'i':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, (uintmax_t) statbuf->st_ino);
-+              break;
-+      case 'a':
-+              strncat(pformat, "lo", buf_len);
-+              printf(pformat, (unsigned long int) (statbuf->st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)));
-+              break;
-+      case 'A':
-+              strncat(pformat, "s", buf_len);
-+              printf(pformat, bb_mode_string(statbuf->st_mode));
-+              break;
-+      case 'f':
-+              strncat(pformat, "lx", buf_len);
-+              printf(pformat, (unsigned long int) statbuf->st_mode);
-+              break;
-+      case 'F':
-+              strncat(pformat, "s", buf_len);
-+              printf(pformat, file_type(statbuf));
-+              break;
-+      case 'h':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, (unsigned long int) statbuf->st_nlink);
-+              break;
-+      case 'u':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, (unsigned long int) statbuf->st_uid);
-+              break;
-+      case 'U':
-+              strncat(pformat, "s", buf_len);
-+              setpwent();
-+              pw_ent = getpwuid(statbuf->st_uid);
-+              printf(pformat, (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN");
-+              break;
-+      case 'g':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, (unsigned long int) statbuf->st_gid);
-+              break;
-+      case 'G':
-+              strncat(pformat, "s", buf_len);
-+              setgrent();
-+              gw_ent = getgrgid(statbuf->st_gid);
-+              printf(pformat, (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN");
-+              break;
-+      case 't':
-+              strncat(pformat, "lx", buf_len);
-+              printf(pformat, (unsigned long int) major(statbuf->st_rdev));
-+              break;
-+      case 'T':
-+              strncat(pformat, "lx", buf_len);
-+              printf(pformat, (unsigned long int) minor(statbuf->st_rdev));
-+              break;
-+      case 's':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, (uintmax_t) (statbuf->st_size));
-+              break;
-+      case 'B':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, (unsigned long int) 512); //ST_NBLOCKSIZE
-+              break;
-+      case 'b':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, (uintmax_t) statbuf->st_blocks);
-+              break;
-+      case 'o':
-+              strncat(pformat, "lu", buf_len);
-+              printf(pformat, (unsigned long int) statbuf->st_blksize);
-+              break;
-+      case 'x':
-+              strncat(pformat, "s", buf_len);
-+              printf(pformat, human_time(statbuf->st_atime));
-+              break;
-+      case 'X':
-+              strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
-+              printf(pformat, (unsigned long int) statbuf->st_atime);
-+              break;
-+      case 'y':
-+              strncat(pformat, "s", buf_len);
-+              printf(pformat, human_time(statbuf->st_mtime));
-+              break;
-+      case 'Y':
-+              strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
-+              printf(pformat, (unsigned long int) statbuf->st_mtime);
-+              break;
-+      case 'z':
-+              strncat(pformat, "s", buf_len);
-+              printf(pformat, human_time(statbuf->st_ctime));
-+              break;
-+      case 'Z':
-+              strncat(pformat, TYPE_SIGNED(time_t) ? "ld" : "lu", buf_len);
-+              printf(pformat, (unsigned long int) statbuf->st_ctime);
-+              break;
-+      default:
-+              strncat(pformat, "c", buf_len);
-+              printf(pformat, m);
-+              break;
-+      }
-+}
-+
-+static void print_it(char const *masterformat, char const *filename, 
-+                     void (*print_func) (char *, size_t, char, char const *, void const *), 
-+                     void const *data)
-+{
-+      char *b;
-+
-+      /* create a working copy of the format string */
-+      char *format = bb_xstrdup(masterformat);
-+
-+      /* Add 2 to accommodate our conversion of the stat `%s' format string
-+       * to the printf `%llu' one.  */
-+      size_t n_alloc = strlen(format) + 2 + 1;
-+      char *dest = xmalloc(n_alloc);
-+
-+      b = format;
-+      while (b) {
-+              char *p = strchr(b, '%');
-+              if (p != NULL) {
-+                      size_t len;
-+                      *p++ = '\0';
-+                      fputs(b, stdout);
-+
-+                      len = strspn(p, "#-+.I 0123456789");
-+                      dest[0] = '%';
-+                      memcpy(dest + 1, p, len);
-+                      dest[1 + len] = 0;
-+                      p += len;
-+
-+                      b = p + 1;
-+                      switch (*p) {
-+                              case '\0':
-+                                      b = NULL;
-+                                      /* fall through */
-+                              case '%':
-+                                      putchar('%');
-+                                      break;
-+                              default:
-+                                      print_func(dest, n_alloc, *p, filename, data);
-+                                      break;
-+                      }
-+
-+              } else {
-+                      fputs(b, stdout);
-+                      b = NULL;
-+              }
-+      }
-+
-+      free(format);
-+      free(dest);
-+}
-+#endif
-+
-+/* Stat the file system and print what we find.  */
-+static int do_statfs(char const *filename, char const *format)
-+{
-+      struct statfs statfsbuf;
-+
-+      if (statfs(filename, &statfsbuf) != 0) {
-+              bb_perror_msg("cannot read file system information for '%s'", filename);
-+              return 0;
-+      }
-+
-+#ifdef CONFIG_FEATURE_STAT_FORMAT
-+      if (format == NULL)
-+              format = (flags & OPT_TERSE
-+                      ? "%n %i %l %t %s %S %b %f %a %c %d\n"
-+                      : "  File: \"%n\"\n"
-+                        "    ID: %-8i Namelen: %-7l Type: %T\n"
-+                        "Block size: %-10s Fundamental block size: %S\n"
-+                        "Blocks: Total: %-10b Free: %-10f Available: %a\n"
-+                        "Inodes: Total: %-10c Free: %d\n");
-+      print_it(format, filename, print_statfs, &statfsbuf);
-+#else
-+
-+      format = (flags & OPT_TERSE
-+              ? "%s %Lx %lu "
-+              : "  File: \"%s\"\n"
-+                "    ID: %-8Lx Namelen: %-7lu ");
-+      printf(format,
-+             filename,
-+             statfsbuf.f_fsid,
-+             statfsbuf.f_namelen);
-+
-+      if (flags & OPT_TERSE)
-+              printf("%lx ", (unsigned long int) (statfsbuf.f_type));
-+      else
-+              printf("Type: %s\n", human_fstype(statfsbuf.f_type));
-+
-+      format = (flags & OPT_TERSE
-+              ? "%lu %lu %ld %ld %ld %ld %ld\n"
-+              : "Block size: %-10lu Fundamental block size: %lu\n"
-+                "Blocks: Total: %-10ld Free: %-10ld Available: %ld\n"
-+                "Inodes: Total: %-10ld Free: %ld\n");
-+      printf(format,
-+             (unsigned long int) (statfsbuf.f_bsize),
-+             statfsbuf.f_frsize ? statfsbuf.f_frsize : statfsbuf.f_bsize,
-+             (intmax_t) (statfsbuf.f_blocks),
-+             (intmax_t) (statfsbuf.f_bfree),
-+             (intmax_t) (statfsbuf.f_bavail),
-+             (intmax_t) (statfsbuf.f_files),
-+             (intmax_t) (statfsbuf.f_ffree));
-+#endif
-+
-+      return 1;
-+}
-+
-+/* stat the file and print what we find */
-+static int do_stat(char const *filename, char const *format)
-+{
-+      struct stat statbuf;
-+
-+      if ((flags & OPT_DEREFERNCE ? stat : lstat) (filename, &statbuf) != 0) {
-+              bb_perror_msg("cannot stat '%s'", filename);
-+              return 0;
-+      }
-+
-+#ifdef CONFIG_FEATURE_STAT_FORMAT
-+      if (format == NULL) {
-+              if (flags & OPT_TERSE) {
-+                      format = "%n %s %b %f %u %g %D %i %h %t %T %X %Y %Z %o\n";
-+              } else {
-+                      if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode)) {
-+                              format =
-+                                      "  File: \"%N\"\n"
-+                                      "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
-+                                      "Device: %Dh/%dd\tInode: %-10i  Links: %-5h"
-+                                      " Device type: %t,%T\n"
-+                                      "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
-+                                      "Access: %x\n" "Modify: %y\n" "Change: %z\n";
-+                      } else {
-+                              format =
-+                                      "  File: \"%N\"\n"
-+                                      "  Size: %-10s\tBlocks: %-10b IO Block: %-6o %F\n"
-+                                      "Device: %Dh/%dd\tInode: %-10i  Links: %h\n"
-+                                      "Access: (%04a/%10.10A)  Uid: (%5u/%8U)   Gid: (%5g/%8G)\n"
-+                                      "Access: %x\n" "Modify: %y\n" "Change: %z\n";
-+                      }
-+              }
-+      }
-+      print_it(format, filename, print_stat, &statbuf);
-+#else
-+      if (flags & OPT_TERSE) {
-+              printf("%s %lu %lu %lx %lu %lu %lx %lu %lu %lx %lx %lu %lu %lu %lu\n",
-+                     filename,
-+                     (uintmax_t) (statbuf.st_size),
-+                     (uintmax_t) statbuf.st_blocks,
-+                     (unsigned long int) statbuf.st_mode,
-+                     (unsigned long int) statbuf.st_uid,
-+                     (unsigned long int) statbuf.st_gid,
-+                     (uintmax_t) statbuf.st_dev,
-+                     (uintmax_t) statbuf.st_ino,
-+                     (unsigned long int) statbuf.st_nlink,
-+                     (unsigned long int) major(statbuf.st_rdev),
-+                     (unsigned long int) minor(statbuf.st_rdev),
-+                     (unsigned long int) statbuf.st_atime,
-+                     (unsigned long int) statbuf.st_mtime,
-+                     (unsigned long int) statbuf.st_ctime,
-+                     (unsigned long int) statbuf.st_blksize
-+              );
-+      } else {
-+              char *linkname = NULL;
-+
-+              struct passwd *pw_ent;
-+              struct group *gw_ent;
-+              setgrent();
-+              gw_ent = getgrgid(statbuf.st_gid);
-+              setpwent();
-+              pw_ent = getpwuid(statbuf.st_uid);
-+
-+              if (S_ISLNK(statbuf.st_mode))
-+                      linkname = xreadlink(filename);
-+              if (linkname)
-+                      printf("  File: \"%s\" -> \"%s\"\n", filename, linkname);
-+              else
-+                      printf("  File: \"%s\"\n", filename);
-+
-+              printf("  Size: %-10lu\tBlocks: %-10lu IO Block: %-6lu %s\n"
-+                     "Device: %lxh/%lud\tInode: %-10lu  Links: %-5lu",
-+                     (uintmax_t) (statbuf.st_size),
-+                     (uintmax_t) statbuf.st_blocks,
-+                     (unsigned long int) statbuf.st_blksize,
-+                     file_type(&statbuf),
-+                     (uintmax_t) statbuf.st_dev,
-+                     (uintmax_t) statbuf.st_dev,
-+                     (uintmax_t) statbuf.st_ino,
-+                     (unsigned long int) statbuf.st_nlink);
-+              if (S_ISBLK(statbuf.st_mode) || S_ISCHR(statbuf.st_mode))
-+                      printf(" Device type: %lx,%lx\n",
-+                             (unsigned long int) major(statbuf.st_rdev),
-+                             (unsigned long int) minor(statbuf.st_rdev));
-+              else
-+                      putchar('\n');
-+              printf("Access: (%04lo/%10.10s)  Uid: (%5lu/%8s)   Gid: (%5lu/%8s)\n"
-+                     "Access: %s\n" "Modify: %s\n" "Change: %s\n",
-+                     (unsigned long int) (statbuf.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO)),
-+                     bb_mode_string(statbuf.st_mode),
-+                     (unsigned long int) statbuf.st_uid,
-+                     (pw_ent != 0L) ? pw_ent->pw_name : "UNKNOWN",
-+                     (unsigned long int) statbuf.st_gid,
-+                     (gw_ent != 0L) ? gw_ent->gr_name : "UNKNOWN",
-+                     human_time(statbuf.st_atime),
-+                     human_time(statbuf.st_mtime),
-+                     human_time(statbuf.st_ctime));
-+      }
-+#endif
-+      return 1;
-+}
-+
-+int stat_main(int argc, char **argv)
-+{
-+      int i;
-+      char *format = NULL;
-+      int ok = 1;
-+      int (*statfunc)(char const *, char const *) = do_stat;
-+
-+      flags = bb_getopt_ulflags(argc, argv, "ftL"
-+#ifdef CONFIG_FEATURE_STAT_FORMAT
-+      "c:", &format
-+#endif
-+      );
-+
-+      if (flags & 1)                /* -f */
-+              statfunc = do_statfs;
-+      if (argc == optind)           /* files */
-+              bb_show_usage();
-+
-+      for (i = optind; i < argc; ++i)
-+              ok &= statfunc(argv[i], format);
-+
-+      return (ok ? EXIT_SUCCESS : EXIT_FAILURE);
-+}
-diff -Nur busybox-1.00/coreutils/sum.c busybox/coreutils/sum.c
---- busybox-1.00/coreutils/sum.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/coreutils/sum.c    2005-06-04 08:20:13.000000000 +0200
-@@ -0,0 +1,181 @@
-+/*
-+ * sum -- checksum and count the blocks in a file
-+ *     Like BSD sum or SysV sum -r, except like SysV sum if -s option is given.
-+ *
-+ * Copyright (C) 86, 89, 91, 1995-2002, 2004 Free Software Foundation, Inc.
-+ * Copyright (C) 2005 by Erik Andersen <andersen@codepoet.org>
-+ * Copyright (C) 2005 by Mike Frysinger <vapier@gentoo.org>
-+ *
-+ * Written by Kayvan Aghaiepour and David MacKenzie
-+ * Taken from coreutils and turned into a busybox applet by Mike Frysinger
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <getopt.h>
-+
-+#include "libbb.h"
-+
-+/* 1 if any of the files read were the standard input */
-+static int have_read_stdin;
-+
-+/* make a little more readable and avoid using strcmp for just 2 bytes */
-+#define IS_STDIN(s) (s[0] == '-' && s[1] == '\0')
-+
-+/* Calculate and print the rotated checksum and the size in 1K blocks
-+   of file FILE, or of the standard input if FILE is "-".
-+   If PRINT_NAME is >1, print FILE next to the checksum and size.
-+   The checksum varies depending on sizeof (int).
-+   Return 1 if successful.  */
-+static int bsd_sum_file(const char *file, int print_name)
-+{
-+      register FILE *fp;
-+      register int checksum = 0;          /* The checksum mod 2^16. */
-+      register uintmax_t total_bytes = 0; /* The number of bytes. */
-+      register int ch;                    /* Each character read. */
-+
-+      if (IS_STDIN(file)) {
-+              fp = stdin;
-+              have_read_stdin = 1;
-+      } else {
-+              fp = bb_wfopen(file, "r");
-+              if (fp == NULL)
-+                      return 0;
-+      }
-+
-+      while ((ch = getc(fp)) != EOF) {
-+              ++total_bytes;
-+              checksum = (checksum >> 1) + ((checksum & 1) << 15);
-+              checksum += ch;
-+              checksum &= 0xffff;             /* Keep it within bounds. */
-+      }
-+
-+      if (ferror(fp)) {
-+              bb_perror_msg(file);
-+              bb_fclose_nonstdin(fp);
-+              return 0;
-+      }
-+
-+      if (bb_fclose_nonstdin(fp) == EOF) {
-+              bb_perror_msg(file);
-+              return 0;
-+      }
-+
-+      printf("%05d %5s ", checksum,
-+             make_human_readable_str(total_bytes, 1, 1024));
-+      if (print_name > 1)
-+              puts(file);
-+      else
-+              printf("\n");
-+
-+      return 1;
-+}
-+
-+/* Calculate and print the checksum and the size in 512-byte blocks
-+   of file FILE, or of the standard input if FILE is "-".
-+   If PRINT_NAME is >0, print FILE next to the checksum and size.
-+   Return 1 if successful.  */
-+static int sysv_sum_file(const char *file, int print_name)
-+{
-+      int fd;
-+      unsigned char buf[8192];
-+      uintmax_t total_bytes = 0;
-+      int r;
-+      int checksum;
-+
-+      /* The sum of all the input bytes, modulo (UINT_MAX + 1).  */
-+      unsigned int s = 0;
-+
-+      if (IS_STDIN(file)) {
-+              fd = 0;
-+              have_read_stdin = 1;
-+      } else {
-+              fd = open(file, O_RDONLY);
-+              if (fd == -1) {
-+                      bb_perror_msg(file);
-+                      return 0;
-+              }
-+      }
-+
-+      while (1) {
-+              size_t i;
-+              size_t bytes_read = safe_read(fd, buf, sizeof(buf));
-+
-+              if (bytes_read == 0)
-+                      break;
-+
-+              if (bytes_read == -1) {
-+                      bb_perror_msg(file);
-+                      if (!IS_STDIN(file))
-+                              close(fd);
-+                      return 0;
-+              }
-+
-+              for (i = 0; i < bytes_read; i++)
-+                      s += buf[i];
-+              total_bytes += bytes_read;
-+      }
-+
-+      if (!IS_STDIN(file) && close(fd) == -1) {
-+              bb_perror_msg(file);
-+              return 0;
-+      }
-+
-+      r = (s & 0xffff) + ((s & 0xffffffff) >> 16);
-+      checksum = (r & 0xffff) + (r >> 16);
-+
-+      printf("%d %s ", checksum,
-+             make_human_readable_str(total_bytes, 1, 512));
-+      if (print_name)
-+              puts(file);
-+      else
-+              printf("\n");
-+
-+      return 1;
-+}
-+
-+int sum_main(int argc, char **argv)
-+{
-+      int flags;
-+      int ok;
-+      int files_given;
-+      int (*sum_func)(const char *, int) = bsd_sum_file;
-+
-+      /* give the bsd func priority over sysv func */
-+      flags = bb_getopt_ulflags(argc, argv, "sr");
-+      if (flags & 1)
-+              sum_func = sysv_sum_file;
-+      if (flags & 2)
-+              sum_func = bsd_sum_file;
-+
-+      have_read_stdin = 0;
-+      files_given = argc - optind;
-+      if (files_given <= 0)
-+              ok = sum_func("-", files_given);
-+      else
-+              for (ok = 1; optind < argc; optind++)
-+                      ok &= sum_func(argv[optind], files_given);
-+
-+      if (have_read_stdin && fclose(stdin) == EOF)
-+              bb_perror_msg_and_die("-");
-+
-+      exit(ok ? EXIT_SUCCESS : EXIT_FAILURE);
-+}
-diff -Nur busybox-1.00/coreutils/test.c busybox/coreutils/test.c
---- busybox-1.00/coreutils/test.c      2004-08-11 04:45:47.000000000 +0200
-+++ busybox/coreutils/test.c   2005-06-04 08:20:13.000000000 +0200
-@@ -51,7 +51,7 @@
-       unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"|
-               "-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S";
--      binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"|
-+      binary-operator ::= "="|"=="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"|
-                       "-nt"|"-ot"|"-ef";
-       operand ::= <any legal UNIX file name>
- */
-@@ -135,6 +135,7 @@
-       "-L", FILSYM, UNOP}, {
-       "-S", FILSOCK, UNOP}, {
-       "=", STREQ, BINOP}, {
-+      "==", STREQ, BINOP}, {
-       "!=", STRNE, BINOP}, {
-       "<", STRLT, BINOP}, {
-       ">", STRGT, BINOP}, {
-@@ -191,6 +192,11 @@
-                       bb_error_msg_and_die("missing ]");
-               argv[argc] = NULL;
-       }
-+      if (strcmp(bb_applet_name, "[[") == 0) {
-+              if (strcmp(argv[--argc], "]]"))
-+                      bb_error_msg_and_die("missing ]]");
-+              argv[argc] = NULL;
-+      }
-       /* Implement special cases from POSIX.2, section 4.62.4 */
-       switch (argc) {
-       case 1:
-@@ -304,7 +310,7 @@
-       return strlen(*t_wp) > 0;
- }
--static int binop()
-+static int binop(void)
- {
-       const char *opnd1, *opnd2;
-       struct t_op const *op;
-@@ -531,7 +537,7 @@
-       return (-1);
- }
--static void initialize_group_array()
-+static void initialize_group_array(void)
- {
-       ngroups = getgroups(0, NULL);
-       group_array = xrealloc(group_array, ngroups * sizeof(gid_t));
-diff -Nur busybox-1.00/coreutils/watch.c busybox/coreutils/watch.c
---- busybox-1.00/coreutils/watch.c     2003-03-19 10:11:34.000000000 +0100
-+++ busybox/coreutils/watch.c  2005-06-04 08:20:13.000000000 +0200
-@@ -100,11 +100,10 @@
-                       //child
-                       close(1);
-                       dup(old_stdout);
--                      if (execvp(*watched_argv, watched_argv)) {
--                              bb_error_msg_and_die("Couldn't run command\n");
--                      }
-+                      execvp(*watched_argv, watched_argv);
-+                      bb_perror_msg_and_die(*watched_argv);
-               } else {
--                      bb_error_msg_and_die("Couldn't vfork\n");
-+                      bb_perror_msg_and_die("vfork");
-               }
-       }
- }
-diff -Nur busybox-1.00/coreutils/who.c busybox/coreutils/who.c
---- busybox-1.00/coreutils/who.c       2004-03-15 09:28:22.000000000 +0100
-+++ busybox/coreutils/who.c    2005-06-04 08:20:13.000000000 +0200
-@@ -74,7 +74,7 @@
-             } else
-                 printf("%-8s  ", "?");
--            printf("%-12.12s   %s\n", ctime(&(ut->ut_tv.tv_sec)) + 4, ut->ut_host);
-+            printf("%-12.12s   %s\n", ctime((time_t*)&(ut->ut_tv.tv_sec)) + 4, ut->ut_host);
-         }
-     }
-     endutent();
-diff -Nur busybox-1.00/debianutils/Config.in busybox/debianutils/Config.in
---- busybox-1.00/debianutils/Config.in 2004-03-15 09:28:24.000000000 +0100
-+++ busybox/debianutils/Config.in      2005-06-04 08:20:10.000000000 +0200
-@@ -24,6 +24,13 @@
-         This program reads a symbolic link and returns the name
-         of the file it points to
-+config CONFIG_FEATURE_READLINK_FOLLOW
-+      bool "  Enable canonicalization by following all symlinks (-f)"
-+      default n
-+      depends on CONFIG_READLINK
-+      help
-+        Enable the readlink option (-f).
-+
- config CONFIG_RUN_PARTS
-       bool "run-parts"
-       default n
-diff -Nur busybox-1.00/debianutils/readlink.c busybox/debianutils/readlink.c
---- busybox-1.00/debianutils/readlink.c        2003-03-19 10:11:41.000000000 +0100
-+++ busybox/debianutils/readlink.c     2005-06-04 08:20:10.000000000 +0200
-@@ -23,18 +23,38 @@
- #include <errno.h>
- #include <unistd.h>
- #include <stdlib.h>
-+#include <getopt.h>
- #include "busybox.h"
-+#ifdef CONFIG_FEATURE_READLINK_FOLLOW
-+# define READLINK_FOLLOW      "f"
-+# define READLINK_FLAG_f      (1 << 0)
-+#else
-+# define READLINK_FOLLOW      ""
-+#endif
-+
-+static const char readlink_options[] = READLINK_FOLLOW;
-+
- int readlink_main(int argc, char **argv)
- {
-       char *buf = NULL;
-+      unsigned long opt = bb_getopt_ulflags(argc, argv, readlink_options);
-+#ifdef CONFIG_FEATURE_READLINK_FOLLOW
-+      RESERVE_CONFIG_BUFFER(resolved_path, PATH_MAX);
-+#endif
-       /* no options, no getopt */
--      if (argc != 2)
-+      if (optind + 1 != argc)
-               bb_show_usage();
--      buf = xreadlink(argv[1]);
-+#ifdef CONFIG_FEATURE_READLINK_FOLLOW
-+      if (opt & READLINK_FLAG_f) {
-+              buf = realpath(argv[optind], resolved_path);
-+      } else
-+#endif
-+              buf = xreadlink(argv[optind]);
-+
-       if (!buf)
-               return EXIT_FAILURE;
-       puts(buf);
-diff -Nur busybox-1.00/debianutils/start_stop_daemon.c busybox/debianutils/start_stop_daemon.c
---- busybox-1.00/debianutils/start_stop_daemon.c       2004-04-13 20:28:46.000000000 +0200
-+++ busybox/debianutils/start_stop_daemon.c    2005-06-04 08:20:10.000000000 +0200
-@@ -238,7 +238,7 @@
-                       &startas, &cmdname, &signame, &userspec, &execname, &pidfile);
-       /* Check one and only one context option was given */
--      if ((opt & 0x80000000UL) || (opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) {
-+      if ((opt & BB_GETOPT_ERROR) || (opt & (SSD_CTX_STOP | SSD_CTX_START)) == 0) {
-               bb_show_usage();
-       }
-diff -Nur busybox-1.00/docs/autodocifier.pl busybox/docs/autodocifier.pl
---- busybox-1.00/docs/autodocifier.pl  2004-04-06 17:26:25.000000000 +0200
-+++ busybox/docs/autodocifier.pl       2005-06-04 08:20:06.000000000 +0200
-@@ -271,4 +271,4 @@
- =cut
--# $Id$
-+# $Id$
-diff -Nur busybox-1.00/docs/busybox.net/FAQ.html busybox/docs/busybox.net/FAQ.html
---- busybox-1.00/docs/busybox.net/FAQ.html     2004-10-13 11:42:10.000000000 +0200
-+++ busybox/docs/busybox.net/FAQ.html  2005-06-04 08:20:06.000000000 +0200
-@@ -15,14 +15,15 @@
- <li><a href="#bugs">I think I found a bug in BusyBox!  What should I do?!</a>
- <li><a href="#job_control">Why do I keep getting "sh: can't access tty; job control
-       turned off" errors?  Why doesn't Control-C work within my shell?</a>
-+<li><a href="#getting_started">How can I get started using BusyBox?</a>
- <li><a href="#demanding">I demand that you to add &lt;favorite feature&gt; right now!   How come
-       you don't answer all my questions on the mailing list instantly?  I demand
-       that you help me with all of my problems <em>Right Now</em>!</a>
--<li><a href="#getting_started">How can I get started using BusyBox?</a>
- <li><a href="#helpme">I need help with BusyBox!  What should I do?</a>
- <li><a href="#contracts">I need you to add &lt;favorite feature&gt;!  Are the BusyBox developers willing to
-       be paid in order to fix bugs or add in &lt;favorite feature&gt;?  Are you willing to provide
-       support contracts?</a>
-+<li><a href="#external">Where can I find other small utilities since busybox does not include the features I want?</a></li>
- <li><a href="#support">I think you guys are great and I want to help support your work!</a>
-@@ -76,6 +77,7 @@
-     with the generous terms of the GPL BusyBox license</a> you can ship BusyBox
-     as part of the software on your device.
-+    <br>
-     <a href="#support">Please consider sharing some of the money you make.</a>
-@@ -84,49 +86,33 @@
- <h2><a name="bugs">I think I found a bug in BusyBox!  What should I do?</h2>
- <p>
--    If you find a problem with BusyBox, please submit a detailed bug report to
--    the BusyBox mailing list at <a href="mailto:busybox@mail.busybox.net">
--    busybox@mail.busybox.net</a>.  Please do not send private email to Erik
--    (the maintainer of BusyBox) asking for private help unless you are planning
--    on paying for consulting services.  When we answer questions on the BusyBox
--    mailing list, it helps everyone, while private answers help only you...
--
--    <p>
--
--    If you find bugs, please submit a detailed bug report to the BusyBox mailing
--    list at busybox@mail.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:
--
--<pre>
--      To: busybox@mail.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:
-+<p>
--              $ date
--              Fri Oct  8 14:19:41 MDT 2004
-+    If you simply need help with using or configuring BusyBox, please submit a
-+    detailed description of your problem to the BusyBox mailing list at <a
-+    href="mailto:busybox@mail.busybox.net"> busybox@mail.busybox.net</a>.
-+    Please do not send private email to Erik (the maintainer of BusyBox) asking
-+    for private help unless you are planning on paying for consulting services.
-+    When we answer questions on the BusyBox mailing list, it helps everyone,
-+    while private answers help only you...
--      But when I use BusyBox date I get this instead:
-+    <p>
--              $ date
--              illegal instruction
-+    The developers of BusyBox are busy people, and have only so much they can
-+    keep in their brains at a time.  As a result, bug reports sometimes get
-+    lost when posted to the mailing list.  To prevent your bug report from
-+    getting lost, if you find a bug in BusyBox, please use the <a
-+    href="http://bugs.busybox.net/">BusyBox Bug and Patch Tracking System</a>
-+    to submit a detailed bug report.
--      I am using Debian unstable, kernel version 2.4.27 on a x86 system,
--      and the latest uClibc from CVS.  Thanks for the wonderful program!
-+    <p>
--        -Diligent
--</pre>
-+    The same also applies to patches... Regardless of whether your patch is a
-+    bug fix or adds shiney new features, please post your patch to the <a
-+    href="http://bugs.busybox.net/">BusyBox Bug and Patch Tracking System</a>
-+    to make certain it is properly considered.
--    Note the careful description and use of examples showing not only what BusyBox
--    does, but also a counter example showing what an equivalent GNU app does.  Bug
--    reports lacking proper detail may never be fixed...  Thanks for understanding.
- <hr />
- <p>
-@@ -153,8 +139,8 @@
-     An easy method to build your own basic BusyBox based system, is to
-     follow these simple steps:
-     <ul>
--      <li> Point your web browser <a href="/cgi-bin/cvsweb/buildroot/">here</a>
--      <li> Click on "Download tarball"
-+      <li> Point your web browser <a href="http://buildroot.uclibc.org/">here</a>
-+      <li> Download a copy of buildroot
-       <li> Unpack the tarball on your Linux system somewhere
-       <li> run 'make' and configure things to taste.
-       <li> run 'unset CC'.   Some Linux systems (i.e. Gentoo) set 'CC'
-@@ -220,19 +206,25 @@
-       href="http://codepoet-consulting.com/">CodePoet Consulting</a> to bid
-     on your project.  If Erik is too busy to personally add your feature, there
-     are many other active BusyBox contributors who will almost certainly be able
--    to help you out.  Erik can contact them privatly, and may even let you to
-+    to help you out.  Erik can contact them privately, and may even let you to
-     post your request for services on the mailing list.
- <hr />
- <p>
-+<h2><a name="external">Where can I find other small utilities since busybox 
-+      does not include the features I want?</a></h2>
-+<p>
-+      We maintain such a <a href="tinyutils.html">list</a> on this site!
-+
-+
-+<hr />
-+<p>
- <h2><a name="support">I think you guys are great and I want to help support your work!</a></h2>
- <p>
--    Wow, that would be great!  Erik personally pays for all the bandwidth, and
--    all servers used for busybox.net out of his own pocket.  If you would like
--    to make a donation to help support BusyBox, and/or request features, you
--    can click here:
-+    Wow, that would be great!  If you would like to make a donation to help
-+    support BusyBox, and/or request features, you can click here:
-     <!-- Begin PayPal Logo -->
-     <center>
-@@ -321,4 +313,3 @@
- <br>
- <!--#include file="footer.html" -->
--
-diff -Nur busybox-1.00/docs/busybox.net/cvs_anon.html busybox/docs/busybox.net/cvs_anon.html
---- busybox-1.00/docs/busybox.net/cvs_anon.html        2004-03-15 09:28:29.000000000 +0100
-+++ busybox/docs/busybox.net/cvs_anon.html     1970-01-01 01:00:00.000000000 +0100
-@@ -1,57 +0,0 @@
--<!--#include file="header.html" -->
--
--
--<h3>Anonymous CVS</h3>
--
--We allow anonymous (read-only) CVS access to everyone.  The first command you
--need to run for anonymous CVS access is:
--<pre>
--cvs -d:pserver:anonymous@busybox.net:/var/cvs login</pre>
--<p>
--CVS will prompt you for a password. Just press the Enter key (there is no
--password for anonymous access).  This step only needs to be done once, the first
--time you attempt to access CVS.
--<p>
--Once the login is complete, you can then check the list of available
--CVS modules by running the following command (all on one line):
--<pre>
--cvs -z3 -d:pserver:anonymous@busybox.net:/var/cvs co -c </pre>
--
--<p>
--If you wish, you can then check out a local copy of any of the
--available modules.  The following is an example of how to grab
--a copy of busybox and tinylogin:
--<pre>
--    cvs -z3 -d:pserver:anonymous@busybox.net:/var/cvs co -P busybox tinylogin</pre>
--This will create a directory called <b>busybox</b> and a directory called
--<b>tinylogin</b> in the current directory.  These directories contain the
--latest and greatest source code for busybox and tinylogin.
--
--<p>
--If you are not already familiar with using CVS, I recommend you visit
--this quick <a href="/cvs_howto.html">Introduction to CVS</a>.
--
--<p>
--I usually create a ~/.cvsrc file with the following things in it, and I
--recommend you should use the same:
--<pre>
--    -z3
--    update -dP
--    rdiff -u
--    diff -ubBwpN
--    checkout -P</pre>
--
--<p>
--Once you've checked out a copy of the source tree, you can update your
--source tree at any time so it is in sync with the latest and greatest by
--running the command:
--<pre>
--cvs update</pre>
--
--Because you've only been granted anonymous access to the tree, you won't be
--able to commit any changes. Changes can be submitted for inclusion by posting
--them to the appropriate mailing list.  For those that are actively contributing
--<a href="cvs_write.html">CVS write access</a> can be made available.
--
--<!--#include file="footer.html" -->
--
-diff -Nur busybox-1.00/docs/busybox.net/cvs_howto.html busybox/docs/busybox.net/cvs_howto.html
---- busybox-1.00/docs/busybox.net/cvs_howto.html       2004-03-15 09:28:29.000000000 +0100
-+++ busybox/docs/busybox.net/cvs_howto.html    1970-01-01 01:00:00.000000000 +0100
-@@ -1,44 +0,0 @@
--<!--#include file="header.html" -->
--
--
--<h3>How to use CVS</h3>
--
--
--If you want to know all the gory details, you will want to visit
--<a href="http://www.cvshome.org/">the CVS main web page</a>.<p>
--For the impatient, the following is probably about all you need to know:
--<p>
--
--<dl>
--    <dt><pre>cvs checkout -c</pre>
--    <dd>Will list the modules available for checkout
--    <dt><pre>cvs checkout &lt module name &gt</pre>
--    <dd>Will checkout the named module
--    <dt><pre>cvs co &lt module name &gt</pre>
--    <dd>Same thing
--    <dt><pre>cvs update</pre>
--
--    <dd>Updates your local archive so it is in sync with the repository
--    -- your local updates are left intact.  Tries to merge upstream updates
--    into your local updates.  You will see the following tags when it is
--    updating your local repository: C means conflict, U means update,
--    P means patched, and M means modified.
--    <dt><pre>cvs up</pre>
--    <dd>Same thing
--    <dt><pre>cvs update &lt file name &gt</pre>
--    <dd>Same thing but for just the named file(s)/directory(s).
--    <dt><pre>cvs commit</pre>
--    <dd>Will check in all your work.
--    <dt><pre>cvs add &lt file name &gt</pre>
--
--    <dd>Adds the named file/directory into CVS
--    <dt><pre>cvs remove &lt file name &gt</pre>
--    <dd>Removes the named file/directory from the upstream repository.
--    <dt><pre>cvs rm &lt file name &gt</pre>
--    <dd>Same thing
--    <dt><pre>cvs log &lt file name &gt</pre>
--</dl>
--
--
--<!--#include file="footer.html" -->
--
-diff -Nur busybox-1.00/docs/busybox.net/cvs_write.html busybox/docs/busybox.net/cvs_write.html
---- busybox-1.00/docs/busybox.net/cvs_write.html       2004-09-08 22:13:05.000000000 +0200
-+++ busybox/docs/busybox.net/cvs_write.html    1970-01-01 01:00:00.000000000 +0100
-@@ -1,32 +0,0 @@
--<!--#include file="header.html" -->
--
--
--<h3>CVS Read/Write Access</h3>
--
--If you want to be able to commit things to CVS, first contribute some
--stuff to show you are serious.  Then, very nicely ask
--<a href="mailto:andersen@codepoet.org">Erik Andersen</a> if he will set you up with
--an account.  To access CVS, you will want to add the following to set up your environment:
--<pre>
--$ export CVS_RSH=/usr/bin/ssh
--$ export CVSROOT='username@cvs.busybox.net:/var/cvs'</pre>
--<br>
--It goes without saying you must change <em>username</em> to your own
--username...
--<p>
--
--To obtain commit access, you will need to demonstrate you are
--serious by submitting a few good patches first.  Then, you will need to
--select a user-name to use when committing stuff, and finally, you will
--need to send me the username you have selected, an ssh key, and the email
--address where you prefer email to be sent (I will forward any email sent
--to you, but not store it).
--
--<p>
--Note that if you would prefer to keep your communications with me
--private, you can encrypt your email using my
--<a href="http://www.codepoet.org/andersen/erik/gpg.asc">public key</a>.
--
--<!--#include file="footer.html" -->
--
--
-diff -Nur busybox-1.00/docs/busybox.net/developer.html busybox/docs/busybox.net/developer.html
---- busybox-1.00/docs/busybox.net/developer.html       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/docs/busybox.net/developer.html    2005-06-04 08:20:06.000000000 +0200
-@@ -0,0 +1,58 @@
-+<!--#include file="header.html" -->
-+
-+
-+<h3>Subversion Read/Write Access</h3>
-+
-+If you want to be able to commit things to Subversion, first contribute some
-+stuff to show you are serious.  Then, very nicely ask <a
-+href="mailto:andersen@codepoet.org">Erik Andersen</a> if he will set you up
-+with an commit access to the Subversion repository.  To access Subversion, you
-+will want to add the following to set up your environment:
-+
-+<p>
-+
-+To obtain commit access, you will need to demonstrate you are serious by
-+submitting a few good patches first.  Then, you will need to select a username
-+to use when committing stuff, and finally, you will need to send me the
-+username you have selected, an ssh key, and the email address where you prefer
-+email to be sent (I will forward any email sent to you, but not store it).
-+
-+<p>
-+
-+Note that if you would prefer to keep your communications with me
-+private, you can encrypt your email using my
-+<a href="http://www.codepoet.org/andersen/erik/gpg.asc">public key</a>.
-+
-+<p>
-+
-+Once you are setup with an account, you will need to use your account to
-+checkout a copy of BusyBox from Subversion:
-+
-+<pre>
-+svn list svn+ssh://username@svn.uclibc.org/svn/trunk/busybox</pre>
-+<br>
-+It goes without saying you must change <em>username</em> to your own
-+username...
-+<p>
-+
-+You can then enter the newly checked out BusyBox directory, make changes, check
-+your changes, diff your changes, revert your changes, and and commit your
-+changes usine commands such as:
-+
-+<pre>
-+svn diff
-+svn status
-+svn revert
-+svn commit</pre>
-+
-+<p>
-+
-+For additional detail on how to use Subversion, please visit the
-+<a href="http://subversion.tigris.org/">the Subversion website</a>.
-+You might also want to read online or buy a copy of <a
-+href="http://svnbook.red-bean.com/">the Subversion Book</a>...
-+
-+
-+<!--#include file="footer.html" -->
-+
-+
-diff -Nur busybox-1.00/docs/busybox.net/download.html busybox/docs/busybox.net/download.html
---- busybox-1.00/docs/busybox.net/download.html        2004-03-15 09:28:29.000000000 +0100
-+++ busybox/docs/busybox.net/download.html     2005-06-04 08:20:06.000000000 +0200
-@@ -9,27 +9,18 @@
- <p>
- You can also obtain <a href= "downloads/snapshots/">Daily Snapshots</a> of
--the latest stable, and the latest development CVS source trees.
--
--<p>
--BusyBox now has <b>two</b> CVS trees.  The "busybox-stable" tree
--contains the older 0.60.x stable series.  The "busybox" tree contains
--the latest 1.0.0-preX development version of busybox.<br>
-+the latest development source tree for those wishing to follow BusyBox development,
-+but cannot or do not wish to use Subversion (svn).
- <ul>
--      <li> Click here to browse the <a href="/cgi-bin/cvsweb/busybox/">
--              CVS tree for the 1.0.0-preX development version of BusyBox</a>
--      </li>
--
--      <li>Click here to browse the <a href="/cgi-bin/cvsweb/busybox.stable/">
--              CVS tree for the stable 0.60.x version of BusyBox</a>.
-+      <li> Click here to <a href="/cgi-bin/viewcvs.cgi/trunk/busybox/">browse the source tree</a>.
-       </li>
--      <li>Anonymous <a href="cvs_anon.html">CVS access</a> is available.
-+      <li>Anonymous <a href="subversion.html">Subversion access</a> is available.
-       </li>
--      <li>For those that are actively contributing there is
--              even <a href="cvs_write.html">CVS write access</a>.
-+      <li>For those that are actively contributing obtaining
-+              <a href="developer.html">Subversion read/write access</a> is also possible.
-       </li>
- </ul>
-diff -Nur busybox-1.00/docs/busybox.net/footer.html busybox/docs/busybox.net/footer.html
---- busybox-1.00/docs/busybox.net/footer.html  2004-03-15 09:28:29.000000000 +0100
-+++ busybox/docs/busybox.net/footer.html       2005-06-04 08:20:06.000000000 +0200
-@@ -7,14 +7,34 @@
- <hr />
--    <p>
--    <font face="arial, helvetica, sans-serif" size="-1">
--      <a HREF="/copyright.txt">Copyright &copy; 1999-2003 Erik Andersen</a>
--      <br>
--      Mail all comments, insults, suggestions and bribes to
--      <br>
--      Erik Andersen <A HREF="mailto:andersen@codepoet.org">andersen@codepoet.org</A><BR>
--    </font>
-+
-+    <table width="100%">
-+      <tr>
-+          <td width="60%">
-+              <font face="arial, helvetica, sans-serif" size="-1">
-+                  <a href="/copyright.txt">Copyright &copy; 1999-2005 Erik Andersen</a>
-+                  <br>
-+                  Mail all comments, insults, suggestions and bribes to
-+                  <br>
-+                  Erik Andersen <a href="mailto:andersen@codepoet.org">andersen@codepoet.org</a><br>
-+              </font>
-+          </td>
-+
-+          <td>
-+              <a href="http://www.vim.org/"><img border=0 width=88 height=31
-+              src="images/written.in.vi.png"
-+              alt="This site created with the vi editor"></a>
-+          </td>
-+
-+          <td>
-+              <a href="http://osuosl.org/"><img border=0 width=114 height=63
-+              src="images/osuosl.png"
-+              alt="This site is kindly hosted by OSL"></a>
-+          </td>
-+
-+      </TR>
-+    </table>
-   </body>
- </html>
-+
-diff -Nur busybox-1.00/docs/busybox.net/header.html busybox/docs/busybox.net/header.html
---- busybox-1.00/docs/busybox.net/header.html  2004-10-08 12:50:08.000000000 +0200
-+++ busybox/docs/busybox.net/header.html       2005-06-04 08:20:06.000000000 +0200
-@@ -48,9 +48,10 @@
-     <br><a href="/lists.html">Mailing Lists</a>
-     <br><a href="/news.html">Latest News</a>
-     <br><a href="/download.html">Download</a>
-+    <br><a href="/cgi-bin/viewcvs.cgi/trunk/busybox/">Browse Source</a>
-+    <br><a href="/subversion.html">Accessing Source</a>
-+    <br><a href="http://bugs.busybox.net/">Bug Tracking</a>
-     <br><a href="/FAQ.html">FAQ</a>
--    <br><a href="/cvs_anon.html">Accessing CVS</a>
--    <br><a href="/cgi-bin/cvsweb/busybox/">Browse CVS</a>
-     <br><a href="/docs.html">Documentation</a>
-     <br><a href="/products.html">Products</a>
-     <br><a href="/shame.html">Hall of Shame</a>
-@@ -58,8 +59,11 @@
-     <p><b>Related Sites</b>
-     <br><a href="http://uclibc.org/">uClibc.org</a>
-+    <br><a href="http://cxx.uclibc.org/">uClibc++</a>
-     <br><a href="http://udhcp.busybox.net/">udhcp</a>
--    <br><a href="http://tinylogin.busybox.net/">tinylogin</a>
-+    <br><a href="http://buildroot.uclibc.org/">buildroot</a>
-+    <br><a href="http://www.scratchbox.org/">Scratchbox</a>
-+    <br><a href="http://openembedded.org/">OpenEmbedded</a>
-     <br><a href="http://www.ucdot.org/">uCdot</a>
-     <br><a href="http://www.linuxdevices.com">LinuxDevices</a>
-     <br><a href="http://slashdot.org/">Slashdot</a>
-Files busybox-1.00/docs/busybox.net/images/osuosl.png and busybox/docs/busybox.net/images/osuosl.png differ
-diff -Nur busybox-1.00/docs/busybox.net/lists.html busybox/docs/busybox.net/lists.html
---- busybox-1.00/docs/busybox.net/lists.html   2004-06-19 08:26:30.000000000 +0200
-+++ busybox/docs/busybox.net/lists.html        2005-06-04 08:20:06.000000000 +0200
-@@ -15,7 +15,8 @@
- wishing to read the complete diff of each and every change to busybox -- not for the
- faint of heart.  Active developers can subscribe by visiting
- <a href="http://codepoet.org/mailman/listinfo/busybox-cvs">this page</a>.
--The CVS server is the only one permtted to post to this list.
-+The Subversion server is the only one permtted to post to this list.  And yes,
-+this list name uses the word 'cvs' even though we don't use that anymore...
- <p>
-diff -Nur busybox-1.00/docs/busybox.net/news.html busybox/docs/busybox.net/news.html
---- busybox-1.00/docs/busybox.net/news.html    2004-10-13 11:42:10.000000000 +0200
-+++ busybox/docs/busybox.net/news.html 2005-06-04 08:20:06.000000000 +0200
-@@ -3,6 +3,25 @@
- <ul>
-+  <li><b>13 January 2005 -- Bug and Patch Tracking</b><p>
-+
-+    Bug reports sometimes get lost when posted to the mailing list.  The
-+    developers of BusyBox are busy people, and have only so much they can keep
-+    in their brains at a time. In my case, I'm lucky if I can remember my own
-+    name, much less a bug report posted last week... To prevent your bug report
-+    from getting lost, if you find a bug in BusyBox, please use the 
-+    <a href="http://bugs.busybox.net/">shiny new Bug and Patch Tracking System</a>
-+    to post all the gory details.
-+
-+    <p>
-+
-+    The same applies to patches... Regardless of whether your patch
-+    is a bug fix or adds spiffy new features, please post your patch
-+    to the Bug and Patch Tracking System to make certain it is
-+    properly considered.
-+
-+
-+  <p>
-   <li><b>13 October 2004 -- BusyBox 1.00 released</b><p>
-     When you take a careful look at nearly every embedded Linux device or
-diff -Nur busybox-1.00/docs/busybox.net/oldnews.html busybox/docs/busybox.net/oldnews.html
---- busybox-1.00/docs/busybox.net/oldnews.html 2004-10-13 11:42:10.000000000 +0200
-+++ busybox/docs/busybox.net/oldnews.html      2005-06-04 08:20:06.000000000 +0200
-@@ -888,7 +888,7 @@
-      Also, some exciting infrastructure news!  Busybox now has its own
-      <a href="lists/busybox/">mailing list</a>,
-      publically browsable
--     <a href="/cgi-bin/cvsweb/busybox/">CVS tree</a>,
-+     <a href="/cgi-bin/viewcvs.cgi/trunk/busybox/">CVS tree</a>,
-      anonymous
-      <a href="cvs_anon.html">CVS access</a>, and
-      for those that are actively contributing there is even
-diff -Nur busybox-1.00/docs/busybox.net/products.html busybox/docs/busybox.net/products.html
---- busybox-1.00/docs/busybox.net/products.html        2004-10-13 11:42:10.000000000 +0200
-+++ busybox/docs/busybox.net/products.html     2005-06-04 08:20:06.000000000 +0200
-@@ -13,7 +13,7 @@
- <ul>
--<li><a href="/cgi-bin/cvsweb/buildroot/">buildroot</a><br>A configurable
-+<li><a href="http://buildroot.uclibc.org/">buildroot</a><br>A configurable
- means for building your own busybox/uClibc based system systems.
- <li><a href="http://www.pengutronix.de/software/ptxdist_en.html">PTXdist</a><br>another
-diff -Nur busybox-1.00/docs/busybox.net/subversion.html busybox/docs/busybox.net/subversion.html
---- busybox-1.00/docs/busybox.net/subversion.html      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/docs/busybox.net/subversion.html   2005-06-04 08:20:06.000000000 +0200
-@@ -0,0 +1,38 @@
-+<!--#include file="header.html" -->
-+
-+
-+<h3>Anonymous Subversion Access</h3>
-+
-+We allow anonymous (read-only) Subversion (svn) access to everyone.  To
-+grab a copy of the latest version of BusyBox using anonymous svn access is:
-+
-+<pre>
-+svn co svn://busybox.net/trunk/busybox</pre>
-+
-+
-+<p>
-+
-+If you are not already familiar with using Subversion, I recommend you visit <a
-+href="http://subversion.tigris.org/">the Subversion website</a>.  You might
-+also want to read online or buy a copy of <a
-+href="http://svnbook.red-bean.com/">the Subversion Book</a>.  If you are
-+already comfortable with using CVS, you may want to skip ahead to the <a
-+href="http://svnbook.red-bean.com/en/1.1/apa.html">Subversion for CVS Users</a>
-+part of the Subversion Book.
-+
-+<p>
-+
-+Once you've checked out a copy of the source tree, you can update your source
-+tree at any time so it is in sync with the latest and greatest by entering your
-+BusyBox directory and running the command:
-+
-+<pre>
-+svn update</pre>
-+
-+Because you've only been granted anonymous access to the tree, you won't be
-+able to commit any changes. Changes can be submitted for inclusion by posting
-+them to the BusyBox mailing list.  For those that are actively contributing
-+<a href="developer.html">Subversion commit access</a> can be made available.
-+
-+<!--#include file="footer.html" -->
-+
-diff -Nur busybox-1.00/docs/busybox.net/tinyutils.html busybox/docs/busybox.net/tinyutils.html
---- busybox-1.00/docs/busybox.net/tinyutils.html       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/docs/busybox.net/tinyutils.html    2005-06-04 08:20:06.000000000 +0200
-@@ -0,0 +1,35 @@
-+<!--#include file="header.html" -->
-+
-+
-+<h3>External Tiny Utilities</h3>
-+
-+This is a list of tiny utilities whose functionality is not provided by 
-+busybox.  If you have additional suggestions, please send an e-mail to our 
-+dev mailing list.
-+
-+<br><br>
-+
-+<table>
-+<tr>
-+ <th>Feature</th>
-+ <th>Utilities</th>
-+</tr>
-+
-+<tr>
-+ <td>SSH</td>
-+ <td><a href="http://matt.ucc.asn.au/dropbear/">Dropbear</a> has both a sshd and a ssh client.</td>
-+</tr>
-+
-+<tr>
-+ <td>SMTP</td>
-+ <td><a href="ftp://ftp.debian.org/debian/pool/main/s/ssmtp/">ssmtp</a> is an extremely simple MTA.</td>
-+</tr>
-+
-+<tr>
-+ <td>DNS</td>
-+ <td><a href="http://www.thekelleys.org.uk/dnsmasq/">dnsmasq</a> is a small forwarding DNS server meant for small environments.</td>
-+</tr>
-+</table>
-+
-+<!--#include file="footer.html" -->
-+
-diff -Nur busybox-1.00/docs/busybox_footer.pod busybox/docs/busybox_footer.pod
---- busybox-1.00/docs/busybox_footer.pod       2004-04-25 08:05:14.000000000 +0200
-+++ busybox/docs/busybox_footer.pod    2005-06-04 08:20:06.000000000 +0200
-@@ -254,5 +254,5 @@
- =cut
--# $Id$
-+# $Id$
-diff -Nur busybox-1.00/docs/new-applet-HOWTO.txt busybox/docs/new-applet-HOWTO.txt
---- busybox-1.00/docs/new-applet-HOWTO.txt     2004-03-15 09:28:26.000000000 +0100
-+++ busybox/docs/new-applet-HOWTO.txt  2005-06-04 08:20:06.000000000 +0200
-@@ -52,10 +52,10 @@
-       char mu;
-       if ((fd = open("/dev/random", O_RDONLY)) < 0)
--              perror_msg_and_die("/dev/random");
-+              bb_perror_msg_and_die("/dev/random");
-       if ((n = safe_read(fd, &mu, 1)) < 1)
--              perror_msg_and_die("/dev/random");
-+              bb_perror_msg_and_die("/dev/random");
-       return mu;
- }
-@@ -137,11 +137,6 @@
-       /* all programs below here are alphabetically "greater than" 'mu' */
--Finally, add a define for your applet to include/config.h
--
--      #undef CONFIG_MU
--
--
- Documentation
- -------------
-diff -Nur busybox-1.00/e2fsprogs/Config.in busybox/e2fsprogs/Config.in
---- busybox-1.00/e2fsprogs/Config.in   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/Config.in        2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,20 @@
-+#
-+# For a description of the syntax of this configuration file,
-+# see scripts/kbuild/config-language.txt.
-+#
-+
-+menu "Linux Ext2 FS Progs"
-+
-+config CONFIG_CHATTR
-+      bool "chattr"
-+      default n
-+      help
-+        chattr changes the file attributes on a second extended file system.
-+
-+config CONFIG_LSATTR
-+      bool "lsattr"
-+      default n
-+      help
-+        lsattr lists the file attributes on a second extended file system.
-+
-+endmenu
-diff -Nur busybox-1.00/e2fsprogs/Makefile busybox/e2fsprogs/Makefile
---- busybox-1.00/e2fsprogs/Makefile    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/Makefile 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,31 @@
-+# Makefile for busybox
-+#
-+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
-+#
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 2 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+# General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program; if not, write to the Free Software
-+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+#
-+
-+top_srcdir=..
-+top_builddir=..
-+srcdir=$(top_srcdir)/e2fsprogs
-+E2FSPROGS_DIR:=./
-+include $(top_builddir)/Rules.mak
-+include $(top_builddir)/.config
-+include Makefile.in
-+all: $(libraries-y)
-+-include $(top_builddir)/.depend
-+
-+clean:
-+      rm -f *.o *.a $(AR_TARGET)
-diff -Nur busybox-1.00/e2fsprogs/Makefile.in busybox/e2fsprogs/Makefile.in
---- busybox-1.00/e2fsprogs/Makefile.in 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/Makefile.in      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,44 @@
-+# Makefile for busybox
-+#
-+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
-+#
-+# This program is free software; you can redistribute it and/or modify
-+# it under the terms of the GNU General Public License as published by
-+# the Free Software Foundation; either version 2 of the License, or
-+# (at your option) any later version.
-+#
-+# This program is distributed in the hope that it will be useful,
-+# but WITHOUT ANY WARRANTY; without even the implied warranty of
-+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+# General Public License for more details.
-+#
-+# You should have received a copy of the GNU General Public License
-+# along with this program; if not, write to the Free Software
-+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+#
-+
-+E2FSPROGS_AR:=e2fsprogs.a
-+ifndef $(E2FSPROGS_DIR)
-+E2FSPROGS_DIR:=$(top_builddir)/e2fsprogs/
-+endif
-+srcdir=$(top_srcdir)/e2fsprogs
-+
-+CFLAGS += -I$(E2FSPROGS_DIR)
-+
-+E2P_SRC:=fgetsetflags.c fgetsetversion.c pf.c iod.c
-+E2P_SRCS:=$(patsubst %,e2p/%, $(E2P_SRC))
-+E2P_OBJS=$(patsubst %.c,%.o, $(E2P_SRCS))
-+
-+E2FSPROGS-:=
-+E2FSPROGS-$(CONFIG_CHATTR)      += chattr.o $(E2P_OBJS)
-+E2FSPROGS-$(CONFIG_LSATTR)      += lsattr.o $(E2P_OBJS)
-+
-+libraries-y+=$(E2FSPROGS_DIR)$(E2FSPROGS_AR)
-+
-+
-+$(E2FSPROGS_DIR)$(E2FSPROGS_AR): $(patsubst %,$(E2FSPROGS_DIR)%, $(E2FSPROGS-y))
-+      $(AR) -ro $@ $(patsubst %,$(E2FSPROGS_DIR)%, $(E2FSPROGS-y))
-+
-+$(E2FSPROGS_DIR)%.o: $(srcdir)/%.c
-+      $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -DHAVE_ERRNO_H=1 -DHAVE_UNISTD_H=1 \
-+              -DHAVE_EXT2_IOCTLS=1 -DHAVE_EXT2_IOCTLS=1 -c -o $@ $<
-diff -Nur busybox-1.00/e2fsprogs/README busybox/e2fsprogs/README
---- busybox-1.00/e2fsprogs/README      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/README   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,3 @@
-+This is a pretty straight rip from the e2fsprogs pkg.
-+
-+See README's in subdirs for specific info.
-diff -Nur busybox-1.00/e2fsprogs/base_device.c busybox/e2fsprogs/base_device.c
---- busybox-1.00/e2fsprogs/base_device.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/base_device.c    2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,147 @@
-+/*
-+ * base_device.c
-+ *
-+ * Return the "base device" given a particular device; this is used to
-+ * assure that we only fsck one partition on a particular drive at any
-+ * one time.  Otherwise, the disk heads will be seeking all over the
-+ * place.  If the base device can not be determined, return NULL.
-+ * 
-+ * The base_device() function returns an allocated string which must
-+ * be freed.
-+ * 
-+ * Written by Theodore Ts'o, <tytso@mit.edu>
-+ * 
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <ctype.h>
-+#include <string.h>
-+
-+#include "busybox.h"
-+
-+#ifdef CONFIG_FEATURE_DEVFS
-+/*
-+ * Required for the uber-silly devfs /dev/ide/host1/bus2/target3/lun3
-+ * pathames.
-+ */
-+static const char *devfs_hier[] = {
-+      "host", "bus", "target", "lun", 0
-+};
-+#endif
-+
-+char *base_device(const char *device)
-+{
-+      char *str, *cp;
-+#ifdef CONFIG_FEATURE_DEVFS
-+      const char **hier, *disk;
-+      int len;
-+#endif
-+
-+      cp = str = bb_xstrdup(device);
-+
-+      /* Skip over /dev/; if it's not present, give up. */
-+      if (strncmp(cp, "/dev/", 5) != 0)
-+              goto errout;
-+      cp += 5;
-+
-+#if 0 /* this is for old stuff no one uses anymore ? */
-+      /* Skip over /dev/dsk/... */
-+      if (strncmp(cp, "dsk/", 4) == 0)
-+              cp += 4;
-+#endif
-+
-+      /*
-+       * For md devices, we treat them all as if they were all
-+       * on one disk, since we don't know how to parallelize them.
-+       */
-+      if (cp[0] == 'm' && cp[1] == 'd') {
-+              *(cp+2) = 0;
-+              return str;
-+      }
-+
-+      /* Handle DAC 960 devices */
-+      if (strncmp(cp, "rd/", 3) == 0) {
-+              cp += 3;
-+              if (cp[0] != 'c' || cp[2] != 'd' ||
-+                  !isdigit(cp[1]) || !isdigit(cp[3]))
-+                      goto errout;
-+              *(cp+4) = 0;
-+              return str;
-+      }
-+
-+      /* Now let's handle /dev/hd* and /dev/sd* devices.... */
-+      if ((cp[0] == 'h' || cp[0] == 's') && (cp[1] == 'd')) {
-+              cp += 2;
-+              /* If there's a single number after /dev/hd, skip it */
-+              if (isdigit(*cp))
-+                      cp++;
-+              /* What follows must be an alpha char, or give up */
-+              if (!isalpha(*cp))
-+                      goto errout;
-+              *(cp + 1) = 0;
-+              return str;
-+      }
-+
-+#ifdef CONFIG_FEATURE_DEVFS
-+      /* Now let's handle devfs (ugh) names */
-+      len = 0;
-+      if (strncmp(cp, "ide/", 4) == 0)
-+              len = 4;
-+      if (strncmp(cp, "scsi/", 5) == 0)
-+              len = 5;
-+      if (len) {
-+              cp += len;
-+              /*
-+               * Now we proceed down the expected devfs hierarchy.
-+               * i.e., .../host1/bus2/target3/lun4/...
-+               * If we don't find the expected token, followed by
-+               * some number of digits at each level, abort.
-+               */
-+              for (hier = devfs_hier; *hier; hier++) {
-+                      len = strlen(*hier);
-+                      if (strncmp(cp, *hier, len) != 0)
-+                              goto errout;
-+                      cp += len;
-+                      while (*cp != '/' && *cp != 0) {
-+                              if (!isdigit(*cp))
-+                                      goto errout;
-+                              cp++;
-+                      }
-+                      cp++;
-+              }
-+              *(cp - 1) = 0;
-+              return str;
-+      }
-+
-+      /* Now handle devfs /dev/disc or /dev/disk names */
-+      disk = 0;
-+      if (strncmp(cp, "discs/", 6) == 0)
-+              disk = "disc";
-+      else if (strncmp(cp, "disks/", 6) == 0)
-+              disk = "disk";
-+      if (disk) {
-+              cp += 6;
-+              if (strncmp(cp, disk, 4) != 0)
-+                      goto errout;
-+              cp += 4;
-+              while (*cp != '/' && *cp != 0) {
-+                      if (!isdigit(*cp))
-+                              goto errout;
-+                      cp++;
-+              }
-+              *cp = 0;
-+              return str;
-+      }
-+#endif
-+
-+errout:
-+      free(str);
-+      return NULL;
-+}
-diff -Nur busybox-1.00/e2fsprogs/blkid/blkid.h busybox/e2fsprogs/blkid/blkid.h
---- busybox-1.00/e2fsprogs/blkid/blkid.h       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/blkid.h    2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,105 @@
-+/*
-+ * blkid.h - Interface for libblkid, a library to identify block devices
-+ *
-+ * Copyright (C) 2001 Andreas Dilger
-+ * Copyright (C) 2003 Theodore Ts'o
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#ifndef _BLKID_BLKID_H
-+#define _BLKID_BLKID_H
-+
-+#include <sys/types.h>
-+#include <linux/types.h>
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#define BLKID_VERSION "1.0.0"
-+#define BLKID_DATE    "12-Feb-2003"
-+
-+typedef struct blkid_struct_dev *blkid_dev;
-+typedef struct blkid_struct_cache *blkid_cache;
-+typedef __s64 blkid_loff_t;
-+
-+typedef struct blkid_struct_tag_iterate *blkid_tag_iterate;
-+typedef struct blkid_struct_dev_iterate *blkid_dev_iterate;
-+
-+/*
-+ * Flags for blkid_get_dev
-+ *
-+ * BLKID_DEV_CREATE   Create an empty device structure if not found
-+ *                    in the cache.
-+ * BLKID_DEV_VERIFY   Make sure the device structure corresponds
-+ *                    with reality.
-+ * BLKID_DEV_FIND     Just look up a device entry, and return NULL
-+ *                    if it is not found.
-+ * BLKID_DEV_NORMAL   Get a valid device structure, either from the
-+ *                    cache or by probing the device.
-+ */
-+#define BLKID_DEV_FIND                0x0000
-+#define BLKID_DEV_CREATE      0x0001
-+#define BLKID_DEV_VERIFY      0x0002
-+#define BLKID_DEV_NORMAL      (BLKID_DEV_CREATE | BLKID_DEV_VERIFY)
-+
-+/* cache.c */
-+extern void blkid_put_cache(blkid_cache cache);
-+extern int blkid_get_cache(blkid_cache *cache, const char *filename);
-+
-+/* dev.c */
-+extern const char *blkid_dev_devname(blkid_dev dev);
-+
-+extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache);
-+extern int blkid_dev_next(blkid_dev_iterate iterate, blkid_dev *dev);
-+extern void blkid_dev_iterate_end(blkid_dev_iterate iterate);
-+
-+/* devno.c */
-+extern char *blkid_devno_to_devname(dev_t devno);
-+
-+/* devname.c */
-+extern int blkid_probe_all(blkid_cache cache);
-+extern blkid_dev blkid_get_dev(blkid_cache cache, const char *devname,
-+                             int flags);
-+
-+/* getsize.c */
-+extern blkid_loff_t blkid_get_dev_size(int fd);
-+
-+/* probe.c */
-+int blkid_known_fstype(const char *fstype);
-+extern blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev);
-+
-+/* read.c */
-+
-+/* resolve.c */
-+extern char *blkid_get_tag_value(blkid_cache cache, const char *tagname,
-+                                     const char *devname);
-+extern char *blkid_get_devname(blkid_cache cache, const char *token,
-+                             const char *value);
-+
-+/* tag.c */
-+extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev);
-+extern int blkid_tag_next(blkid_tag_iterate iterate,
-+                            const char **type, const char **value);
-+extern void blkid_tag_iterate_end(blkid_tag_iterate iterate);
-+
-+extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
-+                                       const char *type,
-+                                       const char *value);
-+extern int blkid_parse_tag_string(const char *token, char **ret_type,
-+                                char **ret_val);
-+
-+/* version.c */
-+extern int blkid_parse_version_string(const char *ver_string);
-+extern int blkid_get_library_version(const char **ver_string,
-+                                   const char **date_string);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _BLKID_BLKID_H */
-diff -Nur busybox-1.00/e2fsprogs/blkid/blkidP.h busybox/e2fsprogs/blkid/blkidP.h
---- busybox-1.00/e2fsprogs/blkid/blkidP.h      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/blkidP.h   2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,239 @@
-+/*
-+ * blkidP.h - Internal interfaces for libblkid
-+ *
-+ * Copyright (C) 2001 Andreas Dilger
-+ * Copyright (C) 2003 Theodore Ts'o
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#ifndef _BLKID_BLKIDP_H
-+#define _BLKID_BLKIDP_H
-+
-+#include <sys/types.h>
-+#include <stdio.h>
-+
-+#include <blkid/blkid.h>
-+
-+#include <blkid/list.h>
-+
-+#ifdef __GNUC__
-+#define __BLKID_ATTR(x) __attribute__(x)
-+#else
-+#define __BLKID_ATTR(x)
-+#endif
-+
-+
-+/*
-+ * This describes the attributes of a specific device.
-+ * We can traverse all of the tags by bid_tags (linking to the tag bit_names).
-+ * The bid_label and bid_uuid fields are shortcuts to the LABEL and UUID tag
-+ * values, if they exist.
-+ */
-+struct blkid_struct_dev
-+{
-+      struct list_head        bid_devs;       /* All devices in the cache */
-+      struct list_head        bid_tags;       /* All tags for this device */
-+      blkid_cache             bid_cache;      /* Dev belongs to this cache */
-+      char                    *bid_name;      /* Device inode pathname */
-+      char                    *bid_type;      /* Preferred device TYPE */
-+      int                     bid_pri;        /* Device priority */
-+      dev_t                   bid_devno;      /* Device major/minor number */
-+      time_t                  bid_time;       /* Last update time of device */
-+      unsigned int            bid_flags;      /* Device status bitflags */
-+      char                    *bid_label;     /* Shortcut to device LABEL */
-+      char                    *bid_uuid;      /* Shortcut to binary UUID */
-+};
-+
-+#define BLKID_BID_FL_VERIFIED 0x0001  /* Device data validated from disk */
-+#define BLKID_BID_FL_INVALID  0x0004  /* Device is invalid */
-+
-+/*
-+ * Each tag defines a NAME=value pair for a particular device.  The tags
-+ * are linked via bit_names for a single device, so that traversing the
-+ * names list will get you a list of all tags associated with a device.
-+ * They are also linked via bit_values for all devices, so one can easily
-+ * search all tags with a given NAME for a specific value.
-+ */
-+struct blkid_struct_tag
-+{
-+      struct list_head        bit_tags;       /* All tags for this device */
-+      struct list_head        bit_names;      /* All tags with given NAME */
-+      char                    *bit_name;      /* NAME of tag (shared) */
-+      char                    *bit_val;       /* value of tag */
-+      blkid_dev               bit_dev;        /* pointer to device */
-+};
-+typedef struct blkid_struct_tag *blkid_tag;
-+
-+/*
-+ * Minimum number of seconds between device probes, even when reading
-+ * from the cache.  This is to avoid re-probing all devices which were
-+ * just probed by another program that does not share the cache.
-+ */
-+#define BLKID_PROBE_MIN               2
-+
-+/*
-+ * Time in seconds an entry remains verified in the in-memory cache
-+ * before being reverified (in case of long-running processes that
-+ * keep a cache in memory and continue to use it for a long time).
-+ */
-+#define BLKID_PROBE_INTERVAL  200
-+
-+/* This describes an entire blkid cache file and probed devices.
-+ * We can traverse all of the found devices via bic_list.
-+ * We can traverse all of the tag types by bic_tags, which hold empty tags
-+ * for each tag type.  Those tags can be used as list_heads for iterating
-+ * through all devices with a specific tag type (e.g. LABEL).
-+ */
-+struct blkid_struct_cache
-+{
-+      struct list_head        bic_devs;       /* List head of all devices */
-+      struct list_head        bic_tags;       /* List head of all tag types */
-+      time_t                  bic_time;       /* Last probe time */
-+      time_t                  bic_ftime;      /* Mod time of the cachefile */
-+      unsigned int            bic_flags;      /* Status flags of the cache */
-+      char                    *bic_filename;  /* filename of cache */
-+};
-+
-+#define BLKID_BIC_FL_PROBED   0x0002  /* We probed /proc/partition devices */
-+#define BLKID_BIC_FL_CHANGED  0x0004  /* Cache has changed from disk */
-+
-+extern char *blkid_strdup(const char *s);
-+extern char *blkid_strndup(const char *s, const int length);
-+
-+#define BLKID_CACHE_FILE "/etc/blkid.tab"
-+extern const char *blkid_devdirs[];
-+
-+#define BLKID_ERR_IO   5
-+#define BLKID_ERR_PROC         9
-+#define BLKID_ERR_MEM 12
-+#define BLKID_ERR_CACHE       14
-+#define BLKID_ERR_DEV 19
-+#define BLKID_ERR_PARAM       22
-+#define BLKID_ERR_BIG 27
-+
-+/*
-+ * Priority settings for different types of devices
-+ */
-+#define BLKID_PRI_EVMS        30
-+#define BLKID_PRI_LVM 20
-+#define BLKID_PRI_MD  10
-+
-+#if defined(TEST_PROGRAM) && !defined(CONFIG_BLKID_DEBUG)
-+#define CONFIG_BLKID_DEBUG
-+#endif
-+
-+#define DEBUG_CACHE   0x0001
-+#define DEBUG_DUMP    0x0002
-+#define DEBUG_DEV     0x0004
-+#define DEBUG_DEVNAME 0x0008
-+#define DEBUG_DEVNO   0x0010
-+#define DEBUG_PROBE   0x0020
-+#define DEBUG_READ    0x0040
-+#define DEBUG_RESOLVE 0x0080
-+#define DEBUG_SAVE    0x0100
-+#define DEBUG_TAG     0x0200
-+#define DEBUG_INIT    0x8000
-+#define DEBUG_ALL     0xFFFF
-+
-+#ifdef CONFIG_BLKID_DEBUG
-+#include <stdio.h>
-+extern int    blkid_debug_mask;
-+#define DBG(m,x)      if ((m) & blkid_debug_mask) x;
-+#else
-+#define DBG(m,x)
-+#endif
-+
-+#ifdef CONFIG_BLKID_DEBUG
-+static inline void DEB_DUMP_TAG(int mask, blkid_tag tag)
-+{
-+      if (!(mask & blkid_debug_mask))
-+              return;
-+      
-+      if (!tag) {
-+              printf("    tag: NULL\n");
-+              return;
-+      }
-+
-+      printf("    tag: %s=\"%s\"\n", tag->bit_name, tag->bit_val);
-+}
-+
-+static inline void DEB_DUMP_DEV(int mask, blkid_dev dev)
-+{
-+      struct list_head *p;
-+
-+      if (!(mask & blkid_debug_mask))
-+              return;
-+      
-+      if (!dev) {
-+              printf("  dev: NULL\n");
-+              return;
-+      }
-+
-+      printf("  dev: name = %s\n", dev->bid_name);
-+      printf("  dev: DEVNO=\"0x%0Lx\"\n", dev->bid_devno);
-+      printf("  dev: TIME=\"%lu\"\n", dev->bid_time);
-+      printf("  dev: PRI=\"%d\"\n", dev->bid_pri);
-+      printf("  dev: flags = 0x%08X\n", dev->bid_flags);
-+
-+      list_for_each(p, &dev->bid_tags) {
-+              blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
-+              DEB_DUMP_TAG(mask, tag);
-+      }
-+      printf("\n");
-+}
-+
-+static inline void DEB_DUMP_CACHE(int mask, blkid_cache cache)
-+{
-+      struct list_head *p;
-+
-+      if (!cache || !(mask & blkid_debug_mask)) {
-+              printf("cache: NULL\n");
-+              return;
-+      }
-+
-+      printf("cache: time = %lu\n", cache->bic_time);
-+      printf("cache: flags = 0x%08X\n", cache->bic_flags);
-+
-+      list_for_each(p, &cache->bic_devs) {
-+              blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
-+              DEB_DUMP_DEV(mask, dev);
-+      }
-+}
-+#else
-+#define DEB_DUMP_TAG(mask, tag) do {} while (0)
-+#define DEB_DUMP_DEV(mask, dev) do {} while (0)
-+#define DEB_DUMP_CACHE(mask, cache) do {} while (0)
-+#endif
-+
-+/* lseek.c */
-+extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence);
-+
-+/* read.c */
-+extern void blkid_read_cache(blkid_cache cache);
-+
-+/* save.c */
-+extern int blkid_flush_cache(blkid_cache cache);
-+
-+/*
-+ * Functions to create and find a specific tag type: tag.c
-+ */
-+extern void blkid_free_tag(blkid_tag tag);
-+extern blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type);
-+extern int blkid_set_tag(blkid_dev dev, const char *name,
-+                       const char *value, const int vlength);
-+
-+/*
-+ * Functions to create and find a specific tag type: dev.c
-+ */
-+extern blkid_dev blkid_new_dev(void);
-+extern void blkid_free_dev(blkid_dev dev);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _BLKID_BLKIDP_H */
-diff -Nur busybox-1.00/e2fsprogs/blkid/cache.c busybox/e2fsprogs/blkid/cache.c
---- busybox-1.00/e2fsprogs/blkid/cache.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/cache.c    2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,126 @@
-+/*
-+ * cache.c - allocation/initialization/free routines for cache
-+ *
-+ * Copyright (C) 2001 Andreas Dilger
-+ * Copyright (C) 2003 Theodore Ts'o
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include "blkidP.h"
-+
-+int blkid_debug_mask = 0;
-+
-+int blkid_get_cache(blkid_cache *ret_cache, const char *filename)
-+{
-+      blkid_cache cache;
-+
-+#ifdef CONFIG_BLKID_DEBUG
-+      if (!(blkid_debug_mask & DEBUG_INIT)) {
-+              char *dstr = getenv("BLKID_DEBUG");
-+
-+              if (dstr)
-+                      blkid_debug_mask = strtoul(dstr, 0, 0);
-+              blkid_debug_mask |= DEBUG_INIT;
-+      }
-+#endif
-+
-+      DBG(DEBUG_CACHE, printf("creating blkid cache (using %s)\n",
-+                              filename ? filename : "default cache"));
-+
-+      if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache))))
-+              return -BLKID_ERR_MEM;
-+
-+      INIT_LIST_HEAD(&cache->bic_devs);
-+      INIT_LIST_HEAD(&cache->bic_tags);
-+
-+      if (filename && !strlen(filename))
-+              filename = 0;
-+      if (!filename && (getuid() == geteuid()))
-+              filename = getenv("BLKID_FILE");
-+      if (!filename)
-+              filename = BLKID_CACHE_FILE;
-+      cache->bic_filename = blkid_strdup(filename);
-+      
-+      blkid_read_cache(cache);
-+      
-+      *ret_cache = cache;
-+      return 0;
-+}
-+
-+void blkid_put_cache(blkid_cache cache)
-+{
-+      if (!cache)
-+              return;
-+
-+      (void) blkid_flush_cache(cache);
-+
-+      DBG(DEBUG_CACHE, printf("freeing cache struct\n"));
-+      
-+      /* DEB_DUMP_CACHE(cache); */
-+
-+      while (!list_empty(&cache->bic_devs)) {
-+              blkid_dev dev = list_entry(cache->bic_devs.next,
-+                                         struct blkid_struct_dev,
-+                                          bid_devs);
-+              blkid_free_dev(dev);
-+      }
-+
-+      while (!list_empty(&cache->bic_tags)) {
-+              blkid_tag tag = list_entry(cache->bic_tags.next,
-+                                         struct blkid_struct_tag,
-+                                         bit_tags);
-+
-+              while (!list_empty(&tag->bit_names)) {
-+                      blkid_tag bad = list_entry(tag->bit_names.next,
-+                                                 struct blkid_struct_tag, 
-+                                                 bit_names);
-+
-+                      DBG(DEBUG_CACHE, printf("warning: unfreed tag %s=%s\n",
-+                                              bad->bit_name, bad->bit_val));
-+                      blkid_free_tag(bad);
-+              }
-+              blkid_free_tag(tag);
-+      }
-+      if (cache->bic_filename)
-+              free(cache->bic_filename);
-+      
-+      free(cache);
-+}
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char** argv)
-+{
-+      blkid_cache cache = NULL;
-+      int ret;
-+
-+      blkid_debug_mask = DEBUG_ALL;
-+      if ((argc > 2)) {
-+              fprintf(stderr, "Usage: %s [filename] \n", argv[0]);
-+              exit(1);
-+      }
-+
-+      if ((ret = blkid_get_cache(&cache, argv[1])) < 0) {
-+              fprintf(stderr, "error %d parsing cache file %s\n", ret,
-+                      argv[1] ? argv[1] : BLKID_CACHE_FILE);
-+              exit(1);
-+      }
-+      if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
-+              fprintf(stderr, "%s: error creating cache (%d)\n",
-+                      argv[0], ret);
-+              exit(1);
-+      }
-+      if ((ret = blkid_probe_all(cache) < 0))
-+              fprintf(stderr, "error probing devices\n");
-+
-+      blkid_put_cache(cache);
-+
-+      return ret;
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/blkid/dev.c busybox/e2fsprogs/blkid/dev.c
---- busybox-1.00/e2fsprogs/blkid/dev.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/dev.c      2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,118 @@
-+/*
-+ * dev.c - allocation/initialization/free routines for dev
-+ *
-+ * Copyright (C) 2001 Andreas Dilger
-+ * Copyright (C) 2003 Theodore Ts'o
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#include "blkidP.h"
-+
-+blkid_dev blkid_new_dev(void)
-+{
-+      blkid_dev dev;
-+
-+      if (!(dev = (blkid_dev) calloc(1, sizeof(struct blkid_struct_dev))))
-+              return NULL;
-+
-+      INIT_LIST_HEAD(&dev->bid_devs);
-+      INIT_LIST_HEAD(&dev->bid_tags);
-+
-+      return dev;
-+}
-+
-+void blkid_free_dev(blkid_dev dev)
-+{
-+      if (!dev)
-+              return;
-+
-+      DBG(DEBUG_DEV,
-+          printf("  freeing dev %s (%s)\n", dev->bid_name, dev->bid_type));
-+      DEB_DUMP_DEV(DEBUG_DEV, dev);
-+
-+      list_del(&dev->bid_devs);
-+      while (!list_empty(&dev->bid_tags)) {
-+              blkid_tag tag = list_entry(dev->bid_tags.next,
-+                                         struct blkid_struct_tag,
-+                                         bit_tags);
-+              blkid_free_tag(tag);
-+      }
-+      if (dev->bid_name)
-+              free(dev->bid_name);
-+      free(dev);
-+}
-+
-+/*
-+ * Given a blkid device, return its name
-+ */
-+extern const char *blkid_dev_devname(blkid_dev dev)
-+{
-+      return dev->bid_name;
-+}
-+
-+/*
-+ * dev iteration routines for the public libblkid interface.
-+ *
-+ * These routines do not expose the list.h implementation, which are a
-+ * contamination of the namespace, and which force us to reveal far, far
-+ * too much of our internal implemenation.  I'm not convinced I want
-+ * to keep list.h in the long term, anyway.  It's fine for kernel
-+ * programming, but performance is not the #1 priority for this
-+ * library, and I really don't like the tradeoff of type-safety for
-+ * performance for this application.  [tytso:20030125.2007EST]
-+ */
-+
-+/*
-+ * This series of functions iterate over all devices in a blkid cache
-+ */
-+#define DEV_ITERATE_MAGIC     0x01a5284c
-+      
-+struct blkid_struct_dev_iterate {
-+      int                     magic;
-+      blkid_cache             cache;
-+      struct list_head        *p;
-+};
-+
-+extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache)
-+{
-+      blkid_dev_iterate       iter;
-+
-+      iter = malloc(sizeof(struct blkid_struct_dev_iterate));
-+      if (iter) {
-+              iter->magic = DEV_ITERATE_MAGIC;
-+              iter->cache = cache;
-+              iter->p = cache->bic_devs.next;
-+      }
-+      return (iter);
-+}
-+
-+/*
-+ * Return 0 on success, -1 on error
-+ */
-+extern int blkid_dev_next(blkid_dev_iterate iter,
-+                        blkid_dev *dev)
-+{
-+      *dev = 0;
-+      if (!iter || iter->magic != DEV_ITERATE_MAGIC ||
-+          iter->p == &iter->cache->bic_devs)
-+              return -1;
-+      *dev = list_entry(iter->p, struct blkid_struct_dev, bid_devs);
-+      iter->p = iter->p->next;
-+      return 0;
-+}
-+
-+extern void blkid_dev_iterate_end(blkid_dev_iterate iter)
-+{
-+      if (!iter || iter->magic != DEV_ITERATE_MAGIC)
-+              return;
-+      iter->magic = 0;
-+      free(iter);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/blkid/devname.c busybox/e2fsprogs/blkid/devname.c
---- busybox-1.00/e2fsprogs/blkid/devname.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/devname.c  2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,376 @@
-+/*
-+ * devname.c - get a dev by its device inode name
-+ *
-+ * Copyright (C) Andries Brouwer
-+ * Copyright (C) 1999, 2000, 2001, 2002, 2003 Theodore Ts'o
-+ * Copyright (C) 2001 Andreas Dilger
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <stdlib.h>
-+#include <string.h>
-+#include <ctype.h>
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_SYS_MKDEV_H
-+#include <sys/mkdev.h>
-+#endif
-+#include <time.h>
-+
-+#include "blkidP.h"
-+
-+/*
-+ * Find a dev struct in the cache by device name, if available.
-+ *
-+ * If there is no entry with the specified device name, and the create
-+ * flag is set, then create an empty device entry.
-+ */
-+blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags)
-+{
-+      blkid_dev dev = NULL, tmp;
-+      struct list_head *p;
-+
-+      if (!cache || !devname)
-+              return NULL;
-+
-+      list_for_each(p, &cache->bic_devs) {
-+              tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
-+              if (strcmp(tmp->bid_name, devname))
-+                      continue;
-+
-+              DBG(DEBUG_DEVNAME, 
-+                  printf("found devname %s in cache\n", tmp->bid_name));
-+              dev = tmp;
-+              break;
-+      }
-+
-+      if (!dev && (flags & BLKID_DEV_CREATE)) {
-+              dev = blkid_new_dev();
-+              if (!dev)
-+                      return NULL;
-+              dev->bid_name = blkid_strdup(devname);
-+              dev->bid_cache = cache;
-+              list_add_tail(&dev->bid_devs, &cache->bic_devs);
-+              cache->bic_flags |= BLKID_BIC_FL_CHANGED;
-+      }
-+
-+      if (flags & BLKID_DEV_VERIFY)
-+              dev = blkid_verify(cache, dev);
-+      return dev;
-+}
-+
-+/*
-+ * Probe a single block device to add to the device cache.
-+ */
-+static void probe_one(blkid_cache cache, const char *ptname,
-+                    dev_t devno, int pri)
-+{
-+      blkid_dev dev = NULL;
-+      struct list_head *p;
-+      const char **dir;
-+      char *devname = NULL;
-+
-+      /* See if we already have this device number in the cache. */
-+      list_for_each(p, &cache->bic_devs) {
-+              blkid_dev tmp = list_entry(p, struct blkid_struct_dev,
-+                                         bid_devs);
-+              if (tmp->bid_devno == devno) {
-+                      dev = blkid_verify(cache, tmp);
-+                      break;
-+              }
-+      }
-+      if (dev && dev->bid_devno == devno)
-+              goto set_pri;
-+
-+      /*
-+       * Take a quick look at /dev/ptname for the device number.  We check
-+       * all of the likely device directories.  If we don't find it, or if
-+       * the stat information doesn't check out, use blkid_devno_to_devname()
-+       * to find it via an exhaustive search for the device major/minor.
-+       */
-+      for (dir = blkid_devdirs; *dir; dir++) {
-+              struct stat st;
-+              char device[256];
-+
-+              sprintf(device, "%s/%s", *dir, ptname);
-+              if ((dev = blkid_get_dev(cache, device, BLKID_DEV_FIND)) &&
-+                  dev->bid_devno == devno)
-+                      goto set_pri;
-+
-+              if (stat(device, &st) == 0 && S_ISBLK(st.st_mode) && 
-+                  st.st_rdev == devno) {
-+                      devname = blkid_strdup(device);
-+                      break;
-+              }
-+      }
-+      if (!devname) {
-+              devname = blkid_devno_to_devname(devno);
-+              if (!devname)
-+                      return;
-+      }
-+      dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL);
-+      free(devname);
-+
-+set_pri:
-+      if (!pri && !strncmp(ptname, "md", 2))
-+              pri = BLKID_PRI_MD;
-+      if (dev)
-+              dev->bid_pri = pri;
-+      return;
-+}
-+
-+#define PROC_PARTITIONS "/proc/partitions"
-+#define VG_DIR                "/proc/lvm/VGs"
-+
-+/*
-+ * This function initializes the UUID cache with devices from the LVM
-+ * proc hierarchy.  We currently depend on the names of the LVM
-+ * hierarchy giving us the device structure in /dev.  (XXX is this a
-+ * safe thing to do?)
-+ */
-+#ifdef VG_DIR
-+#include <dirent.h>
-+static dev_t lvm_get_devno(const char *lvm_device)
-+{
-+      FILE *lvf;
-+      char buf[1024];
-+      int ma, mi;
-+      dev_t ret = 0;
-+
-+      DBG(DEBUG_DEVNAME, printf("opening %s\n", lvm_device));
-+      if ((lvf = fopen(lvm_device, "r")) == NULL) {
-+              DBG(DEBUG_DEVNAME, printf("%s: (%d) %s\n", lvm_device, errno,
-+                                        strerror(errno)));
-+              return 0;
-+      }
-+
-+      while (fgets(buf, sizeof(buf), lvf)) {
-+              if (sscanf(buf, "device: %d:%d", &ma, &mi) == 2) {
-+                      ret = makedev(ma, mi);
-+                      break;
-+              }
-+      }
-+      fclose(lvf);
-+
-+      return ret;
-+}
-+
-+static void lvm_probe_all(blkid_cache cache)
-+{
-+      DIR             *vg_list;
-+      struct dirent   *vg_iter;
-+      int             vg_len = strlen(VG_DIR);
-+      dev_t           dev;
-+
-+      if ((vg_list = opendir(VG_DIR)) == NULL)
-+              return;
-+
-+      DBG(DEBUG_DEVNAME, printf("probing LVM devices under %s\n", VG_DIR));
-+
-+      while ((vg_iter = readdir(vg_list)) != NULL) {
-+              DIR             *lv_list;
-+              char            *vdirname;
-+              char            *vg_name;
-+              struct dirent   *lv_iter;
-+
-+              vg_name = vg_iter->d_name;
-+              if (!strcmp(vg_name, ".") || !strcmp(vg_name, ".."))
-+                      continue;
-+              vdirname = malloc(vg_len + strlen(vg_name) + 8);
-+              if (!vdirname)
-+                      goto exit;
-+              sprintf(vdirname, "%s/%s/LVs", VG_DIR, vg_name);
-+
-+              lv_list = opendir(vdirname);
-+              free(vdirname);
-+              if (lv_list == NULL)
-+                      continue;
-+
-+              while ((lv_iter = readdir(lv_list)) != NULL) {
-+                      char            *lv_name, *lvm_device;
-+
-+                      lv_name = lv_iter->d_name;
-+                      if (!strcmp(lv_name, ".") || !strcmp(lv_name, ".."))
-+                              continue;
-+
-+                      lvm_device = malloc(vg_len + strlen(vg_name) +
-+                                          strlen(lv_name) + 8);
-+                      if (!lvm_device) {
-+                              closedir(lv_list);
-+                              goto exit;
-+                      }
-+                      sprintf(lvm_device, "%s/%s/LVs/%s", VG_DIR, vg_name,
-+                              lv_name);
-+                      dev = lvm_get_devno(lvm_device);
-+                      sprintf(lvm_device, "%s/%s", vg_name, lv_name);
-+                      DBG(DEBUG_DEVNAME, printf("LVM dev %s: devno 0x%04X\n",
-+                                                lvm_device,
-+                                                (unsigned int) dev));
-+                      probe_one(cache, lvm_device, dev, BLKID_PRI_LVM);
-+                      free(lvm_device);
-+              }
-+              closedir(lv_list);
-+      }
-+exit:
-+      closedir(vg_list);
-+}
-+#endif
-+
-+#define PROC_EVMS_VOLUMES "/proc/evms/volumes"
-+
-+static int
-+evms_probe_all(blkid_cache cache)
-+{
-+      char line[100];
-+      int ma, mi, sz, num = 0;
-+      FILE *procpt;
-+      char device[110];
-+
-+      procpt = fopen(PROC_EVMS_VOLUMES, "r");
-+      if (!procpt)
-+              return 0;
-+      while (fgets(line, sizeof(line), procpt)) {
-+              if (sscanf (line, " %d %d %d %*s %*s %[^\n ]",
-+                          &ma, &mi, &sz, device) != 4)
-+                      continue;
-+
-+              DBG(DEBUG_DEVNAME, printf("Checking partition %s (%d, %d)\n",
-+                                        device, ma, mi));
-+
-+              probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS);
-+              num++;
-+      }
-+      fclose(procpt);
-+      return num;
-+}
-+
-+/*
-+ * Read the device data for all available block devices in the system.
-+ */
-+int blkid_probe_all(blkid_cache cache)
-+{
-+      FILE *proc;
-+      char line[1024];
-+      char ptname0[128], ptname1[128], *ptname = 0;
-+      char *ptnames[2];
-+      dev_t devs[2];
-+      int ma, mi;
-+      unsigned long long sz;
-+      int lens[2] = { 0, 0 };
-+      int which = 0, last = 0;
-+
-+      ptnames[0] = ptname0;
-+      ptnames[1] = ptname1;
-+
-+      if (!cache)
-+              return -BLKID_ERR_PARAM;
-+
-+      if (cache->bic_flags & BLKID_BIC_FL_PROBED &&
-+          time(0) - cache->bic_time < BLKID_PROBE_INTERVAL)
-+              return 0;
-+
-+      blkid_read_cache(cache);
-+      evms_probe_all(cache);
-+#ifdef VG_DIR
-+      lvm_probe_all(cache);
-+#endif
-+
-+      proc = fopen(PROC_PARTITIONS, "r");
-+      if (!proc)
-+              return -BLKID_ERR_PROC;
-+
-+      while (fgets(line, sizeof(line), proc)) {
-+              last = which;
-+              which ^= 1;
-+              ptname = ptnames[which];
-+
-+              if (sscanf(line, " %d %d %llu %128[^\n ]",
-+                         &ma, &mi, &sz, ptname) != 4)
-+                      continue;
-+              devs[which] = makedev(ma, mi);
-+
-+              DBG(DEBUG_DEVNAME, printf("read partition name %s\n", ptname));
-+
-+              /* Skip whole disk devs unless they have no partitions
-+               * If we don't have a partition on this dev, also
-+               * check previous dev to see if it didn't have a partn.
-+               * heuristic: partition name ends in a digit.
-+               *
-+               * Skip extended partitions.
-+               * heuristic: size is 1
-+               *
-+               * FIXME: skip /dev/{ida,cciss,rd} whole-disk devs
-+               */
-+
-+              lens[which] = strlen(ptname);
-+              if (isdigit(ptname[lens[which] - 1])) {
-+                      DBG(DEBUG_DEVNAME,
-+                          printf("partition dev %s, devno 0x%04X\n",
-+                                 ptname, (unsigned int) devs[which]));
-+
-+                      if (sz > 1)
-+                              probe_one(cache, ptname, devs[which], 0);
-+                      lens[which] = 0;
-+                      lens[last] = 0;
-+              } else if (lens[last] && strncmp(ptnames[last], ptname,
-+                                               lens[last])) {
-+                      DBG(DEBUG_DEVNAME,
-+                          printf("whole dev %s, devno 0x%04X\n",
-+                                 ptnames[last], (unsigned int) devs[last]));
-+                      probe_one(cache, ptnames[last], devs[last], 0);
-+                      lens[last] = 0;
-+              }
-+      }
-+
-+      /* Handle the last device if it wasn't partitioned */
-+      if (lens[which])
-+              probe_one(cache, ptname, devs[which], 0);
-+
-+      fclose(proc);
-+
-+      cache->bic_time = time(0);
-+      cache->bic_flags |= BLKID_BIC_FL_PROBED;
-+      blkid_flush_cache(cache);
-+      return 0;
-+}
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char **argv)
-+{
-+      blkid_cache cache = NULL;
-+      int ret;
-+
-+      blkid_debug_mask = DEBUG_ALL;
-+      if (argc != 1) {
-+              fprintf(stderr, "Usage: %s\n"
-+                      "Probe all devices and exit\n", argv[0]);
-+              exit(1);
-+      }
-+      if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
-+              fprintf(stderr, "%s: error creating cache (%d)\n",
-+                      argv[0], ret);
-+              exit(1);
-+      }
-+      if (blkid_probe_all(cache) < 0)
-+              printf("%s: error probing devices\n", argv[0]);
-+
-+      blkid_put_cache(cache);
-+      return (0);
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/blkid/devno.c busybox/e2fsprogs/blkid/devno.c
---- busybox-1.00/e2fsprogs/blkid/devno.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/devno.c    2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,233 @@
-+/*
-+ * devno.c - find a particular device by its device number (major/minor)
-+ *
-+ * Copyright (C) 2000, 2001, 2003 Theodore Ts'o
-+ * Copyright (C) 2001 Andreas Dilger
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <stdlib.h>
-+#include <string.h>
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#include <dirent.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_SYS_MKDEV_H
-+#include <sys/mkdev.h>
-+#endif
-+
-+#include "blkidP.h"
-+
-+struct dir_list {
-+      char    *name;
-+      struct dir_list *next;
-+};
-+
-+char *blkid_strndup(const char *s, int length)
-+{
-+      char *ret;
-+
-+      if (!s)
-+              return NULL;
-+
-+      if (!length)
-+              length = strlen(s);
-+
-+      ret = malloc(length + 1);
-+      if (ret) {
-+              strncpy(ret, s, length);
-+              ret[length] = '\0';
-+      }
-+      return ret;
-+}
-+
-+char *blkid_strdup(const char *s)
-+{
-+      return blkid_strndup(s, 0);
-+}
-+
-+/*
-+ * This function adds an entry to the directory list
-+ */
-+static void add_to_dirlist(const char *name, struct dir_list **list)
-+{
-+      struct dir_list *dp;
-+
-+      dp = malloc(sizeof(struct dir_list));
-+      if (!dp)
-+              return;
-+      dp->name = blkid_strdup(name);
-+      if (!dp->name) {
-+              free(dp);
-+              return;
-+      }
-+      dp->next = *list;
-+      *list = dp;
-+}
-+
-+/*
-+ * This function frees a directory list
-+ */
-+static void free_dirlist(struct dir_list **list)
-+{
-+      struct dir_list *dp, *next;
-+
-+      for (dp = *list; dp; dp = next) {
-+              next = dp->next;
-+              free(dp->name);
-+              free(dp);
-+      }
-+      *list = NULL;
-+}
-+
-+static void scan_dir(char *dir_name, dev_t devno, struct dir_list **list,
-+                          char **devname)
-+{
-+      DIR     *dir;
-+      struct dirent *dp;
-+      char    path[1024];
-+      int     dirlen;
-+      struct stat st;
-+
-+      if ((dir = opendir(dir_name)) == NULL)
-+              return;
-+      dirlen = strlen(dir_name) + 2;
-+      while ((dp = readdir(dir)) != 0) {
-+              if (dirlen + strlen(dp->d_name) >= sizeof(path))
-+                      continue;
-+
-+              if (dp->d_name[0] == '.' &&
-+                  ((dp->d_name[1] == 0) ||
-+                   ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
-+                      continue;
-+
-+              sprintf(path, "%s/%s", dir_name, dp->d_name);
-+              if (stat(path, &st) < 0)
-+                      continue;
-+
-+              if (S_ISDIR(st.st_mode))
-+                      add_to_dirlist(path, list);
-+              else if (S_ISBLK(st.st_mode) && st.st_rdev == devno) {
-+                      *devname = blkid_strdup(path);
-+                      DBG(DEBUG_DEVNO,
-+                          printf("found 0x%Lx at %s (%p)\n", devno,
-+                                 path, *devname));
-+                      break;
-+              }
-+      }
-+      closedir(dir);
-+      return;
-+}
-+
-+/* Directories where we will try to search for device numbers */
-+const char *blkid_devdirs[] = { "/devices", "/devfs", "/dev", NULL };
-+
-+/*
-+ * This function finds the pathname to a block device with a given
-+ * device number.  It returns a pointer to allocated memory to the
-+ * pathname on success, and NULL on failure.
-+ */
-+char *blkid_devno_to_devname(dev_t devno)
-+{
-+      struct dir_list *list = NULL, *new_list = NULL;
-+      char *devname = NULL;
-+      const char **dir;
-+
-+      /*
-+       * Add the starting directories to search in reverse order of
-+       * importance, since we are using a stack...
-+       */
-+      for (dir = blkid_devdirs; *dir; dir++)
-+              add_to_dirlist(*dir, &list);
-+
-+      while (list) {
-+              struct dir_list *current = list;
-+
-+              list = list->next;
-+              DBG(DEBUG_DEVNO, printf("directory %s\n", current->name));
-+              scan_dir(current->name, devno, &new_list, &devname);
-+              free(current->name);
-+              free(current);
-+              if (devname)
-+                      break;
-+              /*
-+               * If we're done checking at this level, descend to
-+               * the next level of subdirectories. (breadth-first)
-+               */
-+              if (list == NULL) {
-+                      list = new_list;
-+                      new_list = NULL;
-+              }
-+      }
-+      free_dirlist(&list);
-+      free_dirlist(&new_list);
-+
-+      if (!devname) {
-+              DBG(DEBUG_DEVNO,
-+                  printf("blkid: couldn't find devno 0x%04lx\n", 
-+                         (unsigned long) devno));
-+      } else {
-+              DBG(DEBUG_DEVNO,
-+                  printf("found devno 0x%04Lx as %s\n", devno, devname));
-+      }
-+      
-+
-+      return devname;
-+}
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char** argv)
-+{
-+      char    *devname, *tmp;
-+      int     major, minor;
-+      dev_t   devno;
-+      const char *errmsg = "Couldn't parse %s: %s\n";
-+
-+      blkid_debug_mask = DEBUG_ALL;
-+      if ((argc != 2) && (argc != 3)) {
-+              fprintf(stderr, "Usage:\t%s device_number\n\t%s major minor\n"
-+                      "Resolve a device number to a device name\n",
-+                      argv[0], argv[0]);
-+              exit(1);
-+      }
-+      if (argc == 2) {
-+              devno = strtoul(argv[1], &tmp, 0);
-+              if (*tmp) {
-+                      fprintf(stderr, errmsg, "device number", argv[1]);
-+                      exit(1);
-+              }
-+      } else {
-+              major = strtoul(argv[1], &tmp, 0);
-+              if (*tmp) {
-+                      fprintf(stderr, errmsg, "major number", argv[1]);
-+                      exit(1);
-+              }
-+              minor = strtoul(argv[2], &tmp, 0);
-+              if (*tmp) {
-+                      fprintf(stderr, errmsg, "minor number", argv[2]);
-+                      exit(1);
-+              }
-+              devno = makedev(major, minor);
-+      }
-+      printf("Looking for device 0x%04Lx\n", devno);
-+      devname = blkid_devno_to_devname(devno);
-+      if (devname)
-+              free(devname);
-+      return 0;
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/blkid/getsize.c busybox/e2fsprogs/blkid/getsize.c
---- busybox-1.00/e2fsprogs/blkid/getsize.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/getsize.c  2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,180 @@
-+/*
-+ * getsize.c --- get the size of a partition.
-+ *
-+ * Copyright (C) 1995, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+/* include this before sys/queues.h! */
-+#include "blkidP.h"
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#ifdef HAVE_SYS_IOCTL_H
-+#include <sys/ioctl.h>
-+#endif
-+#ifdef HAVE_LINUX_FD_H
-+#include <linux/fd.h>
-+#endif
-+#ifdef HAVE_SYS_DISKLABEL_H
-+#include <sys/disklabel.h>
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_SYS_DISK_H
-+#ifdef HAVE_SYS_QUEUE_H
-+#include <sys/queue.h> /* for LIST_HEAD */
-+#endif
-+#include <sys/disk.h>
-+#endif
-+#ifdef __linux__
-+#include <sys/utsname.h>
-+#endif
-+
-+#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
-+#define BLKGETSIZE _IO(0x12,96)       /* return device size */
-+#endif
-+
-+#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
-+#define BLKGETSIZE64 _IOR(0x12,114,size_t)    /* return device size in bytes (u64 *arg) */
-+#endif
-+
-+#ifdef APPLE_DARWIN
-+#define BLKGETSIZE DKIOCGETBLOCKCOUNT32
-+#endif /* APPLE_DARWIN */
-+
-+static int valid_offset(int fd, blkid_loff_t offset)
-+{
-+      char ch;
-+
-+      if (blkid_llseek(fd, offset, 0) < 0)
-+              return 0;
-+      if (read(fd, &ch, 1) < 1)
-+              return 0;
-+      return 1;
-+}
-+
-+/*
-+ * Returns the number of blocks in a partition
-+ */
-+blkid_loff_t blkid_get_dev_size(int fd)
-+{
-+      int valid_blkgetsize64 = 1;
-+#ifdef __linux__
-+      struct          utsname ut;
-+#endif
-+      unsigned long long size64;
-+      unsigned long size;
-+      blkid_loff_t high, low;
-+#ifdef FDGETPRM
-+      struct floppy_struct this_floppy;
-+#endif
-+#ifdef HAVE_SYS_DISKLABEL_H
-+      int part = -1;
-+      struct disklabel lab;
-+      struct partition *pp;
-+      char ch;
-+      struct stat st;
-+#endif /* HAVE_SYS_DISKLABEL_H */
-+
-+#ifdef DKIOCGETBLOCKCOUNT     /* For Apple Darwin */
-+      if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) {
-+              if ((sizeof(blkid_loff_t) < sizeof(unsigned long long))
-+                  && (size64 << 9 > 0xFFFFFFFF))
-+                      return 0; /* EFBIG */
-+              return (blkid_loff_t) size64 << 9;
-+      }
-+#endif
-+
-+#ifdef BLKGETSIZE64
-+#ifdef __linux__
-+      if ((uname(&ut) == 0) &&
-+          ((ut.release[0] == '2') && (ut.release[1] == '.') &&
-+           (ut.release[2] < '6') && (ut.release[3] == '.')))
-+              valid_blkgetsize64 = 0;
-+#endif
-+      if (valid_blkgetsize64 &&
-+          ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
-+              if ((sizeof(blkid_loff_t) < sizeof(unsigned long long))
-+                  && ((size64) > 0xFFFFFFFF))
-+                      return 0; /* EFBIG */
-+              return size64;
-+      }
-+#endif
-+
-+#ifdef BLKGETSIZE
-+      if (ioctl(fd, BLKGETSIZE, &size) >= 0)
-+              return (blkid_loff_t)size << 9;
-+#endif
-+
-+#ifdef FDGETPRM
-+      if (ioctl(fd, FDGETPRM, &this_floppy) >= 0)
-+              return (blkid_loff_t)this_floppy.size << 9;
-+#endif
-+#ifdef HAVE_SYS_DISKLABEL_H
-+#if 0
-+      /*
-+       * This should work in theory but I haven't tested it.  Anyone
-+       * on a BSD system want to test this for me?  In the meantime,
-+       * binary search mechanism should work just fine.
-+       */
-+      if ((fstat(fd, &st) >= 0) && S_ISBLK(st.st_mode))
-+              part = st.st_rdev & 7;
-+      if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
-+              pp = &lab.d_partitions[part];
-+              if (pp->p_size)
-+                      return pp->p_size << 9;
-+      }
-+#endif
-+#endif /* HAVE_SYS_DISKLABEL_H */
-+
-+      /*
-+       * OK, we couldn't figure it out by using a specialized ioctl,
-+       * which is generally the best way.  So do binary search to
-+       * find the size of the partition.
-+       */
-+      low = 0;
-+      for (high = 1024; valid_offset(fd, high); high *= 2)
-+              low = high;
-+      while (low < high - 1)
-+      {
-+              const blkid_loff_t mid = (low + high) / 2;
-+
-+              if (valid_offset(fd, mid))
-+                      low = mid;
-+              else
-+                      high = mid;
-+      }
-+      return low + 1;
-+}
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char **argv)
-+{
-+      blkid_loff_t bytes;
-+      int     fd;
-+
-+      if (argc < 2) {
-+              fprintf(stderr, "Usage: %s device\n"
-+                      "Determine the size of a device\n", argv[0]);
-+              return 1;
-+      }
-+
-+      if ((fd = open(argv[1], O_RDONLY)) < 0)
-+              perror(argv[0]);
-+
-+      bytes = blkid_get_dev_size(fd);
-+      printf("Device %s has %Ld 1k blocks.\n", argv[1], bytes >> 10);
-+
-+      return 0;
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/blkid/list.h busybox/e2fsprogs/blkid/list.h
---- busybox-1.00/e2fsprogs/blkid/list.h        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/list.h     2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,179 @@
-+#if !defined(_BLKID_LIST_H) && !defined(LIST_HEAD)
-+#define _BLKID_LIST_H
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+#ifdef __GNUC__
-+#define _INLINE_ static __inline__
-+#else                         /* For Watcom C */
-+#define _INLINE_ static inline
-+#endif
-+
-+/*
-+ * Simple doubly linked list implementation.
-+ *
-+ * Some of the internal functions ("__xxx") are useful when
-+ * manipulating whole lists rather than single entries, as
-+ * sometimes we already know the next/prev entries and we can
-+ * generate better code by using them directly rather than
-+ * using the generic single-entry routines.
-+ */
-+
-+struct list_head {
-+      struct list_head *next, *prev;
-+};
-+
-+#define LIST_HEAD_INIT(name) { &(name), &(name) }
-+
-+#define LIST_HEAD(name) \
-+      struct list_head name = LIST_HEAD_INIT(name)
-+
-+#define INIT_LIST_HEAD(ptr) do { \
-+      (ptr)->next = (ptr); (ptr)->prev = (ptr); \
-+} while (0)
-+
-+/*
-+ * Insert a new entry between two known consecutive entries.
-+ *
-+ * This is only for internal list manipulation where we know
-+ * the prev/next entries already!
-+ */
-+_INLINE_ void __list_add(struct list_head * add,
-+      struct list_head * prev,
-+      struct list_head * next)
-+{
-+      next->prev = add;
-+      add->next = next;
-+      add->prev = prev;
-+      prev->next = add;
-+}
-+
-+/**
-+ * list_add - add a new entry
-+ * @add:      new entry to be added
-+ * @head:     list head to add it after
-+ *
-+ * Insert a new entry after the specified head.
-+ * This is good for implementing stacks.
-+ */
-+_INLINE_ void list_add(struct list_head *add, struct list_head *head)
-+{
-+      __list_add(add, head, head->next);
-+}
-+
-+/**
-+ * list_add_tail - add a new entry
-+ * @add:      new entry to be added
-+ * @head:     list head to add it before
-+ *
-+ * Insert a new entry before the specified head.
-+ * This is useful for implementing queues.
-+ */
-+_INLINE_ void list_add_tail(struct list_head *add, struct list_head *head)
-+{
-+      __list_add(add, head->prev, head);
-+}
-+
-+/*
-+ * Delete a list entry by making the prev/next entries
-+ * point to each other.
-+ *
-+ * This is only for internal list manipulation where we know
-+ * the prev/next entries already!
-+ */
-+_INLINE_ void __list_del(struct list_head * prev,
-+                                struct list_head * next)
-+{
-+      next->prev = prev;
-+      prev->next = next;
-+}
-+
-+/**
-+ * list_del - deletes entry from list.
-+ * @entry:    the element to delete from the list.
-+ *
-+ * list_empty() on @entry does not return true after this, @entry is
-+ * in an undefined state.
-+ */
-+_INLINE_ void list_del(struct list_head *entry)
-+{
-+      __list_del(entry->prev, entry->next);
-+}
-+
-+/**
-+ * list_del_init - deletes entry from list and reinitialize it.
-+ * @entry:    the element to delete from the list.
-+ */
-+_INLINE_ void list_del_init(struct list_head *entry)
-+{
-+      __list_del(entry->prev, entry->next);
-+      INIT_LIST_HEAD(entry);
-+}
-+
-+/**
-+ * list_empty - tests whether a list is empty
-+ * @head:     the list to test.
-+ */
-+_INLINE_ int list_empty(struct list_head *head)
-+{
-+      return head->next == head;
-+}
-+
-+/**
-+ * list_splice - join two lists
-+ * @list:     the new list to add.
-+ * @head:     the place to add it in the first list.
-+ */
-+_INLINE_ void list_splice(struct list_head *list, struct list_head *head)
-+{
-+      struct list_head *first = list->next;
-+
-+      if (first != list) {
-+              struct list_head *last = list->prev;
-+              struct list_head *at = head->next;
-+
-+              first->prev = head;
-+              head->next = first;
-+
-+              last->next = at;
-+              at->prev = last;
-+      }
-+}
-+
-+/**
-+ * list_entry - get the struct for this entry
-+ * @ptr:      the &struct list_head pointer.
-+ * @type:     the type of the struct this is embedded in.
-+ * @member:   the name of the list_struct within the struct.
-+ */
-+#define list_entry(ptr, type, member) \
-+      ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-+
-+/**
-+ * list_for_each - iterate over elements in a list
-+ * @pos:      the &struct list_head to use as a loop counter.
-+ * @head:     the head for your list.
-+ */
-+#define list_for_each(pos, head) \
-+      for (pos = (head)->next; pos != (head); pos = pos->next)
-+
-+/**
-+ * list_for_each_safe - iterate over elements in a list, but don't dereference
-+ *                      pos after the body is done (in case it is freed)
-+ * @pos:      the &struct list_head to use as a loop counter.
-+ * @pnext:    the &struct list_head to use as a pointer to the next item.
-+ * @head:     the head for your list (not included in iteration).
-+ */
-+#define list_for_each_safe(pos, pnext, head) \
-+      for (pos = (head)->next, pnext = pos->next; pos != (head); \
-+           pos = pnext, pnext = pos->next)
-+
-+#undef _INLINE_
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _BLKID_LIST_H */
-diff -Nur busybox-1.00/e2fsprogs/blkid/llseek.c busybox/e2fsprogs/blkid/llseek.c
---- busybox-1.00/e2fsprogs/blkid/llseek.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/llseek.c   2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,139 @@
-+/*
-+ * llseek.c -- stub calling the llseek system call
-+ *
-+ * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef __MSDOS__
-+#include <io.h>
-+#endif
-+
-+#include "blkidP.h"
-+
-+#ifdef __linux__
-+
-+#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
-+
-+#define my_llseek lseek64
-+
-+#elif defined(HAVE_LLSEEK)
-+#include <syscall.h>
-+
-+#ifndef HAVE_LLSEEK_PROTOTYPE
-+extern long long llseek(int fd, long long offset, int origin);
-+#endif
-+
-+#define my_llseek llseek
-+
-+#else /* ! HAVE_LLSEEK */
-+
-+#if defined(__alpha__) || defined(__ia64__)
-+
-+#define llseek lseek
-+
-+#else /* !__alpha__ && !__ia64__*/
-+
-+#include <linux/unistd.h>
-+
-+#ifndef __NR__llseek
-+#define __NR__llseek            140
-+#endif
-+
-+#ifndef __i386__
-+static int _llseek(unsigned int, unsigned long, unsigned long,
-+                 blkid_loff_t *, unsigned int);
-+
-+static _syscall5(int, _llseek, unsigned int, fd, unsigned long, offset_high,
-+               unsigned long, offset_low, blkid_loff_t *, result,
-+               unsigned int, origin)
-+#endif
-+
-+static blkid_loff_t my_llseek(int fd, blkid_loff_t offset, int origin)
-+{
-+      blkid_loff_t result;
-+      int retval;
-+
-+#ifndef __i386__
-+      retval = _llseek(fd, ((unsigned long long) offset) >> 32,
-+                       ((unsigned long long)offset) & 0xffffffff,
-+                       &result, origin);
-+#else
-+      retval = syscall(__NR__llseek, fd, ((unsigned long long) offset) >> 32,
-+                       ((unsigned long long)offset) & 0xffffffff,
-+                       &result, origin);
-+#endif
-+      return (retval == -1 ? (blkid_loff_t) retval : result);
-+}
-+
-+#endif        /* __alpha__ || __ia64__ */
-+
-+#endif /* HAVE_LLSEEK */
-+
-+blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence)
-+{
-+      blkid_loff_t result;
-+      static int do_compat = 0;
-+
-+      if ((sizeof(off_t) >= sizeof(blkid_loff_t)) ||
-+          (offset < ((blkid_loff_t) 1 << ((sizeof(off_t)*8) -1))))
-+              return lseek(fd, (off_t) offset, whence);
-+
-+      if (do_compat) {
-+              errno = EOVERFLOW;
-+              return -1;
-+      }
-+
-+      result = my_llseek(fd, offset, whence);
-+      if (result == -1 && errno == ENOSYS) {
-+              /*
-+               * Just in case this code runs on top of an old kernel
-+               * which does not support the llseek system call
-+               */
-+              do_compat++;
-+              errno = EOVERFLOW;
-+      }
-+      return result;
-+}
-+
-+#else /* !linux */
-+
-+#ifndef EOVERFLOW
-+#ifdef EXT2_ET_INVALID_ARGUMENT
-+#define EOVERFLOW EXT2_ET_INVALID_ARGUMENT
-+#else
-+#define EOVERFLOW 112
-+#endif
-+#endif
-+
-+blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int origin)
-+{
-+#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
-+      return lseek64 (fd, offset, origin);
-+#else
-+      if ((sizeof(off_t) < sizeof(blkid_loff_t)) &&
-+          (offset >= ((blkid_loff_t) 1 << ((sizeof(off_t)*8) - 1)))) {
-+              errno = EOVERFLOW;
-+              return -1;
-+      }
-+      return lseek(fd, (off_t) offset, origin);
-+#endif
-+}
-+
-+#endif        /* linux */
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/blkid/probe.c busybox/e2fsprogs/blkid/probe.c
---- busybox-1.00/e2fsprogs/blkid/probe.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/probe.c    2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,704 @@
-+/*
-+ * probe.c - identify a block device by its contents, and return a dev
-+ *           struct with the details
-+ *
-+ * Copyright (C) 1999 by Andries Brouwer
-+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
-+ * Copyright (C) 2001 by Andreas Dilger
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <fcntl.h>
-+#include <sys/types.h>
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_SYS_MKDEV_H
-+#include <sys/mkdev.h>
-+#endif
-+#ifdef HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include "blkidP.h"
-+#include "uuid/uuid.h"
-+#include "probe.h"
-+
-+/*
-+ * This is a special case code to check for an MDRAID device.  We do
-+ * this special since it requires checking for a superblock at the end
-+ * of the device.
-+ */
-+static int check_mdraid(int fd, unsigned char *ret_uuid)
-+{
-+      struct mdp_superblock_s *md;
-+      blkid_loff_t            offset;
-+      char                    buf[4096];
-+      
-+      if (fd < 0)
-+              return -BLKID_ERR_PARAM;
-+
-+      offset = (blkid_get_dev_size(fd) & ~((blkid_loff_t)65535)) - 65536;
-+
-+      if (blkid_llseek(fd, offset, 0) < 0 ||
-+          read(fd, buf, 4096) != 4096)
-+              return -BLKID_ERR_IO;
-+
-+      /* Check for magic number */
-+      if (memcmp("\251+N\374", buf, 4))
-+              return -BLKID_ERR_PARAM;
-+
-+      if (!ret_uuid)
-+              return 0;
-+      *ret_uuid = 0;
-+
-+      /* The MD UUID is not contiguous in the superblock, make it so */
-+      md = (struct mdp_superblock_s *)buf;
-+      if (md->set_uuid0 || md->set_uuid1 || md->set_uuid2 || md->set_uuid3) {
-+              memcpy(ret_uuid, &md->set_uuid0, 4);
-+              memcpy(ret_uuid, &md->set_uuid1, 12);
-+      }
-+      return 0;
-+}
-+
-+static void set_uuid(blkid_dev dev, uuid_t uuid)
-+{
-+      char    str[37];
-+
-+      if (!uuid_is_null(uuid)) {
-+              uuid_unparse(uuid, str);
-+              blkid_set_tag(dev, "UUID", str, sizeof(str));
-+      }
-+}
-+
-+static void get_ext2_info(blkid_dev dev, unsigned char *buf)
-+{
-+      struct ext2_super_block *es = (struct ext2_super_block *) buf;
-+      const char *label = 0;
-+
-+      DBG(DEBUG_PROBE, printf("ext2_sb.compat = %08X:%08X:%08X\n", 
-+                 blkid_le32(es->s_feature_compat),
-+                 blkid_le32(es->s_feature_incompat),
-+                 blkid_le32(es->s_feature_ro_compat)));
-+
-+      if (strlen(es->s_volume_name))
-+              label = es->s_volume_name;
-+      blkid_set_tag(dev, "LABEL", label, sizeof(es->s_volume_name));
-+
-+      set_uuid(dev, es->s_uuid);
-+}
-+
-+static int probe_ext3(int fd __BLKID_ATTR((unused)), 
-+                    blkid_cache cache __BLKID_ATTR((unused)), 
-+                    blkid_dev dev,
-+                    struct blkid_magic *id, unsigned char *buf)
-+{
-+      struct ext2_super_block *es;
-+
-+      es = (struct ext2_super_block *)buf;
-+
-+      /* Distinguish between jbd and ext2/3 fs */
-+      if (blkid_le32(es->s_feature_incompat) & 
-+          EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
-+              return -BLKID_ERR_PARAM;
-+
-+      /* Distinguish between ext3 and ext2 */
-+      if (!(blkid_le32(es->s_feature_compat) &
-+            EXT3_FEATURE_COMPAT_HAS_JOURNAL))
-+              return -BLKID_ERR_PARAM;
-+
-+      get_ext2_info(dev, buf);
-+
-+      blkid_set_tag(dev, "SEC_TYPE", "ext2", sizeof("ext2"));
-+
-+      return 0;
-+}
-+
-+static int probe_ext2(int fd __BLKID_ATTR((unused)), 
-+                    blkid_cache cache __BLKID_ATTR((unused)), 
-+                    blkid_dev dev,
-+                    struct blkid_magic *id, unsigned char *buf)
-+{
-+      struct ext2_super_block *es;
-+//    const char *sec_type = 0, *label = 0;
-+
-+      es = (struct ext2_super_block *)buf;
-+
-+      /* Distinguish between jbd and ext2/3 fs */
-+      if (blkid_le32(es->s_feature_incompat) & 
-+          EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
-+              return -BLKID_ERR_PARAM;
-+
-+      get_ext2_info(dev, buf);
-+
-+      return 0;
-+}
-+
-+static int probe_jbd(int fd __BLKID_ATTR((unused)), 
-+                   blkid_cache cache __BLKID_ATTR((unused)), 
-+                   blkid_dev dev, 
-+                   struct blkid_magic *id __BLKID_ATTR((unused)), 
-+                   unsigned char *buf)
-+{
-+      struct ext2_super_block *es = (struct ext2_super_block *) buf;
-+
-+      if (!(blkid_le32(es->s_feature_incompat) &
-+            EXT3_FEATURE_INCOMPAT_JOURNAL_DEV))
-+              return -BLKID_ERR_PARAM;
-+
-+      get_ext2_info(dev, buf);
-+
-+      return 0;
-+}
-+
-+static int probe_vfat(int fd __BLKID_ATTR((unused)), 
-+                    blkid_cache cache __BLKID_ATTR((unused)), 
-+                    blkid_dev dev,
-+                    struct blkid_magic *id __BLKID_ATTR((unused)), 
-+                    unsigned char *buf)
-+{
-+      struct vfat_super_block *vs;
-+      char serno[10];
-+      const char *label = 0;
-+      int label_len = 0;
-+
-+      vs = (struct vfat_super_block *)buf;
-+
-+      if (strncmp(vs->vs_label, "NO NAME", 7)) {
-+              char *end = vs->vs_label + sizeof(vs->vs_label) - 1;
-+
-+              while (*end == ' ' && end >= vs->vs_label)
-+                      --end;
-+              if (end >= vs->vs_label) {
-+                      label = vs->vs_label;
-+                      label_len = end - vs->vs_label + 1;
-+              }
-+      }
-+
-+      /* We can't just print them as %04X, because they are unaligned */
-+      sprintf(serno, "%02X%02X-%02X%02X", vs->vs_serno[3], vs->vs_serno[2],
-+              vs->vs_serno[1], vs->vs_serno[0]);
-+      blkid_set_tag(dev, "LABEL", label, label_len);
-+      blkid_set_tag(dev, "UUID", serno, sizeof(serno));
-+
-+      return 0;
-+}
-+
-+static int probe_msdos(int fd __BLKID_ATTR((unused)), 
-+                     blkid_cache cache __BLKID_ATTR((unused)), 
-+                     blkid_dev dev,
-+                     struct blkid_magic *id __BLKID_ATTR((unused)), 
-+                     unsigned char *buf)
-+{
-+      struct msdos_super_block *ms = (struct msdos_super_block *) buf;
-+      char serno[10];
-+      const char *label = 0;
-+      int label_len = 0;
-+
-+      if (strncmp(ms->ms_label, "NO NAME", 7)) {
-+              char *end = ms->ms_label + sizeof(ms->ms_label) - 1;
-+
-+              while (*end == ' ' && end >= ms->ms_label)
-+                      --end;
-+              if (end >= ms->ms_label) {
-+                      label = ms->ms_label;
-+                      label_len = end - ms->ms_label + 1;
-+              }
-+      }
-+
-+      /* We can't just print them as %04X, because they are unaligned */
-+      sprintf(serno, "%02X%02X-%02X%02X", ms->ms_serno[3], ms->ms_serno[2],
-+              ms->ms_serno[1], ms->ms_serno[0]);
-+      blkid_set_tag(dev, "UUID", serno, 0);
-+      blkid_set_tag(dev, "LABEL", label, label_len);
-+      blkid_set_tag(dev, "SEC_TYPE", "msdos", sizeof("msdos"));
-+
-+      return 0;
-+}
-+
-+static int probe_xfs(int fd __BLKID_ATTR((unused)), 
-+                   blkid_cache cache __BLKID_ATTR((unused)), 
-+                   blkid_dev dev,
-+                   struct blkid_magic *id __BLKID_ATTR((unused)), 
-+                   unsigned char *buf)
-+{
-+      struct xfs_super_block *xs;
-+      const char *label = 0;
-+
-+      xs = (struct xfs_super_block *)buf;
-+
-+      if (strlen(xs->xs_fname))
-+              label = xs->xs_fname;
-+      blkid_set_tag(dev, "LABEL", label, sizeof(xs->xs_fname));
-+      set_uuid(dev, xs->xs_uuid);
-+      return 0;
-+}
-+
-+static int probe_reiserfs(int fd __BLKID_ATTR((unused)), 
-+                        blkid_cache cache __BLKID_ATTR((unused)), 
-+                        blkid_dev dev,
-+                        struct blkid_magic *id, unsigned char *buf)
-+{
-+      struct reiserfs_super_block *rs = (struct reiserfs_super_block *) buf;
-+      unsigned int blocksize;
-+      const char *label = 0;
-+
-+      blocksize = blkid_le16(rs->rs_blocksize);
-+
-+      /* If the superblock is inside the journal, we have the wrong one */
-+      if (id->bim_kboff/(blocksize>>10) > blkid_le32(rs->rs_journal_block))
-+              return -BLKID_ERR_BIG;
-+
-+      /* LABEL/UUID are only valid for later versions of Reiserfs v3.6. */
-+      if (!strcmp(id->bim_magic, "ReIsEr2Fs") ||
-+          !strcmp(id->bim_magic, "ReIsEr3Fs")) {
-+              if (strlen(rs->rs_label))
-+                      label = rs->rs_label;
-+              set_uuid(dev, rs->rs_uuid);
-+      }
-+      blkid_set_tag(dev, "LABEL", label, sizeof(rs->rs_label));
-+
-+      return 0;
-+}
-+
-+static int probe_jfs(int fd __BLKID_ATTR((unused)), 
-+                   blkid_cache cache __BLKID_ATTR((unused)), 
-+                   blkid_dev dev,
-+                   struct blkid_magic *id __BLKID_ATTR((unused)), 
-+                   unsigned char *buf)
-+{
-+      struct jfs_super_block *js;
-+      const char *label = 0;
-+
-+      js = (struct jfs_super_block *)buf;
-+
-+      if (strlen((char *) js->js_label))
-+              label = (char *) js->js_label;
-+      blkid_set_tag(dev, "LABEL", label, sizeof(js->js_label));
-+      set_uuid(dev, js->js_uuid);
-+      return 0;
-+}
-+
-+static int probe_romfs(int fd __BLKID_ATTR((unused)), 
-+                     blkid_cache cache __BLKID_ATTR((unused)), 
-+                     blkid_dev dev,
-+                     struct blkid_magic *id __BLKID_ATTR((unused)), 
-+                     unsigned char *buf)
-+{
-+      struct romfs_super_block *ros;
-+      const char *label = 0;
-+
-+      ros = (struct romfs_super_block *)buf;
-+
-+      if (strlen((char *) ros->ros_volume))
-+              label = (char *) ros->ros_volume;
-+      blkid_set_tag(dev, "LABEL", label, 0);
-+      return 0;
-+}
-+
-+static int probe_swap0(int fd __BLKID_ATTR((unused)),
-+                     blkid_cache cache __BLKID_ATTR((unused)),
-+                     blkid_dev dev,
-+                     struct blkid_magic *id __BLKID_ATTR((unused)),
-+                     unsigned char *buf __BLKID_ATTR((unused)))
-+{
-+      blkid_set_tag(dev, "UUID", 0, 0);
-+      blkid_set_tag(dev, "LABEL", 0, 0);
-+      return 0;
-+}
-+
-+static int probe_swap1(int fd,
-+                     blkid_cache cache __BLKID_ATTR((unused)),
-+                     blkid_dev dev,
-+                     struct blkid_magic *id __BLKID_ATTR((unused)),
-+                     unsigned char *buf __BLKID_ATTR((unused)))
-+{
-+      struct swap_id_block *sws;
-+//    const char *label = 0;
-+
-+      probe_swap0(fd, cache, dev, id, buf);
-+      /*
-+       * Version 1 swap headers are always located at offset of 1024
-+       * bytes, although the swap signature itself is located at the
-+       * end of the page (which may vary depending on hardware
-+       * pagesize).
-+       */
-+      if (lseek(fd, 1024, SEEK_SET) < 0) return 1;
-+      if (!(sws = (struct swap_id_block *)malloc(1024))) return 1;
-+      if (read(fd, sws, 1024) != 1024) {
-+              free(sws);
-+              return 1;
-+      }
-+
-+      /* arbitrary sanity check.. is there any garbage down there? */
-+      if (sws->sws_pad[32] == 0 && sws->sws_pad[33] == 0)  {
-+              if (sws->sws_volume[0])
-+                      blkid_set_tag(dev, "LABEL", sws->sws_volume, 
-+                                    sizeof(sws->sws_volume));
-+              if (sws->sws_uuid[0])
-+                      set_uuid(dev, sws->sws_uuid);
-+      }
-+      free(sws);
-+
-+      return 0;
-+}
-+
-+static const char
-+*udf_magic[] = { "BEA01", "BOOT2", "CD001", "CDW02", "NSR02",
-+               "NSR03", "TEA01", 0 };
-+
-+static int probe_udf(int fd, blkid_cache cache __BLKID_ATTR((unused)), 
-+                   blkid_dev dev __BLKID_ATTR((unused)),
-+                     struct blkid_magic *id __BLKID_ATTR((unused)), 
-+                   unsigned char *buf __BLKID_ATTR((unused)))
-+{
-+      int j, bs;
-+      struct iso_volume_descriptor isosb;
-+      const char ** m;
-+
-+      /* determine the block size by scanning in 2K increments
-+         (block sizes larger than 2K will be null padded) */
-+      for (bs = 1; bs < 16; bs++) {
-+              lseek(fd, bs*2048+32768, SEEK_SET);
-+              if (read(fd, (char *)&isosb, sizeof(isosb)) != sizeof(isosb))
-+                      return 1;
-+              if (isosb.id[0])
-+                      break;
-+      }
-+
-+      /* Scan up to another 64 blocks looking for additional VSD's */
-+      for (j = 1; j < 64; j++) {
-+              if (j > 1) {
-+                      lseek(fd, j*bs*2048+32768, SEEK_SET);
-+                      if (read(fd, (char *)&isosb, sizeof(isosb))
-+                          != sizeof(isosb))
-+                              return 1;
-+              }
-+              /* If we find NSR0x then call it udf:
-+                 NSR01 for UDF 1.00
-+                 NSR02 for UDF 1.50
-+                 NSR03 for UDF 2.00 */
-+              if (!strncmp(isosb.id, "NSR0", 4))
-+                      return 0;
-+              for (m = udf_magic; *m; m++)
-+                      if (!strncmp(*m, isosb.id, 5))
-+                              break;
-+              if (*m == 0)
-+                      return 1;
-+      }
-+      return 1;
-+}
-+
-+static int probe_ocfs(int fd __BLKID_ATTR((unused)), 
-+                    blkid_cache cache __BLKID_ATTR((unused)), 
-+                    blkid_dev dev,
-+                    struct blkid_magic *id __BLKID_ATTR((unused)), 
-+                    unsigned char *buf)
-+{
-+      struct ocfs_volume_header ovh;
-+      struct ocfs_volume_label ovl;
-+      __u32 major;
-+
-+      memcpy(&ovh, buf, sizeof(ovh));
-+      memcpy(&ovl, buf+512, sizeof(ovl));
-+
-+      major = ocfsmajor(ovh);
-+      if (major == 1)
-+              blkid_set_tag(dev,"SEC_TYPE","ocfs1",sizeof("ocfs1"));
-+      else if (major >= 9)
-+              blkid_set_tag(dev,"SEC_TYPE","ntocfs",sizeof("ntocfs"));
-+      
-+      blkid_set_tag(dev, "LABEL", ovl.label, ocfslabellen(ovl));
-+      blkid_set_tag(dev, "MOUNT", ovh.mount, ocfsmountlen(ovh));
-+      set_uuid(dev, ovl.vol_id);
-+      return 0;
-+}
-+
-+static int probe_ocfs2(int fd __BLKID_ATTR((unused)), 
-+                     blkid_cache cache __BLKID_ATTR((unused)), 
-+                     blkid_dev dev,
-+                     struct blkid_magic *id __BLKID_ATTR((unused)), 
-+                     unsigned char *buf)
-+{
-+      struct ocfs2_super_block *osb;
-+
-+      osb = (struct ocfs2_super_block *)buf;
-+
-+      blkid_set_tag(dev, "LABEL", osb->s_label, sizeof(osb->s_label));
-+      set_uuid(dev, osb->s_uuid);
-+      return 0;
-+}
-+
-+static int probe_oracleasm(int fd __BLKID_ATTR((unused)), 
-+                         blkid_cache cache __BLKID_ATTR((unused)), 
-+                         blkid_dev dev,
-+                         struct blkid_magic *id __BLKID_ATTR((unused)), 
-+                         unsigned char *buf)
-+{
-+      struct oracle_asm_disk_label *dl;
-+
-+      dl = (struct oracle_asm_disk_label *)buf;
-+
-+      blkid_set_tag(dev, "LABEL", dl->dl_id, sizeof(dl->dl_id));
-+      return 0;
-+}
-+
-+/*
-+ * BLKID_BLK_OFFS is at least as large as the highest bim_kboff defined
-+ * in the type_array table below + bim_kbalign.
-+ *
-+ * When probing for a lot of magics, we handle everything in 1kB buffers so
-+ * that we don't have to worry about reading each combination of block sizes.
-+ */
-+#define BLKID_BLK_OFFS        64      /* currently reiserfs */
-+
-+/*
-+ * Various filesystem magics that we can check for.  Note that kboff and
-+ * sboff are in kilobytes and bytes respectively.  All magics are in
-+ * byte strings so we don't worry about endian issues.
-+ */
-+static struct blkid_magic type_array[] = {
-+/*  type     kboff   sboff len  magic                 probe */
-+  { "oracleasm", 0,   32,  8, "ORCLDISK",             probe_oracleasm },
-+  { "ntfs",      0,      3,  8, "NTFS    ",             0 },
-+  { "jbd",     1,   0x38,  2, "\123\357",             probe_jbd },
-+  { "ext3",    1,   0x38,  2, "\123\357",             probe_ext3 },
-+  { "ext2",    1,   0x38,  2, "\123\357",             probe_ext2 },
-+  { "reiserfs",        8,   0x34,  8, "ReIsErFs",             probe_reiserfs },
-+  { "reiserfs", 64,   0x34,  9, "ReIsEr2Fs",          probe_reiserfs },
-+  { "reiserfs", 64,   0x34,  9, "ReIsEr3Fs",          probe_reiserfs },
-+  { "reiserfs", 64,   0x34,  8, "ReIsErFs",           probe_reiserfs },
-+  { "reiserfs",        8,     20,  8, "ReIsErFs",             probe_reiserfs },
-+  { "vfat",      0,   0x52,  5, "MSWIN",                probe_vfat },
-+  { "vfat",      0,   0x52,  8, "FAT32   ",             probe_vfat },
-+  { "vfat",      0,   0x36,  5, "MSDOS",                probe_msdos },
-+  { "vfat",      0,   0x36,  8, "FAT16   ",             probe_msdos },
-+  { "vfat",      0,   0x36,  8, "FAT12   ",             probe_msdos },
-+  { "minix",     1,   0x10,  2, "\177\023",             0 },
-+  { "minix",     1,   0x10,  2, "\217\023",             0 },
-+  { "minix",   1,   0x10,  2, "\150\044",             0 },
-+  { "minix",   1,   0x10,  2, "\170\044",             0 },
-+  { "vxfs",    1,      0,  4, "\365\374\001\245",     0 },
-+  { "xfs",     0,      0,  4, "XFSB",                 probe_xfs },
-+  { "romfs",   0,      0,  8, "-rom1fs-",             probe_romfs },
-+  { "bfs",     0,      0,  4, "\316\372\173\033",     0 },
-+  { "cramfs",  0,      0,  4, "E=\315\034",           0 },
-+  { "qnx4",    0,      4,  6, "QNX4FS",               0 },
-+  { "udf",    32,      1,  5, "BEA01",                probe_udf },
-+  { "udf",    32,      1,  5, "BOOT2",                probe_udf },
-+  { "udf",    32,      1,  5, "CD001",                probe_udf },
-+  { "udf",    32,      1,  5, "CDW02",                probe_udf },
-+  { "udf",    32,      1,  5, "NSR02",                probe_udf },
-+  { "udf",    32,      1,  5, "NSR03",                probe_udf },
-+  { "udf",    32,      1,  5, "TEA01",                probe_udf },
-+  { "iso9660",        32,      1,  5, "CD001",                0 },
-+  { "iso9660",        32,      9,  5, "CDROM",                0 },
-+  { "jfs",    32,      0,  4, "JFS1",                 probe_jfs },
-+  { "hfs",     1,      0,  2, "BD",                   0 },
-+  { "ufs",     8,  0x55c,  4, "T\031\001\000",        0 },
-+  { "hpfs",    8,      0,  4, "I\350\225\371",        0 },
-+  { "sysv",    0,  0x3f8,  4, "\020~\030\375",        0 },
-+  { "swap",    0,  0xff6, 10, "SWAP-SPACE",           probe_swap0 },
-+  { "swap",    0,  0xff6, 10, "SWAPSPACE2",           probe_swap1 },
-+  { "swap",    0, 0x1ff6, 10, "SWAP-SPACE",           probe_swap0 },
-+  { "swap",    0, 0x1ff6, 10, "SWAPSPACE2",           probe_swap1 },
-+  { "swap",    0, 0x3ff6, 10, "SWAP-SPACE",           probe_swap0 },
-+  { "swap",    0, 0x3ff6, 10, "SWAPSPACE2",           probe_swap1 },
-+  { "swap",    0, 0x7ff6, 10, "SWAP-SPACE",           probe_swap0 },
-+  { "swap",    0, 0x7ff6, 10, "SWAPSPACE2",           probe_swap1 },
-+  { "swap",    0, 0xfff6, 10, "SWAP-SPACE",           probe_swap0 },
-+  { "swap",    0, 0xfff6, 10, "SWAPSPACE2",           probe_swap1 },
-+  { "ocfs",    0,      8,  9, "OracleCFS",            probe_ocfs },
-+  { "ocfs2",   1,      0,  6, "OCFSV2",               probe_ocfs2 },
-+  { "ocfs2",   2,      0,  6, "OCFSV2",               probe_ocfs2 },
-+  { "ocfs2",   4,      0,  6, "OCFSV2",               probe_ocfs2 },
-+  { "ocfs2",   8,      0,  6, "OCFSV2",               probe_ocfs2 },
-+  {   NULL,    0,      0,  0, NULL,                   NULL }
-+};
-+
-+/*
-+ * Verify that the data in dev is consistent with what is on the actual
-+ * block device (using the devname field only).  Normally this will be
-+ * called when finding items in the cache, but for long running processes
-+ * is also desirable to revalidate an item before use.
-+ *
-+ * If we are unable to revalidate the data, we return the old data and
-+ * do not set the BLKID_BID_FL_VERIFIED flag on it.
-+ */
-+blkid_dev blkid_verify(blkid_cache cache, blkid_dev dev)
-+{
-+      struct blkid_magic *id;
-+      unsigned char *bufs[BLKID_BLK_OFFS + 1], *buf;
-+      const char *type;
-+      struct stat st;
-+      time_t diff, now;
-+      int fd, idx;
-+
-+      if (!dev)
-+              return NULL;
-+
-+      now = time(0);
-+      diff = now - dev->bid_time;
-+
-+      if ((now < dev->bid_time) ||
-+          (diff < BLKID_PROBE_MIN) || 
-+          (dev->bid_flags & BLKID_BID_FL_VERIFIED &&
-+           diff < BLKID_PROBE_INTERVAL))
-+              return dev;
-+
-+      DBG(DEBUG_PROBE,
-+          printf("need to revalidate %s (time since last check %lu)\n", 
-+                 dev->bid_name, diff));
-+
-+      if (((fd = open(dev->bid_name, O_RDONLY)) < 0) ||
-+          (fstat(fd, &st) < 0)) {
-+              if (errno == ENXIO || errno == ENODEV || errno == ENOENT) {
-+                      blkid_free_dev(dev);
-+                      return NULL;
-+              }
-+              /* We don't have read permission, just return cache data. */
-+              DBG(DEBUG_PROBE,
-+                  printf("returning unverified data for %s\n",
-+                         dev->bid_name));
-+              return dev;
-+      }
-+
-+      memset(bufs, 0, sizeof(bufs));
-+      
-+      /*
-+       * Iterate over the type array.  If we already know the type,
-+       * then try that first.  If it doesn't work, then blow away
-+       * the type information, and try again.
-+       * 
-+       */
-+try_again:
-+      type = 0;
-+      if (!dev->bid_type || !strcmp(dev->bid_type, "mdraid")) {
-+              uuid_t  uuid;
-+
-+              if (check_mdraid(fd, uuid) == 0) {
-+                      set_uuid(dev, uuid);
-+                      type = "mdraid";
-+                      goto found_type;
-+              }
-+      }
-+      for (id = type_array; id->bim_type; id++) {
-+              if (dev->bid_type &&
-+                  strcmp(id->bim_type, dev->bid_type))
-+                      continue;
-+
-+              idx = id->bim_kboff + (id->bim_sboff >> 10);
-+              if (idx > BLKID_BLK_OFFS || idx < 0)
-+                      continue;
-+              buf = bufs[idx];
-+              if (!buf) {
-+                      if (lseek(fd, idx << 10, SEEK_SET) < 0)
-+                              continue;
-+
-+                      if (!(buf = (unsigned char *)malloc(1024)))
-+                              continue;
-+                      
-+                      if (read(fd, buf, 1024) != 1024) {
-+                              free(buf);
-+                              continue;
-+                      }
-+                      bufs[idx] = buf;
-+              }
-+
-+              if (memcmp(id->bim_magic, buf + (id->bim_sboff&0x3ff),
-+                         id->bim_len))
-+                      continue;
-+
-+              if ((id->bim_probe == NULL) ||
-+                  (id->bim_probe(fd, cache, dev, id, buf) == 0)) {
-+                      type = id->bim_type;
-+                      goto found_type;
-+              }
-+      }
-+
-+      if (!id->bim_type && dev->bid_type) {
-+              /*
-+               * Zap the device filesystem type and try again
-+               */
-+              blkid_set_tag(dev, "TYPE", 0, 0);
-+              blkid_set_tag(dev, "SEC_TYPE", 0, 0);
-+              blkid_set_tag(dev, "LABEL", 0, 0);
-+              blkid_set_tag(dev, "UUID", 0, 0);
-+              goto try_again;
-+      }
-+
-+      if (!dev->bid_type) {
-+              blkid_free_dev(dev);
-+              return NULL;
-+      }
-+              
-+found_type:
-+      if (dev && type) {
-+              dev->bid_devno = st.st_rdev;
-+              dev->bid_time = time(0);
-+              dev->bid_flags |= BLKID_BID_FL_VERIFIED;
-+              cache->bic_flags |= BLKID_BIC_FL_CHANGED;
-+
-+              blkid_set_tag(dev, "TYPE", type, 0);
-+                              
-+              DBG(DEBUG_PROBE, printf("%s: devno 0x%04Lx, type %s\n",
-+                         dev->bid_name, st.st_rdev, type));
-+      }
-+
-+      close(fd);
-+
-+      return dev;
-+}
-+
-+int blkid_known_fstype(const char *fstype)
-+{
-+      struct blkid_magic *id;
-+
-+      for (id = type_array; id->bim_type; id++) {
-+              if (strcmp(fstype, id->bim_type) == 0)
-+                      return 1;
-+      }
-+      return 0;
-+}
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char **argv)
-+{
-+      blkid_dev dev;
-+      blkid_cache cache;
-+      int ret;
-+
-+      blkid_debug_mask = DEBUG_ALL;
-+      if (argc != 2) {
-+              fprintf(stderr, "Usage: %s device\n"
-+                      "Probe a single device to determine type\n", argv[0]);
-+              exit(1);
-+      }
-+      if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
-+              fprintf(stderr, "%s: error creating cache (%d)\n",
-+                      argv[0], ret);
-+              exit(1);
-+      }
-+      dev = blkid_get_dev(cache, argv[1], BLKID_DEV_NORMAL);
-+      if (!dev) {
-+              printf("%s: %s has an unsupported type\n", argv[0], argv[1]);
-+              return (1);
-+      }
-+      printf("%s is type %s\n", argv[1], dev->bid_type ?
-+              dev->bid_type : "(null)");
-+      if (dev->bid_label)
-+              printf("\tlabel is '%s'\n", dev->bid_label);
-+      if (dev->bid_uuid)
-+              printf("\tuuid is %s\n", dev->bid_uuid);
-+      
-+      blkid_free_dev(dev);
-+      return (0);
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/blkid/probe.h busybox/e2fsprogs/blkid/probe.h
---- busybox-1.00/e2fsprogs/blkid/probe.h       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/probe.h    2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,359 @@
-+/*
-+ * probe.h - constants and on-disk structures for extracting device data
-+ *
-+ * Copyright (C) 1999 by Andries Brouwer
-+ * Copyright (C) 1999, 2000, 2003 by Theodore Ts'o
-+ * Copyright (C) 2001 by Andreas Dilger
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#ifndef _BLKID_PROBE_H
-+#define _BLKID_PROBE_H
-+
-+#include <linux/types.h>
-+
-+struct blkid_magic;
-+
-+typedef int (*blkid_probe_t)(int fd, blkid_cache cache, blkid_dev dev, 
-+                           struct blkid_magic *id, unsigned char *buf);
-+
-+struct blkid_magic {
-+      const char      *bim_type;      /* type name for this magic */
-+      long            bim_kboff;      /* kilobyte offset of superblock */
-+      unsigned        bim_sboff;      /* byte offset within superblock */
-+      unsigned        bim_len;        /* length of magic */
-+      const char      *bim_magic;     /* magic string */
-+      blkid_probe_t   bim_probe;      /* probe function */
-+};
-+
-+/*
-+ * Structures for each of the content types we want to extract information
-+ * from.  We do not necessarily need the magic field here, because we have
-+ * already identified the content type before we get this far.  It may still
-+ * be useful if there are probe functions which handle multiple content types.
-+ */
-+struct ext2_super_block {
-+      __u32           s_inodes_count;
-+      __u32           s_blocks_count;
-+      __u32           s_r_blocks_count;
-+      __u32           s_free_blocks_count;
-+      __u32           s_free_inodes_count;
-+      __u32           s_first_data_block;
-+      __u32           s_log_block_size;
-+      __u32           s_dummy3[7];
-+      unsigned char   s_magic[2];
-+      __u16           s_state;
-+      __u32           s_dummy5[8];
-+      __u32           s_feature_compat;
-+      __u32           s_feature_incompat;
-+      __u32           s_feature_ro_compat;
-+      unsigned char   s_uuid[16];
-+      char       s_volume_name[16];
-+};
-+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL               0x00000004
-+#define EXT3_FEATURE_INCOMPAT_RECOVER         0x00000004
-+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x00000008
-+
-+struct xfs_super_block {
-+      unsigned char   xs_magic[4];
-+      __u32           xs_blocksize;
-+      __u64           xs_dblocks;
-+      __u64           xs_rblocks;
-+      __u32           xs_dummy1[2];
-+      unsigned char   xs_uuid[16];
-+      __u32           xs_dummy2[15];
-+      char            xs_fname[12];
-+      __u32           xs_dummy3[2];
-+      __u64           xs_icount;
-+      __u64           xs_ifree;
-+      __u64           xs_fdblocks;
-+};
-+
-+struct reiserfs_super_block {
-+      __u32           rs_blocks_count;
-+      __u32           rs_free_blocks;
-+      __u32           rs_root_block;
-+      __u32           rs_journal_block;
-+      __u32           rs_journal_dev;
-+      __u32           rs_orig_journal_size;
-+      __u32           rs_dummy2[5];
-+      __u16           rs_blocksize;
-+      __u16           rs_dummy3[3];
-+      unsigned char   rs_magic[12];
-+      __u32           rs_dummy4[5];
-+      unsigned char   rs_uuid[16];
-+      char            rs_label[16];
-+};
-+
-+struct jfs_super_block {
-+      unsigned char   js_magic[4];
-+      __u32           js_version;
-+      __u64           js_size;
-+      __u32           js_bsize;
-+      __u32           js_dummy1;
-+      __u32           js_pbsize;
-+      __u32           js_dummy2[27];
-+      unsigned char   js_uuid[16];
-+      unsigned char   js_label[16];
-+      unsigned char   js_loguuid[16];
-+};
-+
-+struct romfs_super_block {
-+      unsigned char   ros_magic[8];
-+      __u32           ros_dummy1[2];
-+      unsigned char   ros_volume[16];
-+};
-+
-+struct swap_id_block {
-+/*    unsigned char   sws_boot[1024]; */
-+      __u32           sws_version;
-+      __u32           sws_lastpage;
-+      __u32           sws_nrbad;
-+      unsigned char   sws_uuid[16];
-+      unsigned char   sws_volume[16];
-+      unsigned char   sws_pad[117];
-+      __u32           sws_badpg;
-+};
-+
-+/* Yucky misaligned values */
-+struct vfat_super_block {
-+/* 00*/       unsigned char   vs_ignored[3];
-+/* 03*/       unsigned char   vs_sysid[8];
-+/* 0b*/       unsigned char   vs_sector_size[2];
-+/* 0d*/       __u8            vs_cluster_size;
-+/* 0e*/       __u16           vs_reserved;
-+/* 10*/       __u8            vs_fats;
-+/* 11*/       unsigned char   vs_dir_entries[2];
-+/* 13*/       unsigned char   vs_sectors[2];
-+/* 15*/       unsigned char   vs_media;
-+/* 16*/       __u16           vs_fat_length;
-+/* 18*/       __u16           vs_secs_track;
-+/* 1a*/       __u16           vs_heads;
-+/* 1c*/       __u32           vs_hidden;
-+/* 20*/       __u32           vs_total_sect;
-+/* 24*/       __u32           vs_fat32_length;
-+/* 28*/       __u16           vs_flags;
-+/* 2a*/       __u8            vs_version[2];
-+/* 2c*/       __u32           vs_root_cluster;
-+/* 30*/       __u16           vs_insfo_sector;
-+/* 32*/       __u16           vs_backup_boot;
-+/* 34*/       __u16           vs_reserved2[6];
-+/* 40*/       unsigned char   vs_unknown[3];
-+/* 43*/       unsigned char   vs_serno[4];
-+/* 47*/       char            vs_label[11];
-+/* 52*/       unsigned char   vs_magic[8];
-+/* 5a*/       unsigned char   vs_dummy2[164];
-+/*1fe*/       unsigned char   vs_pmagic[2];
-+};
-+
-+/* Yucky misaligned values */
-+struct msdos_super_block {
-+/* 00*/       unsigned char   ms_ignored[3];
-+/* 03*/       unsigned char   ms_sysid[8];
-+/* 0b*/       unsigned char   ms_sector_size[2];
-+/* 0d*/       __u8            ms_cluster_size;
-+/* 0e*/       __u16           ms_reserved;
-+/* 10*/       __u8            ms_fats;
-+/* 11*/       unsigned char   ms_dir_entries[2];
-+/* 13*/       unsigned char   ms_sectors[2];
-+/* 15*/       unsigned char   ms_media;
-+/* 16*/       __u16           ms_fat_length;
-+/* 18*/       __u16           ms_secs_track;
-+/* 1a*/       __u16           ms_heads;
-+/* 1c*/       __u32           ms_hidden;
-+/* 20*/       __u32           ms_total_sect;
-+/* 24*/       unsigned char   ms_unknown[3];
-+/* 27*/       unsigned char   ms_serno[4];
-+/* 2b*/       char            ms_label[11];
-+/* 36*/       unsigned char   ms_magic[8];
-+/* 3d*/       unsigned char   ms_dummy2[192];
-+/*1fe*/       unsigned char   ms_pmagic[2];
-+};
-+
-+struct minix_super_block {
-+      __u16           ms_ninodes;
-+      __u16           ms_nzones;
-+      __u16           ms_imap_blocks;
-+      __u16           ms_zmap_blocks;
-+      __u16           ms_firstdatazone;
-+      __u16           ms_log_zone_size;
-+      __u32           ms_max_size;
-+      unsigned char   ms_magic[2];
-+      __u16           ms_state;
-+      __u32           ms_zones;
-+};
-+
-+struct mdp_superblock_s {
-+      __u32 md_magic;
-+      __u32 major_version;
-+      __u32 minor_version;
-+      __u32 patch_version;
-+      __u32 gvalid_words;
-+      __u32 set_uuid0;
-+      __u32 ctime;
-+      __u32 level;
-+      __u32 size;
-+      __u32 nr_disks;
-+      __u32 raid_disks;
-+      __u32 md_minor;
-+      __u32 not_persistent;
-+      __u32 set_uuid1;
-+      __u32 set_uuid2;
-+      __u32 set_uuid3;
-+};
-+
-+struct hfs_super_block {
-+      char    h_magic[2];
-+      char    h_dummy[18];
-+      __u32   h_blksize;
-+};
-+
-+struct ocfs_volume_header {
-+      unsigned char   minor_version[4];
-+      unsigned char   major_version[4];
-+      unsigned char   signature[128];
-+      unsigned char  mount[128];
-+      unsigned char  mount_len[2];
-+};
-+
-+struct ocfs_volume_label {
-+      unsigned char   disk_lock[48];
-+      unsigned char   label[64];      
-+      unsigned char   label_len[2];
-+      unsigned char  vol_id[16];
-+      unsigned char  vol_id_len[2];
-+};
-+
-+#define ocfsmajor(o) ((__u32)o.major_version[0] \
-+                   + (((__u32) o.major_version[1]) << 8) \
-+                   + (((__u32) o.major_version[2]) << 16) \
-+                   + (((__u32) o.major_version[3]) << 24))
-+#define ocfslabellen(o)       ((__u32)o.label_len[0] + (((__u32) o.label_len[1]) << 8))
-+#define ocfsmountlen(o)       ((__u32)o.mount_len[0] + (((__u32) o.mount_len[1])<<8))
-+
-+#define OCFS_MAGIC "OracleCFS"
-+
-+struct ocfs2_super_block {
-+      unsigned char  signature[8];
-+      unsigned char  s_dummy1[184];
-+      unsigned char  s_dummy2[80];
-+      unsigned char  s_label[64];
-+      unsigned char  s_uuid[16];
-+};
-+
-+#define OCFS2_MIN_BLOCKSIZE             512
-+#define OCFS2_MAX_BLOCKSIZE             4096
-+
-+#define OCFS2_SUPER_BLOCK_BLKNO         2
-+
-+#define OCFS2_SUPER_BLOCK_SIGNATURE     "OCFSV2"
-+
-+struct oracle_asm_disk_label {
-+      char dummy[32];
-+      char dl_tag[8];
-+      char dl_id[24];
-+};
-+
-+#define ORACLE_ASM_DISK_LABEL_MARKED    "ORCLDISK"
-+#define ORACLE_ASM_DISK_LABEL_OFFSET    32
-+
-+#define ISODCL(from, to) (to - from + 1)
-+struct iso_volume_descriptor {
-+      char type[ISODCL(1,1)]; /* 711 */
-+      char id[ISODCL(2,6)];
-+      char version[ISODCL(7,7)];
-+      char data[ISODCL(8,2048)];
-+};
-+
-+/*
-+ * Byte swap functions
-+ */
-+#ifdef __GNUC__
-+#define _INLINE_ static __inline__
-+#else                         /* For Watcom C */
-+#define _INLINE_ static inline
-+#endif
-+
-+static __u16 blkid_swab16(__u16 val);
-+static __u32 blkid_swab32(__u32 val);
-+static __u64 blkid_swab64(__u64 val);
-+
-+#if ((defined __GNUC__) && \
-+     (defined(__i386__) || defined(__i486__) || defined(__i586__)))
-+
-+#define _BLKID_HAVE_ASM_BITOPS_
-+
-+_INLINE_ __u32 blkid_swab32(__u32 val)
-+{
-+#ifdef EXT2FS_REQUIRE_486
-+      __asm__("bswap %0" : "=r" (val) : "0" (val));
-+#else
-+      __asm__("xchgb %b0,%h0\n\t"     /* swap lower bytes     */
-+              "rorl $16,%0\n\t"       /* swap words           */
-+              "xchgb %b0,%h0"         /* swap higher bytes    */
-+              :"=q" (val)
-+              : "0" (val));
-+#endif
-+      return val;
-+}
-+
-+_INLINE_ __u16 blkid_swab16(__u16 val)
-+{
-+      __asm__("xchgb %b0,%h0"         /* swap bytes           */ \
-+              : "=q" (val) \
-+              :  "0" (val)); \
-+              return val;
-+}
-+
-+_INLINE_ __u64 blkid_swab64(__u64 val)
-+{
-+      return (blkid_swab32(val >> 32) |
-+              (((__u64) blkid_swab32(val & 0xFFFFFFFFUL)) << 32));
-+}
-+#endif
-+
-+#if !defined(_BLKID_HAVE_ASM_BITOPS_)
-+
-+_INLINE_  __u16 blkid_swab16(__u16 val)
-+{
-+      return (val >> 8) | (val << 8);
-+}
-+
-+_INLINE_ __u32 blkid_swab32(__u32 val)
-+{
-+      return ((val>>24) | ((val>>8)&0xFF00) |
-+              ((val<<8)&0xFF0000) | (val<<24));
-+}
-+
-+_INLINE_ __u64 blkid_swab64(__u64 val)
-+{
-+      return (blkid_swab32(val >> 32) |
-+              (((__u64) blkid_swab32(val & 0xFFFFFFFFUL)) << 32));
-+}
-+#endif 
-+
-+
-+
-+#if  __BYTE_ORDER == __BIG_ENDIAN
-+#define blkid_le16(x) blkid_swab16(x)
-+#define blkid_le32(x) blkid_swab32(x)
-+#define blkid_le64(x) blkid_swab64(x)
-+#define blkid_be16(x) (x)
-+#define blkid_be32(x) (x)
-+#define blkid_be64(x) (x)
-+#else
-+#define blkid_le16(x) (x)
-+#define blkid_le32(x) (x)
-+#define blkid_le64(x) (x)
-+#define blkid_be16(x) blkid_swab16(x)
-+#define blkid_be32(x) blkid_swab32(x)
-+#define blkid_be64(x) blkid_swab64(x)
-+#endif
-+
-+#undef _INLINE_
-+
-+#endif /* _BLKID_PROBE_H */
-diff -Nur busybox-1.00/e2fsprogs/blkid/read.c busybox/e2fsprogs/blkid/read.c
---- busybox-1.00/e2fsprogs/blkid/read.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/read.c     2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,459 @@
-+/*
-+ * read.c - read the blkid cache from disk, to avoid scanning all devices
-+ *
-+ * Copyright (C) 2001, 2003 Theodore Y. Ts'o
-+ * Copyright (C) 2001 Andreas Dilger
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <ctype.h>
-+#include <string.h>
-+#include <time.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "blkidP.h"
-+#include "uuid/uuid.h"
-+
-+#ifdef HAVE_STRTOULL
-+#define __USE_ISOC9X
-+#define STRTOULL strtoull /* defined in stdlib.h if you try hard enough */
-+#else
-+/* FIXME: need to support real strtoull here */
-+#define STRTOULL strtoul
-+#endif
-+
-+#if HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+
-+/*
-+ * File format:
-+ *
-+ *    <device [<NAME="value"> ...]>device_name</device>
-+ *
-+ *    The following tags are required for each entry:
-+ *    <ID="id">       unique (within this file) ID number of this device
-+ *    <TIME="time">   (ascii time_t) time this entry was last read from disk
-+ *    <TYPE="type">   (detected) type of filesystem/data for this partition
-+ *
-+ *    The following tags may be present, depending on the device contents
-+ *    <LABEL="label"> (user supplied) label (volume name, etc)
-+ *    <UUID="uuid">   (generated) universally unique identifier (serial no)
-+ */
-+
-+static char *skip_over_blank(char *cp)
-+{
-+      while (*cp && isspace(*cp))
-+              cp++;
-+      return cp;
-+}
-+
-+static char *skip_over_word(char *cp)
-+{
-+      char ch;
-+
-+      while ((ch = *cp)) {
-+              /* If we see a backslash, skip the next character */
-+              if (ch == '\\') {
-+                      cp++;
-+                      if (*cp == '\0')
-+                              break;
-+                      cp++;
-+                      continue;
-+              }
-+              if (isspace(ch) || ch == '<' || ch == '>')
-+                      break;
-+              cp++;
-+      }
-+      return cp;
-+}
-+
-+static char *strip_line(char *line)
-+{
-+      char    *p;
-+
-+      line = skip_over_blank(line);
-+
-+      p = line + strlen(line) - 1;
-+
-+      while (*line) {
-+              if (isspace(*p))
-+                      *p-- = '\0';
-+              else
-+                      break;
-+      }
-+
-+      return line;
-+}
-+
-+#if 0
-+static char *parse_word(char **buf)
-+{
-+      char *word, *next;
-+
-+      word = *buf;
-+      if (*word == '\0')
-+              return NULL;
-+
-+      word = skip_over_blank(word);
-+      next = skip_over_word(word);
-+      if (*next) {
-+              char *end = next - 1;
-+              if (*end == '"' || *end == '\'')
-+                      *end = '\0';
-+              *next++ = '\0';
-+      }
-+      *buf = next;
-+
-+      if (*word == '"' || *word == '\'')
-+              word++;
-+      return word;
-+}
-+#endif
-+
-+/*
-+ * Start parsing a new line from the cache.
-+ *
-+ * line starts with "<device" return 1 -> continue parsing line
-+ * line starts with "<foo", empty, or # return 0 -> skip line
-+ * line starts with other, return -BLKID_ERR_CACHE -> error
-+ */
-+static int parse_start(char **cp)
-+{
-+      char *p;
-+
-+      p = strip_line(*cp);
-+
-+      /* Skip comment or blank lines.  We can't just NUL the first '#' char,
-+       * in case it is inside quotes, or escaped.
-+       */
-+      if (*p == '\0' || *p == '#')
-+              return 0;
-+
-+      if (!strncmp(p, "<device", 7)) {
-+              DBG(DEBUG_READ, printf("found device header: %8s\n", p));
-+              p += 7;
-+
-+              *cp = p;
-+              return 1;
-+      }
-+
-+      if (*p == '<')
-+              return 0;
-+
-+      return -BLKID_ERR_CACHE;
-+}
-+
-+/* Consume the remaining XML on the line (cosmetic only) */
-+static int parse_end(char **cp)
-+{
-+      *cp = skip_over_blank(*cp);
-+
-+      if (!strncmp(*cp, "</device>", 9)) {
-+              DBG(DEBUG_READ, printf("found device trailer %9s\n", *cp));
-+              *cp += 9;
-+              return 0;
-+      }
-+
-+      return -BLKID_ERR_CACHE;
-+}
-+
-+/*
-+ * Allocate a new device struct with device name filled in.  Will handle
-+ * finding the device on lines of the form:
-+ * <device foo=bar>devname</device>
-+ * <device>devname<foo>bar</foo></device>
-+ */
-+static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp)
-+{
-+      char *start, *tmp, *end, *name;
-+      int ret;
-+
-+      if ((ret = parse_start(cp)) <= 0)
-+              return ret;
-+
-+      start = tmp = strchr(*cp, '>');
-+      if (!start) {
-+              DBG(DEBUG_READ,
-+                  printf("blkid: short line parsing dev: %s\n", *cp));
-+              return -BLKID_ERR_CACHE;
-+      }
-+      start = skip_over_blank(start + 1);
-+      end = skip_over_word(start);
-+
-+      DBG(DEBUG_READ, printf("device should be %*s\n", end - start, start));
-+
-+      if (**cp == '>')
-+              *cp = end;
-+      else
-+              (*cp)++;
-+
-+      *tmp = '\0';
-+
-+      if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) {
-+              DBG(DEBUG_READ,
-+                  printf("blkid: missing </device> ending: %s\n", end));
-+      } else if (tmp)
-+              *tmp = '\0';
-+
-+      if (end - start <= 1) {
-+              DBG(DEBUG_READ, printf("blkid: empty device name: %s\n", *cp));
-+              return -BLKID_ERR_CACHE;
-+      }
-+
-+      name = blkid_strndup(start, end-start);
-+      if (name == NULL)
-+              return -BLKID_ERR_MEM;
-+
-+      DBG(DEBUG_READ, printf("found dev %s\n", name));
-+
-+      if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE)))
-+              return -BLKID_ERR_MEM;
-+
-+      free(name);
-+      return 1;
-+}
-+
-+/*
-+ * Extract a tag of the form NAME="value" from the line.
-+ */
-+static int parse_token(char **name, char **value, char **cp)
-+{
-+      char *end;
-+
-+      if (!name || !value || !cp)
-+              return -BLKID_ERR_PARAM;
-+
-+      if (!(*value = strchr(*cp, '=')))
-+              return 0;
-+
-+      **value = '\0';
-+      *name = strip_line(*cp);
-+      *value = skip_over_blank(*value + 1);
-+
-+      if (**value == '"') {
-+              end = strchr(*value + 1, '"');
-+              if (!end) {
-+                      DBG(DEBUG_READ,
-+                          printf("unbalanced quotes at: %s\n", *value));
-+                      *cp = *value;
-+                      return -BLKID_ERR_CACHE;
-+              }
-+              (*value)++;
-+              *end = '\0';
-+              end++;
-+      } else {
-+              end = skip_over_word(*value);
-+              if (*end) {
-+                      *end = '\0';
-+                      end++;
-+              }
-+      }
-+      *cp = end;
-+
-+      return 1;
-+}
-+
-+/*
-+ * Extract a tag of the form <NAME>value</NAME> from the line.
-+ */
-+/*
-+static int parse_xml(char **name, char **value, char **cp)
-+{
-+      char *end;
-+
-+      if (!name || !value || !cp)
-+              return -BLKID_ERR_PARAM;
-+
-+      *name = strip_line(*cp);
-+
-+      if ((*name)[0] != '<' || (*name)[1] == '/')
-+              return 0;
-+
-+      FIXME: finish this.
-+}
-+*/
-+
-+/*
-+ * Extract a tag from the line.
-+ *
-+ * Return 1 if a valid tag was found.
-+ * Return 0 if no tag found.
-+ * Return -ve error code.
-+ */
-+static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp)
-+{
-+      char *name;
-+      char *value;
-+      int ret;
-+
-+      if (!cache || !dev)
-+              return -BLKID_ERR_PARAM;
-+
-+      if ((ret = parse_token(&name, &value, cp)) <= 0 /* &&
-+          (ret = parse_xml(&name, &value, cp)) <= 0 */)
-+              return ret;
-+
-+      /* Some tags are stored directly in the device struct */
-+      if (!strcmp(name, "DEVNO")) 
-+              dev->bid_devno = STRTOULL(value, 0, 0);
-+      else if (!strcmp(name, "PRI"))
-+              dev->bid_pri = strtol(value, 0, 0);
-+      else if (!strcmp(name, "TIME"))
-+              /* FIXME: need to parse a long long eventually */
-+              dev->bid_time = strtol(value, 0, 0);
-+      else
-+              ret = blkid_set_tag(dev, name, value, strlen(value));
-+
-+      DBG(DEBUG_READ, printf("    tag: %s=\"%s\"\n", name, value));
-+
-+      return ret < 0 ? ret : 1;
-+}
-+
-+/*
-+ * Parse a single line of data, and return a newly allocated dev struct.
-+ * Add the new device to the cache struct, if one was read.
-+ *
-+ * Lines are of the form <device [TAG="value" ...]>/dev/foo</device>
-+ *
-+ * Returns -ve value on error.
-+ * Returns 0 otherwise.
-+ * If a valid device was read, *dev_p is non-NULL, otherwise it is NULL
-+ * (e.g. comment lines, unknown XML content, etc).
-+ */
-+static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp)
-+{
-+      blkid_dev dev;
-+      int ret;
-+
-+      if (!cache || !dev_p)
-+              return -BLKID_ERR_PARAM;
-+
-+      *dev_p = NULL;
-+
-+      DBG(DEBUG_READ, printf("line: %s\n", cp));
-+
-+      if ((ret = parse_dev(cache, dev_p, &cp)) <= 0)
-+              return ret;
-+
-+      dev = *dev_p;
-+
-+      while ((ret = parse_tag(cache, dev, &cp)) > 0) {
-+              ;
-+      }
-+
-+      if (dev->bid_type == NULL) {
-+              DBG(DEBUG_READ,
-+                  printf("blkid: device %s has no TYPE\n",dev->bid_name));
-+              blkid_free_dev(dev);
-+      }
-+
-+      DEB_DUMP_DEV(DEBUG_READ, dev);
-+
-+      return ret;
-+}
-+
-+/*
-+ * Parse the specified filename, and return the data in the supplied or
-+ * a newly allocated cache struct.  If the file doesn't exist, return a
-+ * new empty cache struct.
-+ */
-+void blkid_read_cache(blkid_cache cache)
-+{
-+      FILE *file;
-+      char buf[4096];
-+      int fd, lineno = 0;
-+      struct stat st;
-+
-+      if (!cache)
-+              return;
-+
-+      /*
-+       * If the file doesn't exist, then we just return an empty
-+       * struct so that the cache can be populated.
-+       */
-+      if ((fd = open(cache->bic_filename, O_RDONLY)) < 0)
-+              return;
-+      if (fstat(fd, &st) < 0)
-+              goto errout;
-+      if ((st.st_mtime == cache->bic_ftime) ||
-+          (cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
-+              DBG(DEBUG_CACHE, printf("skipping re-read of %s\n",
-+                                      cache->bic_filename));
-+              goto errout;
-+      }
-+      
-+      DBG(DEBUG_CACHE, printf("reading cache file %s\n",
-+                              cache->bic_filename));
-+
-+      file = fdopen(fd, "r");
-+      if (!file)
-+              goto errout;
-+
-+      while (fgets(buf, sizeof(buf), file)) {
-+              blkid_dev dev;
-+              unsigned int end;
-+
-+              lineno++;
-+              if (buf[0] == 0)
-+                      continue;
-+              end = strlen(buf) - 1;
-+              /* Continue reading next line if it ends with a backslash */
-+              while (buf[end] == '\\' && end < sizeof(buf) - 2 &&
-+                     fgets(buf + end, sizeof(buf) - end, file)) {
-+                      end = strlen(buf) - 1;
-+                      lineno++;
-+              }
-+
-+              if (blkid_parse_line(cache, &dev, buf) < 0) {
-+                      DBG(DEBUG_READ,
-+                          printf("blkid: bad format on line %d\n", lineno));
-+                      continue;
-+              }
-+      }
-+      fclose(file);
-+
-+      /*
-+       * Initially we do not need to write out the cache file.
-+       */
-+      cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
-+      cache->bic_ftime = st.st_mtime;
-+
-+      return;
-+errout:
-+      close(fd);
-+      return;
-+}
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char**argv)
-+{
-+      blkid_cache cache = NULL;
-+      int ret;
-+
-+      blkid_debug_mask = DEBUG_ALL;
-+      if (argc > 2) {
-+              fprintf(stderr, "Usage: %s [filename]\n"
-+                      "Test parsing of the cache (filename)\n", argv[0]);
-+              exit(1);
-+      }
-+      if ((ret = blkid_get_cache(&cache, argv[1])) < 0)
-+              fprintf(stderr, "error %d reading cache file %s\n", ret,
-+                      argv[1] ? argv[1] : BLKID_CACHE_FILE);
-+
-+      blkid_put_cache(cache);
-+
-+      return ret;
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/blkid/resolve.c busybox/e2fsprogs/blkid/resolve.c
---- busybox-1.00/e2fsprogs/blkid/resolve.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/resolve.c  2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,140 @@
-+/*
-+ * resolve.c - resolve names and tags into specific devices
-+ *
-+ * Copyright (C) 2001, 2003 Theodore Ts'o.
-+ * Copyright (C) 2001 Andreas Dilger
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <stdlib.h>
-+#include <fcntl.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include "blkidP.h"
-+#include "probe.h"
-+
-+/*
-+ * Find a tagname (e.g. LABEL or UUID) on a specific device.
-+ */
-+char *blkid_get_tag_value(blkid_cache cache, const char *tagname,
-+                        const char *devname)
-+{
-+      blkid_tag found;
-+      blkid_dev dev;
-+      blkid_cache c = cache;
-+      char *ret = NULL;
-+
-+      DBG(DEBUG_RESOLVE, printf("looking for %s on %s\n", tagname, devname));
-+
-+      if (!devname)
-+              return NULL;
-+
-+      if (!cache) {
-+              if (blkid_get_cache(&c, NULL) < 0)
-+                      return NULL;
-+      }
-+
-+      if ((dev = blkid_get_dev(c, devname, BLKID_DEV_NORMAL)) &&
-+          (found = blkid_find_tag_dev(dev, tagname)))
-+              ret = blkid_strdup(found->bit_val);
-+
-+      if (!cache)
-+              blkid_put_cache(c);
-+
-+      return ret;
-+}
-+
-+/*
-+ * Locate a device name from a token (NAME=value string), or (name, value)
-+ * pair.  In the case of a token, value is ignored.  If the "token" is not
-+ * of the form "NAME=value" and there is no value given, then it is assumed
-+ * to be the actual devname and a copy is returned.
-+ */
-+char *blkid_get_devname(blkid_cache cache, const char *token,
-+                      const char *value)
-+{
-+      blkid_dev dev;
-+      blkid_cache c = cache;
-+      char *t = 0, *v = 0;
-+      char *ret = NULL;
-+
-+      if (!token)
-+              return NULL;
-+      
-+      if (!cache) {
-+              if (blkid_get_cache(&c, NULL) < 0)
-+                      return NULL;
-+      }
-+
-+      DBG(DEBUG_RESOLVE,
-+          printf("looking for %s%s%s %s\n", token, value ? "=" : "",
-+                 value ? value : "", cache ? "in cache" : "from disk"));
-+
-+      if (!value) {
-+              if (!strchr(token, '='))
-+                      return blkid_strdup(token);
-+              blkid_parse_tag_string(token, &t, &v);
-+              if (!t || !v)
-+                      goto errout;
-+              token = t;
-+              value = v;
-+      }
-+
-+      dev = blkid_find_dev_with_tag(c, token, value);
-+      if (!dev)
-+              goto errout;
-+
-+      ret = blkid_strdup(blkid_dev_devname(dev));
-+
-+errout:
-+      if (t)
-+              free(t);
-+      if (v)
-+              free(v);
-+      if (!cache) {
-+              blkid_put_cache(c);
-+      }
-+      return (ret);
-+}
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char **argv)
-+{
-+      char *value;
-+      blkid_cache cache;
-+
-+      blkid_debug_mask = DEBUG_ALL;
-+      if (argc != 2 && argc != 3) {
-+              fprintf(stderr, "Usage:\t%s tagname=value\n"
-+                      "\t%s tagname devname\n"
-+                      "Find which device holds a given token or\n"
-+                      "Find what the value of a tag is in a device\n",
-+                      argv[0], argv[0]);
-+              exit(1);
-+      }
-+      if (blkid_get_cache(&cache, "/dev/null") < 0) {
-+              fprintf(stderr, "Couldn't get blkid cache\n");
-+              exit(1);
-+      }
-+      
-+      if (argv[2]) {
-+              value = blkid_get_tag_value(cache, argv[1], argv[2]);
-+              printf("%s has tag %s=%s\n", argv[2], argv[1],
-+                     value ? value : "<missing>");
-+      } else {
-+              value = blkid_get_devname(cache, argv[1], NULL);
-+              printf("%s has tag %s\n", value ? value : "<none>", argv[1]);
-+      }
-+      blkid_put_cache(cache);
-+      return value ? 0 : 1;
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/blkid/save.c busybox/e2fsprogs/blkid/save.c
---- busybox-1.00/e2fsprogs/blkid/save.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/save.c     2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,193 @@
-+/*
-+ * save.c - write the cache struct to disk
-+ *
-+ * Copyright (C) 2001 by Andreas Dilger
-+ * Copyright (C) 2003 Theodore Ts'o
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <sys/types.h>
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_SYS_MKDEV_H
-+#include <sys/mkdev.h>
-+#endif
-+#ifdef HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include "blkidP.h"
-+
-+static int save_dev(blkid_dev dev, FILE *file)
-+{
-+      struct list_head *p;
-+
-+      if (!dev || dev->bid_name[0] != '/')
-+              return 0;
-+
-+      DBG(DEBUG_SAVE,
-+          printf("device %s, type %s\n", dev->bid_name, dev->bid_type));
-+
-+      fprintf(file,
-+              "<device DEVNO=\"0x%04lx\" TIME=\"%lu\"",
-+              (unsigned long) dev->bid_devno, dev->bid_time);
-+      if (dev->bid_pri)
-+              fprintf(file, " PRI=\"%d\"", dev->bid_pri);
-+      list_for_each(p, &dev->bid_tags) {
-+              blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
-+              fprintf(file, " %s=\"%s\"", tag->bit_name,tag->bit_val);
-+      }
-+      fprintf(file, ">%s</device>\n", dev->bid_name);
-+
-+      return 0;
-+}
-+
-+/*
-+ * Write out the cache struct to the cache file on disk.
-+ */
-+int blkid_flush_cache(blkid_cache cache)
-+{
-+      struct list_head *p;
-+      char *tmp = NULL;
-+      const char *opened = NULL;
-+      const char *filename;
-+      FILE *file = NULL;
-+      int fd, ret = 0;
-+      struct stat st;
-+
-+      if (!cache)
-+              return -BLKID_ERR_PARAM;
-+
-+      if (list_empty(&cache->bic_devs) ||
-+          !(cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
-+              DBG(DEBUG_SAVE, printf("skipping cache file write\n"));
-+              return 0;
-+      }
-+
-+      filename = cache->bic_filename ? cache->bic_filename: BLKID_CACHE_FILE;
-+
-+      /* If we can't write to the cache file, then don't even try */
-+      if (((ret = stat(filename, &st)) < 0 && errno != ENOENT) ||
-+          (ret == 0 && access(filename, W_OK) < 0)) {
-+              DBG(DEBUG_SAVE,
-+                  printf("can't write to cache file %s\n", filename));
-+              return 0;
-+      }
-+
-+      /*
-+       * Try and create a temporary file in the same directory so
-+       * that in case of error we don't overwrite the cache file.
-+       * If the cache file doesn't yet exist, it isn't a regular
-+       * file (e.g. /dev/null or a socket), or we couldn't create
-+       * a temporary file then we open it directly.
-+       */
-+      if (ret == 0 && S_ISREG(st.st_mode)) {
-+              tmp = malloc(strlen(filename) + 8);
-+              if (tmp) {
-+                      sprintf(tmp, "%s-XXXXXX", filename);
-+                      fd = mkstemp(tmp);
-+                      if (fd >= 0) {
-+                              file = fdopen(fd, "w");
-+                              opened = tmp;
-+                      }
-+                      fchmod(fd, 0644);
-+              }
-+      }
-+
-+      if (!file) {
-+              file = fopen(filename, "w");
-+              opened = filename;
-+      }
-+
-+      DBG(DEBUG_SAVE,
-+          printf("writing cache file %s (really %s)\n",
-+                 filename, opened));
-+
-+      if (!file) {
-+              ret = errno;
-+              goto errout;
-+      }
-+
-+      list_for_each(p, &cache->bic_devs) {
-+              blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
-+              if (!dev->bid_type)
-+                      continue;
-+              if ((ret = save_dev(dev, file)) < 0)
-+                      break;
-+      }
-+
-+      if (ret >= 0) {
-+              cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
-+              ret = 1;
-+      }
-+
-+      fclose(file);
-+      if (opened != filename) {
-+              if (ret < 0) {
-+                      unlink(opened);
-+                      DBG(DEBUG_SAVE,
-+                          printf("unlinked temp cache %s\n", opened));
-+              } else {
-+                      char *backup;
-+
-+                      backup = malloc(strlen(filename) + 5);
-+                      if (backup) {
-+                              sprintf(backup, "%s.old", filename);
-+                              unlink(backup);
-+                              link(filename, backup);
-+                              free(backup);
-+                      }
-+                      rename(opened, filename);
-+                      DBG(DEBUG_SAVE,
-+                          printf("moved temp cache %s\n", opened));
-+              }
-+      }
-+
-+errout:
-+      if (tmp)
-+              free(tmp);
-+      return ret;
-+}
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char **argv)
-+{
-+      blkid_cache cache = NULL;
-+      int ret;
-+
-+      blkid_debug_mask = DEBUG_ALL;
-+      if (argc > 2) {
-+              fprintf(stderr, "Usage: %s [filename]\n"
-+                      "Test loading/saving a cache (filename)\n", argv[0]);
-+              exit(1);
-+      }
-+
-+      if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
-+              fprintf(stderr, "%s: error creating cache (%d)\n",
-+                      argv[0], ret);
-+              exit(1);
-+      }
-+      if ((ret = blkid_probe_all(cache)) < 0) {
-+              fprintf(stderr, "error (%d) probing devices\n", ret);
-+              exit(1);
-+      }
-+      cache->bic_filename = blkid_strdup(argv[1]);
-+      
-+      if ((ret = blkid_flush_cache(cache)) < 0) {
-+              fprintf(stderr, "error (%d) saving cache\n", ret);
-+              exit(1);
-+      }
-+
-+      blkid_put_cache(cache);
-+
-+      return ret;
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/blkid/tag.c busybox/e2fsprogs/blkid/tag.c
---- busybox-1.00/e2fsprogs/blkid/tag.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/tag.c      2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,340 @@
-+/*
-+ * tag.c - allocation/initialization/free routines for tag structs
-+ *
-+ * Copyright (C) 2001 Andreas Dilger
-+ * Copyright (C) 2003 Theodore Ts'o
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the
-+ * GNU Lesser General Public License.
-+ * %End-Header%
-+ */
-+
-+#include <stdlib.h>
-+#include <string.h>
-+#include <stdio.h>
-+
-+#include "blkidP.h"
-+
-+static blkid_tag blkid_new_tag(void)
-+{
-+      blkid_tag tag;
-+
-+      if (!(tag = (blkid_tag) calloc(1, sizeof(struct blkid_struct_tag))))
-+              return NULL;
-+
-+      INIT_LIST_HEAD(&tag->bit_tags);
-+      INIT_LIST_HEAD(&tag->bit_names);
-+
-+      return tag;
-+}
-+
-+void blkid_free_tag(blkid_tag tag)
-+{
-+      if (!tag)
-+              return;
-+
-+      DBG(DEBUG_TAG, printf("    freeing tag %s=%s\n", tag->bit_name,
-+                 tag->bit_val ? tag->bit_val : "(NULL)"));
-+      DEB_DUMP_TAG(DEBUG_TAG, tag);
-+
-+      list_del(&tag->bit_tags);       /* list of tags for this device */
-+      list_del(&tag->bit_names);      /* list of tags with this type */
-+
-+      if (tag->bit_name)
-+              free(tag->bit_name);
-+      if (tag->bit_val)
-+              free(tag->bit_val);
-+
-+      free(tag);
-+}
-+
-+/*
-+ * Find the desired tag on a device.  If value is NULL, then the
-+ * first such tag is returned, otherwise return only exact tag if found.
-+ */
-+blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type)
-+{
-+      struct list_head *p;
-+
-+      if (!dev || !type)
-+              return NULL;
-+
-+      list_for_each(p, &dev->bid_tags) {
-+              blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
-+                                         bit_tags);
-+
-+              if (!strcmp(tmp->bit_name, type))
-+                      return tmp;
-+      }
-+      return NULL;
-+}
-+
-+/*
-+ * Find the desired tag type in the cache.
-+ * We return the head tag for this tag type.
-+ */
-+static blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type)
-+{
-+      blkid_tag head = NULL, tmp;
-+      struct list_head *p;
-+
-+      if (!cache || !type)
-+              return NULL;
-+
-+      list_for_each(p, &cache->bic_tags) {
-+              tmp = list_entry(p, struct blkid_struct_tag, bit_tags);
-+              if (!strcmp(tmp->bit_name, type)) {
-+                      DBG(DEBUG_TAG,
-+                          printf("    found cache tag head %s\n", type));
-+                      head = tmp;
-+                      break;
-+              }
-+      }
-+      return head;
-+}
-+
-+/*
-+ * Set a tag on an existing device.
-+ * 
-+ * If value is NULL, then delete the tagsfrom the device.
-+ */
-+int blkid_set_tag(blkid_dev dev, const char *name,
-+                const char *value, const int vlength)
-+{
-+      blkid_tag       t = 0, head = 0;
-+      char            *val = 0;
-+
-+      if (!dev || !name)
-+              return -BLKID_ERR_PARAM;
-+
-+      if (!(val = blkid_strndup(value, vlength)) && value)
-+              return -BLKID_ERR_MEM;
-+      t = blkid_find_tag_dev(dev, name);
-+      if (!value) {
-+              if (t)
-+                      blkid_free_tag(t);
-+      } else if (t) {
-+              if (!strcmp(t->bit_val, val)) {
-+                      /* Same thing, exit */
-+                      free(val);
-+                      return 0;
-+              }
-+              free(t->bit_val);
-+              t->bit_val = val;
-+      } else {
-+              /* Existing tag not present, add to device */
-+              if (!(t = blkid_new_tag()))
-+                      goto errout;
-+              t->bit_name = blkid_strdup(name);
-+              t->bit_val = val;
-+              t->bit_dev = dev;
-+
-+              list_add_tail(&t->bit_tags, &dev->bid_tags);
-+              
-+              if (dev->bid_cache) {
-+                      head = blkid_find_head_cache(dev->bid_cache,
-+                                                   t->bit_name);
-+                      if (!head) {
-+                              head = blkid_new_tag();
-+                              if (!head)
-+                                      goto errout;
-+
-+                              DBG(DEBUG_TAG,
-+                                  printf("    creating new cache tag head %s\n", name));
-+                              head->bit_name = blkid_strdup(name);
-+                              if (!head->bit_name)
-+                                      goto errout;
-+                              list_add_tail(&head->bit_tags,
-+                                            &dev->bid_cache->bic_tags);
-+                      }
-+                      list_add_tail(&t->bit_names, &head->bit_names);
-+              }
-+      }
-+      
-+      /* Link common tags directly to the device struct */
-+      if (!strcmp(name, "TYPE"))
-+              dev->bid_type = val;
-+      else if (!strcmp(name, "LABEL"))
-+              dev->bid_label = val;
-+      else if (!strcmp(name, "UUID"))
-+              dev->bid_uuid = val;
-+              
-+      if (dev->bid_cache)
-+              dev->bid_cache->bic_flags |= BLKID_BIC_FL_CHANGED;
-+      return 0;
-+
-+errout:
-+      if (t)
-+              blkid_free_tag(t);
-+      else if (val)
-+              free(val);
-+      if (head)
-+              blkid_free_tag(head);
-+      return -BLKID_ERR_MEM;
-+}
-+
-+
-+/*
-+ * Parse a "NAME=value" string.  This is slightly different than
-+ * parse_token, because that will end an unquoted value at a space, while
-+ * this will assume that an unquoted value is the rest of the token (e.g.
-+ * if we are passed an already quoted string from the command-line we don't
-+ * have to both quote and escape quote so that the quotes make it to
-+ * us).
-+ *
-+ * Returns 0 on success, and -1 on failure.
-+ */
-+int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val)
-+{
-+      char *name, *value, *cp;
-+
-+      DBG(DEBUG_TAG, printf("trying to parse '%s' as a tag\n", token));
-+
-+      if (!token || !(cp = strchr(token, '=')))
-+              return -1;
-+
-+      name = blkid_strdup(token);
-+      if (!name)
-+              return -1;
-+      value = name + (cp - token);
-+      *value++ = '\0';
-+      if (*value == '"' || *value == '\'') {
-+              char c = *value++;
-+              if (!(cp = strrchr(value, c)))
-+                      goto errout; /* missing closing quote */
-+              *cp = '\0';
-+      }
-+      value = blkid_strdup(value);
-+      if (!value)
-+              goto errout;
-+
-+      *ret_type = name;
-+      *ret_val = value;
-+
-+      return 0;
-+
-+errout:
-+      free(name);
-+      return -1;
-+}
-+
-+/*
-+ * Tag iteration routines for the public libblkid interface.
-+ *
-+ * These routines do not expose the list.h implementation, which are a
-+ * contamination of the namespace, and which force us to reveal far, far
-+ * too much of our internal implemenation.  I'm not convinced I want
-+ * to keep list.h in the long term, anyway.  It's fine for kernel
-+ * programming, but performance is not the #1 priority for this
-+ * library, and I really don't like the tradeoff of type-safety for
-+ * performance for this application.  [tytso:20030125.2007EST]
-+ */
-+
-+/*
-+ * This series of functions iterate over all tags in a device
-+ */
-+#define TAG_ITERATE_MAGIC     0x01a5284c
-+      
-+struct blkid_struct_tag_iterate {
-+      int                     magic;
-+      blkid_dev               dev;
-+      struct list_head        *p;
-+};
-+
-+extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev)
-+{
-+      blkid_tag_iterate       iter;
-+
-+      iter = malloc(sizeof(struct blkid_struct_tag_iterate));
-+      if (iter) {
-+              iter->magic = TAG_ITERATE_MAGIC;
-+              iter->dev = dev;
-+              iter->p = dev->bid_tags.next;
-+      }
-+      return (iter);
-+}
-+
-+/*
-+ * Return 0 on success, -1 on error
-+ */
-+extern int blkid_tag_next(blkid_tag_iterate iter,
-+                        const char **type, const char **value)
-+{
-+      blkid_tag tag;
-+      
-+      *type = 0;
-+      *value = 0;
-+      if (!iter || iter->magic != TAG_ITERATE_MAGIC ||
-+          iter->p == &iter->dev->bid_tags)
-+              return -1;
-+      tag = list_entry(iter->p, struct blkid_struct_tag, bit_tags);
-+      *type = tag->bit_name;
-+      *value = tag->bit_val;
-+      iter->p = iter->p->next;
-+      return 0;
-+}
-+
-+extern void blkid_tag_iterate_end(blkid_tag_iterate iter)
-+{
-+      if (!iter || iter->magic != TAG_ITERATE_MAGIC)
-+              return;
-+      iter->magic = 0;
-+      free(iter);
-+}
-+
-+/*
-+ * This function returns a device which matches a particular
-+ * type/value pair.  If there is more than one device that matches the
-+ * search specification, it returns the one with the highest priority
-+ * value.  This allows us to give preference to EVMS or LVM devices.
-+ *
-+ * XXX there should also be an interface which uses an iterator so we
-+ * can get all of the devices which match a type/value search parameter.
-+ */
-+extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
-+                                       const char *type,
-+                                       const char *value)
-+{
-+      blkid_tag       head;
-+      blkid_dev       dev;
-+      int             pri;
-+      struct list_head *p;
-+
-+      if (!cache || !type || !value)
-+              return NULL;
-+
-+      blkid_read_cache(cache);
-+      
-+      DBG(DEBUG_TAG, printf("looking for %s=%s in cache\n", type, value));
-+      
-+try_again:
-+      pri = -1;
-+      dev = 0;
-+      head = blkid_find_head_cache(cache, type);
-+
-+      if (head) {
-+              list_for_each(p, &head->bit_names) {
-+                      blkid_tag tmp = list_entry(p, struct blkid_struct_tag, 
-+                                                 bit_names);
-+
-+                      if (!strcmp(tmp->bit_val, value) &&
-+                          tmp->bit_dev->bid_pri > pri) {
-+                              dev = tmp->bit_dev;
-+                              pri = dev->bid_pri;
-+                      }
-+              }
-+      }
-+      if (dev && !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) {
-+              dev = blkid_verify(cache, dev);
-+              if (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED))
-+                      goto try_again;
-+      }
-+
-+      if (!dev && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) {
-+              if (blkid_probe_all(cache) < 0)
-+                      return NULL;
-+              goto try_again;
-+      }
-+      return dev;
-+}
-diff -Nur busybox-1.00/e2fsprogs/blkid/version.c busybox/e2fsprogs/blkid/version.c
---- busybox-1.00/e2fsprogs/blkid/version.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/blkid/version.c  2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,49 @@
-+/*
-+ * version.c --- Return the version of the blkid library
-+ *
-+ * Copyright (C) 2004 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <stdio.h>
-+#include <ctype.h>
-+
-+#include "blkid.h"
-+#include "../../version.h"
-+
-+static const char *lib_version = E2FSPROGS_VERSION;
-+static const char *lib_date = E2FSPROGS_DATE;
-+
-+int blkid_parse_version_string(const char *ver_string)
-+{
-+      const char *cp;
-+      int version = 0;
-+
-+      for (cp = ver_string; *cp; cp++) {
-+              if (*cp == '.')
-+                      continue;
-+              if (!isdigit(*cp))
-+                      break;
-+              version = (version * 10) + (*cp - '0');
-+      }
-+      return version;
-+}
-+
-+int blkid_get_library_version(const char **ver_string,
-+                             const char **date_string)
-+{
-+      if (ver_string)
-+              *ver_string = lib_version;
-+      if (date_string)
-+              *date_string = lib_date;
-+
-+      return blkid_parse_version_string(lib_version);
-+}
-diff -Nur busybox-1.00/e2fsprogs/chattr.c busybox/e2fsprogs/chattr.c
---- busybox-1.00/e2fsprogs/chattr.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/chattr.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,225 @@
-+/*
-+ * chattr.c           - Change file attributes on an ext2 file system
-+ *
-+ * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
-+ *                           Laboratoire MASI, Institut Blaise Pascal
-+ *                           Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ * This file can be redistributed under the terms of the GNU General
-+ * Public License
-+ */
-+
-+/*
-+ * History:
-+ * 93/10/30   - Creation
-+ * 93/11/13   - Replace stat() calls by lstat() to avoid loops
-+ * 94/02/27   - Integrated in Ted's distribution
-+ * 98/12/29   - Ignore symlinks when working recursively (G M Sipe)
-+ * 98/12/29   - Display version info only when -V specified (G M Sipe)
-+ */
-+
-+#include <sys/types.h>
-+#include <dirent.h>
-+#include <fcntl.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <sys/param.h>
-+#include <sys/stat.h>
-+#include <ext2fs/ext2_fs.h>
-+
-+#ifdef __GNUC__
-+# define EXT2FS_ATTR(x) __attribute__(x)
-+#else
-+# define EXT2FS_ATTR(x)
-+#endif
-+
-+#include "e2fsbb.h"
-+#include "e2p/e2p.h"
-+
-+#define OPT_ADD 1
-+#define OPT_REM 2
-+#define OPT_SET 4
-+#define OPT_SET_VER 8
-+static int flags;
-+static int recursive;
-+
-+static unsigned long version;
-+
-+static unsigned long af;
-+static unsigned long rf;
-+static unsigned long sf;
-+
-+#ifdef CONFIG_LFS
-+# define LSTAT lstat64
-+# define STRUCT_STAT struct stat64
-+#else
-+# define LSTAT lstat
-+# define STRUCT_STAT struct stat
-+#endif
-+
-+struct flags_char {
-+      unsigned long flag;
-+      char optchar;
-+};
-+
-+static const struct flags_char flags_array[] = {
-+      { EXT2_NOATIME_FL,      'A' },
-+      { EXT2_SYNC_FL,         'S' },
-+      { EXT2_DIRSYNC_FL,      'D' },
-+      { EXT2_APPEND_FL,       'a' },
-+      { EXT2_COMPR_FL,        'c' },
-+      { EXT2_NODUMP_FL,       'd' },
-+      { EXT2_IMMUTABLE_FL,    'i' },
-+      { EXT3_JOURNAL_DATA_FL, 'j' },
-+      { EXT2_SECRM_FL,        's' },
-+      { EXT2_UNRM_FL,         'u' },
-+      { EXT2_NOTAIL_FL,       't' },
-+      { EXT2_TOPDIR_FL,       'T' },
-+      { 0, 0 }
-+};
-+
-+static unsigned long get_flag(char c)
-+{
-+      const struct flags_char *fp;
-+      for (fp = flags_array; fp->flag; fp++)
-+              if (fp->optchar == c)
-+                      return fp->flag;
-+      bb_show_usage();
-+      return 0;
-+}
-+
-+static int decode_arg(char *arg)
-+{
-+      unsigned long *fl;
-+      char opt = *arg++;
-+
-+      if (opt == '-') {
-+              flags |= OPT_REM;
-+              fl = &rf;
-+      } else if (opt == '+') {
-+              flags |= OPT_ADD;
-+              fl = &af;
-+      } else if (opt == '=') {
-+              flags |= OPT_SET;
-+              fl = &sf;
-+      } else
-+              return EOF;
-+
-+      for (; *arg ; ++arg)
-+              (*fl) |= get_flag(*arg);
-+
-+      return 1;
-+}
-+
-+static int chattr_dir_proc(const char *, struct dirent *, void *);
-+
-+static void change_attributes(const char * name)
-+{
-+      unsigned long fsflags;
-+      STRUCT_STAT     st;
-+
-+      if (LSTAT(name, &st) == -1) {
-+              bb_error_msg("stat %s failed", name);
-+              return;
-+      }
-+      if (S_ISLNK(st.st_mode) && recursive)
-+              return;
-+
-+      /* Don't try to open device files, fifos etc.  We probably
-+       * ought to display an error if the file was explicitly given
-+       * on the command line (whether or not recursive was
-+       * requested).  */
-+      if (!S_ISREG(st.st_mode) && !S_ISLNK(st.st_mode) && !S_ISDIR(st.st_mode))
-+              return;
-+
-+      if (flags & OPT_SET_VER)
-+              if (fsetversion(name, version) == -1)
-+                      bb_error_msg("setting version on %s", name);
-+
-+      if (flags & OPT_SET) {
-+              fsflags = sf;
-+      } else {
-+              if (fgetflags(name, &fsflags) == -1) {
-+                      bb_error_msg("reading flags on %s", name);
-+                      goto skip_setflags;
-+              }
-+              if (flags & OPT_REM)
-+                      fsflags &= ~rf;
-+              if (flags & OPT_ADD)
-+                      fsflags |= af;
-+              if (!S_ISDIR(st.st_mode))
-+                      fsflags &= ~EXT2_DIRSYNC_FL;
-+      }
-+      if (fsetflags(name, fsflags) == -1)
-+              bb_error_msg("setting flags on %s", name);
-+
-+skip_setflags:
-+      if (S_ISDIR(st.st_mode) && recursive)
-+              iterate_on_dir(name, chattr_dir_proc, NULL);
-+}
-+
-+static int chattr_dir_proc(const char *dir_name, struct dirent *de, 
-+                           void *private EXT2FS_ATTR((unused)))
-+{
-+      /*if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {*/
-+      if (de->d_name[0] == '.' && (de->d_name[1] == '\0' || \
-+         (de->d_name[1] == '.' && de->d_name[2] == '\0'))) {
-+              char *path = concat_subpath_file(dir_name, de->d_name);
-+              if (path) {
-+                      change_attributes(path);
-+                      free(path);
-+              }
-+      }
-+      return 0;
-+}
-+
-+int chattr_main(int argc, char **argv)
-+{
-+      int i;
-+      char *arg;
-+
-+      /* parse the args */
-+      for (i = 1; i < argc; ++i) {
-+              arg = argv[i];
-+
-+              /* take care of -R and -v <version> */
-+              if (arg[0] == '-') {
-+                      if (arg[1] == 'R' && arg[2] == '\0') {
-+                              recursive = 1;
-+                              continue;
-+                      } else if (arg[1] == 'v' && arg[2] == '\0') {
-+                              char *tmp;
-+                              ++i;
-+                              if (i >= argc)
-+                                      bb_show_usage();
-+                              version = strtol(argv[i], &tmp, 0);
-+                              if (*tmp)
-+                                      bb_error_msg_and_die("bad version '%s'", arg);
-+                              flags |= OPT_SET_VER;
-+                              continue;
-+                      }
-+              }
-+
-+              if (decode_arg(arg) == EOF)
-+                      break;
-+      }
-+
-+      /* run sanity checks on all the arguments given us */
-+      if (i >= argc)
-+              bb_show_usage();
-+      if ((flags & OPT_SET) && ((flags & OPT_ADD) || (flags & OPT_REM)))
-+              bb_error_msg_and_die("= is incompatible with - and +");
-+      if ((rf & af) != 0)
-+              bb_error_msg_and_die("Can't set and unset a flag");
-+      if (!flags)
-+              bb_error_msg_and_die("Must use '-v', =, - or +");
-+
-+      /* now run chattr on all the files passed to us */
-+      while (i < argc)
-+              change_attributes(argv[i++]);
-+
-+      return EXIT_SUCCESS;
-+}
-diff -Nur busybox-1.00/e2fsprogs/e2fsbb.h busybox/e2fsprogs/e2fsbb.h
---- busybox-1.00/e2fsprogs/e2fsbb.h    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2fsbb.h 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,40 @@
-+/*
-+ * File: e2fsbb.h
-+ *
-+ * Redefine a bunch of e2fsprogs stuff to use busybox routines
-+ * instead.  This makes upgrade between e2fsprogs versions easy.
-+ */
-+
-+#ifndef __E2FSBB_H__
-+#define __E2FSBB_H__ 1
-+
-+#include "libbb.h"
-+
-+/* version we've last synced against */
-+#define E2FSPROGS_VERSION "1.37"
-+#define E2FSPROGS_DATE "21-Mar-2005"
-+
-+/* make sure com_err.h isnt included before us */
-+#ifdef __COM_ERR_H__
-+#error You should not have included com_err.h !
-+#endif
-+#define __COM_ERR_H__
-+
-+/* com_err crap */
-+#define com_err(w, c, fmt, args...) bb_error_msg(fmt, ## args)
-+typedef long errcode_t;
-+#define ERRCODE_RANGE 8
-+#define error_message(code) strerror((int) (code & ((1<<ERRCODE_RANGE)-1)))
-+#define initialize_ext2_error_table(x)
-+
-+/* NLS crap */
-+#define _(x) x
-+#define N_(x) x
-+#define P_(singular, plural, n) ((n) == 1 ? (singular) : (plural))
-+
-+/* misc crap */
-+#define fatal_error(msg, err) bb_error_msg_and_die(msg)
-+#define usage() bb_show_usage()
-+#define perror(msg) bb_perror_msg(msg)
-+
-+#endif /* __E2FSBB_H__ */
-diff -Nur busybox-1.00/e2fsprogs/e2p/e2p.h busybox/e2fsprogs/e2p/e2p.h
---- busybox-1.00/e2fsprogs/e2p/e2p.h   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/e2p.h        2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,59 @@
-+#include <sys/types.h>                /* Needed by dirent.h on netbsd */
-+#include <stdio.h>
-+#include <dirent.h>
-+
-+#include <ext2fs/ext2_fs.h>
-+
-+#define E2P_FEATURE_COMPAT    0
-+#define E2P_FEATURE_INCOMPAT  1
-+#define E2P_FEATURE_RO_INCOMPAT       2
-+
-+
-+/* `options' for print_flags() */
-+
-+#define PFOPT_LONG  1 /* Must be 1 for compatibility with `int long_format'. */
-+
-+/*int fgetversion (const char * name, unsigned long * version);*/
-+/*int fsetversion (const char * name, unsigned long version);*/
-+int fgetsetversion(const char * name, unsigned long * get_version, unsigned long set_version);
-+#define fgetversion(name, version) fgetsetversion(name, version, 0)
-+#define fsetversion(name, version) fgetsetversion(name, NULL, version)
-+
-+/*int fgetflags (const char * name, unsigned long * flags);*/
-+/*int fsetflags (const char * name, unsigned long flags);*/
-+int fgetsetflags(const char * name, unsigned long * get_flags, unsigned long set_flags);
-+#define fgetflags(name, flags) fgetsetflags(name, flags, 0)
-+#define fsetflags(name, flags) fgetsetflags(name, NULL, flags)
-+
-+int getflags (int fd, unsigned long * flags);
-+int getversion (int fd, unsigned long * version);
-+int iterate_on_dir (const char * dir_name,
-+                  int (*func) (const char *, struct dirent *, void *),
-+                  void * private);
-+void list_super(struct ext2_super_block * s);
-+void list_super2(struct ext2_super_block * s, FILE *f);
-+void print_fs_errors (FILE * f, unsigned short errors);
-+void print_flags (FILE * f, unsigned long flags, unsigned options);
-+void print_fs_state (FILE * f, unsigned short state);
-+int setflags (int fd, unsigned long flags);
-+int setversion (int fd, unsigned long version);
-+
-+const char *e2p_feature2string(int compat, unsigned int mask);
-+int e2p_string2feature(char *string, int *compat, unsigned int *mask);
-+int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array);
-+
-+int e2p_is_null_uuid(void *uu);
-+void e2p_uuid_to_str(void *uu, char *out);
-+const char *e2p_uuid2str(void *uu);
-+
-+const char *e2p_hash2string(int num);
-+int e2p_string2hash(char *string);
-+
-+const char *e2p_mntopt2string(unsigned int mask);
-+int e2p_string2mntopt(char *string, unsigned int *mask);
-+int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok);
-+
-+unsigned long parse_num_blocks(const char *arg, int log_block_size);
-+
-+char *e2p_os2string(int os_type);
-+int e2p_string2os(char *str);
-diff -Nur busybox-1.00/e2fsprogs/e2p/feature.c busybox/e2fsprogs/e2p/feature.c
---- busybox-1.00/e2fsprogs/e2p/feature.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/feature.c    2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,190 @@
-+/*
-+ * feature.c --- convert between features and strings
-+ * 
-+ * Copyright (C) 1999  Theodore Ts'o <tytso@mit.edu>
-+ * 
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <errno.h>
-+
-+#include "e2p.h"
-+
-+struct feature {
-+      int             compat;
-+      unsigned int    mask;
-+      const char      *string;
-+};
-+
-+static struct feature feature_list[] = {
-+      {       E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_PREALLOC,
-+                      "dir_prealloc" },
-+      {       E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL,
-+                      "has_journal" },
-+      {       E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_IMAGIC_INODES,
-+                      "imagic_inodes" },
-+      {       E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXT_ATTR,
-+                      "ext_attr" },
-+      {       E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX,
-+                      "dir_index" },
-+      {       E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INODE,
-+                      "resize_inode" },
-+      {       E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER,
-+                      "sparse_super" },
-+      {       E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE,
-+                      "large_file" },
-+      {       E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
-+                      "compression" },
-+      {       E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_FILETYPE,
-+                      "filetype" },
-+      {       E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_RECOVER,
-+                      "needs_recovery" },
-+      {       E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV,
-+                      "journal_dev" },
-+      {       E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS,
-+                      "extents" },
-+      {       E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_META_BG,
-+                      "meta_bg" },
-+      {       0, 0, 0 },
-+};
-+
-+const char *e2p_feature2string(int compat, unsigned int mask)
-+{
-+      struct feature  *f;
-+      static char buf[20];
-+      char    fchar;
-+      int     fnum;
-+
-+      for (f = feature_list; f->string; f++) {
-+              if ((compat == f->compat) &&
-+                  (mask == f->mask))
-+                      return f->string;
-+      }
-+      switch (compat) {
-+      case  E2P_FEATURE_COMPAT:
-+              fchar = 'C';
-+              break;
-+      case E2P_FEATURE_INCOMPAT:
-+              fchar = 'I';
-+              break;
-+      case E2P_FEATURE_RO_INCOMPAT:
-+              fchar = 'R';
-+              break;
-+      default:
-+              fchar = '?';
-+              break;
-+      }
-+      for (fnum = 0; mask >>= 1; fnum++);
-+      sprintf(buf, "FEATURE_%c%d", fchar, fnum);
-+      return buf;
-+}
-+
-+int e2p_string2feature(char *string, int *compat_type, unsigned int *mask)
-+{
-+      struct feature  *f;
-+      char            *eptr;
-+      int             num;
-+
-+      for (f = feature_list; f->string; f++) {
-+              if (!strcasecmp(string, f->string)) {
-+                      *compat_type = f->compat;
-+                      *mask = f->mask;
-+                      return 0;
-+              }
-+      }
-+      if (strncasecmp(string, "FEATURE_", 8))
-+              return 1;
-+
-+      switch (string[8]) {
-+      case 'c':
-+      case 'C':
-+              *compat_type = E2P_FEATURE_COMPAT;
-+              break;
-+      case 'i':
-+      case 'I':
-+              *compat_type = E2P_FEATURE_INCOMPAT;
-+              break;
-+      case 'r':
-+      case 'R':
-+              *compat_type = E2P_FEATURE_RO_INCOMPAT;
-+              break;
-+      default:
-+              return 1;
-+      }
-+      if (string[9] == 0)
-+              return 1;
-+      num = strtol(string+9, &eptr, 10);
-+      if (num > 32 || num < 0)
-+              return 1;
-+      if (*eptr)
-+              return 1;
-+      *mask = 1 << num;
-+      return 0;
-+}
-+
-+static char *skip_over_blanks(char *cp)
-+{
-+      while (*cp && isspace(*cp))
-+              cp++;
-+      return cp;
-+}
-+
-+static char *skip_over_word(char *cp)
-+{
-+      while (*cp && !isspace(*cp) && *cp != ',')
-+              cp++;
-+      return cp;
-+}
-+
-+/*
-+ * Edit a feature set array as requested by the user.  The ok_array,
-+ * if set, allows the application to limit what features the user is
-+ * allowed to set or clear using this function.
-+ */
-+int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
-+{
-+      char    *cp, *buf, *next;
-+      int     neg;
-+      unsigned int    mask;
-+      int             compat_type;
-+
-+      buf = malloc(strlen(str)+1);
-+      if (!buf)
-+              return 1;
-+      strcpy(buf, str);
-+      cp = buf;
-+      while (cp && *cp) {
-+              neg = 0;
-+              cp = skip_over_blanks(cp);
-+              next = skip_over_word(cp);
-+              if (*next == 0)
-+                      next = 0;
-+              else
-+                      *next = 0;
-+              switch (*cp) {
-+              case '-':
-+              case '^':
-+                      neg++;
-+              case '+':
-+                      cp++;
-+                      break;
-+              }
-+              if (e2p_string2feature(cp, &compat_type, &mask))
-+                      return 1;
-+              if (ok_array && !(ok_array[compat_type] & mask))
-+                      return 1;
-+              if (neg)
-+                      compat_array[compat_type] &= ~mask;
-+              else
-+                      compat_array[compat_type] |= mask;
-+              cp = next ? next+1 : 0;
-+      }
-+      return 0;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/e2p/fgetsetflags.c busybox/e2fsprogs/e2p/fgetsetflags.c
---- busybox-1.00/e2fsprogs/e2p/fgetsetflags.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/fgetsetflags.c       2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,69 @@
-+/*
-+ * fgetflags.c                - Get a file flags on an ext2 file system
-+ * fsetflags.c                - Set a file flags on an ext2 file system
-+ *
-+ * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
-+ *                           Laboratoire MASI, Institut Blaise Pascal
-+ *                           Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ */
-+
-+/*
-+ * History:
-+ * 93/10/30   - Creation
-+ */
-+
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#if HAVE_EXT2_IOCTLS
-+#include <fcntl.h>
-+#include <sys/ioctl.h>
-+#endif
-+
-+#include "e2p.h"
-+
-+#ifdef O_LARGEFILE
-+#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
-+#else
-+#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
-+#endif
-+
-+int fgetsetflags (const char * name, unsigned long * get_flags, unsigned long set_flags)
-+{
-+#if HAVE_EXT2_IOCTLS
-+      struct stat buf;
-+      int fd, r, f, save_errno = 0;
-+
-+      if (!stat(name, &buf) &&
-+          !S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
-+              goto notsupp;
-+      }
-+      fd = open (name, OPEN_FLAGS);
-+      if (fd == -1)
-+              return -1;
-+      if (!get_flags) {
-+              f = (int) set_flags;
-+              r = ioctl (fd, EXT2_IOC_SETFLAGS, &f);
-+      } else {
-+              r = ioctl (fd, EXT2_IOC_GETFLAGS, &f);
-+              *get_flags = f;
-+      }
-+      if (r == -1)
-+              save_errno = errno;
-+      close (fd);
-+      if (save_errno)
-+              errno = save_errno;
-+      return r;
-+#endif /* HAVE_EXT2_IOCTLS */
-+notsupp:
-+      errno = EOPNOTSUPP;
-+      return -1;
-+}
-diff -Nur busybox-1.00/e2fsprogs/e2p/fgetsetversion.c busybox/e2fsprogs/e2p/fgetsetversion.c
---- busybox-1.00/e2fsprogs/e2p/fgetsetversion.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/fgetsetversion.c     2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,69 @@
-+/*
-+ * fgetversion.c      - Get a file version on an ext2 file system
-+ * fsetversion.c      - Set a file version on an ext2 file system
-+ *
-+ *
-+ * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
-+ *                           Laboratoire MASI, Institut Blaise Pascal
-+ *                           Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ */
-+
-+/*
-+ * History:
-+ * 93/10/30   - Creation
-+ */
-+
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <sys/ioctl.h>
-+
-+#include "e2p.h"
-+
-+#ifdef O_LARGEFILE
-+#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
-+#else
-+#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
-+#endif
-+
-+/* 
-+   To do fsetversion:     unsigned long *ptr_version must be set to NULL.
-+                      and unsigned long version must be set to a value   
-+   To do fgetversion:     unsigned long *ptr_version must NOT be set to NULL
-+                      and unsigned long version is ignored.
-+      TITO.
-+*/
-+
-+int fgetsetversion (const char * name, unsigned long * get_version, unsigned long set_version)
-+{
-+#if HAVE_EXT2_IOCTLS
-+      int fd, r, ver, save_errno = 0;
-+
-+      fd = open (name, OPEN_FLAGS);
-+      if (fd == -1)
-+              return -1;
-+      if (!get_version) {
-+              ver = (int) set_version;
-+              r = ioctl (fd, EXT2_IOC_SETVERSION, &ver);
-+      } else {
-+              r = ioctl (fd, EXT2_IOC_GETVERSION, &ver);
-+              *get_version = ver;
-+      }
-+      if (r == -1)
-+              save_errno = errno;
-+      close (fd);
-+      if (save_errno)
-+              errno = save_errno;
-+      return r;
-+#else /* ! HAVE_EXT2_IOCTLS */
-+      errno = EOPNOTSUPP;
-+      return -1;
-+#endif /* ! HAVE_EXT2_IOCTLS */
-+}
-diff -Nur busybox-1.00/e2fsprogs/e2p/hashstr.c busybox/e2fsprogs/e2p/hashstr.c
---- busybox-1.00/e2fsprogs/e2p/hashstr.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/hashstr.c    2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,70 @@
-+/*
-+ * feature.c --- convert between features and strings
-+ * 
-+ * Copyright (C) 1999  Theodore Ts'o <tytso@mit.edu>
-+ * 
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <errno.h>
-+
-+#include "e2p.h"
-+
-+struct hash {
-+      int             num;
-+      const char      *string;
-+};
-+
-+static struct hash hash_list[] = {
-+      {       EXT2_HASH_LEGACY,       "legacy" },
-+      {       EXT2_HASH_HALF_MD4,     "half_md4" },
-+      {       EXT2_HASH_TEA,          "tea" },
-+      {       0, 0 },
-+};
-+
-+const char *e2p_hash2string(int num)
-+{
-+      struct hash  *p;
-+      static char buf[20];
-+
-+      for (p = hash_list; p->string; p++) {
-+              if (num == p->num)
-+                      return p->string;
-+      }
-+      sprintf(buf, "HASHALG_%d", num);
-+      return buf;
-+}
-+
-+/*
-+ * Returns the hash algorithm, or -1 on error
-+ */
-+int e2p_string2hash(char *string)
-+{
-+      struct hash     *p;
-+      char            *eptr;
-+      int             num;
-+
-+      for (p = hash_list; p->string; p++) {
-+              if (!strcasecmp(string, p->string)) {
-+                      return p->num;
-+              }
-+      }
-+      if (strncasecmp(string, "HASHALG_", 8))
-+              return -1;
-+
-+      if (string[8] == 0)
-+              return -1;
-+      num = strtol(string+8, &eptr, 10);
-+      if (num > 255 || num < 0)
-+              return -1;
-+      if (*eptr)
-+              return -1;
-+      return num;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/e2p/iod.c busybox/e2fsprogs/e2p/iod.c
---- busybox-1.00/e2fsprogs/e2p/iod.c   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/iod.c        2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,51 @@
-+/*
-+ * iod.c              - Iterate a function on each entry of a directory
-+ *
-+ * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
-+ *                           Laboratoire MASI, Institut Blaise Pascal
-+ *                           Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ */
-+
-+/*
-+ * History:
-+ * 93/10/30   - Creation
-+ */
-+
-+#include "e2p.h"
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <string.h>
-+
-+int iterate_on_dir (const char * dir_name,
-+                  int (*func) (const char *, struct dirent *, void *),
-+                  void * private)
-+{
-+      DIR * dir;
-+      struct dirent *de, *dep;
-+      int     max_len, len;
-+
-+      max_len = PATH_MAX + sizeof(struct dirent);
-+      de = (struct dirent *)xmalloc(max_len+1);
-+      memset(de, 0, max_len+1);
-+
-+      dir = opendir (dir_name);
-+      if (dir == NULL) {
-+              free(de);
-+              return -1;
-+      }
-+      while ((dep = readdir (dir))) {
-+              len = sizeof(struct dirent);
-+              if (len < dep->d_reclen)
-+                      len = dep->d_reclen;
-+              if (len > max_len)
-+                      len = max_len;
-+              memcpy(de, dep, len);
-+              (*func) (dir_name, de, private);
-+      }
-+      free(de);
-+      closedir(dir);
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/e2p/ls.c busybox/e2fsprogs/e2p/ls.c
---- busybox-1.00/e2fsprogs/e2p/ls.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/ls.c 2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,276 @@
-+/*
-+ * ls.c                       - List the contents of an ext2fs superblock
-+ *
-+ * Copyright (C) 1992, 1993, 1994  Remy Card <card@masi.ibp.fr>
-+ *                                 Laboratoire MASI, Institut Blaise Pascal
-+ *                                 Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ * Copyright (C) 1995, 1996, 1997  Theodore Ts'o <tytso@mit.edu>
-+ * 
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ */
-+
-+#include <stdio.h>
-+#include <sys/types.h>
-+#include <string.h>
-+#include <grp.h>
-+#include <pwd.h>
-+#include <time.h>
-+
-+#include "e2p.h"
-+
-+static void print_user (unsigned short uid, FILE *f)
-+{
-+      struct passwd *pw;
-+
-+      fprintf(f, "%u ", uid);
-+      pw = getpwuid (uid);
-+      if (pw == NULL)
-+              fprintf(f, "(user unknown)\n");
-+      else
-+              fprintf(f, "(user %s)\n", pw->pw_name);
-+}
-+
-+static void print_group (unsigned short gid, FILE *f)
-+{
-+      struct group *gr;
-+
-+      fprintf(f, "%u ", gid);
-+      gr = getgrgid (gid);
-+      if (gr == NULL)
-+              fprintf(f, "(group unknown)\n");
-+      else
-+              fprintf(f, "(group %s)\n", gr->gr_name);
-+}
-+
-+#define MONTH_INT (86400 * 30)
-+#define WEEK_INT (86400 * 7)
-+#define DAY_INT       (86400)
-+#define HOUR_INT (60 * 60)
-+#define MINUTE_INT (60)
-+
-+static const char *interval_string(unsigned int secs)
-+{
-+      static char buf[256], tmp[80];
-+      int             hr, min, num;
-+
-+      buf[0] = 0;
-+
-+      if (secs == 0)
-+              return "<none>";
-+
-+      if (secs >= MONTH_INT) {
-+              num = secs / MONTH_INT;
-+              secs -= num*MONTH_INT;
-+              sprintf(buf, "%d month%s", num, (num>1) ? "s" : "");
-+      }
-+      if (secs >= WEEK_INT) {
-+              num = secs / WEEK_INT;
-+              secs -= num*WEEK_INT;
-+              sprintf(tmp, "%s%d week%s", buf[0] ? ", " : "",
-+                      num, (num>1) ? "s" : "");
-+              strcat(buf, tmp);
-+      }
-+      if (secs >= DAY_INT) {
-+              num = secs / DAY_INT;
-+              secs -= num*DAY_INT;
-+              sprintf(tmp, "%s%d day%s", buf[0] ? ", " : "",
-+                      num, (num>1) ? "s" : "");
-+              strcat(buf, tmp);
-+      }
-+      if (secs > 0) {
-+              hr = secs / HOUR_INT;
-+              secs -= hr*HOUR_INT;
-+              min = secs / MINUTE_INT;
-+              secs -= min*MINUTE_INT;
-+              sprintf(tmp, "%s%d:%02d:%02d", buf[0] ? ", " : "",
-+                      hr, min, secs);
-+              strcat(buf, tmp);
-+      }
-+      return buf;
-+}
-+
-+static void print_features(struct ext2_super_block * s, FILE *f)
-+{
-+#ifdef EXT2_DYNAMIC_REV
-+      int     i, j, printed=0;
-+      __u32   *mask = &s->s_feature_compat, m;
-+
-+      fprintf(f, "Filesystem features:     ");
-+      for (i=0; i <3; i++,mask++) {
-+              for (j=0,m=1; j < 32; j++, m<<=1) {
-+                      if (*mask & m) {
-+                              fprintf(f, " %s", e2p_feature2string(i, m));
-+                              printed++;
-+                      }
-+              }
-+      }
-+      if (printed == 0)
-+              fprintf(f, " (none)");
-+      fprintf(f, "\n");
-+#endif
-+}
-+
-+static void print_mntopts(struct ext2_super_block * s, FILE *f)
-+{
-+#ifdef EXT2_DYNAMIC_REV
-+      int     i, printed=0;
-+      __u32   mask = s->s_default_mount_opts, m;
-+
-+      fprintf(f, "Default mount options:   ");
-+      if (mask & EXT3_DEFM_JMODE) {
-+              fprintf(f, " %s", e2p_mntopt2string(mask & EXT3_DEFM_JMODE));
-+              printed++;
-+      }
-+      for (i=0,m=1; i < 32; i++, m<<=1) {
-+              if (m & EXT3_DEFM_JMODE)
-+                      continue;
-+              if (mask & m) {
-+                      fprintf(f, " %s", e2p_mntopt2string(m));
-+                      printed++;
-+              }
-+      }
-+      if (printed == 0)
-+              fprintf(f, " (none)");
-+      fprintf(f, "\n");
-+#endif
-+}
-+
-+
-+#ifndef EXT2_INODE_SIZE
-+#define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
-+#endif
-+
-+#ifndef EXT2_GOOD_OLD_REV
-+#define EXT2_GOOD_OLD_REV 0
-+#endif
-+
-+void list_super2(struct ext2_super_block * sb, FILE *f)
-+{
-+      int inode_blocks_per_group;
-+      char buf[80], *str;
-+      time_t  tm;
-+
-+      inode_blocks_per_group = (((sb->s_inodes_per_group *
-+                                  EXT2_INODE_SIZE(sb)) +
-+                                 EXT2_BLOCK_SIZE(sb) - 1) /
-+                                EXT2_BLOCK_SIZE(sb));
-+      if (sb->s_volume_name[0]) {
-+              memset(buf, 0, sizeof(buf));
-+              strncpy(buf, sb->s_volume_name, sizeof(sb->s_volume_name));
-+      } else
-+              strcpy(buf, "<none>");
-+      fprintf(f, "Filesystem volume name:   %s\n", buf);
-+      if (sb->s_last_mounted[0]) {
-+              memset(buf, 0, sizeof(buf));
-+              strncpy(buf, sb->s_last_mounted, sizeof(sb->s_last_mounted));
-+      } else
-+              strcpy(buf, "<not available>");
-+      fprintf(f, "Last mounted on:          %s\n", buf);
-+      fprintf(f, "Filesystem UUID:          %s\n", e2p_uuid2str(sb->s_uuid));
-+      fprintf(f, "Filesystem magic number:  0x%04X\n", sb->s_magic);
-+      fprintf(f, "Filesystem revision #:    %d", sb->s_rev_level);
-+      if (sb->s_rev_level == EXT2_GOOD_OLD_REV) {
-+              fprintf(f, " (original)\n");
-+#ifdef EXT2_DYNAMIC_REV
-+      } else if (sb->s_rev_level == EXT2_DYNAMIC_REV) {
-+              fprintf(f, " (dynamic)\n");
-+#endif
-+      } else
-+              fprintf(f, " (unknown)\n");
-+      print_features(sb, f);
-+      print_mntopts(sb, f);
-+      fprintf(f, "Filesystem state:        ");
-+      print_fs_state (f, sb->s_state);
-+      fprintf(f, "\n");
-+      fprintf(f, "Errors behavior:          ");
-+      print_fs_errors(f, sb->s_errors);
-+      fprintf(f, "\n");
-+      str = e2p_os2string(sb->s_creator_os);
-+      fprintf(f, "Filesystem OS type:       %s\n", str);
-+      free(str);
-+      fprintf(f, "Inode count:              %u\n", sb->s_inodes_count);
-+      fprintf(f, "Block count:              %u\n", sb->s_blocks_count);
-+      fprintf(f, "Reserved block count:     %u\n", sb->s_r_blocks_count);
-+      fprintf(f, "Free blocks:              %u\n", sb->s_free_blocks_count);
-+      fprintf(f, "Free inodes:              %u\n", sb->s_free_inodes_count);
-+      fprintf(f, "First block:              %u\n", sb->s_first_data_block);
-+      fprintf(f, "Block size:               %u\n", EXT2_BLOCK_SIZE(sb));
-+      fprintf(f, "Fragment size:            %u\n", EXT2_FRAG_SIZE(sb));
-+      if (sb->s_reserved_gdt_blocks)
-+              fprintf(f, "Reserved GDT blocks:      %u\n", 
-+                      sb->s_reserved_gdt_blocks);
-+      fprintf(f, "Blocks per group:         %u\n", sb->s_blocks_per_group);
-+      fprintf(f, "Fragments per group:      %u\n", sb->s_frags_per_group);
-+      fprintf(f, "Inodes per group:         %u\n", sb->s_inodes_per_group);
-+      fprintf(f, "Inode blocks per group:   %u\n", inode_blocks_per_group);
-+      if (sb->s_first_meta_bg)
-+              fprintf(f, "First meta block group:   %u\n",
-+                      sb->s_first_meta_bg);
-+      if (sb->s_mkfs_time) {
-+              tm = sb->s_mkfs_time;
-+              fprintf(f, "Filesystem created:       %s", ctime(&tm));
-+      }
-+      tm = sb->s_mtime;
-+      fprintf(f, "Last mount time:          %s",
-+              sb->s_mtime ? ctime(&tm) : "n/a\n");
-+      tm = sb->s_wtime;
-+      fprintf(f, "Last write time:          %s", ctime(&tm));
-+      fprintf(f, "Mount count:              %u\n", sb->s_mnt_count);
-+      fprintf(f, "Maximum mount count:      %d\n", sb->s_max_mnt_count);
-+      tm = sb->s_lastcheck;
-+      fprintf(f, "Last checked:             %s", ctime(&tm));
-+      fprintf(f, "Check interval:           %u (%s)\n", sb->s_checkinterval,
-+             interval_string(sb->s_checkinterval));
-+      if (sb->s_checkinterval)
-+      {
-+              time_t next;
-+
-+              next = sb->s_lastcheck + sb->s_checkinterval;
-+              fprintf(f, "Next check after:         %s", ctime(&next));
-+      }
-+      fprintf(f, "Reserved blocks uid:      ");
-+      print_user(sb->s_def_resuid, f);
-+      fprintf(f, "Reserved blocks gid:      ");
-+      print_group(sb->s_def_resgid, f);
-+      if (sb->s_rev_level >= EXT2_DYNAMIC_REV) {
-+              fprintf(f, "First inode:              %d\n", sb->s_first_ino);
-+              fprintf(f, "Inode size:           %d\n", sb->s_inode_size);
-+      }
-+      if (!e2p_is_null_uuid(sb->s_journal_uuid))
-+              fprintf(f, "Journal UUID:             %s\n",
-+                      e2p_uuid2str(sb->s_journal_uuid));
-+      if (sb->s_journal_inum)
-+              fprintf(f, "Journal inode:            %u\n",
-+                      sb->s_journal_inum);
-+      if (sb->s_journal_dev)
-+              fprintf(f, "Journal device:               0x%04x\n",
-+                      sb->s_journal_dev);
-+      if (sb->s_last_orphan)
-+              fprintf(f, "First orphan inode:       %u\n",
-+                      sb->s_last_orphan);
-+      if ((sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) ||
-+          sb->s_def_hash_version)
-+              fprintf(f, "Default directory hash:   %s\n",
-+                      e2p_hash2string(sb->s_def_hash_version));
-+      if (!e2p_is_null_uuid(sb->s_hash_seed))
-+              fprintf(f, "Directory Hash Seed:      %s\n",
-+                      e2p_uuid2str(sb->s_hash_seed));
-+      if (sb->s_jnl_backup_type) {
-+              fprintf(f, "Journal backup:           ");
-+              switch (sb->s_jnl_backup_type) {
-+              case 1:
-+                      fprintf(f, "inode blocks\n");
-+                      break;
-+              default:
-+                      fprintf(f, "type %u\n", sb->s_jnl_backup_type);
-+              }
-+      }
-+}
-+
-+void list_super (struct ext2_super_block * s)
-+{
-+      list_super2(s, stdout);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/e2p/mntopts.c busybox/e2fsprogs/e2p/mntopts.c
---- busybox-1.00/e2fsprogs/e2p/mntopts.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/mntopts.c    2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,136 @@
-+/*
-+ * mountopts.c --- convert between default mount options and strings
-+ * 
-+ * Copyright (C) 2002  Theodore Ts'o <tytso@mit.edu>
-+ * 
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <errno.h>
-+
-+#include "e2p.h"
-+
-+struct mntopt {
-+      unsigned int    mask;
-+      const char      *string;
-+};
-+
-+static struct mntopt mntopt_list[] = {
-+      { EXT2_DEFM_DEBUG,      "debug" },
-+      { EXT2_DEFM_BSDGROUPS,  "bsdgroups" },
-+      { EXT2_DEFM_XATTR_USER, "user_xattr" },
-+      { EXT2_DEFM_ACL,        "acl" },
-+      { EXT2_DEFM_UID16,      "uid16" },
-+      { EXT3_DEFM_JMODE_DATA, "journal_data" },
-+      { EXT3_DEFM_JMODE_ORDERED, "journal_data_ordered" },
-+      { EXT3_DEFM_JMODE_WBACK, "journal_data_writeback" },
-+      { 0, 0 },
-+};
-+
-+const char *e2p_mntopt2string(unsigned int mask)
-+{
-+      struct mntopt  *f;
-+      static char buf[20];
-+      int     fnum;
-+
-+      for (f = mntopt_list; f->string; f++) {
-+              if (mask == f->mask)
-+                      return f->string;
-+      }
-+      for (fnum = 0; mask >>= 1; fnum++);
-+      sprintf(buf, "MNTOPT_%d", fnum);
-+      return buf;
-+}
-+
-+int e2p_string2mntopt(char *string, unsigned int *mask)
-+{
-+      struct mntopt  *f;
-+      char            *eptr;
-+      int             num;
-+
-+      for (f = mntopt_list; f->string; f++) {
-+              if (!strcasecmp(string, f->string)) {
-+                      *mask = f->mask;
-+                      return 0;
-+              }
-+      }
-+      if (strncasecmp(string, "MNTOPT_", 8))
-+              return 1;
-+
-+      if (string[8] == 0)
-+              return 1;
-+      num = strtol(string+8, &eptr, 10);
-+      if (num > 32 || num < 0)
-+              return 1;
-+      if (*eptr)
-+              return 1;
-+      *mask = 1 << num;
-+      return 0;
-+}
-+
-+static char *skip_over_blanks(char *cp)
-+{
-+      while (*cp && isspace(*cp))
-+              cp++;
-+      return cp;
-+}
-+
-+static char *skip_over_word(char *cp)
-+{
-+      while (*cp && !isspace(*cp) && *cp != ',')
-+              cp++;
-+      return cp;
-+}
-+
-+/*
-+ * Edit a mntopt set array as requested by the user.  The ok
-+ * parameter, if non-zero, allows the application to limit what
-+ * mntopts the user is allowed to set or clear using this function.
-+ */
-+int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok)
-+{
-+      char    *cp, *buf, *next;
-+      int     neg;
-+      unsigned int    mask;
-+
-+      buf = malloc(strlen(str)+1);
-+      if (!buf)
-+              return 1;
-+      strcpy(buf, str);
-+      cp = buf;
-+      while (cp && *cp) {
-+              neg = 0;
-+              cp = skip_over_blanks(cp);
-+              next = skip_over_word(cp);
-+              if (*next == 0)
-+                      next = 0;
-+              else
-+                      *next = 0;
-+              switch (*cp) {
-+              case '-':
-+              case '^':
-+                      neg++;
-+              case '+':
-+                      cp++;
-+                      break;
-+              }
-+              if (e2p_string2mntopt(cp, &mask))
-+                      return 1;
-+              if (ok && !(ok & mask))
-+                      return 1;
-+              if (mask & EXT3_DEFM_JMODE)
-+                      *mntopts &= ~EXT3_DEFM_JMODE;
-+              if (neg)
-+                      *mntopts &= ~mask;
-+              else
-+                      *mntopts |= mask;
-+              cp = next ? next+1 : 0;
-+      }
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/e2p/ostype.c busybox/e2fsprogs/e2p/ostype.c
---- busybox-1.00/e2fsprogs/e2p/ostype.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/ostype.c     2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,73 @@
-+/*
-+ * getostype.c          - Get the Filesystem OS type
-+ *
-+ * Copyright (C) 2004,2005  Theodore Ts'o <tytso@mit.edu>
-+ *
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ */
-+
-+#include "e2p.h"
-+#include <string.h>
-+
-+const char *os_tab[] =
-+      { "Linux", 
-+        "Hurd", 
-+        "Masix", 
-+        "FreeBSD", 
-+        "Lites",
-+        0 };
-+
-+/*
-+ * Convert an os_type to a string
-+ */
-+char *e2p_os2string(int os_type)
-+{
-+        const char    *os;
-+      char            *ret;
-+
-+      if (os_type <= EXT2_OS_LITES)
-+              os = os_tab[os_type];
-+      else
-+              os = "(unknown os)";
-+
-+        ret = malloc(strlen(os)+1);
-+        strcpy(ret, os);
-+        return ret;
-+}
-+
-+/*
-+ * Convert an os_type to a string
-+ */
-+int e2p_string2os(char *str)
-+{
-+      const char      **cpp;
-+      int             i = 0;
-+
-+      for (cpp = os_tab; *cpp; cpp++, i++) {
-+              if (!strcasecmp(str, *cpp))
-+                      return i;
-+      }
-+      return -1;
-+}
-+
-+#ifdef TEST_PROGRAM
-+int main(int argc, char **argv)
-+{
-+      char    *s;
-+      int     i, os;
-+
-+      for (i=0; i <= EXT2_OS_LITES; i++) {
-+              s = e2p_os2string(i);
-+              os = e2p_string2os(s);
-+              printf("%d: %s (%d)\n", i, s, os);
-+              if (i != os) {
-+                      fprintf(stderr, "Failure!\n");
-+                      exit(1);
-+              }
-+      }
-+      exit(0);
-+}
-+#endif
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/e2p/parse_num.c busybox/e2fsprogs/e2p/parse_num.c
---- busybox-1.00/e2fsprogs/e2p/parse_num.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/parse_num.c  2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,64 @@
-+/*
-+ * parse_num.c                - Parse the number of blocks 
-+ *
-+ * Copyright (C) 2004,2005  Theodore Ts'o <tytso@mit.edu>
-+ * 
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ */
-+
-+#include "e2p.h"
-+
-+#include <stdlib.h>
-+
-+unsigned long parse_num_blocks(const char *arg, int log_block_size)
-+{
-+      char *p;
-+      unsigned long long num;
-+
-+      num = strtoull(arg, &p, 0);
-+
-+      if (p[0] && p[1]) 
-+              return 0;
-+
-+      switch (*p) {           /* Using fall-through logic */
-+      case 'T': case 't': 
-+              num <<= 10;
-+      case 'G': case 'g': 
-+              num <<= 10;
-+      case 'M': case 'm': 
-+              num <<= 10;
-+      case 'K': case 'k': 
-+              num >>= log_block_size; 
-+              break;
-+      case 's': 
-+              num >>= 1;
-+              break;
-+      case '\0':
-+              break;
-+      default: 
-+              return 0;
-+      }
-+      return num;
-+}
-+
-+#ifdef DEBUG
-+#include <unistd.h>
-+#include <stdio.h>
-+
-+main(int argc, char **argv)
-+{
-+      unsigned long num;
-+      int log_block_size = 0;
-+
-+      if (argc != 2) {
-+              fprintf(stderr, "Usage: %s arg\n", argv[0]);
-+              exit(1);
-+      }
-+
-+      num = parse_num_blocks(argv[1], log_block_size);
-+
-+      printf("Parsed number: %lu\n", num);
-+      exit(0);
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/e2p/pe.c busybox/e2fsprogs/e2p/pe.c
---- busybox-1.00/e2fsprogs/e2p/pe.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/pe.c 2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,37 @@
-+/*
-+ * pe.c                       - Print a second extended filesystem errors behavior
-+ *
-+ * Copyright (C) 1992, 1993, 1994  Remy Card <card@masi.ibp.fr>
-+ *                                 Laboratoire MASI, Institut Blaise Pascal
-+ *                                 Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ */
-+
-+/*
-+ * History:
-+ * 94/01/09   - Creation
-+ */
-+
-+#include <stdio.h>
-+
-+#include "e2p.h"
-+
-+void print_fs_errors (FILE * f, unsigned short errors)
-+{
-+      switch (errors)
-+      {
-+              case EXT2_ERRORS_CONTINUE:
-+                      fprintf (f, "Continue");
-+                      break;
-+              case EXT2_ERRORS_RO:
-+                      fprintf (f, "Remount read-only");
-+                      break;
-+              case EXT2_ERRORS_PANIC:
-+                      fprintf (f, "Panic");
-+                      break;
-+              default:
-+                      fprintf (f, "Unknown (continue)");
-+      }
-+}
-diff -Nur busybox-1.00/e2fsprogs/e2p/pf.c busybox/e2fsprogs/e2p/pf.c
---- busybox-1.00/e2fsprogs/e2p/pf.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/pf.c 2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,74 @@
-+/*
-+ * pf.c                       - Print file attributes on an ext2 file system
-+ *
-+ * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
-+ *                           Laboratoire MASI, Institut Blaise Pascal
-+ *                           Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ */
-+
-+/*
-+ * History:
-+ * 93/10/30   - Creation
-+ */
-+
-+#include <stdio.h>
-+
-+#include "e2p.h"
-+
-+struct flags_name {
-+      unsigned long   flag;
-+      const char      *short_name;
-+      const char      *long_name;
-+};
-+
-+static struct flags_name flags_array[] = {
-+      { EXT2_SECRM_FL, "s", "Secure_Deletion" },
-+      { EXT2_UNRM_FL, "u" , "Undelete" },
-+      { EXT2_SYNC_FL, "S", "Synchronous_Updates" },
-+      { EXT2_DIRSYNC_FL, "D", "Synchronous_Directory_Updates" },
-+      { EXT2_IMMUTABLE_FL, "i", "Immutable" },
-+      { EXT2_APPEND_FL, "a", "Append_Only" },
-+      { EXT2_NODUMP_FL, "d", "No_Dump" },
-+      { EXT2_NOATIME_FL, "A", "No_Atime" },
-+      { EXT2_COMPR_FL, "c", "Compression_Requested" },
-+#ifdef ENABLE_COMPRESSION
-+      { EXT2_COMPRBLK_FL, "B", "Compressed_File" },
-+      { EXT2_DIRTY_FL, "Z", "Compressed_Dirty_File" },
-+      { EXT2_NOCOMPR_FL, "X", "Compression_Raw_Access" },
-+      { EXT2_ECOMPR_FL, "E", "Compression_Error" },
-+#endif
-+      { EXT3_JOURNAL_DATA_FL, "j", "Journaled_Data" },
-+      { EXT2_INDEX_FL, "I", "Indexed_direcctory" }, 
-+      { EXT2_NOTAIL_FL, "t", "No_Tailmerging" },
-+      { EXT2_TOPDIR_FL, "T", "Top_of_Directory_Hierarchies" },
-+      { 0, NULL, NULL }
-+};
-+
-+void print_flags (FILE * f, unsigned long flags, unsigned options)
-+{
-+      int long_opt = (options & PFOPT_LONG);
-+      struct flags_name *fp;
-+      int     first = 1;
-+
-+      for (fp = flags_array; fp->flag != 0; fp++) {
-+              if (flags & fp->flag) {
-+                      if (long_opt) {
-+                              if (first)
-+                                      first = 0;
-+                              else
-+                                      fputs(", ", f);
-+                              fputs(fp->long_name, f);
-+                      } else
-+                              fputs(fp->short_name, f);
-+              } else {
-+                      if (!long_opt)
-+                              fputs("-", f);
-+              }
-+      }
-+      if (long_opt && first)
-+              fputs("---", f);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/e2p/ps.c busybox/e2fsprogs/e2p/ps.c
---- busybox-1.00/e2fsprogs/e2p/ps.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/ps.c 2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,29 @@
-+/*
-+ * ps.c                       - Print filesystem state
-+ *
-+ * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
-+ *                           Laboratoire MASI, Institut Blaise Pascal
-+ *                           Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ * This file can be redistributed under the terms of the GNU Library General
-+ * Public License
-+ */
-+
-+/*
-+ * History:
-+ * 93/12/22   - Creation
-+ */
-+
-+#include <stdio.h>
-+
-+#include "e2p.h"
-+
-+void print_fs_state (FILE * f, unsigned short state)
-+{
-+      if (state & EXT2_VALID_FS)
-+              fprintf (f, " clean");
-+      else
-+              fprintf (f, " not clean");
-+      if (state & EXT2_ERROR_FS)
-+              fprintf (f, " with errors");
-+}
-diff -Nur busybox-1.00/e2fsprogs/e2p/uuid.c busybox/e2fsprogs/e2p/uuid.c
---- busybox-1.00/e2fsprogs/e2p/uuid.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/e2p/uuid.c       2005-06-04 08:20:15.000000000 +0200
-@@ -0,0 +1,79 @@
-+/*
-+ * uuid.c -- utility routines for manipulating UUID's.
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <ext2fs/ext2_types.h>
-+
-+#include "e2p.h"
-+
-+struct uuid {
-+      __u32   time_low;
-+      __u16   time_mid;
-+      __u16   time_hi_and_version;
-+      __u16   clock_seq;
-+      __u8    node[6];
-+};
-+
-+/* Returns 1 if the uuid is the NULL uuid */
-+int e2p_is_null_uuid(void *uu)
-+{
-+      __u8    *cp;
-+      int     i;
-+
-+      for (i=0, cp = uu; i < 16; i++)
-+              if (*cp)
-+                      return 0;
-+      return 1;
-+}
-+
-+static void e2p_unpack_uuid(void *in, struct uuid *uu)
-+{
-+      __u8    *ptr = in;
-+      __u32   tmp;
-+
-+      tmp = *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      uu->time_low = tmp;
-+
-+      tmp = *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      uu->time_mid = tmp;
-+      
-+      tmp = *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      uu->time_hi_and_version = tmp;
-+
-+      tmp = *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      uu->clock_seq = tmp;
-+
-+      memcpy(uu->node, ptr, 6);
-+}
-+
-+void e2p_uuid_to_str(void *uu, char *out)
-+{
-+      struct uuid uuid;
-+
-+      e2p_unpack_uuid(uu, &uuid);
-+      sprintf(out,
-+              "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
-+              uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
-+              uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
-+              uuid.node[0], uuid.node[1], uuid.node[2],
-+              uuid.node[3], uuid.node[4], uuid.node[5]);
-+}
-+
-+const char *e2p_uuid2str(void *uu)
-+{
-+      static char buf[80];
-+
-+      if (e2p_is_null_uuid(uu))
-+              return "<none>";
-+      e2p_uuid_to_str(uu, buf);
-+      return buf;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/alloc.c busybox/e2fsprogs/ext2fs/alloc.c
---- busybox-1.00/e2fsprogs/ext2fs/alloc.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/alloc.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,173 @@
-+/*
-+ * alloc.c --- allocate new inodes, blocks for ext2fs
-+ *
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <time.h>
-+#include <string.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * Right now, just search forward from the parent directory's block
-+ * group to find the next free inode.
-+ *
-+ * Should have a special policy for directories.
-+ */
-+errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, 
-+                         int mode EXT2FS_ATTR((unused)),
-+                         ext2fs_inode_bitmap map, ext2_ino_t *ret)
-+{
-+      ext2_ino_t      dir_group = 0;
-+      ext2_ino_t      i;
-+      ext2_ino_t      start_inode;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+      
-+      if (!map)
-+              map = fs->inode_map;
-+      if (!map)
-+              return EXT2_ET_NO_INODE_BITMAP;
-+      
-+      if (dir > 0) 
-+              dir_group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super);
-+
-+      start_inode = (dir_group * EXT2_INODES_PER_GROUP(fs->super)) + 1;
-+      if (start_inode < EXT2_FIRST_INODE(fs->super))
-+              start_inode = EXT2_FIRST_INODE(fs->super);
-+      i = start_inode;
-+
-+      do {
-+              if (!ext2fs_fast_test_inode_bitmap(map, i))
-+                      break;
-+              i++;
-+              if (i > fs->super->s_inodes_count)
-+                      i = EXT2_FIRST_INODE(fs->super);
-+      } while (i != start_inode);
-+      
-+      if (ext2fs_test_inode_bitmap(map, i))
-+              return EXT2_ET_INODE_ALLOC_FAIL;
-+      *ret = i;
-+      return 0;
-+}
-+
-+/*
-+ * Stupid algorithm --- we now just search forward starting from the
-+ * goal.  Should put in a smarter one someday....
-+ */
-+errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
-+                         ext2fs_block_bitmap map, blk_t *ret)
-+{
-+      blk_t   i;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (!map)
-+              map = fs->block_map;
-+      if (!map)
-+              return EXT2_ET_NO_BLOCK_BITMAP;
-+      if (!goal || (goal >= fs->super->s_blocks_count))
-+              goal = fs->super->s_first_data_block;
-+      i = goal;
-+      do {
-+              if (!ext2fs_fast_test_block_bitmap(map, i)) {
-+                      *ret = i;
-+                      return 0;
-+              }
-+              i++;
-+              if (i >= fs->super->s_blocks_count)
-+                      i = fs->super->s_first_data_block;
-+      } while (i != goal);
-+      return EXT2_ET_BLOCK_ALLOC_FAIL;
-+}
-+
-+/*
-+ * This function zeros out the allocated block, and updates all of the
-+ * appropriate filesystem records.
-+ */
-+errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
-+                           char *block_buf, blk_t *ret)
-+{
-+      errcode_t       retval;
-+      blk_t           block;
-+      char            *buf = 0;
-+
-+      if (!block_buf) {
-+              retval = ext2fs_get_mem(fs->blocksize, &buf);
-+              if (retval)
-+                      return retval;
-+              block_buf = buf;
-+      }
-+      memset(block_buf, 0, fs->blocksize);
-+
-+      if (!fs->block_map) {
-+              retval = ext2fs_read_block_bitmap(fs);
-+              if (retval)
-+                      goto fail;
-+      }
-+
-+      retval = ext2fs_new_block(fs, goal, 0, &block);
-+      if (retval)
-+              goto fail;
-+
-+      retval = io_channel_write_blk(fs->io, block, 1, block_buf);
-+      if (retval)
-+              goto fail;
-+      
-+      ext2fs_block_alloc_stats(fs, block, +1);
-+      *ret = block;
-+      return 0;
-+
-+fail:
-+      if (buf)
-+              ext2fs_free_mem(&buf);
-+      return retval;
-+}
-+
-+errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
-+                               int num, ext2fs_block_bitmap map, blk_t *ret)
-+{
-+      blk_t   b = start;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (!map)
-+              map = fs->block_map;
-+      if (!map)
-+              return EXT2_ET_NO_BLOCK_BITMAP;
-+      if (!b)
-+              b = fs->super->s_first_data_block;
-+      if (!finish)
-+              finish = start;
-+      if (!num)
-+              num = 1;
-+      do {
-+              if (b+num-1 > fs->super->s_blocks_count)
-+                      b = fs->super->s_first_data_block;
-+              if (ext2fs_fast_test_block_bitmap_range(map, b, num)) {
-+                      *ret = b;
-+                      return 0;
-+              }
-+              b++;
-+      } while (b != finish);
-+      return EXT2_ET_BLOCK_ALLOC_FAIL;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/alloc_sb.c busybox/e2fsprogs/ext2fs/alloc_sb.c
---- busybox-1.00/e2fsprogs/ext2fs/alloc_sb.c   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/alloc_sb.c        2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,57 @@
-+/*
-+ * alloc_sb.c --- Allocate the superblock and block group descriptors for a 
-+ * newly initialized filesystem.  Used by mke2fs when initializing a filesystem
-+ *
-+ * Copyright (C) 1994, 1995, 1996, 2003 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+int ext2fs_reserve_super_and_bgd(ext2_filsys fs, 
-+                               dgrp_t group,
-+                               ext2fs_block_bitmap bmap)
-+{
-+      blk_t   super_blk, old_desc_blk, new_desc_blk;
-+      int     j, old_desc_blocks, num_blocks;
-+
-+      num_blocks = ext2fs_super_and_bgd_loc(fs, group, &super_blk, 
-+                                            &old_desc_blk, &new_desc_blk, 0);
-+
-+      if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
-+              old_desc_blocks = fs->super->s_first_meta_bg;
-+      else
-+              old_desc_blocks = 
-+                      fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
-+
-+      if (super_blk || (group == 0))
-+              ext2fs_mark_block_bitmap(bmap, super_blk);
-+
-+      if (old_desc_blk) {
-+              for (j=0; j < old_desc_blocks; j++)
-+                      ext2fs_mark_block_bitmap(bmap, old_desc_blk + j);
-+      }
-+      if (new_desc_blk)
-+              ext2fs_mark_block_bitmap(bmap, new_desc_blk);
-+
-+      return num_blocks;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/alloc_stats.c busybox/e2fsprogs/ext2fs/alloc_stats.c
---- busybox-1.00/e2fsprogs/ext2fs/alloc_stats.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/alloc_stats.c     2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,52 @@
-+/*
-+ * alloc_stats.c --- Update allocation statistics for ext2fs
-+ *
-+ * Copyright (C) 2001 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ */
-+
-+#include <stdio.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
-+                             int inuse, int isdir)
-+{
-+      int     group = ext2fs_group_of_ino(fs, ino);
-+
-+      if (inuse > 0)
-+              ext2fs_mark_inode_bitmap(fs->inode_map, ino);
-+      else
-+              ext2fs_unmark_inode_bitmap(fs->inode_map, ino);
-+      fs->group_desc[group].bg_free_inodes_count -= inuse;
-+      if (isdir)
-+              fs->group_desc[group].bg_used_dirs_count += inuse;
-+      fs->super->s_free_inodes_count -= inuse;
-+      ext2fs_mark_super_dirty(fs);
-+      ext2fs_mark_ib_dirty(fs);
-+}
-+
-+void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse)
-+{
-+      ext2fs_inode_alloc_stats2(fs, ino, inuse, 0);
-+}
-+
-+void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse)
-+{
-+      int     group = ext2fs_group_of_blk(fs, blk);
-+
-+      if (inuse > 0)
-+              ext2fs_mark_block_bitmap(fs->block_map, blk);
-+      else
-+              ext2fs_unmark_block_bitmap(fs->block_map, blk);
-+      fs->group_desc[group].bg_free_blocks_count -= inuse;
-+      fs->super->s_free_blocks_count -= inuse;
-+      ext2fs_mark_super_dirty(fs);
-+      ext2fs_mark_bb_dirty(fs);
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/alloc_tables.c busybox/e2fsprogs/ext2fs/alloc_tables.c
---- busybox-1.00/e2fsprogs/ext2fs/alloc_tables.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/alloc_tables.c    2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,117 @@
-+/*
-+ * alloc_tables.c --- Allocate tables for a newly initialized
-+ * filesystem.  Used by mke2fs when initializing a filesystem
-+ *
-+ * Copyright (C) 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
-+                                    ext2fs_block_bitmap bmap)
-+{
-+      errcode_t       retval;
-+      blk_t           group_blk, start_blk, last_blk, new_blk, blk;
-+      int             j;
-+
-+      group_blk = fs->super->s_first_data_block +
-+              (group * fs->super->s_blocks_per_group);
-+      
-+      last_blk = group_blk + fs->super->s_blocks_per_group;
-+      if (last_blk >= fs->super->s_blocks_count)
-+              last_blk = fs->super->s_blocks_count - 1;
-+
-+      if (!bmap)
-+              bmap = fs->block_map;
-+      
-+      /*
-+       * Allocate the block and inode bitmaps, if necessary
-+       */
-+      if (fs->stride) {
-+              start_blk = group_blk + fs->inode_blocks_per_group;
-+              start_blk += ((fs->stride * group) %
-+                            (last_blk - start_blk));
-+              if (start_blk > last_blk)
-+                      start_blk = group_blk;
-+      } else
-+              start_blk = group_blk;
-+
-+      if (!fs->group_desc[group].bg_block_bitmap) {
-+              retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-+                                              1, bmap, &new_blk);
-+              if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) 
-+                      retval = ext2fs_get_free_blocks(fs, group_blk,
-+                                      last_blk, 1, bmap, &new_blk);
-+              if (retval)
-+                      return retval;
-+              ext2fs_mark_block_bitmap(bmap, new_blk);
-+              fs->group_desc[group].bg_block_bitmap = new_blk;
-+      }
-+
-+      if (!fs->group_desc[group].bg_inode_bitmap) {
-+              retval = ext2fs_get_free_blocks(fs, start_blk, last_blk,
-+                                              1, bmap, &new_blk);
-+              if (retval == EXT2_ET_BLOCK_ALLOC_FAIL) 
-+                      retval = ext2fs_get_free_blocks(fs, group_blk,
-+                                      last_blk, 1, bmap, &new_blk);
-+              if (retval)
-+                      return retval;
-+              ext2fs_mark_block_bitmap(bmap, new_blk);
-+              fs->group_desc[group].bg_inode_bitmap = new_blk;
-+      }
-+
-+      /*
-+       * Allocate the inode table
-+       */
-+      if (!fs->group_desc[group].bg_inode_table) {
-+              retval = ext2fs_get_free_blocks(fs, group_blk, last_blk,
-+                                              fs->inode_blocks_per_group,
-+                                              bmap, &new_blk);
-+              if (retval)
-+                      return retval;
-+              for (j=0, blk = new_blk;
-+                   j < fs->inode_blocks_per_group;
-+                   j++, blk++)
-+                      ext2fs_mark_block_bitmap(bmap, blk);
-+              fs->group_desc[group].bg_inode_table = new_blk;
-+      }
-+
-+      
-+      return 0;
-+}
-+
-+      
-+
-+errcode_t ext2fs_allocate_tables(ext2_filsys fs)
-+{
-+      errcode_t       retval;
-+      dgrp_t          i;
-+
-+      for (i = 0; i < fs->group_desc_count; i++) {
-+              retval = ext2fs_allocate_group_table(fs, i, fs->block_map);
-+              if (retval)
-+                      return retval;
-+      }
-+      return 0;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/badblocks.c busybox/e2fsprogs/ext2fs/badblocks.c
---- busybox-1.00/e2fsprogs/ext2fs/badblocks.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/badblocks.c       2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,327 @@
-+/*
-+ * badblocks.c --- routines to manipulate the bad block structure
-+ * 
-+ * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+/*
-+ * Helper function for making a badblocks list
-+ */
-+static errcode_t make_u32_list(int size, int num, __u32 *list,
-+                             ext2_u32_list *ret)
-+{
-+      ext2_u32_list   bb;
-+      errcode_t       retval;
-+      
-+      retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_list), &bb);
-+      if (retval)
-+              return retval;
-+      memset(bb, 0, sizeof(struct ext2_struct_u32_list));
-+      bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
-+      bb->size = size ? size : 10;
-+      bb->num = num;
-+      retval = ext2fs_get_mem(bb->size * sizeof(blk_t), &bb->list);
-+      if (!bb->list) {
-+              ext2fs_free_mem(&bb);
-+              return retval;
-+      }
-+      if (list)
-+              memcpy(bb->list, list, bb->size * sizeof(blk_t));
-+      else
-+              memset(bb->list, 0, bb->size * sizeof(blk_t));
-+      *ret = bb;
-+      return 0;
-+}
-+      
-+
-+/*
-+ * This procedure creates an empty u32 list.
-+ */
-+errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size)
-+{
-+      return make_u32_list(size, 0, 0, ret);
-+}
-+
-+/*
-+ * This procedure creates an empty badblocks list.
-+ */
-+errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
-+{
-+      return make_u32_list(size, 0, 0, (ext2_badblocks_list *) ret);
-+}
-+
-+
-+/*
-+ * This procedure copies a badblocks list
-+ */
-+errcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest)
-+{
-+      errcode_t       retval;
-+      
-+      retval = make_u32_list(src->size, src->num, src->list, dest);
-+      if (retval)
-+              return retval;
-+      (*dest)->badblocks_flags = src->badblocks_flags;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
-+                              ext2_badblocks_list *dest)
-+{
-+      return ext2fs_u32_copy((ext2_u32_list) src,
-+                             (ext2_u32_list *) dest);
-+}
-+
-+/*
-+ * This procedure frees a badblocks list.
-+ *
-+ * (note: moved to closefs.c)
-+ */
-+
-+
-+/*
-+ * This procedure adds a block to a badblocks list.
-+ */
-+errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk)
-+{
-+      errcode_t       retval;
-+      int             i, j;
-+      unsigned long   old_size;
-+
-+      EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
-+
-+      if (bb->num >= bb->size) {
-+              old_size = bb->size * sizeof(__u32);
-+              bb->size += 100;
-+              retval = ext2fs_resize_mem(old_size, bb->size * sizeof(__u32),
-+                                         &bb->list);
-+              if (retval) {
-+                      bb->size -= 100;
-+                      return retval;
-+              }
-+      }
-+
-+      /*
-+       * Add special case code for appending to the end of the list
-+       */
-+      i = bb->num-1;
-+      if ((bb->num != 0) && (bb->list[i] == blk))
-+              return 0;
-+      if ((bb->num == 0) || (bb->list[i] < blk)) {
-+              bb->list[bb->num++] = blk;
-+              return 0;
-+      }
-+
-+      j = bb->num;
-+      for (i=0; i < bb->num; i++) {
-+              if (bb->list[i] == blk)
-+                      return 0;
-+              if (bb->list[i] > blk) {
-+                      j = i;
-+                      break;
-+              }
-+      }
-+      for (i=bb->num; i > j; i--)
-+              bb->list[i] = bb->list[i-1];
-+      bb->list[j] = blk;
-+      bb->num++;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
-+{
-+      return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk);
-+}
-+
-+/*
-+ * This procedure finds a particular block is on a badblocks
-+ * list.
-+ */
-+int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk)
-+{
-+      int     low, high, mid;
-+
-+      if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
-+              return -1;
-+
-+      if (bb->num == 0)
-+              return -1;
-+
-+      low = 0;
-+      high = bb->num-1;
-+      if (blk == bb->list[low])
-+              return low;
-+      if (blk == bb->list[high])
-+              return high;
-+
-+      while (low < high) {
-+              mid = (low+high)/2;
-+              if (mid == low || mid == high)
-+                      break;
-+              if (blk == bb->list[mid])
-+                      return mid;
-+              if (blk < bb->list[mid])
-+                      high = mid;
-+              else
-+                      low = mid;
-+      }
-+      return -1;
-+}
-+
-+/*
-+ * This procedure tests to see if a particular block is on a badblocks
-+ * list.
-+ */
-+int ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk)
-+{
-+      if (ext2fs_u32_list_find(bb, blk) < 0)
-+              return 0;
-+      else
-+              return 1;
-+}
-+
-+int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
-+{
-+      return ext2fs_u32_list_test((ext2_u32_list) bb, (__u32) blk);
-+}
-+
-+
-+/*
-+ * Remove a block from the badblock list
-+ */
-+int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk)
-+{
-+      int     remloc, i;
-+
-+      if (bb->num == 0)
-+              return -1;
-+
-+      remloc = ext2fs_u32_list_find(bb, blk);
-+      if (remloc < 0)
-+              return -1;
-+
-+      for (i = remloc ; i < bb->num-1; i++)
-+              bb->list[i] = bb->list[i+1];
-+      bb->num--;
-+      return 0;
-+}
-+
-+void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk)
-+{
-+      ext2fs_u32_list_del(bb, blk);
-+}
-+
-+errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
-+                                      ext2_u32_iterate *ret)
-+{
-+      ext2_u32_iterate iter;
-+      errcode_t               retval;
-+
-+      EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
-+
-+      retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_iterate), &iter);
-+      if (retval)
-+              return retval;
-+
-+      iter->magic = EXT2_ET_MAGIC_BADBLOCKS_ITERATE;
-+      iter->bb = bb;
-+      iter->ptr = 0;
-+      *ret = iter;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
-+                                            ext2_badblocks_iterate *ret)
-+{
-+      return ext2fs_u32_list_iterate_begin((ext2_u32_list) bb,
-+                                            (ext2_u32_iterate *) ret);
-+}
-+
-+
-+int ext2fs_u32_list_iterate(ext2_u32_iterate iter, __u32 *blk)
-+{
-+      ext2_u32_list   bb;
-+
-+      if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE)
-+              return 0;
-+
-+      bb = iter->bb;
-+
-+      if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
-+              return 0;
-+      
-+      if (iter->ptr < bb->num) {
-+              *blk = bb->list[iter->ptr++];
-+              return 1;
-+      } 
-+      *blk = 0;
-+      return 0;
-+}
-+
-+int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk)
-+{
-+      return ext2fs_u32_list_iterate((ext2_u32_iterate) iter,
-+                                     (__u32 *) blk);
-+}
-+
-+
-+void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter)
-+{
-+      if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE))
-+              return;
-+
-+      iter->bb = 0;
-+      ext2fs_free_mem(&iter);
-+}
-+
-+void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter)
-+{
-+      ext2fs_u32_list_iterate_end((ext2_u32_iterate) iter);
-+}
-+
-+
-+int ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2)
-+{
-+      EXT2_CHECK_MAGIC(bb1, EXT2_ET_MAGIC_BADBLOCKS_LIST);
-+      EXT2_CHECK_MAGIC(bb2, EXT2_ET_MAGIC_BADBLOCKS_LIST);
-+
-+      if (bb1->num != bb2->num)
-+              return 0;
-+
-+      if (memcmp(bb1->list, bb2->list, bb1->num * sizeof(blk_t)) != 0)
-+              return 0;
-+      return 1;
-+}
-+
-+int ext2fs_badblocks_equal(ext2_badblocks_list bb1, ext2_badblocks_list bb2)
-+{
-+      return ext2fs_u32_list_equal((ext2_u32_list) bb1,
-+                                   (ext2_u32_list) bb2);
-+}
-+
-+int ext2fs_u32_list_count(ext2_u32_list bb)
-+{
-+      return bb->num;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/bb_compat.c busybox/e2fsprogs/ext2fs/bb_compat.c
---- busybox-1.00/e2fsprogs/ext2fs/bb_compat.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/bb_compat.c       2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,63 @@
-+/*
-+ * bb_compat.c --- compatibility badblocks routines
-+ * 
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+errcode_t badblocks_list_create(badblocks_list *ret, int size)
-+{
-+      return ext2fs_badblocks_list_create(ret, size);
-+}
-+
-+void badblocks_list_free(badblocks_list bb)
-+{
-+      ext2fs_badblocks_list_free(bb);
-+}
-+
-+errcode_t badblocks_list_add(badblocks_list bb, blk_t blk)
-+{
-+      return ext2fs_badblocks_list_add(bb, blk);
-+}
-+
-+int badblocks_list_test(badblocks_list bb, blk_t blk)
-+{
-+      return ext2fs_badblocks_list_test(bb, blk);
-+}
-+
-+errcode_t badblocks_list_iterate_begin(badblocks_list bb,
-+                                     badblocks_iterate *ret)
-+{
-+      return ext2fs_badblocks_list_iterate_begin(bb, ret);
-+}
-+
-+int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk)
-+{
-+      return ext2fs_badblocks_list_iterate(iter, blk);
-+}
-+
-+void badblocks_list_iterate_end(badblocks_iterate iter)
-+{
-+      ext2fs_badblocks_list_iterate_end(iter);
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/bb_inode.c busybox/e2fsprogs/ext2fs/bb_inode.c
---- busybox-1.00/e2fsprogs/ext2fs/bb_inode.c   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/bb_inode.c        2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,267 @@
-+/*
-+ * bb_inode.c --- routines to update the bad block inode.
-+ * 
-+ * WARNING: This routine modifies a lot of state in the filesystem; if
-+ * this routine returns an error, the bad block inode may be in an
-+ * inconsistent state.
-+ * 
-+ * Copyright (C) 1994, 1995 Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct set_badblock_record {
-+      ext2_badblocks_iterate  bb_iter;
-+      int             bad_block_count;
-+      blk_t           *ind_blocks;
-+      int             max_ind_blocks;
-+      int             ind_blocks_size;
-+      int             ind_blocks_ptr;
-+      char            *block_buf;
-+      errcode_t       err;
-+};
-+
-+static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
-+                            e2_blkcnt_t blockcnt,
-+                            blk_t ref_block, int ref_offset,
-+                            void *priv_data);
-+static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
-+                              e2_blkcnt_t blockcnt,
-+                              blk_t ref_block, int ref_offset,
-+                              void *priv_data);
-+      
-+/*
-+ * Given a bad blocks bitmap, update the bad blocks inode to reflect
-+ * the map.
-+ */
-+errcode_t ext2fs_update_bb_inode(ext2_filsys fs, ext2_badblocks_list bb_list)
-+{
-+      errcode_t                       retval;
-+      struct set_badblock_record      rec;
-+      struct ext2_inode               inode;
-+      
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (!fs->block_map)
-+              return EXT2_ET_NO_BLOCK_BITMAP;
-+      
-+      rec.bad_block_count = 0;
-+      rec.ind_blocks_size = rec.ind_blocks_ptr = 0;
-+      rec.max_ind_blocks = 10;
-+      retval = ext2fs_get_mem(rec.max_ind_blocks * sizeof(blk_t),
-+                              &rec.ind_blocks);
-+      if (retval)
-+              return retval;
-+      memset(rec.ind_blocks, 0, rec.max_ind_blocks * sizeof(blk_t));
-+      retval = ext2fs_get_mem(fs->blocksize, &rec.block_buf);
-+      if (retval)
-+              goto cleanup;
-+      memset(rec.block_buf, 0, fs->blocksize);
-+      rec.err = 0;
-+      
-+      /*
-+       * First clear the old bad blocks (while saving the indirect blocks) 
-+       */
-+      retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO,
-+                                     BLOCK_FLAG_DEPTH_TRAVERSE, 0,
-+                                     clear_bad_block_proc, &rec);
-+      if (retval)
-+              goto cleanup;
-+      if (rec.err) {
-+              retval = rec.err;
-+              goto cleanup;
-+      }
-+      
-+      /*
-+       * Now set the bad blocks!
-+       *
-+       * First, mark the bad blocks as used.  This prevents a bad
-+       * block from being used as an indirecto block for the bad
-+       * block inode (!).
-+       */
-+      if (bb_list) {
-+              retval = ext2fs_badblocks_list_iterate_begin(bb_list,
-+                                                           &rec.bb_iter);
-+              if (retval)
-+                      goto cleanup;
-+              retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO,
-+                                             BLOCK_FLAG_APPEND, 0,
-+                                             set_bad_block_proc, &rec);
-+              ext2fs_badblocks_list_iterate_end(rec.bb_iter);
-+              if (retval) 
-+                      goto cleanup;
-+              if (rec.err) {
-+                      retval = rec.err;
-+                      goto cleanup;
-+              }
-+      }
-+      
-+      /*
-+       * Update the bad block inode's mod time and block count
-+       * field.  
-+       */
-+      retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
-+      if (retval)
-+              goto cleanup;
-+      
-+      inode.i_atime = inode.i_mtime = time(0);
-+      if (!inode.i_ctime)
-+              inode.i_ctime = time(0);
-+      inode.i_blocks = rec.bad_block_count * (fs->blocksize / 512);
-+      inode.i_size = rec.bad_block_count * fs->blocksize;
-+
-+      retval = ext2fs_write_inode(fs, EXT2_BAD_INO, &inode);
-+      if (retval)
-+              goto cleanup;
-+      
-+cleanup:
-+      ext2fs_free_mem(&rec.ind_blocks);
-+      ext2fs_free_mem(&rec.block_buf);
-+      return retval;
-+}
-+
-+/*
-+ * Helper function for update_bb_inode()
-+ *
-+ * Clear the bad blocks in the bad block inode, while saving the
-+ * indirect blocks.
-+ */
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int clear_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
-+                              e2_blkcnt_t blockcnt,
-+                              blk_t ref_block EXT2FS_ATTR((unused)),
-+                              int ref_offset EXT2FS_ATTR((unused)),
-+                              void *priv_data)
-+{
-+      struct set_badblock_record *rec = (struct set_badblock_record *)
-+              priv_data;
-+      errcode_t       retval;
-+      unsigned long   old_size;
-+
-+      if (!*block_nr)
-+              return 0;
-+
-+      /*
-+       * If the block number is outrageous, clear it and ignore it.
-+       */
-+      if (*block_nr >= fs->super->s_blocks_count ||
-+          *block_nr < fs->super->s_first_data_block) {
-+              *block_nr = 0;
-+              return BLOCK_CHANGED;
-+      }
-+
-+      if (blockcnt < 0) {
-+              if (rec->ind_blocks_size >= rec->max_ind_blocks) {
-+                      old_size = rec->max_ind_blocks * sizeof(blk_t);
-+                      rec->max_ind_blocks += 10;
-+                      retval = ext2fs_resize_mem(old_size, 
-+                                 rec->max_ind_blocks * sizeof(blk_t),
-+                                 &rec->ind_blocks);
-+                      if (retval) {
-+                              rec->max_ind_blocks -= 10;
-+                              rec->err = retval;
-+                              return BLOCK_ABORT;
-+                      }
-+              }
-+              rec->ind_blocks[rec->ind_blocks_size++] = *block_nr;
-+      }
-+
-+      /*
-+       * Mark the block as unused, and update accounting information
-+       */
-+      ext2fs_block_alloc_stats(fs, *block_nr, -1);
-+      
-+      *block_nr = 0;
-+      return BLOCK_CHANGED;
-+}
-+
-+      
-+/*
-+ * Helper function for update_bb_inode()
-+ *
-+ * Set the block list in the bad block inode, using the supplied bitmap.
-+ */
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int set_bad_block_proc(ext2_filsys fs, blk_t *block_nr,
-+                            e2_blkcnt_t blockcnt,
-+                            blk_t ref_block EXT2FS_ATTR((unused)),
-+                            int ref_offset EXT2FS_ATTR((unused)),
-+                            void *priv_data)
-+{
-+      struct set_badblock_record *rec = (struct set_badblock_record *)
-+              priv_data;
-+      errcode_t       retval;
-+      blk_t           blk;
-+
-+      if (blockcnt >= 0) {
-+              /*
-+               * Get the next bad block.
-+               */
-+              if (!ext2fs_badblocks_list_iterate(rec->bb_iter, &blk))
-+                      return BLOCK_ABORT;
-+              rec->bad_block_count++;
-+      } else {
-+              /*
-+               * An indirect block; fetch a block from the
-+               * previously used indirect block list.  The block
-+               * most be not marked as used; if so, get another one.
-+               * If we run out of reserved indirect blocks, allocate
-+               * a new one.
-+               */
-+      retry:
-+              if (rec->ind_blocks_ptr < rec->ind_blocks_size) {
-+                      blk = rec->ind_blocks[rec->ind_blocks_ptr++];
-+                      if (ext2fs_test_block_bitmap(fs->block_map, blk))
-+                              goto retry;
-+              } else {
-+                      retval = ext2fs_new_block(fs, 0, 0, &blk);
-+                      if (retval) {
-+                              rec->err = retval;
-+                              return BLOCK_ABORT;
-+                      }
-+              }
-+              retval = io_channel_write_blk(fs->io, blk, 1, rec->block_buf);
-+              if (retval) {
-+                      rec->err = retval;
-+                      return BLOCK_ABORT;
-+              }
-+      }
-+      
-+      /*
-+       * Update block counts
-+       */
-+      ext2fs_block_alloc_stats(fs, blk, +1);
-+      
-+      *block_nr = blk;
-+      return BLOCK_CHANGED;
-+}
-+
-+
-+
-+
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/bitmaps.c busybox/e2fsprogs/ext2fs/bitmaps.c
---- busybox-1.00/e2fsprogs/ext2fs/bitmaps.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/bitmaps.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,212 @@
-+/*
-+ * bitmaps.c --- routines to read, write, and manipulate the inode and
-+ * block bitmaps.
-+ *
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+static errcode_t make_bitmap(__u32 start, __u32 end, __u32 real_end,
-+                           const char *descr, char *init_map,
-+                           ext2fs_generic_bitmap *ret)
-+{
-+      ext2fs_generic_bitmap   bitmap;
-+      errcode_t               retval;
-+      size_t                  size;
-+
-+      retval = ext2fs_get_mem(sizeof(struct ext2fs_struct_generic_bitmap), 
-+                              &bitmap);
-+      if (retval)
-+              return retval;
-+
-+      bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
-+      bitmap->fs = NULL;
-+      bitmap->start = start;
-+      bitmap->end = end;
-+      bitmap->real_end = real_end;
-+      bitmap->base_error_code = EXT2_ET_BAD_GENERIC_MARK;
-+      if (descr) {
-+              retval = ext2fs_get_mem(strlen(descr)+1, &bitmap->description);
-+              if (retval) {
-+                      ext2fs_free_mem(&bitmap);
-+                      return retval;
-+              }
-+              strcpy(bitmap->description, descr);
-+      } else
-+              bitmap->description = 0;
-+
-+      size = (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1);
-+      retval = ext2fs_get_mem(size, &bitmap->bitmap);
-+      if (retval) {
-+              ext2fs_free_mem(&bitmap->description);
-+              ext2fs_free_mem(&bitmap);
-+              return retval;
-+      }
-+
-+      if (init_map)
-+              memcpy(bitmap->bitmap, init_map, size);
-+      else
-+              memset(bitmap->bitmap, 0, size);
-+      *ret = bitmap;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
-+                                       __u32 end,
-+                                       __u32 real_end,
-+                                       const char *descr,
-+                                       ext2fs_generic_bitmap *ret)
-+{
-+      return make_bitmap(start, end, real_end, descr, 0, ret);
-+}
-+
-+errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
-+                           ext2fs_generic_bitmap *dest)
-+{
-+      errcode_t               retval;
-+      ext2fs_generic_bitmap   new_map;
-+
-+      retval = make_bitmap(src->start, src->end, src->real_end,
-+                           src->description, src->bitmap, &new_map);
-+      if (retval)
-+              return retval;
-+      new_map->magic = src->magic;
-+      new_map->fs = src->fs;
-+      new_map->base_error_code = src->base_error_code;
-+      *dest = new_map;
-+      return 0;
-+}
-+
-+void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map)
-+{
-+      __u32   i, j;
-+
-+      for (i=map->end+1, j = i - map->start; i <= map->real_end; i++, j++)
-+              ext2fs_set_bit(j, map->bitmap);
-+
-+      return;
-+}     
-+
-+errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
-+                                     const char *descr,
-+                                     ext2fs_inode_bitmap *ret)
-+{
-+      ext2fs_inode_bitmap bitmap;
-+      errcode_t       retval;
-+      __u32           start, end, real_end;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      fs->write_bitmaps = ext2fs_write_bitmaps;
-+
-+      start = 1;
-+      end = fs->super->s_inodes_count;
-+      real_end = (EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count);
-+
-+      retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
-+                                              descr, &bitmap);
-+      if (retval)
-+              return retval;
-+      
-+      bitmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
-+      bitmap->fs = fs;
-+      bitmap->base_error_code = EXT2_ET_BAD_INODE_MARK;
-+      
-+      *ret = bitmap;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
-+                                     const char *descr,
-+                                     ext2fs_block_bitmap *ret)
-+{
-+      ext2fs_block_bitmap bitmap;
-+      errcode_t       retval;
-+      __u32           start, end, real_end;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      fs->write_bitmaps = ext2fs_write_bitmaps;
-+
-+      start = fs->super->s_first_data_block;
-+      end = fs->super->s_blocks_count-1;
-+      real_end = (EXT2_BLOCKS_PER_GROUP(fs->super)  
-+                  * fs->group_desc_count)-1 + start;
-+      
-+      retval = ext2fs_allocate_generic_bitmap(start, end, real_end,
-+                                              descr, &bitmap);
-+      if (retval)
-+              return retval;
-+
-+      bitmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
-+      bitmap->fs = fs;
-+      bitmap->base_error_code = EXT2_ET_BAD_BLOCK_MARK;
-+      
-+      *ret = bitmap;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
-+                                      ext2_ino_t end, ext2_ino_t *oend)
-+{
-+      EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
-+      
-+      if (end > bitmap->real_end)
-+              return EXT2_ET_FUDGE_INODE_BITMAP_END;
-+      if (oend)
-+              *oend = bitmap->end;
-+      bitmap->end = end;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
-+                                      blk_t end, blk_t *oend)
-+{
-+      EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
-+      
-+      if (end > bitmap->real_end)
-+              return EXT2_ET_FUDGE_BLOCK_BITMAP_END;
-+      if (oend)
-+              *oend = bitmap->end;
-+      bitmap->end = end;
-+      return 0;
-+}
-+
-+void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap)
-+{
-+      if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
-+              return;
-+
-+      memset(bitmap->bitmap, 0,
-+             (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
-+}
-+
-+void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap)
-+{
-+      if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
-+              return;
-+
-+      memset(bitmap->bitmap, 0,
-+             (size_t) (((bitmap->real_end - bitmap->start) / 8) + 1));
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/bitops.c busybox/e2fsprogs/ext2fs/bitops.c
---- busybox-1.00/e2fsprogs/ext2fs/bitops.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/bitops.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,91 @@
-+/*
-+ * bitops.c --- Bitmap frobbing code.  See bitops.h for the inlined
-+ *    routines.
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#ifndef _EXT2_HAVE_ASM_BITOPS_
-+
-+/*
-+ * For the benefit of those who are trying to port Linux to another
-+ * architecture, here are some C-language equivalents.  You should
-+ * recode these in the native assmebly language, if at all possible.
-+ *
-+ * C language equivalents written by Theodore Ts'o, 9/26/92.
-+ * Modified by Pete A. Zaitcev 7/14/95 to be portable to big endian
-+ * systems, as well as non-32 bit systems.
-+ */
-+
-+int ext2fs_set_bit(int nr,void * addr)
-+{
-+      int             mask, retval;
-+      unsigned char   *ADDR = (unsigned char *) addr;
-+
-+      ADDR += nr >> 3;
-+      mask = 1 << (nr & 0x07);
-+      retval = mask & *ADDR;
-+      *ADDR |= mask;
-+      return retval;
-+}
-+
-+int ext2fs_clear_bit(int nr, void * addr)
-+{
-+      int             mask, retval;
-+      unsigned char   *ADDR = (unsigned char *) addr;
-+
-+      ADDR += nr >> 3;
-+      mask = 1 << (nr & 0x07);
-+      retval = mask & *ADDR;
-+      *ADDR &= ~mask;
-+      return retval;
-+}
-+
-+int ext2fs_test_bit(int nr, const void * addr)
-+{
-+      int                     mask;
-+      const unsigned char     *ADDR = (const unsigned char *) addr;
-+
-+      ADDR += nr >> 3;
-+      mask = 1 << (nr & 0x07);
-+      return (mask & *ADDR);
-+}
-+
-+#endif        /* !_EXT2_HAVE_ASM_BITOPS_ */
-+
-+void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
-+                      const char *description)
-+{
-+#ifndef OMIT_COM_ERR
-+      if (description)
-+              com_err(0, errcode, "#%lu for %s", arg, description);
-+      else
-+              com_err(0, errcode, "#%lu", arg);
-+#endif
-+}
-+
-+void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
-+                          int code, unsigned long arg)
-+{
-+#ifndef OMIT_COM_ERR
-+      if (bitmap->description)
-+              com_err(0, bitmap->base_error_code+code,
-+                      "#%lu for %s", arg, bitmap->description);
-+      else
-+              com_err(0, bitmap->base_error_code + code, "#%lu", arg);
-+#endif
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/bitops.h busybox/e2fsprogs/ext2fs/bitops.h
---- busybox-1.00/e2fsprogs/ext2fs/bitops.h     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/bitops.h  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,617 @@
-+/*
-+ * bitops.h --- Bitmap frobbing code.  The byte swapping routines are
-+ *    also included here.
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ * i386 bitops operations taken from <asm/bitops.h>, Copyright 1992,
-+ * Linus Torvalds.
-+ */
-+
-+
-+extern int ext2fs_set_bit(int nr,void * addr);
-+extern int ext2fs_clear_bit(int nr, void * addr);
-+extern int ext2fs_test_bit(int nr, const void * addr);
-+extern __u16 ext2fs_swab16(__u16 val);
-+extern __u32 ext2fs_swab32(__u32 val);
-+
-+#ifdef WORDS_BIGENDIAN
-+#define ext2fs_cpu_to_le32(x) ext2fs_swab32((x))
-+#define ext2fs_le32_to_cpu(x) ext2fs_swab32((x))
-+#define ext2fs_cpu_to_le16(x) ext2fs_swab16((x))
-+#define ext2fs_le16_to_cpu(x) ext2fs_swab16((x))
-+#define ext2fs_cpu_to_be32(x) ((__u32)(x))
-+#define ext2fs_be32_to_cpu(x) ((__u32)(x))
-+#define ext2fs_cpu_to_be16(x) ((__u16)(x))
-+#define ext2fs_be16_to_cpu(x) ((__u16)(x))
-+#else
-+#define ext2fs_cpu_to_le32(x) ((__u32)(x))
-+#define ext2fs_le32_to_cpu(x) ((__u32)(x))
-+#define ext2fs_cpu_to_le16(x) ((__u16)(x))
-+#define ext2fs_le16_to_cpu(x) ((__u16)(x))
-+#define ext2fs_cpu_to_be32(x) ext2fs_swab32((x))
-+#define ext2fs_be32_to_cpu(x) ext2fs_swab32((x))
-+#define ext2fs_cpu_to_be16(x) ext2fs_swab16((x))
-+#define ext2fs_be16_to_cpu(x) ext2fs_swab16((x))
-+#endif
-+
-+/*
-+ * EXT2FS bitmap manipulation routines.
-+ */
-+
-+/* Support for sending warning messages from the inline subroutines */
-+extern const char *ext2fs_block_string;
-+extern const char *ext2fs_inode_string;
-+extern const char *ext2fs_mark_string;
-+extern const char *ext2fs_unmark_string;
-+extern const char *ext2fs_test_string;
-+extern void ext2fs_warn_bitmap(errcode_t errcode, unsigned long arg,
-+                             const char *description);
-+extern void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap,
-+                              int code, unsigned long arg);
-+
-+extern int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
-+extern int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
-+                                     blk_t block);
-+extern int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, blk_t block);
-+
-+extern int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
-+extern int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+                                     ext2_ino_t inode);
-+extern int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, ext2_ino_t inode);
-+
-+extern void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
-+                                        blk_t block);
-+extern void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
-+                                          blk_t block);
-+extern int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
-+                                       blk_t block);
-+
-+extern void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+                                        ext2_ino_t inode);
-+extern void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+                                          ext2_ino_t inode);
-+extern int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+                                       ext2_ino_t inode);
-+extern blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap);
-+extern ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap);
-+extern blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap);
-+extern ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap);
-+
-+extern void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                         blk_t block, int num);
-+extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                           blk_t block, int num);
-+extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                        blk_t block, int num);
-+extern void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                              blk_t block, int num);
-+extern void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                                blk_t block, int num);
-+extern int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                             blk_t block, int num);
-+extern void ext2fs_set_bitmap_padding(ext2fs_generic_bitmap map);
-+
-+/* These two routines moved to gen_bitmap.c */
-+extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
-+                                       __u32 bitno);
-+extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
-+                                         blk_t bitno);
-+/*
-+ * The inline routines themselves...
-+ * 
-+ * If NO_INLINE_FUNCS is defined, then we won't try to do inline
-+ * functions at all; they will be included as normal functions in
-+ * inline.c
-+ */
-+#ifdef NO_INLINE_FUNCS
-+#if (defined(__GNUC__) && (defined(__i386__) || defined(__i486__) || \
-+                         defined(__i586__) || defined(__mc68000__) || \
-+                         defined(__sparc__)))
-+      /* This prevents bitops.c from trying to include the C */
-+      /* function version of these functions */
-+#define _EXT2_HAVE_ASM_BITOPS_
-+#endif
-+#endif /* NO_INLINE_FUNCS */
-+
-+#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
-+#ifdef INCLUDE_INLINE_FUNCS
-+#define _INLINE_ extern
-+#else
-+#ifdef __GNUC__
-+#define _INLINE_ extern __inline__
-+#else                         /* For Watcom C */
-+#define _INLINE_ extern inline
-+#endif
-+#endif
-+
-+#if ((defined __GNUC__) && !defined(_EXT2_USE_C_VERSIONS_) && \
-+     (defined(__i386__) || defined(__i486__) || defined(__i586__)))
-+
-+#define _EXT2_HAVE_ASM_BITOPS_
-+#define _EXT2_HAVE_ASM_SWAB_
-+#define _EXT2_HAVE_ASM_FINDBIT_
-+
-+/*
-+ * These are done by inline assembly for speed reasons.....
-+ *
-+ * All bitoperations return 0 if the bit was cleared before the
-+ * operation and != 0 if it was not.  Bit 0 is the LSB of addr; bit 32
-+ * is the LSB of (addr+1).
-+ */
-+
-+/*
-+ * Some hacks to defeat gcc over-optimizations..
-+ */
-+struct __dummy_h { unsigned long a[100]; };
-+#define EXT2FS_ADDR (*(struct __dummy_h *) addr)
-+#define EXT2FS_CONST_ADDR (*(const struct __dummy_h *) addr)  
-+
-+_INLINE_ int ext2fs_set_bit(int nr, void * addr)
-+{
-+      int oldbit;
-+
-+      __asm__ __volatile__("btsl %2,%1\n\tsbbl %0,%0"
-+              :"=r" (oldbit),"=m" (EXT2FS_ADDR)
-+              :"r" (nr));
-+      return oldbit;
-+}
-+
-+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
-+{
-+      int oldbit;
-+
-+      __asm__ __volatile__("btrl %2,%1\n\tsbbl %0,%0"
-+              :"=r" (oldbit),"=m" (EXT2FS_ADDR)
-+              :"r" (nr));
-+      return oldbit;
-+}
-+
-+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
-+{
-+      int oldbit;
-+
-+      __asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
-+              :"=r" (oldbit)
-+              :"m" (EXT2FS_CONST_ADDR),"r" (nr));
-+      return oldbit;
-+}
-+
-+#if 0
-+_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
-+{
-+      int d0, d1, d2;
-+      int res;
-+
-+      if (!size)
-+              return 0;
-+      /* This looks at memory. Mark it volatile to tell gcc not to move it around */
-+      __asm__ __volatile__(
-+              "cld\n\t"                            
-+              "xorl %%eax,%%eax\n\t"
-+              "xorl %%edx,%%edx\n\t"
-+              "repe; scasl\n\t"
-+              "je 1f\n\t"
-+              "movl -4(%%edi),%%eax\n\t"
-+              "subl $4,%%edi\n\t"
-+              "bsfl %%eax,%%edx\n"
-+              "1:\tsubl %%esi,%%edi\n\t"
-+              "shll $3,%%edi\n\t"
-+              "addl %%edi,%%edx"
-+              :"=d" (res), "=&c" (d0), "=&D" (d1), "=&a" (d2)
-+              :"1" ((size + 31) >> 5), "2" (addr), "S" (addr));
-+      return res;
-+}
-+
-+_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
-+{
-+      unsigned long * p = ((unsigned long *) addr) + (offset >> 5);
-+      int set = 0, bit = offset & 31, res;
-+      
-+      if (bit) {
-+              /*
-+               * Look for zero in first byte
-+               */
-+              __asm__("bsfl %1,%0\n\t"
-+                      "jne 1f\n\t"
-+                      "movl $32, %0\n"
-+                      "1:"
-+                      : "=r" (set)
-+                      : "r" (*p >> bit));
-+              if (set < (32 - bit))
-+                      return set + offset;
-+              set = 32 - bit;
-+              p++;
-+      }
-+      /*
-+       * No bit found yet, search remaining full bytes for a bit
-+       */
-+      res = ext2fs_find_first_bit_set(p, size - 32 * (p - (unsigned long *) addr));
-+      return (offset + set + res);
-+}
-+#endif
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+_INLINE_ __u32 ext2fs_swab32(__u32 val)
-+{
-+#ifdef EXT2FS_REQUIRE_486
-+      __asm__("bswap %0" : "=r" (val) : "0" (val));
-+#else
-+      __asm__("xchgb %b0,%h0\n\t"     /* swap lower bytes     */
-+              "rorl $16,%0\n\t"       /* swap words           */
-+              "xchgb %b0,%h0"         /* swap higher bytes    */
-+              :"=q" (val)
-+              : "0" (val));
-+#endif
-+      return val;
-+}
-+
-+_INLINE_ __u16 ext2fs_swab16(__u16 val)
-+{
-+      __asm__("xchgb %b0,%h0"         /* swap bytes           */ \
-+              : "=q" (val) \
-+              :  "0" (val)); \
-+              return val;
-+}
-+#endif
-+
-+#undef EXT2FS_ADDR
-+
-+#endif        /* i386 */
-+
-+#ifdef __mc68000__
-+
-+#define _EXT2_HAVE_ASM_BITOPS_
-+
-+_INLINE_ int ext2fs_set_bit(int nr,void * addr)
-+{
-+      char retval;
-+
-+      __asm__ __volatile__ ("bfset %2@{%1:#1}; sne %0"
-+           : "=d" (retval) : "d" (nr^7), "a" (addr));
-+
-+      return retval;
-+}
-+
-+_INLINE_ int ext2fs_clear_bit(int nr, void * addr)
-+{
-+      char retval;
-+
-+      __asm__ __volatile__ ("bfclr %2@{%1:#1}; sne %0"
-+           : "=d" (retval) : "d" (nr^7), "a" (addr));
-+
-+      return retval;
-+}
-+
-+_INLINE_ int ext2fs_test_bit(int nr, const void * addr)
-+{
-+      char retval;
-+
-+      __asm__ __volatile__ ("bftst %2@{%1:#1}; sne %0"
-+           : "=d" (retval) : "d" (nr^7), "a" (addr));
-+
-+      return retval;
-+}
-+
-+#endif /* __mc68000__ */
-+
-+
-+#if !defined(_EXT2_HAVE_ASM_SWAB_) && defined(EXT2FS_ENABLE_SWAPFS)
-+
-+_INLINE_ __u16 ext2fs_swab16(__u16 val)
-+{
-+      return (val >> 8) | (val << 8);
-+}
-+
-+_INLINE_ __u32 ext2fs_swab32(__u32 val)
-+{
-+      return ((val>>24) | ((val>>8)&0xFF00) |
-+              ((val<<8)&0xFF0000) | (val<<24));
-+}
-+
-+#endif /* !_EXT2_HAVE_ASM_SWAB */
-+
-+#if !defined(_EXT2_HAVE_ASM_FINDBIT_)
-+_INLINE_ int ext2fs_find_first_bit_set(void * addr, unsigned size)
-+{
-+      char    *cp = (unsigned char *) addr;
-+      int     res = 0, d0;
-+
-+      if (!size)
-+              return 0;
-+
-+      while ((size > res) && (*cp == 0)) {
-+              cp++;
-+              res += 8;
-+      }
-+      d0 = ffs(*cp);
-+      if (d0 == 0)
-+              return size;
-+      
-+      return res + d0 - 1;
-+}
-+
-+_INLINE_ int ext2fs_find_next_bit_set (void * addr, int size, int offset)
-+{
-+      unsigned char * p;
-+      int set = 0, bit = offset & 7, res = 0, d0;
-+      
-+      res = offset >> 3;
-+      p = ((unsigned char *) addr) + res;
-+      
-+      if (bit) {
-+              set = ffs(*p & ~((1 << bit) - 1));
-+              if (set)
-+                      return (offset & ~7) + set - 1;
-+              p++;
-+              res += 8;
-+      }
-+      while ((size > res) && (*p == 0)) {
-+              p++;
-+              res += 8;
-+      }
-+      d0 = ffs(*p);
-+      if (d0 == 0)
-+              return size;
-+
-+      return (res + d0 - 1);
-+}
-+#endif        
-+
-+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
-+                                      blk_t bitno);
-+
-+_INLINE_ int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap,
-+                                      blk_t bitno)
-+{
-+      if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
-+              ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno);
-+              return 0;
-+      }
-+      return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap,
-+                                     blk_t block)
-+{
-+      return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap)
-+                                     bitmap,
-+                                        block);
-+}
-+
-+_INLINE_ int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
-+                                       blk_t block)
-+{
-+      return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
-+                                          block);
-+}
-+
-+_INLINE_ int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap,
-+                                     blk_t block)
-+{
-+      return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
-+                                        block);
-+}
-+
-+_INLINE_ int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+                                     ext2_ino_t inode)
-+{
-+      return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
-+                                        inode);
-+}
-+
-+_INLINE_ int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+                                       ext2_ino_t inode)
-+{
-+      return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
-+                                   inode);
-+}
-+
-+_INLINE_ int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+                                     ext2_ino_t inode)
-+{
-+      return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, 
-+                                        inode);
-+}
-+
-+_INLINE_ void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap,
-+                                          blk_t block)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+      if ((block < bitmap->start) || (block > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
-+                                 bitmap->description);
-+              return;
-+      }
-+#endif        
-+      ext2fs_set_bit(block - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap,
-+                                            blk_t block)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+      if ((block < bitmap->start) || (block > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK,
-+                                 block, bitmap->description);
-+              return;
-+      }
-+#endif
-+      ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap,
-+                                          blk_t block)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+      if ((block < bitmap->start) || (block > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
-+                                 block, bitmap->description);
-+              return 0;
-+      }
-+#endif
-+      return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+                                          ext2_ino_t inode)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+      if ((inode < bitmap->start) || (inode > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK,
-+                                 inode, bitmap->description);
-+              return;
-+      }
-+#endif
-+      ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+                                            ext2_ino_t inode)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+      if ((inode < bitmap->start) || (inode > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK,
-+                                 inode, bitmap->description);
-+              return;
-+      }
-+#endif
-+      ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap,
-+                                         ext2_ino_t inode)
-+{
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+      if ((inode < bitmap->start) || (inode > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST,
-+                                 inode, bitmap->description);
-+              return 0;
-+      }
-+#endif
-+      return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap)
-+{
-+      return bitmap->start;
-+}
-+
-+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap)
-+{
-+      return bitmap->start;
-+}
-+
-+_INLINE_ blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap)
-+{
-+      return bitmap->end;
-+}
-+
-+_INLINE_ ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap)
-+{
-+      return bitmap->end;
-+}
-+
-+_INLINE_ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                          blk_t block, int num)
-+{
-+      int     i;
-+
-+      if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
-+                                 block, bitmap->description);
-+              return 0;
-+      }
-+      for (i=0; i < num; i++) {
-+              if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
-+                      return 0;
-+      }
-+      return 1;
-+}
-+
-+_INLINE_ int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                               blk_t block, int num)
-+{
-+      int     i;
-+
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+      if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST,
-+                                 block, bitmap->description);
-+              return 0;
-+      }
-+#endif
-+      for (i=0; i < num; i++) {
-+              if (ext2fs_fast_test_block_bitmap(bitmap, block+i))
-+                      return 0;
-+      }
-+      return 1;
-+}
-+
-+_INLINE_ void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                           blk_t block, int num)
-+{
-+      int     i;
-+      
-+      if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
-+                                 bitmap->description);
-+              return;
-+      }
-+      for (i=0; i < num; i++)
-+              ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                                blk_t block, int num)
-+{
-+      int     i;
-+      
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+      if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block,
-+                                 bitmap->description);
-+              return;
-+      }
-+#endif        
-+      for (i=0; i < num; i++)
-+              ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                             blk_t block, int num)
-+{
-+      int     i;
-+      
-+      if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
-+                                 bitmap->description);
-+              return;
-+      }
-+      for (i=0; i < num; i++)
-+              ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
-+}
-+
-+_INLINE_ void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
-+                                                  blk_t block, int num)
-+{
-+      int     i;
-+      
-+#ifdef EXT2FS_DEBUG_FAST_OPS
-+      if ((block < bitmap->start) || (block+num-1 > bitmap->end)) {
-+              ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block,
-+                                 bitmap->description);
-+              return;
-+      }
-+#endif        
-+      for (i=0; i < num; i++)
-+              ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap);
-+}
-+#undef _INLINE_
-+#endif
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/block.c busybox/e2fsprogs/ext2fs/block.c
---- busybox-1.00/e2fsprogs/ext2fs/block.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/block.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,437 @@
-+/*
-+ * block.c --- iterate over all blocks in an inode
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct block_context {
-+      ext2_filsys     fs;
-+      int (*func)(ext2_filsys fs,
-+                  blk_t       *blocknr,
-+                  e2_blkcnt_t bcount,
-+                  blk_t       ref_blk,
-+                  int         ref_offset,
-+                  void        *priv_data);
-+      e2_blkcnt_t     bcount;
-+      int             bsize;
-+      int             flags;
-+      errcode_t       errcode;
-+      char    *ind_buf;
-+      char    *dind_buf;
-+      char    *tind_buf;
-+      void    *priv_data;
-+};
-+
-+static int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
-+                           int ref_offset, struct block_context *ctx)
-+{
-+      int     ret = 0, changed = 0;
-+      int     i, flags, limit, offset;
-+      blk_t   *block_nr;
-+
-+      limit = ctx->fs->blocksize >> 2;
-+      if (!(ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
-+          !(ctx->flags & BLOCK_FLAG_DATA_ONLY))
-+              ret = (*ctx->func)(ctx->fs, ind_block,
-+                                 BLOCK_COUNT_IND, ref_block,
-+                                 ref_offset, ctx->priv_data);
-+      if (!*ind_block || (ret & BLOCK_ABORT)) {
-+              ctx->bcount += limit;
-+              return ret;
-+      }
-+      if (*ind_block >= ctx->fs->super->s_blocks_count ||
-+          *ind_block < ctx->fs->super->s_first_data_block) {
-+              ctx->errcode = EXT2_ET_BAD_IND_BLOCK;
-+              ret |= BLOCK_ERROR;
-+              return ret;
-+      }
-+      ctx->errcode = ext2fs_read_ind_block(ctx->fs, *ind_block, 
-+                                           ctx->ind_buf);
-+      if (ctx->errcode) {
-+              ret |= BLOCK_ERROR;
-+              return ret;
-+      }
-+
-+      block_nr = (blk_t *) ctx->ind_buf;
-+      offset = 0;
-+      if (ctx->flags & BLOCK_FLAG_APPEND) {
-+              for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) {
-+                      flags = (*ctx->func)(ctx->fs, block_nr, ctx->bcount,
-+                                           *ind_block, offset, 
-+                                           ctx->priv_data);
-+                      changed |= flags;
-+                      if (flags & BLOCK_ABORT) {
-+                              ret |= BLOCK_ABORT;
-+                              break;
-+                      }
-+                      offset += sizeof(blk_t);
-+              }
-+      } else {
-+              for (i = 0; i < limit; i++, ctx->bcount++, block_nr++) {
-+                      if (*block_nr == 0)
-+                              continue;
-+                      flags = (*ctx->func)(ctx->fs, block_nr, ctx->bcount,
-+                                           *ind_block, offset, 
-+                                           ctx->priv_data);
-+                      changed |= flags;
-+                      if (flags & BLOCK_ABORT) {
-+                              ret |= BLOCK_ABORT;
-+                              break;
-+                      }
-+                      offset += sizeof(blk_t);
-+              }
-+      }
-+      if (changed & BLOCK_CHANGED) {
-+              ctx->errcode = ext2fs_write_ind_block(ctx->fs, *ind_block,
-+                                                    ctx->ind_buf);
-+              if (ctx->errcode)
-+                      ret |= BLOCK_ERROR | BLOCK_ABORT;
-+      }
-+      if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
-+          !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
-+          !(ret & BLOCK_ABORT))
-+              ret |= (*ctx->func)(ctx->fs, ind_block,
-+                                  BLOCK_COUNT_IND, ref_block,
-+                                  ref_offset, ctx->priv_data);
-+      return ret;
-+}
-+      
-+static int block_iterate_dind(blk_t *dind_block, blk_t ref_block,
-+                            int ref_offset, struct block_context *ctx)
-+{
-+      int     ret = 0, changed = 0;
-+      int     i, flags, limit, offset;
-+      blk_t   *block_nr;
-+
-+      limit = ctx->fs->blocksize >> 2;
-+      if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
-+                          BLOCK_FLAG_DATA_ONLY)))
-+              ret = (*ctx->func)(ctx->fs, dind_block,
-+                                 BLOCK_COUNT_DIND, ref_block,
-+                                 ref_offset, ctx->priv_data);
-+      if (!*dind_block || (ret & BLOCK_ABORT)) {
-+              ctx->bcount += limit*limit;
-+              return ret;
-+      }
-+      if (*dind_block >= ctx->fs->super->s_blocks_count ||
-+          *dind_block < ctx->fs->super->s_first_data_block) {
-+              ctx->errcode = EXT2_ET_BAD_DIND_BLOCK;
-+              ret |= BLOCK_ERROR;
-+              return ret;
-+      }
-+      ctx->errcode = ext2fs_read_ind_block(ctx->fs, *dind_block, 
-+                                           ctx->dind_buf);
-+      if (ctx->errcode) {
-+              ret |= BLOCK_ERROR;
-+              return ret;
-+      }
-+
-+      block_nr = (blk_t *) ctx->dind_buf;
-+      offset = 0;
-+      if (ctx->flags & BLOCK_FLAG_APPEND) {
-+              for (i = 0; i < limit; i++, block_nr++) {
-+                      flags = block_iterate_ind(block_nr,
-+                                                *dind_block, offset,
-+                                                ctx);
-+                      changed |= flags;
-+                      if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+                              ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
-+                              break;
-+                      }
-+                      offset += sizeof(blk_t);
-+              }
-+      } else {
-+              for (i = 0; i < limit; i++, block_nr++) {
-+                      if (*block_nr == 0) {
-+                              ctx->bcount += limit;
-+                              continue;
-+                      }
-+                      flags = block_iterate_ind(block_nr,
-+                                                *dind_block, offset,
-+                                                ctx);
-+                      changed |= flags;
-+                      if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+                              ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
-+                              break;
-+                      }
-+                      offset += sizeof(blk_t);
-+              }
-+      }
-+      if (changed & BLOCK_CHANGED) {
-+              ctx->errcode = ext2fs_write_ind_block(ctx->fs, *dind_block,
-+                                                    ctx->dind_buf);
-+              if (ctx->errcode)
-+                      ret |= BLOCK_ERROR | BLOCK_ABORT;
-+      }
-+      if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
-+          !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
-+          !(ret & BLOCK_ABORT))
-+              ret |= (*ctx->func)(ctx->fs, dind_block,
-+                                  BLOCK_COUNT_DIND, ref_block,
-+                                  ref_offset, ctx->priv_data);
-+      return ret;
-+}
-+      
-+static int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
-+                            int ref_offset, struct block_context *ctx)
-+{
-+      int     ret = 0, changed = 0;
-+      int     i, flags, limit, offset;
-+      blk_t   *block_nr;
-+
-+      limit = ctx->fs->blocksize >> 2;
-+      if (!(ctx->flags & (BLOCK_FLAG_DEPTH_TRAVERSE |
-+                          BLOCK_FLAG_DATA_ONLY)))
-+              ret = (*ctx->func)(ctx->fs, tind_block,
-+                                 BLOCK_COUNT_TIND, ref_block,
-+                                 ref_offset, ctx->priv_data);
-+      if (!*tind_block || (ret & BLOCK_ABORT)) {
-+              ctx->bcount += limit*limit*limit;
-+              return ret;
-+      }
-+      if (*tind_block >= ctx->fs->super->s_blocks_count ||
-+          *tind_block < ctx->fs->super->s_first_data_block) {
-+              ctx->errcode = EXT2_ET_BAD_TIND_BLOCK;
-+              ret |= BLOCK_ERROR;
-+              return ret;
-+      }
-+      ctx->errcode = ext2fs_read_ind_block(ctx->fs, *tind_block, 
-+                                           ctx->tind_buf);
-+      if (ctx->errcode) {
-+              ret |= BLOCK_ERROR;
-+              return ret;
-+      }
-+
-+      block_nr = (blk_t *) ctx->tind_buf;
-+      offset = 0;
-+      if (ctx->flags & BLOCK_FLAG_APPEND) {
-+              for (i = 0; i < limit; i++, block_nr++) {
-+                      flags = block_iterate_dind(block_nr,
-+                                                 *tind_block,
-+                                                 offset, ctx);
-+                      changed |= flags;
-+                      if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+                              ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
-+                              break;
-+                      }
-+                      offset += sizeof(blk_t);
-+              }
-+      } else {
-+              for (i = 0; i < limit; i++, block_nr++) {
-+                      if (*block_nr == 0) {
-+                              ctx->bcount += limit*limit;
-+                              continue;
-+                      }
-+                      flags = block_iterate_dind(block_nr,
-+                                                 *tind_block,
-+                                                 offset, ctx);
-+                      changed |= flags;
-+                      if (flags & (BLOCK_ABORT | BLOCK_ERROR)) {
-+                              ret |= flags & (BLOCK_ABORT | BLOCK_ERROR);
-+                              break;
-+                      }
-+                      offset += sizeof(blk_t);
-+              }
-+      }
-+      if (changed & BLOCK_CHANGED) {
-+              ctx->errcode = ext2fs_write_ind_block(ctx->fs, *tind_block,
-+                                                    ctx->tind_buf);
-+              if (ctx->errcode)
-+                      ret |= BLOCK_ERROR | BLOCK_ABORT;
-+      }
-+      if ((ctx->flags & BLOCK_FLAG_DEPTH_TRAVERSE) &&
-+          !(ctx->flags & BLOCK_FLAG_DATA_ONLY) &&
-+          !(ret & BLOCK_ABORT))
-+              ret |= (*ctx->func)(ctx->fs, tind_block,
-+                                  BLOCK_COUNT_TIND, ref_block,
-+                                  ref_offset, ctx->priv_data);
-+      
-+      return ret;
-+}
-+      
-+errcode_t ext2fs_block_iterate2(ext2_filsys fs,
-+                              ext2_ino_t ino,
-+                              int     flags,
-+                              char *block_buf,
-+                              int (*func)(ext2_filsys fs,
-+                                          blk_t       *blocknr,
-+                                          e2_blkcnt_t blockcnt,
-+                                          blk_t       ref_blk,
-+                                          int         ref_offset,
-+                                          void        *priv_data),
-+                              void *priv_data)
-+{
-+      int     i;
-+      int     got_inode = 0;
-+      int     ret = 0;
-+      blk_t   blocks[EXT2_N_BLOCKS];  /* directory data blocks */
-+      struct ext2_inode inode;
-+      errcode_t       retval;
-+      struct block_context ctx;
-+      int     limit;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      /*
-+       * Check to see if we need to limit large files
-+       */
-+      if (flags & BLOCK_FLAG_NO_LARGE) {
-+              ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
-+              if (ctx.errcode)
-+                      return ctx.errcode;
-+              got_inode = 1;
-+              if (!LINUX_S_ISDIR(inode.i_mode) &&
-+                  (inode.i_size_high != 0))
-+                      return EXT2_ET_FILE_TOO_BIG;
-+      }
-+
-+      retval = ext2fs_get_blocks(fs, ino, blocks);
-+      if (retval)
-+              return retval;
-+
-+      limit = fs->blocksize >> 2;
-+
-+      ctx.fs = fs;
-+      ctx.func = func;
-+      ctx.priv_data = priv_data;
-+      ctx.flags = flags;
-+      ctx.bcount = 0;
-+      if (block_buf) {
-+              ctx.ind_buf = block_buf;
-+      } else {
-+              retval = ext2fs_get_mem(fs->blocksize * 3, &ctx.ind_buf);
-+              if (retval)
-+                      return retval;
-+      }
-+      ctx.dind_buf = ctx.ind_buf + fs->blocksize;
-+      ctx.tind_buf = ctx.dind_buf + fs->blocksize;
-+
-+      /*
-+       * Iterate over the HURD translator block (if present)
-+       */
-+      if ((fs->super->s_creator_os == EXT2_OS_HURD) &&
-+          !(flags & BLOCK_FLAG_DATA_ONLY)) {
-+              ctx.errcode = ext2fs_read_inode(fs, ino, &inode);
-+              if (ctx.errcode)
-+                      goto abort_exit;
-+              got_inode = 1;
-+              if (inode.osd1.hurd1.h_i_translator) {
-+                      ret |= (*ctx.func)(fs,
-+                                         &inode.osd1.hurd1.h_i_translator,
-+                                         BLOCK_COUNT_TRANSLATOR,
-+                                         0, 0, priv_data);
-+                      if (ret & BLOCK_ABORT)
-+                              goto abort_exit;
-+              }
-+      }
-+      
-+      /*
-+       * Iterate over normal data blocks
-+       */
-+      for (i = 0; i < EXT2_NDIR_BLOCKS ; i++, ctx.bcount++) {
-+              if (blocks[i] || (flags & BLOCK_FLAG_APPEND)) {
-+                      ret |= (*ctx.func)(fs, &blocks[i],
-+                                          ctx.bcount, 0, i, priv_data);
-+                      if (ret & BLOCK_ABORT)
-+                              goto abort_exit;
-+              }
-+      }
-+      if (*(blocks + EXT2_IND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
-+              ret |= block_iterate_ind(blocks + EXT2_IND_BLOCK,
-+                                       0, EXT2_IND_BLOCK, &ctx);
-+              if (ret & BLOCK_ABORT)
-+                      goto abort_exit;
-+      } else
-+              ctx.bcount += limit;
-+      if (*(blocks + EXT2_DIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
-+              ret |= block_iterate_dind(blocks + EXT2_DIND_BLOCK,
-+                                        0, EXT2_DIND_BLOCK, &ctx);
-+              if (ret & BLOCK_ABORT)
-+                      goto abort_exit;
-+      } else
-+              ctx.bcount += limit * limit;
-+      if (*(blocks + EXT2_TIND_BLOCK) || (flags & BLOCK_FLAG_APPEND)) {
-+              ret |= block_iterate_tind(blocks + EXT2_TIND_BLOCK,
-+                                        0, EXT2_TIND_BLOCK, &ctx);
-+              if (ret & BLOCK_ABORT)
-+                      goto abort_exit;
-+      }
-+
-+abort_exit:
-+      if (ret & BLOCK_CHANGED) {
-+              if (!got_inode) {
-+                      retval = ext2fs_read_inode(fs, ino, &inode);
-+                      if (retval)
-+                              return retval;
-+              }
-+              for (i=0; i < EXT2_N_BLOCKS; i++)
-+                      inode.i_block[i] = blocks[i];
-+              retval = ext2fs_write_inode(fs, ino, &inode);
-+              if (retval)
-+                      return retval;
-+      }
-+
-+      if (!block_buf)
-+              ext2fs_free_mem(&ctx.ind_buf);
-+
-+      return (ret & BLOCK_ERROR) ? ctx.errcode : 0;
-+}
-+
-+/*
-+ * Emulate the old ext2fs_block_iterate function!
-+ */
-+
-+struct xlate {
-+      int (*func)(ext2_filsys fs,
-+                  blk_t       *blocknr,
-+                  int         bcount,
-+                  void        *priv_data);
-+      void *real_private;
-+};
-+
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int xlate_func(ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t blockcnt,
-+                    blk_t ref_block EXT2FS_ATTR((unused)),
-+                    int ref_offset EXT2FS_ATTR((unused)),
-+                    void *priv_data)
-+{
-+      struct xlate *xl = (struct xlate *) priv_data;
-+
-+      return (*xl->func)(fs, blocknr, (int) blockcnt, xl->real_private);
-+}
-+
-+errcode_t ext2fs_block_iterate(ext2_filsys fs,
-+                             ext2_ino_t ino,
-+                             int      flags,
-+                             char *block_buf,
-+                             int (*func)(ext2_filsys fs,
-+                                         blk_t        *blocknr,
-+                                         int  blockcnt,
-+                                         void *priv_data),
-+                             void *priv_data)
-+{
-+      struct xlate xl;
-+      
-+      xl.real_private = priv_data;
-+      xl.func = func;
-+
-+      return ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_NO_LARGE | flags,
-+                                   block_buf, xlate_func, &xl);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/bmap.c busybox/e2fsprogs/ext2fs/bmap.c
---- busybox-1.00/e2fsprogs/ext2fs/bmap.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/bmap.c    2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,270 @@
-+/*
-+ * bmap.c --- logical to physical block mapping
-+ *
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#if defined(__GNUC__) && !defined(NO_INLINE_FUNCS)
-+#define _BMAP_INLINE_ __inline__
-+#else
-+#define _BMAP_INLINE_
-+#endif
-+
-+extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
-+                           struct ext2_inode *inode, 
-+                           char *block_buf, int bmap_flags,
-+                           blk_t block, blk_t *phys_blk);
-+
-+#define inode_bmap(inode, nr) ((inode)->i_block[(nr)])
-+
-+static _BMAP_INLINE_ errcode_t block_ind_bmap(ext2_filsys fs, int flags, 
-+                                            blk_t ind, char *block_buf, 
-+                                            int *blocks_alloc,
-+                                            blk_t nr, blk_t *ret_blk)
-+{
-+      errcode_t       retval;
-+      blk_t           b;
-+
-+      if (!ind) {
-+              if (flags & BMAP_SET)
-+                      return EXT2_ET_SET_BMAP_NO_IND;
-+              *ret_blk = 0;
-+              return 0;
-+      }
-+      retval = io_channel_read_blk(fs->io, ind, 1, block_buf);
-+      if (retval)
-+              return retval;
-+
-+      if (flags & BMAP_SET) {
-+              b = *ret_blk;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+              if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+                  (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
-+                      b = ext2fs_swab32(b);
-+#endif
-+              ((blk_t *) block_buf)[nr] = b;
-+              return io_channel_write_blk(fs->io, ind, 1, block_buf);
-+      }
-+
-+      b = ((blk_t *) block_buf)[nr];
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+          (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
-+              b = ext2fs_swab32(b);
-+#endif
-+
-+      if (!b && (flags & BMAP_ALLOC)) {
-+              b = nr ? ((blk_t *) block_buf)[nr-1] : 0;
-+              retval = ext2fs_alloc_block(fs, b,
-+                                          block_buf + fs->blocksize, &b);
-+              if (retval)
-+                      return retval;
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+              if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+                  (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
-+                      ((blk_t *) block_buf)[nr] = ext2fs_swab32(b);
-+              else
-+#endif
-+                      ((blk_t *) block_buf)[nr] = b;
-+
-+              retval = io_channel_write_blk(fs->io, ind, 1, block_buf);
-+              if (retval)
-+                      return retval;
-+
-+              (*blocks_alloc)++;
-+      }
-+
-+      *ret_blk = b;
-+      return 0;
-+}
-+
-+static _BMAP_INLINE_ errcode_t block_dind_bmap(ext2_filsys fs, int flags,
-+                                             blk_t dind, char *block_buf, 
-+                                             int *blocks_alloc,
-+                                             blk_t nr, blk_t *ret_blk)
-+{
-+      blk_t           b;
-+      errcode_t       retval;
-+      blk_t           addr_per_block;
-+      
-+      addr_per_block = (blk_t) fs->blocksize >> 2;
-+
-+      retval = block_ind_bmap(fs, flags & ~BMAP_SET, dind, block_buf, 
-+                              blocks_alloc, nr / addr_per_block, &b);
-+      if (retval)
-+              return retval;
-+      retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc,
-+                              nr % addr_per_block, ret_blk);
-+      return retval;
-+}
-+
-+static _BMAP_INLINE_ errcode_t block_tind_bmap(ext2_filsys fs, int flags,
-+                                             blk_t tind, char *block_buf, 
-+                                             int *blocks_alloc,
-+                                             blk_t nr, blk_t *ret_blk)
-+{
-+      blk_t           b;
-+      errcode_t       retval;
-+      blk_t           addr_per_block;
-+      
-+      addr_per_block = (blk_t) fs->blocksize >> 2;
-+
-+      retval = block_dind_bmap(fs, flags & ~BMAP_SET, tind, block_buf, 
-+                               blocks_alloc, nr / addr_per_block, &b);
-+      if (retval)
-+              return retval;
-+      retval = block_ind_bmap(fs, flags, b, block_buf, blocks_alloc,
-+                              nr % addr_per_block, ret_blk);
-+      return retval;
-+}
-+
-+errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
-+                    char *block_buf, int bmap_flags, blk_t block,
-+                    blk_t *phys_blk)
-+{
-+      struct ext2_inode inode_buf;
-+      blk_t addr_per_block;
-+      blk_t   b;
-+      char    *buf = 0;
-+      errcode_t       retval = 0;
-+      int             blocks_alloc = 0, inode_dirty = 0;
-+
-+      if (!(bmap_flags & BMAP_SET))
-+              *phys_blk = 0;
-+
-+      /* Read inode structure if necessary */
-+      if (!inode) {
-+              retval = ext2fs_read_inode(fs, ino, &inode_buf);
-+              if (retval)
-+                      return retval;
-+              inode = &inode_buf;
-+      }
-+      addr_per_block = (blk_t) fs->blocksize >> 2;
-+
-+      if (!block_buf) {
-+              retval = ext2fs_get_mem(fs->blocksize * 2, &buf);
-+              if (retval)
-+                      return retval;
-+              block_buf = buf;
-+      }
-+
-+      if (block < EXT2_NDIR_BLOCKS) {
-+              if (bmap_flags & BMAP_SET) {
-+                      b = *phys_blk;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+                      if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+                          (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
-+                              b = ext2fs_swab32(b);
-+#endif
-+                      inode_bmap(inode, block) = b;
-+                      inode_dirty++;
-+                      goto done;
-+              }
-+
-+              *phys_blk = inode_bmap(inode, block);
-+              b = block ? inode_bmap(inode, block-1) : 0;
-+              
-+              if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) {
-+                      retval = ext2fs_alloc_block(fs, b, block_buf, &b);
-+                      if (retval)
-+                              goto done;
-+                      inode_bmap(inode, block) = b;
-+                      blocks_alloc++;
-+                      *phys_blk = b;
-+              }
-+              goto done;
-+      }
-+      
-+      /* Indirect block */
-+      block -= EXT2_NDIR_BLOCKS;
-+      if (block < addr_per_block) {
-+              b = inode_bmap(inode, EXT2_IND_BLOCK);
-+              if (!b) {
-+                      if (!(bmap_flags & BMAP_ALLOC)) {
-+                              if (bmap_flags & BMAP_SET)
-+                                      retval = EXT2_ET_SET_BMAP_NO_IND;
-+                              goto done;
-+                      }
-+
-+                      b = inode_bmap(inode, EXT2_IND_BLOCK-1);
-+                      retval = ext2fs_alloc_block(fs, b, block_buf, &b);
-+                      if (retval)
-+                              goto done;
-+                      inode_bmap(inode, EXT2_IND_BLOCK) = b;
-+                      blocks_alloc++;
-+              }
-+              retval = block_ind_bmap(fs, bmap_flags, b, block_buf, 
-+                                      &blocks_alloc, block, phys_blk);
-+              goto done;
-+      }
-+      
-+      /* Doubly indirect block  */
-+      block -= addr_per_block;
-+      if (block < addr_per_block * addr_per_block) {
-+              b = inode_bmap(inode, EXT2_DIND_BLOCK);
-+              if (!b) {
-+                      if (!(bmap_flags & BMAP_ALLOC)) {
-+                              if (bmap_flags & BMAP_SET)
-+                                      retval = EXT2_ET_SET_BMAP_NO_IND;
-+                              goto done;
-+                      }
-+
-+                      b = inode_bmap(inode, EXT2_IND_BLOCK);
-+                      retval = ext2fs_alloc_block(fs, b, block_buf, &b);
-+                      if (retval)
-+                              goto done;
-+                      inode_bmap(inode, EXT2_DIND_BLOCK) = b;
-+                      blocks_alloc++;
-+              }
-+              retval = block_dind_bmap(fs, bmap_flags, b, block_buf, 
-+                                       &blocks_alloc, block, phys_blk);
-+              goto done;
-+      }
-+
-+      /* Triply indirect block */
-+      block -= addr_per_block * addr_per_block;
-+      b = inode_bmap(inode, EXT2_TIND_BLOCK);
-+      if (!b) {
-+              if (!(bmap_flags & BMAP_ALLOC)) {
-+                      if (bmap_flags & BMAP_SET)
-+                              retval = EXT2_ET_SET_BMAP_NO_IND;
-+                      goto done;
-+              }
-+
-+              b = inode_bmap(inode, EXT2_DIND_BLOCK);
-+              retval = ext2fs_alloc_block(fs, b, block_buf, &b);
-+              if (retval)
-+                      goto done;
-+              inode_bmap(inode, EXT2_TIND_BLOCK) = b;
-+              blocks_alloc++;
-+      }
-+      retval = block_tind_bmap(fs, bmap_flags, b, block_buf, 
-+                               &blocks_alloc, block, phys_blk);
-+done:
-+      if (buf)
-+              ext2fs_free_mem(&buf);
-+      if ((retval == 0) && (blocks_alloc || inode_dirty)) {
-+              inode->i_blocks += (blocks_alloc * fs->blocksize) / 512;
-+              retval = ext2fs_write_inode(fs, ino, inode);
-+      }
-+      return retval;
-+}
-+
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/bmove.c busybox/e2fsprogs/ext2fs/bmove.c
---- busybox-1.00/e2fsprogs/ext2fs/bmove.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/bmove.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,160 @@
-+/*
-+ * bmove.c --- Move blocks around to make way for a particular
-+ *    filesystem structure.
-+ *
-+ * Copyright (C) 1997 Theodore Ts'o.  This file may be redistributed
-+ * under the terms of the GNU Public License.
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#if HAVE_SYS_TIME_H
-+#include <sys/time.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+struct process_block_struct {
-+      ext2_ino_t              ino;
-+      struct ext2_inode *     inode;
-+      ext2fs_block_bitmap     reserve;
-+      ext2fs_block_bitmap     alloc_map;
-+      errcode_t               error;
-+      char                    *buf;
-+      int                     add_dir;
-+      int                     flags;
-+};
-+
-+static int process_block(ext2_filsys fs, blk_t        *block_nr,
-+                       e2_blkcnt_t blockcnt, blk_t ref_block,
-+                       int ref_offset, void *priv_data)
-+{
-+      struct process_block_struct *pb;
-+      errcode_t       retval;
-+      int             ret;
-+      blk_t           block, orig;
-+
-+      pb = (struct process_block_struct *) priv_data;
-+      block = orig = *block_nr;
-+      ret = 0;
-+      
-+      /*
-+       * Let's see if this is one which we need to relocate
-+       */
-+      if (ext2fs_test_block_bitmap(pb->reserve, block)) {
-+              do {
-+                      if (++block >= fs->super->s_blocks_count)
-+                              block = fs->super->s_first_data_block;
-+                      if (block == orig) {
-+                              pb->error = EXT2_ET_BLOCK_ALLOC_FAIL;
-+                              return BLOCK_ABORT;
-+                      }
-+              } while (ext2fs_test_block_bitmap(pb->reserve, block) ||
-+                       ext2fs_test_block_bitmap(pb->alloc_map, block));
-+
-+              retval = io_channel_read_blk(fs->io, orig, 1, pb->buf);
-+              if (retval) {
-+                      pb->error = retval;
-+                      return BLOCK_ABORT;
-+              }
-+              retval = io_channel_write_blk(fs->io, block, 1, pb->buf);
-+              if (retval) {
-+                      pb->error = retval;
-+                      return BLOCK_ABORT;
-+              }
-+              *block_nr = block;
-+              ext2fs_mark_block_bitmap(pb->alloc_map, block);
-+              ret = BLOCK_CHANGED;
-+              if (pb->flags & EXT2_BMOVE_DEBUG)
-+                      printf("ino=%ld, blockcnt=%lld, %d->%d\n", pb->ino,
-+                             blockcnt, orig, block);
-+      }
-+      if (pb->add_dir) {
-+              retval = ext2fs_add_dir_block(fs->dblist, pb->ino,
-+                                            block, (int) blockcnt);
-+              if (retval) {
-+                      pb->error = retval;
-+                      ret |= BLOCK_ABORT;
-+              }
-+      }
-+      return ret;
-+}
-+
-+errcode_t ext2fs_move_blocks(ext2_filsys fs,
-+                           ext2fs_block_bitmap reserve,
-+                           ext2fs_block_bitmap alloc_map,
-+                           int flags)
-+{
-+      ext2_ino_t      ino;
-+      struct ext2_inode inode;
-+      errcode_t       retval;
-+      struct process_block_struct pb;
-+      ext2_inode_scan scan;
-+      char            *block_buf;
-+      
-+      retval = ext2fs_open_inode_scan(fs, 0, &scan);
-+      if (retval)
-+              return retval;
-+
-+      pb.reserve = reserve;
-+      pb.error = 0;
-+      pb.alloc_map = alloc_map ? alloc_map : fs->block_map;
-+      pb.flags = flags;
-+      
-+      retval = ext2fs_get_mem(fs->blocksize * 4, &block_buf);
-+      if (retval)
-+              return retval;
-+      pb.buf = block_buf + fs->blocksize * 3;
-+
-+      /*
-+       * If GET_DBLIST is set in the flags field, then we should
-+       * gather directory block information while we're doing the
-+       * block move.
-+       */
-+      if (flags & EXT2_BMOVE_GET_DBLIST) {
-+              if (fs->dblist) {
-+                      ext2fs_free_dblist(fs->dblist);
-+                      fs->dblist = NULL;
-+              }
-+              retval = ext2fs_init_dblist(fs, 0);
-+              if (retval)
-+                      return retval;
-+      }
-+
-+      retval = ext2fs_get_next_inode(scan, &ino, &inode);
-+      if (retval)
-+              return retval;
-+      
-+      while (ino) {
-+              if ((inode.i_links_count == 0) ||
-+                  !ext2fs_inode_has_valid_blocks(&inode))
-+                      goto next;
-+              
-+              pb.ino = ino;
-+              pb.inode = &inode;
-+
-+              pb.add_dir = (LINUX_S_ISDIR(inode.i_mode) &&
-+                            flags & EXT2_BMOVE_GET_DBLIST);
-+
-+              retval = ext2fs_block_iterate2(fs, ino, 0, block_buf,
-+                                            process_block, &pb);
-+              if (retval)
-+                      return retval;
-+              if (pb.error)
-+                      return pb.error;
-+
-+      next:
-+              retval = ext2fs_get_next_inode(scan, &ino, &inode);
-+              if (retval == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE)
-+                      goto next;
-+      }
-+      return 0;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/brel.h busybox/e2fsprogs/ext2fs/brel.h
---- busybox-1.00/e2fsprogs/ext2fs/brel.h       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/brel.h    2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,86 @@
-+/*
-+ * brel.h
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+struct ext2_block_relocate_entry {
-+      blk_t   new;
-+      __s16   offset;
-+      __u16   flags;
-+      union {
-+              blk_t           block_ref;
-+              ext2_ino_t      inode_ref;
-+      } owner;
-+};
-+
-+#define RELOCATE_TYPE_REF  0x0007
-+#define RELOCATE_BLOCK_REF 0x0001
-+#define RELOCATE_INODE_REF 0x0002
-+
-+typedef struct ext2_block_relocation_table *ext2_brel;
-+
-+struct ext2_block_relocation_table {
-+      __u32   magic;
-+      char    *name;
-+      blk_t   current;
-+      void    *priv_data;
-+
-+      /*
-+       * Add a block relocation entry.
-+       */
-+      errcode_t (*put)(ext2_brel brel, blk_t old,
-+                            struct ext2_block_relocate_entry *ent);
-+
-+      /*
-+       * Get a block relocation entry.
-+       */
-+      errcode_t (*get)(ext2_brel brel, blk_t old,
-+                            struct ext2_block_relocate_entry *ent);
-+
-+      /*
-+       * Initialize for iterating over the block relocation entries.
-+       */
-+      errcode_t (*start_iter)(ext2_brel brel);
-+      
-+      /*
-+       * The iterator function for the inode relocation entries.
-+       * Returns an inode number of 0 when out of entries.
-+       */
-+      errcode_t (*next)(ext2_brel brel, blk_t *old,
-+                        struct ext2_block_relocate_entry *ent);
-+
-+      /*
-+       * Move the inode relocation table from one block number to
-+       * another.
-+       */
-+      errcode_t (*move)(ext2_brel brel, blk_t old, blk_t new);
-+
-+      /*
-+       * Remove a block relocation entry.
-+       */
-+      errcode_t (*delete)(ext2_brel brel, blk_t old);
-+
-+
-+      /*
-+       * Free the block relocation table.
-+       */
-+      errcode_t (*free)(ext2_brel brel);
-+};
-+
-+errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block,
-+                                  ext2_brel *brel);
-+
-+#define ext2fs_brel_put(brel, old, ent) ((brel)->put((brel), old, ent))
-+#define ext2fs_brel_get(brel, old, ent) ((brel)->get((brel), old, ent))
-+#define ext2fs_brel_start_iter(brel) ((brel)->start_iter((brel)))
-+#define ext2fs_brel_next(brel, old, ent) ((brel)->next((brel), old, ent))
-+#define ext2fs_brel_move(brel, old, new) ((brel)->move((brel), old, new))
-+#define ext2fs_brel_delete(brel, old) ((brel)->delete((brel), old))
-+#define ext2fs_brel_free(brel) ((brel)->free((brel)))
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/brel_ma.c busybox/e2fsprogs/ext2fs/brel_ma.c
---- busybox-1.00/e2fsprogs/ext2fs/brel_ma.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/brel_ma.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,197 @@
-+/*
-+ * brel_ma.c
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * TODO: rewrite to not use a direct array!!!  (Fortunately this
-+ * module isn't really used yet.)
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <fcntl.h>
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+#include "brel.h"
-+
-+static errcode_t bma_put(ext2_brel brel, blk_t old,
-+                      struct ext2_block_relocate_entry *ent);
-+static errcode_t bma_get(ext2_brel brel, blk_t old,
-+                      struct ext2_block_relocate_entry *ent);
-+static errcode_t bma_start_iter(ext2_brel brel);
-+static errcode_t bma_next(ext2_brel brel, blk_t *old,
-+                       struct ext2_block_relocate_entry *ent);
-+static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new);
-+static errcode_t bma_delete(ext2_brel brel, blk_t old);
-+static errcode_t bma_free(ext2_brel brel);
-+
-+struct brel_ma {
-+      __u32 magic;
-+      blk_t max_block;
-+      struct ext2_block_relocate_entry *entries;
-+};
-+
-+errcode_t ext2fs_brel_memarray_create(char *name, blk_t max_block,
-+                                    ext2_brel *new_brel)
-+{
-+      ext2_brel               brel = 0;
-+      errcode_t       retval;
-+      struct brel_ma  *ma = 0;
-+      size_t          size;
-+
-+      *new_brel = 0;
-+
-+      /*
-+       * Allocate memory structures
-+       */
-+      retval = ext2fs_get_mem(sizeof(struct ext2_block_relocation_table),
-+                              &brel);
-+      if (retval)
-+              goto errout;
-+      memset(brel, 0, sizeof(struct ext2_block_relocation_table));
-+      
-+      retval = ext2fs_get_mem(strlen(name)+1, &brel->name);
-+      if (retval)
-+              goto errout;
-+      strcpy(brel->name, name);
-+      
-+      retval = ext2fs_get_mem(sizeof(struct brel_ma), &ma);
-+      if (retval)
-+              goto errout;
-+      memset(ma, 0, sizeof(struct brel_ma));
-+      brel->priv_data = ma;
-+      
-+      size = (size_t) (sizeof(struct ext2_block_relocate_entry) *
-+                       (max_block+1));
-+      retval = ext2fs_get_mem(size, &ma->entries);
-+      if (retval)
-+              goto errout;
-+      memset(ma->entries, 0, size);
-+      ma->max_block = max_block;
-+
-+      /*
-+       * Fill in the brel data structure
-+       */
-+      brel->put = bma_put;
-+      brel->get = bma_get;
-+      brel->start_iter = bma_start_iter;
-+      brel->next = bma_next;
-+      brel->move = bma_move;
-+      brel->delete = bma_delete;
-+      brel->free = bma_free;
-+      
-+      *new_brel = brel;
-+      return 0;
-+
-+errout:
-+      bma_free(brel);
-+      return retval;
-+}
-+
-+static errcode_t bma_put(ext2_brel brel, blk_t old,
-+                      struct ext2_block_relocate_entry *ent)
-+{
-+      struct brel_ma  *ma;
-+
-+      ma = brel->priv_data;
-+      if (old > ma->max_block)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      ma->entries[(unsigned)old] = *ent;
-+      return 0;
-+}
-+
-+static errcode_t bma_get(ext2_brel brel, blk_t old,
-+                      struct ext2_block_relocate_entry *ent)
-+{
-+      struct brel_ma  *ma;
-+
-+      ma = brel->priv_data;
-+      if (old > ma->max_block)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      if (ma->entries[(unsigned)old].new == 0)
-+              return ENOENT;
-+      *ent = ma->entries[old];
-+      return 0;
-+}
-+
-+static errcode_t bma_start_iter(ext2_brel brel)
-+{
-+      brel->current = 0;
-+      return 0;
-+}
-+
-+static errcode_t bma_next(ext2_brel brel, blk_t *old,
-+                        struct ext2_block_relocate_entry *ent)
-+{
-+      struct brel_ma  *ma;
-+
-+      ma = brel->priv_data;
-+      while (++brel->current < ma->max_block) {
-+              if (ma->entries[(unsigned)brel->current].new == 0)
-+                      continue;
-+              *old = brel->current;
-+              *ent = ma->entries[(unsigned)brel->current];
-+              return 0;
-+      }
-+      *old = 0;
-+      return 0;
-+}
-+
-+static errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new)
-+{
-+      struct brel_ma  *ma;
-+
-+      ma = brel->priv_data;
-+      if ((old > ma->max_block) || (new > ma->max_block))
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      if (ma->entries[(unsigned)old].new == 0)
-+              return ENOENT;
-+      ma->entries[(unsigned)new] = ma->entries[old];
-+      ma->entries[(unsigned)old].new = 0;
-+      return 0;
-+}
-+
-+static errcode_t bma_delete(ext2_brel brel, blk_t old)
-+{
-+      struct brel_ma  *ma;
-+
-+      ma = brel->priv_data;
-+      if (old > ma->max_block)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      if (ma->entries[(unsigned)old].new == 0)
-+              return ENOENT;
-+      ma->entries[(unsigned)old].new = 0;
-+      return 0;
-+}
-+
-+static errcode_t bma_free(ext2_brel brel)
-+{
-+      struct brel_ma  *ma;
-+
-+      if (!brel)
-+              return 0;
-+
-+      ma = brel->priv_data;
-+
-+      if (ma) {
-+              if (ma->entries)
-+                      ext2fs_free_mem(&ma->entries);
-+              ext2fs_free_mem(&ma);
-+      }
-+      if (brel->name)
-+              ext2fs_free_mem(&brel->name);
-+      ext2fs_free_mem(&brel);
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/check_desc.c busybox/e2fsprogs/ext2fs/check_desc.c
---- busybox-1.00/e2fsprogs/ext2fs/check_desc.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/check_desc.c      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,68 @@
-+/*
-+ * check_desc.c --- Check the group descriptors of an ext2 filesystem
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * This routine sanity checks the group descriptors
-+ */
-+errcode_t ext2fs_check_desc(ext2_filsys fs)
-+{
-+      dgrp_t i;
-+      blk_t block = fs->super->s_first_data_block;
-+      blk_t next;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      for (i = 0; i < fs->group_desc_count; i++) {
-+              next = block + fs->super->s_blocks_per_group;
-+              /*
-+               * Check to make sure block bitmap for group is
-+               * located within the group.
-+               */
-+              if (fs->group_desc[i].bg_block_bitmap < block ||
-+                  fs->group_desc[i].bg_block_bitmap >= next)
-+                      return EXT2_ET_GDESC_BAD_BLOCK_MAP;
-+              /*
-+               * Check to make sure inode bitmap for group is
-+               * located within the group
-+               */
-+              if (fs->group_desc[i].bg_inode_bitmap < block ||
-+                  fs->group_desc[i].bg_inode_bitmap >= next)
-+                      return EXT2_ET_GDESC_BAD_INODE_MAP;
-+              /*
-+               * Check to make sure inode table for group is located
-+               * within the group
-+               */
-+              if (fs->group_desc[i].bg_inode_table < block ||
-+                  ((fs->group_desc[i].bg_inode_table +
-+                    fs->inode_blocks_per_group) >= next))
-+                      return EXT2_ET_GDESC_BAD_INODE_TABLE;
-+              
-+              block = next;
-+      }
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/closefs.c busybox/e2fsprogs/ext2fs/closefs.c
---- busybox-1.00/e2fsprogs/ext2fs/closefs.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/closefs.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,381 @@
-+/*
-+ * closefs.c --- close an ext2 filesystem
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <time.h>
-+#include <string.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+static int test_root(int a, int b)
-+{
-+      if (a == 0)
-+              return 1;
-+      while (1) {
-+              if (a == 1)
-+                      return 1;
-+              if (a % b)
-+                      return 0;
-+              a = a / b;
-+      }
-+}
-+
-+int ext2fs_bg_has_super(ext2_filsys fs, int group_block)
-+{
-+      if (!(fs->super->s_feature_ro_compat &
-+            EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
-+              return 1;
-+
-+      if (test_root(group_block, 3) || (test_root(group_block, 5)) ||
-+          test_root(group_block, 7))
-+              return 1;
-+
-+      return 0;
-+}
-+
-+int ext2fs_super_and_bgd_loc(ext2_filsys fs, 
-+                           dgrp_t group,
-+                           blk_t *ret_super_blk,
-+                           blk_t *ret_old_desc_blk,
-+                           blk_t *ret_new_desc_blk,
-+                           int *ret_meta_bg)
-+{
-+      blk_t   group_block, super_blk = 0, old_desc_blk = 0, new_desc_blk = 0;
-+      unsigned int meta_bg, meta_bg_size;
-+      int     numblocks, has_super;
-+      int     old_desc_blocks;
-+
-+      group_block = fs->super->s_first_data_block +
-+              (group * fs->super->s_blocks_per_group);
-+
-+      if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
-+              old_desc_blocks = fs->super->s_first_meta_bg;
-+      else
-+              old_desc_blocks = 
-+                      fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
-+
-+      if (group == fs->group_desc_count-1) {
-+              numblocks = (fs->super->s_blocks_count -
-+                           fs->super->s_first_data_block) %
-+                      fs->super->s_blocks_per_group;
-+              if (!numblocks)
-+                      numblocks = fs->super->s_blocks_per_group;
-+      } else
-+              numblocks = fs->super->s_blocks_per_group;
-+
-+      has_super = ext2fs_bg_has_super(fs, group);
-+
-+      if (has_super) {
-+              super_blk = group_block;
-+              numblocks--;
-+      }
-+      meta_bg_size = (fs->blocksize / sizeof (struct ext2_group_desc));
-+      meta_bg = group / meta_bg_size;
-+
-+      if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
-+          (meta_bg < fs->super->s_first_meta_bg)) {
-+              if (has_super) {
-+                      old_desc_blk = group_block + 1;
-+                      numblocks -= old_desc_blocks;
-+              }
-+      } else {
-+              if (((group % meta_bg_size) == 0) ||
-+                  ((group % meta_bg_size) == 1) ||
-+                  ((group % meta_bg_size) == (meta_bg_size-1))) {
-+                      if (has_super)
-+                              has_super = 1;
-+                      new_desc_blk = group_block + has_super;
-+                      numblocks--;
-+              }
-+      }
-+              
-+      numblocks -= 2 + fs->inode_blocks_per_group;
-+
-+      if (ret_super_blk)
-+              *ret_super_blk = super_blk;
-+      if (ret_old_desc_blk)
-+              *ret_old_desc_blk = old_desc_blk;
-+      if (ret_new_desc_blk)
-+              *ret_new_desc_blk = new_desc_blk;
-+      if (ret_meta_bg)
-+              *ret_meta_bg = meta_bg;
-+      return (numblocks);
-+}
-+
-+
-+/*
-+ * This function forces out the primary superblock.  We need to only
-+ * write out those fields which we have changed, since if the
-+ * filesystem is mounted, it may have changed some of the other
-+ * fields.
-+ *
-+ * It takes as input a superblock which has already been byte swapped
-+ * (if necessary).
-+ *
-+ */
-+static errcode_t write_primary_superblock(ext2_filsys fs,
-+                                        struct ext2_super_block *super)
-+{
-+      __u16           *old_super, *new_super;
-+      int             check_idx, write_idx, size;
-+      errcode_t       retval;
-+
-+      if (!fs->io->manager->write_byte || !fs->orig_super) {
-+              io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET);
-+              retval = io_channel_write_blk(fs->io, 1, -SUPERBLOCK_SIZE,
-+                                            super);
-+              io_channel_set_blksize(fs->io, fs->blocksize);
-+              return retval;
-+      }
-+
-+      old_super = (__u16 *) fs->orig_super;
-+      new_super = (__u16 *) super;
-+
-+      for (check_idx = 0; check_idx < SUPERBLOCK_SIZE/2; check_idx++) {
-+              if (old_super[check_idx] == new_super[check_idx])
-+                      continue;
-+              write_idx = check_idx;
-+              for (check_idx++; check_idx < SUPERBLOCK_SIZE/2; check_idx++)
-+                      if (old_super[check_idx] == new_super[check_idx])
-+                              break;
-+              size = 2 * (check_idx - write_idx);
-+#if 0
-+              printf("Writing %d bytes starting at %d\n",
-+                     size, write_idx*2);
-+#endif
-+              retval = io_channel_write_byte(fs->io,
-+                             SUPERBLOCK_OFFSET + (2 * write_idx), size,
-+                                             new_super + write_idx);
-+              if (retval)
-+                      return retval;
-+      }
-+      memcpy(fs->orig_super, super, SUPERBLOCK_SIZE);
-+      return 0;
-+}
-+
-+
-+/*
-+ * Updates the revision to EXT2_DYNAMIC_REV
-+ */
-+void ext2fs_update_dynamic_rev(ext2_filsys fs)
-+{
-+      struct ext2_super_block *sb = fs->super;
-+
-+      if (sb->s_rev_level > EXT2_GOOD_OLD_REV)
-+              return;
-+
-+      sb->s_rev_level = EXT2_DYNAMIC_REV;
-+      sb->s_first_ino = EXT2_GOOD_OLD_FIRST_INO;
-+      sb->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE;
-+      /* s_uuid is handled by e2fsck already */
-+      /* other fields should be left alone */
-+}
-+
-+static errcode_t write_backup_super(ext2_filsys fs, dgrp_t group,
-+                                  blk_t group_block,
-+                                  struct ext2_super_block *super_shadow)
-+{
-+      dgrp_t  sgrp = group;
-+      
-+      if (sgrp > ((1 << 16) - 1))
-+              sgrp = (1 << 16) - 1;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if (fs->flags & EXT2_FLAG_SWAP_BYTES)
-+              super_shadow->s_block_group_nr = ext2fs_swab16(sgrp);
-+      else
-+#endif
-+              fs->super->s_block_group_nr = sgrp;
-+
-+      return io_channel_write_blk(fs->io, group_block, -SUPERBLOCK_SIZE, 
-+                                  super_shadow);
-+}
-+
-+
-+errcode_t ext2fs_flush(ext2_filsys fs)
-+{
-+      dgrp_t          i,j;
-+      blk_t           group_block;
-+      errcode_t       retval;
-+      unsigned long   fs_state;
-+      struct ext2_super_block *super_shadow = 0;
-+      struct ext2_group_desc *group_shadow = 0;
-+      struct ext2_group_desc *s, *t;
-+      char    *group_ptr;
-+      int     old_desc_blocks;
-+      
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      fs_state = fs->super->s_state;
-+
-+      fs->super->s_wtime = time(NULL);
-+      fs->super->s_block_group_nr = 0;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-+              retval = EXT2_ET_NO_MEMORY;
-+              retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super_shadow);
-+              if (retval)
-+                      goto errout;
-+              retval = ext2fs_get_mem((size_t)(fs->blocksize *
-+                                               fs->desc_blocks),
-+                                      &group_shadow);
-+              if (retval)
-+                      goto errout;
-+              memset(group_shadow, 0, (size_t) fs->blocksize *
-+                     fs->desc_blocks);
-+
-+              /* swap the group descriptors */
-+              for (j=0, s=fs->group_desc, t=group_shadow;
-+                   j < fs->group_desc_count; j++, t++, s++) {
-+                      *t = *s;
-+                      ext2fs_swap_group_desc(t);
-+              }
-+      } else {
-+              super_shadow = fs->super;
-+              group_shadow = fs->group_desc;
-+      }
-+#else
-+      super_shadow = fs->super;
-+      group_shadow = fs->group_desc;
-+#endif
-+      
-+      /*
-+       * If this is an external journal device, don't write out the
-+       * block group descriptors or any of the backup superblocks
-+       */
-+      if (fs->super->s_feature_incompat &
-+          EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)
-+              goto write_primary_superblock_only;
-+
-+      /*
-+       * Set the state of the FS to be non-valid.  (The state has
-+       * already been backed up earlier, and will be restored after
-+       * we write out the backup superblocks.)
-+       */
-+      fs->super->s_state &= ~EXT2_VALID_FS;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-+              *super_shadow = *fs->super;
-+              ext2fs_swap_super(super_shadow);
-+      }
-+#endif
-+
-+      /*
-+       * Write out the master group descriptors, and the backup
-+       * superblocks and group descriptors.
-+       */
-+      group_block = fs->super->s_first_data_block;
-+      group_ptr = (char *) group_shadow;
-+      if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG)
-+              old_desc_blocks = fs->super->s_first_meta_bg;
-+      else
-+              old_desc_blocks = fs->desc_blocks;
-+
-+      for (i = 0; i < fs->group_desc_count; i++) {
-+              blk_t   super_blk, old_desc_blk, new_desc_blk;
-+              int     meta_bg;
-+
-+              ext2fs_super_and_bgd_loc(fs, i, &super_blk, &old_desc_blk, 
-+                                       &new_desc_blk, &meta_bg);
-+
-+              if (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) &&i && super_blk) {
-+                      retval = write_backup_super(fs, i, super_blk,
-+                                                  super_shadow);
-+                      if (retval)
-+                              goto errout;
-+              }
-+              if (fs->flags & EXT2_FLAG_SUPER_ONLY)
-+                      continue;
-+              if ((old_desc_blk) && 
-+                  (!(fs->flags & EXT2_FLAG_MASTER_SB_ONLY) || (i == 0))) {
-+                      retval = io_channel_write_blk(fs->io,
-+                            old_desc_blk, old_desc_blocks, group_ptr);
-+                      if (retval)
-+                              goto errout;
-+              }
-+              if (new_desc_blk) {
-+                      retval = io_channel_write_blk(fs->io, new_desc_blk,
-+                              1, group_ptr + (meta_bg*fs->blocksize));
-+                      if (retval)
-+                              goto errout;
-+              }
-+      }
-+      fs->super->s_block_group_nr = 0;
-+      fs->super->s_state = fs_state;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-+              *super_shadow = *fs->super;
-+              ext2fs_swap_super(super_shadow);
-+      }
-+#endif
-+
-+      /*
-+       * If the write_bitmaps() function is present, call it to
-+       * flush the bitmaps.  This is done this way so that a simple
-+       * program that doesn't mess with the bitmaps doesn't need to
-+       * drag in the bitmaps.c code.
-+       */
-+      if (fs->write_bitmaps) {
-+              retval = fs->write_bitmaps(fs);
-+              if (retval)
-+                      goto errout;
-+      }
-+
-+write_primary_superblock_only:
-+      /*
-+       * Write out master superblock.  This has to be done
-+       * separately, since it is located at a fixed location
-+       * (SUPERBLOCK_OFFSET).  We flush all other pending changes
-+       * out to disk first, just to avoid a race condition with an
-+       * insy-tinsy window....
-+       */
-+      retval = io_channel_flush(fs->io);
-+      retval = write_primary_superblock(fs, super_shadow);
-+      if (retval)
-+              goto errout;
-+
-+      fs->flags &= ~EXT2_FLAG_DIRTY;
-+
-+      retval = io_channel_flush(fs->io);
-+errout:
-+      fs->super->s_state = fs_state;
-+      if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-+              if (super_shadow)
-+                      ext2fs_free_mem(&super_shadow);
-+              if (group_shadow)
-+                      ext2fs_free_mem(&group_shadow);
-+      }
-+      return retval;
-+}
-+
-+errcode_t ext2fs_close(ext2_filsys fs)
-+{
-+      errcode_t       retval;
-+      
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (fs->flags & EXT2_FLAG_DIRTY) {
-+              retval = ext2fs_flush(fs);
-+              if (retval)
-+                      return retval;
-+      }
-+      if (fs->write_bitmaps) {
-+              retval = fs->write_bitmaps(fs);
-+              if (retval)
-+                      return retval;
-+      }
-+      ext2fs_free(fs);
-+      return 0;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/cmp_bitmaps.c busybox/e2fsprogs/ext2fs/cmp_bitmaps.c
---- busybox-1.00/e2fsprogs/ext2fs/cmp_bitmaps.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/cmp_bitmaps.c     2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,72 @@
-+/*
-+ * cmp_bitmaps.c --- routines to compare inode and block bitmaps.
-+ *
-+ * Copyright (C) 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
-+                                    ext2fs_block_bitmap bm2)
-+{
-+      blk_t   i;
-+      
-+      EXT2_CHECK_MAGIC(bm1, EXT2_ET_MAGIC_BLOCK_BITMAP);
-+      EXT2_CHECK_MAGIC(bm2, EXT2_ET_MAGIC_BLOCK_BITMAP);
-+
-+      if ((bm1->start != bm2->start) ||
-+          (bm1->end != bm2->end) ||
-+          (memcmp(bm1->bitmap, bm2->bitmap,
-+                  (size_t) (bm1->end - bm1->start)/8)))
-+              return EXT2_ET_NEQ_BLOCK_BITMAP;
-+
-+      for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
-+              if (ext2fs_fast_test_block_bitmap(bm1, i) !=
-+                  ext2fs_fast_test_block_bitmap(bm2, i))
-+                      return EXT2_ET_NEQ_BLOCK_BITMAP;
-+
-+      return 0;
-+}
-+
-+errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
-+                                    ext2fs_inode_bitmap bm2)
-+{
-+      ext2_ino_t      i;
-+      
-+      EXT2_CHECK_MAGIC(bm1, EXT2_ET_MAGIC_INODE_BITMAP);
-+      EXT2_CHECK_MAGIC(bm2, EXT2_ET_MAGIC_INODE_BITMAP);
-+
-+      if ((bm1->start != bm2->start) ||
-+          (bm1->end != bm2->end) ||
-+          (memcmp(bm1->bitmap, bm2->bitmap,
-+                  (size_t) (bm1->end - bm1->start)/8)))
-+              return EXT2_ET_NEQ_INODE_BITMAP;
-+
-+      for (i = bm1->end - ((bm1->end - bm1->start) % 8); i <= bm1->end; i++)
-+              if (ext2fs_fast_test_inode_bitmap(bm1, i) !=
-+                  ext2fs_fast_test_inode_bitmap(bm2, i))
-+                      return EXT2_ET_NEQ_INODE_BITMAP;
-+
-+      return 0;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/dblist.c busybox/e2fsprogs/ext2fs/dblist.c
---- busybox-1.00/e2fsprogs/ext2fs/dblist.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/dblist.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,260 @@
-+/*
-+ * dblist.c -- directory block list functions
-+ * 
-+ * Copyright 1997 by Theodore Ts'o
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b);
-+
-+/*
-+ * Returns the number of directories in the filesystem as reported by
-+ * the group descriptors.  Of course, the group descriptors could be
-+ * wrong!
-+ */
-+errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs)
-+{
-+      dgrp_t  i;
-+      ext2_ino_t      num_dirs, max_dirs;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+      
-+      num_dirs = 0;
-+      max_dirs = fs->super->s_inodes_per_group;
-+      for (i = 0; i < fs->group_desc_count; i++) {
-+              if (fs->group_desc[i].bg_used_dirs_count > max_dirs)
-+                      num_dirs += max_dirs / 8;
-+              else
-+                      num_dirs += fs->group_desc[i].bg_used_dirs_count;
-+      }
-+      if (num_dirs > fs->super->s_inodes_count)
-+              num_dirs = fs->super->s_inodes_count;
-+
-+      *ret_num_dirs = num_dirs;
-+
-+      return 0;
-+}
-+
-+/*
-+ * helper function for making a new directory block list (for
-+ * initialize and copy).
-+ */
-+static errcode_t make_dblist(ext2_filsys fs, ext2_ino_t size, ext2_ino_t count,
-+                           struct ext2_db_entry *list,
-+                           ext2_dblist *ret_dblist)
-+{
-+      ext2_dblist     dblist;
-+      errcode_t       retval;
-+      size_t          len;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if ((ret_dblist == 0) && fs->dblist &&
-+          (fs->dblist->magic == EXT2_ET_MAGIC_DBLIST))
-+              return 0;
-+
-+      retval = ext2fs_get_mem(sizeof(struct ext2_struct_dblist), &dblist);
-+      if (retval)
-+              return retval;
-+      memset(dblist, 0, sizeof(struct ext2_struct_dblist));
-+
-+      dblist->magic = EXT2_ET_MAGIC_DBLIST;
-+      dblist->fs = fs;
-+      if (size)
-+              dblist->size = size;
-+      else {
-+              retval = ext2fs_get_num_dirs(fs, &dblist->size);
-+              if (retval)
-+                      goto cleanup;
-+              dblist->size = (dblist->size * 2) + 12;
-+      }
-+      len = (size_t) sizeof(struct ext2_db_entry) * dblist->size;
-+      dblist->count = count;
-+      retval = ext2fs_get_mem(len, &dblist->list);
-+      if (retval)
-+              goto cleanup;
-+      
-+      if (list)
-+              memcpy(dblist->list, list, len);
-+      else
-+              memset(dblist->list, 0, len);
-+      if (ret_dblist)
-+              *ret_dblist = dblist;
-+      else
-+              fs->dblist = dblist;
-+      return 0;
-+cleanup:
-+      if (dblist)
-+              ext2fs_free_mem(&dblist);
-+      return retval;
-+}
-+
-+/*
-+ * Initialize a directory block list
-+ */
-+errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist)
-+{
-+      ext2_dblist     dblist;
-+      errcode_t       retval;
-+
-+      retval = make_dblist(fs, 0, 0, 0, &dblist);
-+      if (retval)
-+              return retval;
-+
-+      dblist->sorted = 1;
-+      if (ret_dblist)
-+              *ret_dblist = dblist;
-+      else
-+              fs->dblist = dblist;
-+
-+      return 0;
-+}
-+
-+/*
-+ * Copy a directory block list
-+ */
-+errcode_t ext2fs_copy_dblist(ext2_dblist src, ext2_dblist *dest)
-+{
-+      ext2_dblist     dblist;
-+      errcode_t       retval;
-+
-+      retval = make_dblist(src->fs, src->size, src->count, src->list,
-+                           &dblist);
-+      if (retval)
-+              return retval;
-+      dblist->sorted = src->sorted;
-+      *dest = dblist;
-+      return 0;
-+}
-+
-+/*
-+ * Close a directory block list
-+ *
-+ * (moved to closefs.c)
-+ */
-+
-+
-+/*
-+ * Add a directory block to the directory block list
-+ */
-+errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk,
-+                             int blockcnt)
-+{
-+      struct ext2_db_entry    *new_entry;
-+      errcode_t               retval;
-+      unsigned long           old_size;
-+      
-+      EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
-+
-+      if (dblist->count >= dblist->size) {
-+              old_size = dblist->size * sizeof(struct ext2_db_entry);
-+              dblist->size += 100;
-+              retval = ext2fs_resize_mem(old_size, (size_t) dblist->size *
-+                                         sizeof(struct ext2_db_entry),
-+                                         &dblist->list);
-+              if (retval) {
-+                      dblist->size -= 100;
-+                      return retval;
-+              }
-+      }
-+      new_entry = dblist->list + ( (int) dblist->count++);
-+      new_entry->blk = blk;
-+      new_entry->ino = ino;
-+      new_entry->blockcnt = blockcnt;
-+
-+      dblist->sorted = 0;
-+
-+      return 0;
-+}
-+
-+/*
-+ * Change the directory block to the directory block list
-+ */
-+errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino, blk_t blk,
-+                             int blockcnt)
-+{
-+      dgrp_t                  i;
-+      
-+      EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
-+
-+      for (i=0; i < dblist->count; i++) {
-+              if ((dblist->list[i].ino != ino) ||
-+                  (dblist->list[i].blockcnt != blockcnt))
-+                      continue;
-+              dblist->list[i].blk = blk;
-+              dblist->sorted = 0;
-+              return 0;
-+      }
-+      return EXT2_ET_DB_NOT_FOUND;
-+}
-+
-+void ext2fs_dblist_sort(ext2_dblist dblist,
-+                      EXT2_QSORT_TYPE (*sortfunc)(const void *,
-+                                                  const void *))
-+{
-+      if (!sortfunc)
-+              sortfunc = dir_block_cmp;
-+      qsort(dblist->list, (size_t) dblist->count,
-+            sizeof(struct ext2_db_entry), sortfunc);
-+      dblist->sorted = 1;
-+}
-+
-+/*
-+ * This function iterates over the directory block list
-+ */
-+errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
-+                              int (*func)(ext2_filsys fs,
-+                                          struct ext2_db_entry *db_info,
-+                                          void        *priv_data),
-+                              void *priv_data)
-+{
-+      ext2_ino_t      i;
-+      int             ret;
-+      
-+      EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
-+
-+      if (!dblist->sorted)
-+              ext2fs_dblist_sort(dblist, 0);
-+      for (i=0; i < dblist->count; i++) {
-+              ret = (*func)(dblist->fs, &dblist->list[(int)i], priv_data);
-+              if (ret & DBLIST_ABORT)
-+                      return 0;
-+      }
-+      return 0;
-+}
-+
-+static EXT2_QSORT_TYPE dir_block_cmp(const void *a, const void *b)
-+{
-+      const struct ext2_db_entry *db_a =
-+              (const struct ext2_db_entry *) a;
-+      const struct ext2_db_entry *db_b =
-+              (const struct ext2_db_entry *) b;
-+
-+      if (db_a->blk != db_b->blk)
-+              return (int) (db_a->blk - db_b->blk);
-+      
-+      if (db_a->ino != db_b->ino)
-+              return (int) (db_a->ino - db_b->ino);
-+
-+      return (int) (db_a->blockcnt - db_b->blockcnt);
-+}
-+
-+int ext2fs_dblist_count(ext2_dblist dblist)
-+{
-+      return (int) dblist->count;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/dblist_dir.c busybox/e2fsprogs/ext2fs/dblist_dir.c
---- busybox-1.00/e2fsprogs/ext2fs/dblist_dir.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/dblist_dir.c      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,75 @@
-+/*
-+ * dblist_dir.c --- iterate by directory entry
-+ *
-+ * Copyright 1997 by Theodore Ts'o
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info,
-+                     void *priv_data);
-+
-+errcode_t ext2fs_dblist_dir_iterate(ext2_dblist dblist,
-+                                  int flags,
-+                                  char        *block_buf,
-+                                  int (*func)(ext2_ino_t dir,
-+                                              int     entry,
-+                                              struct ext2_dir_entry *dirent,
-+                                              int     offset,
-+                                              int     blocksize,
-+                                              char    *buf,
-+                                              void    *priv_data),
-+                                  void *priv_data)
-+{
-+      errcode_t               retval;
-+      struct dir_context      ctx;
-+
-+      EXT2_CHECK_MAGIC(dblist, EXT2_ET_MAGIC_DBLIST);
-+
-+      ctx.dir = 0;
-+      ctx.flags = flags;
-+      if (block_buf)
-+              ctx.buf = block_buf;
-+      else {
-+              retval = ext2fs_get_mem(dblist->fs->blocksize, &ctx.buf);
-+              if (retval)
-+                      return retval;
-+      }
-+      ctx.func = func;
-+      ctx.priv_data = priv_data;
-+      ctx.errcode = 0;
-+
-+      retval = ext2fs_dblist_iterate(dblist, db_dir_proc, &ctx);
-+      
-+      if (!block_buf)
-+              ext2fs_free_mem(&ctx.buf);
-+      if (retval)
-+              return retval;
-+      return ctx.errcode;
-+}
-+
-+static int db_dir_proc(ext2_filsys fs, struct ext2_db_entry *db_info,
-+                     void *priv_data)
-+{
-+      struct dir_context      *ctx;
-+
-+      ctx = (struct dir_context *) priv_data;
-+      ctx->dir = db_info->ino;
-+      
-+      return ext2fs_process_dir_block(fs, &db_info->blk,
-+                                      db_info->blockcnt, 0, 0, priv_data);
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/dir_iterate.c busybox/e2fsprogs/ext2fs/dir_iterate.c
---- busybox-1.00/e2fsprogs/ext2fs/dir_iterate.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/dir_iterate.c     2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,219 @@
-+/*
-+ * dir_iterate.c --- ext2fs directory iteration operations
-+ * 
-+ * Copyright (C) 1993, 1994, 1994, 1995, 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+/*
-+ * This function checks to see whether or not a potential deleted
-+ * directory entry looks valid.  What we do is check the deleted entry
-+ * and each successive entry to make sure that they all look valid and
-+ * that the last deleted entry ends at the beginning of the next
-+ * undeleted entry.  Returns 1 if the deleted entry looks valid, zero
-+ * if not valid.
-+ */
-+static int ext2fs_validate_entry(char *buf, int offset, int final_offset)
-+{
-+      struct ext2_dir_entry *dirent;
-+      
-+      while (offset < final_offset) {
-+              dirent = (struct ext2_dir_entry *)(buf + offset);
-+              offset += dirent->rec_len;
-+              if ((dirent->rec_len < 8) ||
-+                  ((dirent->rec_len % 4) != 0) ||
-+                  (((dirent->name_len & 0xFF)+8) > dirent->rec_len))
-+                      return 0;
-+      }
-+      return (offset == final_offset);
-+}
-+
-+errcode_t ext2fs_dir_iterate2(ext2_filsys fs,
-+                            ext2_ino_t dir,
-+                            int flags,
-+                            char *block_buf,
-+                            int (*func)(ext2_ino_t    dir,
-+                                        int           entry,
-+                                        struct ext2_dir_entry *dirent,
-+                                        int   offset,
-+                                        int   blocksize,
-+                                        char  *buf,
-+                                        void  *priv_data),
-+                            void *priv_data)
-+{
-+      struct          dir_context     ctx;
-+      errcode_t       retval;
-+      
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      retval = ext2fs_check_directory(fs, dir);
-+      if (retval)
-+              return retval;
-+      
-+      ctx.dir = dir;
-+      ctx.flags = flags;
-+      if (block_buf)
-+              ctx.buf = block_buf;
-+      else {
-+              retval = ext2fs_get_mem(fs->blocksize, &ctx.buf);
-+              if (retval)
-+                      return retval;
-+      }
-+      ctx.func = func;
-+      ctx.priv_data = priv_data;
-+      ctx.errcode = 0;
-+      retval = ext2fs_block_iterate2(fs, dir, 0, 0,
-+                                     ext2fs_process_dir_block, &ctx);
-+      if (!block_buf)
-+              ext2fs_free_mem(&ctx.buf);
-+      if (retval)
-+              return retval;
-+      return ctx.errcode;
-+}
-+
-+struct xlate {
-+      int (*func)(struct ext2_dir_entry *dirent,
-+                  int         offset,
-+                  int         blocksize,
-+                  char        *buf,
-+                  void        *priv_data);
-+      void *real_private;
-+};
-+
-+static int xlate_func(ext2_ino_t dir EXT2FS_ATTR((unused)),
-+                    int entry EXT2FS_ATTR((unused)),
-+                    struct ext2_dir_entry *dirent, int offset,
-+                    int blocksize, char *buf, void *priv_data)
-+{
-+      struct xlate *xl = (struct xlate *) priv_data;
-+
-+      return (*xl->func)(dirent, offset, blocksize, buf, xl->real_private);
-+}
-+
-+extern errcode_t ext2fs_dir_iterate(ext2_filsys fs, 
-+                            ext2_ino_t dir,
-+                            int flags,
-+                            char *block_buf,
-+                            int (*func)(struct ext2_dir_entry *dirent,
-+                                        int   offset,
-+                                        int   blocksize,
-+                                        char  *buf,
-+                                        void  *priv_data),
-+                            void *priv_data)
-+{
-+      struct xlate xl;
-+      
-+      xl.real_private = priv_data;
-+      xl.func = func;
-+
-+      return ext2fs_dir_iterate2(fs, dir, flags, block_buf,
-+                                 xlate_func, &xl);
-+}
-+
-+
-+/*
-+ * Helper function which is private to this module.  Used by
-+ * ext2fs_dir_iterate() and ext2fs_dblist_dir_iterate()
-+ */
-+int ext2fs_process_dir_block(ext2_filsys fs,
-+                           blk_t      *blocknr,
-+                           e2_blkcnt_t blockcnt,
-+                           blk_t      ref_block EXT2FS_ATTR((unused)),
-+                           int        ref_offset EXT2FS_ATTR((unused)),
-+                           void       *priv_data)
-+{
-+      struct dir_context *ctx = (struct dir_context *) priv_data;
-+      unsigned int    offset = 0;
-+      unsigned int    next_real_entry = 0;
-+      int             ret = 0;
-+      int             changed = 0;
-+      int             do_abort = 0;
-+      int             entry, size;
-+      struct ext2_dir_entry *dirent;
-+
-+      if (blockcnt < 0)
-+              return 0;
-+
-+      entry = blockcnt ? DIRENT_OTHER_FILE : DIRENT_DOT_FILE;
-+      
-+      ctx->errcode = ext2fs_read_dir_block(fs, *blocknr, ctx->buf);
-+      if (ctx->errcode)
-+              return BLOCK_ABORT;
-+
-+      while (offset < fs->blocksize) {
-+              dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
-+              if (((offset + dirent->rec_len) > fs->blocksize) ||
-+                  (dirent->rec_len < 8) ||
-+                  ((dirent->rec_len % 4) != 0) ||
-+                  (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) {
-+                      ctx->errcode = EXT2_ET_DIR_CORRUPTED;
-+                      return BLOCK_ABORT;
-+              }
-+              if (!dirent->inode &&
-+                  !(ctx->flags & DIRENT_FLAG_INCLUDE_EMPTY))
-+                      goto next;
-+
-+              ret = (ctx->func)(ctx->dir,
-+                                (next_real_entry > offset) ?
-+                                DIRENT_DELETED_FILE : entry,
-+                                dirent, offset,
-+                                fs->blocksize, ctx->buf,
-+                                ctx->priv_data);
-+              if (entry < DIRENT_OTHER_FILE)
-+                      entry++;
-+                      
-+              if (ret & DIRENT_CHANGED)
-+                      changed++;
-+              if (ret & DIRENT_ABORT) {
-+                      do_abort++;
-+                      break;
-+              }
-+next:         
-+              if (next_real_entry == offset)
-+                      next_real_entry += dirent->rec_len;
-+ 
-+              if (ctx->flags & DIRENT_FLAG_INCLUDE_REMOVED) {
-+                      size = ((dirent->name_len & 0xFF) + 11) & ~3;
-+
-+                      if (dirent->rec_len != size)  {
-+                              unsigned int final_offset;
-+
-+                              final_offset = offset + dirent->rec_len;
-+                              offset += size;
-+                              while (offset < final_offset &&
-+                                     !ext2fs_validate_entry(ctx->buf,
-+                                                            offset,
-+                                                            final_offset))
-+                                      offset += 4;
-+                              continue;
-+                      }
-+              }
-+              offset += dirent->rec_len;
-+      }
-+
-+      if (changed) {
-+              ctx->errcode = ext2fs_write_dir_block(fs, *blocknr, ctx->buf);
-+              if (ctx->errcode)
-+                      return BLOCK_ABORT;
-+      }
-+      if (do_abort)
-+              return BLOCK_ABORT;
-+      return 0;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/dirblock.c busybox/e2fsprogs/ext2fs/dirblock.c
---- busybox-1.00/e2fsprogs/ext2fs/dirblock.c   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/dirblock.c        2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,130 @@
-+/*
-+ * dirblock.c --- directory block routines.
-+ * 
-+ * Copyright (C) 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
-+                               void *buf, int flags EXT2FS_ATTR((unused)))
-+{
-+      errcode_t       retval;
-+      char            *p, *end;
-+      struct ext2_dir_entry *dirent;
-+      unsigned int    name_len, rec_len, do_swap;
-+      
-+
-+      retval = io_channel_read_blk(fs->io, block, 1, buf);
-+      if (retval)
-+              return retval;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      do_swap = (fs->flags & (EXT2_FLAG_SWAP_BYTES|
-+                              EXT2_FLAG_SWAP_BYTES_READ)) != 0;
-+#endif
-+      p = (char *) buf;
-+      end = (char *) buf + fs->blocksize;
-+      while (p < end-8) {
-+              dirent = (struct ext2_dir_entry *) p;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+              if (do_swap) {
-+                      dirent->inode = ext2fs_swab32(dirent->inode);
-+                      dirent->rec_len = ext2fs_swab16(dirent->rec_len);
-+                      dirent->name_len = ext2fs_swab16(dirent->name_len);
-+              }
-+#endif
-+              name_len = dirent->name_len;
-+#ifdef WORDS_BIGENDIAN
-+              if (flags & EXT2_DIRBLOCK_V2_STRUCT)
-+                      dirent->name_len = ext2fs_swab16(dirent->name_len);
-+#endif
-+              rec_len = dirent->rec_len;
-+              if ((rec_len < 8) || (rec_len % 4)) {
-+                      rec_len = 8;
-+                      retval = EXT2_ET_DIR_CORRUPTED;
-+              }
-+              if (((name_len & 0xFF) + 8) > dirent->rec_len)
-+                      retval = EXT2_ET_DIR_CORRUPTED;
-+              p += rec_len;
-+      }
-+      return retval;
-+}
-+
-+errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
-+                               void *buf)
-+{
-+      return ext2fs_read_dir_block2(fs, block, buf, 0);
-+}
-+
-+
-+errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
-+                                void *inbuf, int flags EXT2FS_ATTR((unused)))
-+{
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      int             do_swap = 0;
-+      errcode_t       retval;
-+      char            *p, *end;
-+      char            *buf = 0;
-+      struct ext2_dir_entry *dirent;
-+
-+      if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+          (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
-+              do_swap = 1;
-+
-+#ifndef WORDS_BIGENDIAN
-+      if (!do_swap)
-+              return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
-+#endif
-+
-+      retval = ext2fs_get_mem(fs->blocksize, &buf);
-+      if (retval)
-+              return retval;
-+      memcpy(buf, inbuf, fs->blocksize);
-+      p = buf;
-+      end = buf + fs->blocksize;
-+      while (p < end) {
-+              dirent = (struct ext2_dir_entry *) p;
-+              if ((dirent->rec_len < 8) ||
-+                  (dirent->rec_len % 4)) {
-+                      ext2fs_free_mem(&buf);
-+                      return (EXT2_ET_DIR_CORRUPTED);
-+              }
-+              p += dirent->rec_len;
-+              if (do_swap) {
-+                      dirent->inode = ext2fs_swab32(dirent->inode);
-+                      dirent->rec_len = ext2fs_swab16(dirent->rec_len);
-+                      dirent->name_len = ext2fs_swab16(dirent->name_len);
-+              }
-+#ifdef WORDS_BIGENDIAN 
-+              if (flags & EXT2_DIRBLOCK_V2_STRUCT)
-+                      dirent->name_len = ext2fs_swab16(dirent->name_len);
-+#endif
-+      }
-+      retval = io_channel_write_blk(fs->io, block, 1, buf);
-+      ext2fs_free_mem(&buf);
-+      return retval;
-+#else
-+      return io_channel_write_blk(fs->io, block, 1, (char *) inbuf);
-+#endif
-+}
-+
-+
-+errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
-+                               void *inbuf)
-+{
-+      return ext2fs_write_dir_block2(fs, block, inbuf, 0);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/dirhash.c busybox/e2fsprogs/ext2fs/dirhash.c
---- busybox-1.00/e2fsprogs/ext2fs/dirhash.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/dirhash.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,233 @@
-+/*
-+ * dirhash.c -- Calculate the hash of a directory entry
-+ *
-+ * Copyright (c) 2001  Daniel Phillips
-+ * 
-+ * Copyright (c) 2002 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * Keyed 32-bit hash function using TEA in a Davis-Meyer function
-+ *   H0 = Key
-+ *   Hi = E Mi(Hi-1) + Hi-1
-+ *
-+ * (see Applied Cryptography, 2nd edition, p448).
-+ *
-+ * Jeremy Fitzhardinge <jeremy@zip.com.au> 1998
-+ * 
-+ * This code is made available under the terms of the GPL
-+ */
-+#define DELTA 0x9E3779B9
-+
-+static void TEA_transform(__u32 buf[4], __u32 const in[])
-+{
-+      __u32   sum = 0;
-+      __u32   b0 = buf[0], b1 = buf[1];
-+      __u32   a = in[0], b = in[1], c = in[2], d = in[3];
-+      int     n = 16;
-+
-+      do {                                                    
-+              sum += DELTA;                                   
-+              b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); 
-+              b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); 
-+      } while(--n);
-+
-+      buf[0] += b0;
-+      buf[1] += b1;
-+}
-+
-+/* F, G and H are basic MD4 functions: selection, majority, parity */
-+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z))))
-+#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z)))
-+#define H(x, y, z) ((x) ^ (y) ^ (z))
-+
-+/*
-+ * The generic round function.  The application is so specific that
-+ * we don't bother protecting all the arguments with parens, as is generally
-+ * good macro practice, in favor of extra legibility.
-+ * Rotation is separate from addition to prevent recomputation
-+ */
-+#define ROUND(f, a, b, c, d, x, s)    \
-+      (a += f(b, c, d) + x, a = (a << s) | (a >> (32-s)))
-+#define K1 0
-+#define K2 013240474631UL
-+#define K3 015666365641UL
-+
-+/*
-+ * Basic cut-down MD4 transform.  Returns only 32 bits of result.
-+ */
-+static void halfMD4Transform (__u32 buf[4], __u32 const in[])
-+{
-+      __u32   a = buf[0], b = buf[1], c = buf[2], d = buf[3];
-+
-+      /* Round 1 */
-+      ROUND(F, a, b, c, d, in[0] + K1,  3);
-+      ROUND(F, d, a, b, c, in[1] + K1,  7);
-+      ROUND(F, c, d, a, b, in[2] + K1, 11);
-+      ROUND(F, b, c, d, a, in[3] + K1, 19);
-+      ROUND(F, a, b, c, d, in[4] + K1,  3);
-+      ROUND(F, d, a, b, c, in[5] + K1,  7);
-+      ROUND(F, c, d, a, b, in[6] + K1, 11);
-+      ROUND(F, b, c, d, a, in[7] + K1, 19);
-+
-+      /* Round 2 */
-+      ROUND(G, a, b, c, d, in[1] + K2,  3);
-+      ROUND(G, d, a, b, c, in[3] + K2,  5);
-+      ROUND(G, c, d, a, b, in[5] + K2,  9);
-+      ROUND(G, b, c, d, a, in[7] + K2, 13);
-+      ROUND(G, a, b, c, d, in[0] + K2,  3);
-+      ROUND(G, d, a, b, c, in[2] + K2,  5);
-+      ROUND(G, c, d, a, b, in[4] + K2,  9);
-+      ROUND(G, b, c, d, a, in[6] + K2, 13);
-+
-+      /* Round 3 */
-+      ROUND(H, a, b, c, d, in[3] + K3,  3);
-+      ROUND(H, d, a, b, c, in[7] + K3,  9);
-+      ROUND(H, c, d, a, b, in[2] + K3, 11);
-+      ROUND(H, b, c, d, a, in[6] + K3, 15);
-+      ROUND(H, a, b, c, d, in[1] + K3,  3);
-+      ROUND(H, d, a, b, c, in[5] + K3,  9);
-+      ROUND(H, c, d, a, b, in[0] + K3, 11);
-+      ROUND(H, b, c, d, a, in[4] + K3, 15);
-+
-+      buf[0] += a;
-+      buf[1] += b;
-+      buf[2] += c;
-+      buf[3] += d;
-+}
-+
-+#undef ROUND
-+#undef F
-+#undef G
-+#undef H
-+#undef K1
-+#undef K2
-+#undef K3
-+
-+/* The old legacy hash */
-+static ext2_dirhash_t dx_hack_hash (const char *name, int len)
-+{
-+      __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9;
-+      while (len--) {
-+              __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373));
-+              
-+              if (hash & 0x80000000) hash -= 0x7fffffff;
-+              hash1 = hash0;
-+              hash0 = hash;
-+      }
-+      return (hash0 << 1);
-+}
-+
-+static void str2hashbuf(const char *msg, int len, __u32 *buf, int num)
-+{
-+      __u32   pad, val;
-+      int     i;
-+
-+      pad = (__u32)len | ((__u32)len << 8);
-+      pad |= pad << 16;
-+
-+      val = pad;
-+      if (len > num*4)
-+              len = num * 4;
-+      for (i=0; i < len; i++) {
-+              if ((i % 4) == 0)
-+                      val = pad;
-+              val = msg[i] + (val << 8);
-+              if ((i % 4) == 3) {
-+                      *buf++ = val;
-+                      val = pad;
-+                      num--;
-+              }
-+      }
-+      if (--num >= 0)
-+              *buf++ = val;
-+      while (--num >= 0)
-+              *buf++ = pad;
-+}
-+
-+/*
-+ * Returns the hash of a filename.  If len is 0 and name is NULL, then
-+ * this function can be used to test whether or not a hash version is
-+ * supported.
-+ * 
-+ * The seed is an 4 longword (32 bits) "secret" which can be used to
-+ * uniquify a hash.  If the seed is all zero's, then some default seed
-+ * may be used.
-+ * 
-+ * A particular hash version specifies whether or not the seed is
-+ * represented, and whether or not the returned hash is 32 bits or 64
-+ * bits.  32 bit hashes will return 0 for the minor hash.
-+ */
-+errcode_t ext2fs_dirhash(int version, const char *name, int len,
-+                       const __u32 *seed,
-+                       ext2_dirhash_t *ret_hash,
-+                       ext2_dirhash_t *ret_minor_hash)
-+{
-+      __u32   hash;
-+      __u32   minor_hash = 0;
-+      const char      *p;
-+      int             i;
-+      __u32           in[8], buf[4];
-+
-+      /* Initialize the default seed for the hash checksum functions */
-+      buf[0] = 0x67452301;
-+      buf[1] = 0xefcdab89;
-+      buf[2] = 0x98badcfe;
-+      buf[3] = 0x10325476;
-+
-+      /* Check to see if the seed is all zero's */
-+      if (seed) {
-+              for (i=0; i < 4; i++) {
-+                      if (seed[i])
-+                              break;
-+              }
-+              if (i < 4)
-+                      memcpy(buf, seed, sizeof(buf));
-+      }
-+              
-+      switch (version) {
-+      case EXT2_HASH_LEGACY:
-+              hash = dx_hack_hash(name, len);
-+              break;
-+      case EXT2_HASH_HALF_MD4:
-+              p = name;
-+              while (len > 0) {
-+                      str2hashbuf(p, len, in, 8);
-+                      halfMD4Transform(buf, in);
-+                      len -= 32;
-+                      p += 32;
-+              }
-+              minor_hash = buf[2];
-+              hash = buf[1];
-+              break;
-+      case EXT2_HASH_TEA:
-+              p = name;
-+              while (len > 0) {
-+                      str2hashbuf(p, len, in, 4);
-+                      TEA_transform(buf, in);
-+                      len -= 16;
-+                      p += 16;
-+              }
-+              hash = buf[0];
-+              minor_hash = buf[1];
-+              break;
-+      default:
-+              *ret_hash = 0;
-+              return EXT2_ET_DIRHASH_UNSUPP;
-+      }
-+      *ret_hash = hash & ~1;
-+      if (ret_minor_hash)
-+              *ret_minor_hash = minor_hash;
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/dosio.c busybox/e2fsprogs/ext2fs/dosio.c
---- busybox-1.00/e2fsprogs/ext2fs/dosio.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/dosio.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,456 @@
-+/*
-+ * dosio.c -- Disk I/O module for the ext2fs/DOS library.
-+ *
-+ * Copyright (c) 1997 by Theodore Ts'o.
-+ * 
-+ * Copyright (c) 1997 Mark Habersack
-+ * This file may be distributed under the terms of the GNU Public License.
-+ *
-+ */
-+
-+#include <stdio.h>
-+#include <bios.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <io.h>
-+#ifdef HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include <ext2fs/ext2_types.h>
-+#include "utils.h"
-+#include "dosio.h"
-+#include "et/com_err.h"
-+#include "ext2_err.h"
-+#include "ext2fs/io.h"
-+
-+/*
-+ * Some helper macros
-+ */
-+#define LINUX_EXT2FS       0x83
-+#define LINUX_SWAP         0x82
-+#define WRITE_ERR(_msg_) write(2, _msg_, strlen(_msg_))
-+#define WRITE_ERR_S(_msg_) write(2, _msg_, sizeof(_msg_))
-+
-+/*
-+ * Exported variables
-+ */
-+unsigned long        _dio_error;
-+unsigned long        _dio_hw_error;
-+
-+/*
-+ * Array of all opened partitions
-+ */
-+static PARTITION        **partitions = NULL;
-+static unsigned short   npart = 0; /* Number of mapped partitions */
-+static PARTITION        *active = NULL;
-+
-+/*
-+ * I/O Manager routine prototypes
-+ */
-+static errcode_t dos_open(const char *dev, int flags, io_channel *channel);
-+static errcode_t dos_close(io_channel channel);
-+static errcode_t dos_set_blksize(io_channel channel, int blksize);
-+static errcode_t dos_read_blk(io_channel channel, unsigned long block,
-+                                             int count, void *buf);
-+static errcode_t dos_write_blk(io_channel channel, unsigned long block,
-+                               int count, const void *buf);
-+static errcode_t dos_flush(io_channel channel);
-+
-+static struct struct_io_manager struct_dos_manager = {
-+        EXT2_ET_MAGIC_IO_MANAGER,
-+        "DOS I/O Manager",
-+        dos_open,
-+        dos_close,
-+        dos_set_blksize,
-+        dos_read_blk,
-+        dos_write_blk,
-+        dos_flush
-+};
-+io_manager dos_io_manager = &struct_dos_manager;
-+
-+/*
-+ * Macro taken from unix_io.c
-+ */
-+/*
-+ * For checking structure magic numbers...
-+ */
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+          if ((struct)->magic != (code)) return (code)
-+
-+/*
-+ * Calculates a CHS address of a sector from its LBA
-+ * offset for the given partition.
-+ */
-+static void lba2chs(unsigned long lba_addr, CHS *chs, PARTITION *part)
-+{
-+  unsigned long      abss;
-+
-+  chs->offset = lba_addr & 0x000001FF;
-+  abss = (lba_addr >> 9) + part->start;
-+  chs->cyl    = abss / (part->sects * part->heads);
-+  chs->head   = (abss / part->sects) % part->heads;
-+  chs->sector = (abss % part->sects) + 1;
-+}
-+
-+#ifdef __TURBOC__
-+#pragma argsused
-+#endif
-+/*
-+ * Scans the passed partition table looking for *pno partition
-+ * that has LINUX_EXT2FS type.
-+ *
-+ * TODO:
-+ * For partition numbers >5 Linux uses DOS extended partitions -
-+ * dive into them an return an appropriate entry. Also dive into
-+ * extended partitions when scanning for a first Linux/ext2fs.
-+ */
-+static PTABLE_ENTRY *scan_partition_table(PTABLE_ENTRY *pentry,
-+                                          unsigned short phys,
-+                                          unsigned char *pno)
-+{
-+  unsigned        i;
-+
-+  if(*pno != 0xFF && *pno >= 5)
-+     return NULL; /* We don't support extended partitions for now */
-+
-+  if(*pno != 0xFF)
-+  {
-+    if(pentry[*pno].type == LINUX_EXT2FS)
-+      return &pentry[*pno];
-+    else
-+    {
-+      if(!pentry[*pno].type)
-+        *pno = 0xFE;
-+      else if(pentry[*pno].type == LINUX_SWAP)
-+        *pno = 0xFD;
-+      return NULL;
-+    }
-+  }
-+
-+  for(i = 0; i < 4; i++)
-+    if(pentry[i].type == LINUX_EXT2FS)
-+    {
-+      *pno = i;
-+      return &pentry[i];
-+    }
-+
-+  return NULL;
-+}
-+
-+/*
-+ * Allocate libext2fs structures associated with I/O manager
-+ */
-+static io_channel alloc_io_channel(PARTITION *part)
-+{
-+  io_channel     ioch;
-+
-+  ioch = (io_channel)malloc(sizeof(struct struct_io_channel));
-+  if (!ioch)
-+        return NULL;
-+  memset(ioch, 0, sizeof(struct struct_io_channel));
-+  ioch->magic = EXT2_ET_MAGIC_IO_CHANNEL;
-+  ioch->manager = dos_io_manager;
-+  ioch->name = (char *)malloc(strlen(part->dev)+1);
-+  if (!ioch->name) {
-+        free(ioch);
-+        return NULL;
-+  }
-+  strcpy(ioch->name, part->dev);
-+  ioch->private_data = part;
-+  ioch->block_size = 1024; /* The smallest ext2fs block size */
-+  ioch->read_error = 0;
-+  ioch->write_error = 0;
-+
-+  return ioch;
-+}
-+
-+#ifdef __TURBOC__
-+#pragma argsused
-+#endif
-+/*
-+ * Open the 'name' partition, initialize all information structures
-+ * we need to keep and create libext2fs I/O manager.
-+ */
-+static errcode_t dos_open(const char *dev, int flags, io_channel *channel)
-+{
-+  unsigned char  *tmp, sec[512];
-+  PARTITION      *part;
-+  PTABLE_ENTRY   *pent;
-+  PARTITION        **newparts;
-+  
-+  if(!dev)
-+  {
-+    _dio_error = ERR_BADDEV;
-+    return EXT2_ET_BAD_DEVICE_NAME;
-+  }
-+
-+  /*
-+   * First check whether the dev name is OK
-+   */
-+  tmp = (unsigned char*)strrchr(dev, '/');
-+  if(!tmp)
-+  {
-+    _dio_error = ERR_BADDEV;
-+    return EXT2_ET_BAD_DEVICE_NAME;
-+  }
-+  *tmp = 0;
-+  if(strcmp(dev, "/dev"))
-+  {
-+    _dio_error = ERR_BADDEV;
-+    return EXT2_ET_BAD_DEVICE_NAME;
-+  }
-+  *tmp++ = '/';
-+
-+  /*
-+   * Check whether the partition data is already in cache
-+   */
-+
-+  part = (PARTITION*)malloc(sizeof(PARTITION));
-+  if (!part)
-+        return ENOMEM;
-+  {
-+    int   i = 0;
-+
-+    for(;i < npart; i++)
-+      if(!strcmp(partitions[i]->dev, dev))
-+      {
-+        /* Found it! Make it the active one */
-+        active = partitions[i];
-+        *channel = alloc_io_channel(active);
-+      if (!*channel)
-+              return ENOMEM;
-+        return 0;
-+      }
-+  }
-+
-+  /*
-+   * Drive number & optionally partn number
-+   */
-+  switch(tmp[0])
-+  {
-+    case 'h':
-+    case 's':
-+      part->phys = 0x80;
-+      part->phys += toupper(tmp[2]) - 'A';
-+      /*
-+       * Do we have the partition number?
-+       */
-+      if(tmp[3])
-+        part->pno = isdigit((int)tmp[3]) ? tmp[3] - '0' - 1: 0;
-+      else
-+        part->pno = 0xFF;
-+      break;
-+
-+    case 'f':
-+      if(tmp[2])
-+        part->phys = isdigit((int)tmp[2]) ? tmp[2] - '0' : 0;
-+      else
-+        part->phys = 0x00; /* We'll assume /dev/fd0 */
-+      break;
-+
-+    default:
-+      _dio_error = ERR_BADDEV;
-+      return ENODEV;
-+  }
-+
-+  if(part->phys < 0x80)
-+  {
-+     /* We don't support floppies for now */
-+     _dio_error = ERR_NOTSUPP;
-+     return EINVAL;
-+  }
-+
-+  part->dev = strdup(dev);
-+
-+  /*
-+   * Get drive's geometry
-+   */
-+  _dio_hw_error = biosdisk(DISK_GET_GEOMETRY,
-+                           part->phys,
-+                           0, /* head */
-+                           0, /* cylinder */
-+                           1, /* sector */
-+                           1, /* just one sector */
-+                           sec);
-+
-+  if(!HW_OK())
-+  {
-+    _dio_error = ERR_HARDWARE;
-+    if (part)
-+          free(part);
-+    return EFAULT;
-+  }
-+
-+  /*
-+   * Calculate the geometry
-+   */
-+  part->cyls  = (unsigned short)(((sec[0] >> 6) << 8) + sec[1] + 1);
-+  part->heads = sec[3] + 1;
-+  part->sects = sec[0] & 0x3F;
-+
-+  /*
-+   * Now that we know all we need, let's look for the partition
-+   */
-+  _dio_hw_error = biosdisk(DISK_READ, part->phys, 0, 0, 1, 1, sec);
-+
-+  if(!HW_OK())
-+  {
-+    _dio_error = ERR_HARDWARE;
-+    if (part)
-+          free(part);
-+    return EFAULT;
-+  }
-+
-+  pent = (PTABLE_ENTRY*)&sec[0x1BE];
-+  pent = scan_partition_table(pent, part->phys, &part->pno);
-+
-+  if(!pent)
-+  {
-+    _dio_error = part->pno == 0xFE ? ERR_EMPTYPART :
-+                 part->pno == 0xFD ? ERR_LINUXSWAP : ERR_NOTEXT2FS;
-+    if (part)
-+          free(part);
-+    return ENODEV;
-+  }
-+
-+  /*
-+   * Calculate the remaining figures
-+   */
-+  {
-+    unsigned long    fsec, fhead, fcyl;
-+
-+    fsec = (unsigned long)(pent->start_sec & 0x3F);
-+    fhead = (unsigned long)pent->start_head;
-+    fcyl = ((pent->start_sec >> 6) << 8) + pent->start_cyl;
-+    part->start = fsec + fhead * part->sects + fcyl *
-+                  (part->heads * part->sects) - 1;
-+    part->len = pent->size;
-+  }
-+
-+  /*
-+   * Add the partition to the table
-+   */
-+  newparts = (PARTITION**)realloc(partitions, sizeof(PARTITION) * npart);
-+  if (!newparts) {
-+        free(part);
-+        return ENOMEM;
-+  }
-+  partitions = newparts;
-+  partitions[npart++] = active = part;
-+
-+  /*
-+   * Now alloc all libe2fs structures
-+   */
-+  *channel = alloc_io_channel(active);
-+  if (!*channel)
-+        return ENOMEM;
-+
-+  return 0;
-+}
-+
-+static errcode_t dos_close(io_channel channel)
-+{
-+      if (channel->name)
-+              free(channel->name);
-+      if (channel)
-+              free(channel);
-+
-+      return 0;
-+}
-+
-+static errcode_t dos_set_blksize(io_channel channel, int blksize)
-+{
-+  channel->block_size = blksize;
-+
-+  return 0;
-+}
-+
-+static errcode_t dos_read_blk(io_channel channel, unsigned long block,
-+                                             int count, void *buf)
-+{
-+  PARTITION     *part;
-+  size_t        size;
-+  ext2_loff_t   loc;
-+  CHS           chs;
-+
-+  EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+  part = (PARTITION*)channel->private_data;
-+
-+  size = (size_t)((count < 0) ? -count : count * channel->block_size);
-+  loc = (ext2_loff_t) block * channel->block_size;
-+
-+  lba2chs(loc, &chs, part);
-+  /*
-+   * Potential bug here:
-+   *   If DJGPP is used then reads of >18 sectors will fail!
-+   *   Have to rewrite biosdisk.
-+   */
-+  _dio_hw_error = biosdisk(DISK_READ,
-+                           part->phys,
-+                           chs.head,
-+                           chs.cyl,
-+                           chs.sector,
-+                           size < 512 ? 1 : size/512,
-+                           buf);
-+
-+  if(!HW_OK())
-+  {
-+    _dio_error = ERR_HARDWARE;
-+    return EFAULT;
-+  }
-+
-+  return 0;
-+}
-+
-+static errcode_t dos_write_blk(io_channel channel, unsigned long block,
-+                               int count, const void *buf)
-+{
-+  PARTITION     *part;
-+  size_t        size;
-+  ext2_loff_t   loc;
-+  CHS           chs;
-+
-+  EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+  part = (PARTITION*)channel->private_data;
-+
-+  if(count == 1)
-+    size = (size_t)channel->block_size;
-+  else
-+  {
-+    if (count < 0)
-+      size = (size_t)-count;
-+    else
-+      size = (size_t)(count * channel->block_size);
-+  }
-+
-+  loc = (ext2_loff_t)block * channel->block_size;
-+  lba2chs(loc, &chs, part);
-+  _dio_hw_error = biosdisk(DISK_WRITE,
-+                           part->phys,
-+                           chs.head,
-+                           chs.cyl,
-+                           chs.sector,
-+                           size < 512 ? 1 : size/512,
-+                           (void*)buf);
-+
-+  if(!HW_OK())
-+  {
-+    _dio_error = ERR_HARDWARE;
-+    return EFAULT;
-+  }
-+
-+  return 0;
-+}
-+
-+#ifdef __TURBOC__
-+#pragma argsused
-+#endif
-+static errcode_t dos_flush(io_channel channel)
-+{
-+  /*
-+   * No buffers, no flush...
-+   */
-+  return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/dosio.h busybox/e2fsprogs/ext2fs/dosio.h
---- busybox-1.00/e2fsprogs/ext2fs/dosio.h      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/dosio.h   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,153 @@
-+/*
-+ * v1.0
-+ *
-+ * Disk I/O include file for the ext2fs/DOS library.
-+ *
-+ * Copyright (c) 1997 Mark Habersack
-+ * This file may be distributed under the terms of the GNU Public License.
-+ *
-+ */
-+#ifndef __diskio_h
-+#define __diskio_h
-+#ifdef __TURBOC__
-+#ifndef __LARGE__
-+# error "ext2fs/DOS library requires LARGE model!"
-+#endif
-+#endif
-+
-+#ifdef __TURBOC__
-+#include "msdos.h"
-+#endif
-+
-+/*
-+ * A helper structure used in LBA => CHS conversion
-+ */
-+typedef struct
-+{
-+  unsigned short       cyl;     /* Cylinder (or track) */
-+  unsigned short       head;
-+  unsigned short       sector;
-+  unsigned short       offset;  /* Offset of byte within the sector */
-+} CHS;
-+
-+/*
-+ * All partition data we need is here
-+ */
-+typedef struct
-+{
-+  char                 *dev;  /* _Linux_ device name (like "/dev/hda1") */
-+  unsigned char        phys;  /* Physical DOS drive number */
-+  unsigned long        start; /* LBA address of partition start */
-+  unsigned long        len;   /* length of partition in sectors */
-+  unsigned char        pno;   /* Partition number (read from *dev) */
-+
-+  /* This partition's drive geometry */
-+  unsigned short       cyls;
-+  unsigned short       heads;
-+  unsigned short       sects;
-+} PARTITION;
-+
-+/*
-+ * PC partition table entry format
-+ */
-+#ifdef __DJGPP__
-+#pragma pack(1)
-+#endif
-+typedef struct
-+{
-+  unsigned char        active;
-+  unsigned char        start_head;
-+  unsigned char        start_sec;
-+  unsigned char        start_cyl;
-+  unsigned char        type;
-+  unsigned char        end_head;
-+  unsigned char        end_sec;
-+  unsigned char        end_cyl;
-+  unsigned long        first_sec_rel;
-+  unsigned long        size;
-+} PTABLE_ENTRY;
-+#ifdef __DJGPP__
-+#pragma pack()
-+#endif
-+
-+/*
-+ * INT 0x13 operation codes
-+ */
-+#define DISK_READ          0x02
-+#define DISK_WRITE         0x03
-+#define DISK_GET_GEOMETRY  0x08
-+#define DISK_READY         0x10
-+
-+/*
-+ * Errors to put in _dio_error
-+ */
-+#define ERR_BADDEV         0x00000001L
-+#define ERR_HARDWARE       0x00000002L
-+#define ERR_NOTSUPP        0x00000003L
-+#define ERR_NOTEXT2FS      0x00000004L
-+#define ERR_EMPTYPART      0x00000005L
-+#define ERR_LINUXSWAP      0x00000006L
-+
-+/*
-+ * Functions in diskio.c
-+ */
-+
-+/*
-+ * Variable contains last module's error
-+ */
-+extern unsigned long        _dio_error;
-+
-+/*
-+ * This one contains last hardware error (if _dio_error == ERR_HARDWARE)
-+ */
-+extern unsigned long        _dio_hw_error;
-+
-+/*
-+ * Macros to check for disk hardware errors
-+ */
-+#define HW_OK()             ((unsigned char)_dio_hw_error == 0x00)
-+#define HW_BAD_CMD()        ((unsigned char)_dio_hw_error == 0x01)
-+#define HW_NO_ADDR_MARK()   ((unsigned char)_dio_hw_error == 0x02)
-+#define HW_WRITE_PROT()     ((unsigned char)_dio_hw_error == 0x03)
-+#define HW_NO_SECTOR()      ((unsigned char)_dio_hw_error == 0x04)
-+#define HW_RESET_FAIL()     ((unsigned char)_dio_hw_error == 0x05)
-+#define HW_DISK_CHANGED()   ((unsigned char)_dio_hw_error == 0x06)
-+#define HW_DRIVE_FAIL()     ((unsigned char)_dio_hw_error == 0x07)
-+#define HW_DMA_OVERRUN()    ((unsigned char)_dio_hw_error == 0x08)
-+#define HW_DMA_BOUNDARY()   ((unsigned char)_dio_hw_error == 0x09)
-+#define HW_BAD_SECTOR()     ((unsigned char)_dio_hw_error == 0x0A)
-+#define HW_BAD_TRACK()      ((unsigned char)_dio_hw_error == 0x0B)
-+#define HW_UNSUPP_TRACK()   ((unsigned char)_dio_hw_error == 0x0C)
-+#define HW_BAD_CRC_ECC()    ((unsigned char)_dio_hw_error == 0x10)
-+#define HW_CRC_ECC_CORR()   ((unsigned char)_dio_hw_error == 0x11)
-+#define HW_CONTR_FAIL()     ((unsigned char)_dio_hw_error == 0x20)
-+#define HW_SEEK_FAIL()      ((unsigned char)_dio_hw_error == 0x40)
-+#define HW_ATTACH_FAIL()    ((unsigned char)_dio_hw_error == 0x80)
-+#define HW_DRIVE_NREADY()   ((unsigned char)_dio_hw_error == 0xAA)
-+#define HW_UNDEF_ERROR()    ((unsigned char)_dio_hw_error == 0xBB)
-+#define HW_WRITE_FAULT()    ((unsigned char)_dio_hw_error == 0xCC)
-+#define HW_STATUS_ERROR()   ((unsigned char)_dio_hw_error == 0xE0)
-+#define HW_SENSE_FAIL()     ((unsigned char)_dio_hw_error == 0xFF)
-+
-+
-+/*
-+ * Open the specified partition.
-+ * String 'dev' must have a format:
-+ *
-+ *  /dev/{sd|hd|fd}[X]
-+ *
-+ * where,
-+ *
-+ *  only one of the option in curly braces can be used and X is an optional
-+ *  partition number for the given device. If X is not specified, function
-+ *  scans the drive's partition table in search for the first Linux ext2fs
-+ *  partition (signature 0x83). Along the way it dives into every extended
-+ *  partition encountered.
-+ *  Scan ends if either (a) there are no more used partition entries, or
-+ *  (b) there is no Xth partition.
-+ *
-+ * Routine returns 0 on success and !=0 otherwise.
-+ */
-+int open_partition(char *dev);
-+
-+#endif /* __diskio_h */
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/dupfs.c busybox/e2fsprogs/ext2fs/dupfs.c
---- busybox-1.00/e2fsprogs/ext2fs/dupfs.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/dupfs.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,96 @@
-+/*
-+ * dupfs.c --- duplicate a ext2 filesystem handle
-+ * 
-+ * Copyright (C) 1997, 1998, 2001, 2003, 2005 by Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <time.h>
-+#include <string.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest)
-+{
-+      ext2_filsys     fs;
-+      errcode_t       retval;
-+
-+      EXT2_CHECK_MAGIC(src, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+      
-+      retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
-+      if (retval)
-+              return retval;
-+
-+      *fs = *src;
-+      fs->device_name = 0;
-+      fs->super = 0;
-+      fs->orig_super = 0;
-+      fs->group_desc = 0;
-+      fs->inode_map = 0;
-+      fs->block_map = 0;
-+      fs->badblocks = 0;
-+      fs->dblist = 0;
-+
-+      io_channel_bumpcount(fs->io);
-+      if (fs->icache)
-+              fs->icache->refcount++;
-+
-+      retval = ext2fs_get_mem(strlen(src->device_name)+1, &fs->device_name);
-+      if (retval)
-+              goto errout;
-+      strcpy(fs->device_name, src->device_name);
-+
-+      retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->super);
-+      if (retval)
-+              goto errout;
-+      memcpy(fs->super, src->super, SUPERBLOCK_SIZE);
-+
-+      retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->orig_super);
-+      if (retval)
-+              goto errout;
-+      memcpy(fs->orig_super, src->orig_super, SUPERBLOCK_SIZE);
-+
-+      retval = ext2fs_get_mem((size_t) fs->desc_blocks * fs->blocksize,
-+                              &fs->group_desc);
-+      if (retval)
-+              goto errout;
-+      memcpy(fs->group_desc, src->group_desc,
-+             (size_t) fs->desc_blocks * fs->blocksize);
-+
-+      if (src->inode_map) {
-+              retval = ext2fs_copy_bitmap(src->inode_map, &fs->inode_map);
-+              if (retval)
-+                      goto errout;
-+      }
-+      if (src->block_map) {
-+              retval = ext2fs_copy_bitmap(src->block_map, &fs->block_map);
-+              if (retval)
-+                      goto errout;
-+      }
-+      if (src->badblocks) {
-+              retval = ext2fs_badblocks_copy(src->badblocks, &fs->badblocks);
-+              if (retval)
-+                      goto errout;
-+      }
-+      if (src->dblist) {
-+              retval = ext2fs_copy_dblist(src->dblist, &fs->dblist);
-+              if (retval)
-+                      goto errout;
-+      }
-+      *dest = fs;
-+      return 0;
-+errout:
-+      ext2fs_free(fs);
-+      return retval;
-+      
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/e2image.h busybox/e2fsprogs/ext2fs/e2image.h
---- busybox-1.00/e2fsprogs/ext2fs/e2image.h    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/e2image.h 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,51 @@
-+/*
-+ * e2image.h --- header file describing the ext2 image format
-+ * 
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ *
-+ * Note: this uses the POSIX IO interfaces, unlike most of the other
-+ * functions in this library.  So sue me.  
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+
-+struct ext2_image_hdr {
-+      __u32   magic_number;   /* This must be EXT2_ET_MAGIC_E2IMAGE */
-+      char    magic_descriptor[16]; /* "Ext2 Image 1.0", w/ null padding */
-+      char    fs_hostname[64];/* Hostname of machine of image */
-+      char    fs_netaddr[32]; /* Network address */
-+      __u32   fs_netaddr_type;/* 0 = IPV4, 1 = IPV6, etc. */
-+      __u32   fs_device;      /* Device number of image */
-+      char    fs_device_name[64]; /* Device name */
-+      char    fs_uuid[16];    /* UUID of filesystem */
-+      __u32   fs_blocksize;   /* Block size of the filesystem */
-+      __u32   fs_reserved[8];
-+      
-+      __u32   image_device;   /* Device number of image file */
-+      __u32   image_inode;    /* Inode number of image file */
-+      __u32   image_time;     /* Time of image creation */
-+      __u32   image_reserved[8];
-+
-+      __u32   offset_super;   /* Byte offset of the sb and descriptors */
-+      __u32   offset_inode;   /* Byte offset of the inode table  */
-+      __u32   offset_inodemap; /* Byte offset of the inode bitmaps */
-+      __u32   offset_blockmap; /* Byte offset of the inode bitmaps */
-+      __u32   offset_reserved[8];
-+};
-+
-+      
-+      
-+      
-+      
-+      
-+      
-+      
-+      
-+      
-+      
-+      
-+      
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/expanddir.c busybox/e2fsprogs/ext2fs/expanddir.c
---- busybox-1.00/e2fsprogs/ext2fs/expanddir.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/expanddir.c       2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,126 @@
-+/*
-+ * expand.c --- expand an ext2fs directory
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999  Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct expand_dir_struct {
-+      int             done;
-+      int             newblocks;
-+      errcode_t       err;
-+};
-+
-+static int expand_dir_proc(ext2_filsys        fs,
-+                         blk_t        *blocknr,
-+                         e2_blkcnt_t  blockcnt,
-+                         blk_t        ref_block EXT2FS_ATTR((unused)),
-+                         int          ref_offset EXT2FS_ATTR((unused)),
-+                         void         *priv_data)
-+{
-+      struct expand_dir_struct *es = (struct expand_dir_struct *) priv_data;
-+      blk_t   new_blk;
-+      static blk_t    last_blk = 0;
-+      char            *block;
-+      errcode_t       retval;
-+      
-+      if (*blocknr) {
-+              last_blk = *blocknr;
-+              return 0;
-+      }
-+      retval = ext2fs_new_block(fs, last_blk, 0, &new_blk);
-+      if (retval) {
-+              es->err = retval;
-+              return BLOCK_ABORT;
-+      }
-+      if (blockcnt > 0) {
-+              retval = ext2fs_new_dir_block(fs, 0, 0, &block);
-+              if (retval) {
-+                      es->err = retval;
-+                      return BLOCK_ABORT;
-+              }
-+              es->done = 1;
-+              retval = ext2fs_write_dir_block(fs, new_blk, block);
-+      } else {
-+              retval = ext2fs_get_mem(fs->blocksize, &block);
-+              if (retval) {
-+                      es->err = retval;
-+                      return BLOCK_ABORT;
-+              }
-+              memset(block, 0, fs->blocksize);
-+              retval = io_channel_write_blk(fs->io, new_blk, 1, block);
-+      }       
-+      if (retval) {
-+              es->err = retval;
-+              return BLOCK_ABORT;
-+      }
-+      ext2fs_free_mem(&block);
-+      *blocknr = new_blk;
-+      ext2fs_block_alloc_stats(fs, new_blk, +1);
-+      es->newblocks++;
-+
-+      if (es->done)
-+              return (BLOCK_CHANGED | BLOCK_ABORT);
-+      else
-+              return BLOCK_CHANGED;
-+}
-+
-+errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir)
-+{
-+      errcode_t       retval;
-+      struct expand_dir_struct es;
-+      struct ext2_inode       inode;
-+      
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (!(fs->flags & EXT2_FLAG_RW))
-+              return EXT2_ET_RO_FILSYS;
-+
-+      if (!fs->block_map)
-+              return EXT2_ET_NO_BLOCK_BITMAP;
-+
-+      retval = ext2fs_check_directory(fs, dir);
-+      if (retval)
-+              return retval;
-+      
-+      es.done = 0;
-+      es.err = 0;
-+      es.newblocks = 0;
-+      
-+      retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND,
-+                                     0, expand_dir_proc, &es);
-+
-+      if (es.err)
-+              return es.err;
-+      if (!es.done)
-+              return EXT2_ET_EXPAND_DIR_ERR;
-+
-+      /*
-+       * Update the size and block count fields in the inode.
-+       */
-+      retval = ext2fs_read_inode(fs, dir, &inode);
-+      if (retval)
-+              return retval;
-+      
-+      inode.i_size += fs->blocksize;
-+      inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
-+
-+      retval = ext2fs_write_inode(fs, dir, &inode);
-+      if (retval)
-+              return retval;
-+
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/ext2_err.h busybox/e2fsprogs/ext2fs/ext2_err.h
---- busybox-1.00/e2fsprogs/ext2fs/ext2_err.h   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/ext2_err.h        2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,117 @@
-+/*
-+ * ext2_err.h:
-+ * This file is automatically generated; please do not edit it.
-+ */
-+
-+#include <et/com_err.h>
-+
-+#define EXT2_ET_BASE                             (2133571328L)
-+#define EXT2_ET_MAGIC_EXT2FS_FILSYS              (2133571329L)
-+#define EXT2_ET_MAGIC_BADBLOCKS_LIST             (2133571330L)
-+#define EXT2_ET_MAGIC_BADBLOCKS_ITERATE          (2133571331L)
-+#define EXT2_ET_MAGIC_INODE_SCAN                 (2133571332L)
-+#define EXT2_ET_MAGIC_IO_CHANNEL                 (2133571333L)
-+#define EXT2_ET_MAGIC_UNIX_IO_CHANNEL            (2133571334L)
-+#define EXT2_ET_MAGIC_IO_MANAGER                 (2133571335L)
-+#define EXT2_ET_MAGIC_BLOCK_BITMAP               (2133571336L)
-+#define EXT2_ET_MAGIC_INODE_BITMAP               (2133571337L)
-+#define EXT2_ET_MAGIC_GENERIC_BITMAP             (2133571338L)
-+#define EXT2_ET_MAGIC_TEST_IO_CHANNEL            (2133571339L)
-+#define EXT2_ET_MAGIC_DBLIST                     (2133571340L)
-+#define EXT2_ET_MAGIC_ICOUNT                     (2133571341L)
-+#define EXT2_ET_MAGIC_PQ_IO_CHANNEL              (2133571342L)
-+#define EXT2_ET_MAGIC_EXT2_FILE                  (2133571343L)
-+#define EXT2_ET_MAGIC_E2IMAGE                    (2133571344L)
-+#define EXT2_ET_MAGIC_INODE_IO_CHANNEL           (2133571345L)
-+#define EXT2_ET_MAGIC_RESERVED_9                 (2133571346L)
-+#define EXT2_ET_BAD_MAGIC                        (2133571347L)
-+#define EXT2_ET_REV_TOO_HIGH                     (2133571348L)
-+#define EXT2_ET_RO_FILSYS                        (2133571349L)
-+#define EXT2_ET_GDESC_READ                       (2133571350L)
-+#define EXT2_ET_GDESC_WRITE                      (2133571351L)
-+#define EXT2_ET_GDESC_BAD_BLOCK_MAP              (2133571352L)
-+#define EXT2_ET_GDESC_BAD_INODE_MAP              (2133571353L)
-+#define EXT2_ET_GDESC_BAD_INODE_TABLE            (2133571354L)
-+#define EXT2_ET_INODE_BITMAP_WRITE               (2133571355L)
-+#define EXT2_ET_INODE_BITMAP_READ                (2133571356L)
-+#define EXT2_ET_BLOCK_BITMAP_WRITE               (2133571357L)
-+#define EXT2_ET_BLOCK_BITMAP_READ                (2133571358L)
-+#define EXT2_ET_INODE_TABLE_WRITE                (2133571359L)
-+#define EXT2_ET_INODE_TABLE_READ                 (2133571360L)
-+#define EXT2_ET_NEXT_INODE_READ                  (2133571361L)
-+#define EXT2_ET_UNEXPECTED_BLOCK_SIZE            (2133571362L)
-+#define EXT2_ET_DIR_CORRUPTED                    (2133571363L)
-+#define EXT2_ET_SHORT_READ                       (2133571364L)
-+#define EXT2_ET_SHORT_WRITE                      (2133571365L)
-+#define EXT2_ET_DIR_NO_SPACE                     (2133571366L)
-+#define EXT2_ET_NO_INODE_BITMAP                  (2133571367L)
-+#define EXT2_ET_NO_BLOCK_BITMAP                  (2133571368L)
-+#define EXT2_ET_BAD_INODE_NUM                    (2133571369L)
-+#define EXT2_ET_BAD_BLOCK_NUM                    (2133571370L)
-+#define EXT2_ET_EXPAND_DIR_ERR                   (2133571371L)
-+#define EXT2_ET_TOOSMALL                         (2133571372L)
-+#define EXT2_ET_BAD_BLOCK_MARK                   (2133571373L)
-+#define EXT2_ET_BAD_BLOCK_UNMARK                 (2133571374L)
-+#define EXT2_ET_BAD_BLOCK_TEST                   (2133571375L)
-+#define EXT2_ET_BAD_INODE_MARK                   (2133571376L)
-+#define EXT2_ET_BAD_INODE_UNMARK                 (2133571377L)
-+#define EXT2_ET_BAD_INODE_TEST                   (2133571378L)
-+#define EXT2_ET_FUDGE_BLOCK_BITMAP_END           (2133571379L)
-+#define EXT2_ET_FUDGE_INODE_BITMAP_END           (2133571380L)
-+#define EXT2_ET_BAD_IND_BLOCK                    (2133571381L)
-+#define EXT2_ET_BAD_DIND_BLOCK                   (2133571382L)
-+#define EXT2_ET_BAD_TIND_BLOCK                   (2133571383L)
-+#define EXT2_ET_NEQ_BLOCK_BITMAP                 (2133571384L)
-+#define EXT2_ET_NEQ_INODE_BITMAP                 (2133571385L)
-+#define EXT2_ET_BAD_DEVICE_NAME                  (2133571386L)
-+#define EXT2_ET_MISSING_INODE_TABLE              (2133571387L)
-+#define EXT2_ET_CORRUPT_SUPERBLOCK               (2133571388L)
-+#define EXT2_ET_BAD_GENERIC_MARK                 (2133571389L)
-+#define EXT2_ET_BAD_GENERIC_UNMARK               (2133571390L)
-+#define EXT2_ET_BAD_GENERIC_TEST                 (2133571391L)
-+#define EXT2_ET_SYMLINK_LOOP                     (2133571392L)
-+#define EXT2_ET_CALLBACK_NOTHANDLED              (2133571393L)
-+#define EXT2_ET_BAD_BLOCK_IN_INODE_TABLE         (2133571394L)
-+#define EXT2_ET_UNSUPP_FEATURE                   (2133571395L)
-+#define EXT2_ET_RO_UNSUPP_FEATURE                (2133571396L)
-+#define EXT2_ET_LLSEEK_FAILED                    (2133571397L)
-+#define EXT2_ET_NO_MEMORY                        (2133571398L)
-+#define EXT2_ET_INVALID_ARGUMENT                 (2133571399L)
-+#define EXT2_ET_BLOCK_ALLOC_FAIL                 (2133571400L)
-+#define EXT2_ET_INODE_ALLOC_FAIL                 (2133571401L)
-+#define EXT2_ET_NO_DIRECTORY                     (2133571402L)
-+#define EXT2_ET_TOO_MANY_REFS                    (2133571403L)
-+#define EXT2_ET_FILE_NOT_FOUND                   (2133571404L)
-+#define EXT2_ET_FILE_RO                          (2133571405L)
-+#define EXT2_ET_DB_NOT_FOUND                     (2133571406L)
-+#define EXT2_ET_DIR_EXISTS                       (2133571407L)
-+#define EXT2_ET_UNIMPLEMENTED                    (2133571408L)
-+#define EXT2_ET_CANCEL_REQUESTED                 (2133571409L)
-+#define EXT2_ET_FILE_TOO_BIG                     (2133571410L)
-+#define EXT2_ET_JOURNAL_NOT_BLOCK                (2133571411L)
-+#define EXT2_ET_NO_JOURNAL_SB                    (2133571412L)
-+#define EXT2_ET_JOURNAL_TOO_SMALL                (2133571413L)
-+#define EXT2_ET_JOURNAL_UNSUPP_VERSION           (2133571414L)
-+#define EXT2_ET_LOAD_EXT_JOURNAL                 (2133571415L)
-+#define EXT2_ET_NO_JOURNAL                       (2133571416L)
-+#define EXT2_ET_DIRHASH_UNSUPP                   (2133571417L)
-+#define EXT2_ET_BAD_EA_BLOCK_NUM                 (2133571418L)
-+#define EXT2_ET_TOO_MANY_INODES                  (2133571419L)
-+#define EXT2_ET_NOT_IMAGE_FILE                   (2133571420L)
-+#define EXT2_ET_RES_GDT_BLOCKS                   (2133571421L)
-+#define EXT2_ET_RESIZE_INODE_CORRUPT             (2133571422L)
-+#define EXT2_ET_SET_BMAP_NO_IND                  (2133571423L)
-+
-+#if 0
-+extern const struct error_table et_ext2_error_table;
-+extern void initialize_ext2_error_table(void);
-+
-+/* For compatibility with Heimdal */
-+extern void initialize_ext2_error_table_r(struct et_list **list);
-+
-+#define ERROR_TABLE_BASE_ext2 (2133571328L)
-+
-+/* for compatibility with older versions... */
-+#define init_ext2_err_tbl initialize_ext2_error_table
-+#define ext2_err_base ERROR_TABLE_BASE_ext2
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/ext2_ext_attr.h busybox/e2fsprogs/ext2fs/ext2_ext_attr.h
---- busybox-1.00/e2fsprogs/ext2fs/ext2_ext_attr.h      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/ext2_ext_attr.h   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,69 @@
-+/*
-+  File: linux/ext2_ext_attr.h
-+
-+  On-disk format of extended attributes for the ext2 filesystem.
-+
-+  (C) 2000 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+*/
-+
-+/* Magic value in attribute blocks */
-+#define EXT2_EXT_ATTR_MAGIC_v1                0xEA010000
-+#define EXT2_EXT_ATTR_MAGIC           0xEA020000
-+
-+/* Maximum number of references to one attribute block */
-+#define EXT2_EXT_ATTR_REFCOUNT_MAX    1024
-+
-+struct ext2_ext_attr_header {
-+      __u32   h_magic;        /* magic number for identification */
-+      __u32   h_refcount;     /* reference count */
-+      __u32   h_blocks;       /* number of disk blocks used */
-+      __u32   h_hash;         /* hash value of all attributes */
-+      __u32   h_reserved[4];  /* zero right now */
-+};
-+
-+struct ext2_ext_attr_entry {
-+      __u8    e_name_len;     /* length of name */
-+      __u8    e_name_index;   /* attribute name index */
-+      __u16   e_value_offs;   /* offset in disk block of value */
-+      __u32   e_value_block;  /* disk block attribute is stored on (n/i) */
-+      __u32   e_value_size;   /* size of attribute value */
-+      __u32   e_hash;         /* hash value of name and value */
-+#if 0
-+      char    e_name[0];      /* attribute name */
-+#endif
-+};
-+
-+#define EXT2_EXT_ATTR_PAD_BITS                2
-+#define EXT2_EXT_ATTR_PAD             (1<<EXT2_EXT_ATTR_PAD_BITS)
-+#define EXT2_EXT_ATTR_ROUND           (EXT2_EXT_ATTR_PAD-1)
-+#define EXT2_EXT_ATTR_LEN(name_len) \
-+      (((name_len) + EXT2_EXT_ATTR_ROUND + \
-+      sizeof(struct ext2_ext_attr_entry)) & ~EXT2_EXT_ATTR_ROUND)
-+#define EXT2_EXT_ATTR_NEXT(entry) \
-+      ( (struct ext2_ext_attr_entry *)( \
-+        (char *)(entry) + EXT2_EXT_ATTR_LEN((entry)->e_name_len)) )
-+#define EXT2_EXT_ATTR_SIZE(size) \
-+      (((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND)
-+#define EXT2_EXT_IS_LAST_ENTRY(entry) (*((__u32 *)(entry)) == 0UL)
-+#define EXT2_EXT_ATTR_NAME(entry) \
-+      (((char *) (entry)) + sizeof(struct ext2_ext_attr_entry))
-+#define EXT2_XATTR_LEN(name_len) \
-+      (((name_len) + EXT2_EXT_ATTR_ROUND + \
-+      sizeof(struct ext2_xattr_entry)) & ~EXT2_EXT_ATTR_ROUND)
-+#define EXT2_XATTR_SIZE(size) \
-+      (((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND)
-+
-+#ifdef __KERNEL__
-+# ifdef CONFIG_EXT2_FS_EXT_ATTR
-+extern int ext2_get_ext_attr(struct inode *, const char *, char *, size_t, int);
-+extern int ext2_set_ext_attr(struct inode *, const char *, char *, size_t, int);
-+extern void ext2_ext_attr_free_inode(struct inode *inode);
-+extern void ext2_ext_attr_put_super(struct super_block *sb);
-+extern int ext2_ext_attr_init(void);
-+extern void ext2_ext_attr_done(void);
-+# else
-+#  define ext2_get_ext_attr NULL
-+#  define ext2_set_ext_attr NULL
-+# endif
-+#endif  /* __KERNEL__ */
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/ext2_fs.h busybox/e2fsprogs/ext2fs/ext2_fs.h
---- busybox-1.00/e2fsprogs/ext2fs/ext2_fs.h    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/ext2_fs.h 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,644 @@
-+/*
-+ *  linux/include/linux/ext2_fs.h
-+ *
-+ * Copyright (C) 1992, 1993, 1994, 1995
-+ * Remy Card (card@masi.ibp.fr)
-+ * Laboratoire MASI - Institut Blaise Pascal
-+ * Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ *  from
-+ *
-+ *  linux/include/linux/minix_fs.h
-+ *
-+ *  Copyright (C) 1991, 1992  Linus Torvalds
-+ */
-+
-+#ifndef _LINUX_EXT2_FS_H
-+#define _LINUX_EXT2_FS_H
-+
-+#include <ext2fs/ext2_types.h>                /* Changed from linux/types.h */
-+
-+/*
-+ * The second extended filesystem constants/structures
-+ */
-+
-+/*
-+ * Define EXT2FS_DEBUG to produce debug messages
-+ */
-+#undef EXT2FS_DEBUG
-+
-+/*
-+ * Define EXT2_PREALLOCATE to preallocate data blocks for expanding files
-+ */
-+#define EXT2_PREALLOCATE
-+#define EXT2_DEFAULT_PREALLOC_BLOCKS  8
-+
-+/*
-+ * The second extended file system version
-+ */
-+#define EXT2FS_DATE           "95/08/09"
-+#define EXT2FS_VERSION                "0.5b"
-+
-+/*
-+ * Special inode numbers
-+ */
-+#define EXT2_BAD_INO           1      /* Bad blocks inode */
-+#define EXT2_ROOT_INO          2      /* Root inode */
-+#define EXT2_ACL_IDX_INO       3      /* ACL inode */
-+#define EXT2_ACL_DATA_INO      4      /* ACL inode */
-+#define EXT2_BOOT_LOADER_INO   5      /* Boot loader inode */
-+#define EXT2_UNDEL_DIR_INO     6      /* Undelete directory inode */
-+#define EXT2_RESIZE_INO                7      /* Reserved group descriptors inode */
-+#define EXT2_JOURNAL_INO       8      /* Journal inode */
-+
-+/* First non-reserved inode for old ext2 filesystems */
-+#define EXT2_GOOD_OLD_FIRST_INO       11
-+
-+/*
-+ * The second extended file system magic number
-+ */
-+#define EXT2_SUPER_MAGIC      0xEF53
-+
-+#ifdef __KERNEL__
-+#define EXT2_SB(sb)   (&((sb)->u.ext2_sb))
-+#else
-+/* Assume that user mode programs are passing in an ext2fs superblock, not
-+ * a kernel struct super_block.  This will allow us to call the feature-test
-+ * macros from user land. */
-+#define EXT2_SB(sb)   (sb)
-+#endif
-+
-+/*
-+ * Maximal count of links to a file
-+ */
-+#define EXT2_LINK_MAX         32000
-+
-+/*
-+ * Macro-instructions used to manage several block sizes
-+ */
-+#define EXT2_MIN_BLOCK_LOG_SIZE               10      /* 1024 */
-+#define EXT2_MAX_BLOCK_LOG_SIZE               16      /* 65536 */
-+#define EXT2_MIN_BLOCK_SIZE   (1 << EXT2_MIN_BLOCK_LOG_SIZE)
-+#define EXT2_MAX_BLOCK_SIZE   (1 << EXT2_MAX_BLOCK_LOG_SIZE)
-+#ifdef __KERNEL__
-+#define EXT2_BLOCK_SIZE(s)    ((s)->s_blocksize)
-+#define EXT2_BLOCK_SIZE_BITS(s)       ((s)->s_blocksize_bits)
-+#define EXT2_ADDR_PER_BLOCK_BITS(s)   (EXT2_SB(s)->addr_per_block_bits)
-+#define EXT2_INODE_SIZE(s)    (EXT2_SB(s)->s_inode_size)
-+#define EXT2_FIRST_INO(s)     (EXT2_SB(s)->s_first_ino)
-+#else
-+#define EXT2_BLOCK_SIZE(s)    (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
-+#define EXT2_BLOCK_SIZE_BITS(s)       ((s)->s_log_block_size + 10)
-+#define EXT2_INODE_SIZE(s)    (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
-+                               EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size)
-+#define EXT2_FIRST_INO(s)     (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
-+                               EXT2_GOOD_OLD_FIRST_INO : (s)->s_first_ino)
-+#endif
-+#define EXT2_ADDR_PER_BLOCK(s)        (EXT2_BLOCK_SIZE(s) / sizeof(__u32))
-+
-+/*
-+ * Macro-instructions used to manage fragments
-+ */
-+#define EXT2_MIN_FRAG_SIZE            EXT2_MIN_BLOCK_SIZE
-+#define EXT2_MAX_FRAG_SIZE            EXT2_MAX_BLOCK_SIZE
-+#define EXT2_MIN_FRAG_LOG_SIZE                EXT2_MIN_BLOCK_LOG_SIZE
-+#ifdef __KERNEL__
-+# define EXT2_FRAG_SIZE(s)            (EXT2_SB(s)->s_frag_size)
-+# define EXT2_FRAGS_PER_BLOCK(s)      (EXT2_SB(s)->s_frags_per_block)
-+#else
-+# define EXT2_FRAG_SIZE(s)            (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
-+# define EXT2_FRAGS_PER_BLOCK(s)      (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
-+#endif
-+
-+/*
-+ * ACL structures
-+ */
-+struct ext2_acl_header        /* Header of Access Control Lists */
-+{
-+      __u32   aclh_size;
-+      __u32   aclh_file_count;
-+      __u32   aclh_acle_count;
-+      __u32   aclh_first_acle;
-+};
-+
-+struct ext2_acl_entry /* Access Control List Entry */
-+{
-+      __u32   acle_size;
-+      __u16   acle_perms;     /* Access permissions */
-+      __u16   acle_type;      /* Type of entry */
-+      __u16   acle_tag;       /* User or group identity */
-+      __u16   acle_pad1;
-+      __u32   acle_next;      /* Pointer on next entry for the */
-+                                      /* same inode or on next free entry */
-+};
-+
-+/*
-+ * Structure of a blocks group descriptor
-+ */
-+struct ext2_group_desc
-+{
-+      __u32   bg_block_bitmap;                /* Blocks bitmap block */
-+      __u32   bg_inode_bitmap;                /* Inodes bitmap block */
-+      __u32   bg_inode_table;         /* Inodes table block */
-+      __u16   bg_free_blocks_count;   /* Free blocks count */
-+      __u16   bg_free_inodes_count;   /* Free inodes count */
-+      __u16   bg_used_dirs_count;     /* Directories count */
-+      __u16   bg_pad;
-+      __u32   bg_reserved[3];
-+};
-+
-+/*
-+ * Data structures used by the directory indexing feature
-+ *
-+ * Note: all of the multibyte integer fields are little endian.
-+ */
-+
-+/*
-+ * Note: dx_root_info is laid out so that if it should somehow get
-+ * overlaid by a dirent the two low bits of the hash version will be
-+ * zero.  Therefore, the hash version mod 4 should never be 0.
-+ * Sincerely, the paranoia department.
-+ */
-+struct ext2_dx_root_info {
-+      __u32 reserved_zero;
-+      __u8 hash_version; /* 0 now, 1 at release */
-+      __u8 info_length; /* 8 */
-+      __u8 indirect_levels;
-+      __u8 unused_flags;
-+};
-+
-+#define EXT2_HASH_LEGACY      0
-+#define EXT2_HASH_HALF_MD4    1
-+#define EXT2_HASH_TEA         2
-+
-+#define EXT2_HASH_FLAG_INCOMPAT       0x1
-+
-+struct ext2_dx_entry {
-+      __u32 hash;
-+      __u32 block;
-+};
-+
-+struct ext2_dx_countlimit {
-+      __u16 limit;
-+      __u16 count;
-+};
-+
-+
-+/*
-+ * Macro-instructions used to manage group descriptors
-+ */
-+#define EXT2_BLOCKS_PER_GROUP(s)      (EXT2_SB(s)->s_blocks_per_group)
-+#define EXT2_INODES_PER_GROUP(s)      (EXT2_SB(s)->s_inodes_per_group)
-+#define EXT2_INODES_PER_BLOCK(s)      (EXT2_BLOCK_SIZE(s)/EXT2_INODE_SIZE(s))
-+/* limits imposed by 16-bit value gd_free_{blocks,inode}_count */
-+#define EXT2_MAX_BLOCKS_PER_GROUP(s)  ((1 << 16) - 8)
-+#define EXT2_MAX_INODES_PER_GROUP(s)  ((1 << 16) - EXT2_INODES_PER_BLOCK(s))
-+#ifdef __KERNEL__
-+#define EXT2_DESC_PER_BLOCK(s)                (EXT2_SB(s)->s_desc_per_block)
-+#define EXT2_DESC_PER_BLOCK_BITS(s)   (EXT2_SB(s)->s_desc_per_block_bits)
-+#else
-+#define EXT2_DESC_PER_BLOCK(s)                (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc))
-+#endif
-+
-+/*
-+ * Constants relative to the data blocks
-+ */
-+#define EXT2_NDIR_BLOCKS              12
-+#define EXT2_IND_BLOCK                        EXT2_NDIR_BLOCKS
-+#define EXT2_DIND_BLOCK                       (EXT2_IND_BLOCK + 1)
-+#define EXT2_TIND_BLOCK                       (EXT2_DIND_BLOCK + 1)
-+#define EXT2_N_BLOCKS                 (EXT2_TIND_BLOCK + 1)
-+
-+/*
-+ * Inode flags
-+ */
-+#define EXT2_SECRM_FL                 0x00000001 /* Secure deletion */
-+#define EXT2_UNRM_FL                  0x00000002 /* Undelete */
-+#define EXT2_COMPR_FL                 0x00000004 /* Compress file */
-+#define EXT2_SYNC_FL                  0x00000008 /* Synchronous updates */
-+#define EXT2_IMMUTABLE_FL             0x00000010 /* Immutable file */
-+#define EXT2_APPEND_FL                        0x00000020 /* writes to file may only append */
-+#define EXT2_NODUMP_FL                        0x00000040 /* do not dump file */
-+#define EXT2_NOATIME_FL                       0x00000080 /* do not update atime */
-+/* Reserved for compression usage... */
-+#define EXT2_DIRTY_FL                 0x00000100
-+#define EXT2_COMPRBLK_FL              0x00000200 /* One or more compressed clusters */
-+#define EXT2_NOCOMPR_FL                       0x00000400 /* Access raw compressed data */
-+#define EXT2_ECOMPR_FL                        0x00000800 /* Compression error */
-+/* End compression flags --- maybe not all used */
-+#define EXT2_BTREE_FL                 0x00001000 /* btree format dir */
-+#define EXT2_INDEX_FL                 0x00001000 /* hash-indexed directory */
-+#define EXT2_IMAGIC_FL                        0x00002000
-+#define EXT3_JOURNAL_DATA_FL          0x00004000 /* file data should be journaled */
-+#define EXT2_NOTAIL_FL                        0x00008000 /* file tail should not be merged */
-+#define EXT2_DIRSYNC_FL               0x00010000 /* Synchronous directory modifications */
-+#define EXT2_TOPDIR_FL                        0x00020000 /* Top of directory hierarchies*/
-+#define EXT3_EXTENTS_FL               0x00080000 /* Inode uses extents */
-+#define EXT2_RESERVED_FL              0x80000000 /* reserved for ext2 lib */
-+
-+#define EXT2_FL_USER_VISIBLE          0x0003DFFF /* User visible flags */
-+#define EXT2_FL_USER_MODIFIABLE               0x000080FF /* User modifiable flags */
-+
-+/*
-+ * ioctl commands
-+ */
-+#define EXT2_IOC_GETFLAGS             _IOR('f', 1, long)
-+#define EXT2_IOC_SETFLAGS             _IOW('f', 2, long)
-+#define EXT2_IOC_GETVERSION           _IOR('v', 1, long)
-+#define EXT2_IOC_SETVERSION           _IOW('v', 2, long)
-+
-+/*
-+ * Structure of an inode on the disk
-+ */
-+struct ext2_inode {
-+      __u16   i_mode;         /* File mode */
-+      __u16   i_uid;          /* Low 16 bits of Owner Uid */
-+      __u32   i_size;         /* Size in bytes */
-+      __u32   i_atime;        /* Access time */
-+      __u32   i_ctime;        /* Creation time */
-+      __u32   i_mtime;        /* Modification time */
-+      __u32   i_dtime;        /* Deletion Time */
-+      __u16   i_gid;          /* Low 16 bits of Group Id */
-+      __u16   i_links_count;  /* Links count */
-+      __u32   i_blocks;       /* Blocks count */
-+      __u32   i_flags;        /* File flags */
-+      union {
-+              struct {
-+                      __u32  l_i_reserved1;
-+              } linux1;
-+              struct {
-+                      __u32  h_i_translator;
-+              } hurd1;
-+              struct {
-+                      __u32  m_i_reserved1;
-+              } masix1;
-+      } osd1;                         /* OS dependent 1 */
-+      __u32   i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
-+      __u32   i_generation;   /* File version (for NFS) */
-+      __u32   i_file_acl;     /* File ACL */
-+      __u32   i_dir_acl;      /* Directory ACL */
-+      __u32   i_faddr;        /* Fragment address */
-+      union {
-+              struct {
-+                      __u8    l_i_frag;       /* Fragment number */
-+                      __u8    l_i_fsize;      /* Fragment size */
-+                      __u16   i_pad1;
-+                      __u16   l_i_uid_high;   /* these 2 fields    */
-+                      __u16   l_i_gid_high;   /* were reserved2[0] */
-+                      __u32   l_i_reserved2;
-+              } linux2;
-+              struct {
-+                      __u8    h_i_frag;       /* Fragment number */
-+                      __u8    h_i_fsize;      /* Fragment size */
-+                      __u16   h_i_mode_high;
-+                      __u16   h_i_uid_high;
-+                      __u16   h_i_gid_high;
-+                      __u32   h_i_author;
-+              } hurd2;
-+              struct {
-+                      __u8    m_i_frag;       /* Fragment number */
-+                      __u8    m_i_fsize;      /* Fragment size */
-+                      __u16   m_pad1;
-+                      __u32   m_i_reserved2[2];
-+              } masix2;
-+      } osd2;                         /* OS dependent 2 */
-+};
-+
-+/*
-+ * Permanent part of an large inode on the disk
-+ */
-+struct ext2_inode_large {
-+      __u16   i_mode;         /* File mode */
-+      __u16   i_uid;          /* Low 16 bits of Owner Uid */
-+      __u32   i_size;         /* Size in bytes */
-+      __u32   i_atime;        /* Access time */
-+      __u32   i_ctime;        /* Creation time */
-+      __u32   i_mtime;        /* Modification time */
-+      __u32   i_dtime;        /* Deletion Time */
-+      __u16   i_gid;          /* Low 16 bits of Group Id */
-+      __u16   i_links_count;  /* Links count */
-+      __u32   i_blocks;       /* Blocks count */
-+      __u32   i_flags;        /* File flags */
-+      union {
-+              struct {
-+                      __u32  l_i_reserved1;
-+              } linux1;
-+              struct {
-+                      __u32  h_i_translator;
-+              } hurd1;
-+              struct {
-+                      __u32  m_i_reserved1;
-+              } masix1;
-+      } osd1;                         /* OS dependent 1 */
-+      __u32   i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
-+      __u32   i_generation;   /* File version (for NFS) */
-+      __u32   i_file_acl;     /* File ACL */
-+      __u32   i_dir_acl;      /* Directory ACL */
-+      __u32   i_faddr;        /* Fragment address */
-+      union {
-+              struct {
-+                      __u8    l_i_frag;       /* Fragment number */
-+                      __u8    l_i_fsize;      /* Fragment size */
-+                      __u16   i_pad1;
-+                      __u16   l_i_uid_high;   /* these 2 fields    */
-+                      __u16   l_i_gid_high;   /* were reserved2[0] */
-+                      __u32   l_i_reserved2;
-+              } linux2;
-+              struct {
-+                      __u8    h_i_frag;       /* Fragment number */
-+                      __u8    h_i_fsize;      /* Fragment size */
-+                      __u16   h_i_mode_high;
-+                      __u16   h_i_uid_high;
-+                      __u16   h_i_gid_high;
-+                      __u32   h_i_author;
-+              } hurd2;
-+              struct {
-+                      __u8    m_i_frag;       /* Fragment number */
-+                      __u8    m_i_fsize;      /* Fragment size */
-+                      __u16   m_pad1;
-+                      __u32   m_i_reserved2[2];
-+              } masix2;
-+      } osd2;                         /* OS dependent 2 */
-+      __u16   i_extra_isize;
-+      __u16   i_pad1;
-+};
-+
-+#define i_size_high   i_dir_acl
-+
-+#if defined(__KERNEL__) || defined(__linux__)
-+#define i_reserved1   osd1.linux1.l_i_reserved1
-+#define i_frag                osd2.linux2.l_i_frag
-+#define i_fsize               osd2.linux2.l_i_fsize
-+#define i_uid_low     i_uid
-+#define i_gid_low     i_gid
-+#define i_uid_high    osd2.linux2.l_i_uid_high
-+#define i_gid_high    osd2.linux2.l_i_gid_high
-+#define i_reserved2   osd2.linux2.l_i_reserved2
-+
-+#else
-+#if defined(__GNU__)
-+
-+#define i_translator  osd1.hurd1.h_i_translator
-+#define i_frag                osd2.hurd2.h_i_frag;
-+#define i_fsize               osd2.hurd2.h_i_fsize;
-+#define i_uid_high    osd2.hurd2.h_i_uid_high
-+#define i_gid_high    osd2.hurd2.h_i_gid_high
-+#define i_author      osd2.hurd2.h_i_author
-+
-+#else
-+#if defined(__masix__)
-+
-+#define i_reserved1   osd1.masix1.m_i_reserved1
-+#define i_frag                osd2.masix2.m_i_frag
-+#define i_fsize               osd2.masix2.m_i_fsize
-+#define i_reserved2   osd2.masix2.m_i_reserved2
-+
-+#endif  /* __masix__ */
-+#endif  /* __GNU__ */
-+#endif        /* defined(__KERNEL__) || defined(__linux__) */
-+
-+/*
-+ * File system states
-+ */
-+#define EXT2_VALID_FS                 0x0001  /* Unmounted cleanly */
-+#define EXT2_ERROR_FS                 0x0002  /* Errors detected */
-+
-+/*
-+ * Mount flags
-+ */
-+#define EXT2_MOUNT_CHECK              0x0001  /* Do mount-time checks */
-+#define EXT2_MOUNT_GRPID              0x0004  /* Create files with directory's group */
-+#define EXT2_MOUNT_DEBUG              0x0008  /* Some debugging messages */
-+#define EXT2_MOUNT_ERRORS_CONT                0x0010  /* Continue on errors */
-+#define EXT2_MOUNT_ERRORS_RO          0x0020  /* Remount fs ro on errors */
-+#define EXT2_MOUNT_ERRORS_PANIC               0x0040  /* Panic on errors */
-+#define EXT2_MOUNT_MINIX_DF           0x0080  /* Mimics the Minix statfs */
-+#define EXT2_MOUNT_NO_UID32           0x0200  /* Disable 32-bit UIDs */
-+
-+#define clear_opt(o, opt)             o &= ~EXT2_MOUNT_##opt
-+#define set_opt(o, opt)                       o |= EXT2_MOUNT_##opt
-+#define test_opt(sb, opt)             (EXT2_SB(sb)->s_mount_opt & \
-+                                       EXT2_MOUNT_##opt)
-+/*
-+ * Maximal mount counts between two filesystem checks
-+ */
-+#define EXT2_DFL_MAX_MNT_COUNT                20      /* Allow 20 mounts */
-+#define EXT2_DFL_CHECKINTERVAL                0       /* Don't use interval check */
-+
-+/*
-+ * Behaviour when detecting errors
-+ */
-+#define EXT2_ERRORS_CONTINUE          1       /* Continue execution */
-+#define EXT2_ERRORS_RO                        2       /* Remount fs read-only */
-+#define EXT2_ERRORS_PANIC             3       /* Panic */
-+#define EXT2_ERRORS_DEFAULT           EXT2_ERRORS_CONTINUE
-+
-+/*
-+ * Structure of the super block
-+ */
-+struct ext2_super_block {
-+      __u32   s_inodes_count;         /* Inodes count */
-+      __u32   s_blocks_count;         /* Blocks count */
-+      __u32   s_r_blocks_count;       /* Reserved blocks count */
-+      __u32   s_free_blocks_count;    /* Free blocks count */
-+      __u32   s_free_inodes_count;    /* Free inodes count */
-+      __u32   s_first_data_block;     /* First Data Block */
-+      __u32   s_log_block_size;       /* Block size */
-+      __s32   s_log_frag_size;        /* Fragment size */
-+      __u32   s_blocks_per_group;     /* # Blocks per group */
-+      __u32   s_frags_per_group;      /* # Fragments per group */
-+      __u32   s_inodes_per_group;     /* # Inodes per group */
-+      __u32   s_mtime;                /* Mount time */
-+      __u32   s_wtime;                /* Write time */
-+      __u16   s_mnt_count;            /* Mount count */
-+      __s16   s_max_mnt_count;        /* Maximal mount count */
-+      __u16   s_magic;                /* Magic signature */
-+      __u16   s_state;                /* File system state */
-+      __u16   s_errors;               /* Behaviour when detecting errors */
-+      __u16   s_minor_rev_level;      /* minor revision level */
-+      __u32   s_lastcheck;            /* time of last check */
-+      __u32   s_checkinterval;        /* max. time between checks */
-+      __u32   s_creator_os;           /* OS */
-+      __u32   s_rev_level;            /* Revision level */
-+      __u16   s_def_resuid;           /* Default uid for reserved blocks */
-+      __u16   s_def_resgid;           /* Default gid for reserved blocks */
-+      /*
-+       * These fields are for EXT2_DYNAMIC_REV superblocks only.
-+       *
-+       * Note: the difference between the compatible feature set and
-+       * the incompatible feature set is that if there is a bit set
-+       * in the incompatible feature set that the kernel doesn't
-+       * know about, it should refuse to mount the filesystem.
-+       *
-+       * e2fsck's requirements are more strict; if it doesn't know
-+       * about a feature in either the compatible or incompatible
-+       * feature set, it must abort and not try to meddle with
-+       * things it doesn't understand...
-+       */
-+      __u32   s_first_ino;            /* First non-reserved inode */
-+      __u16   s_inode_size;           /* size of inode structure */
-+      __u16   s_block_group_nr;       /* block group # of this superblock */
-+      __u32   s_feature_compat;       /* compatible feature set */
-+      __u32   s_feature_incompat;     /* incompatible feature set */
-+      __u32   s_feature_ro_compat;    /* readonly-compatible feature set */
-+      __u8    s_uuid[16];             /* 128-bit uuid for volume */
-+      char    s_volume_name[16];      /* volume name */
-+      char    s_last_mounted[64];     /* directory where last mounted */
-+      __u32   s_algorithm_usage_bitmap; /* For compression */
-+      /*
-+       * Performance hints.  Directory preallocation should only
-+       * happen if the EXT2_FEATURE_COMPAT_DIR_PREALLOC flag is on.
-+       */
-+      __u8    s_prealloc_blocks;      /* Nr of blocks to try to preallocate*/
-+      __u8    s_prealloc_dir_blocks;  /* Nr to preallocate for dirs */
-+      __u16   s_reserved_gdt_blocks;  /* Per group table for online growth */
-+      /*
-+       * Journaling support valid if EXT2_FEATURE_COMPAT_HAS_JOURNAL set.
-+       */
-+      __u8    s_journal_uuid[16];     /* uuid of journal superblock */
-+      __u32   s_journal_inum;         /* inode number of journal file */
-+      __u32   s_journal_dev;          /* device number of journal file */
-+      __u32   s_last_orphan;          /* start of list of inodes to delete */
-+      __u32   s_hash_seed[4];         /* HTREE hash seed */
-+      __u8    s_def_hash_version;     /* Default hash version to use */
-+      __u8    s_jnl_backup_type;      /* Default type of journal backup */
-+      __u16   s_reserved_word_pad;
-+      __u32   s_default_mount_opts;
-+      __u32   s_first_meta_bg;        /* First metablock group */
-+      __u32   s_mkfs_time;            /* When the filesystem was created */
-+      __u32   s_jnl_blocks[17];       /* Backup of the journal inode */
-+      __u32   s_reserved[172];        /* Padding to the end of the block */
-+};
-+
-+/*
-+ * Codes for operating systems
-+ */
-+#define EXT2_OS_LINUX         0
-+#define EXT2_OS_HURD          1
-+#define EXT2_OS_MASIX         2
-+#define EXT2_OS_FREEBSD               3
-+#define EXT2_OS_LITES         4
-+
-+/*
-+ * Revision levels
-+ */
-+#define EXT2_GOOD_OLD_REV     0       /* The good old (original) format */
-+#define EXT2_DYNAMIC_REV      1       /* V2 format w/ dynamic inode sizes */
-+
-+#define EXT2_CURRENT_REV      EXT2_GOOD_OLD_REV
-+#define EXT2_MAX_SUPP_REV     EXT2_DYNAMIC_REV
-+
-+#define EXT2_GOOD_OLD_INODE_SIZE 128
-+
-+/*
-+ * Journal inode backup types
-+ */
-+#define EXT3_JNL_BACKUP_BLOCKS        1
-+
-+/*
-+ * Feature set definitions
-+ */
-+
-+#define EXT2_HAS_COMPAT_FEATURE(sb,mask)                      \
-+      ( EXT2_SB(sb)->s_feature_compat & (mask) )
-+#define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask)                   \
-+      ( EXT2_SB(sb)->s_feature_ro_compat & (mask) )
-+#define EXT2_HAS_INCOMPAT_FEATURE(sb,mask)                    \
-+      ( EXT2_SB(sb)->s_feature_incompat & (mask) )
-+
-+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC      0x0001
-+#define EXT2_FEATURE_COMPAT_IMAGIC_INODES     0x0002
-+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL               0x0004
-+#define EXT2_FEATURE_COMPAT_EXT_ATTR          0x0008
-+#define EXT2_FEATURE_COMPAT_RESIZE_INODE      0x0010
-+#define EXT2_FEATURE_COMPAT_DIR_INDEX         0x0020
-+
-+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER   0x0001
-+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE     0x0002
-+/* #define EXT2_FEATURE_RO_COMPAT_BTREE_DIR   0x0004 not used */
-+
-+#define EXT2_FEATURE_INCOMPAT_COMPRESSION     0x0001
-+#define EXT2_FEATURE_INCOMPAT_FILETYPE                0x0002
-+#define EXT3_FEATURE_INCOMPAT_RECOVER         0x0004 /* Needs recovery */
-+#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV     0x0008 /* Journal device */
-+#define EXT2_FEATURE_INCOMPAT_META_BG         0x0010
-+#define EXT3_FEATURE_INCOMPAT_EXTENTS         0x0040
-+
-+
-+#define EXT2_FEATURE_COMPAT_SUPP      0
-+#define EXT2_FEATURE_INCOMPAT_SUPP    (EXT2_FEATURE_INCOMPAT_FILETYPE)
-+#define EXT2_FEATURE_RO_COMPAT_SUPP   (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
-+                                       EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
-+                                       EXT2_FEATURE_RO_COMPAT_BTREE_DIR)
-+
-+/*
-+ * Default values for user and/or group using reserved blocks
-+ */
-+#define EXT2_DEF_RESUID               0
-+#define EXT2_DEF_RESGID               0
-+
-+/*
-+ * Default mount options
-+ */
-+#define EXT2_DEFM_DEBUG               0x0001
-+#define EXT2_DEFM_BSDGROUPS   0x0002
-+#define EXT2_DEFM_XATTR_USER  0x0004
-+#define EXT2_DEFM_ACL         0x0008
-+#define EXT2_DEFM_UID16               0x0010
-+#define EXT3_DEFM_JMODE               0x0060 
-+#define EXT3_DEFM_JMODE_DATA  0x0020
-+#define EXT3_DEFM_JMODE_ORDERED       0x0040
-+#define EXT3_DEFM_JMODE_WBACK 0x0060
-+
-+/*
-+ * Structure of a directory entry
-+ */
-+#define EXT2_NAME_LEN 255
-+
-+struct ext2_dir_entry {
-+      __u32   inode;                  /* Inode number */
-+      __u16   rec_len;                /* Directory entry length */
-+      __u16   name_len;               /* Name length */
-+      char    name[EXT2_NAME_LEN];    /* File name */
-+};
-+
-+/*
-+ * The new version of the directory entry.  Since EXT2 structures are
-+ * stored in intel byte order, and the name_len field could never be
-+ * bigger than 255 chars, it's safe to reclaim the extra byte for the
-+ * file_type field.
-+ */
-+struct ext2_dir_entry_2 {
-+      __u32   inode;                  /* Inode number */
-+      __u16   rec_len;                /* Directory entry length */
-+      __u8    name_len;               /* Name length */
-+      __u8    file_type;
-+      char    name[EXT2_NAME_LEN];    /* File name */
-+};
-+
-+/*
-+ * Ext2 directory file types.  Only the low 3 bits are used.  The
-+ * other bits are reserved for now.
-+ */
-+#define EXT2_FT_UNKNOWN               0
-+#define EXT2_FT_REG_FILE      1
-+#define EXT2_FT_DIR           2
-+#define EXT2_FT_CHRDEV                3
-+#define EXT2_FT_BLKDEV                4
-+#define EXT2_FT_FIFO          5
-+#define EXT2_FT_SOCK          6
-+#define EXT2_FT_SYMLINK               7
-+
-+#define EXT2_FT_MAX           8
-+
-+/*
-+ * EXT2_DIR_PAD defines the directory entries boundaries
-+ *
-+ * NOTE: It must be a multiple of 4
-+ */
-+#define EXT2_DIR_PAD                  4
-+#define EXT2_DIR_ROUND                        (EXT2_DIR_PAD - 1)
-+#define EXT2_DIR_REC_LEN(name_len)    (((name_len) + 8 + EXT2_DIR_ROUND) & \
-+                                       ~EXT2_DIR_ROUND)
-+
-+#endif        /* _LINUX_EXT2_FS_H */
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/ext2_io.h busybox/e2fsprogs/ext2fs/ext2_io.h
---- busybox-1.00/e2fsprogs/ext2fs/ext2_io.h    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/ext2_io.h 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,108 @@
-+/*
-+ * io.h --- the I/O manager abstraction
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#ifndef _EXT2FS_EXT2_IO_H
-+#define _EXT2FS_EXT2_IO_H
-+
-+/*
-+ * ext2_loff_t is defined here since unix_io.c needs it.
-+ */
-+#if defined(__GNUC__) || defined(HAS_LONG_LONG)
-+typedef long long     ext2_loff_t;
-+#else
-+typedef long          ext2_loff_t;
-+#endif
-+
-+/* llseek.c */
-+ext2_loff_t ext2fs_llseek (int, ext2_loff_t, int);
-+
-+typedef struct struct_io_manager *io_manager;
-+typedef struct struct_io_channel *io_channel;
-+
-+#define CHANNEL_FLAGS_WRITETHROUGH    0x01
-+
-+struct struct_io_channel {
-+      errcode_t       magic;
-+      io_manager      manager;
-+      char            *name;
-+      int             block_size;
-+      errcode_t       (*read_error)(io_channel channel,
-+                                    unsigned long block,
-+                                    int count,
-+                                    void *data,
-+                                    size_t size,
-+                                    int actual_bytes_read,
-+                                    errcode_t error);
-+      errcode_t       (*write_error)(io_channel channel,
-+                                     unsigned long block,
-+                                     int count,
-+                                     const void *data,
-+                                     size_t size,
-+                                     int actual_bytes_written,
-+                                     errcode_t error);
-+      int             refcount;
-+      int             flags;
-+      int             reserved[14];
-+      void            *private_data;
-+      void            *app_data;
-+};
-+
-+struct struct_io_manager {
-+      errcode_t magic;
-+      const char *name;
-+      errcode_t (*open)(const char *name, int flags, io_channel *channel);
-+      errcode_t (*close)(io_channel channel);
-+      errcode_t (*set_blksize)(io_channel channel, int blksize);
-+      errcode_t (*read_blk)(io_channel channel, unsigned long block,
-+                            int count, void *data);
-+      errcode_t (*write_blk)(io_channel channel, unsigned long block,
-+                             int count, const void *data);
-+      errcode_t (*flush)(io_channel channel);
-+      errcode_t (*write_byte)(io_channel channel, unsigned long offset,
-+                              int count, const void *data);
-+      errcode_t (*set_option)(io_channel channel, const char *option, 
-+                              const char *arg);
-+      int             reserved[14];
-+};
-+
-+#define IO_FLAG_RW    1
-+
-+/*
-+ * Convenience functions....
-+ */
-+#define io_channel_close(c)           ((c)->manager->close((c)))
-+#define io_channel_set_blksize(c,s)   ((c)->manager->set_blksize((c),s))
-+#define io_channel_read_blk(c,b,n,d)  ((c)->manager->read_blk((c),b,n,d))
-+#define io_channel_write_blk(c,b,n,d) ((c)->manager->write_blk((c),b,n,d))
-+#define io_channel_flush(c)           ((c)->manager->flush((c)))
-+#define io_channel_bumpcount(c)               ((c)->refcount++)
-+      
-+/* io_manager.c */
-+extern errcode_t io_channel_set_options(io_channel channel, 
-+                                      const char *options);
-+extern errcode_t io_channel_write_byte(io_channel channel, 
-+                                     unsigned long offset,
-+                                     int count, const void *data);
-+
-+/* unix_io.c */
-+extern io_manager unix_io_manager;
-+
-+/* test_io.c */
-+extern io_manager test_io_manager, test_io_backing_manager;
-+extern void (*test_io_cb_read_blk)
-+      (unsigned long block, int count, errcode_t err);
-+extern void (*test_io_cb_write_blk)
-+      (unsigned long block, int count, errcode_t err);
-+extern void (*test_io_cb_set_blksize)
-+      (int blksize, errcode_t err);
-+
-+#endif /* _EXT2FS_EXT2_IO_H */
-+      
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/ext2_types.h busybox/e2fsprogs/ext2fs/ext2_types.h
---- busybox-1.00/e2fsprogs/ext2fs/ext2_types.h 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/ext2_types.h      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1 @@
-+#include <linux/types.h>
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/ext2fs.h busybox/e2fsprogs/ext2fs/ext2fs.h
---- busybox-1.00/e2fsprogs/ext2fs/ext2fs.h     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/ext2fs.h  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,1137 @@
-+/*
-+ * ext2fs.h --- ext2fs
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#ifndef _EXT2FS_EXT2FS_H
-+#define _EXT2FS_EXT2FS_H
-+
-+#ifdef __GNUC__
-+#define EXT2FS_ATTR(x) __attribute__(x)
-+#else
-+#define EXT2FS_ATTR(x)
-+#endif
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/*
-+ * Non-GNU C compilers won't necessarily understand inline
-+ */
-+#if (!defined(__GNUC__) && !defined(__WATCOMC__))
-+#define NO_INLINE_FUNCS
-+#endif
-+
-+/*
-+ * Build in support for byte-swapping filesystems if we the feature
-+ * has been configured or if we're being built on a CPU architecture
-+ * with a non-native byte order.
-+ */
-+#if defined(ENABLE_SWAPFS) || defined(WORDS_BIGENDIAN)
-+#define EXT2FS_ENABLE_SWAPFS
-+#endif
-+
-+/*
-+ * Where the master copy of the superblock is located, and how big
-+ * superblocks are supposed to be.  We define SUPERBLOCK_SIZE because
-+ * the size of the superblock structure is not necessarily trustworthy
-+ * (some versions have the padding set up so that the superblock is
-+ * 1032 bytes long).
-+ */
-+#define SUPERBLOCK_OFFSET     1024
-+#define SUPERBLOCK_SIZE       1024
-+
-+/*
-+ * The last ext2fs revision level that this version of the library is
-+ * able to support.
-+ */
-+#define EXT2_LIB_CURRENT_REV  EXT2_DYNAMIC_REV
-+
-+#ifdef HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include <stdio.h>
-+#include <stdlib.h>
-+
-+#if EXT2_FLAT_INCLUDES
-+#include "e2_types.h"
-+#include "ext2_fs.h"
-+#else
-+#include <ext2fs/ext2_types.h>
-+#include <ext2fs/ext2_fs.h>
-+#endif /* EXT2_FLAT_INCLUDES */
-+
-+typedef __u32         ext2_ino_t;
-+typedef __u32         blk_t;
-+typedef __u32         dgrp_t;
-+typedef __u32         ext2_off_t;
-+typedef __s64         e2_blkcnt_t;
-+typedef __u32         ext2_dirhash_t;
-+
-+#if EXT2_FLAT_INCLUDES
-+#include "com_err.h"
-+#include "ext2_io.h"
-+#include "ext2_err.h"
-+#else
-+#include <et/com_err.h>
-+#include <ext2fs/ext2_io.h>
-+#include <ext2fs/ext2_err.h>
-+#endif
-+
-+/*
-+ * Portability help for Microsoft Visual C++
-+ */
-+#ifdef _MSC_VER
-+#define EXT2_QSORT_TYPE int __cdecl
-+#else
-+#define EXT2_QSORT_TYPE int
-+#endif
-+
-+typedef struct struct_ext2_filsys *ext2_filsys;
-+
-+struct ext2fs_struct_generic_bitmap {
-+      errcode_t       magic;
-+      ext2_filsys     fs;
-+      __u32           start, end;
-+      __u32           real_end;
-+      char    *       description;
-+      char    *       bitmap;
-+      errcode_t       base_error_code;
-+      __u32           reserved[7];
-+};
-+
-+#define EXT2FS_MARK_ERROR     0
-+#define EXT2FS_UNMARK_ERROR   1
-+#define EXT2FS_TEST_ERROR     2
-+
-+typedef struct ext2fs_struct_generic_bitmap *ext2fs_generic_bitmap;
-+typedef struct ext2fs_struct_generic_bitmap *ext2fs_inode_bitmap;
-+typedef struct ext2fs_struct_generic_bitmap *ext2fs_block_bitmap;
-+
-+#ifdef EXT2_DYNAMIC_REV
-+#define EXT2_FIRST_INODE(s)   EXT2_FIRST_INO(s)
-+#else
-+#define EXT2_FIRST_INODE(s)   EXT2_FIRST_INO
-+#define EXT2_INODE_SIZE(s)    sizeof(struct ext2_inode)
-+#endif
-+
-+/*
-+ * badblocks list definitions
-+ */
-+
-+typedef struct ext2_struct_u32_list *ext2_badblocks_list;
-+typedef struct ext2_struct_u32_iterate *ext2_badblocks_iterate;
-+
-+typedef struct ext2_struct_u32_list *ext2_u32_list;
-+typedef struct ext2_struct_u32_iterate *ext2_u32_iterate;
-+
-+/* old */
-+typedef struct ext2_struct_u32_list *badblocks_list;
-+typedef struct ext2_struct_u32_iterate *badblocks_iterate;
-+
-+#define BADBLOCKS_FLAG_DIRTY  1
-+
-+/*
-+ * ext2_dblist structure and abstractions (see dblist.c)
-+ */
-+struct ext2_db_entry {
-+      ext2_ino_t      ino;
-+      blk_t   blk;
-+      int     blockcnt;
-+};
-+
-+typedef struct ext2_struct_dblist *ext2_dblist;
-+
-+#define DBLIST_ABORT  1
-+
-+/*
-+ * ext2_fileio definitions
-+ */
-+
-+#define EXT2_FILE_WRITE               0x0001
-+#define EXT2_FILE_CREATE      0x0002
-+
-+#define EXT2_FILE_MASK                0x00FF
-+
-+#define EXT2_FILE_BUF_DIRTY   0x4000
-+#define EXT2_FILE_BUF_VALID   0x2000
-+
-+typedef struct ext2_file *ext2_file_t;
-+
-+#define EXT2_SEEK_SET 0
-+#define EXT2_SEEK_CUR 1
-+#define EXT2_SEEK_END 2
-+
-+/*
-+ * Flags for the ext2_filsys structure and for ext2fs_open()
-+ */
-+#define EXT2_FLAG_RW                  0x01
-+#define EXT2_FLAG_CHANGED             0x02
-+#define EXT2_FLAG_DIRTY                       0x04
-+#define EXT2_FLAG_VALID                       0x08
-+#define EXT2_FLAG_IB_DIRTY            0x10
-+#define EXT2_FLAG_BB_DIRTY            0x20
-+#define EXT2_FLAG_SWAP_BYTES          0x40
-+#define EXT2_FLAG_SWAP_BYTES_READ     0x80
-+#define EXT2_FLAG_SWAP_BYTES_WRITE    0x100
-+#define EXT2_FLAG_MASTER_SB_ONLY      0x200
-+#define EXT2_FLAG_FORCE                       0x400
-+#define EXT2_FLAG_SUPER_ONLY          0x800
-+#define EXT2_FLAG_JOURNAL_DEV_OK      0x1000
-+#define EXT2_FLAG_IMAGE_FILE          0x2000
-+
-+/*
-+ * Special flag in the ext2 inode i_flag field that means that this is
-+ * a new inode.  (So that ext2_write_inode() can clear extra fields.)
-+ */
-+#define EXT2_NEW_INODE_FL     0x80000000
-+
-+/*
-+ * Flags for mkjournal
-+ *
-+ * EXT2_MKJOURNAL_V1_SUPER    Make a (deprecated) V1 journal superblock
-+ */
-+#define EXT2_MKJOURNAL_V1_SUPER       0x0000001
-+
-+struct struct_ext2_filsys {
-+      errcode_t                       magic;
-+      io_channel                      io;
-+      int                             flags;
-+      char *                          device_name;
-+      struct ext2_super_block *       super;
-+      unsigned int                    blocksize;
-+      int                             fragsize;
-+      dgrp_t                          group_desc_count;
-+      unsigned long                   desc_blocks;
-+      struct ext2_group_desc *        group_desc;
-+      int                             inode_blocks_per_group;
-+      ext2fs_inode_bitmap             inode_map;
-+      ext2fs_block_bitmap             block_map;
-+      errcode_t (*get_blocks)(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
-+      errcode_t (*check_directory)(ext2_filsys fs, ext2_ino_t ino);
-+      errcode_t (*write_bitmaps)(ext2_filsys fs);
-+      errcode_t (*read_inode)(ext2_filsys fs, ext2_ino_t ino,
-+                              struct ext2_inode *inode);
-+      errcode_t (*write_inode)(ext2_filsys fs, ext2_ino_t ino,
-+                              struct ext2_inode *inode);
-+      ext2_badblocks_list             badblocks;
-+      ext2_dblist                     dblist;
-+      __u32                           stride; /* for mke2fs */
-+      struct ext2_super_block *       orig_super;
-+      struct ext2_image_hdr *         image_header;
-+      __u32                           umask;
-+      /*
-+       * Reserved for future expansion
-+       */
-+      __u32                           reserved[8];
-+
-+      /*
-+       * Reserved for the use of the calling application.
-+       */
-+      void *                          priv_data;
-+
-+      /*
-+       * Inode cache
-+       */
-+      struct ext2_inode_cache         *icache;
-+      io_channel                      image_io;
-+};
-+
-+#if EXT2_FLAT_INCLUDES
-+#include "e2_bitops.h"
-+#else
-+#include <ext2fs/bitops.h>
-+#endif
-+
-+/*
-+ * Return flags for the block iterator functions
-+ */
-+#define BLOCK_CHANGED 1
-+#define BLOCK_ABORT   2
-+#define BLOCK_ERROR   4
-+
-+/*
-+ * Block interate flags
-+ *
-+ * BLOCK_FLAG_APPEND, or BLOCK_FLAG_HOLE, indicates that the interator
-+ * function should be called on blocks where the block number is zero.
-+ * This is used by ext2fs_expand_dir() to be able to add a new block
-+ * to an inode.  It can also be used for programs that want to be able
-+ * to deal with files that contain "holes".
-+ * 
-+ * BLOCK_FLAG_TRAVERSE indicates that the iterator function for the
-+ * indirect, doubly indirect, etc. blocks should be called after all
-+ * of the blocks containined in the indirect blocks are processed.
-+ * This is useful if you are going to be deallocating blocks from an
-+ * inode.
-+ *
-+ * BLOCK_FLAG_DATA_ONLY indicates that the iterator function should be
-+ * called for data blocks only.
-+ *
-+ * BLOCK_FLAG_NO_LARGE is for internal use only.  It informs
-+ * ext2fs_block_iterate2 that large files won't be accepted.
-+ */
-+#define BLOCK_FLAG_APPEND     1
-+#define BLOCK_FLAG_HOLE               1
-+#define BLOCK_FLAG_DEPTH_TRAVERSE     2
-+#define BLOCK_FLAG_DATA_ONLY  4
-+
-+#define BLOCK_FLAG_NO_LARGE   0x1000
-+
-+/*
-+ * Magic "block count" return values for the block iterator function.
-+ */
-+#define BLOCK_COUNT_IND               (-1)
-+#define BLOCK_COUNT_DIND      (-2)
-+#define BLOCK_COUNT_TIND      (-3)
-+#define BLOCK_COUNT_TRANSLATOR        (-4)
-+
-+#if 0
-+/*
-+ * Flags for ext2fs_move_blocks
-+ */
-+#define EXT2_BMOVE_GET_DBLIST 0x0001  
-+#define EXT2_BMOVE_DEBUG      0x0002
-+#endif
-+
-+/*
-+ * Flags for directory block reading and writing functions
-+ */
-+#define EXT2_DIRBLOCK_V2_STRUCT       0x0001
-+
-+/*
-+ * Return flags for the directory iterator functions
-+ */
-+#define DIRENT_CHANGED        1
-+#define DIRENT_ABORT  2
-+#define DIRENT_ERROR  3
-+
-+/*
-+ * Directory iterator flags
-+ */
-+
-+#define DIRENT_FLAG_INCLUDE_EMPTY     1
-+#define DIRENT_FLAG_INCLUDE_REMOVED   2
-+
-+#define DIRENT_DOT_FILE               1
-+#define DIRENT_DOT_DOT_FILE   2
-+#define DIRENT_OTHER_FILE     3
-+#define DIRENT_DELETED_FILE   4
-+
-+/*
-+ * Inode scan definitions
-+ */
-+typedef struct ext2_struct_inode_scan *ext2_inode_scan;
-+
-+/*
-+ * ext2fs_scan flags
-+ */
-+#define EXT2_SF_CHK_BADBLOCKS 0x0001
-+#define EXT2_SF_BAD_INODE_BLK 0x0002
-+#define EXT2_SF_BAD_EXTRA_BYTES       0x0004
-+#define EXT2_SF_SKIP_MISSING_ITABLE   0x0008
-+
-+/*
-+ * ext2fs_check_if_mounted flags
-+ */
-+#define EXT2_MF_MOUNTED               1
-+#define EXT2_MF_ISROOT                2
-+#define EXT2_MF_READONLY      4
-+#define EXT2_MF_SWAP          8
-+
-+/*
-+ * Ext2/linux mode flags.  We define them here so that we don't need
-+ * to depend on the OS's sys/stat.h, since we may be compiling on a
-+ * non-Linux system.
-+ */
-+#define LINUX_S_IFMT  00170000
-+#define LINUX_S_IFSOCK 0140000
-+#define LINUX_S_IFLNK  0120000
-+#define LINUX_S_IFREG  0100000
-+#define LINUX_S_IFBLK  0060000
-+#define LINUX_S_IFDIR  0040000
-+#define LINUX_S_IFCHR  0020000
-+#define LINUX_S_IFIFO  0010000
-+#define LINUX_S_ISUID  0004000
-+#define LINUX_S_ISGID  0002000
-+#define LINUX_S_ISVTX  0001000
-+
-+#define LINUX_S_IRWXU 00700
-+#define LINUX_S_IRUSR 00400
-+#define LINUX_S_IWUSR 00200
-+#define LINUX_S_IXUSR 00100
-+
-+#define LINUX_S_IRWXG 00070
-+#define LINUX_S_IRGRP 00040
-+#define LINUX_S_IWGRP 00020
-+#define LINUX_S_IXGRP 00010
-+
-+#define LINUX_S_IRWXO 00007
-+#define LINUX_S_IROTH 00004
-+#define LINUX_S_IWOTH 00002
-+#define LINUX_S_IXOTH 00001
-+
-+#define LINUX_S_ISLNK(m)      (((m) & LINUX_S_IFMT) == LINUX_S_IFLNK)
-+#define LINUX_S_ISREG(m)      (((m) & LINUX_S_IFMT) == LINUX_S_IFREG)
-+#define LINUX_S_ISDIR(m)      (((m) & LINUX_S_IFMT) == LINUX_S_IFDIR)
-+#define LINUX_S_ISCHR(m)      (((m) & LINUX_S_IFMT) == LINUX_S_IFCHR)
-+#define LINUX_S_ISBLK(m)      (((m) & LINUX_S_IFMT) == LINUX_S_IFBLK)
-+#define LINUX_S_ISFIFO(m)     (((m) & LINUX_S_IFMT) == LINUX_S_IFIFO)
-+#define LINUX_S_ISSOCK(m)     (((m) & LINUX_S_IFMT) == LINUX_S_IFSOCK)
-+
-+/*
-+ * ext2 size of an inode
-+ */
-+#define EXT2_I_SIZE(i)        ((i)->i_size | ((__u64) (i)->i_size_high << 32))
-+
-+/*
-+ * ext2_icount_t abstraction
-+ */
-+#define EXT2_ICOUNT_OPT_INCREMENT     0x01
-+
-+typedef struct ext2_icount *ext2_icount_t;
-+
-+/*
-+ * Flags for ext2fs_bmap
-+ */
-+#define BMAP_ALLOC    0x0001
-+#define BMAP_SET      0x0002
-+
-+/*
-+ * Flags for imager.c functions
-+ */
-+#define IMAGER_FLAG_INODEMAP  1
-+#define IMAGER_FLAG_SPARSEWRITE       2
-+
-+/*
-+ * For checking structure magic numbers...
-+ */
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+        if ((struct)->magic != (code)) return (code)
-+
-+
-+/*
-+ * For ext2 compression support
-+ */
-+#define EXT2FS_COMPRESSED_BLKADDR ((blk_t) 0xffffffff)
-+#define HOLE_BLKADDR(_b) ((_b) == 0 || (_b) == EXT2FS_COMPRESSED_BLKADDR)
-+
-+/*
-+ * Features supported by this version of the library
-+ */
-+#define EXT2_LIB_FEATURE_COMPAT_SUPP  (EXT2_FEATURE_COMPAT_DIR_PREALLOC|\
-+                                       EXT2_FEATURE_COMPAT_IMAGIC_INODES|\
-+                                       EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
-+                                       EXT2_FEATURE_COMPAT_RESIZE_INODE|\
-+                                       EXT2_FEATURE_COMPAT_DIR_INDEX|\
-+                                       EXT2_FEATURE_COMPAT_EXT_ATTR)
-+
-+/* This #ifdef is temporary until compression is fully supported */
-+#ifdef ENABLE_COMPRESSION
-+#ifndef I_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL
-+/* If the below warning bugs you, then have
-+   `CPPFLAGS=-DI_KNOW_THAT_COMPRESSION_IS_EXPERIMENTAL' in your
-+   environment at configure time. */
-+ #warning "Compression support is experimental"
-+#endif
-+#define EXT2_LIB_FEATURE_INCOMPAT_SUPP        (EXT2_FEATURE_INCOMPAT_FILETYPE|\
-+                                       EXT2_FEATURE_INCOMPAT_COMPRESSION|\
-+                                       EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
-+                                       EXT2_FEATURE_INCOMPAT_META_BG|\
-+                                       EXT3_FEATURE_INCOMPAT_RECOVER)
-+#else
-+#define EXT2_LIB_FEATURE_INCOMPAT_SUPP        (EXT2_FEATURE_INCOMPAT_FILETYPE|\
-+                                       EXT3_FEATURE_INCOMPAT_JOURNAL_DEV|\
-+                                       EXT2_FEATURE_INCOMPAT_META_BG|\
-+                                       EXT3_FEATURE_INCOMPAT_RECOVER)
-+#endif
-+#define EXT2_LIB_FEATURE_RO_COMPAT_SUPP       (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
-+                                       EXT2_FEATURE_RO_COMPAT_LARGE_FILE)
-+/*
-+ * function prototypes
-+ */
-+
-+/* alloc.c */
-+extern errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir, int mode,
-+                                ext2fs_inode_bitmap map, ext2_ino_t *ret);
-+extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
-+                                ext2fs_block_bitmap map, blk_t *ret);
-+extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
-+                                      blk_t finish, int num,
-+                                      ext2fs_block_bitmap map,
-+                                      blk_t *ret);
-+extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
-+                                  char *block_buf, blk_t *ret);
-+
-+/* alloc_sb.c */
-+extern int ext2fs_reserve_super_and_bgd(ext2_filsys fs, 
-+                                      dgrp_t group,
-+                                      ext2fs_block_bitmap bmap);
-+
-+/* alloc_stats.c */
-+void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse);
-+void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
-+                             int inuse, int isdir);
-+void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse);
-+
-+/* alloc_tables.c */
-+extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
-+extern errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
-+                                           ext2fs_block_bitmap bmap);
-+
-+/* badblocks.c */
-+extern errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size);
-+extern errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk);
-+extern int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk);
-+extern int ext2fs_u32_list_test(ext2_u32_list bb, blk_t blk);
-+extern errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
-+                                             ext2_u32_iterate *ret);
-+extern int ext2fs_u32_list_iterate(ext2_u32_iterate iter, blk_t *blk);
-+extern void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter);
-+extern errcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest);
-+extern int ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2);
-+
-+extern errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret,
-+                                          int size);
-+extern errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb,
-+                                         blk_t blk);
-+extern int ext2fs_badblocks_list_test(ext2_badblocks_list bb,
-+                                  blk_t blk);
-+extern int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk);
-+extern void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk);
-+extern errcode_t
-+      ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
-+                                          ext2_badblocks_iterate *ret);
-+extern int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter,
-+                                       blk_t *blk);
-+extern void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter);
-+extern errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
-+                                     ext2_badblocks_list *dest);
-+extern int ext2fs_badblocks_equal(ext2_badblocks_list bb1,
-+                                ext2_badblocks_list bb2);
-+extern int ext2fs_u32_list_count(ext2_u32_list bb);
-+
-+/* bb_compat */
-+extern errcode_t badblocks_list_create(badblocks_list *ret, int size);
-+extern errcode_t badblocks_list_add(badblocks_list bb, blk_t blk);
-+extern int badblocks_list_test(badblocks_list bb, blk_t blk);
-+extern errcode_t badblocks_list_iterate_begin(badblocks_list bb,
-+                                            badblocks_iterate *ret);
-+extern int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk);
-+extern void badblocks_list_iterate_end(badblocks_iterate iter);
-+extern void badblocks_list_free(badblocks_list bb);
-+
-+/* bb_inode.c */
-+extern errcode_t ext2fs_update_bb_inode(ext2_filsys fs,
-+                                      ext2_badblocks_list bb_list);
-+
-+/* bitmaps.c */
-+extern errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs);
-+extern errcode_t ext2fs_write_block_bitmap (ext2_filsys fs);
-+extern errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs);
-+extern errcode_t ext2fs_read_block_bitmap(ext2_filsys fs);
-+extern errcode_t ext2fs_allocate_generic_bitmap(__u32 start,
-+                                              __u32 end,
-+                                              __u32 real_end,
-+                                              const char *descr,
-+                                              ext2fs_generic_bitmap *ret);
-+extern errcode_t ext2fs_allocate_block_bitmap(ext2_filsys fs,
-+                                            const char *descr,
-+                                            ext2fs_block_bitmap *ret);
-+extern errcode_t ext2fs_allocate_inode_bitmap(ext2_filsys fs,
-+                                            const char *descr,
-+                                            ext2fs_inode_bitmap *ret);
-+extern errcode_t ext2fs_fudge_inode_bitmap_end(ext2fs_inode_bitmap bitmap,
-+                                             ext2_ino_t end, ext2_ino_t *oend);
-+extern errcode_t ext2fs_fudge_block_bitmap_end(ext2fs_block_bitmap bitmap,
-+                                             blk_t end, blk_t *oend);
-+extern void ext2fs_clear_inode_bitmap(ext2fs_inode_bitmap bitmap);
-+extern void ext2fs_clear_block_bitmap(ext2fs_block_bitmap bitmap);
-+extern errcode_t ext2fs_read_bitmaps(ext2_filsys fs);
-+extern errcode_t ext2fs_write_bitmaps(ext2_filsys fs);
-+
-+/* block.c */
-+extern errcode_t ext2fs_block_iterate(ext2_filsys fs,
-+                                    ext2_ino_t        ino,
-+                                    int       flags,
-+                                    char *block_buf,
-+                                    int (*func)(ext2_filsys fs,
-+                                                blk_t *blocknr,
-+                                                int   blockcnt,
-+                                                void  *priv_data),
-+                                    void *priv_data);
-+errcode_t ext2fs_block_iterate2(ext2_filsys fs,
-+                              ext2_ino_t      ino,
-+                              int     flags,
-+                              char *block_buf,
-+                              int (*func)(ext2_filsys fs,
-+                                          blk_t       *blocknr,
-+                                          e2_blkcnt_t blockcnt,
-+                                          blk_t       ref_blk,
-+                                          int         ref_offset,
-+                                          void        *priv_data),
-+                              void *priv_data);
-+
-+/* bmap.c */
-+extern errcode_t ext2fs_bmap(ext2_filsys fs, ext2_ino_t ino,
-+                           struct ext2_inode *inode, 
-+                           char *block_buf, int bmap_flags,
-+                           blk_t block, blk_t *phys_blk);
-+
-+
-+#if 0
-+/* bmove.c */
-+extern errcode_t ext2fs_move_blocks(ext2_filsys fs,
-+                                  ext2fs_block_bitmap reserve,
-+                                  ext2fs_block_bitmap alloc_map,
-+                                  int flags);
-+#endif
-+
-+/* check_desc.c */
-+extern errcode_t ext2fs_check_desc(ext2_filsys fs);
-+
-+/* closefs.c */
-+extern errcode_t ext2fs_close(ext2_filsys fs);
-+extern errcode_t ext2fs_flush(ext2_filsys fs);
-+extern int ext2fs_bg_has_super(ext2_filsys fs, int group_block);
-+extern int ext2fs_super_and_bgd_loc(ext2_filsys fs, 
-+                                  dgrp_t group,
-+                                  blk_t *ret_super_blk,
-+                                  blk_t *ret_old_desc_blk,
-+                                  blk_t *ret_new_desc_blk,
-+                                  int *ret_meta_bg);
-+extern void ext2fs_update_dynamic_rev(ext2_filsys fs);
-+
-+/* cmp_bitmaps.c */
-+extern errcode_t ext2fs_compare_block_bitmap(ext2fs_block_bitmap bm1,
-+                                           ext2fs_block_bitmap bm2);
-+extern errcode_t ext2fs_compare_inode_bitmap(ext2fs_inode_bitmap bm1,
-+                                           ext2fs_inode_bitmap bm2);
-+
-+/* dblist.c */
-+
-+extern errcode_t ext2fs_get_num_dirs(ext2_filsys fs, ext2_ino_t *ret_num_dirs);
-+extern errcode_t ext2fs_init_dblist(ext2_filsys fs, ext2_dblist *ret_dblist);
-+extern errcode_t ext2fs_add_dir_block(ext2_dblist dblist, ext2_ino_t ino,
-+                                    blk_t blk, int blockcnt);
-+extern void ext2fs_dblist_sort(ext2_dblist dblist,
-+                             EXT2_QSORT_TYPE (*sortfunc)(const void *,
-+                                                         const void *));
-+extern errcode_t ext2fs_dblist_iterate(ext2_dblist dblist,
-+      int (*func)(ext2_filsys fs, struct ext2_db_entry *db_info,
-+                  void        *priv_data),
-+       void *priv_data);
-+extern errcode_t ext2fs_set_dir_block(ext2_dblist dblist, ext2_ino_t ino,
-+                                    blk_t blk, int blockcnt);
-+extern errcode_t ext2fs_copy_dblist(ext2_dblist src,
-+                                  ext2_dblist *dest);
-+extern int ext2fs_dblist_count(ext2_dblist dblist);
-+
-+/* dblist_dir.c */
-+extern errcode_t
-+      ext2fs_dblist_dir_iterate(ext2_dblist dblist,
-+                                int   flags,
-+                                char  *block_buf,
-+                                int (*func)(ext2_ino_t        dir,
-+                                            int               entry,
-+                                            struct ext2_dir_entry *dirent,
-+                                            int       offset,
-+                                            int       blocksize,
-+                                            char      *buf,
-+                                            void      *priv_data),
-+                                void *priv_data);
-+
-+/* dirblock.c */
-+extern errcode_t ext2fs_read_dir_block(ext2_filsys fs, blk_t block,
-+                                     void *buf);
-+extern errcode_t ext2fs_read_dir_block2(ext2_filsys fs, blk_t block,
-+                                      void *buf, int flags);
-+extern errcode_t ext2fs_write_dir_block(ext2_filsys fs, blk_t block,
-+                                      void *buf);
-+extern errcode_t ext2fs_write_dir_block2(ext2_filsys fs, blk_t block,
-+                                       void *buf, int flags);
-+
-+/* dirhash.c */
-+extern errcode_t ext2fs_dirhash(int version, const char *name, int len,
-+                              const __u32 *seed,
-+                              ext2_dirhash_t *ret_hash,
-+                              ext2_dirhash_t *ret_minor_hash);
-+
-+
-+/* dir_iterate.c */
-+extern errcode_t ext2fs_dir_iterate(ext2_filsys fs, 
-+                            ext2_ino_t dir,
-+                            int flags,
-+                            char *block_buf,
-+                            int (*func)(struct ext2_dir_entry *dirent,
-+                                        int   offset,
-+                                        int   blocksize,
-+                                        char  *buf,
-+                                        void  *priv_data),
-+                            void *priv_data);
-+extern errcode_t ext2fs_dir_iterate2(ext2_filsys fs, 
-+                            ext2_ino_t dir,
-+                            int flags,
-+                            char *block_buf,
-+                            int (*func)(ext2_ino_t    dir,
-+                                        int   entry,
-+                                        struct ext2_dir_entry *dirent,
-+                                        int   offset,
-+                                        int   blocksize,
-+                                        char  *buf,
-+                                        void  *priv_data),
-+                            void *priv_data);
-+
-+/* dupfs.c */
-+extern errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest);
-+
-+/* expanddir.c */
-+extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir);
-+
-+/* ext_attr.c */
-+extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf);
-+extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block,
-+                                     void *buf);
-+extern errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
-+                                         char *block_buf,
-+                                         int adjust, __u32 *newcount);
-+
-+/* fileio.c */
-+extern errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
-+                                 struct ext2_inode *inode,
-+                                 int flags, ext2_file_t *ret);
-+extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
-+                                int flags, ext2_file_t *ret);
-+extern ext2_filsys ext2fs_file_get_fs(ext2_file_t file);
-+extern errcode_t ext2fs_file_close(ext2_file_t file);
-+extern errcode_t ext2fs_file_flush(ext2_file_t file);
-+extern errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
-+                                unsigned int wanted, unsigned int *got);
-+extern errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
-+                                 unsigned int nbytes, unsigned int *written);
-+extern errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset,
-+                                 int whence, __u64 *ret_pos);
-+extern errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
-+                                 int whence, ext2_off_t *ret_pos);
-+errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size);
-+extern ext2_off_t ext2fs_file_get_size(ext2_file_t file);
-+extern errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size);
-+
-+/* finddev.c */
-+extern char *ext2fs_find_block_device(dev_t device);
-+
-+/* flushb.c */
-+extern errcode_t ext2fs_sync_device(int fd, int flushb);
-+
-+/* freefs.c */
-+extern void ext2fs_free(ext2_filsys fs);
-+extern void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap);
-+extern void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap);
-+extern void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap);
-+extern void ext2fs_free_dblist(ext2_dblist dblist);
-+extern void ext2fs_badblocks_list_free(ext2_badblocks_list bb);
-+extern void ext2fs_u32_list_free(ext2_u32_list bb);
-+
-+/* getsize.c */
-+extern errcode_t ext2fs_get_device_size(const char *file, int blocksize,
-+                                      blk_t *retblocks);
-+
-+/* getsectsize.c */
-+errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize);
-+
-+/* imager.c */
-+extern errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags);
-+extern errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, int flags);
-+extern errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, int flags);
-+extern errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, int flags);
-+extern errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags);
-+extern errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags);
-+
-+/* ind_block.c */
-+errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf);
-+errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf);
-+
-+/* initialize.c */
-+extern errcode_t ext2fs_initialize(const char *name, int flags,
-+                                 struct ext2_super_block *param,
-+                                 io_manager manager, ext2_filsys *ret_fs);
-+
-+/* icount.c */
-+extern void ext2fs_free_icount(ext2_icount_t icount);
-+extern errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, 
-+                                     unsigned int size,
-+                                     ext2_icount_t hint, ext2_icount_t *ret);
-+extern errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, 
-+                                    unsigned int size,
-+                                    ext2_icount_t *ret);
-+extern errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino,
-+                                   __u16 *ret);
-+extern errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
-+                                       __u16 *ret);
-+extern errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
-+                                       __u16 *ret);
-+extern errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
-+                                   __u16 count);
-+extern ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount);
-+errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *);
-+
-+/* inode.c */
-+extern errcode_t ext2fs_flush_icache(ext2_filsys fs);
-+extern errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan, 
-+                                          ext2_ino_t *ino,
-+                                          struct ext2_inode *inode, 
-+                                          int bufsize);
-+extern errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
-+                                ext2_inode_scan *ret_scan);
-+extern void ext2fs_close_inode_scan(ext2_inode_scan scan);
-+extern errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
-+                             struct ext2_inode *inode);
-+extern errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
-+                                                 int  group);
-+extern void ext2fs_set_inode_callback
-+      (ext2_inode_scan scan,
-+       errcode_t (*done_group)(ext2_filsys fs,
-+                               ext2_inode_scan scan,
-+                               dgrp_t group,
-+                               void * priv_data),
-+       void *done_group_data);
-+extern int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
-+                                 int clear_flags);
-+extern errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
-+                                      struct ext2_inode * inode, 
-+                                      int bufsize);
-+extern errcode_t ext2fs_read_inode (ext2_filsys fs, ext2_ino_t ino,
-+                          struct ext2_inode * inode);
-+extern errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
-+                                       struct ext2_inode * inode, 
-+                                       int bufsize);
-+extern errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
-+                          struct ext2_inode * inode);
-+extern errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
-+                          struct ext2_inode * inode);
-+extern errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks);
-+extern errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino);
-+
-+/* inode_io.c */
-+extern io_manager inode_io_manager;
-+extern errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino, 
-+                                      char **name);
-+extern errcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
-+                                       struct ext2_inode *inode,
-+                                       char **name);
-+      
-+/* ismounted.c */
-+extern errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags);
-+extern errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
-+                                        char *mtpt, int mtlen);
-+
-+/* namei.c */
-+extern errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
-+                       int namelen, char *buf, ext2_ino_t *inode);
-+extern errcode_t ext2fs_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+                      const char *name, ext2_ino_t *inode);
-+errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+                            const char *name, ext2_ino_t *inode);
-+extern errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+                      ext2_ino_t inode, ext2_ino_t *res_inode);
-+
-+/* native.c */
-+int ext2fs_native_flag(void);
-+
-+/* newdir.c */
-+extern errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
-+                              ext2_ino_t parent_ino, char **block);
-+
-+/* mkdir.c */
-+extern errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
-+                            const char *name);
-+
-+/* mkjournal.c */
-+extern errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
-+                                                __u32 size, int flags,
-+                                                char  **ret_jsb);
-+extern errcode_t ext2fs_add_journal_device(ext2_filsys fs,
-+                                         ext2_filsys journal_dev);
-+extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size,
-+                                        int flags);
-+
-+/* openfs.c */
-+extern errcode_t ext2fs_open(const char *name, int flags, int superblock,
-+                           unsigned int block_size, io_manager manager,
-+                           ext2_filsys *ret_fs);
-+extern errcode_t ext2fs_open2(const char *name, const char *io_options, 
-+                            int flags, int superblock, 
-+                            unsigned int block_size, io_manager manager,
-+                            ext2_filsys *ret_fs);
-+extern blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, 
-+                                       dgrp_t i);
-+errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io);
-+errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io);
-+errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io);
-+
-+/* get_pathname.c */
-+extern errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
-+                             char **name);
-+
-+/* link.c */
-+errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
-+                    ext2_ino_t ino, int flags);
-+errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir, const char *name,
-+                      ext2_ino_t ino, int flags);
-+
-+/* read_bb.c */
-+extern errcode_t ext2fs_read_bb_inode(ext2_filsys fs,
-+                                    ext2_badblocks_list *bb_list);
-+
-+/* read_bb_file.c */
-+extern errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f, 
-+                                    ext2_badblocks_list *bb_list,
-+                                    void *priv_data,
-+                                    void (*invalid)(ext2_filsys fs,
-+                                                    blk_t blk,
-+                                                    char *badstr,
-+                                                    void *priv_data));
-+extern errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f, 
-+                                   ext2_badblocks_list *bb_list,
-+                                   void (*invalid)(ext2_filsys fs,
-+                                                   blk_t blk));
-+
-+/* res_gdt.c */
-+extern errcode_t ext2fs_create_resize_inode(ext2_filsys fs);
-+
-+/* rs_bitmap.c */
-+extern errcode_t ext2fs_resize_generic_bitmap(__u32 new_end,
-+                                            __u32 new_real_end,
-+                                            ext2fs_generic_bitmap bmap);
-+extern errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
-+                                          ext2fs_inode_bitmap bmap);
-+extern errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
-+                                          ext2fs_block_bitmap bmap);
-+extern errcode_t ext2fs_copy_bitmap(ext2fs_generic_bitmap src,
-+                                  ext2fs_generic_bitmap *dest);
-+
-+/* swapfs.c */
-+extern void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, 
-+                               int has_header);
-+extern void ext2fs_swap_super(struct ext2_super_block * super);
-+extern void ext2fs_swap_group_desc(struct ext2_group_desc *gdp);
-+extern void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
-+                                 struct ext2_inode_large *f, int hostorder,
-+                                 int bufsize);
-+extern void ext2fs_swap_inode(ext2_filsys fs,struct ext2_inode *t,
-+                            struct ext2_inode *f, int hostorder);
-+
-+/* valid_blk.c */
-+extern int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode);
-+
-+/* version.c */
-+extern int ext2fs_parse_version_string(const char *ver_string);
-+extern int ext2fs_get_library_version(const char **ver_string,
-+                                    const char **date_string);
-+
-+/* write_bb_file.c */
-+extern errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
-+                                    unsigned int flags,
-+                                    FILE *f);
-+
-+
-+/* inline functions */
-+extern errcode_t ext2fs_get_mem(unsigned long size, void *ptr);
-+extern errcode_t ext2fs_free_mem(void *ptr);
-+extern errcode_t ext2fs_resize_mem(unsigned long old_size,
-+                                 unsigned long size, void *ptr);
-+extern void ext2fs_mark_super_dirty(ext2_filsys fs);
-+extern void ext2fs_mark_changed(ext2_filsys fs);
-+extern int ext2fs_test_changed(ext2_filsys fs);
-+extern void ext2fs_mark_valid(ext2_filsys fs);
-+extern void ext2fs_unmark_valid(ext2_filsys fs);
-+extern int ext2fs_test_valid(ext2_filsys fs);
-+extern void ext2fs_mark_ib_dirty(ext2_filsys fs);
-+extern void ext2fs_mark_bb_dirty(ext2_filsys fs);
-+extern int ext2fs_test_ib_dirty(ext2_filsys fs);
-+extern int ext2fs_test_bb_dirty(ext2_filsys fs);
-+extern int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk);
-+extern int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino);
-+extern blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
-+                                    struct ext2_inode *inode);
-+
-+/*
-+ * The actual inlined functions definitions themselves...
-+ *
-+ * If NO_INLINE_FUNCS is defined, then we won't try to do inline
-+ * functions at all!
-+ */
-+#if (defined(INCLUDE_INLINE_FUNCS) || !defined(NO_INLINE_FUNCS))
-+#ifdef INCLUDE_INLINE_FUNCS
-+#define _INLINE_ extern
-+#else
-+#ifdef __GNUC__
-+#define _INLINE_ extern __inline__
-+#else                         /* For Watcom C */
-+#define _INLINE_ extern inline
-+#endif
-+#endif
-+
-+#ifndef EXT2_CUSTOM_MEMORY_ROUTINES
-+/*
-+ *  Allocate memory
-+ */
-+_INLINE_ errcode_t ext2fs_get_mem(unsigned long size, void *ptr)
-+{
-+      void **pp = (void **)ptr;
-+
-+      *pp = malloc(size);
-+      if (!*pp)
-+              return EXT2_ET_NO_MEMORY;
-+      return 0;
-+}
-+
-+/*
-+ * Free memory
-+ */
-+_INLINE_ errcode_t ext2fs_free_mem(void *ptr)
-+{
-+      void **pp = (void **)ptr;
-+
-+      free(*pp);
-+      *pp = 0;
-+      return 0;
-+}
-+      
-+/*
-+ *  Resize memory
-+ */
-+_INLINE_ errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_size,
-+                                   unsigned long size, void *ptr)
-+{
-+      void *p;
-+      void **pp = (void **)ptr;
-+
-+      p = realloc(*pp, size);
-+      if (!p)
-+              return EXT2_ET_NO_MEMORY;
-+      *pp = p;
-+      return 0;
-+}
-+#endif        /* Custom memory routines */
-+
-+/*
-+ * Mark a filesystem superblock as dirty
-+ */
-+_INLINE_ void ext2fs_mark_super_dirty(ext2_filsys fs)
-+{
-+      fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED;
-+}
-+
-+/*
-+ * Mark a filesystem as changed
-+ */
-+_INLINE_ void ext2fs_mark_changed(ext2_filsys fs)
-+{
-+      fs->flags |= EXT2_FLAG_CHANGED;
-+}
-+
-+/*
-+ * Check to see if a filesystem has changed
-+ */
-+_INLINE_ int ext2fs_test_changed(ext2_filsys fs)
-+{
-+      return (fs->flags & EXT2_FLAG_CHANGED);
-+}
-+
-+/*
-+ * Mark a filesystem as valid
-+ */
-+_INLINE_ void ext2fs_mark_valid(ext2_filsys fs)
-+{
-+      fs->flags |= EXT2_FLAG_VALID;
-+}
-+
-+/*
-+ * Mark a filesystem as NOT valid
-+ */
-+_INLINE_ void ext2fs_unmark_valid(ext2_filsys fs)
-+{
-+      fs->flags &= ~EXT2_FLAG_VALID;
-+}
-+
-+/*
-+ * Check to see if a filesystem is valid
-+ */
-+_INLINE_ int ext2fs_test_valid(ext2_filsys fs)
-+{
-+      return (fs->flags & EXT2_FLAG_VALID);
-+}
-+
-+/*
-+ * Mark the inode bitmap as dirty
-+ */
-+_INLINE_ void ext2fs_mark_ib_dirty(ext2_filsys fs)
-+{
-+      fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED;
-+}
-+
-+/*
-+ * Mark the block bitmap as dirty
-+ */
-+_INLINE_ void ext2fs_mark_bb_dirty(ext2_filsys fs)
-+{
-+      fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED;
-+}
-+
-+/*
-+ * Check to see if a filesystem's inode bitmap is dirty
-+ */
-+_INLINE_ int ext2fs_test_ib_dirty(ext2_filsys fs)
-+{
-+      return (fs->flags & EXT2_FLAG_IB_DIRTY);
-+}
-+
-+/*
-+ * Check to see if a filesystem's block bitmap is dirty
-+ */
-+_INLINE_ int ext2fs_test_bb_dirty(ext2_filsys fs)
-+{
-+      return (fs->flags & EXT2_FLAG_BB_DIRTY);
-+}
-+
-+/*
-+ * Return the group # of a block
-+ */
-+_INLINE_ int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk)
-+{
-+      return (blk - fs->super->s_first_data_block) /
-+              fs->super->s_blocks_per_group;
-+}
-+
-+/*
-+ * Return the group # of an inode number
-+ */
-+_INLINE_ int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino)
-+{
-+      return (ino - 1) / fs->super->s_inodes_per_group;
-+}
-+
-+_INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
-+                                      struct ext2_inode *inode)
-+{
-+       return inode->i_blocks -
-+              (inode->i_file_acl ? fs->blocksize >> 9 : 0);
-+}
-+#undef _INLINE_
-+#endif
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _EXT2FS_EXT2FS_H */
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/ext2fsP.h busybox/e2fsprogs/ext2fs/ext2fsP.h
---- busybox-1.00/e2fsprogs/ext2fs/ext2fsP.h    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/ext2fsP.h 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,88 @@
-+/*
-+ * ext2fsP.h --- private header file for ext2 library
-+ * 
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include "ext2fs.h"
-+
-+/*
-+ * Badblocks list
-+ */
-+struct ext2_struct_u32_list {
-+      int     magic;
-+      int     num;
-+      int     size;
-+      __u32   *list;
-+      int     badblocks_flags;
-+};
-+
-+struct ext2_struct_u32_iterate {
-+      int                     magic;
-+      ext2_u32_list           bb;
-+      int                     ptr;
-+};
-+
-+
-+/*
-+ * Directory block iterator definition
-+ */
-+struct ext2_struct_dblist {
-+      int                     magic;
-+      ext2_filsys             fs;
-+      ext2_ino_t              size;
-+      ext2_ino_t              count;
-+      int                     sorted;
-+      struct ext2_db_entry *  list;
-+};
-+
-+/*
-+ * For directory iterators
-+ */
-+struct dir_context {
-+      ext2_ino_t              dir;
-+      int             flags;
-+      char            *buf;
-+      int (*func)(ext2_ino_t  dir,
-+                  int entry,
-+                  struct ext2_dir_entry *dirent,
-+                  int offset,
-+                  int blocksize,
-+                  char        *buf,
-+                  void        *priv_data);
-+      void            *priv_data;
-+      errcode_t       errcode;
-+};
-+
-+/*
-+ * Inode cache structure
-+ */
-+struct ext2_inode_cache {
-+      void *                          buffer;
-+      blk_t                           buffer_blk;
-+      int                             cache_last;
-+      int                             cache_size;
-+      int                             refcount;
-+      struct ext2_inode_cache_ent     *cache;
-+};
-+
-+struct ext2_inode_cache_ent {
-+      ext2_ino_t              ino;
-+      struct ext2_inode       inode;
-+};
-+
-+/* Function prototypes */
-+
-+extern int ext2fs_process_dir_block(ext2_filsys       fs,
-+                                  blk_t               *blocknr,
-+                                  e2_blkcnt_t         blockcnt,
-+                                  blk_t               ref_block,
-+                                  int                 ref_offset,
-+                                  void                *priv_data);
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/ext_attr.c busybox/e2fsprogs/ext2fs/ext_attr.c
---- busybox-1.00/e2fsprogs/ext2fs/ext_attr.c   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/ext_attr.c        2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,105 @@
-+/*
-+ * ext_attr.c --- extended attribute blocks
-+ * 
-+ * Copyright (C) 2001 Andreas Gruenbacher, <a.gruenbacher@computer.org>
-+ *
-+ * Copyright (C) 2002 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2_ext_attr.h"
-+
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf)
-+{
-+      errcode_t       retval;
-+
-+      retval = io_channel_read_blk(fs->io, block, 1, buf);
-+      if (retval)
-+              return retval;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if ((fs->flags & (EXT2_FLAG_SWAP_BYTES|
-+                        EXT2_FLAG_SWAP_BYTES_READ)) != 0)
-+              ext2fs_swap_ext_attr(buf, buf, fs->blocksize, 1);
-+#endif
-+      return 0;
-+}
-+
-+errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *inbuf)
-+{
-+      errcode_t       retval;
-+      char            *write_buf;
-+      char            *buf = NULL;
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+          (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) {
-+              retval = ext2fs_get_mem(fs->blocksize, &buf);
-+              if (retval)
-+                      return retval;
-+              write_buf = buf;
-+              ext2fs_swap_ext_attr(buf, inbuf, fs->blocksize, 1);
-+      } else
-+#endif
-+              write_buf = (char *) inbuf;
-+      retval = io_channel_write_blk(fs->io, block, 1, write_buf);
-+      if (buf)
-+              ext2fs_free_mem(&buf);
-+      if (!retval)
-+              ext2fs_mark_changed(fs);
-+      return retval;
-+}
-+
-+/*
-+ * This function adjusts the reference count of the EA block.
-+ */
-+errcode_t ext2fs_adjust_ea_refcount(ext2_filsys fs, blk_t blk,
-+                                  char *block_buf, int adjust,
-+                                  __u32 *newcount)
-+{
-+      errcode_t       retval;
-+      struct ext2_ext_attr_header *header;
-+      char    *buf = 0;
-+
-+      if ((blk >= fs->super->s_blocks_count) ||
-+          (blk < fs->super->s_first_data_block))
-+              return EXT2_ET_BAD_EA_BLOCK_NUM;
-+
-+      if (!block_buf) {
-+              retval = ext2fs_get_mem(fs->blocksize, &buf);
-+              if (retval)
-+                      return retval;
-+              block_buf = buf;
-+      }
-+
-+      retval = ext2fs_read_ext_attr(fs, blk, block_buf);
-+      if (retval)
-+              goto errout;
-+
-+      header = (struct ext2_ext_attr_header *) block_buf;
-+      header->h_refcount += adjust;
-+      if (newcount)
-+              *newcount = header->h_refcount;
-+
-+      retval = ext2fs_write_ext_attr(fs, blk, block_buf);
-+      if (retval)
-+              goto errout;
-+
-+errout:
-+      if (buf)
-+              ext2fs_free_mem(&buf);
-+      return retval;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/fileio.c busybox/e2fsprogs/ext2fs/fileio.c
---- busybox-1.00/e2fsprogs/ext2fs/fileio.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/fileio.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,378 @@
-+/*
-+ * fileio.c --- Simple file I/O routines
-+ * 
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct ext2_file {
-+      errcode_t               magic;
-+      ext2_filsys             fs;
-+      ext2_ino_t              ino;
-+      struct ext2_inode       inode;
-+      int                     flags;
-+      __u64                   pos;
-+      blk_t                   blockno;
-+      blk_t                   physblock;
-+      char                    *buf;
-+};
-+
-+#define BMAP_BUFFER (file->buf + fs->blocksize)
-+
-+errcode_t ext2fs_file_open2(ext2_filsys fs, ext2_ino_t ino,
-+                          struct ext2_inode *inode,
-+                          int flags, ext2_file_t *ret)
-+{
-+      ext2_file_t     file;
-+      errcode_t       retval;
-+
-+      /*
-+       * Don't let caller create or open a file for writing if the
-+       * filesystem is read-only.
-+       */
-+      if ((flags & (EXT2_FILE_WRITE | EXT2_FILE_CREATE)) &&
-+          !(fs->flags & EXT2_FLAG_RW))
-+              return EXT2_ET_RO_FILSYS;
-+
-+      retval = ext2fs_get_mem(sizeof(struct ext2_file), &file);
-+      if (retval)
-+              return retval;
-+      
-+      memset(file, 0, sizeof(struct ext2_file));
-+      file->magic = EXT2_ET_MAGIC_EXT2_FILE;
-+      file->fs = fs;
-+      file->ino = ino;
-+      file->flags = flags & EXT2_FILE_MASK;
-+
-+      if (inode) {
-+              memcpy(&file->inode, inode, sizeof(struct ext2_inode));
-+      } else {
-+              retval = ext2fs_read_inode(fs, ino, &file->inode);
-+              if (retval)
-+                      goto fail;
-+      }
-+      
-+      retval = ext2fs_get_mem(fs->blocksize * 3, &file->buf);
-+      if (retval)
-+              goto fail;
-+
-+      *ret = file;
-+      return 0;
-+      
-+fail:
-+      if (file->buf)
-+              ext2fs_free_mem(&file->buf);
-+      ext2fs_free_mem(&file);
-+      return retval;
-+}
-+
-+errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino,
-+                         int flags, ext2_file_t *ret)
-+{
-+      return ext2fs_file_open2(fs, ino, NULL, flags, ret);
-+}
-+
-+/*
-+ * This function returns the filesystem handle of a file from the structure
-+ */
-+ext2_filsys ext2fs_file_get_fs(ext2_file_t file)
-+{
-+      if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
-+              return 0;
-+      return file->fs;
-+}
-+
-+/*
-+ * This function flushes the dirty block buffer out to disk if
-+ * necessary.
-+ */
-+errcode_t ext2fs_file_flush(ext2_file_t file)
-+{
-+      errcode_t       retval;
-+      ext2_filsys fs;
-+      
-+      EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+      fs = file->fs;
-+
-+      if (!(file->flags & EXT2_FILE_BUF_VALID) ||
-+          !(file->flags & EXT2_FILE_BUF_DIRTY))
-+              return 0;
-+
-+      /*
-+       * OK, the physical block hasn't been allocated yet.
-+       * Allocate it.
-+       */
-+      if (!file->physblock) {
-+              retval = ext2fs_bmap(fs, file->ino, &file->inode,
-+                                   BMAP_BUFFER, file->ino ? BMAP_ALLOC : 0,
-+                                   file->blockno, &file->physblock);
-+              if (retval)
-+                      return retval;
-+      }
-+
-+      retval = io_channel_write_blk(fs->io, file->physblock,
-+                                    1, file->buf);
-+      if (retval)
-+              return retval;
-+
-+      file->flags &= ~EXT2_FILE_BUF_DIRTY;
-+
-+      return retval;
-+}
-+
-+/*
-+ * This function synchronizes the file's block buffer and the current
-+ * file position, possibly invalidating block buffer if necessary
-+ */
-+static errcode_t sync_buffer_position(ext2_file_t file)
-+{
-+      blk_t   b;
-+      errcode_t       retval;
-+
-+      b = file->pos / file->fs->blocksize;
-+      if (b != file->blockno) {
-+              retval = ext2fs_file_flush(file);
-+              if (retval)
-+                      return retval;
-+              file->flags &= ~EXT2_FILE_BUF_VALID;
-+      }
-+      file->blockno = b;
-+      return 0;
-+}
-+
-+/*
-+ * This function loads the file's block buffer with valid data from
-+ * the disk as necessary.
-+ *
-+ * If dontfill is true, then skip initializing the buffer since we're
-+ * going to be replacing its entire contents anyway.  If set, then the
-+ * function basically only sets file->physblock and EXT2_FILE_BUF_VALID
-+ */
-+#define DONTFILL 1
-+static errcode_t load_buffer(ext2_file_t file, int dontfill)
-+{
-+      ext2_filsys     fs = file->fs;
-+      errcode_t       retval;
-+
-+      if (!(file->flags & EXT2_FILE_BUF_VALID)) {
-+              retval = ext2fs_bmap(fs, file->ino, &file->inode,
-+                                   BMAP_BUFFER, 0, file->blockno,
-+                                   &file->physblock);
-+              if (retval)
-+                      return retval;
-+              if (!dontfill) {
-+                      if (file->physblock) {
-+                              retval = io_channel_read_blk(fs->io,
-+                                                           file->physblock, 
-+                                                           1, file->buf);
-+                              if (retval)
-+                                      return retval;
-+                      } else
-+                              memset(file->buf, 0, fs->blocksize);
-+              }
-+              file->flags |= EXT2_FILE_BUF_VALID;
-+      }
-+      return 0;
-+}
-+      
-+
-+errcode_t ext2fs_file_close(ext2_file_t file)
-+{
-+      errcode_t       retval;
-+      
-+      EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+
-+      retval = ext2fs_file_flush(file);
-+      
-+      if (file->buf)
-+              ext2fs_free_mem(&file->buf);
-+      ext2fs_free_mem(&file);
-+
-+      return retval;
-+}
-+
-+
-+errcode_t ext2fs_file_read(ext2_file_t file, void *buf,
-+                         unsigned int wanted, unsigned int *got)
-+{
-+      ext2_filsys     fs;
-+      errcode_t       retval = 0;
-+      unsigned int    start, c, count = 0;
-+      __u64           left;
-+      char            *ptr = (char *) buf;
-+
-+      EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+      fs = file->fs;
-+
-+      while ((file->pos < EXT2_I_SIZE(&file->inode)) && (wanted > 0)) {
-+              retval = sync_buffer_position(file);
-+              if (retval)
-+                      goto fail;
-+              retval = load_buffer(file, 0);
-+              if (retval)
-+                      goto fail;
-+
-+              start = file->pos % fs->blocksize;
-+              c = fs->blocksize - start;
-+              if (c > wanted)
-+                      c = wanted;
-+              left = EXT2_I_SIZE(&file->inode) - file->pos ;
-+              if (c > left)
-+                      c = left;
-+      
-+              memcpy(ptr, file->buf+start, c);
-+              file->pos += c;
-+              ptr += c;
-+              count += c;
-+              wanted -= c;
-+      }
-+      
-+fail:
-+      if (got)
-+              *got = count;
-+      return retval;
-+}
-+
-+
-+errcode_t ext2fs_file_write(ext2_file_t file, const void *buf,
-+                          unsigned int nbytes, unsigned int *written)
-+{
-+      ext2_filsys     fs;
-+      errcode_t       retval = 0;
-+      unsigned int    start, c, count = 0;
-+      const char      *ptr = (const char *) buf;
-+
-+      EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+      fs = file->fs;
-+
-+      if (!(file->flags & EXT2_FILE_WRITE))
-+              return EXT2_ET_FILE_RO;
-+
-+      while (nbytes > 0) {
-+              retval = sync_buffer_position(file);
-+              if (retval)
-+                      goto fail;
-+              
-+              start = file->pos % fs->blocksize;
-+              c = fs->blocksize - start;
-+              if (c > nbytes)
-+                      c = nbytes;
-+
-+              /*
-+               * We only need to do a read-modify-update cycle if
-+               * we're doing a partial write.
-+               */
-+              retval = load_buffer(file, (c == fs->blocksize));
-+              if (retval)
-+                      goto fail;
-+
-+              file->flags |= EXT2_FILE_BUF_DIRTY;
-+              memcpy(file->buf+start, ptr, c);
-+              file->pos += c;
-+              ptr += c;
-+              count += c;
-+              nbytes -= c;
-+      }
-+      
-+fail:
-+      if (written)
-+              *written = count;
-+      return retval;
-+}
-+
-+errcode_t ext2fs_file_llseek(ext2_file_t file, __u64 offset,
-+                          int whence, __u64 *ret_pos)
-+{
-+      EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+
-+      if (whence == EXT2_SEEK_SET)
-+              file->pos = offset;
-+      else if (whence == EXT2_SEEK_CUR)
-+              file->pos += offset;
-+      else if (whence == EXT2_SEEK_END)
-+              file->pos = EXT2_I_SIZE(&file->inode) + offset;
-+      else
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      if (ret_pos)
-+              *ret_pos = file->pos;
-+
-+      return 0;
-+}
-+
-+errcode_t ext2fs_file_lseek(ext2_file_t file, ext2_off_t offset,
-+                          int whence, ext2_off_t *ret_pos)
-+{
-+      __u64           loffset, ret_loffset;
-+      errcode_t       retval;
-+      
-+      loffset = offset;
-+      retval = ext2fs_file_llseek(file, loffset, whence, &ret_loffset);
-+      if (ret_pos)
-+              *ret_pos = (ext2_off_t) ret_loffset;
-+      return retval;
-+}
-+
-+
-+/*
-+ * This function returns the size of the file, according to the inode
-+ */
-+errcode_t ext2fs_file_get_lsize(ext2_file_t file, __u64 *ret_size)
-+{
-+      if (file->magic != EXT2_ET_MAGIC_EXT2_FILE)
-+              return EXT2_ET_MAGIC_EXT2_FILE;
-+      *ret_size = EXT2_I_SIZE(&file->inode);
-+      return 0;
-+}
-+
-+/*
-+ * This function returns the size of the file, according to the inode
-+ */
-+ext2_off_t ext2fs_file_get_size(ext2_file_t file)
-+{
-+      __u64   size;
-+
-+      if (ext2fs_file_get_lsize(file, &size))
-+              return 0;
-+      if ((size >> 32) != 0)
-+              return 0;
-+      return size;
-+}
-+
-+/*
-+ * This function sets the size of the file, truncating it if necessary
-+ * 
-+ * XXX still need to call truncate
-+ */
-+errcode_t ext2fs_file_set_size(ext2_file_t file, ext2_off_t size)
-+{
-+      errcode_t       retval;
-+      EXT2_CHECK_MAGIC(file, EXT2_ET_MAGIC_EXT2_FILE);
-+      
-+      file->inode.i_size = size;
-+      file->inode.i_size_high = 0;
-+      if (file->ino) {
-+              retval = ext2fs_write_inode(file->fs, file->ino, &file->inode);
-+              if (retval)
-+                      return retval;
-+      }
-+
-+      /* 
-+       * XXX truncate inode if necessary
-+       */
-+
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/finddev.c busybox/e2fsprogs/ext2fs/finddev.c
---- busybox-1.00/e2fsprogs/ext2fs/finddev.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/finddev.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,208 @@
-+/*
-+ * finddev.c -- this routine attempts to find a particular device in
-+ *    /dev
-+ * 
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <stdlib.h>
-+#include <string.h>
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#include <dirent.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_SYS_MKDEV_H
-+#include <sys/mkdev.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct dir_list {
-+      char    *name;
-+      struct dir_list *next;
-+};
-+
-+/*
-+ * This function adds an entry to the directory list
-+ */
-+static void add_to_dirlist(const char *name, struct dir_list **list)
-+{
-+      struct dir_list *dp;
-+
-+      dp = malloc(sizeof(struct dir_list));
-+      if (!dp)
-+              return;
-+      dp->name = malloc(strlen(name)+1);
-+      if (!dp->name) {
-+              free(dp);
-+              return;
-+      }
-+      strcpy(dp->name, name);
-+      dp->next = *list;
-+      *list = dp;
-+}
-+
-+/*
-+ * This function frees a directory list
-+ */
-+static void free_dirlist(struct dir_list **list)
-+{
-+      struct dir_list *dp, *next;
-+
-+      for (dp = *list; dp; dp = next) {
-+              next = dp->next;
-+              free(dp->name);
-+              free(dp);
-+      }
-+      *list = 0;
-+}
-+
-+static int scan_dir(char *dir_name, dev_t device, struct dir_list **list,
-+                  char **ret_path)
-+{
-+      DIR     *dir;
-+      struct dirent *dp;
-+      char    path[1024], *cp;
-+      int     dirlen;
-+      struct stat st;
-+
-+      dirlen = strlen(dir_name);
-+      if ((dir = opendir(dir_name)) == NULL)
-+              return errno;
-+      dp = readdir(dir);
-+      while (dp) {
-+              if (dirlen + strlen(dp->d_name) + 2 >= sizeof(path))
-+                      goto skip_to_next;
-+              if (dp->d_name[0] == '.' &&
-+                  ((dp->d_name[1] == 0) ||
-+                   ((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
-+                      goto skip_to_next;
-+              sprintf(path, "%s/%s", dir_name, dp->d_name);
-+              if (stat(path, &st) < 0)
-+                      goto skip_to_next;
-+              if (S_ISDIR(st.st_mode))
-+                      add_to_dirlist(path, list);
-+              if (S_ISBLK(st.st_mode) && st.st_rdev == device) {
-+                      cp = malloc(strlen(path)+1);
-+                      if (!cp) {
-+                              closedir(dir);
-+                              return ENOMEM;
-+                      }
-+                      strcpy(cp, path);
-+                      *ret_path = cp;
-+                      goto success;
-+              }
-+      skip_to_next:
-+              dp = readdir(dir);
-+      }
-+success:
-+      closedir(dir);
-+      return 0;
-+}
-+
-+/*
-+ * This function finds the pathname to a block device with a given
-+ * device number.  It returns a pointer to allocated memory to the
-+ * pathname on success, and NULL on failure.
-+ */
-+char *ext2fs_find_block_device(dev_t device)
-+{
-+      struct dir_list *list = 0, *new_list = 0;
-+      struct dir_list *current;
-+      char    *ret_path = 0;
-+
-+      /*
-+       * Add the starting directories to search...
-+       */
-+      add_to_dirlist("/devices", &list);
-+      add_to_dirlist("/devfs", &list);
-+      add_to_dirlist("/dev", &list);
-+      
-+      while (list) {
-+              current = list;
-+              list = list->next;
-+#ifdef DEBUG
-+              printf("Scanning directory %s\n", current->name);
-+#endif
-+              scan_dir(current->name, device, &new_list, &ret_path);
-+              free(current->name);
-+              free(current);
-+              if (ret_path)
-+                      break;
-+              /*
-+               * If we're done checking at this level, descend to
-+               * the next level of subdirectories. (breadth-first)
-+               */
-+              if (list == 0) {
-+                      list = new_list;
-+                      new_list = 0;
-+              }
-+      }
-+      free_dirlist(&list);
-+      free_dirlist(&new_list);
-+      return ret_path;
-+}
-+
-+      
-+#ifdef DEBUG
-+int main(int argc, char** argv)
-+{
-+      char    *devname, *tmp;
-+      int     major, minor;
-+      dev_t   device;
-+      const char *errmsg = "Couldn't parse %s: %s\n";
-+
-+      if ((argc != 2) && (argc != 3)) {
-+              fprintf(stderr, "Usage: %s device_number\n", argv[0]);
-+              fprintf(stderr, "\t: %s major minor\n", argv[0]);
-+              exit(1);
-+      }
-+      if (argc == 2) {
-+              device = strtoul(argv[1], &tmp, 0);
-+              if (*tmp) {
-+                      fprintf(stderr, errmsg, "device number", argv[1]);
-+                      exit(1);
-+              }
-+      } else {
-+              major = strtoul(argv[1], &tmp, 0);
-+              if (*tmp) {
-+                      fprintf(stderr, errmsg, "major number", argv[1]);
-+                      exit(1);
-+              }
-+              minor = strtoul(argv[2], &tmp, 0);
-+              if (*tmp) {
-+                      fprintf(stderr, errmsg, "minor number", argv[2]);
-+                      exit(1);
-+              }
-+              device = makedev(major, minor);
-+              printf("Looking for device 0x%04x (%d:%d)\n", device,
-+                     major, minor);
-+      }
-+      devname = ext2fs_find_block_device(device);
-+      if (devname) {
-+              printf("Found device!  %s\n", devname);
-+              free(devname);
-+      } else {
-+              printf("Couldn't find device.\n");
-+      }
-+      return 0;
-+}
-+      
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/flushb.c busybox/e2fsprogs/ext2fs/flushb.c
---- busybox-1.00/e2fsprogs/ext2fs/flushb.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/flushb.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,82 @@
-+/*
-+ * flushb.c --- Hides system-dependent information for both syncing a
-+ *    device to disk and to flush any buffers from disk cache.
-+ * 
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_SYS_IOCTL_H
-+#include <sys/ioctl.h>
-+#endif
-+#if HAVE_SYS_MOUNT_H
-+#include <sys/param.h>
-+#include <sys/mount.h>                /* This may define BLKFLSBUF */
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * For Linux, define BLKFLSBUF and FDFLUSH if necessary, since 
-+ * not all portable header file does so for us.  This really should be
-+ * fixed in the glibc header files.  (Recent glibcs appear to define
-+ * BLKFLSBUF in sys/mount.h, but FDFLUSH still doesn't seem to be
-+ * defined anywhere portable.)  Until then....
-+ */
-+#ifdef __linux__
-+#ifndef BLKFLSBUF
-+#define BLKFLSBUF     _IO(0x12,97)    /* flush buffer cache */
-+#endif
-+#ifndef FDFLUSH
-+#define FDFLUSH               _IO(2,0x4b)     /* flush floppy disk */
-+#endif
-+#endif
-+
-+/*
-+ * This function will sync a device/file, and optionally attempt to
-+ * flush the buffer cache.  The latter is basically only useful for
-+ * system benchmarks and for torturing systems in burn-in tests.  :)
-+ */
-+errcode_t ext2fs_sync_device(int fd, int flushb)
-+{
-+      /*
-+       * We always sync the device in case we're running on old
-+       * kernels for which we can lose data if we don't.  (There
-+       * still is a race condition for those kernels, but this
-+       * reduces it greatly.)
-+       */
-+      if (fsync (fd) == -1)
-+              return errno;
-+
-+      if (flushb) {
-+
-+#ifdef BLKFLSBUF
-+              if (ioctl (fd, BLKFLSBUF, 0) == 0)
-+                      return 0;
-+#else
-+#ifdef __GNUC__
-+ #warning BLKFLSBUF not defined
-+#endif /* __GNUC__ */
-+#endif
-+#ifdef FDFLUSH
-+              ioctl (fd, FDFLUSH, 0);   /* In case this is a floppy */
-+#else
-+#ifdef __GNUC__
-+ #warning FDFLUSH not defined
-+#endif /* __GNUC__ */
-+#endif
-+      }
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/freefs.c busybox/e2fsprogs/ext2fs/freefs.c
---- busybox-1.00/e2fsprogs/ext2fs/freefs.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/freefs.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,147 @@
-+/*
-+ * freefs.c --- free an ext2 filesystem
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache);
-+
-+void ext2fs_free(ext2_filsys fs)
-+{
-+      if (!fs || (fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS))
-+              return;
-+      if (fs->image_io != fs->io) {
-+              if (fs->image_io)
-+                      io_channel_close(fs->image_io);
-+      }
-+      if (fs->io) {
-+              io_channel_close(fs->io);
-+      }
-+      if (fs->device_name)
-+              ext2fs_free_mem(&fs->device_name);
-+      if (fs->super)
-+              ext2fs_free_mem(&fs->super);
-+      if (fs->orig_super)
-+              ext2fs_free_mem(&fs->orig_super);
-+      if (fs->group_desc)
-+              ext2fs_free_mem(&fs->group_desc);
-+      if (fs->block_map)
-+              ext2fs_free_block_bitmap(fs->block_map);
-+      if (fs->inode_map)
-+              ext2fs_free_inode_bitmap(fs->inode_map);
-+
-+      if (fs->badblocks)
-+              ext2fs_badblocks_list_free(fs->badblocks);
-+      fs->badblocks = 0;
-+
-+      if (fs->dblist)
-+              ext2fs_free_dblist(fs->dblist);
-+
-+      if (fs->icache)
-+              ext2fs_free_inode_cache(fs->icache);
-+      
-+      fs->magic = 0;
-+
-+      ext2fs_free_mem(&fs);
-+}
-+
-+void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
-+{
-+      if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_GENERIC_BITMAP))
-+              return;
-+
-+      bitmap->magic = 0;
-+      if (bitmap->description) {
-+              ext2fs_free_mem(&bitmap->description);
-+              bitmap->description = 0;
-+      }
-+      if (bitmap->bitmap) {
-+              ext2fs_free_mem(&bitmap->bitmap);
-+              bitmap->bitmap = 0;
-+      }
-+      ext2fs_free_mem(&bitmap);
-+}
-+
-+void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
-+{
-+      if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
-+              return;
-+
-+      bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
-+      ext2fs_free_generic_bitmap(bitmap);
-+}
-+
-+void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap)
-+{
-+      if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
-+              return;
-+
-+      bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
-+      ext2fs_free_generic_bitmap(bitmap);
-+}
-+
-+/*
-+ * Free the inode cache structure
-+ */
-+static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache)
-+{
-+      if (--icache->refcount)
-+              return;
-+      if (icache->buffer)
-+              ext2fs_free_mem(&icache->buffer);
-+      if (icache->cache)
-+              ext2fs_free_mem(&icache->cache);
-+      icache->buffer_blk = 0;
-+      ext2fs_free_mem(&icache);
-+}
-+
-+/*
-+ * This procedure frees a badblocks list.
-+ */
-+void ext2fs_u32_list_free(ext2_u32_list bb)
-+{
-+      if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
-+              return;
-+
-+      if (bb->list)
-+              ext2fs_free_mem(&bb->list);
-+      bb->list = 0;
-+      ext2fs_free_mem(&bb);
-+}
-+
-+void ext2fs_badblocks_list_free(ext2_badblocks_list bb)
-+{
-+      ext2fs_u32_list_free((ext2_u32_list) bb);
-+}
-+
-+
-+/*
-+ * Free a directory block list
-+ */
-+void ext2fs_free_dblist(ext2_dblist dblist)
-+{
-+      if (!dblist || (dblist->magic != EXT2_ET_MAGIC_DBLIST))
-+              return;
-+
-+      if (dblist->list)
-+              ext2fs_free_mem(&dblist->list);
-+      dblist->list = 0;
-+      if (dblist->fs && dblist->fs->dblist == dblist)
-+              dblist->fs->dblist = 0;
-+      dblist->magic = 0;
-+      ext2fs_free_mem(&dblist);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/gen_bitmap.c busybox/e2fsprogs/ext2fs/gen_bitmap.c
---- busybox-1.00/e2fsprogs/ext2fs/gen_bitmap.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/gen_bitmap.c      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,48 @@
-+/*
-+ * gen_bitmap.c --- Generic bitmap routines that used to be inlined.
-+ * 
-+ * Copyright (C) 2001 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
-+                                       __u32 bitno)
-+{
-+      if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
-+              ext2fs_warn_bitmap2(bitmap, EXT2FS_MARK_ERROR, bitno);
-+              return 0;
-+      }
-+      return ext2fs_set_bit(bitno - bitmap->start, bitmap->bitmap);
-+}
-+
-+int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
-+                                         blk_t bitno)
-+{
-+      if ((bitno < bitmap->start) || (bitno > bitmap->end)) {
-+              ext2fs_warn_bitmap2(bitmap, EXT2FS_UNMARK_ERROR, bitno);
-+              return 0;
-+      }
-+      return ext2fs_clear_bit(bitno - bitmap->start, bitmap->bitmap);
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/get_pathname.c busybox/e2fsprogs/ext2fs/get_pathname.c
---- busybox-1.00/e2fsprogs/ext2fs/get_pathname.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/get_pathname.c    2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,157 @@
-+/*
-+ * get_pathname.c --- do directry/inode -> name translation
-+ * 
-+ * Copyright (C) 1993, 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ *
-+ *    ext2fs_get_pathname(fs, dir, ino, name)
-+ *
-+ *    This function translates takes two inode numbers into a
-+ *    string, placing the result in <name>.  <dir> is the containing
-+ *    directory inode, and <ino> is the inode number itself.  If
-+ *    <ino> is zero, then ext2fs_get_pathname will return pathname
-+ *    of the the directory <dir>.
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct get_pathname_struct {
-+      ext2_ino_t      search_ino;
-+      ext2_ino_t      parent;
-+      char            *name;
-+      errcode_t       errcode;
-+};
-+
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int get_pathname_proc(struct ext2_dir_entry *dirent,
-+                           int        offset EXT2FS_ATTR((unused)),
-+                           int        blocksize EXT2FS_ATTR((unused)),
-+                           char       *buf EXT2FS_ATTR((unused)),
-+                           void       *priv_data)
-+{
-+      struct get_pathname_struct      *gp;
-+      errcode_t                       retval;
-+
-+      gp = (struct get_pathname_struct *) priv_data;
-+
-+      if (((dirent->name_len & 0xFF) == 2) &&
-+          !strncmp(dirent->name, "..", 2))
-+              gp->parent = dirent->inode;
-+      if (dirent->inode == gp->search_ino) {
-+              retval = ext2fs_get_mem((dirent->name_len & 0xFF) + 1,
-+                                      &gp->name);
-+              if (retval) {
-+                      gp->errcode = retval;
-+                      return DIRENT_ABORT;
-+              }
-+              strncpy(gp->name, dirent->name, (dirent->name_len & 0xFF));
-+              gp->name[dirent->name_len & 0xFF] = '\0';
-+              return DIRENT_ABORT;
-+      }
-+      return 0;
-+}
-+
-+static errcode_t ext2fs_get_pathname_int(ext2_filsys fs, ext2_ino_t dir, 
-+                                       ext2_ino_t ino, int maxdepth, 
-+                                       char *buf, char **name)
-+{
-+      struct get_pathname_struct gp;
-+      char    *parent_name, *ret;
-+      errcode_t       retval;
-+
-+      if (dir == ino) {
-+              retval = ext2fs_get_mem(2, name);
-+              if (retval)
-+                      return retval;
-+              strcpy(*name, (dir == EXT2_ROOT_INO) ? "/" : ".");
-+              return 0;
-+      }
-+
-+      if (!dir || (maxdepth < 0)) {
-+              retval = ext2fs_get_mem(4, name);
-+              if (retval)
-+                      return retval;
-+              strcpy(*name, "...");
-+              return 0;
-+      }
-+
-+      gp.search_ino = ino;
-+      gp.parent = 0;
-+      gp.name = 0;
-+      gp.errcode = 0;
-+      
-+      retval = ext2fs_dir_iterate(fs, dir, 0, buf, get_pathname_proc, &gp);
-+      if (retval)
-+              goto cleanup;
-+      if (gp.errcode) {
-+              retval = gp.errcode;
-+              goto cleanup;
-+      }
-+
-+      retval = ext2fs_get_pathname_int(fs, gp.parent, dir, maxdepth-1,
-+                                       buf, &parent_name);
-+      if (retval)
-+              goto cleanup;
-+      if (!ino) {
-+              *name = parent_name;
-+              return 0;
-+      }
-+      
-+      if (gp.name) 
-+              retval = ext2fs_get_mem(strlen(parent_name)+strlen(gp.name)+2,
-+                                      &ret);
-+      else
-+              retval = ext2fs_get_mem(strlen(parent_name)+5, &ret);
-+      if (retval)
-+              goto cleanup;
-+      
-+      ret[0] = 0;
-+      if (parent_name[1])
-+              strcat(ret, parent_name);
-+      strcat(ret, "/");
-+      if (gp.name)
-+              strcat(ret, gp.name);
-+      else
-+              strcat(ret, "???");
-+      *name = ret;
-+      ext2fs_free_mem(&parent_name);
-+      retval = 0;
-+      
-+cleanup:
-+      if (gp.name)
-+              ext2fs_free_mem(&gp.name);
-+      return retval;
-+}
-+
-+errcode_t ext2fs_get_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino,
-+                            char **name)
-+{
-+      char    *buf;
-+      errcode_t       retval;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      retval = ext2fs_get_mem(fs->blocksize, &buf);
-+      if (retval)
-+              return retval;
-+      if (dir == ino)
-+              ino = 0;
-+      retval = ext2fs_get_pathname_int(fs, dir, ino, 32, buf, name);
-+      ext2fs_free_mem(&buf);
-+      return retval;
-+      
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/getsectsize.c busybox/e2fsprogs/ext2fs/getsectsize.c
---- busybox-1.00/e2fsprogs/ext2fs/getsectsize.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/getsectsize.c     2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,57 @@
-+/*
-+ * getsectsize.c --- get the sector size of a device.
-+ * 
-+ * Copyright (C) 1995, 1995 Theodore Ts'o.
-+ * Copyright (C) 2003 VMware, Inc.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#ifdef HAVE_LINUX_FD_H
-+#include <sys/ioctl.h>
-+#include <linux/fd.h>
-+#endif
-+
-+#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
-+#define BLKSSZGET  _IO(0x12,104)/* get block device sector size */
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * Returns the number of blocks in a partition
-+ */
-+errcode_t ext2fs_get_device_sectsize(const char *file, int *sectsize)
-+{
-+      int     fd;
-+
-+#ifdef CONFIG_LFS
-+      fd = open64(file, O_RDONLY);
-+#else
-+      fd = open(file, O_RDONLY);
-+#endif
-+      if (fd < 0)
-+              return errno;
-+
-+#ifdef BLKSSZGET
-+      if (ioctl(fd, BLKSSZGET, sectsize) >= 0) {
-+              close(fd);
-+              return 0;
-+      }
-+#endif
-+      *sectsize = 0;
-+      close(fd);
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/getsize.c busybox/e2fsprogs/ext2fs/getsize.c
---- busybox-1.00/e2fsprogs/ext2fs/getsize.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/getsize.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,290 @@
-+/*
-+ * getsize.c --- get the size of a partition.
-+ * 
-+ * Copyright (C) 1995, 1995 Theodore Ts'o.
-+ * Copyright (C) 2003 VMware, Inc.
-+ *
-+ * Windows version of ext2fs_get_device_size by Chris Li, VMware.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#ifdef HAVE_SYS_IOCTL_H
-+#include <sys/ioctl.h>
-+#endif
-+#ifdef HAVE_LINUX_FD_H
-+#include <linux/fd.h>
-+#endif
-+#ifdef HAVE_SYS_DISKLABEL_H
-+#include <sys/disklabel.h>
-+#endif
-+#ifdef HAVE_SYS_DISK_H
-+#ifdef HAVE_SYS_QUEUE_H
-+#include <sys/queue.h> /* for LIST_HEAD */
-+#endif
-+#include <sys/disk.h>
-+#endif
-+#ifdef __linux__
-+#include <sys/utsname.h>
-+#endif
-+
-+#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
-+#define BLKGETSIZE _IO(0x12,96)       /* return device size */
-+#endif
-+
-+#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
-+#define BLKGETSIZE64 _IOR(0x12,114,size_t)    /* return device size in bytes (u64 *arg) */
-+#endif
-+
-+#ifdef APPLE_DARWIN
-+#define BLKGETSIZE DKIOCGETBLOCKCOUNT32
-+#endif /* APPLE_DARWIN */
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#if defined(__CYGWIN__) || defined (WIN32)
-+#include "windows.h"
-+#include "winioctl.h"
-+
-+#if (_WIN32_WINNT >= 0x0500)
-+#define HAVE_GET_FILE_SIZE_EX 1
-+#endif
-+
-+errcode_t ext2fs_get_device_size(const char *file, int blocksize,
-+                               blk_t *retblocks)
-+{
-+      HANDLE dev;
-+      PARTITION_INFORMATION pi;
-+      DISK_GEOMETRY gi;
-+      DWORD retbytes;
-+#ifdef HAVE_GET_FILE_SIZE_EX
-+      LARGE_INTEGER filesize;
-+#else
-+      DWORD filesize;
-+#endif /* HAVE_GET_FILE_SIZE_EX */
-+
-+      dev = CreateFile(file, GENERIC_READ, 
-+                       FILE_SHARE_READ | FILE_SHARE_WRITE ,
-+                       NULL,  OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,  NULL); 
-+ 
-+      if (dev == INVALID_HANDLE_VALUE)
-+              return EBADF;
-+      if (DeviceIoControl(dev, IOCTL_DISK_GET_PARTITION_INFO,
-+                          &pi, sizeof(PARTITION_INFORMATION),
-+                          &pi, sizeof(PARTITION_INFORMATION),
-+                          &retbytes, NULL)) {
-+
-+              *retblocks = pi.PartitionLength.QuadPart / blocksize;
-+      
-+      } else if (DeviceIoControl(dev, IOCTL_DISK_GET_DRIVE_GEOMETRY,
-+                              &gi, sizeof(DISK_GEOMETRY),
-+                              &gi, sizeof(DISK_GEOMETRY),
-+                              &retbytes, NULL)) {
-+
-+              *retblocks = gi.BytesPerSector *
-+                           gi.SectorsPerTrack *
-+                           gi.TracksPerCylinder *
-+                           gi.Cylinders.QuadPart / blocksize;
-+
-+#ifdef HAVE_GET_FILE_SIZE_EX
-+      } else if (GetFileSizeEx(dev, &filesize)) {
-+              *retblocks = filesize.QuadPart / blocksize;
-+      }
-+#else
-+      } else {
-+              filesize = GetFileSize(dev, NULL);
-+              if (INVALID_FILE_SIZE != filesize) {
-+                      *retblocks = filesize / blocksize;
-+              }
-+      }
-+#endif /* HAVE_GET_FILE_SIZE_EX */
-+
-+      CloseHandle(dev);
-+      return 0;
-+}
-+
-+#else
-+
-+static int valid_offset (int fd, ext2_loff_t offset)
-+{
-+      char ch;
-+
-+      if (ext2fs_llseek (fd, offset, 0) < 0)
-+              return 0;
-+      if (read (fd, &ch, 1) < 1)
-+              return 0;
-+      return 1;
-+}
-+
-+/*
-+ * Returns the number of blocks in a partition
-+ */
-+errcode_t ext2fs_get_device_size(const char *file, int blocksize,
-+                               blk_t *retblocks)
-+{
-+      int     fd;
-+      int valid_blkgetsize64 = 1;
-+#ifdef __linux__
-+      struct          utsname ut;
-+#endif
-+      unsigned long long size64;
-+      unsigned long   size;
-+      ext2_loff_t high, low;
-+#ifdef FDGETPRM
-+      struct floppy_struct this_floppy;
-+#endif
-+#ifdef HAVE_SYS_DISKLABEL_H
-+      int part;
-+      struct disklabel lab;
-+      struct partition *pp;
-+      char ch;
-+#endif /* HAVE_SYS_DISKLABEL_H */
-+
-+#ifdef CONFIG_LFS
-+      fd = open64(file, O_RDONLY);
-+#else
-+      fd = open(file, O_RDONLY);
-+#endif
-+      if (fd < 0)
-+              return errno;
-+
-+#ifdef DKIOCGETBLOCKCOUNT     /* For Apple Darwin */
-+      if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0) {
-+              if ((sizeof(*retblocks) < sizeof(unsigned long long))
-+                  && ((size64 / (blocksize / 512)) > 0xFFFFFFFF))
-+                      return EFBIG;
-+              close(fd);
-+              *retblocks = size64 / (blocksize / 512);
-+              return 0;
-+      }
-+#endif
-+
-+#ifdef BLKGETSIZE64
-+#ifdef __linux__
-+      if ((uname(&ut) == 0) &&
-+          ((ut.release[0] == '2') && (ut.release[1] == '.') &&
-+           (ut.release[2] < '6') && (ut.release[3] == '.')))
-+              valid_blkgetsize64 = 0;
-+#endif
-+      if (valid_blkgetsize64 &&
-+          ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
-+              if ((sizeof(*retblocks) < sizeof(unsigned long long))
-+                  && ((size64 / blocksize) > 0xFFFFFFFF))
-+                      return EFBIG;
-+              close(fd);
-+              *retblocks = size64 / blocksize;
-+              return 0;
-+      }
-+#endif
-+
-+#ifdef BLKGETSIZE
-+      if (ioctl(fd, BLKGETSIZE, &size) >= 0) {
-+              close(fd);
-+              *retblocks = size / (blocksize / 512);
-+              return 0;
-+      }
-+#endif
-+
-+#ifdef FDGETPRM
-+      if (ioctl(fd, FDGETPRM, &this_floppy) >= 0) {
-+              close(fd);
-+              *retblocks = this_floppy.size / (blocksize / 512);
-+              return 0;
-+      }
-+#endif
-+
-+#ifdef HAVE_SYS_DISKLABEL_H
-+#if defined(DIOCGMEDIASIZE)
-+      {
-+          off_t ms;
-+          u_int bs;
-+          if (ioctl(fd, DIOCGMEDIASIZE, &ms) >= 0) {
-+              *retblocks = ms / blocksize;
-+              return 0;
-+          }
-+      }
-+#elif defined(DIOCGDINFO)
-+      /* old disklabel interface */
-+      part = strlen(file) - 1;
-+      if (part >= 0) {
-+              ch = file[part];
-+              if (isdigit(ch))
-+                      part = 0;
-+              else if (ch >= 'a' && ch <= 'h')
-+                      part = ch - 'a';
-+              else
-+                      part = -1;
-+      }
-+      if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
-+              pp = &lab.d_partitions[part];
-+              if (pp->p_size) {
-+                      close(fd);
-+                      *retblocks = pp->p_size / (blocksize / 512);
-+                      return 0;
-+              }
-+      }
-+#endif /* defined(DIOCG*) */
-+#endif /* HAVE_SYS_DISKLABEL_H */
-+
-+      /*
-+       * OK, we couldn't figure it out by using a specialized ioctl,
-+       * which is generally the best way.  So do binary search to
-+       * find the size of the partition.
-+       */
-+      low = 0;
-+      for (high = 1024; valid_offset (fd, high); high *= 2)
-+              low = high;
-+      while (low < high - 1)
-+      {
-+              const ext2_loff_t mid = (low + high) / 2;
-+
-+              if (valid_offset (fd, mid))
-+                      low = mid;
-+              else
-+                      high = mid;
-+      }
-+      valid_offset (fd, 0);
-+      close(fd);
-+      size64 = low + 1;
-+      if ((sizeof(*retblocks) < sizeof(unsigned long long))
-+          && ((size64 / blocksize) > 0xFFFFFFFF))
-+              return EFBIG;
-+      *retblocks = size64 / blocksize;
-+      return 0;
-+}
-+
-+#endif /* WIN32 */
-+
-+#ifdef DEBUG
-+int main(int argc, char **argv)
-+{
-+      blk_t   blocks;
-+      int     retval;
-+      
-+      if (argc < 2) {
-+              fprintf(stderr, "Usage: %s device\n", argv[0]);
-+              exit(1);
-+      }
-+
-+      retval = ext2fs_get_device_size(argv[1], 1024, &blocks);
-+      if (retval) {
-+              com_err(argv[0], retval,
-+                      "while calling ext2fs_get_device_size");
-+              exit(1);
-+      }
-+      printf("Device %s has %d 1k blocks.\n", argv[1], blocks);
-+      exit(0);
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/icount.c busybox/e2fsprogs/ext2fs/icount.c
---- busybox-1.00/e2fsprogs/ext2fs/icount.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/icount.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,483 @@
-+/*
-+ * icount.c --- an efficient inode count abstraction
-+ *
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <stdio.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * The data storage strategy used by icount relies on the observation
-+ * that most inode counts are either zero (for non-allocated inodes),
-+ * one (for most files), and only a few that are two or more
-+ * (directories and files that are linked to more than one directory).
-+ *
-+ * Also, e2fsck tends to load the icount data sequentially.
-+ *
-+ * So, we use an inode bitmap to indicate which inodes have a count of
-+ * one, and then use a sorted list to store the counts for inodes
-+ * which are greater than one.
-+ *
-+ * We also use an optional bitmap to indicate which inodes are already
-+ * in the sorted list, to speed up the use of this abstraction by
-+ * e2fsck's pass 2.  Pass 2 increments inode counts as it finds them,
-+ * so this extra bitmap avoids searching the sorted list to see if a
-+ * particular inode is on the sorted list already.
-+ */
-+
-+struct ext2_icount_el {
-+      ext2_ino_t      ino;
-+      __u16   count;
-+};
-+
-+struct ext2_icount {
-+      errcode_t               magic;
-+      ext2fs_inode_bitmap     single;
-+      ext2fs_inode_bitmap     multiple;
-+      ext2_ino_t              count;
-+      ext2_ino_t              size;
-+      ext2_ino_t              num_inodes;
-+      ext2_ino_t              cursor;
-+      struct ext2_icount_el   *list;
-+};
-+
-+void ext2fs_free_icount(ext2_icount_t icount)
-+{
-+      if (!icount)
-+              return;
-+
-+      icount->magic = 0;
-+      if (icount->list)
-+              ext2fs_free_mem(&icount->list);
-+      if (icount->single)
-+              ext2fs_free_inode_bitmap(icount->single);
-+      if (icount->multiple)
-+              ext2fs_free_inode_bitmap(icount->multiple);
-+      ext2fs_free_mem(&icount);
-+}
-+
-+errcode_t ext2fs_create_icount2(ext2_filsys fs, int flags, unsigned int size,
-+                              ext2_icount_t hint, ext2_icount_t *ret)
-+{
-+      ext2_icount_t   icount;
-+      errcode_t       retval;
-+      size_t          bytes;
-+      ext2_ino_t      i;
-+
-+      if (hint) {
-+              EXT2_CHECK_MAGIC(hint, EXT2_ET_MAGIC_ICOUNT);
-+              if (hint->size > size)
-+                      size = (size_t) hint->size;
-+      }
-+      
-+      retval = ext2fs_get_mem(sizeof(struct ext2_icount), &icount);
-+      if (retval)
-+              return retval;
-+      memset(icount, 0, sizeof(struct ext2_icount));
-+
-+      retval = ext2fs_allocate_inode_bitmap(fs, 0, 
-+                                            &icount->single);
-+      if (retval)
-+              goto errout;
-+
-+      if (flags & EXT2_ICOUNT_OPT_INCREMENT) {
-+              retval = ext2fs_allocate_inode_bitmap(fs, 0, 
-+                                                    &icount->multiple);
-+              if (retval)
-+                      goto errout;
-+      } else
-+              icount->multiple = 0;
-+
-+      if (size) {
-+              icount->size = size;
-+      } else {
-+              /*
-+               * Figure out how many special case inode counts we will
-+               * have.  We know we will need one for each directory;
-+               * we also need to reserve some extra room for file links
-+               */
-+              retval = ext2fs_get_num_dirs(fs, &icount->size);
-+              if (retval)
-+                      goto errout;
-+              icount->size += fs->super->s_inodes_count / 50;
-+      }
-+      
-+      bytes = (size_t) (icount->size * sizeof(struct ext2_icount_el));
-+#if 0
-+      printf("Icount allocated %d entries, %d bytes.\n",
-+             icount->size, bytes);
-+#endif
-+      retval = ext2fs_get_mem(bytes, &icount->list);
-+      if (retval)
-+              goto errout;
-+      memset(icount->list, 0, bytes);
-+
-+      icount->magic = EXT2_ET_MAGIC_ICOUNT;
-+      icount->count = 0;
-+      icount->cursor = 0;
-+      icount->num_inodes = fs->super->s_inodes_count;
-+
-+      /*
-+       * Populate the sorted list with those entries which were
-+       * found in the hint icount (since those are ones which will
-+       * likely need to be in the sorted list this time around).
-+       */
-+      if (hint) {
-+              for (i=0; i < hint->count; i++)
-+                      icount->list[i].ino = hint->list[i].ino;
-+              icount->count = hint->count;
-+      }
-+
-+      *ret = icount;
-+      return 0;
-+
-+errout:
-+      ext2fs_free_icount(icount);
-+      return(retval);
-+}
-+
-+errcode_t ext2fs_create_icount(ext2_filsys fs, int flags, 
-+                             unsigned int size,
-+                             ext2_icount_t *ret)
-+{
-+      return ext2fs_create_icount2(fs, flags, size, 0, ret);
-+}
-+
-+/*
-+ * insert_icount_el() --- Insert a new entry into the sorted list at a
-+ *    specified position.
-+ */
-+static struct ext2_icount_el *insert_icount_el(ext2_icount_t icount,
-+                                          ext2_ino_t ino, int pos)
-+{
-+      struct ext2_icount_el   *el;
-+      errcode_t               retval;
-+      ext2_ino_t                      new_size = 0;
-+      int                     num;
-+
-+      if (icount->count >= icount->size) {
-+              if (icount->count) {
-+                      new_size = icount->list[(unsigned)icount->count-1].ino;
-+                      new_size = (ext2_ino_t) (icount->count * 
-+                              ((float) icount->num_inodes / new_size));
-+              }
-+              if (new_size < (icount->size + 100))
-+                      new_size = icount->size + 100;
-+#if 0
-+              printf("Reallocating icount %d entries...\n", new_size);
-+#endif        
-+              retval = ext2fs_resize_mem((size_t) icount->size *
-+                                         sizeof(struct ext2_icount_el),
-+                                         (size_t) new_size *
-+                                         sizeof(struct ext2_icount_el),
-+                                         &icount->list);
-+              if (retval)
-+                      return 0;
-+              icount->size = new_size;
-+      }
-+      num = (int) icount->count - pos;
-+      if (num < 0)
-+              return 0;       /* should never happen */
-+      if (num) {
-+              memmove(&icount->list[pos+1], &icount->list[pos],
-+                      sizeof(struct ext2_icount_el) * num);
-+      }
-+      icount->count++;
-+      el = &icount->list[pos];
-+      el->count = 0;
-+      el->ino = ino;
-+      return el;
-+}
-+
-+/*
-+ * get_icount_el() --- given an inode number, try to find icount
-+ *    information in the sorted list.  If the create flag is set,
-+ *    and we can't find an entry, create one in the sorted list.
-+ */
-+static struct ext2_icount_el *get_icount_el(ext2_icount_t icount,
-+                                          ext2_ino_t ino, int create)
-+{
-+      float   range;
-+      int     low, high, mid;
-+      ext2_ino_t      lowval, highval;
-+
-+      if (!icount || !icount->list)
-+              return 0;
-+
-+      if (create && ((icount->count == 0) ||
-+                     (ino > icount->list[(unsigned)icount->count-1].ino))) {
-+              return insert_icount_el(icount, ino, (unsigned) icount->count);
-+      }
-+      if (icount->count == 0)
-+              return 0;
-+      
-+      if (icount->cursor >= icount->count)
-+              icount->cursor = 0;
-+      if (ino == icount->list[icount->cursor].ino)
-+              return &icount->list[icount->cursor++];
-+#if 0
-+      printf("Non-cursor get_icount_el: %u\n", ino);
-+#endif
-+      low = 0;
-+      high = (int) icount->count-1;
-+      while (low <= high) {
-+#if 0
-+              mid = (low+high)/2;
-+#else
-+              if (low == high)
-+                      mid = low;
-+              else {
-+                      /* Interpolate for efficiency */
-+                      lowval = icount->list[low].ino;
-+                      highval = icount->list[high].ino;
-+
-+                      if (ino < lowval)
-+                              range = 0;
-+                      else if (ino > highval)
-+                              range = 1;
-+                      else 
-+                              range = ((float) (ino - lowval)) /
-+                                      (highval - lowval);
-+                      mid = low + ((int) (range * (high-low)));
-+              }
-+#endif
-+              if (ino == icount->list[mid].ino) {
-+                      icount->cursor = mid+1;
-+                      return &icount->list[mid];
-+              }
-+              if (ino < icount->list[mid].ino)
-+                      high = mid-1;
-+              else
-+                      low = mid+1;
-+      }
-+      /*
-+       * If we need to create a new entry, it should be right at
-+       * low (where high will be left at low-1).
-+       */
-+      if (create)
-+              return insert_icount_el(icount, ino, low);
-+      return 0;
-+}
-+
-+errcode_t ext2fs_icount_validate(ext2_icount_t icount, FILE *out)
-+{
-+      errcode_t       ret = 0;
-+      unsigned int    i;
-+      const char *bad = "bad icount";
-+      
-+      EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-+
-+      if (icount->count > icount->size) {
-+              fprintf(out, "%s: count > size\n", bad);
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      }
-+      for (i=1; i < icount->count; i++) {
-+              if (icount->list[i-1].ino >= icount->list[i].ino) {
-+                      fprintf(out, "%s: list[%d].ino=%u, list[%d].ino=%u\n",
-+                              bad, i-1, icount->list[i-1].ino,
-+                              i, icount->list[i].ino);
-+                      ret = EXT2_ET_INVALID_ARGUMENT;
-+              }
-+      }
-+      return ret;
-+}
-+
-+errcode_t ext2fs_icount_fetch(ext2_icount_t icount, ext2_ino_t ino, __u16 *ret)
-+{
-+      struct ext2_icount_el   *el;
-+      
-+      EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-+
-+      if (!ino || (ino > icount->num_inodes))
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      if (ext2fs_test_inode_bitmap(icount->single, ino)) {
-+              *ret = 1;
-+              return 0;
-+      }
-+      if (icount->multiple &&
-+          !ext2fs_test_inode_bitmap(icount->multiple, ino)) {
-+              *ret = 0;
-+              return 0;
-+      }
-+      el = get_icount_el(icount, ino, 0);
-+      if (!el) {
-+              *ret = 0;
-+              return 0;
-+      }
-+      *ret = el->count;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_icount_increment(ext2_icount_t icount, ext2_ino_t ino,
-+                                __u16 *ret)
-+{
-+      struct ext2_icount_el   *el;
-+
-+      EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-+
-+      if (!ino || (ino > icount->num_inodes))
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      if (ext2fs_test_inode_bitmap(icount->single, ino)) {
-+              /*
-+               * If the existing count is 1, then we know there is
-+               * no entry in the list.
-+               */
-+              el = get_icount_el(icount, ino, 1);
-+              if (!el)
-+                      return EXT2_ET_NO_MEMORY;
-+              ext2fs_unmark_inode_bitmap(icount->single, ino);
-+              el->count = 2;
-+      } else if (icount->multiple) {
-+              /*
-+               * The count is either zero or greater than 1; if the
-+               * inode is set in icount->multiple, then there should
-+               * be an entry in the list, so find it using
-+               * get_icount_el().
-+               */
-+              if (ext2fs_test_inode_bitmap(icount->multiple, ino)) {
-+                      el = get_icount_el(icount, ino, 1);
-+                      if (!el)
-+                              return EXT2_ET_NO_MEMORY;
-+                      el->count++;
-+              } else {
-+                      /*
-+                       * The count was zero; mark the single bitmap
-+                       * and return.
-+                       */
-+              zero_count:
-+                      ext2fs_mark_inode_bitmap(icount->single, ino);
-+                      if (ret)
-+                              *ret = 1;
-+                      return 0;
-+              }
-+      } else {
-+              /*
-+               * The count is either zero or greater than 1; try to
-+               * find an entry in the list to determine which.
-+               */
-+              el = get_icount_el(icount, ino, 0);
-+              if (!el) {
-+                      /* No entry means the count was zero */
-+                      goto zero_count;
-+              }
-+              el = get_icount_el(icount, ino, 1);
-+              if (!el)
-+                      return EXT2_ET_NO_MEMORY;
-+              el->count++;
-+      }
-+      if (icount->multiple)
-+              ext2fs_mark_inode_bitmap(icount->multiple, ino);
-+      if (ret)
-+              *ret = el->count;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_icount_decrement(ext2_icount_t icount, ext2_ino_t ino,
-+                                __u16 *ret)
-+{
-+      struct ext2_icount_el   *el;
-+
-+      if (!ino || (ino > icount->num_inodes))
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-+
-+      if (ext2fs_test_inode_bitmap(icount->single, ino)) {
-+              ext2fs_unmark_inode_bitmap(icount->single, ino);
-+              if (icount->multiple)
-+                      ext2fs_unmark_inode_bitmap(icount->multiple, ino);
-+              else {
-+                      el = get_icount_el(icount, ino, 0);
-+                      if (el)
-+                              el->count = 0;
-+              }
-+              if (ret)
-+                      *ret = 0;
-+              return 0;
-+      }
-+
-+      if (icount->multiple &&
-+          !ext2fs_test_inode_bitmap(icount->multiple, ino))
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      
-+      el = get_icount_el(icount, ino, 0);
-+      if (!el || el->count == 0)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      el->count--;
-+      if (el->count == 1)
-+              ext2fs_mark_inode_bitmap(icount->single, ino);
-+      if ((el->count == 0) && icount->multiple)
-+              ext2fs_unmark_inode_bitmap(icount->multiple, ino);
-+
-+      if (ret)
-+              *ret = el->count;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_icount_store(ext2_icount_t icount, ext2_ino_t ino,
-+                            __u16 count)
-+{
-+      struct ext2_icount_el   *el;
-+
-+      if (!ino || (ino > icount->num_inodes))
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      EXT2_CHECK_MAGIC(icount, EXT2_ET_MAGIC_ICOUNT);
-+
-+      if (count == 1) {
-+              ext2fs_mark_inode_bitmap(icount->single, ino);
-+              if (icount->multiple)
-+                      ext2fs_unmark_inode_bitmap(icount->multiple, ino);
-+              return 0;
-+      }
-+      if (count == 0) {
-+              ext2fs_unmark_inode_bitmap(icount->single, ino);
-+              if (icount->multiple) {
-+                      /*
-+                       * If the icount->multiple bitmap is enabled,
-+                       * we can just clear both bitmaps and we're done
-+                       */
-+                      ext2fs_unmark_inode_bitmap(icount->multiple, ino);
-+              } else {
-+                      el = get_icount_el(icount, ino, 0);
-+                      if (el)
-+                              el->count = 0;
-+              }
-+              return 0;
-+      }
-+
-+      /*
-+       * Get the icount element
-+       */
-+      el = get_icount_el(icount, ino, 1);
-+      if (!el)
-+              return EXT2_ET_NO_MEMORY;
-+      el->count = count;
-+      ext2fs_unmark_inode_bitmap(icount->single, ino);
-+      if (icount->multiple)
-+              ext2fs_mark_inode_bitmap(icount->multiple, ino);
-+      return 0;
-+}
-+
-+ext2_ino_t ext2fs_get_icount_size(ext2_icount_t icount)
-+{
-+      if (!icount || icount->magic != EXT2_ET_MAGIC_ICOUNT)
-+              return 0;
-+
-+      return icount->size;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/imager.c busybox/e2fsprogs/ext2fs/imager.c
---- busybox-1.00/e2fsprogs/ext2fs/imager.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/imager.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,387 @@
-+/*
-+ * image.c --- writes out the critical parts of the filesystem as a
-+ *    flat file.
-+ *
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ *
-+ * Note: this uses the POSIX IO interfaces, unlike most of the other
-+ * functions in this library.  So sue me.  
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#ifndef HAVE_TYPE_SSIZE_T
-+typedef int ssize_t;
-+#endif
-+
-+/*
-+ * This function returns 1 if the specified block is all zeros
-+ */
-+static int check_zero_block(char *buf, int blocksize)
-+{
-+      char    *cp = buf;
-+      int     left = blocksize;
-+
-+      while (left > 0) {
-+              if (*cp++)
-+                      return 0;
-+              left--;
-+      }
-+      return 1;
-+}
-+
-+/*
-+ * Write the inode table out as a single block.
-+ */
-+#define BUF_BLOCKS    32
-+
-+errcode_t ext2fs_image_inode_write(ext2_filsys fs, int fd, int flags)
-+{
-+      unsigned int    group, left, c, d;
-+      char            *buf, *cp;
-+      blk_t           blk;
-+      ssize_t         actual;
-+      errcode_t       retval;
-+
-+      buf = malloc(fs->blocksize * BUF_BLOCKS);
-+      if (!buf)
-+              return ENOMEM;
-+      
-+      for (group = 0; group < fs->group_desc_count; group++) {
-+              blk = fs->group_desc[(unsigned)group].bg_inode_table;
-+              if (!blk)
-+                      return EXT2_ET_MISSING_INODE_TABLE;
-+              left = fs->inode_blocks_per_group;
-+              while (left) {
-+                      c = BUF_BLOCKS;
-+                      if (c > left)
-+                              c = left;
-+                      retval = io_channel_read_blk(fs->io, blk, c, buf);
-+                      if (retval)
-+                              goto errout;
-+                      cp = buf;
-+                      while (c) {
-+                              if (!(flags & IMAGER_FLAG_SPARSEWRITE)) {
-+                                      d = c;
-+                                      goto skip_sparse;
-+                              }
-+                              /* Skip zero blocks */
-+                              if (check_zero_block(cp, fs->blocksize)) {
-+                                      c--;
-+                                      blk++;
-+                                      left--;
-+                                      cp += fs->blocksize;
-+                                      lseek(fd, fs->blocksize, SEEK_CUR);
-+                                      continue;
-+                              }
-+                              /* Find non-zero blocks */
-+                              for (d=1; d < c; d++) {
-+                                      if (check_zero_block(cp + d*fs->blocksize, fs->blocksize))
-+                                              break;
-+                              }
-+                      skip_sparse:
-+                              actual = write(fd, cp, fs->blocksize * d);
-+                              if (actual == -1) {
-+                                      retval = errno;
-+                                      goto errout;
-+                              }
-+                              if (actual != (ssize_t) (fs->blocksize * d)) {
-+                                      retval = EXT2_ET_SHORT_WRITE;
-+                                      goto errout;
-+                              }
-+                              blk += d;
-+                              left -= d;
-+                              cp += fs->blocksize * d;
-+                              c -= d;
-+                      }
-+              }
-+      }
-+      retval = 0;
-+
-+errout:
-+      free(buf);
-+      return retval;
-+}
-+
-+/*
-+ * Read in the inode table and stuff it into place
-+ */
-+errcode_t ext2fs_image_inode_read(ext2_filsys fs, int fd, 
-+                                int flags EXT2FS_ATTR((unused)))
-+{
-+      unsigned int    group, c, left;
-+      char            *buf;
-+      blk_t           blk;
-+      ssize_t         actual;
-+      errcode_t       retval;
-+
-+      buf = malloc(fs->blocksize * BUF_BLOCKS);
-+      if (!buf)
-+              return ENOMEM;
-+      
-+      for (group = 0; group < fs->group_desc_count; group++) {
-+              blk = fs->group_desc[(unsigned)group].bg_inode_table;
-+              if (!blk) {
-+                      retval = EXT2_ET_MISSING_INODE_TABLE;
-+                      goto errout;
-+              }
-+              left = fs->inode_blocks_per_group;
-+              while (left) {
-+                      c = BUF_BLOCKS;
-+                      if (c > left)
-+                              c = left;
-+                      actual = read(fd, buf, fs->blocksize * c);
-+                      if (actual == -1) {
-+                              retval = errno;
-+                              goto errout;
-+                      }
-+                      if (actual != (ssize_t) (fs->blocksize * c)) {
-+                              retval = EXT2_ET_SHORT_READ;
-+                              goto errout;
-+                      }
-+                      retval = io_channel_write_blk(fs->io, blk, c, buf);
-+                      if (retval)
-+                              goto errout;
-+                      
-+                      blk += c;
-+                      left -= c;
-+              }
-+      }
-+      retval = ext2fs_flush_icache(fs);
-+
-+errout:
-+      free(buf);
-+      return retval;
-+}
-+
-+/*
-+ * Write out superblock and group descriptors
-+ */
-+errcode_t ext2fs_image_super_write(ext2_filsys fs, int fd, 
-+                                 int flags EXT2FS_ATTR((unused)))
-+{
-+      char            *buf, *cp;
-+      ssize_t         actual;
-+      errcode_t       retval;
-+
-+      buf = malloc(fs->blocksize);
-+      if (!buf)
-+              return ENOMEM;
-+
-+      /*
-+       * Write out the superblock
-+       */
-+      memset(buf, 0, fs->blocksize);
-+      memcpy(buf, fs->super, SUPERBLOCK_SIZE);
-+      actual = write(fd, buf, fs->blocksize);
-+      if (actual == -1) {
-+              retval = errno;
-+              goto errout;
-+      }
-+      if (actual != (ssize_t) fs->blocksize) {
-+              retval = EXT2_ET_SHORT_WRITE;
-+              goto errout;
-+      }
-+
-+      /*
-+       * Now write out the block group descriptors
-+       */
-+      cp = (char *) fs->group_desc;
-+      actual = write(fd, cp, fs->blocksize * fs->desc_blocks);
-+      if (actual == -1) {
-+              retval = errno;
-+              goto errout;
-+      }
-+      if (actual != (ssize_t) (fs->blocksize * fs->desc_blocks)) {
-+              retval = EXT2_ET_SHORT_WRITE;
-+              goto errout;
-+      }
-+      
-+      retval = 0;
-+
-+errout:
-+      free(buf);
-+      return retval;
-+}
-+
-+/*
-+ * Read the superblock and group descriptors and overwrite them.
-+ */
-+errcode_t ext2fs_image_super_read(ext2_filsys fs, int fd, 
-+                                int flags EXT2FS_ATTR((unused)))
-+{
-+      char            *buf;
-+      ssize_t         actual, size;
-+      errcode_t       retval;
-+
-+      size = fs->blocksize * (fs->group_desc_count + 1);
-+      buf = malloc(size);
-+      if (!buf)
-+              return ENOMEM;
-+
-+      /*
-+       * Read it all in.
-+       */
-+      actual = read(fd, buf, size);
-+      if (actual == -1) {
-+              retval = errno;
-+              goto errout;
-+      }
-+      if (actual != size) {
-+              retval = EXT2_ET_SHORT_READ;
-+              goto errout;
-+      }
-+
-+      /*
-+       * Now copy in the superblock and group descriptors
-+       */
-+      memcpy(fs->super, buf, SUPERBLOCK_SIZE);
-+
-+      memcpy(fs->group_desc, buf + fs->blocksize,
-+             fs->blocksize * fs->group_desc_count);
-+
-+      retval = 0;
-+
-+errout:
-+      free(buf);
-+      return retval;
-+}
-+
-+/*
-+ * Write the block/inode bitmaps.
-+ */
-+errcode_t ext2fs_image_bitmap_write(ext2_filsys fs, int fd, int flags)
-+{
-+      char            *ptr;
-+      int             c, size;
-+      char            zero_buf[1024];
-+      ssize_t         actual;
-+      errcode_t       retval;
-+
-+      if (flags & IMAGER_FLAG_INODEMAP) {
-+              if (!fs->inode_map) {
-+                      retval = ext2fs_read_inode_bitmap(fs);
-+                      if (retval)
-+                              return retval;
-+              }
-+              ptr = fs->inode_map->bitmap;
-+              size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
-+      } else {
-+              if (!fs->block_map) {
-+                      retval = ext2fs_read_block_bitmap(fs);
-+                      if (retval)
-+                              return retval;
-+              }
-+              ptr = fs->block_map->bitmap;
-+              size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-+      }
-+      size = size * fs->group_desc_count;
-+
-+      actual = write(fd, ptr, size);
-+      if (actual == -1) {
-+              retval = errno;
-+              goto errout;
-+      }
-+      if (actual != size) {
-+              retval = EXT2_ET_SHORT_WRITE;
-+              goto errout;
-+      }
-+      size = size % fs->blocksize;
-+      memset(zero_buf, 0, sizeof(zero_buf));
-+      if (size) {
-+              size = fs->blocksize - size;
-+              while (size) {
-+                      c = size;
-+                      if (c > (int) sizeof(zero_buf))
-+                              c = sizeof(zero_buf);
-+                      actual = write(fd, zero_buf, c);
-+                      if (actual == -1) {
-+                              retval = errno;
-+                              goto errout;
-+                      }
-+                      if (actual != c) {
-+                              retval = EXT2_ET_SHORT_WRITE;
-+                              goto errout;
-+                      }
-+                      size -= c;
-+              }
-+      }
-+      retval = 0;
-+errout:
-+      return (retval);
-+}
-+
-+
-+/*
-+ * Read the block/inode bitmaps.
-+ */
-+errcode_t ext2fs_image_bitmap_read(ext2_filsys fs, int fd, int flags)
-+{
-+      char            *ptr, *buf = 0;
-+      int             size;
-+      ssize_t         actual;
-+      errcode_t       retval;
-+
-+      if (flags & IMAGER_FLAG_INODEMAP) {
-+              if (!fs->inode_map) {
-+                      retval = ext2fs_read_inode_bitmap(fs);
-+                      if (retval)
-+                              return retval;
-+              }
-+              ptr = fs->inode_map->bitmap;
-+              size = (EXT2_INODES_PER_GROUP(fs->super) / 8);
-+      } else {
-+              if (!fs->block_map) {
-+                      retval = ext2fs_read_block_bitmap(fs);
-+                      if (retval)
-+                              return retval;
-+              }
-+              ptr = fs->block_map->bitmap;
-+              size = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-+      }
-+      size = size * fs->group_desc_count;
-+
-+      buf = malloc(size);
-+      if (!buf)
-+              return ENOMEM;
-+
-+      actual = read(fd, buf, size);
-+      if (actual == -1) {
-+              retval = errno;
-+              goto errout;
-+      }
-+      if (actual != size) {
-+              retval = EXT2_ET_SHORT_WRITE;
-+              goto errout;
-+      }
-+      memcpy(ptr, buf, size);
-+      
-+      retval = 0;
-+errout:
-+      if (buf)
-+              free(buf);
-+      return (retval);
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/ind_block.c busybox/e2fsprogs/ext2fs/ind_block.c
---- busybox-1.00/e2fsprogs/ext2fs/ind_block.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/ind_block.c       2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,66 @@
-+/*
-+ * ind_block.c --- indirect block I/O routines
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 
-+ *    2001, 2002, 2003, 2004, 2005 by  Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_read_ind_block(ext2_filsys fs, blk_t blk, void *buf)
-+{
-+      errcode_t       retval;
-+      blk_t           *block_nr;
-+      int             i;
-+      int             limit = fs->blocksize >> 2;
-+
-+      if ((fs->flags & EXT2_FLAG_IMAGE_FILE) &&
-+          (fs->io != fs->image_io))
-+              memset(buf, 0, fs->blocksize);
-+      else {
-+              retval = io_channel_read_blk(fs->io, blk, 1, buf);
-+              if (retval)
-+                      return retval;
-+      }
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if (fs->flags & (EXT2_FLAG_SWAP_BYTES | EXT2_FLAG_SWAP_BYTES_READ)) {
-+              block_nr = (blk_t *) buf;
-+              for (i = 0; i < limit; i++, block_nr++)
-+                      *block_nr = ext2fs_swab32(*block_nr);
-+      }
-+#endif
-+      return 0;
-+}
-+
-+errcode_t ext2fs_write_ind_block(ext2_filsys fs, blk_t blk, void *buf)
-+{
-+      blk_t           *block_nr;
-+      int             i;
-+      int             limit = fs->blocksize >> 2;
-+
-+      if (fs->flags & EXT2_FLAG_IMAGE_FILE)
-+              return 0;
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if (fs->flags & (EXT2_FLAG_SWAP_BYTES | EXT2_FLAG_SWAP_BYTES_WRITE)) {
-+              block_nr = (blk_t *) buf;
-+              for (i = 0; i < limit; i++, block_nr++)
-+                      *block_nr = ext2fs_swab32(*block_nr);
-+      }
-+#endif
-+      return io_channel_write_blk(fs->io, blk, 1, buf);
-+}
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/initialize.c busybox/e2fsprogs/ext2fs/initialize.c
---- busybox-1.00/e2fsprogs/ext2fs/initialize.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/initialize.c      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,387 @@
-+/*
-+ * initialize.c --- initialize a filesystem handle given superblock
-+ *    parameters.  Used by mke2fs when initializing a filesystem.
-+ * 
-+ * Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#if defined(__linux__)    &&  defined(EXT2_OS_LINUX)
-+#define CREATOR_OS EXT2_OS_LINUX
-+#else
-+#if defined(__GNU__)     &&   defined(EXT2_OS_HURD)
-+#define CREATOR_OS EXT2_OS_HURD
-+#else
-+#if defined(__FreeBSD__) &&   defined(EXT2_OS_FREEBSD)
-+#define CREATOR_OS EXT2_OS_FREEBSD
-+#else
-+#if defined(LITES)       &&   defined(EXT2_OS_LITES)
-+#define CREATOR_OS EXT2_OS_LITES
-+#else
-+#define CREATOR_OS EXT2_OS_LINUX /* by default */
-+#endif /* defined(LITES) && defined(EXT2_OS_LITES) */
-+#endif /* defined(__FreeBSD__) && defined(EXT2_OS_FREEBSD) */
-+#endif /* defined(__GNU__)     && defined(EXT2_OS_HURD) */
-+#endif /* defined(__linux__)   && defined(EXT2_OS_LINUX) */
-+      
-+/*
-+ * Note we override the kernel include file's idea of what the default
-+ * check interval (never) should be.  It's a good idea to check at
-+ * least *occasionally*, specially since servers will never rarely get
-+ * to reboot, since Linux is so robust these days.  :-)
-+ * 
-+ * 180 days (six months) seems like a good value.
-+ */
-+#ifdef EXT2_DFL_CHECKINTERVAL
-+#undef EXT2_DFL_CHECKINTERVAL
-+#endif
-+#define EXT2_DFL_CHECKINTERVAL (86400L * 180L)
-+
-+/*
-+ * Calculate the number of GDT blocks to reserve for online filesystem growth.
-+ * The absolute maximum number of GDT blocks we can reserve is determined by
-+ * the number of block pointers that can fit into a single block.
-+ */
-+static int calc_reserved_gdt_blocks(ext2_filsys fs)
-+{
-+      struct ext2_super_block *sb = fs->super;
-+      unsigned long bpg = sb->s_blocks_per_group;
-+      unsigned int gdpb = fs->blocksize / sizeof(struct ext2_group_desc);
-+      unsigned long max_blocks = 0xffffffff;
-+      unsigned long rsv_groups;
-+      int rsv_gdb;
-+
-+      /* We set it at 1024x the current filesystem size, or
-+       * the upper block count limit (2^32), whichever is lower.
-+       */
-+      if (sb->s_blocks_count < max_blocks / 1024)
-+              max_blocks = sb->s_blocks_count * 1024;
-+      rsv_groups = (max_blocks - sb->s_first_data_block + bpg - 1) / bpg;
-+      rsv_gdb = (rsv_groups + gdpb - 1) / gdpb - fs->desc_blocks;
-+      if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb))
-+              rsv_gdb = EXT2_ADDR_PER_BLOCK(sb);
-+#ifdef RES_GDT_DEBUG
-+      printf("max_blocks %lu, rsv_groups = %lu, rsv_gdb = %lu\n",
-+             max_blocks, rsv_groups, rsv_gdb);
-+#endif
-+
-+      return rsv_gdb;
-+}
-+
-+errcode_t ext2fs_initialize(const char *name, int flags,
-+                          struct ext2_super_block *param,
-+                          io_manager manager, ext2_filsys *ret_fs)
-+{
-+      ext2_filsys     fs;
-+      errcode_t       retval;
-+      struct ext2_super_block *super;
-+      int             frags_per_block;
-+      unsigned int    rem;
-+      unsigned int    overhead = 0;
-+      blk_t           group_block;
-+      unsigned int    ipg;
-+      dgrp_t          i;
-+      blk_t           numblocks;
-+      int             rsv_gdt;
-+      char            *buf;
-+
-+      if (!param || !param->s_blocks_count)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      
-+      retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
-+      if (retval)
-+              return retval;
-+      
-+      memset(fs, 0, sizeof(struct struct_ext2_filsys));
-+      fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
-+      fs->flags = flags | EXT2_FLAG_RW;
-+      fs->umask = 022;
-+#ifdef WORDS_BIGENDIAN
-+      fs->flags |= EXT2_FLAG_SWAP_BYTES;
-+#endif
-+      retval = manager->open(name, IO_FLAG_RW, &fs->io);
-+      if (retval)
-+              goto cleanup;
-+      fs->image_io = fs->io;
-+      fs->io->app_data = fs;
-+      retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name);
-+      if (retval)
-+              goto cleanup;
-+
-+      strcpy(fs->device_name, name);
-+      retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &super);
-+      if (retval)
-+              goto cleanup;
-+      fs->super = super;
-+
-+      memset(super, 0, SUPERBLOCK_SIZE);
-+
-+#define set_field(field, default) (super->field = param->field ? \
-+                                 param->field : (default))
-+
-+      super->s_magic = EXT2_SUPER_MAGIC;
-+      super->s_state = EXT2_VALID_FS;
-+
-+      set_field(s_log_block_size, 0); /* default blocksize: 1024 bytes */
-+      set_field(s_log_frag_size, 0); /* default fragsize: 1024 bytes */
-+      set_field(s_first_data_block, super->s_log_block_size ? 0 : 1);
-+      set_field(s_max_mnt_count, EXT2_DFL_MAX_MNT_COUNT);
-+      set_field(s_errors, EXT2_ERRORS_DEFAULT);
-+      set_field(s_feature_compat, 0);
-+      set_field(s_feature_incompat, 0);
-+      set_field(s_feature_ro_compat, 0);
-+      set_field(s_first_meta_bg, 0);
-+      if (super->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
-+              retval = EXT2_ET_UNSUPP_FEATURE;
-+              goto cleanup;
-+      }
-+      if (super->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) {
-+              retval = EXT2_ET_RO_UNSUPP_FEATURE;
-+              goto cleanup;
-+      }
-+
-+      set_field(s_rev_level, EXT2_GOOD_OLD_REV);
-+      if (super->s_rev_level >= EXT2_DYNAMIC_REV) {
-+              set_field(s_first_ino, EXT2_GOOD_OLD_FIRST_INO);
-+              set_field(s_inode_size, EXT2_GOOD_OLD_INODE_SIZE);
-+      }
-+
-+      set_field(s_checkinterval, EXT2_DFL_CHECKINTERVAL);
-+      super->s_mkfs_time = super->s_lastcheck = time(NULL);
-+
-+      super->s_creator_os = CREATOR_OS;
-+
-+      fs->blocksize = EXT2_BLOCK_SIZE(super);
-+      fs->fragsize = EXT2_FRAG_SIZE(super);
-+      frags_per_block = fs->blocksize / fs->fragsize;
-+
-+      /* default: (fs->blocksize*8) blocks/group, up to 2^16 (GDT limit) */
-+      set_field(s_blocks_per_group, fs->blocksize * 8);
-+      if (super->s_blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(super))
-+              super->s_blocks_per_group = EXT2_MAX_BLOCKS_PER_GROUP(super);
-+      super->s_frags_per_group = super->s_blocks_per_group * frags_per_block;
-+      
-+      super->s_blocks_count = param->s_blocks_count;
-+      super->s_r_blocks_count = param->s_r_blocks_count;
-+      if (super->s_r_blocks_count >= param->s_blocks_count) {
-+              retval = EXT2_ET_INVALID_ARGUMENT;
-+              goto cleanup;
-+      }
-+
-+      /*
-+       * If we're creating an external journal device, we don't need
-+       * to bother with the rest.
-+       */
-+      if (super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
-+              fs->group_desc_count = 0;
-+              ext2fs_mark_super_dirty(fs);
-+              *ret_fs = fs;
-+              return 0;
-+      }
-+
-+retry:
-+      fs->group_desc_count = (super->s_blocks_count -
-+                              super->s_first_data_block +
-+                              EXT2_BLOCKS_PER_GROUP(super) - 1)
-+              / EXT2_BLOCKS_PER_GROUP(super);
-+      if (fs->group_desc_count == 0) {
-+              retval = EXT2_ET_TOOSMALL;
-+              goto cleanup;
-+      }
-+      fs->desc_blocks = (fs->group_desc_count +
-+                         EXT2_DESC_PER_BLOCK(super) - 1)
-+              / EXT2_DESC_PER_BLOCK(super);
-+
-+      i = fs->blocksize >= 4096 ? 1 : 4096 / fs->blocksize;
-+      set_field(s_inodes_count, super->s_blocks_count / i);
-+
-+      /*
-+       * Make sure we have at least EXT2_FIRST_INO + 1 inodes, so
-+       * that we have enough inodes for the filesystem(!)
-+       */
-+      if (super->s_inodes_count < EXT2_FIRST_INODE(super)+1)
-+              super->s_inodes_count = EXT2_FIRST_INODE(super)+1;
-+      
-+      /*
-+       * There should be at least as many inodes as the user
-+       * requested.  Figure out how many inodes per group that
-+       * should be.  But make sure that we don't allocate more than
-+       * one bitmap's worth of inodes each group.
-+       */
-+      ipg = (super->s_inodes_count + fs->group_desc_count - 1) /
-+              fs->group_desc_count;
-+      if (ipg > fs->blocksize * 8) {
-+              if (super->s_blocks_per_group >= 256) {
-+                      /* Try again with slightly different parameters */
-+                      super->s_blocks_per_group -= 8;
-+                      super->s_blocks_count = param->s_blocks_count;
-+                      super->s_frags_per_group = super->s_blocks_per_group *
-+                              frags_per_block;
-+                      goto retry;
-+              } else
-+                      return EXT2_ET_TOO_MANY_INODES;
-+      }
-+
-+      if (ipg > (unsigned) EXT2_MAX_INODES_PER_GROUP(super))
-+              ipg = EXT2_MAX_INODES_PER_GROUP(super);
-+
-+      super->s_inodes_per_group = ipg;
-+      if (super->s_inodes_count > ipg * fs->group_desc_count)
-+              super->s_inodes_count = ipg * fs->group_desc_count;
-+
-+      /*
-+       * Make sure the number of inodes per group completely fills
-+       * the inode table blocks in the descriptor.  If not, add some
-+       * additional inodes/group.  Waste not, want not...
-+       */
-+      fs->inode_blocks_per_group = (((super->s_inodes_per_group *
-+                                      EXT2_INODE_SIZE(super)) +
-+                                     EXT2_BLOCK_SIZE(super) - 1) /
-+                                    EXT2_BLOCK_SIZE(super));
-+      super->s_inodes_per_group = ((fs->inode_blocks_per_group *
-+                                    EXT2_BLOCK_SIZE(super)) /
-+                                   EXT2_INODE_SIZE(super));
-+      /*
-+       * Finally, make sure the number of inodes per group is a
-+       * multiple of 8.  This is needed to simplify the bitmap
-+       * splicing code.
-+       */
-+      super->s_inodes_per_group &= ~7;
-+      fs->inode_blocks_per_group = (((super->s_inodes_per_group *
-+                                      EXT2_INODE_SIZE(super)) +
-+                                     EXT2_BLOCK_SIZE(super) - 1) /
-+                                    EXT2_BLOCK_SIZE(super));
-+
-+      /*
-+       * adjust inode count to reflect the adjusted inodes_per_group
-+       */
-+      super->s_inodes_count = super->s_inodes_per_group *
-+              fs->group_desc_count;
-+      super->s_free_inodes_count = super->s_inodes_count;
-+
-+      /*
-+       * check the number of reserved group descriptor table blocks
-+       */
-+      if (super->s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INODE)
-+              rsv_gdt = calc_reserved_gdt_blocks(fs);
-+      else
-+              rsv_gdt = 0;
-+      set_field(s_reserved_gdt_blocks, rsv_gdt);
-+      if (super->s_reserved_gdt_blocks > EXT2_ADDR_PER_BLOCK(super)) {
-+              retval = EXT2_ET_RES_GDT_BLOCKS;
-+              goto cleanup;
-+      }
-+
-+      /*
-+       * Overhead is the number of bookkeeping blocks per group.  It
-+       * includes the superblock backup, the group descriptor
-+       * backups, the inode bitmap, the block bitmap, and the inode
-+       * table.
-+       */
-+
-+      overhead = (int) (2 + fs->inode_blocks_per_group);
-+
-+      if (ext2fs_bg_has_super(fs, fs->group_desc_count - 1))
-+              overhead += 1 + fs->desc_blocks + super->s_reserved_gdt_blocks;
-+
-+      /* This can only happen if the user requested too many inodes */
-+      if (overhead > super->s_blocks_per_group)
-+              return EXT2_ET_TOO_MANY_INODES;
-+
-+      /*
-+       * See if the last group is big enough to support the
-+       * necessary data structures.  If not, we need to get rid of
-+       * it.
-+       */
-+      rem = ((super->s_blocks_count - super->s_first_data_block) %
-+             super->s_blocks_per_group);
-+      if ((fs->group_desc_count == 1) && rem && (rem < overhead))
-+              return EXT2_ET_TOOSMALL;
-+      if (rem && (rem < overhead+50)) {
-+              super->s_blocks_count -= rem;
-+              goto retry;
-+      }
-+
-+      /*
-+       * At this point we know how big the filesystem will be.  So
-+       * we can do any and all allocations that depend on the block
-+       * count.
-+       */
-+
-+      retval = ext2fs_get_mem(strlen(fs->device_name) + 80, &buf);
-+      if (retval)
-+              goto cleanup;
-+      
-+      sprintf(buf, "block bitmap for %s", fs->device_name);
-+      retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map);
-+      if (retval)
-+              goto cleanup;
-+      
-+      sprintf(buf, "inode bitmap for %s", fs->device_name);
-+      retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
-+      if (retval)
-+              goto cleanup;
-+
-+      ext2fs_free_mem(&buf);
-+
-+      retval = ext2fs_get_mem((size_t) fs->desc_blocks * fs->blocksize,
-+                              &fs->group_desc);
-+      if (retval)
-+              goto cleanup;
-+
-+      memset(fs->group_desc, 0, (size_t) fs->desc_blocks * fs->blocksize);
-+
-+      /*
-+       * Reserve the superblock and group descriptors for each
-+       * group, and fill in the correct group statistics for group.
-+       * Note that although the block bitmap, inode bitmap, and
-+       * inode table have not been allocated (and in fact won't be
-+       * by this routine), they are accounted for nevertheless.
-+       */
-+      group_block = super->s_first_data_block;
-+      super->s_free_blocks_count = 0;
-+      for (i = 0; i < fs->group_desc_count; i++) {
-+              numblocks = ext2fs_reserve_super_and_bgd(fs, i, fs->block_map);
-+
-+              super->s_free_blocks_count += numblocks;
-+              fs->group_desc[i].bg_free_blocks_count = numblocks;
-+              fs->group_desc[i].bg_free_inodes_count =
-+                      fs->super->s_inodes_per_group;
-+              fs->group_desc[i].bg_used_dirs_count = 0;
-+              
-+              group_block += super->s_blocks_per_group;
-+      }
-+      
-+      ext2fs_mark_super_dirty(fs);
-+      ext2fs_mark_bb_dirty(fs);
-+      ext2fs_mark_ib_dirty(fs);
-+      
-+      io_channel_set_blksize(fs->io, fs->blocksize);
-+
-+      *ret_fs = fs;
-+      return 0;
-+cleanup:
-+      ext2fs_free(fs);
-+      return retval;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/inline.c busybox/e2fsprogs/ext2fs/inline.c
---- busybox-1.00/e2fsprogs/ext2fs/inline.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/inline.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,32 @@
-+/*
-+ * inline.c --- Includes the inlined functions defined in the header
-+ *    files as standalone functions, in case the application program
-+ *    is compiled with inlining turned off.
-+ * 
-+ * Copyright (C) 1993, 1994 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#define INCLUDE_INLINE_FUNCS
-+#include "ext2fs.h"
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/inode.c busybox/e2fsprogs/ext2fs/inode.c
---- busybox-1.00/e2fsprogs/ext2fs/inode.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/inode.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,794 @@
-+/*
-+ * inode.c --- utility routines to read and write inodes
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+#include "e2image.h"
-+
-+struct ext2_struct_inode_scan {
-+      errcode_t               magic;
-+      ext2_filsys             fs;
-+      ext2_ino_t              current_inode;
-+      blk_t                   current_block;
-+      dgrp_t                  current_group;
-+      ext2_ino_t              inodes_left;
-+      blk_t                   blocks_left;
-+      dgrp_t                  groups_left;
-+      blk_t                   inode_buffer_blocks;
-+      char *                  inode_buffer;
-+      int                     inode_size;
-+      char *                  ptr;
-+      int                     bytes_left;
-+      char                    *temp_buffer;
-+      errcode_t               (*done_group)(ext2_filsys fs,
-+                                            ext2_inode_scan scan,
-+                                            dgrp_t group,
-+                                            void * priv_data);
-+      void *                  done_group_data;
-+      int                     bad_block_ptr;
-+      int                     scan_flags;
-+      int                     reserved[6];
-+};
-+
-+/*
-+ * This routine flushes the icache, if it exists.
-+ */
-+errcode_t ext2fs_flush_icache(ext2_filsys fs)
-+{
-+      int     i;
-+      
-+      if (!fs->icache)
-+              return 0;
-+
-+      for (i=0; i < fs->icache->cache_size; i++)
-+              fs->icache->cache[i].ino = 0;
-+
-+      fs->icache->buffer_blk = 0;
-+      return 0;
-+}
-+
-+static errcode_t create_icache(ext2_filsys fs)
-+{
-+      errcode_t       retval;
-+      
-+      if (fs->icache)
-+              return 0;
-+      retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache), &fs->icache);
-+      if (retval)
-+              return retval;
-+
-+      memset(fs->icache, 0, sizeof(struct ext2_inode_cache));
-+      retval = ext2fs_get_mem(fs->blocksize, &fs->icache->buffer);
-+      if (retval) {
-+              ext2fs_free_mem(&fs->icache);
-+              return retval;
-+      }
-+      fs->icache->buffer_blk = 0;
-+      fs->icache->cache_last = -1;
-+      fs->icache->cache_size = 4;
-+      fs->icache->refcount = 1;
-+      retval = ext2fs_get_mem(sizeof(struct ext2_inode_cache_ent)
-+                              * fs->icache->cache_size,
-+                              &fs->icache->cache);
-+      if (retval) {
-+              ext2fs_free_mem(&fs->icache->buffer);
-+              ext2fs_free_mem(&fs->icache);
-+              return retval;
-+      }
-+      ext2fs_flush_icache(fs);
-+      return 0;
-+}
-+
-+errcode_t ext2fs_open_inode_scan(ext2_filsys fs, int buffer_blocks,
-+                               ext2_inode_scan *ret_scan)
-+{
-+      ext2_inode_scan scan;
-+      errcode_t       retval;
-+      errcode_t (*save_get_blocks)(ext2_filsys f, ext2_ino_t ino, blk_t *blocks);
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      /*
-+       * If fs->badblocks isn't set, then set it --- since the inode
-+       * scanning functions require it.
-+       */
-+      if (fs->badblocks == 0) {
-+              /*
-+               * Temporarly save fs->get_blocks and set it to zero,
-+               * for compatibility with old e2fsck's.
-+               */
-+              save_get_blocks = fs->get_blocks;
-+              fs->get_blocks = 0;
-+              retval = ext2fs_read_bb_inode(fs, &fs->badblocks);
-+              if (retval && fs->badblocks) {
-+                      ext2fs_badblocks_list_free(fs->badblocks);
-+                      fs->badblocks = 0;
-+              }
-+              fs->get_blocks = save_get_blocks;
-+      }
-+
-+      retval = ext2fs_get_mem(sizeof(struct ext2_struct_inode_scan), &scan);
-+      if (retval)
-+              return retval;
-+      memset(scan, 0, sizeof(struct ext2_struct_inode_scan));
-+
-+      scan->magic = EXT2_ET_MAGIC_INODE_SCAN;
-+      scan->fs = fs;
-+      scan->inode_size = EXT2_INODE_SIZE(fs->super);
-+      scan->bytes_left = 0;
-+      scan->current_group = 0;
-+      scan->groups_left = fs->group_desc_count - 1;
-+      scan->inode_buffer_blocks = buffer_blocks ? buffer_blocks : 8;
-+      scan->current_block = scan->fs->
-+              group_desc[scan->current_group].bg_inode_table;
-+      scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
-+      scan->blocks_left = scan->fs->inode_blocks_per_group;
-+      retval = ext2fs_get_mem((size_t) (scan->inode_buffer_blocks * 
-+                                        fs->blocksize),
-+                              &scan->inode_buffer);
-+      scan->done_group = 0;
-+      scan->done_group_data = 0;
-+      scan->bad_block_ptr = 0;
-+      if (retval) {
-+              ext2fs_free_mem(&scan);
-+              return retval;
-+      }
-+      retval = ext2fs_get_mem(scan->inode_size, &scan->temp_buffer);
-+      if (retval) {
-+              ext2fs_free_mem(&scan->inode_buffer);
-+              ext2fs_free_mem(&scan);
-+              return retval;
-+      }
-+      if (scan->fs->badblocks && scan->fs->badblocks->num)
-+              scan->scan_flags |= EXT2_SF_CHK_BADBLOCKS;
-+      *ret_scan = scan;
-+      return 0;
-+}
-+
-+void ext2fs_close_inode_scan(ext2_inode_scan scan)
-+{
-+      if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
-+              return;
-+      
-+      ext2fs_free_mem(&scan->inode_buffer);
-+      scan->inode_buffer = NULL;
-+      ext2fs_free_mem(&scan->temp_buffer);
-+      scan->temp_buffer = NULL;
-+      ext2fs_free_mem(&scan);
-+      return;
-+}
-+
-+void ext2fs_set_inode_callback(ext2_inode_scan scan,
-+                             errcode_t (*done_group)(ext2_filsys fs,
-+                                                     ext2_inode_scan scan,
-+                                                     dgrp_t group,
-+                                                     void * priv_data),
-+                             void *done_group_data)
-+{
-+      if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
-+              return;
-+      
-+      scan->done_group = done_group;
-+      scan->done_group_data = done_group_data;
-+}
-+
-+int ext2fs_inode_scan_flags(ext2_inode_scan scan, int set_flags,
-+                          int clear_flags)
-+{
-+      int     old_flags;
-+
-+      if (!scan || (scan->magic != EXT2_ET_MAGIC_INODE_SCAN))
-+              return 0;
-+
-+      old_flags = scan->scan_flags;
-+      scan->scan_flags &= ~clear_flags;
-+      scan->scan_flags |= set_flags;
-+      return old_flags;
-+}
-+
-+/*
-+ * This function is called by ext2fs_get_next_inode when it needs to
-+ * get ready to read in a new blockgroup.
-+ */
-+static errcode_t get_next_blockgroup(ext2_inode_scan scan)
-+{
-+      scan->current_group++;
-+      scan->groups_left--;
-+                      
-+      scan->current_block = scan->fs->
-+              group_desc[scan->current_group].bg_inode_table;
-+
-+      scan->current_inode = scan->current_group *
-+              EXT2_INODES_PER_GROUP(scan->fs->super);
-+
-+      scan->bytes_left = 0;
-+      scan->inodes_left = EXT2_INODES_PER_GROUP(scan->fs->super);
-+      scan->blocks_left = scan->fs->inode_blocks_per_group;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_inode_scan_goto_blockgroup(ext2_inode_scan scan,
-+                                          int group)
-+{
-+      scan->current_group = group - 1;
-+      scan->groups_left = scan->fs->group_desc_count - group;
-+      return get_next_blockgroup(scan);
-+}
-+
-+/*
-+ * This function is called by get_next_blocks() to check for bad
-+ * blocks in the inode table.
-+ *
-+ * This function assumes that badblocks_list->list is sorted in
-+ * increasing order.
-+ */
-+static errcode_t check_for_inode_bad_blocks(ext2_inode_scan scan,
-+                                          blk_t *num_blocks)
-+{
-+      blk_t   blk = scan->current_block;
-+      badblocks_list  bb = scan->fs->badblocks;
-+
-+      /*
-+       * If the inode table is missing, then obviously there are no
-+       * bad blocks.  :-)
-+       */
-+      if (blk == 0)
-+              return 0;
-+
-+      /*
-+       * If the current block is greater than the bad block listed
-+       * in the bad block list, then advance the pointer until this
-+       * is no longer the case.  If we run out of bad blocks, then
-+       * we don't need to do any more checking!
-+       */
-+      while (blk > bb->list[scan->bad_block_ptr]) {
-+              if (++scan->bad_block_ptr >= bb->num) {
-+                      scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
-+                      return 0;
-+              }
-+      }
-+
-+      /*
-+       * If the current block is equal to the bad block listed in
-+       * the bad block list, then handle that one block specially.
-+       * (We could try to handle runs of bad blocks, but that
-+       * only increases CPU efficiency by a small amount, at the
-+       * expense of a huge expense of code complexity, and for an
-+       * uncommon case at that.)
-+       */
-+      if (blk == bb->list[scan->bad_block_ptr]) {
-+              scan->scan_flags |= EXT2_SF_BAD_INODE_BLK;
-+              *num_blocks = 1;
-+              if (++scan->bad_block_ptr >= bb->num)
-+                      scan->scan_flags &= ~EXT2_SF_CHK_BADBLOCKS;
-+              return 0;
-+      }
-+
-+      /*
-+       * If there is a bad block in the range that we're about to
-+       * read in, adjust the number of blocks to read so that we we
-+       * don't read in the bad block.  (Then the next block to read
-+       * will be the bad block, which is handled in the above case.)
-+       */
-+      if ((blk + *num_blocks) > bb->list[scan->bad_block_ptr])
-+              *num_blocks = (int) (bb->list[scan->bad_block_ptr] - blk);
-+
-+      return 0;
-+}
-+
-+/*
-+ * This function is called by ext2fs_get_next_inode when it needs to
-+ * read in more blocks from the current blockgroup's inode table.
-+ */
-+static errcode_t get_next_blocks(ext2_inode_scan scan)
-+{
-+      blk_t           num_blocks;
-+      errcode_t       retval;
-+
-+      /*
-+       * Figure out how many blocks to read; we read at most
-+       * inode_buffer_blocks, and perhaps less if there aren't that
-+       * many blocks left to read.
-+       */
-+      num_blocks = scan->inode_buffer_blocks;
-+      if (num_blocks > scan->blocks_left)
-+              num_blocks = scan->blocks_left;
-+
-+      /*
-+       * If the past block "read" was a bad block, then mark the
-+       * left-over extra bytes as also being bad.
-+       */
-+      if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK) {
-+              if (scan->bytes_left)
-+                      scan->scan_flags |= EXT2_SF_BAD_EXTRA_BYTES;
-+              scan->scan_flags &= ~EXT2_SF_BAD_INODE_BLK;
-+      }
-+
-+      /*
-+       * Do inode bad block processing, if necessary.
-+       */
-+      if (scan->scan_flags & EXT2_SF_CHK_BADBLOCKS) {
-+              retval = check_for_inode_bad_blocks(scan, &num_blocks);
-+              if (retval)
-+                      return retval;
-+      }
-+              
-+      if ((scan->scan_flags & EXT2_SF_BAD_INODE_BLK) ||
-+          (scan->current_block == 0)) {
-+              memset(scan->inode_buffer, 0,
-+                     (size_t) num_blocks * scan->fs->blocksize);
-+      } else {
-+              retval = io_channel_read_blk(scan->fs->io,
-+                                           scan->current_block,
-+                                           (int) num_blocks,
-+                                           scan->inode_buffer);
-+              if (retval)
-+                      return EXT2_ET_NEXT_INODE_READ;
-+      }
-+      scan->ptr = scan->inode_buffer;
-+      scan->bytes_left = num_blocks * scan->fs->blocksize;
-+
-+      scan->blocks_left -= num_blocks;
-+      if (scan->current_block)
-+              scan->current_block += num_blocks;
-+      return 0;
-+}
-+
-+#if 0
-+/*
-+ * Returns 1 if the entire inode_buffer has a non-zero size and
-+ * contains all zeros.  (Not just deleted inodes, since that means
-+ * that part of the inode table was used at one point; we want all
-+ * zeros, which means that the inode table is pristine.)
-+ */
-+static inline int is_empty_scan(ext2_inode_scan scan)
-+{
-+      int     i;
-+      
-+      if (scan->bytes_left == 0)
-+              return 0;
-+
-+      for (i=0; i < scan->bytes_left; i++)
-+              if (scan->ptr[i])
-+                      return 0;
-+      return 1;
-+}
-+#endif
-+
-+errcode_t ext2fs_get_next_inode_full(ext2_inode_scan scan, ext2_ino_t *ino,
-+                                   struct ext2_inode *inode, int bufsize)
-+{
-+      errcode_t       retval;
-+      int             extra_bytes = 0;
-+      
-+      EXT2_CHECK_MAGIC(scan, EXT2_ET_MAGIC_INODE_SCAN);
-+
-+      /*
-+       * Do we need to start reading a new block group?
-+       */
-+      if (scan->inodes_left <= 0) {
-+      force_new_group:
-+              if (scan->done_group) {
-+                      retval = (scan->done_group)
-+                              (scan->fs, scan, scan->current_group,
-+                               scan->done_group_data);
-+                      if (retval)
-+                              return retval;
-+              }
-+              if (scan->groups_left <= 0) {
-+                      *ino = 0;
-+                      return 0;
-+              }
-+              retval = get_next_blockgroup(scan);
-+              if (retval)
-+                      return retval;
-+      }
-+      /*
-+       * This is done outside the above if statement so that the
-+       * check can be done for block group #0.
-+       */
-+      if (scan->current_block == 0) {
-+              if (scan->scan_flags & EXT2_SF_SKIP_MISSING_ITABLE) {
-+                      goto force_new_group;
-+              } else
-+                      return EXT2_ET_MISSING_INODE_TABLE;
-+      }
-+      
-+
-+      /*
-+       * Have we run out of space in the inode buffer?  If so, we
-+       * need to read in more blocks.
-+       */
-+      if (scan->bytes_left < scan->inode_size) {
-+              memcpy(scan->temp_buffer, scan->ptr, scan->bytes_left);
-+              extra_bytes = scan->bytes_left;
-+
-+              retval = get_next_blocks(scan);
-+              if (retval)
-+                      return retval;
-+#if 0
-+              /*
-+               * XXX test  Need check for used inode somehow.
-+               * (Note: this is hard.)
-+               */
-+              if (is_empty_scan(scan))
-+                      goto force_new_group;
-+#endif
-+      }
-+
-+      retval = 0;
-+      if (extra_bytes) {
-+              memcpy(scan->temp_buffer+extra_bytes, scan->ptr,
-+                     scan->inode_size - extra_bytes);
-+              scan->ptr += scan->inode_size - extra_bytes;
-+              scan->bytes_left -= scan->inode_size - extra_bytes;
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+              if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+                  (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
-+                      ext2fs_swap_inode_full(scan->fs, 
-+                              (struct ext2_inode_large *) inode,
-+                              (struct ext2_inode_large *) scan->temp_buffer, 
-+                              0, bufsize);
-+              else
-+#endif
-+                      *inode = *((struct ext2_inode *) scan->temp_buffer);
-+              if (scan->scan_flags & EXT2_SF_BAD_EXTRA_BYTES)
-+                      retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
-+              scan->scan_flags &= ~EXT2_SF_BAD_EXTRA_BYTES;
-+      } else {
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+              if ((scan->fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+                  (scan->fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
-+                      ext2fs_swap_inode_full(scan->fs, 
-+                              (struct ext2_inode_large *) inode,
-+                              (struct ext2_inode_large *) scan->ptr,
-+                              0, bufsize);
-+              else
-+#endif
-+                      memcpy(inode, scan->ptr, bufsize);
-+              scan->ptr += scan->inode_size;
-+              scan->bytes_left -= scan->inode_size;
-+              if (scan->scan_flags & EXT2_SF_BAD_INODE_BLK)
-+                      retval = EXT2_ET_BAD_BLOCK_IN_INODE_TABLE;
-+      }
-+
-+      scan->inodes_left--;
-+      scan->current_inode++;
-+      *ino = scan->current_inode;
-+      return retval;
-+}
-+
-+errcode_t ext2fs_get_next_inode(ext2_inode_scan scan, ext2_ino_t *ino,
-+                              struct ext2_inode *inode)
-+{
-+      return ext2fs_get_next_inode_full(scan, ino, inode,
-+                                              sizeof(struct ext2_inode));
-+}
-+
-+/*
-+ * Functions to read and write a single inode.
-+ */
-+errcode_t ext2fs_read_inode_full(ext2_filsys fs, ext2_ino_t ino,
-+                               struct ext2_inode * inode, int bufsize)
-+{
-+      unsigned long   group, block, block_nr, offset;
-+      char            *ptr;
-+      errcode_t       retval;
-+      int             clen, i, inodes_per_block, length;
-+      io_channel      io;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      /* Check to see if user has an override function */
-+      if (fs->read_inode) {
-+              retval = (fs->read_inode)(fs, ino, inode);
-+              if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
-+                      return retval;
-+      }
-+      /* Create inode cache if not present */
-+      if (!fs->icache) {
-+              retval = create_icache(fs);
-+              if (retval)
-+                      return retval;
-+      }
-+      /* Check to see if it's in the inode cache */
-+      if (bufsize == sizeof(struct ext2_inode)) {
-+              /* only old good inode can be retrieve from the cache */
-+              for (i=0; i < fs->icache->cache_size; i++) {
-+                      if (fs->icache->cache[i].ino == ino) {
-+                              *inode = fs->icache->cache[i].inode;
-+                              return 0;
-+                      }
-+              }
-+      }
-+      if ((ino == 0) || (ino > fs->super->s_inodes_count))
-+              return EXT2_ET_BAD_INODE_NUM;
-+      if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
-+              inodes_per_block = fs->blocksize / EXT2_INODE_SIZE(fs->super);
-+              block_nr = fs->image_header->offset_inode / fs->blocksize;
-+              block_nr += (ino - 1) / inodes_per_block;
-+              offset = ((ino - 1) % inodes_per_block) *
-+                      EXT2_INODE_SIZE(fs->super);
-+              io = fs->image_io;
-+      } else {
-+              group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
-+              offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
-+                      EXT2_INODE_SIZE(fs->super);
-+              block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
-+              if (!fs->group_desc[(unsigned)group].bg_inode_table)
-+                      return EXT2_ET_MISSING_INODE_TABLE;
-+              block_nr = fs->group_desc[(unsigned)group].bg_inode_table + 
-+                      block;
-+              io = fs->io;
-+      }
-+      offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
-+
-+      length = EXT2_INODE_SIZE(fs->super);
-+      if (bufsize < length)
-+              length = bufsize;
-+
-+      ptr = (char *) inode;
-+      while (length) {
-+              clen = length;
-+              if ((offset + length) > fs->blocksize)
-+                      clen = fs->blocksize - offset;
-+
-+              if (block_nr != fs->icache->buffer_blk) {
-+                      retval = io_channel_read_blk(io, block_nr, 1,
-+                                                   fs->icache->buffer);
-+                      if (retval)
-+                              return retval;
-+                      fs->icache->buffer_blk = block_nr;
-+              }
-+
-+              memcpy(ptr, ((char *) fs->icache->buffer) + (unsigned) offset,
-+                     clen);
-+
-+              offset = 0;
-+              length -= clen;
-+              ptr += clen;
-+              block_nr++;
-+      }
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+          (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))
-+              ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) inode, 
-+                                     (struct ext2_inode_large *) inode, 
-+                                     0, length);
-+#endif
-+
-+      /* Update the inode cache */
-+      fs->icache->cache_last = (fs->icache->cache_last + 1) %
-+              fs->icache->cache_size;
-+      fs->icache->cache[fs->icache->cache_last].ino = ino;
-+      fs->icache->cache[fs->icache->cache_last].inode = *inode;
-+      
-+      return 0;
-+}
-+
-+errcode_t ext2fs_read_inode(ext2_filsys fs, ext2_ino_t ino,
-+                          struct ext2_inode * inode)
-+{
-+      return ext2fs_read_inode_full(fs, ino, inode,
-+                                      sizeof(struct ext2_inode));
-+}
-+
-+errcode_t ext2fs_write_inode_full(ext2_filsys fs, ext2_ino_t ino,
-+                                struct ext2_inode * inode, int bufsize)
-+{
-+      unsigned long group, block, block_nr, offset;
-+      errcode_t retval = 0;
-+      struct ext2_inode_large temp_inode, *w_inode;
-+      char *ptr;
-+      int clen, i, length;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      /* Check to see if user provided an override function */
-+      if (fs->write_inode) {
-+              retval = (fs->write_inode)(fs, ino, inode);
-+              if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
-+                      return retval;
-+      }
-+
-+      /* Check to see if the inode cache needs to be updated */
-+      if (fs->icache) {
-+              for (i=0; i < fs->icache->cache_size; i++) {
-+                      if (fs->icache->cache[i].ino == ino) {
-+                              fs->icache->cache[i].inode = *inode;
-+                              break;
-+                      }
-+              }
-+      } else {
-+              retval = create_icache(fs);
-+              if (retval)
-+                      return retval;
-+      }
-+              
-+      if (!(fs->flags & EXT2_FLAG_RW))
-+              return EXT2_ET_RO_FILSYS;
-+
-+      if ((ino == 0) || (ino > fs->super->s_inodes_count))
-+              return EXT2_ET_BAD_INODE_NUM;
-+
-+      length = bufsize;
-+      if (length < EXT2_INODE_SIZE(fs->super))
-+              length = EXT2_INODE_SIZE(fs->super);
-+
-+      if (length > (int) sizeof(struct ext2_inode_large)) {
-+              w_inode = malloc(length);
-+              if (!w_inode)
-+                      return ENOMEM;
-+      } else
-+              w_inode = &temp_inode;
-+      memset(w_inode, 0, length);
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if ((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+          (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))
-+              ext2fs_swap_inode_full(fs, w_inode, 
-+                                     (struct ext2_inode_large *) inode, 
-+                                     1, bufsize);
-+      else
-+#endif
-+              memcpy(w_inode, inode, bufsize);
-+      
-+      group = (ino - 1) / EXT2_INODES_PER_GROUP(fs->super);
-+      offset = ((ino - 1) % EXT2_INODES_PER_GROUP(fs->super)) *
-+              EXT2_INODE_SIZE(fs->super);
-+      block = offset >> EXT2_BLOCK_SIZE_BITS(fs->super);
-+      if (!fs->group_desc[(unsigned) group].bg_inode_table)
-+              return EXT2_ET_MISSING_INODE_TABLE;
-+      block_nr = fs->group_desc[(unsigned) group].bg_inode_table + block;
-+
-+      offset &= (EXT2_BLOCK_SIZE(fs->super) - 1);
-+
-+      length = EXT2_INODE_SIZE(fs->super);
-+      if (length > bufsize)
-+              length = bufsize;
-+
-+      ptr = (char *) w_inode;
-+
-+      while (length) {
-+              clen = length;
-+              if ((offset + length) > fs->blocksize)
-+                      clen = fs->blocksize - offset;
-+
-+              if (fs->icache->buffer_blk != block_nr) {
-+                      retval = io_channel_read_blk(fs->io, block_nr, 1,
-+                                                   fs->icache->buffer);
-+                      if (retval)
-+                              goto errout;
-+                      fs->icache->buffer_blk = block_nr;
-+              }
-+
-+      
-+              memcpy((char *) fs->icache->buffer + (unsigned) offset, 
-+                     ptr, clen);
-+
-+              retval = io_channel_write_blk(fs->io, block_nr, 1, 
-+                                            fs->icache->buffer);
-+              if (retval)
-+                      goto errout;
-+
-+              offset = 0;
-+              ptr += clen;
-+              length -= clen;
-+              block_nr++;
-+      }
-+              
-+      fs->flags |= EXT2_FLAG_CHANGED;
-+errout:
-+      if (w_inode && w_inode != &temp_inode)
-+              free(w_inode);
-+      return retval;
-+}
-+
-+errcode_t ext2fs_write_inode(ext2_filsys fs, ext2_ino_t ino,
-+                           struct ext2_inode *inode)
-+{
-+      return ext2fs_write_inode_full(fs, ino, inode,
-+                                     sizeof(struct ext2_inode));
-+}
-+
-+/* 
-+ * This function should be called when writing a new inode.  It makes
-+ * sure that extra part of large inodes is initialized properly.
-+ */
-+errcode_t ext2fs_write_new_inode(ext2_filsys fs, ext2_ino_t ino,
-+                               struct ext2_inode *inode)
-+{
-+      struct ext2_inode       *buf;
-+      int                     size = EXT2_INODE_SIZE(fs->super);
-+      struct ext2_inode_large *large_inode;
-+
-+      if (size == sizeof(struct ext2_inode))
-+              return ext2fs_write_inode_full(fs, ino, inode,
-+                                             sizeof(struct ext2_inode));
-+
-+      buf = malloc(size);
-+      if (!buf)
-+              return ENOMEM;
-+
-+      memset(buf, 0, size);
-+      *buf = *inode;
-+
-+      large_inode = (struct ext2_inode_large *) buf;
-+      large_inode->i_extra_isize = sizeof(struct ext2_inode_large) - 
-+              EXT2_GOOD_OLD_INODE_SIZE;
-+
-+      return ext2fs_write_inode_full(fs, ino, buf, size);
-+}
-+
-+ 
-+errcode_t ext2fs_get_blocks(ext2_filsys fs, ext2_ino_t ino, blk_t *blocks)
-+{
-+      struct ext2_inode       inode;
-+      int                     i;
-+      errcode_t               retval;
-+      
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (ino > fs->super->s_inodes_count)
-+              return EXT2_ET_BAD_INODE_NUM;
-+
-+      if (fs->get_blocks) {
-+              if (!(*fs->get_blocks)(fs, ino, blocks))
-+                      return 0;
-+      }
-+      retval = ext2fs_read_inode(fs, ino, &inode);
-+      if (retval)
-+              return retval;
-+      for (i=0; i < EXT2_N_BLOCKS; i++)
-+              blocks[i] = inode.i_block[i];
-+      return 0;
-+}
-+
-+errcode_t ext2fs_check_directory(ext2_filsys fs, ext2_ino_t ino)
-+{
-+      struct  ext2_inode      inode;
-+      errcode_t               retval;
-+      
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (ino > fs->super->s_inodes_count)
-+              return EXT2_ET_BAD_INODE_NUM;
-+
-+      if (fs->check_directory) {
-+              retval = (fs->check_directory)(fs, ino);
-+              if (retval != EXT2_ET_CALLBACK_NOTHANDLED)
-+                      return retval;
-+      }
-+      retval = ext2fs_read_inode(fs, ino, &inode);
-+      if (retval)
-+              return retval;
-+      if (!LINUX_S_ISDIR(inode.i_mode))
-+              return EXT2_ET_NO_DIRECTORY;
-+      return 0;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/inode_io.c busybox/e2fsprogs/ext2fs/inode_io.c
---- busybox-1.00/e2fsprogs/ext2fs/inode_io.c   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/inode_io.c        2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,270 @@
-+/*
-+ * inode_io.c --- This is allows an inode in an ext2 filesystem image
-+ *    to be accessed via the I/O manager interface.
-+ *
-+ * Copyright (C) 2002 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * For checking structure magic numbers...
-+ */
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+        if ((struct)->magic != (code)) return (code)
-+
-+struct inode_private_data {
-+      int                             magic;
-+      char                            name[32];
-+      ext2_file_t                     file;
-+      ext2_filsys                     fs;
-+      ext2_ino_t                      ino;
-+      struct ext2_inode               inode;
-+      int                             flags;
-+      struct inode_private_data       *next;
-+};
-+
-+#define CHANNEL_HAS_INODE     0x8000
-+
-+static struct inode_private_data *top_intern;
-+static int ino_unique = 0;
-+
-+static errcode_t inode_open(const char *name, int flags, io_channel *channel);
-+static errcode_t inode_close(io_channel channel);
-+static errcode_t inode_set_blksize(io_channel channel, int blksize);
-+static errcode_t inode_read_blk(io_channel channel, unsigned long block,
-+                             int count, void *data);
-+static errcode_t inode_write_blk(io_channel channel, unsigned long block,
-+                              int count, const void *data);
-+static errcode_t inode_flush(io_channel channel);
-+static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
-+                              int size, const void *data);
-+
-+static struct struct_io_manager struct_inode_manager = {
-+      EXT2_ET_MAGIC_IO_MANAGER,
-+      "Inode I/O Manager",
-+      inode_open,
-+      inode_close,
-+      inode_set_blksize,
-+      inode_read_blk,
-+      inode_write_blk,
-+      inode_flush,
-+      inode_write_byte
-+};
-+
-+io_manager inode_io_manager = &struct_inode_manager;
-+
-+errcode_t ext2fs_inode_io_intern2(ext2_filsys fs, ext2_ino_t ino,
-+                                struct ext2_inode *inode,
-+                                char **name)
-+{
-+      struct inode_private_data       *data;
-+      errcode_t                       retval;
-+
-+      if ((retval = ext2fs_get_mem(sizeof(struct inode_private_data),
-+                                   &data)))
-+              return retval;
-+      data->magic = EXT2_ET_MAGIC_INODE_IO_CHANNEL;
-+      sprintf(data->name, "%u:%d", ino, ino_unique++);
-+      data->file = 0;
-+      data->fs = fs;
-+      data->ino = ino;
-+      data->flags = 0;
-+      if (inode) {
-+              memcpy(&data->inode, inode, sizeof(struct ext2_inode));
-+              data->flags |= CHANNEL_HAS_INODE;
-+      }
-+      data->next = top_intern;
-+      top_intern = data;
-+      *name = data->name;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_inode_io_intern(ext2_filsys fs, ext2_ino_t ino,
-+                               char **name)
-+{
-+      return ext2fs_inode_io_intern2(fs, ino, NULL, name);
-+}
-+
-+
-+static errcode_t inode_open(const char *name, int flags, io_channel *channel)
-+{
-+      io_channel      io = NULL;
-+      struct inode_private_data *prev, *data = NULL;
-+      errcode_t       retval;
-+      int             open_flags;
-+
-+      if (name == 0)
-+              return EXT2_ET_BAD_DEVICE_NAME;
-+
-+      for (data = top_intern, prev = NULL; data;
-+           prev = data, data = data->next)
-+              if (strcmp(name, data->name) == 0)
-+                      break;
-+      if (!data)
-+              return ENOENT;
-+      if (prev)
-+              prev->next = data->next;
-+      else
-+              top_intern = data->next;
-+
-+      retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
-+      if (retval)
-+              goto cleanup;
-+      memset(io, 0, sizeof(struct struct_io_channel));
-+
-+      io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
-+      io->manager = inode_io_manager;
-+      retval = ext2fs_get_mem(strlen(name)+1, &io->name);
-+      if (retval)
-+              goto cleanup;
-+
-+      strcpy(io->name, name);
-+      io->private_data = data;
-+      io->block_size = 1024;
-+      io->read_error = 0;
-+      io->write_error = 0;
-+      io->refcount = 1;
-+
-+      open_flags = (flags & IO_FLAG_RW) ? EXT2_FILE_WRITE : 0;
-+      retval = ext2fs_file_open2(data->fs, data->ino,
-+                                 (data->flags & CHANNEL_HAS_INODE) ?
-+                                 &data->inode : 0, open_flags,
-+                                 &data->file);
-+      if (retval)
-+              goto cleanup;
-+              
-+      *channel = io;
-+      return 0;
-+
-+cleanup:
-+      if (data) {
-+              ext2fs_free_mem(&data);
-+      }
-+      if (io)
-+              ext2fs_free_mem(&io);
-+      return retval;
-+}
-+
-+static errcode_t inode_close(io_channel channel)
-+{
-+      struct inode_private_data *data;
-+      errcode_t       retval = 0;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct inode_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+      if (--channel->refcount > 0)
-+              return 0;
-+
-+      retval = ext2fs_file_close(data->file);
-+      
-+      ext2fs_free_mem(&channel->private_data);
-+      if (channel->name)
-+              ext2fs_free_mem(&channel->name);
-+      ext2fs_free_mem(&channel);
-+      return retval;
-+}
-+
-+static errcode_t inode_set_blksize(io_channel channel, int blksize)
-+{
-+      struct inode_private_data *data;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct inode_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+      channel->block_size = blksize;
-+      return 0;
-+}
-+
-+
-+static errcode_t inode_read_blk(io_channel channel, unsigned long block,
-+                             int count, void *buf)
-+{
-+      struct inode_private_data *data;
-+      errcode_t       retval;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct inode_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+      if ((retval = ext2fs_file_lseek(data->file,
-+                                      block * channel->block_size,
-+                                      EXT2_SEEK_SET, 0)))
-+              return retval;
-+
-+      count = (count < 0) ? -count : (count * channel->block_size);
-+
-+      return ext2fs_file_read(data->file, buf, count, 0);
-+}
-+
-+static errcode_t inode_write_blk(io_channel channel, unsigned long block,
-+                              int count, const void *buf)
-+{
-+      struct inode_private_data *data;
-+      errcode_t       retval;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct inode_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+      if ((retval = ext2fs_file_lseek(data->file,
-+                                      block * channel->block_size,
-+                                      EXT2_SEEK_SET, 0)))
-+              return retval;
-+
-+      count = (count < 0) ? -count : (count * channel->block_size);
-+
-+      return ext2fs_file_write(data->file, buf, count, 0);
-+}
-+
-+static errcode_t inode_write_byte(io_channel channel, unsigned long offset,
-+                               int size, const void *buf)
-+{
-+      struct inode_private_data *data;
-+      errcode_t       retval = 0;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct inode_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+      if ((retval = ext2fs_file_lseek(data->file, offset,
-+                                      EXT2_SEEK_SET, 0)))
-+              return retval;
-+
-+      return ext2fs_file_write(data->file, buf, size, 0);
-+}
-+
-+/*
-+ * Flush data buffers to disk.  
-+ */
-+static errcode_t inode_flush(io_channel channel)
-+{
-+      struct inode_private_data *data;
-+      
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct inode_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_INODE_IO_CHANNEL);
-+
-+      return ext2fs_file_flush(data->file);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/io_manager.c busybox/e2fsprogs/ext2fs/io_manager.c
---- busybox-1.00/e2fsprogs/ext2fs/io_manager.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/io_manager.c      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,69 @@
-+/*
-+ * io_manager.c --- the I/O manager abstraction
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t io_channel_set_options(io_channel channel, const char *opts)
-+{
-+      errcode_t retval = 0;
-+      char *next, *ptr, *options, *arg;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+
-+      if (!opts)
-+              return 0;
-+
-+      if (!channel->manager->set_option)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      options = malloc(strlen(opts)+1);
-+      if (!options)
-+              return EXT2_ET_NO_MEMORY;
-+      strcpy(options, opts);
-+      ptr = options;
-+
-+      while (ptr && *ptr) {
-+              next = strchr(ptr, '&');
-+              if (next)
-+                      *next++ = 0;
-+
-+              arg = strchr(ptr, '=');
-+              if (arg)
-+                      *arg++ = 0;
-+
-+              retval = (channel->manager->set_option)(channel, ptr, arg);
-+              if (retval)
-+                      break;
-+              ptr = next;
-+      }
-+      free(options);
-+      return retval;
-+}
-+
-+errcode_t io_channel_write_byte(io_channel channel, unsigned long offset,
-+                              int count, const void *data)
-+{
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+
-+      if (channel->manager->write_byte) 
-+              return channel->manager->write_byte(channel, offset, 
-+                                                  count, data);
-+
-+      return EXT2_ET_UNIMPLEMENTED;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/irel.h busybox/e2fsprogs/ext2fs/irel.h
---- busybox-1.00/e2fsprogs/ext2fs/irel.h       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/irel.h    2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,114 @@
-+/*
-+ * irel.h
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+struct ext2_inode_reference {
-+      blk_t   block;
-+      __u16 offset;
-+};
-+
-+struct ext2_inode_relocate_entry {
-+      ext2_ino_t      new;
-+      ext2_ino_t      orig;
-+      __u16           flags;
-+      __u16           max_refs;
-+};
-+
-+typedef struct ext2_inode_relocation_table *ext2_irel;
-+
-+struct ext2_inode_relocation_table {
-+      __u32   magic;
-+      char    *name;
-+      ext2_ino_t      current;
-+      void    *priv_data;
-+
-+      /*
-+       * Add an inode relocation entry.
-+       */
-+      errcode_t (*put)(ext2_irel irel, ext2_ino_t old,
-+                            struct ext2_inode_relocate_entry *ent);
-+      /*
-+       * Get an inode relocation entry.
-+       */
-+      errcode_t (*get)(ext2_irel irel, ext2_ino_t old,
-+                            struct ext2_inode_relocate_entry *ent);
-+
-+      /*
-+       * Get an inode relocation entry by its original inode number
-+       */
-+      errcode_t (*get_by_orig)(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
-+                               struct ext2_inode_relocate_entry *ent);
-+
-+      /*
-+       * Initialize for iterating over the inode relocation entries.
-+       */
-+      errcode_t (*start_iter)(ext2_irel irel);
-+
-+      /*
-+       * The iterator function for the inode relocation entries.
-+       * Returns an inode number of 0 when out of entries.
-+       */
-+      errcode_t (*next)(ext2_irel irel, ext2_ino_t *old,
-+                        struct ext2_inode_relocate_entry *ent);
-+
-+      /*
-+       * Add an inode reference (i.e., note the fact that a
-+       * particular block/offset contains a reference to an inode)
-+       */
-+      errcode_t (*add_ref)(ext2_irel irel, ext2_ino_t ino,
-+                           struct ext2_inode_reference *ref);
-+
-+      /*
-+       * Initialize for iterating over the inode references for a
-+       * particular inode.
-+       */
-+      errcode_t (*start_iter_ref)(ext2_irel irel, ext2_ino_t ino);
-+
-+      /*
-+       * The iterator function for the inode references for an
-+       * inode.  The references for only one inode can be interator
-+       * over at a time, as the iterator state is stored in ext2_irel.
-+       */
-+      errcode_t (*next_ref)(ext2_irel irel,
-+                            struct ext2_inode_reference *ref);
-+
-+      /*
-+       * Move the inode relocation table from one inode number to
-+       * another.  Note that the inode references also must move.
-+       */
-+      errcode_t (*move)(ext2_irel irel, ext2_ino_t old, ext2_ino_t new);
-+
-+      /*
-+       * Remove an inode relocation entry, along with all of the
-+       * inode references.
-+       */
-+      errcode_t (*delete)(ext2_irel irel, ext2_ino_t old);
-+
-+      /*
-+       * Free the inode relocation table.
-+       */
-+      errcode_t (*free)(ext2_irel irel);
-+};
-+
-+errcode_t ext2fs_irel_memarray_create(char *name, ext2_ino_t max_inode,
-+                                  ext2_irel *irel);
-+
-+#define ext2fs_irel_put(irel, old, ent) ((irel)->put((irel), old, ent))
-+#define ext2fs_irel_get(irel, old, ent) ((irel)->get((irel), old, ent))
-+#define ext2fs_irel_get_by_orig(irel, orig, old, ent) \
-+                      ((irel)->get_by_orig((irel), orig, old, ent))
-+#define ext2fs_irel_start_iter(irel) ((irel)->start_iter((irel)))
-+#define ext2fs_irel_next(irel, old, ent) ((irel)->next((irel), old, ent))
-+#define ext2fs_irel_add_ref(irel, ino, ref) ((irel)->add_ref((irel), ino, ref))
-+#define ext2fs_irel_start_iter_ref(irel, ino) ((irel)->start_iter_ref((irel), ino))
-+#define ext2fs_irel_next_ref(irel, ref) ((irel)->next_ref((irel), ref))
-+#define ext2fs_irel_move(irel, old, new) ((irel)->move((irel), old, new))
-+#define ext2fs_irel_delete(irel, old) ((irel)->delete((irel), old))
-+#define ext2fs_irel_free(irel) ((irel)->free((irel)))
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/irel_ma.c busybox/e2fsprogs/ext2fs/irel_ma.c
---- busybox-1.00/e2fsprogs/ext2fs/irel_ma.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/irel_ma.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,372 @@
-+/*
-+ * irel_ma.c
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <fcntl.h>
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+#include "irel.h"
-+
-+static errcode_t ima_put(ext2_irel irel, ext2_ino_t old,
-+                       struct ext2_inode_relocate_entry *ent);
-+static errcode_t ima_get(ext2_irel irel, ext2_ino_t old,
-+                       struct ext2_inode_relocate_entry *ent);
-+static errcode_t ima_get_by_orig(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
-+                               struct ext2_inode_relocate_entry *ent);
-+static errcode_t ima_start_iter(ext2_irel irel);
-+static errcode_t ima_next(ext2_irel irel, ext2_ino_t *old,
-+                        struct ext2_inode_relocate_entry *ent);
-+static errcode_t ima_add_ref(ext2_irel irel, ext2_ino_t ino,
-+                           struct ext2_inode_reference *ref);
-+static errcode_t ima_start_iter_ref(ext2_irel irel, ext2_ino_t ino);
-+static errcode_t ima_next_ref(ext2_irel irel, struct ext2_inode_reference *ref);
-+static errcode_t ima_move(ext2_irel irel, ext2_ino_t old, ext2_ino_t new);
-+static errcode_t ima_delete(ext2_irel irel, ext2_ino_t old);
-+static errcode_t ima_free(ext2_irel irel);
-+
-+/*
-+ * This data structure stores the array of inode references; there is
-+ * a structure for each inode.
-+ */
-+struct inode_reference_entry {
-+      __u16 num;
-+      struct ext2_inode_reference *refs;
-+};
-+
-+struct irel_ma {
-+      __u32 magic;
-+      ext2_ino_t max_inode;
-+      ext2_ino_t ref_current;
-+      int   ref_iter;
-+      ext2_ino_t      *orig_map;
-+      struct ext2_inode_relocate_entry *entries;
-+      struct inode_reference_entry *ref_entries;
-+};
-+
-+errcode_t ext2fs_irel_memarray_create(char *name, ext2_ino_t max_inode,
-+                                    ext2_irel *new_irel)
-+{
-+      ext2_irel               irel = 0;
-+      errcode_t       retval;
-+      struct irel_ma  *ma = 0;
-+      size_t          size;
-+
-+      *new_irel = 0;
-+
-+      /*
-+       * Allocate memory structures
-+       */
-+      retval = ext2fs_get_mem(sizeof(struct ext2_inode_relocation_table),
-+                              &irel);
-+      if (retval)
-+              goto errout;
-+      memset(irel, 0, sizeof(struct ext2_inode_relocation_table));
-+      
-+      retval = ext2fs_get_mem(strlen(name)+1, &irel->name);
-+      if (retval)
-+              goto errout;
-+      strcpy(irel->name, name);
-+      
-+      retval = ext2fs_get_mem(sizeof(struct irel_ma), &ma);
-+      if (retval)
-+              goto errout;
-+      memset(ma, 0, sizeof(struct irel_ma));
-+      irel->priv_data = ma;
-+      
-+      size = (size_t) (sizeof(ext2_ino_t) * (max_inode+1));
-+      retval = ext2fs_get_mem(size, &ma->orig_map);
-+      if (retval)
-+              goto errout;
-+      memset(ma->orig_map, 0, size);
-+
-+      size = (size_t) (sizeof(struct ext2_inode_relocate_entry) *
-+                       (max_inode+1));
-+      retval = ext2fs_get_mem(size, &ma->entries);
-+      if (retval)
-+              goto errout;
-+      memset(ma->entries, 0, size);
-+
-+      size = (size_t) (sizeof(struct inode_reference_entry) *
-+                       (max_inode+1));
-+      retval = ext2fs_get_mem(size, &ma->ref_entries);
-+      if (retval)
-+              goto errout;
-+      memset(ma->ref_entries, 0, size);
-+      ma->max_inode = max_inode;
-+
-+      /*
-+       * Fill in the irel data structure
-+       */
-+      irel->put = ima_put;
-+      irel->get = ima_get;
-+      irel->get_by_orig = ima_get_by_orig;
-+      irel->start_iter = ima_start_iter;
-+      irel->next = ima_next;
-+      irel->add_ref = ima_add_ref;
-+      irel->start_iter_ref = ima_start_iter_ref;
-+      irel->next_ref = ima_next_ref;
-+      irel->move = ima_move;
-+      irel->delete = ima_delete;
-+      irel->free = ima_free;
-+      
-+      *new_irel = irel;
-+      return 0;
-+
-+errout:
-+      ima_free(irel);
-+      return retval;
-+}
-+
-+static errcode_t ima_put(ext2_irel irel, ext2_ino_t old,
-+                      struct ext2_inode_relocate_entry *ent)
-+{
-+      struct inode_reference_entry    *ref_ent;
-+      struct irel_ma                  *ma;
-+      errcode_t                       retval;
-+      size_t                          size, old_size;
-+
-+      ma = irel->priv_data;
-+      if (old > ma->max_inode)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      /*
-+       * Force the orig field to the correct value; the application
-+       * program shouldn't be messing with this field.
-+       */
-+      if (ma->entries[(unsigned) old].new == 0)
-+              ent->orig = old;
-+      else
-+              ent->orig = ma->entries[(unsigned) old].orig;
-+      
-+      /*
-+       * If max_refs has changed, reallocate the refs array
-+       */
-+      ref_ent = ma->ref_entries + (unsigned) old;
-+      if (ref_ent->refs && ent->max_refs !=
-+          ma->entries[(unsigned) old].max_refs) {
-+              size = (sizeof(struct ext2_inode_reference) * ent->max_refs);
-+              old_size = (sizeof(struct ext2_inode_reference) *
-+                          ma->entries[(unsigned) old].max_refs);
-+              retval = ext2fs_resize_mem(old_size, size, &ref_ent->refs);
-+              if (retval)
-+                      return retval;
-+      }
-+
-+      ma->entries[(unsigned) old] = *ent;
-+      ma->orig_map[(unsigned) ent->orig] = old;
-+      return 0;
-+}
-+
-+static errcode_t ima_get(ext2_irel irel, ext2_ino_t old,
-+                      struct ext2_inode_relocate_entry *ent)
-+{
-+      struct irel_ma  *ma;
-+
-+      ma = irel->priv_data;
-+      if (old > ma->max_inode)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      if (ma->entries[(unsigned) old].new == 0)
-+              return ENOENT;
-+      *ent = ma->entries[(unsigned) old];
-+      return 0;
-+}
-+
-+static errcode_t ima_get_by_orig(ext2_irel irel, ext2_ino_t orig, ext2_ino_t *old,
-+                      struct ext2_inode_relocate_entry *ent)
-+{
-+      struct irel_ma  *ma;
-+      ext2_ino_t      ino;
-+
-+      ma = irel->priv_data;
-+      if (orig > ma->max_inode)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      ino = ma->orig_map[(unsigned) orig];
-+      if (ino == 0)
-+              return ENOENT;
-+      *old = ino;
-+      *ent = ma->entries[(unsigned) ino];
-+      return 0;
-+}
-+
-+static errcode_t ima_start_iter(ext2_irel irel)
-+{
-+      irel->current = 0;
-+      return 0;
-+}
-+
-+static errcode_t ima_next(ext2_irel irel, ext2_ino_t *old,
-+                       struct ext2_inode_relocate_entry *ent)
-+{
-+      struct irel_ma  *ma;
-+
-+      ma = irel->priv_data;
-+      while (++irel->current < ma->max_inode) {
-+              if (ma->entries[(unsigned) irel->current].new == 0)
-+                      continue;
-+              *old = irel->current;
-+              *ent = ma->entries[(unsigned) irel->current];
-+              return 0;
-+      }
-+      *old = 0;
-+      return 0;
-+}
-+
-+static errcode_t ima_add_ref(ext2_irel irel, ext2_ino_t ino,
-+                           struct ext2_inode_reference *ref)
-+{
-+      struct irel_ma  *ma;
-+      size_t          size;
-+      struct inode_reference_entry *ref_ent;
-+      struct ext2_inode_relocate_entry *ent;
-+      errcode_t               retval;
-+
-+      ma = irel->priv_data;
-+      if (ino > ma->max_inode)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      ref_ent = ma->ref_entries + (unsigned) ino;
-+      ent = ma->entries + (unsigned) ino;
-+      
-+      /*
-+       * If the inode reference array doesn't exist, create it.
-+       */
-+      if (ref_ent->refs == 0) {
-+              size = (size_t) ((sizeof(struct ext2_inode_reference) * 
-+                                ent->max_refs));
-+              retval = ext2fs_get_mem(size, &ref_ent->refs);
-+              if (retval)
-+                      return retval;
-+              memset(ref_ent->refs, 0, size);
-+              ref_ent->num = 0;
-+      }
-+
-+      if (ref_ent->num >= ent->max_refs)
-+              return EXT2_ET_TOO_MANY_REFS;
-+
-+      ref_ent->refs[(unsigned) ref_ent->num++] = *ref;
-+      return 0;
-+}
-+
-+static errcode_t ima_start_iter_ref(ext2_irel irel, ext2_ino_t ino)
-+{
-+      struct irel_ma  *ma;
-+
-+      ma = irel->priv_data;
-+      if (ino > ma->max_inode)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      if (ma->entries[(unsigned) ino].new == 0)
-+              return ENOENT;
-+      ma->ref_current = ino;
-+      ma->ref_iter = 0;
-+      return 0;
-+}
-+
-+static errcode_t ima_next_ref(ext2_irel irel,
-+                            struct ext2_inode_reference *ref)
-+{
-+      struct irel_ma  *ma;
-+      struct inode_reference_entry *ref_ent;
-+
-+      ma = irel->priv_data;
-+      
-+      ref_ent = ma->ref_entries + ma->ref_current;
-+
-+      if ((ref_ent->refs == NULL) ||
-+          (ma->ref_iter >= ref_ent->num)) {
-+              ref->block = 0;
-+              ref->offset = 0;
-+              return 0;
-+      }
-+      *ref = ref_ent->refs[ma->ref_iter++];
-+      return 0;
-+}
-+
-+
-+static errcode_t ima_move(ext2_irel irel, ext2_ino_t old, ext2_ino_t new)
-+{
-+      struct irel_ma  *ma;
-+
-+      ma = irel->priv_data;
-+      if ((old > ma->max_inode) || (new > ma->max_inode))
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      if (ma->entries[(unsigned) old].new == 0)
-+              return ENOENT;
-+      
-+      ma->entries[(unsigned) new] = ma->entries[(unsigned) old];
-+      if (ma->ref_entries[(unsigned) new].refs)
-+              ext2fs_free_mem(&ma->ref_entries[(unsigned) new].refs);
-+      ma->ref_entries[(unsigned) new] = ma->ref_entries[(unsigned) old];
-+      
-+      ma->entries[(unsigned) old].new = 0;
-+      ma->ref_entries[(unsigned) old].num = 0;
-+      ma->ref_entries[(unsigned) old].refs = 0;
-+
-+      ma->orig_map[ma->entries[new].orig] = new;
-+      return 0;
-+}
-+
-+static errcode_t ima_delete(ext2_irel irel, ext2_ino_t old)
-+{
-+      struct irel_ma  *ma;
-+
-+      ma = irel->priv_data;
-+      if (old > ma->max_inode)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+      if (ma->entries[(unsigned) old].new == 0)
-+              return ENOENT;
-+      
-+      ma->entries[old].new = 0;
-+      if (ma->ref_entries[(unsigned) old].refs)
-+              ext2fs_free_mem(&ma->ref_entries[(unsigned) old].refs);
-+      ma->orig_map[ma->entries[(unsigned) old].orig] = 0;
-+      
-+      ma->ref_entries[(unsigned) old].num = 0;
-+      ma->ref_entries[(unsigned) old].refs = 0;
-+      return 0;
-+}
-+
-+static errcode_t ima_free(ext2_irel irel)
-+{
-+      struct irel_ma  *ma;
-+      ext2_ino_t      ino;
-+
-+      if (!irel)
-+              return 0;
-+
-+      ma = irel->priv_data;
-+
-+      if (ma) {
-+              if (ma->orig_map)
-+                      ext2fs_free_mem(&ma->orig_map);
-+              if (ma->entries)
-+                      ext2fs_free_mem(&ma->entries);
-+              if (ma->ref_entries) {
-+                      for (ino = 0; ino <= ma->max_inode; ino++) {
-+                              if (ma->ref_entries[(unsigned) ino].refs)
-+                                      ext2fs_free_mem(&ma->ref_entries[(unsigned) ino].refs);
-+                      }
-+                      ext2fs_free_mem(&ma->ref_entries);
-+              }
-+              ext2fs_free_mem(&ma);
-+      }
-+      if (irel->name)
-+              ext2fs_free_mem(&irel->name);
-+      ext2fs_free_mem(&irel);
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/ismounted.c busybox/e2fsprogs/ext2fs/ismounted.c
---- busybox-1.00/e2fsprogs/ext2fs/ismounted.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/ismounted.c       2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,358 @@
-+/*
-+ * ismounted.c --- Check to see if the filesystem was mounted
-+ * 
-+ * Copyright (C) 1995,1996,1997,1998,1999,2000 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#ifdef HAVE_LINUX_FD_H
-+#include <linux/fd.h>
-+#endif
-+#ifdef HAVE_MNTENT_H
-+#include <mntent.h>
-+#endif
-+#ifdef HAVE_GETMNTINFO
-+#include <paths.h>
-+#include <sys/param.h>
-+#include <sys/mount.h>
-+#endif /* HAVE_GETMNTINFO */
-+#include <string.h>
-+#include <sys/stat.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#ifdef HAVE_MNTENT_H
-+/*
-+ * Helper function which checks a file in /etc/mtab format to see if a
-+ * filesystem is mounted.  Returns an error if the file doesn't exist
-+ * or can't be opened.  
-+ */
-+static errcode_t check_mntent_file(const char *mtab_file, const char *file, 
-+                                 int *mount_flags, char *mtpt, int mtlen)
-+{
-+      struct mntent   *mnt;
-+      struct stat     st_buf;
-+      errcode_t       retval = 0;
-+      dev_t           file_dev=0, file_rdev=0;
-+      ino_t           file_ino=0;
-+      FILE            *f;
-+      int             fd;
-+
-+      *mount_flags = 0;
-+      if ((f = setmntent (mtab_file, "r")) == NULL)
-+              return errno;
-+      if (stat(file, &st_buf) == 0) {
-+              if (S_ISBLK(st_buf.st_mode)) {
-+#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
-+                      file_rdev = st_buf.st_rdev;
-+#endif        /* __GNU__ */
-+              } else {
-+                      file_dev = st_buf.st_dev;
-+                      file_ino = st_buf.st_ino;
-+              }
-+      }
-+      while ((mnt = getmntent (f)) != NULL) {
-+              if (strcmp(file, mnt->mnt_fsname) == 0)
-+                      break;
-+              if (stat(mnt->mnt_fsname, &st_buf) == 0) {
-+                      if (S_ISBLK(st_buf.st_mode)) {
-+#ifndef __GNU__
-+                              if (file_rdev && (file_rdev == st_buf.st_rdev))
-+                                      break;
-+#endif        /* __GNU__ */
-+                      } else {
-+                              if (file_dev && ((file_dev == st_buf.st_dev) &&
-+                                               (file_ino == st_buf.st_ino)))
-+                                      break;
-+                      }
-+              }
-+      }
-+
-+      if (mnt == 0) {
-+#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
-+              /*
-+               * Do an extra check to see if this is the root device.  We
-+               * can't trust /etc/mtab, and /proc/mounts will only list
-+               * /dev/root for the root filesystem.  Argh.  Instead we
-+               * check if the given device has the same major/minor number
-+               * as the device that the root directory is on.
-+               */
-+              if (file_rdev && stat("/", &st_buf) == 0) {
-+                      if (st_buf.st_dev == file_rdev) {
-+                              *mount_flags = EXT2_MF_MOUNTED;
-+                              if (mtpt)
-+                                      strncpy(mtpt, "/", mtlen);
-+                              goto is_root;
-+                      }
-+              }
-+#endif        /* __GNU__ */
-+              goto errout;
-+      }
-+#ifndef __GNU__ /* The GNU hurd is deficient; what else is new? */
-+      /* Validate the entry in case /etc/mtab is out of date */
-+      /* 
-+       * We need to be paranoid, because some broken distributions
-+       * (read: Slackware) don't initialize /etc/mtab before checking
-+       * all of the non-root filesystems on the disk.
-+       */
-+      if (stat(mnt->mnt_dir, &st_buf) < 0) {
-+              retval = errno;
-+              if (retval == ENOENT) {
-+#ifdef DEBUG
-+                      printf("Bogus entry in %s!  (%s does not exist)\n",
-+                             mtab_file, mnt->mnt_dir);
-+#endif /* DEBUG */
-+                      retval = 0;
-+              }
-+              goto errout;
-+      }
-+      if (file_rdev && (st_buf.st_dev != file_rdev)) {
-+#ifdef DEBUG
-+              printf("Bogus entry in %s!  (%s not mounted on %s)\n",
-+                     mtab_file, file, mnt->mnt_dir);
-+#endif /* DEBUG */
-+              goto errout;
-+      }
-+#endif /* __GNU__ */
-+      *mount_flags = EXT2_MF_MOUNTED;
-+      
-+#ifdef MNTOPT_RO
-+      /* Check to see if the ro option is set */
-+      if (hasmntopt(mnt, MNTOPT_RO))
-+              *mount_flags |= EXT2_MF_READONLY;
-+#endif
-+
-+      if (mtpt)
-+              strncpy(mtpt, mnt->mnt_dir, mtlen);
-+      /*
-+       * Check to see if we're referring to the root filesystem.
-+       * If so, do a manual check to see if we can open /etc/mtab
-+       * read/write, since if the root is mounted read/only, the
-+       * contents of /etc/mtab may not be accurate.
-+       */
-+      if (!strcmp(mnt->mnt_dir, "/")) {
-+is_root:
-+#define TEST_FILE "/.ismount-test-file"               
-+              *mount_flags |= EXT2_MF_ISROOT;
-+              fd = open(TEST_FILE, O_RDWR|O_CREAT);
-+              if (fd < 0) {
-+                      if (errno == EROFS)
-+                              *mount_flags |= EXT2_MF_READONLY;
-+              } else
-+                      close(fd);
-+              (void) unlink(TEST_FILE);
-+      }
-+      retval = 0;
-+errout:
-+      endmntent (f);
-+      return retval;
-+}
-+
-+static errcode_t check_mntent(const char *file, int *mount_flags,
-+                            char *mtpt, int mtlen)
-+{
-+      errcode_t       retval;
-+
-+#ifdef DEBUG
-+      retval = check_mntent_file("/tmp/mtab", file, mount_flags,
-+                                 mtpt, mtlen);
-+      if (retval == 0)
-+              return 0;
-+#endif /* DEBUG */
-+#ifdef __linux__
-+      retval = check_mntent_file("/proc/mounts", file, mount_flags,
-+                                 mtpt, mtlen);
-+      if (retval == 0 && (*mount_flags != 0))
-+              return 0;
-+#endif /* __linux__ */
-+#if defined(MOUNTED) || defined(_PATH_MOUNTED)
-+#ifndef MOUNTED
-+#define MOUNTED _PATH_MOUNTED
-+#endif /* MOUNTED */
-+      retval = check_mntent_file(MOUNTED, file, mount_flags, mtpt, mtlen);
-+      return retval;
-+#else 
-+      *mount_flags = 0;
-+      return 0;
-+#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */
-+}
-+
-+#else
-+#if defined(HAVE_GETMNTINFO)
-+
-+static errcode_t check_getmntinfo(const char *file, int *mount_flags,
-+                                char *mtpt, int mtlen)
-+{
-+      struct statfs *mp;
-+        int    len, n;
-+        const  char   *s1;
-+      char    *s2;
-+
-+        n = getmntinfo(&mp, MNT_NOWAIT);
-+        if (n == 0)
-+              return errno;
-+
-+        len = sizeof(_PATH_DEV) - 1;
-+        s1 = file;
-+        if (strncmp(_PATH_DEV, s1, len) == 0)
-+                s1 += len;
-+ 
-+      *mount_flags = 0;
-+        while (--n >= 0) {
-+                s2 = mp->f_mntfromname;
-+                if (strncmp(_PATH_DEV, s2, len) == 0) {
-+                        s2 += len - 1;
-+                        *s2 = 'r';
-+                }
-+                if (strcmp(s1, s2) == 0 || strcmp(s1, &s2[1]) == 0) {
-+                      *mount_flags = EXT2_MF_MOUNTED;
-+                      break;
-+              }
-+                ++mp;
-+      }
-+      if (mtpt)
-+              strncpy(mtpt, mp->f_mntonname, mtlen);
-+      return 0;
-+}
-+#endif /* HAVE_GETMNTINFO */
-+#endif /* HAVE_MNTENT_H */
-+
-+/*
-+ * Check to see if we're dealing with the swap device.
-+ */
-+static int is_swap_device(const char *file)
-+{
-+      FILE            *f;
-+      char            buf[1024], *cp;
-+      dev_t           file_dev;
-+      struct stat     st_buf;
-+      int             ret = 0;
-+
-+      file_dev = 0;
-+#ifndef __GNU__ /* The GNU hurd is broken with respect to stat devices */
-+      if ((stat(file, &st_buf) == 0) &&
-+          S_ISBLK(st_buf.st_mode))
-+              file_dev = st_buf.st_rdev;
-+#endif        /* __GNU__ */
-+
-+      if (!(f = fopen("/proc/swaps", "r")))
-+              return 0;
-+      /* Skip the first line */
-+      fgets(buf, sizeof(buf), f);
-+      while (!feof(f)) {
-+              if (!fgets(buf, sizeof(buf), f))
-+                      break;
-+              if ((cp = strchr(buf, ' ')) != NULL)
-+                      *cp = 0;
-+              if ((cp = strchr(buf, '\t')) != NULL)
-+                      *cp = 0;
-+              if (strcmp(buf, file) == 0) {
-+                      ret++;
-+                      break;
-+              }
-+#ifndef __GNU__
-+              if (file_dev && (stat(buf, &st_buf) == 0) &&
-+                  S_ISBLK(st_buf.st_mode) &&
-+                  file_dev == st_buf.st_rdev) {
-+                      ret++;
-+                      break;
-+              }
-+#endif        /* __GNU__ */
-+      }
-+      fclose(f);
-+      return ret;
-+}
-+
-+
-+/*
-+ * ext2fs_check_mount_point() returns 1 if the device is mounted, 0
-+ * otherwise.  If mtpt is non-NULL, the directory where the device is
-+ * mounted is copied to where mtpt is pointing, up to mtlen
-+ * characters.
-+ */
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+errcode_t ext2fs_check_mount_point(const char *device, int *mount_flags,
-+                                char *mtpt, int mtlen)
-+{
-+      if (is_swap_device(device)) {
-+              *mount_flags = EXT2_MF_MOUNTED | EXT2_MF_SWAP;
-+              strncpy(mtpt, "<swap>", mtlen);
-+              return 0;
-+      }
-+#ifdef HAVE_MNTENT_H
-+      return check_mntent(device, mount_flags, mtpt, mtlen);
-+#else 
-+#ifdef HAVE_GETMNTINFO
-+      return check_getmntinfo(device, mount_flags, mtpt, mtlen);
-+#else
-+#ifdef __GNUC__
-+ #warning "Can't use getmntent or getmntinfo to check for mounted filesystems!"
-+#endif
-+      *mount_flags = 0;
-+      return 0;
-+#endif /* HAVE_GETMNTINFO */
-+#endif /* HAVE_MNTENT_H */
-+}
-+
-+/*
-+ * ext2fs_check_if_mounted() sets the mount_flags EXT2_MF_MOUNTED,
-+ * EXT2_MF_READONLY, and EXT2_MF_ROOT
-+ * 
-+ */
-+errcode_t ext2fs_check_if_mounted(const char *file, int *mount_flags)
-+{
-+      return ext2fs_check_mount_point(file, mount_flags, NULL, 0);
-+}
-+
-+#ifdef DEBUG
-+int main(int argc, char **argv)
-+{
-+      int     retval, mount_flags;
-+      char    mntpt[80];
-+      
-+      if (argc < 2) {
-+              fprintf(stderr, "Usage: %s device\n", argv[0]);
-+              exit(1);
-+      }
-+
-+      mntpt[0] = 0;
-+      retval = ext2fs_check_mount_point(argv[1], &mount_flags,
-+                                        mntpt, sizeof(mntpt));
-+      if (retval) {
-+              com_err(argv[0], retval,
-+                      "while calling ext2fs_check_if_mounted");
-+              exit(1);
-+      }
-+      printf("Device %s reports flags %02x\n", argv[1], mount_flags);
-+      if (mount_flags & EXT2_MF_MOUNTED)
-+              printf("\t%s is mounted.\n", argv[1]);
-+
-+      if (mount_flags & EXT2_MF_SWAP)
-+              printf("\t%s is a swap device.\n", argv[1]);
-+
-+      if (mount_flags & EXT2_MF_READONLY)
-+              printf("\t%s is read-only.\n", argv[1]);
-+      
-+      if (mount_flags & EXT2_MF_ISROOT)
-+              printf("\t%s is the root filesystem.\n", argv[1]);
-+      if (mntpt[0])
-+              printf("\t%s is mounted on %s.\n", argv[1], mntpt);
-+      
-+      exit(0);
-+}
-+#endif /* DEBUG */
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/jfs_compat.h busybox/e2fsprogs/ext2fs/jfs_compat.h
---- busybox-1.00/e2fsprogs/ext2fs/jfs_compat.h 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/jfs_compat.h      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,67 @@
-+
-+#ifndef _JFS_COMPAT_H
-+#define _JFS_COMPAT_H
-+
-+#include "kernel-list.h"
-+#include <errno.h>
-+#ifdef HAVE_NETINET_IN_H
-+#include <netinet/in.h>
-+#endif
-+
-+#define printk printf
-+#define KERN_ERR ""
-+#define KERN_DEBUG ""
-+
-+#define READ 0
-+#define WRITE 1
-+
-+#define cpu_to_be32(n) htonl(n)
-+#define be32_to_cpu(n) ntohl(n)
-+
-+typedef unsigned int tid_t;
-+typedef struct journal_s journal_t;
-+
-+struct buffer_head;
-+struct inode;
-+
-+struct journal_s
-+{
-+      unsigned long           j_flags;
-+      int                     j_errno;
-+      struct buffer_head *    j_sb_buffer;
-+      struct journal_superblock_s *j_superblock;
-+      int                     j_format_version;
-+      unsigned long           j_head;
-+      unsigned long           j_tail;
-+      unsigned long           j_free;
-+      unsigned long           j_first, j_last;
-+      kdev_t                  j_dev;
-+      kdev_t                  j_fs_dev;
-+      int                     j_blocksize;
-+      unsigned int            j_blk_offset;
-+      unsigned int            j_maxlen;
-+      struct inode *          j_inode;
-+      tid_t                   j_tail_sequence;
-+      tid_t                   j_transaction_sequence;
-+      __u8                    j_uuid[16];
-+      struct jbd_revoke_table_s *j_revoke;
-+};
-+
-+#define J_ASSERT(assert)                                              \
-+      do { if (!(assert)) {                                           \
-+              printf ("Assertion failure in %s() at %s line %d: "     \
-+                      "\"%s\"\n",                                     \
-+                      __FUNCTION__, __FILE__, __LINE__, # assert);    \
-+              fatal_error(e2fsck_global_ctx, 0);                      \
-+      } } while (0)
-+
-+#define is_journal_abort(x) 0
-+
-+#define BUFFER_TRACE(bh, info)        do {} while (0)
-+
-+/* Need this so we can compile with configure --enable-gcc-wall */
-+#ifdef NO_INLINE_FUNCS
-+#define inline
-+#endif
-+
-+#endif /* _JFS_COMPAT_H */
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/jfs_dat.h busybox/e2fsprogs/ext2fs/jfs_dat.h
---- busybox-1.00/e2fsprogs/ext2fs/jfs_dat.h    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/jfs_dat.h 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,64 @@
-+/*
-+ * jfs_dat.h --- stripped down header file which only contains the JFS
-+ *    on-disk data structures
-+ */
-+
-+#define JFS_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */
-+
-+/*
-+ * On-disk structures
-+ */
-+
-+/* 
-+ * Descriptor block types:
-+ */
-+
-+#define JFS_DESCRIPTOR_BLOCK  1
-+#define JFS_COMMIT_BLOCK      2
-+#define JFS_SUPERBLOCK                3
-+
-+/*
-+ * Standard header for all descriptor blocks:
-+ */
-+typedef struct journal_header_s
-+{
-+      __u32           h_magic;
-+      __u32           h_blocktype;
-+      __u32           h_sequence;
-+} journal_header_t;
-+
-+
-+/* 
-+ * The block tag: used to describe a single buffer in the journal 
-+ */
-+typedef struct journal_block_tag_s
-+{
-+      __u32           t_blocknr;      /* The on-disk block number */
-+      __u32           t_flags;        /* See below */
-+} journal_block_tag_t;
-+
-+/* Definitions for the journal tag flags word: */
-+#define JFS_FLAG_ESCAPE               1       /* on-disk block is escaped */
-+#define JFS_FLAG_SAME_UUID    2       /* block has same uuid as previous */
-+#define JFS_FLAG_DELETED      4       /* block deleted by this transaction */
-+#define JFS_FLAG_LAST_TAG     8       /* last tag in this descriptor block */
-+
-+
-+/*
-+ * The journal superblock
-+ */
-+typedef struct journal_superblock_s
-+{
-+      journal_header_t s_header;
-+
-+      /* Static information describing the journal */
-+      __u32           s_blocksize;    /* journal device blocksize */
-+      __u32           s_maxlen;       /* total blocks in journal file */
-+      __u32           s_first;        /* first block of log information */
-+      
-+      /* Dynamic information describing the current state of the log */
-+      __u32           s_sequence;     /* first commit ID expected in log */
-+      __u32           s_start;        /* blocknr of start of log */
-+      
-+} journal_superblock_t;
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/jfs_user.h busybox/e2fsprogs/ext2fs/jfs_user.h
---- busybox-1.00/e2fsprogs/ext2fs/jfs_user.h   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/jfs_user.h        2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,8 @@
-+#ifndef _JFS_USER_H
-+#define _JFS_USER_H
-+
-+typedef unsigned short kdev_t;
-+
-+#include "kernel-jbd.h"
-+
-+#endif /* _JFS_USER_H */
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/kernel-jbd.h busybox/e2fsprogs/ext2fs/kernel-jbd.h
---- busybox-1.00/e2fsprogs/ext2fs/kernel-jbd.h 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/kernel-jbd.h      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,910 @@
-+/*
-+ * linux/include/linux/jbd.h
-+ * 
-+ * Written by Stephen C. Tweedie <sct@redhat.com>
-+ *
-+ * Copyright 1998-2000 Red Hat, Inc --- All Rights Reserved
-+ *
-+ * This file is part of the Linux kernel and is made available under
-+ * the terms of the GNU General Public License, version 2, or at your
-+ * option, any later version, incorporated herein by reference.
-+ *
-+ * Definitions for transaction data structures for the buffer cache
-+ * filesystem journaling support.
-+ */
-+
-+#ifndef _LINUX_JBD_H
-+#define _LINUX_JBD_H
-+
-+#if defined(CONFIG_JBD) || defined(CONFIG_JBD_MODULE) || !defined(__KERNEL__)
-+
-+/* Allow this file to be included directly into e2fsprogs */
-+#ifndef __KERNEL__
-+#include "jfs_compat.h"
-+#define JFS_DEBUG
-+#define jfs_debug jbd_debug
-+#else
-+
-+#include <linux/journal-head.h>
-+#include <linux/stddef.h>
-+#include <asm/semaphore.h>
-+#endif
-+
-+#ifndef __GNUC__
-+#define __FUNCTION__ ""
-+#endif
-+
-+#define journal_oom_retry 1
-+
-+#ifdef __STDC__
-+#ifdef __CONFIG_JBD_DEBUG__E2FS
-+/*
-+ * Define JBD_EXPENSIVE_CHECKING to enable more expensive internal
-+ * consistency checks.  By default we don't do this unless
-+ * __CONFIG_JBD_DEBUG__E2FS is on.
-+ */
-+#define JBD_EXPENSIVE_CHECKING
-+extern int journal_enable_debug;
-+
-+#define jbd_debug(n, f, a...)                                         \
-+      do {                                                            \
-+              if ((n) <= journal_enable_debug) {                      \
-+                      printk (KERN_DEBUG "(%s, %d): %s: ",            \
-+                              __FILE__, __LINE__, __FUNCTION__);      \
-+                      printk (f, ## a);                               \
-+              }                                                       \
-+      } while (0)
-+#else
-+#ifdef __GNUC__
-+#define jbd_debug(f, a...)    /**/
-+#else
-+#define jbd_debug(f, ...)     /**/
-+#endif        
-+#endif
-+#else
-+#define jbd_debug(x)          /* AIX doesn't do STDC */
-+#endif
-+
-+extern void * __jbd_kmalloc (char *where, size_t size, int flags, int retry);
-+#define jbd_kmalloc(size, flags) \
-+      __jbd_kmalloc(__FUNCTION__, (size), (flags), journal_oom_retry)
-+#define jbd_rep_kmalloc(size, flags) \
-+      __jbd_kmalloc(__FUNCTION__, (size), (flags), 1)
-+
-+#define JFS_MIN_JOURNAL_BLOCKS 1024
-+
-+#ifdef __KERNEL__
-+typedef struct handle_s               handle_t;       /* Atomic operation type */
-+typedef struct journal_s      journal_t;      /* Journal control structure */
-+#endif
-+
-+/*
-+ * Internal structures used by the logging mechanism:
-+ */
-+
-+#define JFS_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */
-+
-+/*
-+ * On-disk structures
-+ */
-+
-+/* 
-+ * Descriptor block types:
-+ */
-+
-+#define JFS_DESCRIPTOR_BLOCK  1
-+#define JFS_COMMIT_BLOCK      2
-+#define JFS_SUPERBLOCK_V1     3
-+#define JFS_SUPERBLOCK_V2     4
-+#define JFS_REVOKE_BLOCK      5
-+
-+/*
-+ * Standard header for all descriptor blocks:
-+ */
-+typedef struct journal_header_s
-+{
-+      __u32           h_magic;
-+      __u32           h_blocktype;
-+      __u32           h_sequence;
-+} journal_header_t;
-+
-+
-+/* 
-+ * The block tag: used to describe a single buffer in the journal 
-+ */
-+typedef struct journal_block_tag_s
-+{
-+      __u32           t_blocknr;      /* The on-disk block number */
-+      __u32           t_flags;        /* See below */
-+} journal_block_tag_t;
-+
-+/* 
-+ * The revoke descriptor: used on disk to describe a series of blocks to
-+ * be revoked from the log 
-+ */
-+typedef struct journal_revoke_header_s
-+{
-+      journal_header_t r_header;
-+      int              r_count;       /* Count of bytes used in the block */
-+} journal_revoke_header_t;
-+
-+
-+/* Definitions for the journal tag flags word: */
-+#define JFS_FLAG_ESCAPE               1       /* on-disk block is escaped */
-+#define JFS_FLAG_SAME_UUID    2       /* block has same uuid as previous */
-+#define JFS_FLAG_DELETED      4       /* block deleted by this transaction */
-+#define JFS_FLAG_LAST_TAG     8       /* last tag in this descriptor block */
-+
-+
-+/*
-+ * The journal superblock.  All fields are in big-endian byte order.
-+ */
-+typedef struct journal_superblock_s
-+{
-+/* 0x0000 */
-+      journal_header_t s_header;
-+
-+/* 0x000C */
-+      /* Static information describing the journal */
-+      __u32   s_blocksize;            /* journal device blocksize */
-+      __u32   s_maxlen;               /* total blocks in journal file */
-+      __u32   s_first;                /* first block of log information */
-+      
-+/* 0x0018 */
-+      /* Dynamic information describing the current state of the log */
-+      __u32   s_sequence;             /* first commit ID expected in log */
-+      __u32   s_start;                /* blocknr of start of log */
-+
-+/* 0x0020 */
-+      /* Error value, as set by journal_abort(). */
-+      __s32   s_errno;
-+
-+/* 0x0024 */
-+      /* Remaining fields are only valid in a version-2 superblock */
-+      __u32   s_feature_compat;       /* compatible feature set */
-+      __u32   s_feature_incompat;     /* incompatible feature set */
-+      __u32   s_feature_ro_compat;    /* readonly-compatible feature set */
-+/* 0x0030 */
-+      __u8    s_uuid[16];             /* 128-bit uuid for journal */
-+
-+/* 0x0040 */
-+      __u32   s_nr_users;             /* Nr of filesystems sharing log */
-+      
-+      __u32   s_dynsuper;             /* Blocknr of dynamic superblock copy*/
-+      
-+/* 0x0048 */
-+      __u32   s_max_transaction;      /* Limit of journal blocks per trans.*/
-+      __u32   s_max_trans_data;       /* Limit of data blocks per trans. */
-+
-+/* 0x0050 */
-+      __u32   s_padding[44];
-+
-+/* 0x0100 */
-+      __u8    s_users[16*48];         /* ids of all fs'es sharing the log */
-+/* 0x0400 */
-+} journal_superblock_t;
-+
-+#define JFS_HAS_COMPAT_FEATURE(j,mask)                                        \
-+      ((j)->j_format_version >= 2 &&                                  \
-+       ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask))))
-+#define JFS_HAS_RO_COMPAT_FEATURE(j,mask)                             \
-+      ((j)->j_format_version >= 2 &&                                  \
-+       ((j)->j_superblock->s_feature_ro_compat & cpu_to_be32((mask))))
-+#define JFS_HAS_INCOMPAT_FEATURE(j,mask)                              \
-+      ((j)->j_format_version >= 2 &&                                  \
-+       ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask))))
-+
-+#define JFS_FEATURE_INCOMPAT_REVOKE   0x00000001
-+
-+/* Features known to this kernel version: */
-+#define JFS_KNOWN_COMPAT_FEATURES     0
-+#define JFS_KNOWN_ROCOMPAT_FEATURES   0
-+#define JFS_KNOWN_INCOMPAT_FEATURES   JFS_FEATURE_INCOMPAT_REVOKE
-+
-+#ifdef __KERNEL__
-+
-+#include <linux/fs.h>
-+#include <linux/sched.h>
-+
-+#define JBD_ASSERTIONS
-+#ifdef JBD_ASSERTIONS
-+#define J_ASSERT(assert)                                              \
-+do {                                                                  \
-+      if (!(assert)) {                                                \
-+              printk (KERN_EMERG                                      \
-+                      "Assertion failure in %s() at %s:%d: \"%s\"\n", \
-+                      __FUNCTION__, __FILE__, __LINE__, # assert);    \
-+              BUG();                                                  \
-+      }                                                               \
-+} while (0)
-+
-+#if defined(CONFIG_BUFFER_DEBUG)
-+void buffer_assertion_failure(struct buffer_head *bh);
-+#define J_ASSERT_BH(bh, expr)                                         \
-+      do {                                                            \
-+              if (!(expr))                                            \
-+                      buffer_assertion_failure(bh);                   \
-+              J_ASSERT(expr);                                         \
-+      } while (0)
-+#define J_ASSERT_JH(jh, expr) J_ASSERT_BH(jh2bh(jh), expr)
-+#else
-+#define J_ASSERT_BH(bh, expr) J_ASSERT(expr)
-+#define J_ASSERT_JH(jh, expr) J_ASSERT(expr)
-+#endif
-+
-+#else
-+#define J_ASSERT(assert)
-+#endif                /* JBD_ASSERTIONS */
-+
-+enum jbd_state_bits {
-+      BH_JWrite
-+        = BH_PrivateStart,    /* 1 if being written to log (@@@ DEBUGGING) */
-+      BH_Freed,               /* 1 if buffer has been freed (truncated) */
-+      BH_Revoked,             /* 1 if buffer has been revoked from the log */
-+      BH_RevokeValid,         /* 1 if buffer revoked flag is valid */
-+      BH_JBDDirty,            /* 1 if buffer is dirty but journaled */
-+};
-+
-+/* Return true if the buffer is one which JBD is managing */
-+static inline int buffer_jbd(struct buffer_head *bh)
-+{
-+      return __buffer_state(bh, JBD);
-+}
-+
-+static inline struct buffer_head *jh2bh(struct journal_head *jh)
-+{
-+      return jh->b_bh;
-+}
-+
-+static inline struct journal_head *bh2jh(struct buffer_head *bh)
-+{
-+      return bh->b_private;
-+}
-+
-+struct jbd_revoke_table_s;
-+
-+/* The handle_t type represents a single atomic update being performed
-+ * by some process.  All filesystem modifications made by the process go
-+ * through this handle.  Recursive operations (such as quota operations)
-+ * are gathered into a single update.
-+ *
-+ * The buffer credits field is used to account for journaled buffers
-+ * being modified by the running process.  To ensure that there is
-+ * enough log space for all outstanding operations, we need to limit the
-+ * number of outstanding buffers possible at any time.  When the
-+ * operation completes, any buffer credits not used are credited back to
-+ * the transaction, so that at all times we know how many buffers the
-+ * outstanding updates on a transaction might possibly touch. */
-+
-+struct handle_s 
-+{
-+      /* Which compound transaction is this update a part of? */
-+      transaction_t         * h_transaction;
-+
-+      /* Number of remaining buffers we are allowed to dirty: */
-+      int                     h_buffer_credits;
-+
-+      /* Reference count on this handle */
-+      int                     h_ref;
-+
-+      /* Field for caller's use to track errors through large fs
-+         operations */
-+      int                     h_err;
-+
-+      /* Flags */
-+      unsigned int    h_sync:         1;      /* sync-on-close */
-+      unsigned int    h_jdata:        1;      /* force data journaling */
-+      unsigned int    h_aborted:      1;      /* fatal error on handle */
-+};
-+
-+
-+/* The transaction_t type is the guts of the journaling mechanism.  It
-+ * tracks a compound transaction through its various states:
-+ *
-+ * RUNNING:   accepting new updates
-+ * LOCKED:    Updates still running but we don't accept new ones
-+ * RUNDOWN:   Updates are tidying up but have finished requesting
-+ *            new buffers to modify (state not used for now)
-+ * FLUSH:       All updates complete, but we are still writing to disk
-+ * COMMIT:      All data on disk, writing commit record
-+ * FINISHED:  We still have to keep the transaction for checkpointing.
-+ *
-+ * The transaction keeps track of all of the buffers modified by a
-+ * running transaction, and all of the buffers committed but not yet
-+ * flushed to home for finished transactions.
-+ */
-+
-+struct transaction_s 
-+{
-+      /* Pointer to the journal for this transaction. */
-+      journal_t *             t_journal;
-+      
-+      /* Sequence number for this transaction */
-+      tid_t                   t_tid;
-+      
-+      /* Transaction's current state */
-+      enum {
-+              T_RUNNING,
-+              T_LOCKED,
-+              T_RUNDOWN,
-+              T_FLUSH,
-+              T_COMMIT,
-+              T_FINISHED 
-+      }                       t_state;
-+
-+      /* Where in the log does this transaction's commit start? */
-+      unsigned long           t_log_start;
-+      
-+      /* Doubly-linked circular list of all inodes owned by this
-+           transaction */     /* AKPM: unused */
-+      struct inode *          t_ilist;
-+      
-+      /* Number of buffers on the t_buffers list */
-+      int                     t_nr_buffers;
-+      
-+      /* Doubly-linked circular list of all buffers reserved but not
-+           yet modified by this transaction */
-+      struct journal_head *   t_reserved_list;
-+      
-+      /* Doubly-linked circular list of all metadata buffers owned by this
-+           transaction */
-+      struct journal_head *   t_buffers;
-+      
-+      /*
-+       * Doubly-linked circular list of all data buffers still to be
-+       * flushed before this transaction can be committed.
-+       * Protected by journal_datalist_lock.
-+       */
-+      struct journal_head *   t_sync_datalist;
-+      
-+      /*
-+       * Doubly-linked circular list of all writepage data buffers
-+       * still to be written before this transaction can be committed.
-+       * Protected by journal_datalist_lock.
-+       */
-+      struct journal_head *   t_async_datalist;
-+      
-+      /* Doubly-linked circular list of all forget buffers (superceded
-+           buffers which we can un-checkpoint once this transaction
-+           commits) */
-+      struct journal_head *   t_forget;
-+      
-+      /*
-+       * Doubly-linked circular list of all buffers still to be
-+       * flushed before this transaction can be checkpointed.
-+       */
-+      /* Protected by journal_datalist_lock */
-+      struct journal_head *   t_checkpoint_list;
-+      
-+      /* Doubly-linked circular list of temporary buffers currently
-+           undergoing IO in the log */
-+      struct journal_head *   t_iobuf_list;
-+      
-+      /* Doubly-linked circular list of metadata buffers being
-+           shadowed by log IO.  The IO buffers on the iobuf list and the
-+           shadow buffers on this list match each other one for one at
-+           all times. */
-+      struct journal_head *   t_shadow_list;
-+      
-+      /* Doubly-linked circular list of control buffers being written
-+           to the log. */
-+      struct journal_head *   t_log_list;
-+      
-+      /* Number of outstanding updates running on this transaction */
-+      int                     t_updates;
-+
-+      /* Number of buffers reserved for use by all handles in this
-+       * transaction handle but not yet modified. */
-+      int                     t_outstanding_credits;
-+      
-+      /*
-+       * Forward and backward links for the circular list of all
-+       * transactions awaiting checkpoint.
-+       */
-+      /* Protected by journal_datalist_lock */
-+      transaction_t           *t_cpnext, *t_cpprev;
-+
-+      /* When will the transaction expire (become due for commit), in
-+       * jiffies ? */
-+      unsigned long           t_expires;
-+
-+      /* How many handles used this transaction? */
-+      int t_handle_count;
-+};
-+
-+
-+/* The journal_t maintains all of the journaling state information for a
-+ * single filesystem.  It is linked to from the fs superblock structure.
-+ * 
-+ * We use the journal_t to keep track of all outstanding transaction
-+ * activity on the filesystem, and to manage the state of the log
-+ * writing process. */
-+
-+struct journal_s
-+{
-+      /* General journaling state flags */
-+      unsigned long           j_flags;
-+
-+      /* Is there an outstanding uncleared error on the journal (from
-+       * a prior abort)? */
-+      int                     j_errno;
-+      
-+      /* The superblock buffer */
-+      struct buffer_head *    j_sb_buffer;
-+      journal_superblock_t *  j_superblock;
-+
-+      /* Version of the superblock format */
-+      int                     j_format_version;
-+
-+      /* Number of processes waiting to create a barrier lock */
-+      int                     j_barrier_count;
-+      
-+      /* The barrier lock itself */
-+      struct semaphore        j_barrier;
-+      
-+      /* Transactions: The current running transaction... */
-+      transaction_t *         j_running_transaction;
-+      
-+      /* ... the transaction we are pushing to disk ... */
-+      transaction_t *         j_committing_transaction;
-+      
-+      /* ... and a linked circular list of all transactions waiting
-+       * for checkpointing. */
-+      /* Protected by journal_datalist_lock */
-+      transaction_t *         j_checkpoint_transactions;
-+
-+      /* Wait queue for waiting for a locked transaction to start
-+           committing, or for a barrier lock to be released */
-+      wait_queue_head_t       j_wait_transaction_locked;
-+      
-+      /* Wait queue for waiting for checkpointing to complete */
-+      wait_queue_head_t       j_wait_logspace;
-+      
-+      /* Wait queue for waiting for commit to complete */
-+      wait_queue_head_t       j_wait_done_commit;
-+      
-+      /* Wait queue to trigger checkpointing */
-+      wait_queue_head_t       j_wait_checkpoint;
-+      
-+      /* Wait queue to trigger commit */
-+      wait_queue_head_t       j_wait_commit;
-+      
-+      /* Wait queue to wait for updates to complete */
-+      wait_queue_head_t       j_wait_updates;
-+
-+      /* Semaphore for locking against concurrent checkpoints */
-+      struct semaphore        j_checkpoint_sem;
-+
-+      /* The main journal lock, used by lock_journal() */
-+      struct semaphore        j_sem;
-+              
-+      /* Journal head: identifies the first unused block in the journal. */
-+      unsigned long           j_head;
-+      
-+      /* Journal tail: identifies the oldest still-used block in the
-+       * journal. */
-+      unsigned long           j_tail;
-+
-+      /* Journal free: how many free blocks are there in the journal? */
-+      unsigned long           j_free;
-+
-+      /* Journal start and end: the block numbers of the first usable
-+       * block and one beyond the last usable block in the journal. */
-+      unsigned long           j_first, j_last;
-+
-+      /* Device, blocksize and starting block offset for the location
-+       * where we store the journal. */
-+      kdev_t                  j_dev;
-+      int                     j_blocksize;
-+      unsigned int            j_blk_offset;
-+
-+      /* Device which holds the client fs.  For internal journal this
-+       * will be equal to j_dev. */
-+      kdev_t                  j_fs_dev;
-+
-+      /* Total maximum capacity of the journal region on disk. */
-+      unsigned int            j_maxlen;
-+
-+      /* Optional inode where we store the journal.  If present, all
-+       * journal block numbers are mapped into this inode via
-+       * bmap(). */
-+      struct inode *          j_inode;
-+
-+      /* Sequence number of the oldest transaction in the log */
-+      tid_t                   j_tail_sequence;
-+      /* Sequence number of the next transaction to grant */
-+      tid_t                   j_transaction_sequence;
-+      /* Sequence number of the most recently committed transaction */
-+      tid_t                   j_commit_sequence;
-+      /* Sequence number of the most recent transaction wanting commit */
-+      tid_t                   j_commit_request;
-+
-+      /* Journal uuid: identifies the object (filesystem, LVM volume
-+       * etc) backed by this journal.  This will eventually be
-+       * replaced by an array of uuids, allowing us to index multiple
-+       * devices within a single journal and to perform atomic updates
-+       * across them.  */
-+
-+      __u8                    j_uuid[16];
-+
-+      /* Pointer to the current commit thread for this journal */
-+      struct task_struct *    j_task;
-+
-+      /* Maximum number of metadata buffers to allow in a single
-+       * compound commit transaction */
-+      int                     j_max_transaction_buffers;
-+
-+      /* What is the maximum transaction lifetime before we begin a
-+       * commit? */
-+      unsigned long           j_commit_interval;
-+
-+      /* The timer used to wakeup the commit thread: */
-+      struct timer_list *     j_commit_timer;
-+      int                     j_commit_timer_active;
-+
-+      /* Link all journals together - system-wide */
-+      struct list_head        j_all_journals;
-+
-+      /* The revoke table: maintains the list of revoked blocks in the
-+           current transaction. */
-+      struct jbd_revoke_table_s *j_revoke;
-+};
-+
-+/* 
-+ * Journal flag definitions 
-+ */
-+#define JFS_UNMOUNT   0x001   /* Journal thread is being destroyed */
-+#define JFS_ABORT     0x002   /* Journaling has been aborted for errors. */
-+#define JFS_ACK_ERR   0x004   /* The errno in the sb has been acked */
-+#define JFS_FLUSHED   0x008   /* The journal superblock has been flushed */
-+#define JFS_LOADED    0x010   /* The journal superblock has been loaded */
-+
-+/* 
-+ * Function declarations for the journaling transaction and buffer
-+ * management
-+ */
-+
-+/* Filing buffers */
-+extern void __journal_unfile_buffer(struct journal_head *);
-+extern void journal_unfile_buffer(struct journal_head *);
-+extern void __journal_refile_buffer(struct journal_head *);
-+extern void journal_refile_buffer(struct journal_head *);
-+extern void __journal_file_buffer(struct journal_head *, transaction_t *, int);
-+extern void __journal_free_buffer(struct journal_head *bh);
-+extern void journal_file_buffer(struct journal_head *, transaction_t *, int);
-+extern void __journal_clean_data_list(transaction_t *transaction);
-+
-+/* Log buffer allocation */
-+extern struct journal_head * journal_get_descriptor_buffer(journal_t *);
-+extern unsigned long journal_next_log_block(journal_t *);
-+
-+/* Commit management */
-+extern void journal_commit_transaction(journal_t *);
-+
-+/* Checkpoint list management */
-+int __journal_clean_checkpoint_list(journal_t *journal);
-+extern void journal_remove_checkpoint(struct journal_head *);
-+extern void __journal_remove_checkpoint(struct journal_head *);
-+extern void journal_insert_checkpoint(struct journal_head *, transaction_t *);
-+extern void __journal_insert_checkpoint(struct journal_head *,transaction_t *);
-+
-+/* Buffer IO */
-+extern int 
-+journal_write_metadata_buffer(transaction_t     *transaction,
-+                            struct journal_head  *jh_in,
-+                            struct journal_head **jh_out,
-+                            int                  blocknr);
-+
-+/* Transaction locking */
-+extern void           __wait_on_journal (journal_t *);
-+
-+/*
-+ * Journal locking.
-+ *
-+ * We need to lock the journal during transaction state changes so that
-+ * nobody ever tries to take a handle on the running transaction while
-+ * we are in the middle of moving it to the commit phase.  
-+ *
-+ * Note that the locking is completely interrupt unsafe.  We never touch
-+ * journal structures from interrupts.
-+ *
-+ * In 2.2, the BKL was required for lock_journal.  This is no longer
-+ * the case.
-+ */
-+
-+static inline void lock_journal(journal_t *journal)
-+{
-+      down(&journal->j_sem);
-+}
-+
-+/* This returns zero if we acquired the semaphore */
-+static inline int try_lock_journal(journal_t * journal)
-+{
-+      return down_trylock(&journal->j_sem);
-+}
-+
-+static inline void unlock_journal(journal_t * journal)
-+{
-+      up(&journal->j_sem);
-+}
-+
-+
-+static inline handle_t *journal_current_handle(void)
-+{
-+      return current->journal_info;
-+}
-+
-+/* The journaling code user interface:
-+ *
-+ * Create and destroy handles
-+ * Register buffer modifications against the current transaction. 
-+ */
-+
-+extern handle_t *journal_start(journal_t *, int nblocks);
-+extern handle_t *journal_try_start(journal_t *, int nblocks);
-+extern int     journal_restart (handle_t *, int nblocks);
-+extern int     journal_extend (handle_t *, int nblocks);
-+extern int     journal_get_write_access (handle_t *, struct buffer_head *);
-+extern int     journal_get_create_access (handle_t *, struct buffer_head *);
-+extern int     journal_get_undo_access (handle_t *, struct buffer_head *);
-+extern int     journal_dirty_data (handle_t *,
-+                              struct buffer_head *, int async);
-+extern int     journal_dirty_metadata (handle_t *, struct buffer_head *);
-+extern void    journal_release_buffer (handle_t *, struct buffer_head *);
-+extern void    journal_forget (handle_t *, struct buffer_head *);
-+extern void    journal_sync_buffer (struct buffer_head *);
-+extern int     journal_flushpage(journal_t *, struct page *, unsigned long);
-+extern int     journal_try_to_free_buffers(journal_t *, struct page *, int);
-+extern int     journal_stop(handle_t *);
-+extern int     journal_flush (journal_t *);
-+
-+extern void    journal_lock_updates (journal_t *);
-+extern void    journal_unlock_updates (journal_t *);
-+
-+extern journal_t * journal_init_dev(kdev_t dev, kdev_t fs_dev,
-+                              int start, int len, int bsize);
-+extern journal_t * journal_init_inode (struct inode *);
-+extern int       journal_update_format (journal_t *);
-+extern int       journal_check_used_features 
-+                 (journal_t *, unsigned long, unsigned long, unsigned long);
-+extern int       journal_check_available_features 
-+                 (journal_t *, unsigned long, unsigned long, unsigned long);
-+extern int       journal_set_features 
-+                 (journal_t *, unsigned long, unsigned long, unsigned long);
-+extern int       journal_create     (journal_t *);
-+extern int       journal_load       (journal_t *journal);
-+extern void      journal_destroy    (journal_t *);
-+extern int       journal_recover    (journal_t *journal);
-+extern int       journal_wipe       (journal_t *, int);
-+extern int       journal_skip_recovery (journal_t *);
-+extern void      journal_update_superblock (journal_t *, int);
-+extern void      __journal_abort      (journal_t *);
-+extern void      journal_abort      (journal_t *, int);
-+extern int       journal_errno      (journal_t *);
-+extern void      journal_ack_err    (journal_t *);
-+extern int       journal_clear_err  (journal_t *);
-+extern unsigned long journal_bmap(journal_t *journal, unsigned long blocknr);
-+extern int        journal_force_commit(journal_t *journal);
-+
-+/*
-+ * journal_head management
-+ */
-+extern struct journal_head
-+              *journal_add_journal_head(struct buffer_head *bh);
-+extern void   journal_remove_journal_head(struct buffer_head *bh);
-+extern void   __journal_remove_journal_head(struct buffer_head *bh);
-+extern void   journal_unlock_journal_head(struct journal_head *jh);
-+
-+/* Primary revoke support */
-+#define JOURNAL_REVOKE_DEFAULT_HASH 256
-+extern int       journal_init_revoke(journal_t *, int);
-+extern void      journal_destroy_revoke_caches(void);
-+extern int       journal_init_revoke_caches(void);
-+
-+extern void      journal_destroy_revoke(journal_t *);
-+extern int       journal_revoke (handle_t *,
-+                              unsigned long, struct buffer_head *);
-+extern int       journal_cancel_revoke(handle_t *, struct journal_head *);
-+extern void      journal_write_revoke_records(journal_t *, transaction_t *);
-+
-+/* Recovery revoke support */
-+extern int       journal_set_revoke(journal_t *, unsigned long, tid_t);
-+extern int       journal_test_revoke(journal_t *, unsigned long, tid_t);
-+extern void      journal_clear_revoke(journal_t *);
-+extern void      journal_brelse_array(struct buffer_head *b[], int n);
-+
-+/* The log thread user interface:
-+ *
-+ * Request space in the current transaction, and force transaction commit
-+ * transitions on demand.
-+ */
-+
-+extern int    log_space_left (journal_t *); /* Called with journal locked */
-+extern tid_t  log_start_commit (journal_t *, transaction_t *);
-+extern void   log_wait_commit (journal_t *, tid_t);
-+extern int    log_do_checkpoint (journal_t *, int);
-+
-+extern void   log_wait_for_space(journal_t *, int nblocks);
-+extern void   __journal_drop_transaction(journal_t *, transaction_t *);
-+extern int    cleanup_journal_tail(journal_t *);
-+
-+/* Reduce journal memory usage by flushing */
-+extern void shrink_journal_memory(void);
-+
-+/* Debugging code only: */
-+
-+#define jbd_ENOSYS() \
-+do {                                                                \
-+      printk (KERN_ERR "JBD unimplemented function " __FUNCTION__); \
-+      current->state = TASK_UNINTERRUPTIBLE;                        \
-+      schedule();                                                   \
-+} while (1)
-+
-+/*
-+ * is_journal_abort
-+ *
-+ * Simple test wrapper function to test the JFS_ABORT state flag.  This
-+ * bit, when set, indicates that we have had a fatal error somewhere,
-+ * either inside the journaling layer or indicated to us by the client
-+ * (eg. ext3), and that we and should not commit any further
-+ * transactions.  
-+ */
-+
-+static inline int is_journal_aborted(journal_t *journal)
-+{
-+      return journal->j_flags & JFS_ABORT;
-+}
-+
-+static inline int is_handle_aborted(handle_t *handle)
-+{
-+      if (handle->h_aborted)
-+              return 1;
-+      return is_journal_aborted(handle->h_transaction->t_journal);
-+}
-+
-+static inline void journal_abort_handle(handle_t *handle)
-+{
-+      handle->h_aborted = 1;
-+}
-+
-+/* Not all architectures define BUG() */
-+#ifndef BUG
-+#define BUG() do { \
-+        printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
-+      * ((char *) 0) = 0; \
-+ } while (0)
-+#endif /* BUG */
-+
-+#else
-+
-+extern int       journal_recover    (journal_t *journal);
-+extern int       journal_skip_recovery (journal_t *);
-+
-+/* Primary revoke support */
-+extern int       journal_init_revoke(journal_t *, int);
-+extern void      journal_destroy_revoke_caches(void);
-+extern int       journal_init_revoke_caches(void);
-+
-+/* Recovery revoke support */
-+extern int       journal_set_revoke(journal_t *, unsigned long, tid_t);
-+extern int       journal_test_revoke(journal_t *, unsigned long, tid_t);
-+extern void      journal_clear_revoke(journal_t *);
-+extern void      journal_brelse_array(struct buffer_head *b[], int n);
-+
-+extern void      journal_destroy_revoke(journal_t *);
-+#endif /* __KERNEL__   */
-+
-+/* Comparison functions for transaction IDs: perform comparisons using
-+ * modulo arithmetic so that they work over sequence number wraps. */
-+
-+static inline int tid_gt(tid_t x, tid_t y)
-+{
-+      int difference = (x - y);
-+      return (difference > 0);
-+}
-+
-+static inline int tid_geq(tid_t x, tid_t y)
-+{
-+      int difference = (x - y);
-+      return (difference >= 0);
-+}
-+
-+extern int journal_blocks_per_page(struct inode *inode);
-+
-+/*
-+ * Definitions which augment the buffer_head layer
-+ */
-+
-+/* journaling buffer types */
-+#define BJ_None               0       /* Not journaled */
-+#define BJ_SyncData   1       /* Normal data: flush before commit */
-+#define BJ_AsyncData  2       /* writepage data: wait on it before commit */
-+#define BJ_Metadata   3       /* Normal journaled metadata */
-+#define BJ_Forget     4       /* Buffer superceded by this transaction */
-+#define BJ_IO         5       /* Buffer is for temporary IO use */
-+#define BJ_Shadow     6       /* Buffer contents being shadowed to the log */
-+#define BJ_LogCtl     7       /* Buffer contains log descriptors */
-+#define BJ_Reserved   8       /* Buffer is reserved for access by journal */
-+#define BJ_Types      9
-+ 
-+extern int jbd_blocks_per_page(struct inode *inode);
-+
-+#ifdef __KERNEL__
-+
-+extern spinlock_t jh_splice_lock;
-+/*
-+ * Once `expr1' has been found true, take jh_splice_lock
-+ * and then reevaluate everything.
-+ */
-+#define SPLICE_LOCK(expr1, expr2)                             \
-+      ({                                                      \
-+              int ret = (expr1);                              \
-+              if (ret) {                                      \
-+                      spin_lock(&jh_splice_lock);             \
-+                      ret = (expr1) && (expr2);               \
-+                      spin_unlock(&jh_splice_lock);           \
-+              }                                               \
-+              ret;                                            \
-+      })
-+
-+/*
-+ * A number of buffer state predicates.  They test for
-+ * buffer_jbd() because they are used in core kernel code.
-+ *
-+ * These will be racy on SMP unless we're *sure* that the
-+ * buffer won't be detached from the journalling system
-+ * in parallel.
-+ */
-+
-+/* Return true if the buffer is on journal list `list' */
-+static inline int buffer_jlist_eq(struct buffer_head *bh, int list)
-+{
-+      return SPLICE_LOCK(buffer_jbd(bh), bh2jh(bh)->b_jlist == list);
-+}
-+
-+/* Return true if this bufer is dirty wrt the journal */
-+static inline int buffer_jdirty(struct buffer_head *bh)
-+{
-+      return buffer_jbd(bh) && __buffer_state(bh, JBDDirty);
-+}
-+
-+/* Return true if it's a data buffer which journalling is managing */
-+static inline int buffer_jbd_data(struct buffer_head *bh)
-+{
-+      return SPLICE_LOCK(buffer_jbd(bh),
-+                      bh2jh(bh)->b_jlist == BJ_SyncData ||
-+                      bh2jh(bh)->b_jlist == BJ_AsyncData);
-+}
-+
-+#ifdef CONFIG_SMP
-+#define assert_spin_locked(lock)      J_ASSERT(spin_is_locked(lock))
-+#else
-+#define assert_spin_locked(lock)      do {} while(0)
-+#endif
-+
-+#define buffer_trace_init(bh) do {} while (0)
-+#define print_buffer_fields(bh)       do {} while (0)
-+#define print_buffer_trace(bh)        do {} while (0)
-+#define BUFFER_TRACE(bh, info)        do {} while (0)
-+#define BUFFER_TRACE2(bh, bh2, info)  do {} while (0)
-+#define JBUFFER_TRACE(jh, info)       do {} while (0)
-+
-+#endif        /* __KERNEL__ */
-+
-+#endif        /* CONFIG_JBD || CONFIG_JBD_MODULE || !__KERNEL__ */
-+
-+/*
-+ * Compatibility no-ops which allow the kernel to compile without CONFIG_JBD
-+ * go here.
-+ */
-+
-+#if defined(__KERNEL__) && !(defined(CONFIG_JBD) || defined(CONFIG_JBD_MODULE))
-+
-+#define J_ASSERT(expr)                        do {} while (0)
-+#define J_ASSERT_BH(bh, expr)         do {} while (0)
-+#define buffer_jbd(bh)                        0
-+#define buffer_jlist_eq(bh, val)      0
-+#define journal_buffer_journal_lru(bh)        0
-+
-+#endif        /* defined(__KERNEL__) && !defined(CONFIG_JBD) */
-+#endif        /* _LINUX_JBD_H */
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/kernel-list.h busybox/e2fsprogs/ext2fs/kernel-list.h
---- busybox-1.00/e2fsprogs/ext2fs/kernel-list.h        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/kernel-list.h     2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,112 @@
-+#ifndef _LINUX_LIST_H
-+#define _LINUX_LIST_H
-+
-+/*
-+ * Simple doubly linked list implementation.
-+ *
-+ * Some of the internal functions ("__xxx") are useful when
-+ * manipulating whole lists rather than single entries, as
-+ * sometimes we already know the next/prev entries and we can
-+ * generate better code by using them directly rather than
-+ * using the generic single-entry routines.
-+ */
-+
-+struct list_head {
-+      struct list_head *next, *prev;
-+};
-+
-+#define LIST_HEAD_INIT(name) { &(name), &(name) }
-+
-+#define LIST_HEAD(name) \
-+      struct list_head name = { &name, &name }
-+
-+#define INIT_LIST_HEAD(ptr) do { \
-+      (ptr)->next = (ptr); (ptr)->prev = (ptr); \
-+} while (0)
-+
-+#if (!defined(__GNUC__) && !defined(__WATCOMC__))
-+#define __inline__
-+#endif
-+
-+/*
-+ * Insert a new entry between two known consecutive entries. 
-+ *
-+ * This is only for internal list manipulation where we know
-+ * the prev/next entries already!
-+ */
-+static __inline__ void __list_add(struct list_head * new,
-+      struct list_head * prev,
-+      struct list_head * next)
-+{
-+      next->prev = new;
-+      new->next = next;
-+      new->prev = prev;
-+      prev->next = new;
-+}
-+
-+/*
-+ * Insert a new entry after the specified head..
-+ */
-+static __inline__ void list_add(struct list_head *new, struct list_head *head)
-+{
-+      __list_add(new, head, head->next);
-+}
-+
-+/*
-+ * Insert a new entry at the tail
-+ */
-+static __inline__ void list_add_tail(struct list_head *new, struct list_head *head)
-+{
-+      __list_add(new, head->prev, head);
-+}
-+
-+/*
-+ * Delete a list entry by making the prev/next entries
-+ * point to each other.
-+ *
-+ * This is only for internal list manipulation where we know
-+ * the prev/next entries already!
-+ */
-+static __inline__ void __list_del(struct list_head * prev,
-+                                struct list_head * next)
-+{
-+      next->prev = prev;
-+      prev->next = next;
-+}
-+
-+static __inline__ void list_del(struct list_head *entry)
-+{
-+      __list_del(entry->prev, entry->next);
-+}
-+
-+static __inline__ int list_empty(struct list_head *head)
-+{
-+      return head->next == head;
-+}
-+
-+/*
-+ * Splice in "list" into "head"
-+ */
-+static __inline__ void list_splice(struct list_head *list, struct list_head *head)
-+{
-+      struct list_head *first = list->next;
-+
-+      if (first != list) {
-+              struct list_head *last = list->prev;
-+              struct list_head *at = head->next;
-+
-+              first->prev = head;
-+              head->next = first;
-+
-+              last->next = at;
-+              at->prev = last;
-+      }
-+}
-+
-+#define list_entry(ptr, type, member) \
-+      ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-+
-+#define list_for_each(pos, head) \
-+        for (pos = (head)->next; pos != (head); pos = pos->next)
-+
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/link.c busybox/e2fsprogs/ext2fs/link.c
---- busybox-1.00/e2fsprogs/ext2fs/link.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/link.c    2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,134 @@
-+/*
-+ * link.c --- create links in a ext2fs directory
-+ * 
-+ * Copyright (C) 1993, 1994 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct link_struct  {
-+      const char      *name;
-+      int             namelen;
-+      ext2_ino_t      inode;
-+      int             flags;
-+      int             done;
-+      struct ext2_super_block *sb;
-+};    
-+
-+static int link_proc(struct ext2_dir_entry *dirent,
-+                   int        offset,
-+                   int        blocksize,
-+                   char       *buf,
-+                   void       *priv_data)
-+{
-+      struct link_struct *ls = (struct link_struct *) priv_data;
-+      struct ext2_dir_entry *next;
-+      int rec_len, min_rec_len;
-+      int ret = 0;
-+
-+      rec_len = EXT2_DIR_REC_LEN(ls->namelen);
-+
-+      /*
-+       * See if the following directory entry (if any) is unused;
-+       * if so, absorb it into this one.
-+       */
-+      next = (struct ext2_dir_entry *) (buf + offset + dirent->rec_len);
-+      if ((offset + dirent->rec_len < blocksize - 8) &&
-+          (next->inode == 0) &&
-+          (offset + dirent->rec_len + next->rec_len <= blocksize)) {
-+              dirent->rec_len += next->rec_len;
-+              ret = DIRENT_CHANGED;
-+      }
-+
-+      /*
-+       * If the directory entry is used, see if we can split the
-+       * directory entry to make room for the new name.  If so,
-+       * truncate it and return.
-+       */
-+      if (dirent->inode) {
-+              min_rec_len = EXT2_DIR_REC_LEN(dirent->name_len & 0xFF);
-+              if (dirent->rec_len < (min_rec_len + rec_len))
-+                      return ret;
-+              rec_len = dirent->rec_len - min_rec_len;
-+              dirent->rec_len = min_rec_len;
-+              next = (struct ext2_dir_entry *) (buf + offset +
-+                                                dirent->rec_len);
-+              next->inode = 0;
-+              next->name_len = 0;
-+              next->rec_len = rec_len;
-+              return DIRENT_CHANGED;
-+      }
-+
-+      /*
-+       * If we get this far, then the directory entry is not used.
-+       * See if we can fit the request entry in.  If so, do it.
-+       */
-+      if (dirent->rec_len < rec_len)
-+              return ret;
-+      dirent->inode = ls->inode;
-+      dirent->name_len = ls->namelen;
-+      strncpy(dirent->name, ls->name, ls->namelen);
-+      if (ls->sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE)
-+              dirent->name_len |= (ls->flags & 0x7) << 8;
-+
-+      ls->done++;
-+      return DIRENT_ABORT|DIRENT_CHANGED;
-+}
-+
-+/*
-+ * Note: the low 3 bits of the flags field are used as the directory
-+ * entry filetype.
-+ */
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name, 
-+                    ext2_ino_t ino, int flags)
-+{
-+      errcode_t               retval;
-+      struct link_struct      ls;
-+      struct ext2_inode       inode;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (!(fs->flags & EXT2_FLAG_RW))
-+              return EXT2_ET_RO_FILSYS;
-+
-+      ls.name = name;
-+      ls.namelen = name ? strlen(name) : 0;
-+      ls.inode = ino;
-+      ls.flags = flags;
-+      ls.done = 0;
-+      ls.sb = fs->super;
-+
-+      retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
-+                                  0, link_proc, &ls);
-+      if (retval)
-+              return retval;
-+
-+      if (!ls.done)
-+              return EXT2_ET_DIR_NO_SPACE;
-+
-+      if ((retval = ext2fs_read_inode(fs, dir, &inode)) != 0)
-+              return retval;
-+
-+      if (inode.i_flags & EXT2_INDEX_FL) {
-+              inode.i_flags &= ~EXT2_INDEX_FL;
-+              if ((retval = ext2fs_write_inode(fs, dir, &inode)) != 0)
-+                      return retval;
-+      }
-+
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/llseek.c busybox/e2fsprogs/ext2fs/llseek.c
---- busybox-1.00/e2fsprogs/ext2fs/llseek.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/llseek.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,135 @@
-+/*
-+ * llseek.c -- stub calling the llseek system call
-+ *
-+ * Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef __MSDOS__
-+#include <io.h>
-+#endif
-+#include "et/com_err.h"
-+#include "ext2fs/ext2_io.h"
-+
-+#ifdef __linux__
-+
-+#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
-+
-+#define my_llseek lseek64
-+
-+#else
-+#if defined(HAVE_LLSEEK)
-+#include <syscall.h>
-+
-+#ifndef HAVE_LLSEEK_PROTOTYPE
-+extern long long llseek (int fd, long long offset, int origin);
-+#endif
-+
-+#define my_llseek llseek
-+
-+#else /* ! HAVE_LLSEEK */
-+
-+#if defined(__alpha__) || defined (__ia64__)
-+
-+#define llseek lseek
-+
-+#else /* !__alpha__ && !__ia64__*/
-+
-+#include <linux/unistd.h>
-+
-+#ifndef __NR__llseek
-+#define __NR__llseek            140
-+#endif
-+
-+#ifndef __i386__
-+static int _llseek (unsigned int, unsigned long,
-+                 unsigned long, ext2_loff_t *, unsigned int);
-+
-+static _syscall5(int,_llseek,unsigned int,fd,unsigned long,offset_high,
-+               unsigned long, offset_low,ext2_loff_t *,result,
-+               unsigned int, origin)
-+#endif
-+
-+static ext2_loff_t my_llseek (int fd, ext2_loff_t offset, int origin)
-+{
-+      ext2_loff_t result;
-+      int retval;
-+
-+#ifndef __i386__
-+      retval = _llseek(fd, ((unsigned long long) offset) >> 32,
-+#else                   
-+      retval = syscall(__NR__llseek, fd, (unsigned long long) (offset >> 32),
-+#endif
-+                        ((unsigned long long) offset) & 0xffffffff,
-+                      &result, origin);
-+      return (retval == -1 ? (ext2_loff_t) retval : result);
-+}
-+
-+#endif        /* __alpha__ || __ia64__ */
-+
-+#endif /* HAVE_LLSEEK */
-+#endif /* defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE) */
-+
-+ext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin)
-+{
-+      ext2_loff_t result;
-+      static int do_compat = 0;
-+
-+      if ((sizeof(off_t) >= sizeof(ext2_loff_t)) ||
-+          (offset < ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1))))
-+              return lseek(fd, (off_t) offset, origin);
-+
-+      if (do_compat) {
-+              errno = EINVAL;
-+              return -1;
-+      }
-+      
-+      result = my_llseek (fd, offset, origin);
-+      if (result == -1 && errno == ENOSYS) {
-+              /*
-+               * Just in case this code runs on top of an old kernel
-+               * which does not support the llseek system call
-+               */
-+              do_compat++;
-+              errno = EINVAL;
-+      }
-+      return result;
-+}
-+
-+#else /* !linux */
-+
-+#ifndef EINVAL
-+#define EINVAL EXT2_ET_INVALID_ARGUMENT
-+#endif
-+
-+ext2_loff_t ext2fs_llseek (int fd, ext2_loff_t offset, int origin)
-+{
-+#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
-+      return lseek64 (fd, offset, origin);
-+#else
-+      if ((sizeof(off_t) < sizeof(ext2_loff_t)) &&
-+          (offset >= ((ext2_loff_t) 1 << ((sizeof(off_t)*8) -1)))) {
-+              errno = EINVAL;
-+              return -1;
-+      }
-+      return lseek (fd, (off_t) offset, origin);
-+#endif
-+}
-+
-+#endif        /* linux */
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/lookup.c busybox/e2fsprogs/ext2fs/lookup.c
---- busybox-1.00/e2fsprogs/ext2fs/lookup.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/lookup.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,69 @@
-+/*
-+ * lookup.c --- ext2fs directory lookup operations
-+ * 
-+ * Copyright (C) 1993, 1994, 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct lookup_struct  {
-+      const char      *name;
-+      int             len;
-+      ext2_ino_t      *inode;
-+      int             found;
-+};    
-+
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int lookup_proc(struct ext2_dir_entry *dirent,
-+                     int      offset EXT2FS_ATTR((unused)),
-+                     int      blocksize EXT2FS_ATTR((unused)),
-+                     char     *buf EXT2FS_ATTR((unused)),
-+                     void     *priv_data)
-+{
-+      struct lookup_struct *ls = (struct lookup_struct *) priv_data;
-+
-+      if (ls->len != (dirent->name_len & 0xFF))
-+              return 0;
-+      if (strncmp(ls->name, dirent->name, (dirent->name_len & 0xFF)))
-+              return 0;
-+      *ls->inode = dirent->inode;
-+      ls->found++;
-+      return DIRENT_ABORT;
-+}
-+
-+
-+errcode_t ext2fs_lookup(ext2_filsys fs, ext2_ino_t dir, const char *name,
-+                      int namelen, char *buf, ext2_ino_t *inode)
-+{
-+      errcode_t       retval;
-+      struct lookup_struct ls;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      ls.name = name;
-+      ls.len = namelen;
-+      ls.inode = inode;
-+      ls.found = 0;
-+
-+      retval = ext2fs_dir_iterate(fs, dir, 0, buf, lookup_proc, &ls);
-+      if (retval)
-+              return retval;
-+
-+      return (ls.found) ? 0 : EXT2_ET_FILE_NOT_FOUND;
-+}
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/mkdir.c busybox/e2fsprogs/ext2fs/mkdir.c
---- busybox-1.00/e2fsprogs/ext2fs/mkdir.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/mkdir.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,142 @@
-+/*
-+ * mkdir.c --- make a directory in the filesystem
-+ * 
-+ * Copyright (C) 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#ifndef EXT2_FT_DIR
-+#define EXT2_FT_DIR           2
-+#endif
-+
-+errcode_t ext2fs_mkdir(ext2_filsys fs, ext2_ino_t parent, ext2_ino_t inum,
-+                     const char *name)
-+{
-+      errcode_t               retval;
-+      struct ext2_inode       parent_inode, inode;
-+      ext2_ino_t              ino = inum;
-+      ext2_ino_t              scratch_ino;
-+      blk_t                   blk;
-+      char                    *block = 0;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      /*
-+       * Allocate an inode, if necessary
-+       */
-+      if (!ino) {
-+              retval = ext2fs_new_inode(fs, parent, LINUX_S_IFDIR | 0755,
-+                                        0, &ino);
-+              if (retval)
-+                      goto cleanup;
-+      }
-+
-+      /*
-+       * Allocate a data block for the directory
-+       */
-+      retval = ext2fs_new_block(fs, 0, 0, &blk);
-+      if (retval)
-+              goto cleanup;
-+
-+      /*
-+       * Create a scratch template for the directory
-+       */
-+      retval = ext2fs_new_dir_block(fs, ino, parent, &block);
-+      if (retval)
-+              goto cleanup;
-+
-+      /*
-+       * Get the parent's inode, if necessary
-+       */
-+      if (parent != ino) {
-+              retval = ext2fs_read_inode(fs, parent, &parent_inode);
-+              if (retval)
-+                      goto cleanup;
-+      } else
-+              memset(&parent_inode, 0, sizeof(parent_inode));
-+
-+      /*
-+       * Create the inode structure....
-+       */
-+      memset(&inode, 0, sizeof(struct ext2_inode));
-+      inode.i_mode = LINUX_S_IFDIR | (0777 & ~fs->umask);
-+      inode.i_uid = inode.i_gid = 0;
-+      inode.i_blocks = fs->blocksize / 512;
-+      inode.i_block[0] = blk;
-+      inode.i_links_count = 2;
-+      inode.i_ctime = inode.i_atime = inode.i_mtime = time(NULL);
-+      inode.i_size = fs->blocksize;
-+
-+      /*
-+       * Write out the inode and inode data block
-+       */
-+      retval = ext2fs_write_dir_block(fs, blk, block);
-+      if (retval)
-+              goto cleanup;
-+      retval = ext2fs_write_new_inode(fs, ino, &inode); 
-+      if (retval)
-+              goto cleanup;
-+
-+      /*
-+       * Link the directory into the filesystem hierarchy
-+       */
-+      if (name) {
-+              retval = ext2fs_lookup(fs, parent, name, strlen(name), 0,
-+                                     &scratch_ino);
-+              if (!retval) {
-+                      retval = EXT2_ET_DIR_EXISTS;
-+                      name = 0;
-+                      goto cleanup;
-+              }
-+              if (retval != EXT2_ET_FILE_NOT_FOUND)
-+                      goto cleanup;
-+              retval = ext2fs_link(fs, parent, name, ino, EXT2_FT_DIR);
-+              if (retval)
-+                      goto cleanup;
-+      }
-+
-+      /*
-+       * Update parent inode's counts
-+       */
-+      if (parent != ino) {
-+              parent_inode.i_links_count++;
-+              retval = ext2fs_write_inode(fs, parent, &parent_inode);
-+              if (retval)
-+                      goto cleanup;
-+      }
-+      
-+      /*
-+       * Update accounting....
-+       */
-+      ext2fs_block_alloc_stats(fs, blk, +1);
-+      ext2fs_inode_alloc_stats2(fs, ino, +1, 1);
-+
-+cleanup:
-+      if (block)
-+              ext2fs_free_mem(&block);
-+      return retval;
-+
-+}
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/mkjournal.c busybox/e2fsprogs/ext2fs/mkjournal.c
---- busybox-1.00/e2fsprogs/ext2fs/mkjournal.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/mkjournal.c       2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,425 @@
-+/*
-+ * mkjournal.c --- make a journal for a filesystem
-+ *
-+ * Copyright (C) 2000 Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#if HAVE_SYS_IOCTL_H
-+#include <sys/ioctl.h>
-+#endif
-+#if HAVE_NETINET_IN_H
-+#include <netinet/in.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "e2p/e2p.h"
-+#include "ext2fs.h"
-+#include "jfs_user.h"
-+
-+/*
-+ * This function automatically sets up the journal superblock and
-+ * returns it as an allocated block.
-+ */
-+errcode_t ext2fs_create_journal_superblock(ext2_filsys fs,
-+                                         __u32 size, int flags,
-+                                         char  **ret_jsb)
-+{
-+      errcode_t               retval;
-+      journal_superblock_t    *jsb;
-+
-+      if (size < 1024)
-+              return EXT2_ET_JOURNAL_TOO_SMALL;
-+
-+      if ((retval = ext2fs_get_mem(fs->blocksize, &jsb)))
-+              return retval;
-+
-+      memset (jsb, 0, fs->blocksize);
-+
-+      jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER);
-+      if (flags & EXT2_MKJOURNAL_V1_SUPER)
-+              jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V1);
-+      else
-+              jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2);
-+      jsb->s_blocksize = htonl(fs->blocksize);
-+      jsb->s_maxlen = htonl(size);
-+      jsb->s_nr_users = htonl(1);
-+      jsb->s_first = htonl(1);
-+      jsb->s_sequence = htonl(1);
-+      memcpy(jsb->s_uuid, fs->super->s_uuid, sizeof(fs->super->s_uuid));
-+      /*
-+       * If we're creating an external journal device, we need to
-+       * adjust these fields.
-+       */
-+      if (fs->super->s_feature_incompat &
-+          EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
-+              jsb->s_nr_users = 0;
-+              if (fs->blocksize == 1024)
-+                      jsb->s_first = htonl(3);
-+              else
-+                      jsb->s_first = htonl(2);
-+      }
-+
-+      *ret_jsb = (char *) jsb;
-+      return 0;
-+}
-+
-+/*
-+ * This function writes a journal using POSIX routines.  It is used
-+ * for creating external journals and creating journals on live
-+ * filesystems.
-+ */
-+static errcode_t write_journal_file(ext2_filsys fs, char *filename,
-+                                  blk_t size, int flags)
-+{
-+      errcode_t       retval;
-+      char            *buf = 0;
-+      int             fd, ret_size;
-+      blk_t           i;
-+
-+      if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf)))
-+              return retval;
-+
-+      /* Open the device or journal file */
-+      if ((fd = open(filename, O_WRONLY)) < 0) {
-+              retval = errno;
-+              goto errout;
-+      }
-+
-+      /* Write the superblock out */
-+      retval = EXT2_ET_SHORT_WRITE;
-+      ret_size = write(fd, buf, fs->blocksize);
-+      if (ret_size < 0) {
-+              retval = errno;
-+              goto errout;
-+      }
-+      if (ret_size != (int) fs->blocksize)
-+              goto errout;
-+      memset(buf, 0, fs->blocksize);
-+
-+      for (i = 1; i < size; i++) {
-+              ret_size = write(fd, buf, fs->blocksize);
-+              if (ret_size < 0) {
-+                      retval = errno;
-+                      goto errout;
-+              }
-+              if (ret_size != (int) fs->blocksize)
-+                      goto errout;
-+      }
-+      close(fd);
-+
-+      retval = 0;
-+errout:
-+      ext2fs_free_mem(&buf);
-+      return retval;
-+}
-+
-+/*
-+ * Helper function for creating the journal using direct I/O routines
-+ */
-+struct mkjournal_struct {
-+      int             num_blocks;
-+      int             newblocks;
-+      char            *buf;
-+      errcode_t       err;
-+};
-+
-+static int mkjournal_proc(ext2_filsys fs,
-+                         blk_t        *blocknr,
-+                         e2_blkcnt_t  blockcnt,
-+                         blk_t        ref_block EXT2FS_ATTR((unused)),
-+                         int          ref_offset EXT2FS_ATTR((unused)),
-+                         void         *priv_data)
-+{
-+      struct mkjournal_struct *es = (struct mkjournal_struct *) priv_data;
-+      blk_t   new_blk;
-+      static blk_t    last_blk = 0;
-+      errcode_t       retval;
-+      
-+      if (*blocknr) {
-+              last_blk = *blocknr;
-+              return 0;
-+      }
-+      retval = ext2fs_new_block(fs, last_blk, 0, &new_blk);
-+      if (retval) {
-+              es->err = retval;
-+              return BLOCK_ABORT;
-+      }
-+      if (blockcnt > 0)
-+              es->num_blocks--;
-+
-+      es->newblocks++;
-+      retval = io_channel_write_blk(fs->io, new_blk, 1, es->buf);
-+
-+      if (blockcnt == 0)
-+              memset(es->buf, 0, fs->blocksize);
-+
-+      if (retval) {
-+              es->err = retval;
-+              return BLOCK_ABORT;
-+      }
-+      *blocknr = new_blk;
-+      last_blk = new_blk;
-+      ext2fs_block_alloc_stats(fs, new_blk, +1);
-+
-+      if (es->num_blocks == 0)
-+              return (BLOCK_CHANGED | BLOCK_ABORT);
-+      else
-+              return BLOCK_CHANGED;
-+      
-+}
-+
-+/*
-+ * This function creates a journal using direct I/O routines.
-+ */
-+static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
-+                                   blk_t size, int flags)
-+{
-+      char                    *buf;
-+      errcode_t               retval;
-+      struct ext2_inode       inode;
-+      struct mkjournal_struct es;
-+
-+      if ((retval = ext2fs_create_journal_superblock(fs, size, flags, &buf)))
-+              return retval;
-+      
-+      if ((retval = ext2fs_read_bitmaps(fs)))
-+              return retval;
-+
-+      if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
-+              return retval;
-+
-+      if (inode.i_blocks > 0)
-+              return EEXIST;
-+
-+      es.num_blocks = size;
-+      es.newblocks = 0;
-+      es.buf = buf;
-+      es.err = 0;
-+
-+      retval = ext2fs_block_iterate2(fs, journal_ino, BLOCK_FLAG_APPEND,
-+                                     0, mkjournal_proc, &es);
-+      if (es.err) {
-+              retval = es.err;
-+              goto errout;
-+      }
-+
-+      if ((retval = ext2fs_read_inode(fs, journal_ino, &inode)))
-+              goto errout;
-+
-+      inode.i_size += fs->blocksize * size;
-+      inode.i_blocks += (fs->blocksize / 512) * es.newblocks;
-+      inode.i_mtime = inode.i_ctime = time(0);
-+      inode.i_links_count = 1;
-+      inode.i_mode = LINUX_S_IFREG | 0600;
-+
-+      if ((retval = ext2fs_write_inode(fs, journal_ino, &inode)))
-+              goto errout;
-+      retval = 0;
-+
-+      memcpy(fs->super->s_jnl_blocks, inode.i_block, EXT2_N_BLOCKS*4);
-+      fs->super->s_jnl_blocks[16] = inode.i_size;
-+      fs->super->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS;
-+      ext2fs_mark_super_dirty(fs);
-+
-+errout:
-+      ext2fs_free_mem(&buf);
-+      return retval;
-+}
-+
-+/*
-+ * This function adds a journal device to a filesystem
-+ */
-+errcode_t ext2fs_add_journal_device(ext2_filsys fs, ext2_filsys journal_dev)
-+{
-+      struct stat     st;
-+      errcode_t       retval;
-+      char            buf[1024];
-+      journal_superblock_t    *jsb;
-+      int             start;
-+      __u32           i, nr_users;
-+
-+      /* Make sure the device exists and is a block device */
-+      if (stat(journal_dev->device_name, &st) < 0)
-+              return errno;
-+      
-+      if (!S_ISBLK(st.st_mode))
-+              return EXT2_ET_JOURNAL_NOT_BLOCK; /* Must be a block device */
-+
-+      /* Get the journal superblock */
-+      start = 1;
-+      if (journal_dev->blocksize == 1024)
-+              start++;
-+      if ((retval = io_channel_read_blk(journal_dev->io, start, -1024, buf)))
-+              return retval;
-+
-+      jsb = (journal_superblock_t *) buf;
-+      if ((jsb->s_header.h_magic != (unsigned) ntohl(JFS_MAGIC_NUMBER)) ||
-+          (jsb->s_header.h_blocktype != (unsigned) ntohl(JFS_SUPERBLOCK_V2)))
-+              return EXT2_ET_NO_JOURNAL_SB;
-+
-+      if (ntohl(jsb->s_blocksize) != (unsigned long) fs->blocksize)
-+              return EXT2_ET_UNEXPECTED_BLOCK_SIZE;
-+
-+      /* Check and see if this filesystem has already been added */
-+      nr_users = ntohl(jsb->s_nr_users);
-+      for (i=0; i < nr_users; i++) {
-+              if (memcmp(fs->super->s_uuid,
-+                         &jsb->s_users[i*16], 16) == 0)
-+                      break;
-+      }
-+      if (i >= nr_users) {
-+              memcpy(&jsb->s_users[nr_users*16],
-+                     fs->super->s_uuid, 16);
-+              jsb->s_nr_users = htonl(nr_users+1);
-+      }
-+
-+      /* Writeback the journal superblock */
-+      if ((retval = io_channel_write_blk(journal_dev->io, start, -1024, buf)))
-+              return retval;
-+      
-+      fs->super->s_journal_inum = 0;
-+      fs->super->s_journal_dev = st.st_rdev;
-+      memcpy(fs->super->s_journal_uuid, jsb->s_uuid,
-+             sizeof(fs->super->s_journal_uuid));
-+      fs->super->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
-+      ext2fs_mark_super_dirty(fs);
-+      return 0;
-+}
-+
-+/*
-+ * This function adds a journal inode to a filesystem, using either
-+ * POSIX routines if the filesystem is mounted, or using direct I/O
-+ * functions if it is not.
-+ */
-+errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t size, int flags)
-+{
-+      errcode_t               retval;
-+      ext2_ino_t              journal_ino;
-+      struct stat             st;
-+      char                    jfile[1024];
-+      int                     fd, mount_flags, f;
-+
-+      if ((retval = ext2fs_check_mount_point(fs->device_name, &mount_flags,
-+                                             jfile, sizeof(jfile)-10)))
-+              return retval;
-+
-+      if (mount_flags & EXT2_MF_MOUNTED) {
-+              strcat(jfile, "/.journal");
-+
-+              /*
-+               * If .../.journal already exists, make sure any 
-+               * immutable or append-only flags are cleared.
-+               */
-+#if defined(HAVE_CHFLAGS) && defined(UF_NODUMP)
-+              (void) chflags (jfile, 0);
-+#else
-+#if HAVE_EXT2_IOCTLS
-+              fd = open(jfile, O_RDONLY);
-+              if (fd >= 0) {
-+                      f = 0;
-+                      ioctl(fd, EXT2_IOC_SETFLAGS, &f);
-+                      close(fd);
-+              }
-+#endif
-+#endif
-+
-+              /* Create the journal file */
-+              if ((fd = open(jfile, O_CREAT|O_WRONLY, 0600)) < 0)
-+                      return errno;
-+
-+              if ((retval = write_journal_file(fs, jfile, size, flags)))
-+                      goto errout;
-+              
-+              /* Get inode number of the journal file */
-+              if (fstat(fd, &st) < 0)
-+                      goto errout;
-+
-+#if defined(HAVE_CHFLAGS) && defined(UF_NODUMP)
-+              retval = fchflags (fd, UF_NODUMP|UF_IMMUTABLE);
-+#else
-+#if HAVE_EXT2_IOCTLS
-+              f = EXT2_NODUMP_FL | EXT2_IMMUTABLE_FL;
-+              retval = ioctl(fd, EXT2_IOC_SETFLAGS, &f);
-+#endif
-+#endif
-+              if (retval)
-+                      goto errout;
-+              
-+              close(fd);
-+              journal_ino = st.st_ino;
-+      } else {
-+              journal_ino = EXT2_JOURNAL_INO;
-+              if ((retval = write_journal_inode(fs, journal_ino,
-+                                                size, flags)))
-+                      return retval;
-+      }
-+      
-+      fs->super->s_journal_inum = journal_ino;
-+      fs->super->s_journal_dev = 0;
-+      memset(fs->super->s_journal_uuid, 0,
-+             sizeof(fs->super->s_journal_uuid));
-+      fs->super->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL;
-+
-+      ext2fs_mark_super_dirty(fs);
-+      return 0;
-+errout:
-+      close(fd);
-+      return retval;
-+}
-+
-+#ifdef DEBUG
-+main(int argc, char **argv)
-+{
-+      errcode_t       retval;
-+      char            *device_name;
-+      ext2_filsys     fs;
-+
-+      if (argc < 2) {
-+              fprintf(stderr, "Usage: %s filesystem\n", argv[0]);
-+              exit(1);
-+      }
-+      device_name = argv[1];
-+      
-+      retval = ext2fs_open (device_name, EXT2_FLAG_RW, 0, 0,
-+                            unix_io_manager, &fs);
-+      if (retval) {
-+              com_err(argv[0], retval, "while opening %s", device_name);
-+              exit(1);
-+      }
-+
-+      retval = ext2fs_add_journal_inode(fs, 1024);
-+      if (retval) {
-+              com_err(argv[0], retval, "while adding journal to %s",
-+                      device_name);
-+              exit(1);
-+      }
-+      retval = ext2fs_flush(fs);
-+      if (retval) {
-+              printf("Warning, had trouble writing out superblocks.\n");
-+      }
-+      ext2fs_close(fs);
-+      exit(0);
-+      
-+}
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/namei.c busybox/e2fsprogs/ext2fs/namei.c
---- busybox-1.00/e2fsprogs/ext2fs/namei.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/namei.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,205 @@
-+/*
-+ * namei.c --- ext2fs directory lookup operations
-+ * 
-+ * Copyright (C) 1993, 1994, 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+/* #define NAMEI_DEBUG */
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+static errcode_t open_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t base,
-+                          const char *pathname, size_t pathlen, int follow,
-+                          int link_count, char *buf, ext2_ino_t *res_inode);
-+
-+static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
-+                           ext2_ino_t inode, int link_count,
-+                           char *buf, ext2_ino_t *res_inode)
-+{
-+      char *pathname;
-+      char *buffer = 0;
-+      errcode_t retval;
-+      struct ext2_inode ei;
-+
-+#ifdef NAMEI_DEBUG
-+      printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
-+             root, dir, inode, link_count);
-+      
-+#endif
-+      retval = ext2fs_read_inode (fs, inode, &ei);
-+      if (retval) return retval;
-+      if (!LINUX_S_ISLNK (ei.i_mode)) {
-+              *res_inode = inode;
-+              return 0;
-+      }
-+      if (link_count++ > 5) {
-+              return EXT2_ET_SYMLINK_LOOP;
-+      }
-+      if (ext2fs_inode_data_blocks(fs,&ei)) {
-+              retval = ext2fs_get_mem(fs->blocksize, &buffer);
-+              if (retval)
-+                      return retval;
-+              retval = io_channel_read_blk(fs->io, ei.i_block[0], 1, buffer);
-+              if (retval) {
-+                      ext2fs_free_mem(&buffer);
-+                      return retval;
-+              }
-+              pathname = buffer;
-+      } else
-+              pathname = (char *)&(ei.i_block[0]);
-+      retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
-+                          link_count, buf, res_inode);
-+      if (buffer)
-+              ext2fs_free_mem(&buffer);
-+      return retval;
-+}
-+
-+/*
-+ * This routine interprets a pathname in the context of the current
-+ * directory and the root directory, and returns the inode of the
-+ * containing directory, and a pointer to the filename of the file
-+ * (pointing into the pathname) and the length of the filename.
-+ */
-+static errcode_t dir_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
-+                         const char *pathname, int pathlen,
-+                         int link_count, char *buf,
-+                         const char **name, int *namelen,
-+                         ext2_ino_t *res_inode)
-+{
-+      char c;
-+      const char *thisname;
-+      int len;
-+      ext2_ino_t inode;
-+      errcode_t retval;
-+
-+      if ((c = *pathname) == '/') {
-+              dir = root;
-+              pathname++;
-+              pathlen--;
-+      }
-+      while (1) {
-+              thisname = pathname;
-+              for (len=0; --pathlen >= 0;len++) {
-+                      c = *(pathname++);
-+                      if (c == '/')
-+                              break;
-+              }
-+              if (pathlen < 0)
-+                      break;
-+              retval = ext2fs_lookup (fs, dir, thisname, len, buf, &inode);
-+              if (retval) return retval;
-+              retval = follow_link (fs, root, dir, inode,
-+                                    link_count, buf, &dir);
-+              if (retval) return retval;
-+      }
-+      *name = thisname;
-+      *namelen = len;
-+      *res_inode = dir;
-+      return 0;
-+}
-+
-+static errcode_t open_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t base,
-+                          const char *pathname, size_t pathlen, int follow,
-+                          int link_count, char *buf, ext2_ino_t *res_inode)
-+{
-+      const char *basename;
-+      int namelen;
-+      ext2_ino_t dir, inode;
-+      errcode_t retval;
-+
-+#ifdef NAMEI_DEBUG
-+      printf("open_namei: root=%lu, dir=%lu, path=%*s, lc=%d\n",
-+             root, base, pathlen, pathname, link_count);
-+#endif
-+      retval = dir_namei(fs, root, base, pathname, pathlen,
-+                         link_count, buf, &basename, &namelen, &dir);
-+      if (retval) return retval;
-+      if (!namelen) {                     /* special case: '/usr/' etc */
-+              *res_inode=dir;
-+              return 0;
-+      }
-+      retval = ext2fs_lookup (fs, dir, basename, namelen, buf, &inode);
-+      if (retval)
-+              return retval;
-+      if (follow) {
-+              retval = follow_link(fs, root, dir, inode, link_count,
-+                                   buf, &inode);
-+              if (retval)
-+                      return retval;
-+      }
-+#ifdef NAMEI_DEBUG
-+      printf("open_namei: (link_count=%d) returns %lu\n",
-+             link_count, inode);
-+#endif
-+      *res_inode = inode;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_namei(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+                     const char *name, ext2_ino_t *inode)
-+{
-+      char *buf;
-+      errcode_t retval;
-+      
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      retval = ext2fs_get_mem(fs->blocksize, &buf);
-+      if (retval)
-+              return retval;
-+      
-+      retval = open_namei(fs, root, cwd, name, strlen(name), 0, 0,
-+                          buf, inode);
-+
-+      ext2fs_free_mem(&buf);
-+      return retval;
-+}
-+
-+errcode_t ext2fs_namei_follow(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+                            const char *name, ext2_ino_t *inode)
-+{
-+      char *buf;
-+      errcode_t retval;
-+      
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      retval = ext2fs_get_mem(fs->blocksize, &buf);
-+      if (retval)
-+              return retval;
-+      
-+      retval = open_namei(fs, root, cwd, name, strlen(name), 1, 0,
-+                          buf, inode);
-+
-+      ext2fs_free_mem(&buf);
-+      return retval;
-+}
-+
-+errcode_t ext2fs_follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t cwd,
-+                      ext2_ino_t inode, ext2_ino_t *res_inode)
-+{
-+      char *buf;
-+      errcode_t retval;
-+      
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      retval = ext2fs_get_mem(fs->blocksize, &buf);
-+      if (retval)
-+              return retval;
-+
-+      retval = follow_link(fs, root, cwd, inode, 0, buf, res_inode);
-+
-+      ext2fs_free_mem(&buf);
-+      return retval;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/native.c busybox/e2fsprogs/ext2fs/native.c
---- busybox-1.00/e2fsprogs/ext2fs/native.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/native.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,27 @@
-+/*
-+ * native.c --- returns the ext2_flag for a native byte order
-+ * 
-+ * Copyright (C) 1996 Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+int ext2fs_native_flag(void)
-+{
-+#ifdef WORDS_BIGENDIAN
-+      return EXT2_FLAG_SWAP_BYTES;
-+#else
-+      return 0;
-+#endif
-+}
-+
-+      
-+      
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/newdir.c busybox/e2fsprogs/ext2fs/newdir.c
---- busybox-1.00/e2fsprogs/ext2fs/newdir.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/newdir.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,72 @@
-+/*
-+ * newdir.c --- create a new directory block
-+ * 
-+ * Copyright (C) 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+#ifndef EXT2_FT_DIR
-+#define EXT2_FT_DIR           2
-+#endif
-+
-+/*
-+ * Create new directory block
-+ */
-+errcode_t ext2fs_new_dir_block(ext2_filsys fs, ext2_ino_t dir_ino,
-+                             ext2_ino_t parent_ino, char **block)
-+{
-+      struct ext2_dir_entry   *dir = NULL;
-+      errcode_t               retval;
-+      char                    *buf;
-+      int                     rec_len;
-+      int                     filetype = 0;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      retval = ext2fs_get_mem(fs->blocksize, &buf);
-+      if (retval)
-+              return retval;
-+      memset(buf, 0, fs->blocksize);
-+      dir = (struct ext2_dir_entry *) buf;
-+      dir->rec_len = fs->blocksize;
-+
-+      if (dir_ino) {
-+              if (fs->super->s_feature_incompat &
-+                  EXT2_FEATURE_INCOMPAT_FILETYPE)
-+                      filetype = EXT2_FT_DIR << 8;
-+              /*
-+               * Set up entry for '.'
-+               */
-+              dir->inode = dir_ino;
-+              dir->name_len = 1 | filetype;
-+              dir->name[0] = '.';
-+              rec_len = dir->rec_len - EXT2_DIR_REC_LEN(1);
-+              dir->rec_len = EXT2_DIR_REC_LEN(1);
-+
-+              /*
-+               * Set up entry for '..'
-+               */
-+              dir = (struct ext2_dir_entry *) (buf + dir->rec_len);
-+              dir->rec_len = rec_len;
-+              dir->inode = parent_ino;
-+              dir->name_len = 2 | filetype;
-+              dir->name[0] = '.';
-+              dir->name[1] = '.';
-+              
-+      }
-+      *block = buf;
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/openfs.c busybox/e2fsprogs/ext2fs/openfs.c
---- busybox-1.00/e2fsprogs/ext2fs/openfs.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/openfs.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,326 @@
-+/*
-+ * openfs.c --- open an ext2 filesystem
-+ * 
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+
-+
-+#include "ext2fs.h"
-+#include "e2image.h"
-+
-+blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, dgrp_t i)
-+{
-+      int     bg;
-+      int     has_super = 0;
-+      int     ret_blk;
-+
-+      if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
-+          (i < fs->super->s_first_meta_bg))
-+              return (group_block + i + 1);
-+
-+      bg = (fs->blocksize / sizeof (struct ext2_group_desc)) * i;
-+      if (ext2fs_bg_has_super(fs, bg))
-+              has_super = 1;
-+      ret_blk = (fs->super->s_first_data_block + has_super + 
-+                 (bg * fs->super->s_blocks_per_group));
-+      /*
-+       * If group_block is not the normal value, we're trying to use
-+       * the backup group descriptors and superblock --- so use the
-+       * alternate location of the second block group in the
-+       * metablock group.  Ideally we should be testing each bg
-+       * descriptor block individually for correctness, but we don't
-+       * have the infrastructure in place to do that.
-+       */
-+      if (group_block != fs->super->s_first_data_block &&
-+          ((ret_blk + fs->super->s_blocks_per_group) <
-+           fs->super->s_blocks_count))
-+              ret_blk += fs->super->s_blocks_per_group;
-+      return ret_blk;
-+}
-+
-+errcode_t ext2fs_open(const char *name, int flags, int superblock,
-+                    unsigned int block_size, io_manager manager, 
-+                    ext2_filsys *ret_fs)
-+{
-+      return ext2fs_open2(name, 0, flags, superblock, block_size, 
-+                          manager, ret_fs);
-+}
-+
-+/*
-+ *  Note: if superblock is non-zero, block-size must also be non-zero.
-+ *    Superblock and block_size can be zero to use the default size.
-+ *
-+ * Valid flags for ext2fs_open()
-+ * 
-+ *    EXT2_FLAG_RW    - Open the filesystem for read/write.
-+ *    EXT2_FLAG_FORCE - Open the filesystem even if some of the
-+ *                            features aren't supported.
-+ *    EXT2_FLAG_JOURNAL_DEV_OK - Open an ext3 journal device
-+ */
-+errcode_t ext2fs_open2(const char *name, const char *io_options,
-+                     int flags, int superblock,
-+                     unsigned int block_size, io_manager manager, 
-+                     ext2_filsys *ret_fs)
-+{
-+      ext2_filsys     fs;
-+      errcode_t       retval;
-+      unsigned long   i;
-+      int             j, groups_per_block, blocks_per_group;
-+      blk_t           group_block, blk;
-+      char            *dest, *cp;
-+      struct ext2_group_desc *gdp;
-+      
-+      EXT2_CHECK_MAGIC(manager, EXT2_ET_MAGIC_IO_MANAGER);
-+
-+      retval = ext2fs_get_mem(sizeof(struct struct_ext2_filsys), &fs);
-+      if (retval)
-+              return retval;
-+      
-+      memset(fs, 0, sizeof(struct struct_ext2_filsys));
-+      fs->magic = EXT2_ET_MAGIC_EXT2FS_FILSYS;
-+      fs->flags = flags;
-+      fs->umask = 022;
-+      retval = ext2fs_get_mem(strlen(name)+1, &fs->device_name);
-+      if (retval)
-+              goto cleanup;
-+      strcpy(fs->device_name, name);
-+      cp = strchr(fs->device_name, '?');
-+      if (!io_options && cp) {
-+              *cp++ = 0;
-+              io_options = cp;
-+      }
-+              
-+      retval = manager->open(fs->device_name, 
-+                             (flags & EXT2_FLAG_RW) ? IO_FLAG_RW : 0,
-+                             &fs->io);
-+      if (retval)
-+              goto cleanup;
-+      if (io_options && 
-+          (retval = io_channel_set_options(fs->io, io_options)))
-+              goto cleanup;
-+      fs->image_io = fs->io;
-+      fs->io->app_data = fs;
-+      retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->super);
-+      if (retval)
-+              goto cleanup;
-+      if (flags & EXT2_FLAG_IMAGE_FILE) {
-+              retval = ext2fs_get_mem(sizeof(struct ext2_image_hdr),
-+                                      &fs->image_header);
-+              if (retval)
-+                      goto cleanup;
-+              retval = io_channel_read_blk(fs->io, 0,
-+                                           -(int)sizeof(struct ext2_image_hdr),
-+                                           fs->image_header);
-+              if (retval)
-+                      goto cleanup;
-+              if (fs->image_header->magic_number != EXT2_ET_MAGIC_E2IMAGE)
-+                      return EXT2_ET_MAGIC_E2IMAGE;
-+              superblock = 1;
-+              block_size = fs->image_header->fs_blocksize;
-+      }
-+
-+      /*
-+       * If the user specifies a specific block # for the
-+       * superblock, then he/she must also specify the block size!
-+       * Otherwise, read the master superblock located at offset
-+       * SUPERBLOCK_OFFSET from the start of the partition.
-+       *
-+       * Note: we only save a backup copy of the superblock if we
-+       * are reading the superblock from the primary superblock location.
-+       */
-+      if (superblock) {
-+              if (!block_size) {
-+                      retval = EXT2_ET_INVALID_ARGUMENT;
-+                      goto cleanup;
-+              }
-+              io_channel_set_blksize(fs->io, block_size);
-+              group_block = superblock;
-+              fs->orig_super = 0;
-+      } else {
-+              io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET);
-+              superblock = 1;
-+              group_block = 0;
-+              retval = ext2fs_get_mem(SUPERBLOCK_SIZE, &fs->orig_super);
-+              if (retval)
-+                      goto cleanup;
-+      }
-+      retval = io_channel_read_blk(fs->io, superblock, -SUPERBLOCK_SIZE,
-+                                   fs->super);
-+      if (retval)
-+              goto cleanup;
-+      if (fs->orig_super)
-+              memcpy(fs->orig_super, fs->super, SUPERBLOCK_SIZE);
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+      if ((fs->super->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) ||
-+          (fs->flags & EXT2_FLAG_SWAP_BYTES)) {
-+              fs->flags |= EXT2_FLAG_SWAP_BYTES;
-+
-+              ext2fs_swap_super(fs->super);
-+      }
-+#endif
-+      
-+      if (fs->super->s_magic != EXT2_SUPER_MAGIC) {
-+              retval = EXT2_ET_BAD_MAGIC;
-+              goto cleanup;
-+      }
-+      if (fs->super->s_rev_level > EXT2_LIB_CURRENT_REV) {
-+              retval = EXT2_ET_REV_TOO_HIGH;
-+              goto cleanup;
-+      }
-+
-+      /*
-+       * Check for feature set incompatibility
-+       */
-+      if (!(flags & EXT2_FLAG_FORCE)) {
-+              if (fs->super->s_feature_incompat &
-+                  ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
-+                      retval = EXT2_ET_UNSUPP_FEATURE;
-+                      goto cleanup;
-+              }
-+              if ((flags & EXT2_FLAG_RW) &&
-+                  (fs->super->s_feature_ro_compat &
-+                   ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP)) {
-+                      retval = EXT2_ET_RO_UNSUPP_FEATURE;
-+                      goto cleanup;
-+              }
-+              if (!(flags & EXT2_FLAG_JOURNAL_DEV_OK) &&
-+                  (fs->super->s_feature_incompat &
-+                   EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) {
-+                      retval = EXT2_ET_UNSUPP_FEATURE;
-+                      goto cleanup;
-+              }
-+      }
-+      
-+      fs->blocksize = EXT2_BLOCK_SIZE(fs->super);
-+      if (fs->blocksize == 0) {
-+              retval = EXT2_ET_CORRUPT_SUPERBLOCK;
-+              goto cleanup;
-+      }
-+      fs->fragsize = EXT2_FRAG_SIZE(fs->super);
-+      fs->inode_blocks_per_group = ((fs->super->s_inodes_per_group *
-+                                     EXT2_INODE_SIZE(fs->super) +
-+                                     EXT2_BLOCK_SIZE(fs->super) - 1) /
-+                                    EXT2_BLOCK_SIZE(fs->super));
-+      if (block_size) {
-+              if (block_size != fs->blocksize) {
-+                      retval = EXT2_ET_UNEXPECTED_BLOCK_SIZE;
-+                      goto cleanup;
-+              }
-+      }
-+      /*
-+       * Set the blocksize to the filesystem's blocksize.
-+       */
-+      io_channel_set_blksize(fs->io, fs->blocksize);
-+
-+      /*
-+       * If this is an external journal device, don't try to read
-+       * the group descriptors, because they're not there.
-+       */
-+      if (fs->super->s_feature_incompat &
-+          EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) {
-+              fs->group_desc_count = 0;
-+              *ret_fs = fs;
-+              return 0;
-+      }
-+      
-+      /*
-+       * Read group descriptors
-+       */
-+      blocks_per_group = EXT2_BLOCKS_PER_GROUP(fs->super);
-+      if (blocks_per_group == 0 ||
-+          blocks_per_group > EXT2_MAX_BLOCKS_PER_GROUP(fs->super) ||
-+          fs->inode_blocks_per_group > EXT2_MAX_INODES_PER_GROUP(fs->super)) {
-+              retval = EXT2_ET_CORRUPT_SUPERBLOCK;
-+              goto cleanup;
-+      }
-+      fs->group_desc_count = (fs->super->s_blocks_count -
-+                              fs->super->s_first_data_block +
-+                              blocks_per_group - 1) / blocks_per_group;
-+      fs->desc_blocks = (fs->group_desc_count +
-+                         EXT2_DESC_PER_BLOCK(fs->super) - 1)
-+              / EXT2_DESC_PER_BLOCK(fs->super);
-+      retval = ext2fs_get_mem(fs->desc_blocks * fs->blocksize,
-+                              &fs->group_desc);
-+      if (retval)
-+              goto cleanup;
-+      if (!group_block)
-+              group_block = fs->super->s_first_data_block;
-+      dest = (char *) fs->group_desc;
-+      groups_per_block = fs->blocksize / sizeof(struct ext2_group_desc);
-+      for (i=0 ; i < fs->desc_blocks; i++) {
-+              blk = ext2fs_descriptor_block_loc(fs, group_block, i);
-+              retval = io_channel_read_blk(fs->io, blk, 1, dest);
-+              if (retval)
-+                      goto cleanup;
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+              if (fs->flags & EXT2_FLAG_SWAP_BYTES) {
-+                      gdp = (struct ext2_group_desc *) dest;
-+                      for (j=0; j < groups_per_block; j++)
-+                              ext2fs_swap_group_desc(gdp++);
-+              }
-+#endif
-+              dest += fs->blocksize;
-+      }
-+
-+      *ret_fs = fs;
-+      return 0;
-+cleanup:
-+      ext2fs_free(fs);
-+      return retval;
-+}
-+
-+/*
-+ * Set/get the filesystem data I/O channel.
-+ * 
-+ * These functions are only valid if EXT2_FLAG_IMAGE_FILE is true.
-+ */
-+errcode_t ext2fs_get_data_io(ext2_filsys fs, io_channel *old_io)
-+{
-+      if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
-+              return EXT2_ET_NOT_IMAGE_FILE;
-+      if (old_io) {
-+              *old_io = (fs->image_io == fs->io) ? 0 : fs->io;
-+      }
-+      return 0;
-+}
-+
-+errcode_t ext2fs_set_data_io(ext2_filsys fs, io_channel new_io)
-+{
-+      if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
-+              return EXT2_ET_NOT_IMAGE_FILE;
-+      fs->io = new_io ? new_io : fs->image_io;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_rewrite_to_io(ext2_filsys fs, io_channel new_io)
-+{
-+      if ((fs->flags & EXT2_FLAG_IMAGE_FILE) == 0)
-+              return EXT2_ET_NOT_IMAGE_FILE;
-+      fs->io = fs->image_io = new_io;
-+      fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_RW | 
-+              EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY;
-+      fs->flags &= ~EXT2_FLAG_IMAGE_FILE;
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/read_bb.c busybox/e2fsprogs/ext2fs/read_bb.c
---- busybox-1.00/e2fsprogs/ext2fs/read_bb.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/read_bb.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,97 @@
-+/*
-+ * read_bb --- read the bad blocks inode
-+ *
-+ * Copyright (C) 1994 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct read_bb_record {
-+      ext2_badblocks_list     bb_list;
-+      errcode_t       err;
-+};
-+
-+/*
-+ * Helper function for ext2fs_read_bb_inode()
-+ */
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int mark_bad_block(ext2_filsys fs, blk_t *block_nr,
-+                        e2_blkcnt_t blockcnt EXT2FS_ATTR((unused)), 
-+                        blk_t ref_block EXT2FS_ATTR((unused)),
-+                        int ref_offset EXT2FS_ATTR((unused)), 
-+                        void *priv_data)
-+{
-+      struct read_bb_record *rb = (struct read_bb_record *) priv_data;
-+      
-+      if (blockcnt < 0)
-+              return 0;
-+      
-+      if ((*block_nr < fs->super->s_first_data_block) ||
-+          (*block_nr >= fs->super->s_blocks_count))
-+              return 0;       /* Ignore illegal blocks */
-+
-+      rb->err = ext2fs_badblocks_list_add(rb->bb_list, *block_nr);
-+      if (rb->err)
-+              return BLOCK_ABORT;
-+      return 0;
-+}
-+
-+/*
-+ * Reads the current bad blocks from the bad blocks inode.
-+ */
-+errcode_t ext2fs_read_bb_inode(ext2_filsys fs, ext2_badblocks_list *bb_list)
-+{
-+      errcode_t       retval;
-+      struct read_bb_record rb;
-+      struct ext2_inode inode;
-+      blk_t   numblocks;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (!*bb_list) {
-+              retval = ext2fs_read_inode(fs, EXT2_BAD_INO, &inode);
-+              if (retval)
-+                      return retval;
-+              if (inode.i_blocks < 500)
-+                      numblocks = (inode.i_blocks /
-+                                   (fs->blocksize / 512)) + 20;
-+              else
-+                      numblocks = 500;
-+              retval = ext2fs_badblocks_list_create(bb_list, numblocks);
-+              if (retval)
-+                      return retval;
-+      }
-+
-+      rb.bb_list = *bb_list;
-+      rb.err = 0;
-+      retval = ext2fs_block_iterate2(fs, EXT2_BAD_INO, 0, 0,
-+                                    mark_bad_block, &rb);
-+      if (retval)
-+              return retval;
-+
-+      return rb.err;
-+}
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/read_bb_file.c busybox/e2fsprogs/ext2fs/read_bb_file.c
---- busybox-1.00/e2fsprogs/ext2fs/read_bb_file.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/read_bb_file.c    2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,97 @@
-+/*
-+ * read_bb_file.c --- read a list of bad blocks from a FILE *
-+ *
-+ * Copyright (C) 1994, 1995, 2000 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * Reads a list of bad blocks from  a FILE *
-+ */
-+errcode_t ext2fs_read_bb_FILE2(ext2_filsys fs, FILE *f, 
-+                             ext2_badblocks_list *bb_list,
-+                             void *priv_data,
-+                             void (*invalid)(ext2_filsys fs,
-+                                             blk_t blk,
-+                                             char *badstr,
-+                                             void *priv_data))
-+{
-+      errcode_t       retval;
-+      blk_t           blockno;
-+      int             count;
-+      char            buf[128];
-+
-+      if (fs)
-+              EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (!*bb_list) {
-+              retval = ext2fs_badblocks_list_create(bb_list, 10);
-+              if (retval)
-+                      return retval;
-+      }
-+
-+      while (!feof (f)) {
-+              if (fgets(buf, sizeof(buf), f) == NULL)
-+                      break;
-+              count = sscanf(buf, "%u", &blockno);
-+              if (count <= 0)
-+                      continue;
-+              if (fs &&
-+                  ((blockno < fs->super->s_first_data_block) ||
-+                  (blockno >= fs->super->s_blocks_count))) {
-+                      if (invalid)
-+                              (invalid)(fs, blockno, buf, priv_data);
-+                      continue;
-+              }
-+              retval = ext2fs_badblocks_list_add(*bb_list, blockno);
-+              if (retval)
-+                      return retval;
-+      }
-+      return 0;
-+}
-+
-+static void call_compat_invalid(ext2_filsys fs, blk_t blk,
-+                              char *badstr EXT2FS_ATTR((unused)), 
-+                              void *priv_data)
-+{
-+      void (*invalid)(ext2_filsys, blk_t);
-+
-+      invalid = (void (*)(ext2_filsys, blk_t)) priv_data;
-+      if (invalid)
-+              invalid(fs, blk);
-+}
-+
-+
-+/*
-+ * Reads a list of bad blocks from  a FILE *
-+ */
-+errcode_t ext2fs_read_bb_FILE(ext2_filsys fs, FILE *f, 
-+                            ext2_badblocks_list *bb_list,
-+                            void (*invalid)(ext2_filsys fs, blk_t blk))
-+{
-+      return ext2fs_read_bb_FILE2(fs, f, bb_list, (void *) invalid,
-+                                  call_compat_invalid);
-+}
-+
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/res_gdt.c busybox/e2fsprogs/ext2fs/res_gdt.c
---- busybox-1.00/e2fsprogs/ext2fs/res_gdt.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/res_gdt.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,220 @@
-+/*
-+ * res_gdt.c --- reserve blocks for growing the group descriptor table
-+ *               during online resizing.
-+ *
-+ * Copyright (C) 2002 Andreas Dilger
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <time.h>
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * Iterate through the groups which hold BACKUP superblock/GDT copies in an
-+ * ext3 filesystem.  The counters should be initialized to 1, 5, and 7 before
-+ * calling this for the first time.  In a sparse filesystem it will be the
-+ * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
-+ * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
-+ */
-+static unsigned int list_backups(ext2_filsys fs, unsigned int *three,
-+                               unsigned int *five, unsigned int *seven)
-+{
-+      unsigned int *min = three;
-+      int mult = 3;
-+      unsigned int ret;
-+
-+      if (!(fs->super->s_feature_ro_compat &
-+            EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
-+              ret = *min;
-+              *min += 1;
-+              return ret;
-+      }
-+
-+      if (*five < *min) {
-+              min = five;
-+              mult = 5;
-+      }
-+      if (*seven < *min) {
-+              min = seven;
-+              mult = 7;
-+      }
-+
-+      ret = *min;
-+      *min *= mult;
-+
-+      return ret;
-+}
-+
-+/*
-+ * This code assumes that the reserved blocks have already been marked in-use
-+ * during ext2fs_initialize(), so that they are not allocated for other
-+ * uses before we can add them to the resize inode (which has to come
-+ * after the creation of the inode table).
-+ */
-+errcode_t ext2fs_create_resize_inode(ext2_filsys fs)
-+{
-+      errcode_t               retval, retval2;
-+      struct ext2_super_block *sb;
-+      struct ext2_inode       inode;
-+      __u32                   *dindir_buf, *gdt_buf;
-+      int                     rsv_add;
-+      unsigned long long      apb, inode_size;
-+      blk_t                   dindir_blk, rsv_off, gdt_off, gdt_blk;
-+      int                     dindir_dirty = 0, inode_dirty = 0;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      sb = fs->super;
-+
-+      retval = ext2fs_get_mem(2 * fs->blocksize, (void **)&dindir_buf);
-+      if (retval)
-+              goto out_free;
-+      gdt_buf = (__u32 *)((char *)dindir_buf + fs->blocksize);
-+
-+      retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode);
-+      if (retval)
-+              goto out_free;
-+
-+      /* Maximum possible file size (we donly use the dindirect blocks) */
-+      apb = EXT2_ADDR_PER_BLOCK(sb);
-+      rsv_add = fs->blocksize / 512;
-+      if ((dindir_blk = inode.i_block[EXT2_DIND_BLOCK])) {
-+#ifdef RES_GDT_DEBUG
-+              printf("reading GDT dindir %u\n", dindir_blk);
-+#endif
-+              retval = ext2fs_read_ind_block(fs, dindir_blk, dindir_buf);
-+              if (retval)
-+                      goto out_inode;
-+      } else {
-+              blk_t goal = 3 + sb->s_reserved_gdt_blocks +
-+                      fs->desc_blocks + fs->inode_blocks_per_group;
-+
-+              retval = ext2fs_alloc_block(fs, goal, 0, &dindir_blk);
-+              if (retval)
-+                      goto out_free;
-+              inode.i_mode = LINUX_S_IFREG | 0600;
-+              inode.i_links_count = 1;
-+              inode.i_block[EXT2_DIND_BLOCK] = dindir_blk;
-+              inode.i_blocks = rsv_add;
-+              memset(dindir_buf, 0, fs->blocksize);
-+#ifdef RES_GDT_DEBUG
-+              printf("allocated GDT dindir %u\n", dindir_blk);
-+#endif
-+              dindir_dirty = inode_dirty = 1;
-+              inode_size = apb*apb + apb + EXT2_NDIR_BLOCKS;
-+              inode_size *= fs->blocksize;
-+              inode.i_size = inode_size & 0xFFFFFFFF;
-+              inode.i_size_high = (inode_size >> 32) & 0xFFFFFFFF;
-+              if(inode.i_size_high) {
-+                      sb->s_feature_ro_compat |=
-+                              EXT2_FEATURE_RO_COMPAT_LARGE_FILE;
-+              }
-+              inode.i_ctime = time(0);
-+      }
-+
-+      for (rsv_off = 0, gdt_off = fs->desc_blocks,
-+           gdt_blk = sb->s_first_data_block + 1 + fs->desc_blocks;
-+           rsv_off < sb->s_reserved_gdt_blocks;
-+           rsv_off++, gdt_off++, gdt_blk++) {
-+              unsigned int three = 1, five = 5, seven = 7;
-+              unsigned int grp, last = 0;
-+              int gdt_dirty = 0;
-+
-+              gdt_off %= apb;
-+              if (!dindir_buf[gdt_off]) {
-+                      /* FIXME XXX XXX
-+                      blk_t new_blk;
-+
-+                      retval = ext2fs_new_block(fs, gdt_blk, 0, &new_blk);
-+                      if (retval)
-+                              goto out_free;
-+                      if (new_blk != gdt_blk) {
-+                              // XXX free block
-+                              retval = -1; // XXX
-+                      }
-+                      */
-+                      gdt_dirty = dindir_dirty = inode_dirty = 1;
-+                      memset(gdt_buf, 0, fs->blocksize);
-+                      dindir_buf[gdt_off] = gdt_blk;
-+                      inode.i_blocks += rsv_add;
-+#ifdef RES_GDT_DEBUG
-+                      printf("added primary GDT block %u at %u[%u]\n",
-+                             gdt_blk, dindir_blk, gdt_off);
-+#endif
-+              } else if (dindir_buf[gdt_off] == gdt_blk) {
-+#ifdef RES_GDT_DEBUG
-+                      printf("reading primary GDT block %u\n", gdt_blk);
-+#endif
-+                      retval = ext2fs_read_ind_block(fs, gdt_blk, gdt_buf);
-+                      if (retval)
-+                              goto out_dindir;
-+              } else {
-+#ifdef RES_GDT_DEBUG
-+                      printf("bad primary GDT %u != %u at %u[%u]\n",
-+                             dindir_buf[gdt_off], gdt_blk,dindir_blk,gdt_off);
-+#endif
-+                      retval = EXT2_ET_RESIZE_INODE_CORRUPT;
-+                      goto out_dindir;
-+              }
-+
-+              while ((grp = list_backups(fs, &three, &five, &seven)) <
-+                     fs->group_desc_count) {
-+                      blk_t expect = gdt_blk + grp * sb->s_blocks_per_group;
-+
-+                      if (!gdt_buf[last]) {
-+#ifdef RES_GDT_DEBUG
-+                              printf("added backup GDT %u grp %u@%u[%u]\n",
-+                                     expect, grp, gdt_blk, last);
-+#endif
-+                              gdt_buf[last] = expect;
-+                              inode.i_blocks += rsv_add;
-+                              gdt_dirty = inode_dirty = 1;
-+                      } else if (gdt_buf[last] != expect) {
-+#ifdef RES_GDT_DEBUG
-+                              printf("bad backup GDT %u != %u at %u[%u]\n",
-+                                     gdt_buf[last], expect, gdt_blk, last);
-+#endif
-+                              retval = EXT2_ET_RESIZE_INODE_CORRUPT;
-+                              goto out_dindir;
-+                      }
-+                      last++;
-+              }
-+              if (gdt_dirty) {
-+#ifdef RES_GDT_DEBUG
-+                      printf("writing primary GDT block %u\n", gdt_blk);
-+#endif
-+                      retval = ext2fs_write_ind_block(fs, gdt_blk, gdt_buf);
-+                      if (retval)
-+                              goto out_dindir;
-+              }
-+      }
-+
-+out_dindir:
-+      if (dindir_dirty) {
-+              retval2 = ext2fs_write_ind_block(fs, dindir_blk, dindir_buf);
-+              if (!retval)
-+                      retval = retval2;
-+      }
-+out_inode:
-+#ifdef RES_GDT_DEBUG
-+      printf("inode.i_blocks = %u, i_size = %u\n", inode.i_blocks,
-+             inode.i_size);
-+#endif
-+      if (inode_dirty) {
-+              inode.i_atime = inode.i_mtime = time(0);
-+              retval2 = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode);
-+              if (!retval)
-+                      retval = retval2;
-+      }
-+out_free:
-+      ext2fs_free_mem((void **)&dindir_buf);
-+      return retval;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/rs_bitmap.c busybox/e2fsprogs/ext2fs/rs_bitmap.c
---- busybox-1.00/e2fsprogs/ext2fs/rs_bitmap.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/rs_bitmap.c       2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,106 @@
-+/*
-+ * rs_bitmap.c --- routine for changing the size of a bitmap
-+ *
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_resize_generic_bitmap(__u32 new_end, __u32 new_real_end,
-+                                     ext2fs_generic_bitmap bmap)
-+{
-+      errcode_t       retval;
-+      size_t          size, new_size;
-+      __u32           bitno;
-+
-+      if (!bmap)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_GENERIC_BITMAP);
-+
-+      /*
-+       * If we're expanding the bitmap, make sure all of the new
-+       * parts of the bitmap are zero.
-+       */
-+      if (new_end > bmap->end) {
-+              bitno = bmap->real_end;
-+              if (bitno > new_end)
-+                      bitno = new_end;
-+              for (; bitno > bmap->end; bitno--)
-+                      ext2fs_clear_bit(bitno - bmap->start, bmap->bitmap);
-+      }
-+      if (new_real_end == bmap->real_end) {
-+              bmap->end = new_end;
-+              return 0;
-+      }
-+      
-+      size = ((bmap->real_end - bmap->start) / 8) + 1;
-+      new_size = ((new_real_end - bmap->start) / 8) + 1;
-+
-+      if (size != new_size) {
-+              retval = ext2fs_resize_mem(size, new_size, &bmap->bitmap);
-+              if (retval)
-+                      return retval;
-+      }
-+      if (new_size > size)
-+              memset(bmap->bitmap + size, 0, new_size - size);
-+
-+      bmap->end = new_end;
-+      bmap->real_end = new_real_end;
-+      return 0;
-+}
-+
-+errcode_t ext2fs_resize_inode_bitmap(__u32 new_end, __u32 new_real_end,
-+                                   ext2fs_inode_bitmap bmap)
-+{
-+      errcode_t       retval;
-+      
-+      if (!bmap)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_INODE_BITMAP);
-+
-+      bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
-+      retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
-+                                            bmap);
-+      bmap->magic = EXT2_ET_MAGIC_INODE_BITMAP;
-+      return retval;
-+}
-+
-+errcode_t ext2fs_resize_block_bitmap(__u32 new_end, __u32 new_real_end,
-+                                   ext2fs_block_bitmap bmap)
-+{
-+      errcode_t       retval;
-+      
-+      if (!bmap)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      EXT2_CHECK_MAGIC(bmap, EXT2_ET_MAGIC_BLOCK_BITMAP);
-+
-+      bmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
-+      retval = ext2fs_resize_generic_bitmap(new_end, new_real_end,
-+                                            bmap);
-+      bmap->magic = EXT2_ET_MAGIC_BLOCK_BITMAP;
-+      return retval;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/rw_bitmaps.c busybox/e2fsprogs/ext2fs/rw_bitmaps.c
---- busybox-1.00/e2fsprogs/ext2fs/rw_bitmaps.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/rw_bitmaps.c      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,300 @@
-+/*
-+ * rw_bitmaps.c --- routines to read and write the  inode and block bitmaps.
-+ *
-+ * Copyright (C) 1993, 1994, 1994, 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#ifdef HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#ifdef HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+#include "e2image.h"
-+
-+#if defined(__powerpc__) && defined(EXT2FS_ENABLE_SWAPFS)
-+/*
-+ * On the PowerPC, the big-endian variant of the ext2 filesystem
-+ * has its bitmaps stored as 32-bit words with bit 0 as the LSB
-+ * of each word.  Thus a bitmap with only bit 0 set would be, as
-+ * a string of bytes, 00 00 00 01 00 ...
-+ * To cope with this, we byte-reverse each word of a bitmap if
-+ * we have a big-endian filesystem, that is, if we are *not*
-+ * byte-swapping other word-sized numbers.
-+ */
-+#define EXT2_BIG_ENDIAN_BITMAPS
-+#endif
-+
-+#ifdef EXT2_BIG_ENDIAN_BITMAPS
-+static void ext2fs_swap_bitmap(ext2_filsys fs, char *bitmap, int nbytes)
-+{
-+      __u32 *p = (__u32 *) bitmap;
-+      int n;
-+              
-+      for (n = nbytes / sizeof(__u32); n > 0; --n, ++p)
-+              *p = ext2fs_swab32(*p);
-+}
-+#endif
-+
-+errcode_t ext2fs_write_inode_bitmap(ext2_filsys fs)
-+{
-+      dgrp_t          i;
-+      size_t          nbytes;
-+      errcode_t       retval;
-+      char * inode_bitmap = fs->inode_map->bitmap;
-+      char * bitmap_block = NULL;
-+      blk_t           blk;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (!(fs->flags & EXT2_FLAG_RW))
-+              return EXT2_ET_RO_FILSYS;
-+      if (!inode_bitmap)
-+              return 0;
-+      nbytes = (size_t) ((EXT2_INODES_PER_GROUP(fs->super)+7) / 8);
-+      
-+      retval = ext2fs_get_mem(fs->blocksize, &bitmap_block);
-+      if (retval)
-+              return retval;
-+      memset(bitmap_block, 0xff, fs->blocksize);
-+      for (i = 0; i < fs->group_desc_count; i++) {
-+              memcpy(bitmap_block, inode_bitmap, nbytes);
-+              blk = fs->group_desc[i].bg_inode_bitmap;
-+              if (blk) {
-+#ifdef EXT2_BIG_ENDIAN_BITMAPS
-+                      if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+                            (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
-+                              ext2fs_swap_bitmap(fs, bitmap_block, nbytes);
-+#endif
-+                      retval = io_channel_write_blk(fs->io, blk, 1,
-+                                                    bitmap_block);
-+                      if (retval)
-+                              return EXT2_ET_INODE_BITMAP_WRITE;
-+              }
-+              inode_bitmap += nbytes;
-+      }
-+      fs->flags &= ~EXT2_FLAG_IB_DIRTY;
-+      ext2fs_free_mem(&bitmap_block);
-+      return 0;
-+}
-+
-+errcode_t ext2fs_write_block_bitmap (ext2_filsys fs)
-+{
-+      dgrp_t          i;
-+      unsigned int    j;
-+      int             nbytes;
-+      unsigned int    nbits;
-+      errcode_t       retval;
-+      char * block_bitmap = fs->block_map->bitmap;
-+      char * bitmap_block = NULL;
-+      blk_t           blk;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (!(fs->flags & EXT2_FLAG_RW))
-+              return EXT2_ET_RO_FILSYS;
-+      if (!block_bitmap)
-+              return 0;
-+      nbytes = EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-+      retval = ext2fs_get_mem(fs->blocksize, &bitmap_block);
-+      if (retval)
-+              return retval;
-+      memset(bitmap_block, 0xff, fs->blocksize);
-+      for (i = 0; i < fs->group_desc_count; i++) {
-+              memcpy(bitmap_block, block_bitmap, nbytes);
-+              if (i == fs->group_desc_count - 1) {
-+                      /* Force bitmap padding for the last group */
-+                      nbits = ((fs->super->s_blocks_count
-+                                - fs->super->s_first_data_block)
-+                               % EXT2_BLOCKS_PER_GROUP(fs->super));
-+                      if (nbits)
-+                              for (j = nbits; j < fs->blocksize * 8; j++)
-+                                      ext2fs_set_bit(j, bitmap_block);
-+              }
-+              blk = fs->group_desc[i].bg_block_bitmap;
-+              if (blk) {
-+#ifdef EXT2_BIG_ENDIAN_BITMAPS
-+                      if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+                            (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
-+                              ext2fs_swap_bitmap(fs, bitmap_block, nbytes);
-+#endif
-+                      retval = io_channel_write_blk(fs->io, blk, 1,
-+                                                    bitmap_block);
-+                      if (retval)
-+                              return EXT2_ET_BLOCK_BITMAP_WRITE;
-+              }
-+              block_bitmap += nbytes;
-+      }
-+      fs->flags &= ~EXT2_FLAG_BB_DIRTY;
-+      ext2fs_free_mem(&bitmap_block);
-+      return 0;
-+}
-+
-+static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
-+{
-+      dgrp_t i;
-+      char *block_bitmap = 0, *inode_bitmap = 0;
-+      char *buf;
-+      errcode_t retval;
-+      int block_nbytes = (int) EXT2_BLOCKS_PER_GROUP(fs->super) / 8;
-+      int inode_nbytes = (int) EXT2_INODES_PER_GROUP(fs->super) / 8;
-+      blk_t   blk;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      fs->write_bitmaps = ext2fs_write_bitmaps;
-+
-+      retval = ext2fs_get_mem(strlen(fs->device_name) + 80, &buf);
-+      if (retval)
-+              return retval;
-+      if (do_block) {
-+              if (fs->block_map)
-+                      ext2fs_free_block_bitmap(fs->block_map);
-+              sprintf(buf, "block bitmap for %s", fs->device_name);
-+              retval = ext2fs_allocate_block_bitmap(fs, buf, &fs->block_map);
-+              if (retval)
-+                      goto cleanup;
-+              block_bitmap = fs->block_map->bitmap;
-+      }
-+      if (do_inode) {
-+              if (fs->inode_map)
-+                      ext2fs_free_inode_bitmap(fs->inode_map);
-+              sprintf(buf, "inode bitmap for %s", fs->device_name);
-+              retval = ext2fs_allocate_inode_bitmap(fs, buf, &fs->inode_map);
-+              if (retval)
-+                      goto cleanup;
-+              inode_bitmap = fs->inode_map->bitmap;
-+      }
-+      ext2fs_free_mem(&buf);
-+
-+      if (fs->flags & EXT2_FLAG_IMAGE_FILE) {
-+              if (inode_bitmap) {
-+                      blk = (fs->image_header->offset_inodemap /
-+                             fs->blocksize);
-+                      retval = io_channel_read_blk(fs->image_io, blk,
-+                           -(inode_nbytes * fs->group_desc_count),
-+                           inode_bitmap);
-+                      if (retval)
-+                              goto cleanup;
-+              }
-+              if (block_bitmap) {
-+                      blk = (fs->image_header->offset_blockmap /
-+                             fs->blocksize);
-+                      retval = io_channel_read_blk(fs->image_io, blk, 
-+                           -(block_nbytes * fs->group_desc_count),
-+                           block_bitmap);
-+                      if (retval)
-+                              goto cleanup;
-+              }
-+              return 0;
-+      }
-+
-+      for (i = 0; i < fs->group_desc_count; i++) {
-+              if (block_bitmap) {
-+                      blk = fs->group_desc[i].bg_block_bitmap;
-+                      if (blk) {
-+                              retval = io_channel_read_blk(fs->io, blk,
-+                                           -block_nbytes, block_bitmap);
-+                              if (retval) {
-+                                      retval = EXT2_ET_BLOCK_BITMAP_READ;
-+                                      goto cleanup;
-+                              }
-+#ifdef EXT2_BIG_ENDIAN_BITMAPS
-+                              if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+                                    (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
-+                                      ext2fs_swap_bitmap(fs, block_bitmap, block_nbytes);
-+#endif
-+                      } else
-+                              memset(block_bitmap, 0, block_nbytes);
-+                      block_bitmap += block_nbytes;
-+              }
-+              if (inode_bitmap) {
-+                      blk = fs->group_desc[i].bg_inode_bitmap;
-+                      if (blk) {
-+                              retval = io_channel_read_blk(fs->io, blk,
-+                                           -inode_nbytes, inode_bitmap);
-+                              if (retval) {
-+                                      retval = EXT2_ET_INODE_BITMAP_READ;
-+                                      goto cleanup;
-+                              }
-+#ifdef EXT2_BIG_ENDIAN_BITMAPS
-+                              if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
-+                                    (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
-+                                      ext2fs_swap_bitmap(fs, inode_bitmap, inode_nbytes);
-+#endif
-+                      } else
-+                              memset(inode_bitmap, 0, inode_nbytes);
-+                      inode_bitmap += inode_nbytes;
-+              }
-+      }
-+      return 0;
-+      
-+cleanup:
-+      if (do_block) {
-+              ext2fs_free_mem(&fs->block_map);
-+              fs->block_map = 0;
-+      }
-+      if (do_inode) {
-+              ext2fs_free_mem(&fs->inode_map);
-+              fs->inode_map = 0;
-+      }
-+      if (buf)
-+              ext2fs_free_mem(&buf);
-+      return retval;
-+}
-+
-+errcode_t ext2fs_read_inode_bitmap (ext2_filsys fs)
-+{
-+      return read_bitmaps(fs, 1, 0);
-+}
-+
-+errcode_t ext2fs_read_block_bitmap(ext2_filsys fs)
-+{
-+      return read_bitmaps(fs, 0, 1);
-+}
-+
-+errcode_t ext2fs_read_bitmaps(ext2_filsys fs)
-+{
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (fs->inode_map && fs->block_map)
-+              return 0;
-+
-+      return read_bitmaps(fs, !fs->inode_map, !fs->block_map);
-+}
-+
-+errcode_t ext2fs_write_bitmaps(ext2_filsys fs)
-+{
-+      errcode_t       retval;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (fs->block_map && ext2fs_test_bb_dirty(fs)) {
-+              retval = ext2fs_write_block_bitmap(fs);
-+              if (retval)
-+                      return retval;
-+      }
-+      if (fs->inode_map && ext2fs_test_ib_dirty(fs)) {
-+              retval = ext2fs_write_inode_bitmap(fs);
-+              if (retval)
-+                      return retval;
-+      }
-+      return 0;
-+}     
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/sparse.c busybox/e2fsprogs/ext2fs/sparse.c
---- busybox-1.00/e2fsprogs/ext2fs/sparse.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/sparse.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,78 @@
-+/*
-+ * sparse.c --- find the groups in an ext2 filesystem with metadata backups
-+ *
-+ * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
-+ * Copyright (C) 2002 Andreas Dilger.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fsP.h"
-+
-+static int test_root(int a, int b)
-+{
-+      if (a == 0)
-+              return 1;
-+      while (1) {
-+              if (a == 1)
-+                      return 1;
-+              if (a % b)
-+                      return 0;
-+              a = a / b;
-+      }
-+}
-+
-+int ext2fs_bg_has_super(ext2_filsys fs, int group_block)
-+{
-+      if (!(fs->super->s_feature_ro_compat &
-+            EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
-+              return 1;
-+
-+      if (test_root(group_block, 3) || (test_root(group_block, 5)) ||
-+          test_root(group_block, 7))
-+              return 1;
-+
-+      return 0;
-+}
-+
-+/*
-+ * Iterate through the groups which hold BACKUP superblock/GDT copies in an
-+ * ext3 filesystem.  The counters should be initialized to 1, 5, and 7 before
-+ * calling this for the first time.  In a sparse filesystem it will be the
-+ * sequence of powers of 3, 5, and 7: 1, 3, 5, 7, 9, 25, 27, 49, 81, ...
-+ * For a non-sparse filesystem it will be every group: 1, 2, 3, 4, ...
-+ */
-+unsigned int ext2fs_list_backups(ext2_filsys fs, unsigned int *three,
-+                               unsigned int *five, unsigned int *seven)
-+{
-+      unsigned int *min = three;
-+      int mult = 3;
-+      unsigned int ret;
-+
-+      if (!(fs->super->s_feature_ro_compat &
-+            EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
-+              ret = *min;
-+              *min += 1;
-+              return ret;
-+      }
-+
-+      if (*five < *min) {
-+              min = five;
-+              mult = 5;
-+      }
-+      if (*seven < *min) {
-+              min = seven;
-+              mult = 7;
-+      }
-+
-+      ret = *min;
-+      *min *= mult;
-+
-+      return ret;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/swapfs.c busybox/e2fsprogs/ext2fs/swapfs.c
---- busybox-1.00/e2fsprogs/ext2fs/swapfs.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/swapfs.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,237 @@
-+/*
-+ * swapfs.c --- swap ext2 filesystem data structures
-+ * 
-+ * Copyright (C) 1995, 1996, 2002 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+#include <ext2fs/ext2_ext_attr.h>
-+
-+#ifdef EXT2FS_ENABLE_SWAPFS
-+void ext2fs_swap_super(struct ext2_super_block * sb)
-+{
-+      int i;
-+      sb->s_inodes_count = ext2fs_swab32(sb->s_inodes_count);
-+      sb->s_blocks_count = ext2fs_swab32(sb->s_blocks_count);
-+      sb->s_r_blocks_count = ext2fs_swab32(sb->s_r_blocks_count);
-+      sb->s_free_blocks_count = ext2fs_swab32(sb->s_free_blocks_count);
-+      sb->s_free_inodes_count = ext2fs_swab32(sb->s_free_inodes_count);
-+      sb->s_first_data_block = ext2fs_swab32(sb->s_first_data_block);
-+      sb->s_log_block_size = ext2fs_swab32(sb->s_log_block_size);
-+      sb->s_log_frag_size = ext2fs_swab32(sb->s_log_frag_size);
-+      sb->s_blocks_per_group = ext2fs_swab32(sb->s_blocks_per_group);
-+      sb->s_frags_per_group = ext2fs_swab32(sb->s_frags_per_group);
-+      sb->s_inodes_per_group = ext2fs_swab32(sb->s_inodes_per_group);
-+      sb->s_mtime = ext2fs_swab32(sb->s_mtime);
-+      sb->s_wtime = ext2fs_swab32(sb->s_wtime);
-+      sb->s_mnt_count = ext2fs_swab16(sb->s_mnt_count);
-+      sb->s_max_mnt_count = ext2fs_swab16(sb->s_max_mnt_count);
-+      sb->s_magic = ext2fs_swab16(sb->s_magic);
-+      sb->s_state = ext2fs_swab16(sb->s_state);
-+      sb->s_errors = ext2fs_swab16(sb->s_errors);
-+      sb->s_minor_rev_level = ext2fs_swab16(sb->s_minor_rev_level);
-+      sb->s_lastcheck = ext2fs_swab32(sb->s_lastcheck);
-+      sb->s_checkinterval = ext2fs_swab32(sb->s_checkinterval);
-+      sb->s_creator_os = ext2fs_swab32(sb->s_creator_os);
-+      sb->s_rev_level = ext2fs_swab32(sb->s_rev_level);
-+      sb->s_def_resuid = ext2fs_swab16(sb->s_def_resuid);
-+      sb->s_def_resgid = ext2fs_swab16(sb->s_def_resgid);
-+      sb->s_first_ino = ext2fs_swab32(sb->s_first_ino);
-+      sb->s_inode_size = ext2fs_swab16(sb->s_inode_size);
-+      sb->s_block_group_nr = ext2fs_swab16(sb->s_block_group_nr);
-+      sb->s_feature_compat = ext2fs_swab32(sb->s_feature_compat);
-+      sb->s_feature_incompat = ext2fs_swab32(sb->s_feature_incompat);
-+      sb->s_feature_ro_compat = ext2fs_swab32(sb->s_feature_ro_compat);
-+      sb->s_algorithm_usage_bitmap = ext2fs_swab32(sb->s_algorithm_usage_bitmap);
-+      sb->s_reserved_gdt_blocks = ext2fs_swab16(sb->s_reserved_gdt_blocks);
-+      sb->s_journal_inum = ext2fs_swab32(sb->s_journal_inum);
-+      sb->s_journal_dev = ext2fs_swab32(sb->s_journal_dev);
-+      sb->s_last_orphan = ext2fs_swab32(sb->s_last_orphan);
-+      sb->s_default_mount_opts = ext2fs_swab32(sb->s_default_mount_opts);
-+      sb->s_first_meta_bg = ext2fs_swab32(sb->s_first_meta_bg);
-+      sb->s_mkfs_time = ext2fs_swab32(sb->s_mkfs_time);
-+      for (i=0; i < 4; i++)
-+              sb->s_hash_seed[i] = ext2fs_swab32(sb->s_hash_seed[i]);
-+      for (i=0; i < 17; i++)
-+              sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
-+
-+}
-+
-+void ext2fs_swap_group_desc(struct ext2_group_desc *gdp)
-+{
-+      gdp->bg_block_bitmap = ext2fs_swab32(gdp->bg_block_bitmap);
-+      gdp->bg_inode_bitmap = ext2fs_swab32(gdp->bg_inode_bitmap);
-+      gdp->bg_inode_table = ext2fs_swab32(gdp->bg_inode_table);
-+      gdp->bg_free_blocks_count = ext2fs_swab16(gdp->bg_free_blocks_count);
-+      gdp->bg_free_inodes_count = ext2fs_swab16(gdp->bg_free_inodes_count);
-+      gdp->bg_used_dirs_count = ext2fs_swab16(gdp->bg_used_dirs_count);
-+}
-+
-+void ext2fs_swap_ext_attr(char *to, char *from, int bufsize, int has_header)
-+{
-+      struct ext2_ext_attr_header *from_header =
-+              (struct ext2_ext_attr_header *)from;
-+      struct ext2_ext_attr_header *to_header =
-+              (struct ext2_ext_attr_header *)to;
-+      struct ext2_ext_attr_entry *from_entry, *to_entry;
-+      char *from_end = (char *)from_header + bufsize;
-+      int n;
-+
-+      if (to_header != from_header)
-+              memcpy(to_header, from_header, bufsize);
-+
-+      from_entry = (struct ext2_ext_attr_entry *)from_header;
-+      to_entry   = (struct ext2_ext_attr_entry *)to_header;
-+
-+      if (has_header) {
-+              to_header->h_magic    = ext2fs_swab32(from_header->h_magic);
-+              to_header->h_blocks   = ext2fs_swab32(from_header->h_blocks);
-+              to_header->h_refcount = ext2fs_swab32(from_header->h_refcount);
-+              for (n=0; n<4; n++)
-+                      to_header->h_reserved[n] =
-+                              ext2fs_swab32(from_header->h_reserved[n]);
-+              from_entry = (struct ext2_ext_attr_entry *)(from_header+1);
-+              to_entry   = (struct ext2_ext_attr_entry *)(to_header+1);
-+      }
-+
-+      while ((char *)from_entry < from_end && *(__u32 *)from_entry) {
-+              to_entry->e_value_offs  =       
-+                      ext2fs_swab16(from_entry->e_value_offs);
-+              to_entry->e_value_block =       
-+                      ext2fs_swab32(from_entry->e_value_block);
-+              to_entry->e_value_size  =       
-+                      ext2fs_swab32(from_entry->e_value_size);
-+              from_entry = EXT2_EXT_ATTR_NEXT(from_entry);
-+              to_entry   = EXT2_EXT_ATTR_NEXT(to_entry);
-+      }
-+}
-+
-+void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
-+                          struct ext2_inode_large *f, int hostorder,
-+                          int bufsize)
-+{
-+      unsigned i;
-+      int islnk = 0;
-+      __u32 *eaf, *eat;
-+
-+      if (hostorder && LINUX_S_ISLNK(f->i_mode))
-+              islnk = 1;
-+      t->i_mode = ext2fs_swab16(f->i_mode);
-+      if (!hostorder && LINUX_S_ISLNK(t->i_mode))
-+              islnk = 1;
-+      t->i_uid = ext2fs_swab16(f->i_uid);
-+      t->i_size = ext2fs_swab32(f->i_size);
-+      t->i_atime = ext2fs_swab32(f->i_atime);
-+      t->i_ctime = ext2fs_swab32(f->i_ctime);
-+      t->i_mtime = ext2fs_swab32(f->i_mtime);
-+      t->i_dtime = ext2fs_swab32(f->i_dtime);
-+      t->i_gid = ext2fs_swab16(f->i_gid);
-+      t->i_links_count = ext2fs_swab16(f->i_links_count);
-+      t->i_blocks = ext2fs_swab32(f->i_blocks);
-+      t->i_flags = ext2fs_swab32(f->i_flags);
-+      t->i_file_acl = ext2fs_swab32(f->i_file_acl);
-+      t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
-+      if (!islnk || ext2fs_inode_data_blocks(fs, (struct ext2_inode *)t)) {
-+              for (i = 0; i < EXT2_N_BLOCKS; i++)
-+                      t->i_block[i] = ext2fs_swab32(f->i_block[i]);
-+      } else if (t != f) {
-+              for (i = 0; i < EXT2_N_BLOCKS; i++)
-+                      t->i_block[i] = f->i_block[i];
-+      }
-+      t->i_generation = ext2fs_swab32(f->i_generation);
-+      t->i_faddr = ext2fs_swab32(f->i_faddr);
-+
-+      switch (fs->super->s_creator_os) {
-+      case EXT2_OS_LINUX:
-+              t->osd1.linux1.l_i_reserved1 =
-+                      ext2fs_swab32(f->osd1.linux1.l_i_reserved1);
-+              t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
-+              t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
-+              t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
-+              t->osd2.linux2.l_i_uid_high =
-+                ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
-+              t->osd2.linux2.l_i_gid_high =
-+                ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
-+              t->osd2.linux2.l_i_reserved2 =
-+                      ext2fs_swab32(f->osd2.linux2.l_i_reserved2);
-+              break;
-+      case EXT2_OS_HURD:
-+              t->osd1.hurd1.h_i_translator =
-+                ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
-+              t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
-+              t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
-+              t->osd2.hurd2.h_i_mode_high =
-+                ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
-+              t->osd2.hurd2.h_i_uid_high =
-+                ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
-+              t->osd2.hurd2.h_i_gid_high =
-+                ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
-+              t->osd2.hurd2.h_i_author =
-+                ext2fs_swab32 (f->osd2.hurd2.h_i_author);
-+              break;
-+      case EXT2_OS_MASIX:
-+              t->osd1.masix1.m_i_reserved1 =
-+                      ext2fs_swab32(f->osd1.masix1.m_i_reserved1);
-+              t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
-+              t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
-+              t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
-+              t->osd2.masix2.m_i_reserved2[0] =
-+                      ext2fs_swab32(f->osd2.masix2.m_i_reserved2[0]);
-+              t->osd2.masix2.m_i_reserved2[1] =
-+                      ext2fs_swab32(f->osd2.masix2.m_i_reserved2[1]);
-+              break;
-+      }
-+
-+      if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
-+              return; /* no i_extra_isize field */
-+
-+      t->i_extra_isize = ext2fs_swab16(f->i_extra_isize);
-+      if (t->i_extra_isize > EXT2_INODE_SIZE(fs->super) -
-+                              sizeof(struct ext2_inode)) {
-+              /* this is error case: i_extra_size is too large */
-+              return;
-+      }
-+
-+      i = sizeof(struct ext2_inode) + t->i_extra_isize + sizeof(__u32);
-+      if (bufsize < (int) i)
-+              return; /* no space for EA magic */
-+
-+      eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) +
-+                                      f->i_extra_isize);
-+
-+      if (ext2fs_swab32(*eaf) != EXT2_EXT_ATTR_MAGIC)
-+              return; /* it seems no magic here */
-+
-+      eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) +
-+                                      f->i_extra_isize);
-+      *eat = ext2fs_swab32(*eaf);
-+
-+      /* convert EA(s) */
-+      ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
-+                           bufsize - sizeof(struct ext2_inode) -
-+                           t->i_extra_isize - sizeof(__u32), 0);
-+
-+}
-+
-+void ext2fs_swap_inode(ext2_filsys fs, struct ext2_inode *t,
-+                     struct ext2_inode *f, int hostorder)
-+{
-+      ext2fs_swap_inode_full(fs, (struct ext2_inode_large *) t,
-+                              (struct ext2_inode_large *) f, hostorder,
-+                              sizeof(struct ext2_inode));
-+}
-+
-+#endif
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/test_io.c busybox/e2fsprogs/ext2fs/test_io.c
---- busybox-1.00/e2fsprogs/ext2fs/test_io.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/test_io.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,382 @@
-+/*
-+ * test_io.c --- This is the Test I/O interface.
-+ *
-+ * Copyright (C) 1996 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * For checking structure magic numbers...
-+ */
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+        if ((struct)->magic != (code)) return (code)
-+  
-+struct test_private_data {
-+      int     magic;
-+      io_channel real;
-+      int flags;
-+      FILE *outfile;
-+      unsigned long block;
-+      int read_abort_count, write_abort_count;
-+      void (*read_blk)(unsigned long block, int count, errcode_t err);
-+      void (*write_blk)(unsigned long block, int count, errcode_t err);
-+      void (*set_blksize)(int blksize, errcode_t err);
-+      void (*write_byte)(unsigned long block, int count, errcode_t err);
-+};
-+
-+static errcode_t test_open(const char *name, int flags, io_channel *channel);
-+static errcode_t test_close(io_channel channel);
-+static errcode_t test_set_blksize(io_channel channel, int blksize);
-+static errcode_t test_read_blk(io_channel channel, unsigned long block,
-+                             int count, void *data);
-+static errcode_t test_write_blk(io_channel channel, unsigned long block,
-+                              int count, const void *data);
-+static errcode_t test_flush(io_channel channel);
-+static errcode_t test_write_byte(io_channel channel, unsigned long offset,
-+                               int count, const void *buf);
-+static errcode_t test_set_option(io_channel channel, const char *option, 
-+                               const char *arg);
-+
-+static struct struct_io_manager struct_test_manager = {
-+      EXT2_ET_MAGIC_IO_MANAGER,
-+      "Test I/O Manager",
-+      test_open,
-+      test_close,
-+      test_set_blksize,
-+      test_read_blk,
-+      test_write_blk,
-+      test_flush,
-+      test_write_byte,
-+      test_set_option
-+};
-+
-+io_manager test_io_manager = &struct_test_manager;
-+
-+/*
-+ * These global variable can be set by the test program as
-+ * necessary *before* calling test_open
-+ */
-+io_manager test_io_backing_manager = 0;
-+void (*test_io_cb_read_blk)
-+      (unsigned long block, int count, errcode_t err) = 0;
-+void (*test_io_cb_write_blk)
-+      (unsigned long block, int count, errcode_t err) = 0;
-+void (*test_io_cb_set_blksize)
-+      (int blksize, errcode_t err) = 0;
-+void (*test_io_cb_write_byte)
-+      (unsigned long block, int count, errcode_t err) = 0;
-+
-+/*
-+ * Test flags
-+ */
-+#define TEST_FLAG_READ                        0x01
-+#define TEST_FLAG_WRITE                       0x02
-+#define TEST_FLAG_SET_BLKSIZE         0x04
-+#define TEST_FLAG_FLUSH                       0x08
-+#define TEST_FLAG_DUMP                        0x10
-+#define TEST_FLAG_SET_OPTION          0x20
-+
-+static void test_dump_block(io_channel channel,
-+                          struct test_private_data *data,
-+                          unsigned long block, const void *buf)
-+{
-+      const unsigned char *cp;
-+      FILE *f = data->outfile;
-+      int     i;
-+      unsigned long   cksum = 0;
-+
-+      for (i=0, cp = buf; i < channel->block_size; i++, cp++) {
-+              cksum += *cp;
-+      }
-+      fprintf(f, "Contents of block %lu, checksum %08lu: \n", block, cksum);
-+      for (i=0, cp = buf; i < channel->block_size; i++, cp++) {
-+              if ((i % 16) == 0)
-+                      fprintf(f, "%04x: ", i);
-+              fprintf(f, "%02x%c", *cp, ((i % 16) == 15) ? '\n' : ' ');
-+      }
-+}
-+
-+static void test_abort(io_channel channel, unsigned long block)
-+{
-+      struct test_private_data *data;
-+      FILE *f;
-+
-+      data = (struct test_private_data *) channel->private_data;
-+      f = data->outfile;
-+      test_flush(channel);
-+
-+      fprintf(f, "Aborting due to I/O to block %lu\n", block);
-+      fflush(f);
-+      abort();
-+}
-+
-+static errcode_t test_open(const char *name, int flags, io_channel *channel)
-+{
-+      io_channel      io = NULL;
-+      struct test_private_data *data = NULL;
-+      errcode_t       retval;
-+      char            *value;
-+
-+      if (name == 0)
-+              return EXT2_ET_BAD_DEVICE_NAME;
-+      retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
-+      if (retval)
-+              return retval;
-+      memset(io, 0, sizeof(struct struct_io_channel));
-+      io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
-+      retval = ext2fs_get_mem(sizeof(struct test_private_data), &data);
-+      if (retval) {
-+              retval = EXT2_ET_NO_MEMORY;
-+              goto cleanup;
-+      }
-+      io->manager = test_io_manager;
-+      retval = ext2fs_get_mem(strlen(name)+1, &io->name);
-+      if (retval)
-+              goto cleanup;
-+
-+      strcpy(io->name, name);
-+      io->private_data = data;
-+      io->block_size = 1024;
-+      io->read_error = 0;
-+      io->write_error = 0;
-+      io->refcount = 1;
-+
-+      memset(data, 0, sizeof(struct test_private_data));
-+      data->magic = EXT2_ET_MAGIC_TEST_IO_CHANNEL;
-+      if (test_io_backing_manager) {
-+              retval = test_io_backing_manager->open(name, flags,
-+                                                     &data->real);
-+              if (retval)
-+                      goto cleanup;
-+      } else
-+              data->real = 0;
-+      data->read_blk =        test_io_cb_read_blk;
-+      data->write_blk =       test_io_cb_write_blk;
-+      data->set_blksize =     test_io_cb_set_blksize;
-+      data->write_byte =      test_io_cb_write_byte;
-+
-+      data->outfile = NULL;
-+      if ((value = getenv("TEST_IO_LOGFILE")) != NULL)
-+              data->outfile = fopen(value, "w");
-+      if (!data->outfile)
-+              data->outfile = stderr;
-+
-+      data->flags = 0;
-+      if ((value = getenv("TEST_IO_FLAGS")) != NULL)
-+              data->flags = strtoul(value, NULL, 0);
-+      
-+      data->block = 0;
-+      if ((value = getenv("TEST_IO_BLOCK")) != NULL)
-+              data->block = strtoul(value, NULL, 0);
-+
-+      data->read_abort_count = 0;
-+      if ((value = getenv("TEST_IO_READ_ABORT")) != NULL)
-+              data->read_abort_count = strtoul(value, NULL, 0);
-+
-+      data->write_abort_count = 0;
-+      if ((value = getenv("TEST_IO_WRITE_ABORT")) != NULL)
-+              data->write_abort_count = strtoul(value, NULL, 0);
-+      
-+      *channel = io;
-+      return 0;
-+
-+cleanup:
-+      if (io)
-+              ext2fs_free_mem(&io);
-+      if (data)
-+              ext2fs_free_mem(&data);
-+      return retval;
-+}
-+
-+static errcode_t test_close(io_channel channel)
-+{
-+      struct test_private_data *data;
-+      errcode_t       retval = 0;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct test_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+      if (--channel->refcount > 0)
-+              return 0;
-+      
-+      if (data->real)
-+              retval = io_channel_close(data->real);
-+
-+      if (data->outfile && data->outfile != stderr)
-+              fclose(data->outfile);
-+      
-+      ext2fs_free_mem(&channel->private_data);
-+      if (channel->name)
-+              ext2fs_free_mem(&channel->name);
-+      ext2fs_free_mem(&channel);
-+      return retval;
-+}
-+
-+static errcode_t test_set_blksize(io_channel channel, int blksize)
-+{
-+      struct test_private_data *data;
-+      errcode_t       retval = 0;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct test_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+      if (data->real)
-+              retval = io_channel_set_blksize(data->real, blksize);
-+      if (data->set_blksize)
-+              data->set_blksize(blksize, retval);
-+      if (data->flags & TEST_FLAG_SET_BLKSIZE)
-+              fprintf(data->outfile,
-+                      "Test_io: set_blksize(%d) returned %s\n",
-+                      blksize, retval ? error_message(retval) : "OK");
-+      channel->block_size = blksize;
-+      return retval;
-+}
-+
-+
-+static errcode_t test_read_blk(io_channel channel, unsigned long block,
-+                             int count, void *buf)
-+{
-+      struct test_private_data *data;
-+      errcode_t       retval = 0;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct test_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+      if (data->real)
-+              retval = io_channel_read_blk(data->real, block, count, buf);
-+      if (data->read_blk)
-+              data->read_blk(block, count, retval);
-+      if (data->flags & TEST_FLAG_READ)
-+              fprintf(data->outfile,
-+                      "Test_io: read_blk(%lu, %d) returned %s\n",
-+                      block, count, retval ? error_message(retval) : "OK");
-+      if (data->block && data->block == block) {
-+              if (data->flags & TEST_FLAG_DUMP)
-+                      test_dump_block(channel, data, block, buf);
-+              if (--data->read_abort_count == 0)
-+                      test_abort(channel, block);
-+      } 
-+      return retval;
-+}
-+
-+static errcode_t test_write_blk(io_channel channel, unsigned long block,
-+                             int count, const void *buf)
-+{
-+      struct test_private_data *data;
-+      errcode_t       retval = 0;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct test_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+      if (data->real)
-+              retval = io_channel_write_blk(data->real, block, count, buf);
-+      if (data->write_blk)
-+              data->write_blk(block, count, retval);
-+      if (data->flags & TEST_FLAG_WRITE)
-+              fprintf(data->outfile,
-+                      "Test_io: write_blk(%lu, %d) returned %s\n",
-+                      block, count, retval ? error_message(retval) : "OK");
-+      if (data->block && data->block == block) {
-+              if (data->flags & TEST_FLAG_DUMP)
-+                      test_dump_block(channel, data, block, buf);
-+              if (--data->write_abort_count == 0)
-+                      test_abort(channel, block);
-+      }
-+      return retval;
-+}
-+
-+static errcode_t test_write_byte(io_channel channel, unsigned long offset,
-+                             int count, const void *buf)
-+{
-+      struct test_private_data *data;
-+      errcode_t       retval = 0;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct test_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+      if (data->real && data->real->manager->write_byte)
-+              retval = io_channel_write_byte(data->real, offset, count, buf);
-+      if (data->write_byte)
-+              data->write_byte(offset, count, retval);
-+      if (data->flags & TEST_FLAG_WRITE)
-+              fprintf(data->outfile,
-+                      "Test_io: write_byte(%lu, %d) returned %s\n",
-+                      offset, count, retval ? error_message(retval) : "OK");
-+      return retval;
-+}
-+
-+/*
-+ * Flush data buffers to disk.
-+ */
-+static errcode_t test_flush(io_channel channel)
-+{
-+      struct test_private_data *data;
-+      errcode_t       retval = 0;
-+      
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct test_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+      if (data->real)
-+              retval = io_channel_flush(data->real);
-+      
-+      if (data->flags & TEST_FLAG_FLUSH)
-+              fprintf(data->outfile, "Test_io: flush() returned %s\n",
-+                      retval ? error_message(retval) : "OK");
-+      
-+      return retval;
-+}
-+
-+static errcode_t test_set_option(io_channel channel, const char *option, 
-+                               const char *arg)
-+{
-+      struct test_private_data *data;
-+      errcode_t       retval = 0;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct test_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_TEST_IO_CHANNEL);
-+
-+
-+      if (data->flags & TEST_FLAG_SET_OPTION)
-+              fprintf(data->outfile, "Test_io: set_option(%s, %s) ", 
-+                      option, arg);
-+      if (data->real && data->real->manager->set_option) {
-+              retval = (data->real->manager->set_option)(data->real, 
-+                                                         option, arg);
-+              if (data->flags & TEST_FLAG_SET_OPTION)
-+                      fprintf(data->outfile, "returned %s\n",
-+                              retval ? error_message(retval) : "OK");
-+      } else {
-+              if (data->flags & TEST_FLAG_SET_OPTION)
-+                      fprintf(data->outfile, "not implemented\n");
-+      }
-+      return retval;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/unix_io.c busybox/e2fsprogs/ext2fs/unix_io.c
---- busybox-1.00/e2fsprogs/ext2fs/unix_io.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/unix_io.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,707 @@
-+/*
-+ * unix_io.c --- This is the Unix (well, really POSIX) implementation
-+ *    of the I/O manager.
-+ *
-+ * Implements a one-block write-through cache.
-+ *
-+ * Includes support for Windows NT support under Cygwin. 
-+ *
-+ * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-+ *    2002 by Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#if HAVE_ERRNO_H
-+#include <errno.h>
-+#endif
-+#include <fcntl.h>
-+#include <time.h>
-+#ifdef __linux__
-+#include <sys/utsname.h>
-+#endif
-+#if HAVE_SYS_STAT_H
-+#include <sys/stat.h>
-+#endif
-+#if HAVE_SYS_TYPES_H
-+#include <sys/types.h>
-+#endif
-+#if HAVE_SYS_RESOURCE_H
-+#include <sys/resource.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * For checking structure magic numbers...
-+ */
-+
-+#define EXT2_CHECK_MAGIC(struct, code) \
-+        if ((struct)->magic != (code)) return (code)
-+
-+struct unix_cache {
-+      char            *buf;
-+      unsigned long   block;
-+      int             access_time;
-+      unsigned        dirty:1;
-+      unsigned        in_use:1;
-+};
-+
-+#define CACHE_SIZE 8
-+#define WRITE_DIRECT_SIZE 4   /* Must be smaller than CACHE_SIZE */
-+#define READ_DIRECT_SIZE 4    /* Should be smaller than CACHE_SIZE */
-+
-+struct unix_private_data {
-+      int     magic;
-+      int     dev;
-+      int     flags;
-+      int     access_time;
-+      ext2_loff_t offset;
-+      struct unix_cache cache[CACHE_SIZE];
-+};
-+
-+static errcode_t unix_open(const char *name, int flags, io_channel *channel);
-+static errcode_t unix_close(io_channel channel);
-+static errcode_t unix_set_blksize(io_channel channel, int blksize);
-+static errcode_t unix_read_blk(io_channel channel, unsigned long block,
-+                             int count, void *data);
-+static errcode_t unix_write_blk(io_channel channel, unsigned long block,
-+                              int count, const void *data);
-+static errcode_t unix_flush(io_channel channel);
-+static errcode_t unix_write_byte(io_channel channel, unsigned long offset,
-+                              int size, const void *data);
-+static errcode_t unix_set_option(io_channel channel, const char *option, 
-+                               const char *arg);
-+
-+static void reuse_cache(io_channel channel, struct unix_private_data *data,
-+               struct unix_cache *cache, unsigned long block);
-+
-+/* __FreeBSD_kernel__ is defined by GNU/kFreeBSD - the FreeBSD kernel
-+ * does not know buffered block devices - everything is raw. */
-+#if defined(__CYGWIN__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
-+#define NEED_BOUNCE_BUFFER
-+#else
-+#undef NEED_BOUNCE_BUFFER
-+#endif
-+
-+static struct struct_io_manager struct_unix_manager = {
-+      EXT2_ET_MAGIC_IO_MANAGER,
-+      "Unix I/O Manager",
-+      unix_open,
-+      unix_close,
-+      unix_set_blksize,
-+      unix_read_blk,
-+      unix_write_blk,
-+      unix_flush,
-+#ifdef NEED_BOUNCE_BUFFER
-+      0,
-+#else
-+      unix_write_byte,
-+#endif
-+      unix_set_option
-+};
-+
-+io_manager unix_io_manager = &struct_unix_manager;
-+
-+/*
-+ * Here are the raw I/O functions
-+ */
-+#ifndef NEED_BOUNCE_BUFFER
-+static errcode_t raw_read_blk(io_channel channel,
-+                            struct unix_private_data *data,
-+                            unsigned long block,
-+                            int count, void *buf)
-+{
-+      errcode_t       retval;
-+      ssize_t         size;
-+      ext2_loff_t     location;
-+      int             actual = 0;
-+
-+      size = (count < 0) ? -count : count * channel->block_size;
-+      location = ((ext2_loff_t) block * channel->block_size) + data->offset;
-+      if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
-+              retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
-+              goto error_out;
-+      }
-+      actual = read(data->dev, buf, size);
-+      if (actual != size) {
-+              if (actual < 0)
-+                      actual = 0;
-+              retval = EXT2_ET_SHORT_READ;
-+              goto error_out;
-+      }
-+      return 0;
-+      
-+error_out:
-+      memset((char *) buf+actual, 0, size-actual);
-+      if (channel->read_error)
-+              retval = (channel->read_error)(channel, block, count, buf,
-+                                             size, actual, retval);
-+      return retval;
-+}
-+#else /* NEED_BOUNCE_BUFFER */
-+/*
-+ * Windows and FreeBSD block devices only allow sector alignment IO in offset and size
-+ */
-+static errcode_t raw_read_blk(io_channel channel,
-+                            struct unix_private_data *data,
-+                            unsigned long block,
-+                            int count, void *buf)
-+{
-+      errcode_t       retval;
-+      size_t          size, alignsize, fragment;
-+      ext2_loff_t     location;
-+      int             total = 0, actual;
-+#define BLOCKALIGN 512
-+      char            sector[BLOCKALIGN];
-+
-+      size = (count < 0) ? -count : count * channel->block_size;
-+      location = ((ext2_loff_t) block * channel->block_size) + data->offset;
-+#ifdef DEBUG
-+      printf("count=%d, size=%d, block=%d, blk_size=%d, location=%lx\n",
-+                      count, size, block, channel->block_size, location);
-+#endif
-+      if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
-+              retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
-+              goto error_out;
-+      }
-+      fragment = size % BLOCKALIGN;
-+      alignsize = size - fragment;
-+      if (alignsize) {
-+              actual = read(data->dev, buf, alignsize);
-+              if (actual != alignsize)
-+                      goto short_read;
-+      }
-+      if (fragment) {
-+              actual = read(data->dev, sector, BLOCKALIGN);
-+              if (actual != BLOCKALIGN)
-+                      goto short_read;
-+              memcpy(buf+alignsize, sector, fragment);
-+      }
-+      return 0;
-+
-+short_read:
-+      if (actual>0)
-+              total += actual;
-+      retval = EXT2_ET_SHORT_READ;
-+
-+error_out:
-+      memset((char *) buf+total, 0, size-actual);
-+      if (channel->read_error)
-+              retval = (channel->read_error)(channel, block, count, buf,
-+                                             size, actual, retval);
-+      return retval;
-+}
-+#endif
-+
-+static errcode_t raw_write_blk(io_channel channel,
-+                             struct unix_private_data *data,
-+                             unsigned long block,
-+                             int count, const void *buf)
-+{
-+      ssize_t         size;
-+      ext2_loff_t     location;
-+      int             actual = 0;
-+      errcode_t       retval;
-+
-+      if (count == 1)
-+              size = channel->block_size;
-+      else {
-+              if (count < 0)
-+                      size = -count;
-+              else
-+                      size = count * channel->block_size;
-+      }
-+
-+      location = ((ext2_loff_t) block * channel->block_size) + data->offset;
-+      if (ext2fs_llseek(data->dev, location, SEEK_SET) != location) {
-+              retval = errno ? errno : EXT2_ET_LLSEEK_FAILED;
-+              goto error_out;
-+      }
-+      
-+      actual = write(data->dev, buf, size);
-+      if (actual != size) {
-+              retval = EXT2_ET_SHORT_WRITE;
-+              goto error_out;
-+      }
-+      return 0;
-+      
-+error_out:
-+      if (channel->write_error)
-+              retval = (channel->write_error)(channel, block, count, buf,
-+                                              size, actual, retval);
-+      return retval;
-+}
-+
-+
-+/*
-+ * Here we implement the cache functions
-+ */
-+
-+/* Allocate the cache buffers */
-+static errcode_t alloc_cache(io_channel channel,
-+                           struct unix_private_data *data)
-+{
-+      errcode_t               retval;
-+      struct unix_cache       *cache;
-+      int                     i;
-+      
-+      data->access_time = 0;
-+      for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
-+              cache->block = 0;
-+              cache->access_time = 0;
-+              cache->dirty = 0;
-+              cache->in_use = 0;
-+              if ((retval = ext2fs_get_mem(channel->block_size,
-+                                           &cache->buf)))
-+                      return retval;
-+      }
-+      return 0;
-+}
-+
-+/* Free the cache buffers */
-+static void free_cache(struct unix_private_data *data)
-+{
-+      struct unix_cache       *cache;
-+      int                     i;
-+      
-+      data->access_time = 0;
-+      for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
-+              cache->block = 0;
-+              cache->access_time = 0;
-+              cache->dirty = 0;
-+              cache->in_use = 0;
-+              if (cache->buf)
-+                      ext2fs_free_mem(&cache->buf);
-+              cache->buf = 0;
-+      }
-+}
-+
-+#ifndef NO_IO_CACHE
-+/*
-+ * Try to find a block in the cache.  If the block is not found, and
-+ * eldest is a non-zero pointer, then fill in eldest with the cache
-+ * entry to that should be reused.
-+ */
-+static struct unix_cache *find_cached_block(struct unix_private_data *data,
-+                                          unsigned long block,
-+                                          struct unix_cache **eldest)
-+{
-+      struct unix_cache       *cache, *unused_cache, *oldest_cache;
-+      int                     i;
-+      
-+      unused_cache = oldest_cache = 0;
-+      for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
-+              if (!cache->in_use) {
-+                      if (!unused_cache)
-+                              unused_cache = cache;
-+                      continue;
-+              }
-+              if (cache->block == block) {
-+                      cache->access_time = ++data->access_time;
-+                      return cache;
-+              }
-+              if (!oldest_cache ||
-+                  (cache->access_time < oldest_cache->access_time))
-+                      oldest_cache = cache;
-+      }
-+      if (eldest)
-+              *eldest = (unused_cache) ? unused_cache : oldest_cache;
-+      return 0;
-+}
-+
-+/*
-+ * Reuse a particular cache entry for another block.
-+ */
-+static void reuse_cache(io_channel channel, struct unix_private_data *data,
-+               struct unix_cache *cache, unsigned long block)
-+{
-+      if (cache->dirty && cache->in_use)
-+              raw_write_blk(channel, data, cache->block, 1, cache->buf);
-+
-+      cache->in_use = 1;
-+      cache->dirty = 0;
-+      cache->block = block;
-+      cache->access_time = ++data->access_time;
-+}
-+
-+/*
-+ * Flush all of the blocks in the cache
-+ */
-+static errcode_t flush_cached_blocks(io_channel channel,
-+                                   struct unix_private_data *data,
-+                                   int invalidate)
-+
-+{
-+      struct unix_cache       *cache;
-+      errcode_t               retval, retval2;
-+      int                     i;
-+      
-+      retval2 = 0;
-+      for (i=0, cache = data->cache; i < CACHE_SIZE; i++, cache++) {
-+              if (!cache->in_use)
-+                      continue;
-+              
-+              if (invalidate)
-+                      cache->in_use = 0;
-+              
-+              if (!cache->dirty)
-+                      continue;
-+              
-+              retval = raw_write_blk(channel, data,
-+                                     cache->block, 1, cache->buf);
-+              if (retval)
-+                      retval2 = retval;
-+              else
-+                      cache->dirty = 0;
-+      }
-+      return retval2;
-+}
-+#endif /* NO_IO_CACHE */
-+
-+static errcode_t unix_open(const char *name, int flags, io_channel *channel)
-+{
-+      io_channel      io = NULL;
-+      struct unix_private_data *data = NULL;
-+      errcode_t       retval;
-+      int             open_flags;
-+      struct stat     st;
-+#ifdef __linux__
-+      struct          utsname ut;
-+#endif
-+
-+      if (name == 0)
-+              return EXT2_ET_BAD_DEVICE_NAME;
-+      retval = ext2fs_get_mem(sizeof(struct struct_io_channel), &io);
-+      if (retval)
-+              return retval;
-+      memset(io, 0, sizeof(struct struct_io_channel));
-+      io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
-+      retval = ext2fs_get_mem(sizeof(struct unix_private_data), &data);
-+      if (retval)
-+              goto cleanup;
-+
-+      io->manager = unix_io_manager;
-+      retval = ext2fs_get_mem(strlen(name)+1, &io->name);
-+      if (retval)
-+              goto cleanup;
-+
-+      strcpy(io->name, name);
-+      io->private_data = data;
-+      io->block_size = 1024;
-+      io->read_error = 0;
-+      io->write_error = 0;
-+      io->refcount = 1;
-+
-+      memset(data, 0, sizeof(struct unix_private_data));
-+      data->magic = EXT2_ET_MAGIC_UNIX_IO_CHANNEL;
-+
-+      if ((retval = alloc_cache(io, data)))
-+              goto cleanup;
-+
-+      open_flags = (flags & IO_FLAG_RW) ? O_RDWR : O_RDONLY;
-+#ifdef CONFIG_LFS
-+      data->dev = open64(io->name, open_flags);
-+#else
-+      data->dev = open(io->name, open_flags);
-+#endif
-+      if (data->dev < 0) {
-+              retval = errno;
-+              goto cleanup;
-+      }
-+
-+#ifdef __linux__
-+#undef RLIM_INFINITY
-+#if (defined(__alpha__) || ((defined(__sparc__) || defined(__mips__)) && (SIZEOF_LONG == 4)))
-+#define RLIM_INFINITY ((unsigned long)(~0UL>>1))
-+#else
-+#define RLIM_INFINITY  (~0UL)
-+#endif
-+      /*
-+       * Work around a bug in 2.4.10-2.4.18 kernels where writes to
-+       * block devices are wrongly getting hit by the filesize
-+       * limit.  This workaround isn't perfect, since it won't work
-+       * if glibc wasn't built against 2.2 header files.  (Sigh.)
-+       * 
-+       */
-+      if ((flags & IO_FLAG_RW) &&
-+          (uname(&ut) == 0) &&
-+          ((ut.release[0] == '2') && (ut.release[1] == '.') &&
-+           (ut.release[2] == '4') && (ut.release[3] == '.') &&
-+           (ut.release[4] == '1') && (ut.release[5] >= '0') &&
-+           (ut.release[5] < '8')) &&
-+          (fstat(data->dev, &st) == 0) &&
-+          (S_ISBLK(st.st_mode))) {
-+              struct rlimit   rlim;
-+              
-+              rlim.rlim_cur = rlim.rlim_max = (unsigned long) RLIM_INFINITY;
-+              setrlimit(RLIMIT_FSIZE, &rlim);
-+              getrlimit(RLIMIT_FSIZE, &rlim);
-+              if (((unsigned long) rlim.rlim_cur) <
-+                  ((unsigned long) rlim.rlim_max)) {
-+                      rlim.rlim_cur = rlim.rlim_max;
-+                      setrlimit(RLIMIT_FSIZE, &rlim);
-+              }
-+      }
-+#endif
-+      *channel = io;
-+      return 0;
-+
-+cleanup:
-+      if (data) {
-+              free_cache(data);
-+              ext2fs_free_mem(&data);
-+      }
-+      if (io)
-+              ext2fs_free_mem(&io);
-+      return retval;
-+}
-+
-+static errcode_t unix_close(io_channel channel)
-+{
-+      struct unix_private_data *data;
-+      errcode_t       retval = 0;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct unix_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+      if (--channel->refcount > 0)
-+              return 0;
-+
-+#ifndef NO_IO_CACHE
-+      retval = flush_cached_blocks(channel, data, 0);
-+#endif
-+
-+      if (close(data->dev) < 0)
-+              retval = errno;
-+      free_cache(data);
-+
-+      ext2fs_free_mem(&channel->private_data);
-+      if (channel->name)
-+              ext2fs_free_mem(&channel->name);
-+      ext2fs_free_mem(&channel);
-+      return retval;
-+}
-+
-+static errcode_t unix_set_blksize(io_channel channel, int blksize)
-+{
-+      struct unix_private_data *data;
-+      errcode_t               retval;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct unix_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+      if (channel->block_size != blksize) {
-+#ifndef NO_IO_CACHE
-+              if ((retval = flush_cached_blocks(channel, data, 0)))
-+                      return retval;
-+#endif
-+              
-+              channel->block_size = blksize;
-+              free_cache(data);
-+              if ((retval = alloc_cache(channel, data)))
-+                      return retval;
-+      }
-+      return 0;
-+}
-+
-+
-+static errcode_t unix_read_blk(io_channel channel, unsigned long block,
-+                             int count, void *buf)
-+{
-+      struct unix_private_data *data;
-+      struct unix_cache *cache, *reuse[READ_DIRECT_SIZE];
-+      errcode_t       retval;
-+      char            *cp;
-+      int             i, j;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct unix_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+#ifdef NO_IO_CACHE
-+      return raw_read_blk(channel, data, block, count, buf);
-+#else
-+      /*
-+       * If we're doing an odd-sized read or a very large read,
-+       * flush out the cache and then do a direct read.
-+       */
-+      if (count < 0 || count > WRITE_DIRECT_SIZE) {
-+              if ((retval = flush_cached_blocks(channel, data, 0)))
-+                      return retval;
-+              return raw_read_blk(channel, data, block, count, buf);
-+      }
-+
-+      cp = buf;
-+      while (count > 0) {
-+              /* If it's in the cache, use it! */
-+              if ((cache = find_cached_block(data, block, &reuse[0]))) {
-+#ifdef DEBUG
-+                      printf("Using cached block %d\n", block);
-+#endif
-+                      memcpy(cp, cache->buf, channel->block_size);
-+                      count--;
-+                      block++;
-+                      cp += channel->block_size;
-+                      continue;
-+              }
-+              /*
-+               * Find the number of uncached blocks so we can do a
-+               * single read request
-+               */
-+              for (i=1; i < count; i++)
-+                      if (find_cached_block(data, block+i, &reuse[i]))
-+                              break;
-+#ifdef DEBUG
-+              printf("Reading %d blocks starting at %d\n", i, block);
-+#endif
-+              if ((retval = raw_read_blk(channel, data, block, i, cp)))
-+                      return retval;
-+              
-+              /* Save the results in the cache */
-+              for (j=0; j < i; j++) {
-+                      count--;
-+                      cache = reuse[j];
-+                      reuse_cache(channel, data, cache, block++);
-+                      memcpy(cache->buf, cp, channel->block_size);
-+                      cp += channel->block_size;
-+              }
-+      }
-+      return 0;
-+#endif /* NO_IO_CACHE */
-+}
-+
-+static errcode_t unix_write_blk(io_channel channel, unsigned long block,
-+                              int count, const void *buf)
-+{
-+      struct unix_private_data *data;
-+      struct unix_cache *cache, *reuse;
-+      errcode_t       retval = 0;
-+      const char      *cp;
-+      int             writethrough;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct unix_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+#ifdef NO_IO_CACHE
-+      return raw_write_blk(channel, data, block, count, buf);
-+#else 
-+      /*
-+       * If we're doing an odd-sized write or a very large write,
-+       * flush out the cache completely and then do a direct write.
-+       */
-+      if (count < 0 || count > WRITE_DIRECT_SIZE) {
-+              if ((retval = flush_cached_blocks(channel, data, 1)))
-+                      return retval;
-+              return raw_write_blk(channel, data, block, count, buf);
-+      }
-+
-+      /*
-+       * For a moderate-sized multi-block write, first force a write
-+       * if we're in write-through cache mode, and then fill the
-+       * cache with the blocks.
-+       */
-+      writethrough = channel->flags & CHANNEL_FLAGS_WRITETHROUGH;
-+      if (writethrough)
-+              retval = raw_write_blk(channel, data, block, count, buf);
-+      
-+      cp = buf;
-+      while (count > 0) {
-+              cache = find_cached_block(data, block, &reuse);
-+              if (!cache) {
-+                      cache = reuse;
-+                      reuse_cache(channel, data, cache, block);
-+              }
-+              memcpy(cache->buf, cp, channel->block_size);
-+              cache->dirty = !writethrough;
-+              count--;
-+              block++;
-+              cp += channel->block_size;
-+      }
-+      return retval;
-+#endif /* NO_IO_CACHE */
-+}
-+
-+static errcode_t unix_write_byte(io_channel channel, unsigned long offset,
-+                               int size, const void *buf)
-+{
-+      struct unix_private_data *data;
-+      errcode_t       retval = 0;
-+      ssize_t         actual;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct unix_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+#ifndef NO_IO_CACHE
-+      /*
-+       * Flush out the cache completely
-+       */
-+      if ((retval = flush_cached_blocks(channel, data, 1)))
-+              return retval;
-+#endif
-+
-+      if (lseek(data->dev, offset + data->offset, SEEK_SET) < 0)
-+              return errno;
-+      
-+      actual = write(data->dev, buf, size);
-+      if (actual != size)
-+              return EXT2_ET_SHORT_WRITE;
-+
-+      return 0;
-+}
-+
-+/*
-+ * Flush data buffers to disk.  
-+ */
-+static errcode_t unix_flush(io_channel channel)
-+{
-+      struct unix_private_data *data;
-+      errcode_t retval = 0;
-+      
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct unix_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+#ifndef NO_IO_CACHE
-+      retval = flush_cached_blocks(channel, data, 0);
-+#endif
-+      fsync(data->dev);
-+      return retval;
-+}
-+
-+static errcode_t unix_set_option(io_channel channel, const char *option, 
-+                               const char *arg)
-+{
-+      struct unix_private_data *data;
-+      unsigned long tmp;
-+      char *end;
-+
-+      EXT2_CHECK_MAGIC(channel, EXT2_ET_MAGIC_IO_CHANNEL);
-+      data = (struct unix_private_data *) channel->private_data;
-+      EXT2_CHECK_MAGIC(data, EXT2_ET_MAGIC_UNIX_IO_CHANNEL);
-+
-+      if (!strcmp(option, "offset")) {
-+              if (!arg)
-+                      return EXT2_ET_INVALID_ARGUMENT;
-+
-+              tmp = strtoul(arg, &end, 0);
-+              if (*end)
-+                      return EXT2_ET_INVALID_ARGUMENT;
-+              data->offset = tmp;
-+              return 0;
-+      }
-+      return EXT2_ET_INVALID_ARGUMENT;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/unlink.c busybox/e2fsprogs/ext2fs/unlink.c
---- busybox-1.00/e2fsprogs/ext2fs/unlink.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/unlink.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,99 @@
-+/*
-+ * unlink.c --- delete links in a ext2fs directory
-+ * 
-+ * Copyright (C) 1993, 1994, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+struct link_struct  {
-+      const char      *name;
-+      int             namelen;
-+      ext2_ino_t      inode;
-+      int             flags;
-+      struct ext2_dir_entry *prev;
-+      int             done;
-+};    
-+
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+static int unlink_proc(struct ext2_dir_entry *dirent,
-+                   int        offset EXT2FS_ATTR((unused)),
-+                   int        blocksize EXT2FS_ATTR((unused)),
-+                   char       *buf EXT2FS_ATTR((unused)),
-+                   void       *priv_data)
-+{
-+      struct link_struct *ls = (struct link_struct *) priv_data;
-+      struct ext2_dir_entry *prev;
-+
-+      prev = ls->prev;
-+      ls->prev = dirent;
-+
-+      if (ls->name) {
-+              if ((dirent->name_len & 0xFF) != ls->namelen)
-+                      return 0;
-+              if (strncmp(ls->name, dirent->name, dirent->name_len & 0xFF))
-+                      return 0;
-+      }
-+      if (ls->inode) {
-+              if (dirent->inode != ls->inode)
-+                      return 0;
-+      } else {
-+              if (!dirent->inode)
-+                      return 0;
-+      }
-+
-+      if (prev) 
-+              prev->rec_len += dirent->rec_len;
-+      else
-+              dirent->inode = 0;
-+      ls->done++;
-+      return DIRENT_ABORT|DIRENT_CHANGED;
-+}
-+
-+#ifdef __TURBOC__
-+ #pragma argsused
-+#endif
-+errcode_t ext2fs_unlink(ext2_filsys fs, ext2_ino_t dir,
-+                      const char *name, ext2_ino_t ino,
-+                      int flags EXT2FS_ATTR((unused)))
-+{
-+      errcode_t       retval;
-+      struct link_struct ls;
-+
-+      EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
-+
-+      if (!name && !ino)
-+              return EXT2_ET_INVALID_ARGUMENT;
-+
-+      if (!(fs->flags & EXT2_FLAG_RW))
-+              return EXT2_ET_RO_FILSYS;
-+
-+      ls.name = name;
-+      ls.namelen = name ? strlen(name) : 0;
-+      ls.inode = ino;
-+      ls.flags = 0;
-+      ls.done = 0;
-+      ls.prev = 0;
-+
-+      retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY, 
-+                                  0, unlink_proc, &ls);
-+      if (retval)
-+              return retval;
-+
-+      return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/valid_blk.c busybox/e2fsprogs/ext2fs/valid_blk.c
---- busybox-1.00/e2fsprogs/ext2fs/valid_blk.c  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/valid_blk.c       2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,56 @@
-+/*
-+ * valid_blk.c --- does the inode have valid blocks?
-+ *
-+ * Copyright 1997 by Theodore Ts'o
-+ * 
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ * 
-+ */
-+
-+#include <stdio.h>
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <time.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+/*
-+ * This function returns 1 if the inode's block entries actually
-+ * contain block entries.
-+ */
-+int ext2fs_inode_has_valid_blocks(struct ext2_inode *inode)
-+{
-+      /*
-+       * Only directories, regular files, and some symbolic links
-+       * have valid block entries.
-+       */
-+      if (!LINUX_S_ISDIR(inode->i_mode) && !LINUX_S_ISREG(inode->i_mode) &&
-+          !LINUX_S_ISLNK(inode->i_mode))
-+              return 0;
-+      
-+      /*
-+       * If the symbolic link is a "fast symlink", then the symlink
-+       * target is stored in the block entries.
-+       */
-+      if (LINUX_S_ISLNK (inode->i_mode)) {
-+              if (inode->i_file_acl == 0) {
-+                      /* With no EA block, we can rely on i_blocks */
-+                      if (inode->i_blocks == 0)
-+                              return 0;
-+              } else {
-+                      /* With an EA block, life gets more tricky */
-+                      if (inode->i_size >= EXT2_N_BLOCKS*4)
-+                              return 1; /* definitely using i_block[] */
-+                      if (inode->i_size > 4 && inode->i_block[1] == 0)
-+                              return 1; /* definitely using i_block[] */
-+                      return 0; /* Probably a fast symlink */
-+              }
-+      }
-+      return 1;
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/version.c busybox/e2fsprogs/ext2fs/version.c
---- busybox-1.00/e2fsprogs/ext2fs/version.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/version.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,52 @@
-+/*
-+ * version.c --- Return the version of the ext2 library
-+ *
-+ * Copyright (C) 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#if HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#include <string.h>
-+#include <stdio.h>
-+#include <ctype.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+//#include "../../version.h"
-+
-+static const char *lib_version = E2FSPROGS_VERSION;
-+static const char *lib_date = E2FSPROGS_DATE;
-+
-+int ext2fs_parse_version_string(const char *ver_string)
-+{
-+      const char *cp;
-+      int version = 0;
-+
-+      for (cp = ver_string; *cp; cp++) {
-+              if (*cp == '.')
-+                      continue;
-+              if (!isdigit(*cp))
-+                      break;
-+              version = (version * 10) + (*cp - '0');
-+      }
-+      return version;
-+}
-+
-+
-+int ext2fs_get_library_version(const char **ver_string,
-+                             const char **date_string)
-+{
-+      if (ver_string)
-+              *ver_string = lib_version;
-+      if (date_string)
-+              *date_string = lib_date;
-+
-+      return ext2fs_parse_version_string(lib_version);
-+}
-diff -Nur busybox-1.00/e2fsprogs/ext2fs/write_bb_file.c busybox/e2fsprogs/ext2fs/write_bb_file.c
---- busybox-1.00/e2fsprogs/ext2fs/write_bb_file.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/ext2fs/write_bb_file.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,34 @@
-+/*
-+ * write_bb_file.c --- write a list of bad blocks to a FILE *
-+ *
-+ * Copyright (C) 1994, 1995 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+
-+#include "ext2_fs.h"
-+#include "ext2fs.h"
-+
-+errcode_t ext2fs_write_bb_FILE(ext2_badblocks_list bb_list,
-+                             unsigned int flags EXT2FS_ATTR((unused)),
-+                             FILE *f)
-+{
-+      badblocks_iterate       bb_iter;
-+      blk_t                   blk;
-+      errcode_t               retval;
-+
-+      retval = ext2fs_badblocks_list_iterate_begin(bb_list, &bb_iter);
-+      if (retval)
-+              return retval;
-+
-+      while (ext2fs_badblocks_list_iterate(bb_iter, &blk)) {
-+              fprintf(f, "%d\n", blk);
-+      }
-+      ext2fs_badblocks_list_iterate_end(bb_iter);
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/lsattr.c busybox/e2fsprogs/lsattr.c
---- busybox-1.00/e2fsprogs/lsattr.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/lsattr.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,141 @@
-+/*
-+ * lsattr.c           - List file attributes on an ext2 file system
-+ *
-+ * Copyright (C) 1993, 1994  Remy Card <card@masi.ibp.fr>
-+ *                           Laboratoire MASI, Institut Blaise Pascal
-+ *                           Universite Pierre et Marie Curie (Paris VI)
-+ *
-+ * This file can be redistributed under the terms of the GNU General
-+ * Public License
-+ */
-+
-+/*
-+ * History:
-+ * 93/10/30   - Creation
-+ * 93/11/13   - Replace stat() calls by lstat() to avoid loops
-+ * 94/02/27   - Integrated in Ted's distribution
-+ * 98/12/29   - Display version info only when -V specified (G M Sipe)
-+ */
-+
-+#include <sys/types.h>
-+#include <dirent.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <getopt.h>
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <sys/param.h>
-+#include <sys/stat.h>
-+
-+#include <ext2fs/ext2_fs.h>
-+#include "e2fsbb.h"
-+#include "e2p/e2p.h"
-+
-+#ifdef __GNUC__
-+# define EXT2FS_ATTR(x) __attribute__(x)
-+#else
-+# define EXT2FS_ATTR(x)
-+#endif
-+
-+#define OPT_RECUR 1
-+#define OPT_ALL 2
-+#define OPT_DIRS_OPT 4
-+#define OPT_PF_LONG 8
-+#define OPT_GENERATION 16
-+static int flags;
-+
-+#ifdef CONFIG_LFS
-+# define LSTAT lstat64
-+# define STRUCT_STAT struct stat64
-+#else
-+# define LSTAT lstat
-+# define STRUCT_STAT struct stat
-+#endif
-+
-+static void list_attributes(const char *name)
-+{
-+      unsigned long fsflags;
-+      unsigned long generation;
-+
-+      if (fgetflags(name, &fsflags) == -1)
-+              goto read_err;
-+      if (flags & OPT_GENERATION) {
-+              if (fgetversion(name, &generation) == -1)
-+                      goto read_err;
-+              printf("%5lu ", generation);
-+      }
-+
-+      if (flags & OPT_PF_LONG) {
-+              printf("%-28s ", name);
-+              print_flags(stdout, fsflags, PFOPT_LONG);
-+              printf("\n");
-+      } else {
-+              print_flags(stdout, fsflags, 0);
-+              printf(" %s\n", name);
-+      }
-+
-+      return;
-+read_err:
-+      bb_perror_msg("reading %s", name);
-+}
-+
-+static int lsattr_dir_proc(const char *, struct dirent *, void *);
-+
-+static void lsattr_args(const char *name)
-+{
-+      STRUCT_STAT     st;
-+
-+      if (LSTAT(name, &st) == -1) {
-+              bb_perror_msg("stating %s", name);
-+      } else {
-+              if (S_ISDIR(st.st_mode) && !(flags & OPT_DIRS_OPT))
-+                      iterate_on_dir(name, lsattr_dir_proc, NULL);
-+              else
-+                      list_attributes(name);
-+      }
-+}
-+
-+static int lsattr_dir_proc(const char *dir_name, struct dirent *de, 
-+                           void *private EXT2FS_ATTR((unused)))
-+{
-+      STRUCT_STAT     st;
-+      char *path;
-+
-+      path = concat_path_file(dir_name, de->d_name);
-+
-+      if (LSTAT(path, &st) == -1)
-+              bb_perror_msg(path);
-+      else {
-+              if (de->d_name[0] != '.' || (flags & OPT_ALL)) {
-+                      list_attributes(path);
-+                      if (S_ISDIR(st.st_mode) && (flags & OPT_RECUR) &&
-+                         (de->d_name[0] != '.' && (de->d_name[1] != '\0' ||
-+                         (de->d_name[1] != '.' && de->d_name[2] != '\0')))) {
-+                              printf("\n%s:\n", path);
-+                              iterate_on_dir(path, lsattr_dir_proc, NULL);
-+                              printf("\n");
-+                      }
-+              }
-+      }
-+
-+      free(path);
-+
-+      return 0;
-+}
-+
-+int lsattr_main(int argc, char **argv)
-+{
-+      int i;
-+
-+      flags = bb_getopt_ulflags(argc, argv, "Radlv");
-+
-+      if (optind > argc - 1)
-+              lsattr_args(".");
-+      else
-+              for (i = optind; i < argc; i++)
-+                      lsattr_args(argv[i]);
-+
-+      return EXIT_SUCCESS;
-+}
-diff -Nur busybox-1.00/e2fsprogs/util.c busybox/e2fsprogs/util.c
---- busybox-1.00/e2fsprogs/util.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/util.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,207 @@
-+/*
-+ * util.c --- helper functions used by tune2fs and mke2fs
-+ * 
-+ * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <string.h>
-+#include <errno.h>
-+#include <linux/major.h>
-+#include <sys/stat.h>
-+
-+#include "e2fsbb.h"
-+#include "e2p/e2p.h"
-+#include "ext2fs/ext2_fs.h"
-+#include "ext2fs/ext2fs.h"
-+#include "blkid/blkid.h"
-+#include "util.h"
-+
-+void proceed_question(void)
-+{
-+      fputs("Proceed anyway? (y,n) ", stdout);
-+      if (bb_ask_confirmation() == 0)
-+              exit(1);
-+}
-+
-+void check_plausibility(const char *device)
-+{
-+      int val;
-+#ifdef CONFIG_LFS
-+      struct stat64 s;
-+      val = stat64(device, &s);
-+#else
-+      struct stat s;
-+      val = stat(device, &s);
-+#endif
-+
-+      if(val == -1)
-+              bb_perror_msg_and_die("Could not stat %s", device);
-+      if (!S_ISBLK(s.st_mode)) {
-+              printf("%s is not a block special device.\n", device);
-+              proceed_question();
-+              return;
-+      }
-+
-+#ifdef HAVE_LINUX_MAJOR_H
-+#ifndef MAJOR
-+#define MAJOR(dev)    ((dev)>>8)
-+#define MINOR(dev)    ((dev) & 0xff)
-+#endif
-+#ifndef SCSI_BLK_MAJOR
-+#ifdef SCSI_DISK0_MAJOR
-+#ifdef SCSI_DISK8_MAJOR
-+#define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \
-+  ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR) || \
-+  ((M) >= SCSI_DISK8_MAJOR && (M) <= SCSI_DISK15_MAJOR))
-+#else
-+#define SCSI_DISK_MAJOR(M) ((M) == SCSI_DISK0_MAJOR || \
-+  ((M) >= SCSI_DISK1_MAJOR && (M) <= SCSI_DISK7_MAJOR))
-+#endif /* defined(SCSI_DISK8_MAJOR) */
-+#define SCSI_BLK_MAJOR(M) (SCSI_DISK_MAJOR((M)) || (M) == SCSI_CDROM_MAJOR)
-+#else
-+#define SCSI_BLK_MAJOR(M)  ((M) == SCSI_DISK_MAJOR || (M) == SCSI_CDROM_MAJOR)
-+#endif /* defined(SCSI_DISK0_MAJOR) */
-+#endif /* defined(SCSI_BLK_MAJOR) */
-+      if (((MAJOR(s.st_rdev) == HD_MAJOR &&
-+            MINOR(s.st_rdev)%64 == 0) ||
-+           (SCSI_BLK_MAJOR(MAJOR(s.st_rdev)) &&
-+            MINOR(s.st_rdev)%16 == 0))) {
-+              printf("%s is entire device, not just one partition!\n", device);
-+              proceed_question();
-+      }
-+#endif
-+}
-+
-+void check_mount(const char *device, int force, const char *type)
-+{
-+      errcode_t retval;
-+      int mount_flags;
-+
-+      retval = ext2fs_check_if_mounted(device, &mount_flags);
-+      if (retval) {
-+              bb_error_msg("Could not determine if %s is mounted", device);
-+              return;
-+      }
-+      if (!(mount_flags & EXT2_MF_MOUNTED))
-+              return;
-+
-+      bb_error_msg("%s is mounted !", device);
-+      if (force)
-+              bb_error_msg("forcing anyways and ignoring /etc/mtab status");
-+      else
-+              bb_error_msg_and_die("will not make a %s here!", type);
-+}
-+
-+void parse_journal_opts(char **journal_device, int *journal_flags, 
-+                        int *journal_size, const char *opts)
-+{
-+      char *buf, *token, *next, *p, *arg;
-+      int journal_usage = 0;
-+#if 0
-+      int     len;
-+      len = strlen(opts);
-+      buf = xmalloc(len+1);
-+      strcpy(buf, opts);
-+#else
-+      buf = bb_xstrdup(opts);
-+#endif
-+      for (token = buf; token && *token; token = next) {
-+              p = strchr(token, ',');
-+              next = 0;
-+              if (p) {
-+                      *p = 0;
-+                      next = p+1;
-+              } 
-+              arg = strchr(token, '=');
-+              if (arg) {
-+                      *arg = 0;
-+                      arg++;
-+              }
-+              if (strcmp(token, "device") == 0) {
-+                      *journal_device = blkid_get_devname(NULL, arg, NULL);
-+                      if (!journal_device) {
-+                              journal_usage++;
-+                              continue;
-+                      }
-+              } else if (strcmp(token, "size") == 0) {
-+                      if (!arg) {
-+                              journal_usage++;
-+                              continue;
-+                      }
-+                      (*journal_size) = strtoul(arg, &p, 0);
-+                      if (*p)
-+                              journal_usage++;
-+              } else if (strcmp(token, "v1_superblock") == 0) {
-+                      (*journal_flags) |= EXT2_MKJOURNAL_V1_SUPER;
-+                      continue;
-+              } else
-+                      journal_usage++;
-+      }
-+      if (journal_usage)
-+              bb_error_msg_and_die(
-+                      "\nBad journal options specified.\n\n"
-+                      "Journal options are separated by commas, "
-+                      "and may take an argument which\n"
-+                      "\tis set off by an equals ('=') sign.\n\n"
-+                      "Valid journal options are:\n"
-+                      "\tsize=<journal size in megabytes>\n"
-+                      "\tdevice=<journal device>\n\n"
-+                      "The journal size must be between "
-+                      "1024 and 102400 filesystem blocks.\n\n");
-+}     
-+
-+/*
-+ * Determine the number of journal blocks to use, either via
-+ * user-specified # of megabytes, or via some intelligently selected
-+ * defaults.
-+ * 
-+ * Find a reasonable journal file size (in blocks) given the number of blocks
-+ * in the filesystem.  For very small filesystems, it is not reasonable to
-+ * have a journal that fills more than half of the filesystem.
-+ */
-+int figure_journal_size(int size, ext2_filsys fs)
-+{
-+      blk_t j_blocks;
-+
-+      if (fs->super->s_blocks_count < 2048) {
-+              bb_error_msg("Filesystem too small for a journal");
-+              return 0;
-+      }
-+
-+      if (size >= 0) {
-+              j_blocks = size * 1024 / (fs->blocksize / 1024);
-+              if (j_blocks < 1024 || j_blocks > 102400)
-+                      bb_error_msg_and_die("\nThe requested journal "
-+                              "size is %d blocks;\n it must be "
-+                              "between 1024 and 102400 blocks; Aborting",
-+                              j_blocks);
-+              if (j_blocks > fs->super->s_free_blocks_count)
-+                      bb_error_msg_and_die("Journal size too big for filesystem");
-+              return j_blocks;
-+      }
-+
-+      if (fs->super->s_blocks_count < 32768)
-+              j_blocks = 1024;
-+      else if (fs->super->s_blocks_count < 262144)
-+              j_blocks = 4096;
-+      else
-+              j_blocks = 8192;
-+
-+      return j_blocks;
-+}
-+
-+void print_check_message(ext2_filsys fs)
-+{
-+      printf("This filesystem will be automatically "
-+               "checked every %d mounts or\n"
-+               "%g days, whichever comes first.  "
-+               "Use tune2fs -c or -i to override.\n",
-+             fs->super->s_max_mnt_count,
-+             (double)fs->super->s_checkinterval / (3600 * 24));
-+}
-diff -Nur busybox-1.00/e2fsprogs/util.h busybox/e2fsprogs/util.h
---- busybox-1.00/e2fsprogs/util.h      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/util.h   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,18 @@
-+/*
-+ * util.h --- header file defining prototypes for helper functions
-+ * used by tune2fs and mke2fs
-+ * 
-+ * Copyright 2000 by Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * This file may be redistributed under the terms of the GNU Public
-+ * License.
-+ * %End-Header%
-+ */
-+
-+extern void proceed_question(void);
-+extern void check_plausibility(const char *device);
-+extern void parse_journal_opts(char **, int *, int *, const char *opts);
-+extern void check_mount(const char *device, int force, const char *type);
-+extern int figure_journal_size(int size, ext2_filsys fs);
-+extern void print_check_message(ext2_filsys fs);
-diff -Nur busybox-1.00/e2fsprogs/uuid/clear.c busybox/e2fsprogs/uuid/clear.c
---- busybox-1.00/e2fsprogs/uuid/clear.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/clear.c     2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,43 @@
-+/*
-+ * clear.c -- Clear a UUID
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#include "string.h"
-+
-+#include "uuidP.h"
-+
-+void uuid_clear(uuid_t uu)
-+{
-+      memset(uu, 0, 16);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/uuid/compare.c busybox/e2fsprogs/uuid/compare.c
---- busybox-1.00/e2fsprogs/uuid/compare.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/compare.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,55 @@
-+/*
-+ * compare.c --- compare whether or not two UUID's are the same
-+ *
-+ * Returns 0 if the two UUID's are different, and 1 if they are the same.
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#include "uuidP.h"
-+#include <string.h>
-+
-+#define UUCMP(u1,u2) if (u1 != u2) return((u1 < u2) ? -1 : 1);
-+
-+int uuid_compare(const uuid_t uu1, const uuid_t uu2)
-+{
-+      struct uuid     uuid1, uuid2;
-+
-+      uuid_unpack(uu1, &uuid1);
-+      uuid_unpack(uu2, &uuid2);
-+
-+      UUCMP(uuid1.time_low, uuid2.time_low);
-+      UUCMP(uuid1.time_mid, uuid2.time_mid);
-+      UUCMP(uuid1.time_hi_and_version, uuid2.time_hi_and_version);
-+      UUCMP(uuid1.clock_seq, uuid2.clock_seq);
-+      return memcmp(uuid1.node, uuid2.node, 6);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/uuid/copy.c busybox/e2fsprogs/uuid/copy.c
---- busybox-1.00/e2fsprogs/uuid/copy.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/copy.c      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,45 @@
-+/*
-+ * copy.c --- copy UUIDs
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#include "uuidP.h"
-+
-+void uuid_copy(uuid_t dst, const uuid_t src)
-+{
-+      unsigned char           *cp1;
-+      const unsigned char     *cp2;
-+      int                     i;
-+
-+      for (i=0, cp1 = dst, cp2 = src; i < 16; i++)
-+              *cp1++ = *cp2++;
-+}
-diff -Nur busybox-1.00/e2fsprogs/uuid/gen_uuid.c busybox/e2fsprogs/uuid/gen_uuid.c
---- busybox-1.00/e2fsprogs/uuid/gen_uuid.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/gen_uuid.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,310 @@
-+/*
-+ * gen_uuid.c --- generate a DCE-compatible uuid
-+ *
-+ * Copyright (C) 1996, 1997, 1998, 1999 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#ifdef HAVE_UNISTD_H
-+#include <unistd.h>
-+#endif
-+#ifdef HAVE_STDLIB_H
-+#include <stdlib.h>
-+#endif
-+#include <string.h>
-+#include <fcntl.h>
-+#include <errno.h>
-+#include <sys/types.h>
-+#include <sys/time.h>
-+#include <sys/stat.h>
-+#include <sys/file.h>
-+#ifdef HAVE_SYS_IOCTL_H
-+#include <sys/ioctl.h>
-+#endif
-+#ifdef HAVE_SYS_SOCKET_H
-+#include <sys/socket.h>
-+#endif
-+#ifdef HAVE_SYS_SOCKIO_H
-+#include <sys/sockio.h>
-+#endif
-+#ifdef HAVE_NET_IF_H
-+#include <net/if.h>
-+#endif
-+#ifdef HAVE_NETINET_IN_H
-+#include <netinet/in.h>
-+#endif
-+#ifdef HAVE_NET_IF_DL_H
-+#include <net/if_dl.h>
-+#endif
-+
-+#include "uuidP.h"
-+
-+#ifdef HAVE_SRANDOM
-+#define srand(x)      srandom(x)
-+#define rand()                random()
-+#endif
-+
-+static int get_random_fd(void)
-+{
-+      struct timeval  tv;
-+      static int      fd = -2;
-+      int             i;
-+
-+      if (fd == -2) {
-+              gettimeofday(&tv, 0);
-+              fd = open("/dev/urandom", O_RDONLY);
-+              if (fd == -1)
-+                      fd = open("/dev/random", O_RDONLY | O_NONBLOCK);
-+              srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
-+      }
-+      /* Crank the random number generator a few times */
-+      gettimeofday(&tv, 0);
-+      for (i = (tv.tv_sec ^ tv.tv_usec) & 0x1F; i > 0; i--)
-+              rand();
-+      return fd;
-+}
-+
-+
-+/*
-+ * Generate a series of random bytes.  Use /dev/urandom if possible,
-+ * and if not, use srandom/random.
-+ */
-+static void get_random_bytes(void *buf, int nbytes)
-+{
-+      int i, n = nbytes, fd = get_random_fd();
-+      int lose_counter = 0;
-+      unsigned char *cp = (unsigned char *) buf;
-+
-+      if (fd >= 0) {
-+              while (n > 0) {
-+                      i = read(fd, cp, n);
-+                      if (i <= 0) {
-+                              if (lose_counter++ > 16)
-+                                      break;
-+                              continue;
-+                      }
-+                      n -= i;
-+                      cp += i;
-+                      lose_counter = 0;
-+              }
-+      }
-+      
-+      /*
-+       * We do this all the time, but this is the only source of
-+       * randomness if /dev/random/urandom is out to lunch.
-+       */
-+      for (cp = buf, i = 0; i < nbytes; i++)
-+              *cp++ ^= (rand() >> 7) & 0xFF;
-+      return;
-+}
-+
-+/*
-+ * Get the ethernet hardware address, if we can find it...
-+ */
-+static int get_node_id(unsigned char *node_id)
-+{
-+#ifdef HAVE_NET_IF_H
-+      int             sd;
-+      struct ifreq    ifr, *ifrp;
-+      struct ifconf   ifc;
-+      char buf[1024];
-+      int             n, i;
-+      unsigned char   *a;
-+#ifdef HAVE_NET_IF_DL_H
-+      struct sockaddr_dl *sdlp;
-+#endif
-+
-+/*
-+ * BSD 4.4 defines the size of an ifreq to be
-+ * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
-+ * However, under earlier systems, sa_len isn't present, so the size is 
-+ * just sizeof(struct ifreq)
-+ */
-+#ifdef HAVE_SA_LEN
-+#ifndef max
-+#define max(a,b) ((a) > (b) ? (a) : (b))
-+#endif
-+#define ifreq_size(i) max(sizeof(struct ifreq),\
-+     sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
-+#else
-+#define ifreq_size(i) sizeof(struct ifreq)
-+#endif /* HAVE_SA_LEN*/
-+
-+      sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
-+      if (sd < 0) {
-+              return -1;
-+      }
-+      memset(buf, 0, sizeof(buf));
-+      ifc.ifc_len = sizeof(buf);
-+      ifc.ifc_buf = buf;
-+      if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0) {
-+              close(sd);
-+              return -1;
-+      }
-+      n = ifc.ifc_len;
-+      for (i = 0; i < n; i+= ifreq_size(*ifrp) ) {
-+              ifrp = (struct ifreq *)((char *) ifc.ifc_buf+i);
-+              strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
-+#ifdef SIOCGIFHWADDR
-+              if (ioctl(sd, SIOCGIFHWADDR, &ifr) < 0)
-+                      continue;
-+              a = (unsigned char *) &ifr.ifr_hwaddr.sa_data;
-+#else
-+#ifdef SIOCGENADDR
-+              if (ioctl(sd, SIOCGENADDR, &ifr) < 0)
-+                      continue;
-+              a = (unsigned char *) ifr.ifr_enaddr;
-+#else
-+#ifdef HAVE_NET_IF_DL_H
-+              sdlp = (struct sockaddr_dl *) &ifrp->ifr_addr;
-+              if ((sdlp->sdl_family != AF_LINK) || (sdlp->sdl_alen != 6))
-+                      continue;
-+              a = (unsigned char *) &sdlp->sdl_data[sdlp->sdl_nlen];
-+#else
-+              /*
-+               * XXX we don't have a way of getting the hardware
-+               * address
-+               */
-+              close(sd);
-+              return 0;
-+#endif /* HAVE_NET_IF_DL_H */
-+#endif /* SIOCGENADDR */
-+#endif /* SIOCGIFHWADDR */
-+              if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
-+                      continue;
-+              if (node_id) {
-+                      memcpy(node_id, a, 6);
-+                      close(sd);
-+                      return 1;
-+              }
-+      }
-+      close(sd);
-+#endif
-+      return 0;
-+}
-+
-+/* Assume that the gettimeofday() has microsecond granularity */
-+#define MAX_ADJUSTMENT 10
-+
-+static int get_clock(uint32_t *clock_high, uint32_t *clock_low, uint16_t *ret_clock_seq)
-+{
-+      static int                      adjustment = 0;
-+      static struct timeval           last = {0, 0};
-+      static uint16_t                 clock_seq;
-+      struct timeval                  tv;
-+      unsigned long long              clock_reg;
-+      
-+try_again:
-+      gettimeofday(&tv, 0);
-+      if ((last.tv_sec == 0) && (last.tv_usec == 0)) {
-+              get_random_bytes(&clock_seq, sizeof(clock_seq));
-+              clock_seq &= 0x3FFF;
-+              last = tv;
-+              last.tv_sec--;
-+      }
-+      if ((tv.tv_sec < last.tv_sec) ||
-+          ((tv.tv_sec == last.tv_sec) &&
-+           (tv.tv_usec < last.tv_usec))) {
-+              clock_seq = (clock_seq+1) & 0x3FFF;
-+              adjustment = 0;
-+              last = tv;
-+      } else if ((tv.tv_sec == last.tv_sec) &&
-+          (tv.tv_usec == last.tv_usec)) {
-+              if (adjustment >= MAX_ADJUSTMENT)
-+                      goto try_again;
-+              adjustment++;
-+      } else {
-+              adjustment = 0;
-+              last = tv;
-+      }
-+              
-+      clock_reg = tv.tv_usec*10 + adjustment;
-+      clock_reg += ((unsigned long long) tv.tv_sec)*10000000;
-+      clock_reg += (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
-+
-+      *clock_high = clock_reg >> 32;
-+      *clock_low = clock_reg;
-+      *ret_clock_seq = clock_seq;
-+      return 0;
-+}
-+
-+void uuid_generate_time(uuid_t out)
-+{
-+      static unsigned char node_id[6];
-+      static int has_init = 0;
-+      struct uuid uu;
-+      uint32_t        clock_mid;
-+
-+      if (!has_init) {
-+              if (get_node_id(node_id) <= 0) {
-+                      get_random_bytes(node_id, 6);
-+                      /*
-+                       * Set multicast bit, to prevent conflicts
-+                       * with IEEE 802 addresses obtained from
-+                       * network cards
-+                       */
-+                      node_id[0] |= 0x01;
-+              }
-+              has_init = 1;
-+      }
-+      get_clock(&clock_mid, &uu.time_low, &uu.clock_seq);
-+      uu.clock_seq |= 0x8000;
-+      uu.time_mid = (uint16_t) clock_mid;
-+      uu.time_hi_and_version = ((clock_mid >> 16) & 0x0FFF) | 0x1000;
-+      memcpy(uu.node, node_id, 6);
-+      uuid_pack(&uu, out);
-+}
-+
-+void uuid_generate_random(uuid_t out)
-+{
-+      uuid_t  buf;
-+      struct uuid uu;
-+
-+      get_random_bytes(buf, sizeof(buf));
-+      uuid_unpack(buf, &uu);
-+
-+      uu.clock_seq = (uu.clock_seq & 0x3FFF) | 0x8000;
-+      uu.time_hi_and_version = (uu.time_hi_and_version & 0x0FFF) | 0x4000;
-+      uuid_pack(&uu, out);
-+}
-+
-+/*
-+ * This is the generic front-end to uuid_generate_random and
-+ * uuid_generate_time.  It uses uuid_generate_random only if
-+ * /dev/urandom is available, since otherwise we won't have
-+ * high-quality randomness.
-+ */
-+void uuid_generate(uuid_t out)
-+{
-+      if (get_random_fd() >= 0)
-+              uuid_generate_random(out);
-+      else
-+              uuid_generate_time(out);
-+}
-diff -Nur busybox-1.00/e2fsprogs/uuid/isnull.c busybox/e2fsprogs/uuid/isnull.c
---- busybox-1.00/e2fsprogs/uuid/isnull.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/isnull.c    2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,48 @@
-+/*
-+ * isnull.c --- Check whether or not the UUID is null
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#include "uuidP.h"
-+
-+/* Returns 1 if the uuid is the NULL uuid */
-+int uuid_is_null(const uuid_t uu)
-+{
-+      const unsigned char     *cp;
-+      int                     i;
-+
-+      for (i=0, cp = uu; i < 16; i++)
-+              if (*cp++)
-+                      return 0;
-+      return 1;
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/uuid/pack.c busybox/e2fsprogs/uuid/pack.c
---- busybox-1.00/e2fsprogs/uuid/pack.c 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/pack.c      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,69 @@
-+/*
-+ * Internal routine for packing UUID's
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#include <string.h>
-+#include "uuidP.h"
-+
-+void uuid_pack(const struct uuid *uu, uuid_t ptr)
-+{
-+      uint32_t        tmp;
-+      unsigned char   *out = ptr;
-+
-+      tmp = uu->time_low;
-+      out[3] = (unsigned char) tmp;
-+      tmp >>= 8;
-+      out[2] = (unsigned char) tmp;
-+      tmp >>= 8;
-+      out[1] = (unsigned char) tmp;
-+      tmp >>= 8;
-+      out[0] = (unsigned char) tmp;
-+      
-+      tmp = uu->time_mid;
-+      out[5] = (unsigned char) tmp;
-+      tmp >>= 8;
-+      out[4] = (unsigned char) tmp;
-+
-+      tmp = uu->time_hi_and_version;
-+      out[7] = (unsigned char) tmp;
-+      tmp >>= 8;
-+      out[6] = (unsigned char) tmp;
-+
-+      tmp = uu->clock_seq;
-+      out[9] = (unsigned char) tmp;
-+      tmp >>= 8;
-+      out[8] = (unsigned char) tmp;
-+
-+      memcpy(out+10, uu->node, 6);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/uuid/parse.c busybox/e2fsprogs/uuid/parse.c
---- busybox-1.00/e2fsprogs/uuid/parse.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/parse.c     2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,79 @@
-+/*
-+ * parse.c --- UUID parsing
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <ctype.h>
-+#include <string.h>
-+
-+#include "uuidP.h"
-+
-+int uuid_parse(const char *in, uuid_t uu)
-+{
-+      struct uuid     uuid;
-+      int             i;
-+      const char      *cp;
-+      char            buf[3];
-+
-+      if (strlen(in) != 36)
-+              return -1;
-+      for (i=0, cp = in; i <= 36; i++,cp++) {
-+              if ((i == 8) || (i == 13) || (i == 18) ||
-+                  (i == 23)) {
-+                      if (*cp == '-')
-+                              continue;
-+                      else
-+                              return -1;
-+              }
-+              if (i== 36)
-+                      if (*cp == 0)
-+                              continue;
-+              if (!isxdigit(*cp))
-+                      return -1;
-+      }
-+      uuid.time_low = strtoul(in, NULL, 16);
-+      uuid.time_mid = strtoul(in+9, NULL, 16);
-+      uuid.time_hi_and_version = strtoul(in+14, NULL, 16);
-+      uuid.clock_seq = strtoul(in+19, NULL, 16);
-+      cp = in+24;
-+      buf[2] = 0;
-+      for (i=0; i < 6; i++) {
-+              buf[0] = *cp++;
-+              buf[1] = *cp++;
-+              uuid.node[i] = strtoul(buf, NULL, 16);
-+      }
-+      
-+      uuid_pack(&uuid, uu);
-+      return 0;
-+}
-diff -Nur busybox-1.00/e2fsprogs/uuid/unpack.c busybox/e2fsprogs/uuid/unpack.c
---- busybox-1.00/e2fsprogs/uuid/unpack.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/unpack.c    2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,63 @@
-+/*
-+ * Internal routine for unpacking UUID
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#include <string.h>
-+#include "uuidP.h"
-+
-+void uuid_unpack(const uuid_t in, struct uuid *uu)
-+{
-+      const uint8_t   *ptr = in;
-+      uint32_t                tmp;
-+
-+      tmp = *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      uu->time_low = tmp;
-+
-+      tmp = *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      uu->time_mid = tmp;
-+      
-+      tmp = *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      uu->time_hi_and_version = tmp;
-+
-+      tmp = *ptr++;
-+      tmp = (tmp << 8) | *ptr++;
-+      uu->clock_seq = tmp;
-+
-+      memcpy(uu->node, ptr, 6);
-+}
-+
-diff -Nur busybox-1.00/e2fsprogs/uuid/unparse.c busybox/e2fsprogs/uuid/unparse.c
---- busybox-1.00/e2fsprogs/uuid/unparse.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/unparse.c   2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,76 @@
-+/*
-+ * unparse.c -- convert a UUID to string
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+
-+#include "uuidP.h"
-+
-+static const char *fmt_lower = 
-+      "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x";
-+
-+static const char *fmt_upper = 
-+      "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X";
-+
-+#ifdef UUID_UNPARSE_DEFAULT_UPPER
-+#define FMT_DEFAULT fmt_upper
-+#else
-+#define FMT_DEFAULT fmt_lower
-+#endif
-+
-+static void uuid_unparse_x(const uuid_t uu, char *out, const char *fmt)
-+{
-+      struct uuid uuid;
-+
-+      uuid_unpack(uu, &uuid);
-+      sprintf(out, fmt,
-+              uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
-+              uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
-+              uuid.node[0], uuid.node[1], uuid.node[2],
-+              uuid.node[3], uuid.node[4], uuid.node[5]);
-+}
-+
-+void uuid_unparse_lower(const uuid_t uu, char *out)
-+{
-+      uuid_unparse_x(uu, out, fmt_lower);
-+}
-+
-+void uuid_unparse_upper(const uuid_t uu, char *out)
-+{
-+      uuid_unparse_x(uu, out, fmt_upper);
-+}
-+
-+void uuid_unparse(const uuid_t uu, char *out)
-+{
-+      uuid_unparse_x(uu, out, FMT_DEFAULT);
-+}
-diff -Nur busybox-1.00/e2fsprogs/uuid/uuid.h busybox/e2fsprogs/uuid/uuid.h
---- busybox-1.00/e2fsprogs/uuid/uuid.h 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/uuid.h      2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,101 @@
-+/*
-+ * Public include file for the UUID library
-+ * 
-+ * Copyright (C) 1996, 1997, 1998 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#ifndef _UUID_UUID_H
-+#define _UUID_UUID_H
-+
-+#include <sys/types.h>
-+#include <sys/time.h>
-+#include <time.h>
-+
-+typedef unsigned char uuid_t[16];
-+
-+/* UUID Variant definitions */
-+#define UUID_VARIANT_NCS      0
-+#define UUID_VARIANT_DCE      1
-+#define UUID_VARIANT_MICROSOFT        2
-+#define UUID_VARIANT_OTHER    3
-+
-+/* UUID Type definitions */
-+#define UUID_TYPE_DCE_TIME   1
-+#define UUID_TYPE_DCE_RANDOM 4
-+
-+/* Allow UUID constants to be defined */
-+#ifdef __GNUC__
-+#define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \
-+      static const uuid_t name __attribute__ ((unused)) = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15}
-+#else
-+#define UUID_DEFINE(name,u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15) \
-+      static const uuid_t name = {u0,u1,u2,u3,u4,u5,u6,u7,u8,u9,u10,u11,u12,u13,u14,u15}
-+#endif
-+
-+#ifdef __cplusplus
-+extern "C" {
-+#endif
-+
-+/* clear.c */
-+void uuid_clear(uuid_t uu);
-+
-+/* compare.c */
-+int uuid_compare(const uuid_t uu1, const uuid_t uu2);
-+
-+/* copy.c */
-+void uuid_copy(uuid_t dst, const uuid_t src);
-+
-+/* gen_uuid.c */
-+void uuid_generate(uuid_t out);
-+void uuid_generate_random(uuid_t out);
-+void uuid_generate_time(uuid_t out);
-+
-+/* isnull.c */
-+int uuid_is_null(const uuid_t uu);
-+
-+/* parse.c */
-+int uuid_parse(const char *in, uuid_t uu);
-+
-+/* unparse.c */
-+void uuid_unparse(const uuid_t uu, char *out);
-+void uuid_unparse_lower(const uuid_t uu, char *out);
-+void uuid_unparse_upper(const uuid_t uu, char *out);
-+
-+/* uuid_time.c */
-+time_t uuid_time(const uuid_t uu, struct timeval *ret_tv);
-+int uuid_type(const uuid_t uu);
-+int uuid_variant(const uuid_t uu);
-+
-+#ifdef __cplusplus
-+}
-+#endif
-+
-+#endif /* _UUID_UUID_H */
-diff -Nur busybox-1.00/e2fsprogs/uuid/uuidP.h busybox/e2fsprogs/uuid/uuidP.h
---- busybox-1.00/e2fsprogs/uuid/uuidP.h        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/uuidP.h     2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,63 @@
-+/*
-+ * uuid.h -- private header file for uuids
-+ * 
-+ * Copyright (C) 1996, 1997 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#ifdef HAVE_INTTYPES_H
-+#include <inttypes.h>
-+#else
-+#include <uuid/uuid_types.h>
-+#endif
-+#include <sys/types.h>
-+
-+#include "uuid.h"
-+
-+/*
-+ * Offset between 15-Oct-1582 and 1-Jan-70
-+ */
-+#define TIME_OFFSET_HIGH 0x01B21DD2
-+#define TIME_OFFSET_LOW  0x13814000
-+
-+struct uuid {
-+      uint32_t        time_low;
-+      uint16_t        time_mid;
-+      uint16_t        time_hi_and_version;
-+      uint16_t        clock_seq;
-+      uint8_t node[6];
-+};
-+
-+
-+/*
-+ * prototypes
-+ */
-+void uuid_pack(const struct uuid *uu, uuid_t ptr);
-+void uuid_unpack(const uuid_t in, struct uuid *uu);
-diff -Nur busybox-1.00/e2fsprogs/uuid/uuid_time.c busybox/e2fsprogs/uuid/uuid_time.c
---- busybox-1.00/e2fsprogs/uuid/uuid_time.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/e2fsprogs/uuid/uuid_time.c 2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,161 @@
-+/*
-+ * uuid_time.c --- Interpret the time field from a uuid.  This program
-+ *    violates the UUID abstraction barrier by reaching into the guts
-+ *    of a UUID and interpreting it.
-+ * 
-+ * Copyright (C) 1998, 1999 Theodore Ts'o.
-+ *
-+ * %Begin-Header%
-+ * 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, and the entire permission notice in its entirety,
-+ *    including the disclaimer of warranties.
-+ * 2. Redistributions in binary form must reproduce the above copyright
-+ *    notice, this list of conditions and the following disclaimer in the
-+ *    documentation and/or other materials provided with the distribution.
-+ * 3. 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 ``AS IS'' AND ANY EXPRESS OR IMPLIED
-+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF
-+ * WHICH ARE HEREBY 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 NOT ADVISED OF THE POSSIBILITY OF SUCH
-+ * DAMAGE.
-+ * %End-Header%
-+ */
-+
-+#include <stdio.h>
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <sys/types.h>
-+#include <sys/time.h>
-+#include <time.h>
-+
-+#include "uuidP.h"
-+
-+time_t uuid_time(const uuid_t uu, struct timeval *ret_tv)
-+{
-+      struct uuid             uuid;
-+      uint32_t                        high;
-+      struct timeval          tv;
-+      unsigned long long      clock_reg;
-+
-+      uuid_unpack(uu, &uuid);
-+      
-+      high = uuid.time_mid | ((uuid.time_hi_and_version & 0xFFF) << 16);
-+      clock_reg = uuid.time_low | ((unsigned long long) high << 32);
-+
-+      clock_reg -= (((unsigned long long) 0x01B21DD2) << 32) + 0x13814000;
-+      tv.tv_sec = clock_reg / 10000000;
-+      tv.tv_usec = (clock_reg % 10000000) / 10;
-+
-+      if (ret_tv)
-+              *ret_tv = tv;
-+
-+      return tv.tv_sec;
-+}
-+
-+int uuid_type(const uuid_t uu)
-+{
-+      struct uuid             uuid;
-+
-+      uuid_unpack(uu, &uuid); 
-+      return ((uuid.time_hi_and_version >> 12) & 0xF);
-+}
-+
-+int uuid_variant(const uuid_t uu)
-+{
-+      struct uuid             uuid;
-+      int                     var;
-+
-+      uuid_unpack(uu, &uuid); 
-+      var = uuid.clock_seq;
-+
-+      if ((var & 0x8000) == 0)
-+              return UUID_VARIANT_NCS;
-+      if ((var & 0x4000) == 0)
-+              return UUID_VARIANT_DCE;
-+      if ((var & 0x2000) == 0)
-+              return UUID_VARIANT_MICROSOFT;
-+      return UUID_VARIANT_OTHER;
-+}
-+
-+#ifdef DEBUG
-+static const char *variant_string(int variant)
-+{
-+      switch (variant) {
-+      case UUID_VARIANT_NCS:
-+              return "NCS";
-+      case UUID_VARIANT_DCE:
-+              return "DCE";
-+      case UUID_VARIANT_MICROSOFT:
-+              return "Microsoft";
-+      default:
-+              return "Other";
-+      }
-+}
-+
-+      
-+int
-+main(int argc, char **argv)
-+{
-+      uuid_t          buf;
-+      time_t          time_reg;
-+      struct timeval  tv;
-+      int             type, variant;
-+
-+      if (argc != 2) {
-+              fprintf(stderr, "Usage: %s uuid\n", argv[0]);
-+              exit(1);
-+      }
-+      if (uuid_parse(argv[1], buf)) {
-+              fprintf(stderr, "Invalid UUID: %s\n", argv[1]);
-+              exit(1);
-+      }
-+      variant = uuid_variant(buf);
-+      type = uuid_type(buf);
-+      time_reg = uuid_time(buf, &tv);
-+
-+      printf("UUID variant is %d (%s)\n", variant, variant_string(variant));
-+      if (variant != UUID_VARIANT_DCE) {
-+              printf("Warning: This program only knows how to interpret "
-+                     "DCE UUIDs.\n\tThe rest of the output is likely "
-+                     "to be incorrect!!\n");
-+      }
-+      printf("UUID type is %d", type);
-+      switch (type) {
-+      case 1:
-+              printf(" (time based)\n");
-+              break;
-+      case 2:
-+              printf(" (DCE)\n");
-+              break;
-+      case 3:
-+              printf(" (name-based)\n");
-+              break;
-+      case 4:
-+              printf(" (random)\n");
-+              break;
-+      default:
-+              printf("\n");
-+      }
-+      if (type != 1) {
-+              printf("Warning: not a time-based UUID, so UUID time "
-+                     "decoding will likely not work!\n");
-+      }
-+      printf("UUID time is: (%ld, %ld): %s\n", tv.tv_sec, tv.tv_usec,
-+             ctime(&time_reg));
-+      
-+      return 0;
-+}
-+#endif
-diff -Nur busybox-1.00/editors/sed.c busybox/editors/sed.c
---- busybox-1.00/editors/sed.c 2004-05-26 12:03:33.000000000 +0200
-+++ busybox/editors/sed.c      2005-06-04 08:20:21.000000000 +0200
-@@ -34,7 +34,10 @@
-   resulting sed_cmd_t structures are appended to a linked list
-   (sed_cmd_head/sed_cmd_tail).
--  process_file() does actual sedding, reading data lines from an input FILE *
-+  add_input_file() adds a FILE * to the list of input files.  We need to
-+  know them all ahead of time to find the last line for the $ match.
-+
-+  process_files() does actual sedding, reading data lines from each input FILE *
-   (which could be stdin) and applying the sed command list (sed_cmd_head) to
-   each of the resulting lines.
-@@ -54,7 +57,7 @@
-        - grouped commands: {cmd1;cmd2}
-        - transliteration (y/source-chars/dest-chars/)
-        - pattern space hold space storing / swapping (g, h, x)
--       - labels / branching (: label, b, t)
-+       - labels / branching (: label, b, t, T)
-        (Note: Specifying an address (range) to match is *optional*; commands
-        default to the whole pattern space if no specific address match was
-@@ -62,7 +65,7 @@
-       Unsupported features:
--       - GNU extensions
-+       - most GNU extensions
-        - and more.
-       Todo:
-@@ -112,17 +115,20 @@
- /* globals */
- /* options */
--static int be_quiet = 0, in_place=0, regex_type=0;
--FILE *nonstdout;
--char *outname;
--
-+static int be_quiet, in_place, regex_type;
-+static FILE *nonstdout;
-+static char *outname,*hold_space;
-+
-+/* List of input files */
-+static int input_file_count,current_input_file;
-+static FILE **input_file_list;
- static const char bad_format_in_subst[] =
-       "bad format in substitution expression";
--const char *const semicolon_whitespace = "; \n\r\t\v";
-+static const char *const semicolon_whitespace = "; \n\r\t\v";
--regmatch_t regmatch[10];
--static regex_t *previous_regex_ptr = NULL;
-+static regmatch_t regmatch[10];
-+static regex_t *previous_regex_ptr;
- /* linked list of sed commands */
- static sed_cmd_t sed_cmd_head;
-@@ -133,7 +139,7 @@
-       char *string;
-       struct append_list *next;
- };
--struct append_list *append_head=NULL, *append_tail=NULL;
-+static struct append_list *append_head=NULL, *append_tail=NULL;
- #ifdef CONFIG_FEATURE_CLEAN_UP
- static void free_and_close_stuff(void)
-@@ -169,6 +175,11 @@
-               free(sed_cmd);
-               sed_cmd = sed_cmd_next;
-       }
-+
-+      if(hold_space) free(hold_space);
-+
-+    while(current_input_file<input_file_count)
-+              fclose(input_file_list[current_input_file++]);
- }
- #endif
-@@ -429,7 +440,7 @@
-               if(sed_cmd->cmd=='w')
-                       sed_cmd->file=bb_xfopen(sed_cmd->string,"w");
-       /* handle branch commands */
--      } else if (strchr(":bt", sed_cmd->cmd)) {
-+      } else if (strchr(":btT", sed_cmd->cmd)) {
-               int length;
-               while(isspace(*cmdstr)) cmdstr++;
-@@ -471,7 +482,7 @@
- /* Parse address+command sets, skipping comment lines. */
--void add_cmd(char *cmdstr)
-+static void add_cmd(char *cmdstr)
- {
-       static char *add_cmd_line=NULL;
-       sed_cmd_t *sed_cmd;
-@@ -563,7 +574,9 @@
-       }
- }
--struct pipeline {
-+/* Append to a string, reallocating memory as necessary. */
-+
-+static struct pipeline {
-       char *buf;      /* Space to hold string */
-       int idx;        /* Space used */
-       int len;        /* Space allocated */
-@@ -571,7 +584,7 @@
- #define PIPE_GROW 64
--void pipe_putc(char c)
-+static void pipe_putc(char c)
- {
-       if(pipeline.idx==pipeline.len) {
-               pipeline.buf = xrealloc(pipeline.buf, pipeline.len + PIPE_GROW);
-@@ -716,20 +729,29 @@
-       append_head=append_tail=NULL;
- }
--/* Get next line of input, flushing append buffer and noting if we hit EOF
-- * without a newline on the last line.
-+static void add_input_file(FILE *file)
-+{
-+      input_file_list=xrealloc(input_file_list,(input_file_count+1)*sizeof(FILE *));
-+      input_file_list[input_file_count++]=file;
-+}
-+
-+/* Get next line of input from input_file_list, flushing append buffer and
-+ * noting if we ran out of files without a newline on the last line we read.
-  */
--static char *get_next_line(FILE * file, int *no_newline)
-+static char *get_next_line(int *no_newline)
- {
--      char *temp;
-+      char *temp=NULL;
-       int len;
-       flush_append();
--      temp=bb_get_line_from_file(file);
--      if(temp) {
--              len=strlen(temp);
--              if(len && temp[len-1]=='\n') temp[len-1]=0;
--              else *no_newline=1;
-+      while(current_input_file<input_file_count) {
-+              temp=bb_get_line_from_file(input_file_list[current_input_file]);
-+              if(temp) {
-+                      len=strlen(temp);
-+                      *no_newline=!(len && temp[len-1]=='\n');
-+                      if(!*no_newline) temp[len-1]=0;
-+                      break;
-+              } else fclose(input_file_list[current_input_file++]);
-       }
-       return temp;
-@@ -755,15 +777,15 @@
- #define sed_puts(s,n) missing_newline=puts_maybe_newline(s,nonstdout,missing_newline,n)
--static void process_file(FILE *file)
-+static void process_files(void)
- {
--      char *pattern_space, *next_line, *hold_space=NULL;
--      static int linenum = 0, missing_newline=0;
-+      char *pattern_space, *next_line;
-+      int linenum = 0, missing_newline=0;
-       int no_newline,next_no_newline=0;
--      next_line = get_next_line(file,&next_no_newline);
-+      next_line = get_next_line(&next_no_newline);
--      /* go through every line in the file */
-+      /* go through every line in each file */
-       for(;;) {
-               sed_cmd_t *sed_cmd;
-               int substituted=0;
-@@ -773,7 +795,7 @@
-               no_newline=next_no_newline;
-               /* Read one line in advance so we can act on the last line, the '$' address */
--              next_line = get_next_line(file,&next_no_newline);
-+              next_line = get_next_line(&next_no_newline);
-               linenum++;
- restart:
-               /* for every line, go through all the commands */
-@@ -908,7 +930,7 @@
-                                       /* Cut and paste text (replace) */
-                                       case 'c':
-                                               /* Only triggers on last line of a matching range. */
--                                              if (!sed_cmd->in_match) sed_puts(sed_cmd->string,1);
-+                                              if (!sed_cmd->in_match) sed_puts(sed_cmd->string,0);
-                                               goto discard_line;
-                                       /* Read file, append contents to output */
-@@ -942,7 +964,7 @@
-                                                       free(pattern_space);
-                                                       pattern_space = next_line;
-                                                       no_newline=next_no_newline;
--                                                      next_line = get_next_line(file,&next_no_newline);
-+                                                      next_line = get_next_line(&next_no_newline);
-                                                       linenum++;
-                                                       break;
-                                               }
-@@ -972,17 +994,21 @@
-                                                       pattern_space[len]='\n';
-                                                       strcpy(pattern_space+len+1, next_line);
-                                                       no_newline=next_no_newline;
--                                                      next_line = get_next_line(file,&next_no_newline);
-+                                                      next_line = get_next_line(&next_no_newline);
-                                                       linenum++;
-                                               }
-                                               break;
-                                       }
--                                      /* Test if substition worked, branch if so. */
-+                                      /* Test/branch if substitution occurred */
-                                       case 't':
--                                              if (!substituted) break;
-+                                              if(!substituted) break;
-                                               substituted=0;
--                                                      /* Fall through */
-+                                              /* Fall through */
-+                                      /* Test/branch if substitution didn't occur */
-+                                      case 'T':
-+                                              if (substituted) break;
-+                                              /* Fall through */
-                                       /* Branch to label */
-                                       case 'b':
-                                               if (!sed_cmd->string) goto discard_commands;
-@@ -1007,10 +1033,7 @@
-                                       }
-                                       case 'g':       /* Replace pattern space with hold space */
-                                               free(pattern_space);
--                                              if (hold_space) {
--                                                      pattern_space = strdup(hold_space);
--                                                      no_newline=0;
--                                              }
-+                                              pattern_space = strdup(hold_space ? hold_space : "");
-                                               break;
-                                       case 'G':       /* Append newline and hold space to pattern space */
-                                       {
-@@ -1096,9 +1119,7 @@
- extern int sed_main(int argc, char **argv)
- {
--      int status = EXIT_SUCCESS;
--      int opt;
--      uint8_t getpat = 1;
-+      int status = EXIT_SUCCESS, opt, getpat = 1;
- #ifdef CONFIG_FEATURE_CLEAN_UP
-       /* destroy command strings on exit */
-@@ -1153,8 +1174,7 @@
-               }
-       }
--      /* if we didn't get a pattern from a -e and no command file was specified,
--       * argv[optind] should be the pattern. no pattern, no worky */
-+      /* if we didn't get a pattern from -e or -f, use argv[optind] */
-       if(getpat) {
-               if (argv[optind] == NULL)
-                       bb_show_usage();
-@@ -1171,49 +1191,47 @@
-        * files were specified or '-' was specified, take input from stdin.
-        * Otherwise, we process all the files specified. */
-       if (argv[optind] == NULL) {
--              if(in_place) {
--                      fprintf(stderr,"sed: Filename required for -i\n");
--                      exit(1);
--              }
--              process_file(stdin);
-+              if(in_place) bb_error_msg_and_die("Filename required for -i");
-+              add_input_file(stdin);
-+              process_files();
-       } else {
-               int i;
-               FILE *file;
-               for (i = optind; i < argc; i++) {
-                       if(!strcmp(argv[i], "-") && !in_place) {
--                              process_file(stdin);
-+                              add_input_file(stdin);
-+                              process_files();
-                       } else {
-                               file = bb_wfopen(argv[i], "r");
-                               if (file) {
-                                       if(in_place) {
-                                               struct stat statbuf;
-+                                              int nonstdoutfd;
-+                                              
-                                               outname=bb_xstrndup(argv[i],strlen(argv[i])+6);
-                                               strcat(outname,"XXXXXX");
-+                                              if(-1==(nonstdoutfd=mkstemp(outname)))
-+                                                      bb_error_msg_and_die("no temp file");
-+                                              nonstdout=fdopen(nonstdoutfd,"w");
-                                               /* Set permissions of output file */
-                                               fstat(fileno(file),&statbuf);
--                                              mkstemp(outname);
--                                              nonstdout=bb_wfopen(outname,"w");
--                                              /* Set permissions of output file */
--                                              fstat(fileno(file),&statbuf);
--                                              fchmod(fileno(nonstdout),statbuf.st_mode);
--                                              atexit(cleanup_outname);
--                                      }
--                                      process_file(file);
--                                      fclose(file);
--                                      if(in_place) {
-+                                              fchmod(nonstdoutfd,statbuf.st_mode);
-+                                              add_input_file(file);
-+                                              process_files();
-                                               fclose(nonstdout);
-                                               nonstdout=stdout;
-                                               unlink(argv[i]);
-                                               rename(outname,argv[i]);
-                                               free(outname);
-                                               outname=0;
--                                      }
-+                                      } else add_input_file(file);
-                               } else {
-                                       status = EXIT_FAILURE;
-                               }
-                       }
-               }
-+              if(input_file_count>current_input_file) process_files();
-       }
-       return status;
-diff -Nur busybox-1.00/editors/vi.c busybox/editors/vi.c
---- busybox-1.00/editors/vi.c  2004-08-19 21:15:06.000000000 +0200
-+++ busybox/editors/vi.c       2005-06-04 08:20:21.000000000 +0200
-@@ -19,7 +19,7 @@
-  */
- static const char vi_Version[] =
--      "$Id$";
-+      "$Id$";
- /*
-  * To compile for standalone use:
-@@ -2340,7 +2340,7 @@
- }
- //----- IO Routines --------------------------------------------
--static Byte get_one_char()
-+static Byte get_one_char(void)
- {
-       static Byte c;
-@@ -2600,25 +2600,25 @@
- }
- //----- Erase from cursor to end of line -----------------------
--static void clear_to_eol()
-+static void clear_to_eol(void)
- {
-       write1(Ceol);   // Erase from cursor to end of line
- }
- //----- Erase from cursor to end of screen -----------------------
--static void clear_to_eos()
-+static void clear_to_eos(void)
- {
-       write1(Ceos);   // Erase from cursor to end of screen
- }
- //----- Start standout mode ------------------------------------
--static void standout_start() // send "start reverse video" sequence
-+static void standout_start(void) // send "start reverse video" sequence
- {
-       write1(SOs);     // Start reverse video mode
- }
- //----- End standout mode --------------------------------------
--static void standout_end() // send "end reverse video" sequence
-+static void standout_end(void) // send "end reverse video" sequence
- {
-       write1(SOn);     // End reverse video mode
- }
-@@ -2648,7 +2648,7 @@
- //----- Screen[] Routines --------------------------------------
- //----- Erase the Screen[] memory ------------------------------
--static void screen_erase()
-+static void screen_erase(void)
- {
-       memset(screen, ' ', screensize);        // clear new screen
- }
-diff -Nur busybox-1.00/examples/depmod.pl busybox/examples/depmod.pl
---- busybox-1.00/examples/depmod.pl    2004-03-15 09:28:33.000000000 +0100
-+++ busybox/examples/depmod.pl 2005-06-04 08:20:22.000000000 +0200
-@@ -233,5 +233,5 @@
- =cut
--# $Id$
-+# $Id$
-diff -Nur busybox-1.00/examples/zcip.script busybox/examples/zcip.script
---- busybox-1.00/examples/zcip.script  1970-01-01 01:00:00.000000000 +0100
-+++ busybox/examples/zcip.script       2005-06-04 08:20:22.000000000 +0200
-@@ -0,0 +1,38 @@
-+#!/bin/sh
-+
-+# only for use as a "zcip" callback script
-+if [ "x$interface" = x ]
-+then
-+      exit 1
-+fi
-+
-+# zcip should start on boot/resume and various media changes
-+case "$1" in
-+init)
-+      # for now, zcip requires the link to be already up,
-+      # and it drops links when they go down.  that isn't
-+      # the most robust model...
-+      exit 0
-+      ;;
-+config)
-+      if [ "x$ip" = x ]
-+      then
-+              exit 1
-+      fi
-+      # remember $ip for $interface, to use on restart
-+      if [ "x$IP" != x -a -w "$IP.$interface" ]
-+      then
-+              echo $ip > "$IP.$interface"
-+      fi
-+      exec ip address add dev $interface \
-+              scope link local "$ip/16" broadcast +
-+      ;;
-+deconfig)
-+      if [ x$ip = x ]
-+      then
-+              exit 1
-+      fi
-+      exec ip address del dev $interface local $ip
-+      ;;
-+esac
-+exit 1
-diff -Nur busybox-1.00/findutils/find.c busybox/findutils/find.c
---- busybox-1.00/findutils/find.c      2004-03-15 09:28:37.000000000 +0100
-+++ busybox/findutils/find.c   2005-06-04 08:20:20.000000000 +0200
-@@ -59,7 +59,7 @@
- #endif
- #ifdef CONFIG_FEATURE_FIND_NEWER
--time_t newer_mtime;
-+static time_t newer_mtime;
- #endif
- #ifdef CONFIG_FEATURE_FIND_INUM
-diff -Nur busybox-1.00/findutils/grep.c busybox/findutils/grep.c
---- busybox-1.00/findutils/grep.c      2004-10-08 10:10:57.000000000 +0200
-+++ busybox/findutils/grep.c   2005-06-04 08:20:20.000000000 +0200
-@@ -98,7 +98,7 @@
-       }
-       last_line_printed = linenum;
- #endif
--      if (print_filename)
-+      if (print_filename > 0)
-               printf("%s%c", cur_file, decoration);
-       if (print_line_num)
-               printf("%i%c", linenum, decoration);
-@@ -219,7 +219,7 @@
-       /* grep -c: print [filename:]count, even if count is zero */
-       if (print_match_counts) {
--              if (print_filename)
-+              if (print_filename > 0)
-                       printf("%s:", cur_file);
-                   printf("%d\n", nmatches);
-       }
-diff -Nur busybox-1.00/include/applets.h busybox/include/applets.h
---- busybox-1.00/include/applets.h     2004-08-27 01:01:34.000000000 +0200
-+++ busybox/include/applets.h  2005-06-04 08:20:17.000000000 +0200
-@@ -16,40 +16,41 @@
- #if defined(PROTOTYPES)
--  #define APPLET(a,b,c,d) extern int b(int argc, char **argv);
--  #define APPLET_NOUSAGE(a,b,c,d) extern int b(int argc, char **argv);
--  #define APPLET_ODDNAME(a,b,c,d,e) extern int b(int argc, char **argv);
-+# define APPLET(a,b,c,d) extern int b(int argc, char **argv);
-+# define APPLET_NOUSAGE(a,b,c,d) extern int b(int argc, char **argv);
-+# define APPLET_ODDNAME(a,b,c,d,e) extern int b(int argc, char **argv);
-   extern const char usage_messages[];
- #elif defined(MAKE_USAGE)
--  #ifdef CONFIG_FEATURE_VERBOSE_USAGE
--    #define APPLET(a,b,c,d) a##_trivial_usage "\n\n" a##_full_usage "\0"
--    #define APPLET_NOUSAGE(a,b,c,d) "\b\0"
--    #define APPLET_ODDNAME(a,b,c,d,e) e##_trivial_usage "\n\n" e##_full_usage "\0"
--  #else
--    #define APPLET(a,b,c,d) a##_trivial_usage "\0"
--    #define APPLET_NOUSAGE(a,b,c,d) "\b\0"
--    #define APPLET_ODDNAME(a,b,c,d,e) e##_trivial_usage "\0"
--  #endif
-+# ifdef CONFIG_FEATURE_VERBOSE_USAGE
-+#  define APPLET(a,b,c,d) a##_trivial_usage "\n\n" a##_full_usage "\0"
-+#  define APPLET_NOUSAGE(a,b,c,d) "\b\0"
-+#  define APPLET_ODDNAME(a,b,c,d,e) e##_trivial_usage "\n\n" e##_full_usage "\0"
-+# else
-+#  define APPLET(a,b,c,d) a##_trivial_usage "\0"
-+#  define APPLET_NOUSAGE(a,b,c,d) "\b\0"
-+#  define APPLET_ODDNAME(a,b,c,d,e) e##_trivial_usage "\0"
-+# endif
- #elif defined(MAKE_LINKS)
--#  define APPLET(a,b,c,d) LINK c a
--#  define APPLET_NOUSAGE(a,b,c,d) LINK c a
--#  define APPLET_ODDNAME(a,b,c,d,e) LINK c a
-+# define APPLET(a,b,c,d) LINK c a
-+# define APPLET_NOUSAGE(a,b,c,d) LINK c a
-+# define APPLET_ODDNAME(a,b,c,d,e) LINK c a
- #else
-   const struct BB_applet applets[] = {
--  #define APPLET(a,b,c,d) {#a,b,c,d},
--  #define APPLET_NOUSAGE(a,b,c,d) {a,b,c,d},
--  #define APPLET_ODDNAME(a,b,c,d,e) {a,b,c,d},
-+# define APPLET(a,b,c,d) {#a,b,c,d},
-+# define APPLET_NOUSAGE(a,b,c,d) {a,b,c,d},
-+# define APPLET_ODDNAME(a,b,c,d,e) {a,b,c,d},
- #endif
- #ifdef CONFIG_INSTALL_NO_USR
--#define _BB_DIR_USR_BIN _BB_DIR_BIN
--#define _BB_DIR_USR_SBIN _BB_DIR_SBIN
-+# define _BB_DIR_USR_BIN _BB_DIR_BIN
-+# define _BB_DIR_USR_SBIN _BB_DIR_SBIN
- #endif
- #ifdef CONFIG_TEST
-       APPLET_NOUSAGE("[", test_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
-+      APPLET_NOUSAGE("[[", test_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_ADDGROUP
-       APPLET(addgroup, addgroup_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-@@ -88,6 +89,9 @@
- #ifdef CONFIG_CAT
-       APPLET(cat, cat_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_CHATTR
-+      APPLET(chattr, chattr_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-+#endif
- #ifdef CONFIG_CHGRP
-       APPLET(chgrp, chgrp_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
-@@ -109,6 +113,9 @@
- #ifdef CONFIG_CMP
-       APPLET(cmp, cmp_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_COMM
-+      APPLET(comm, comm_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
-+#endif
- #ifdef CONFIG_CP
-       APPLET(cp, cp_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
-@@ -170,7 +177,7 @@
-       APPLET(dumpkmap, dumpkmap_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_DUMPLEASES
--        APPLET(dumpleases, dumpleases_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
-+      APPLET(dumpleases, dumpleases_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_ECHO
-       APPLET(echo, echo_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-@@ -178,12 +185,21 @@
- #if defined(CONFIG_FEATURE_GREP_EGREP_ALIAS)
-       APPLET_NOUSAGE("egrep", grep_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_EJECT
-+      APPLET(eject, eject_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
-+#endif
- #ifdef CONFIG_ENV
-       APPLET(env, env_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_ETHER_WAKE
-+      APPLET_ODDNAME("ether-wake", etherwake_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER, ether_wake)
-+#endif
- #ifdef CONFIG_EXPR
-       APPLET(expr, expr_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_FAKEIDENTD
-+      APPLET(fakeidentd, fakeidentd_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
-+#endif
- #ifdef CONFIG_FALSE
-       APPLET(false, false_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
-@@ -355,6 +371,9 @@
- #ifdef CONFIG_LS
-       APPLET(ls, ls_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_LSATTR
-+      APPLET(lsattr, lsattr_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-+#endif
- #ifdef CONFIG_LSMOD
-       APPLET(lsmod, lsmod_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
- #endif
-@@ -412,6 +431,9 @@
- #ifdef CONFIG_NETSTAT
-       APPLET(netstat, netstat_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_NICE
-+      APPLET(nice, nice_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-+#endif
- #ifdef CONFIG_NSLOOKUP
-       APPLET(nslookup, nslookup_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
- #endif
-@@ -440,11 +462,14 @@
-       APPLET_NOUSAGE("pipe_progress", pipe_progress_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_PIVOT_ROOT
--      APPLET(pivot_root, pivot_root_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
-+      APPLET(pivot_root, pivot_root_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_POWEROFF
-       APPLET(poweroff, poweroff_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_PRINTENV
-+      APPLET(printenv, printenv_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-+#endif
- #ifdef CONFIG_PRINTF
-       APPLET(printf, printf_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
- #endif
-@@ -460,6 +485,9 @@
- #ifdef CONFIG_READLINK
-       APPLET(readlink, readlink_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_READPROFILE
-+      APPLET(readprofile, readprofile_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
-+#endif
- #ifdef CONFIG_REALPATH
-       APPLET(realpath, realpath_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
- #endif
-@@ -482,7 +510,7 @@
-       APPLET(rmmod, rmmod_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_ROUTE
--      APPLET(route, route_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
-+      APPLET(route, route_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_RPM
-       APPLET(rpm, rpm_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-@@ -524,7 +552,10 @@
-       APPLET(sort, sort_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_START_STOP_DAEMON
--    APPLET_ODDNAME("start-stop-daemon", start_stop_daemon_main, _BB_DIR_SBIN, _BB_SUID_NEVER, start_stop_daemon)
-+      APPLET_ODDNAME("start-stop-daemon", start_stop_daemon_main, _BB_DIR_SBIN, _BB_SUID_NEVER, start_stop_daemon)
-+#endif
-+#ifdef CONFIG_STAT
-+      APPLET(stat, stat_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_STRINGS
-       APPLET(strings, strings_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
-@@ -538,6 +569,9 @@
- #ifdef CONFIG_SULOGIN
-       APPLET(sulogin, sulogin_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_SUM
-+      APPLET(sum, sum_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
-+#endif
- #ifdef CONFIG_SWAPONOFF
-       APPLET(swapoff, swap_on_off_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
- #endif
-@@ -599,7 +633,7 @@
-       APPLET(udhcpc, udhcpc_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_UDHCPD
--        APPLET(udhcpd, udhcpd_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
-+      APPLET(udhcpd, udhcpd_main, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)
- #endif
- #ifdef CONFIG_UMOUNT
-       APPLET(umount, umount_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-@@ -670,6 +704,9 @@
- #ifdef CONFIG_GUNZIP
-       APPLET(zcat, gunzip_main, _BB_DIR_BIN, _BB_SUID_NEVER)
- #endif
-+#ifdef CONFIG_ZCIP
-+      APPLET(zcip, zcip_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
-+#endif
- #if !defined(PROTOTYPES) && !defined(MAKE_USAGE)
-       { 0,NULL,0 }
-diff -Nur busybox-1.00/include/busybox.h busybox/include/busybox.h
---- busybox-1.00/include/busybox.h     2004-03-15 09:28:38.000000000 +0100
-+++ busybox/include/busybox.h  2005-06-04 08:20:17.000000000 +0200
-@@ -32,10 +32,10 @@
- #include <sys/stat.h>
- #include <sys/types.h>
--#if __GNU_LIBRARY__ < 5
--#ifndef __dietlibc__
--#error "Sorry, libc5 is not supported"
--#endif
-+#if __GNU_LIBRARY__ < 5 && \
-+    !defined(__dietlibc__) && \
-+    !defined(_NEWLIB_VERSION)
-+#error "Sorry, this libc version is not supported :("
- #endif
- #ifndef BB_EXTRA_VERSION
-diff -Nur busybox-1.00/include/inet_common.h busybox/include/inet_common.h
---- busybox-1.00/include/inet_common.h 2004-03-10 08:42:37.000000000 +0100
-+++ busybox/include/inet_common.h      2005-06-04 08:20:17.000000000 +0200
-@@ -4,7 +4,7 @@
-  *
-  * Heavily modified by Manuel Novoa III       Mar 12, 2001
-  *
-- * Version:     $Id$
-+ * Version:     $Id$
-  *
-  */
-@@ -29,5 +29,7 @@
- extern int INET_rresolve(char *name, size_t len, struct sockaddr_in *s_in,
-                        int numeric, unsigned int netmask);
-+#ifdef CONFIG_FEATURE_IPV6
- extern int INET6_resolve(const char *name, struct sockaddr_in6 *sin6);
- extern int INET6_rresolve(char *name, size_t len, struct sockaddr_in6 *sin6, int numeric);
-+#endif
-diff -Nur busybox-1.00/include/libbb.h busybox/include/libbb.h
---- busybox-1.00/include/libbb.h       2004-09-15 05:04:07.000000000 +0200
-+++ busybox/include/libbb.h    2005-06-04 08:20:17.000000000 +0200
-@@ -43,7 +43,7 @@
- #include "config.h"
- #ifdef CONFIG_SELINUX
--#include <proc_secure.h>
-+#include <selinux/selinux.h>  
- #endif
- #include "pwd_.h"
-@@ -137,6 +137,7 @@
- extern char *find_real_root_device_name(void);
- extern char *bb_get_line_from_file(FILE *file);
- extern char *bb_get_chomped_line_from_file(FILE *file);
-+extern char *bb_get_chunk_from_file(FILE *file);
- extern int bb_copyfd_size(int fd1, int fd2, const off_t size);
- extern int bb_copyfd_eof(int fd1, int fd2);
- extern void  bb_xprint_and_close_file(FILE *file);
-@@ -150,6 +151,7 @@
- extern int   bb_fclose_nonstdin(FILE *f);
- extern void  bb_fflush_stdout_and_exit(int retval) __attribute__ ((noreturn));
-+#define BB_GETOPT_ERROR 0x80000000UL
- extern const char *bb_opt_complementaly;
- extern const struct option *bb_applet_long_options;
- extern unsigned long bb_getopt_ulflags(int argc, char **argv, const char *applet_opts, ...);
-@@ -323,6 +325,7 @@
- extern const char * const bb_msg_memory_exhausted;
- extern const char * const bb_msg_invalid_date;
- extern const char * const bb_msg_io_error;
-+extern const char * const bb_msg_read_error;
- extern const char * const bb_msg_write_error;
- extern const char * const bb_msg_name_longer_than_foo;
- extern const char * const bb_msg_unknown;
-@@ -421,11 +424,11 @@
- #define FAIL_DELAY    3
- extern void change_identity ( const struct passwd *pw );
- extern const char *change_identity_e2str ( const struct passwd *pw );
--extern void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args
-+extern void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args);
- #ifdef CONFIG_SELINUX
--      , security_id_t sid
--#endif
--);
-+extern void renew_current_security_context(void);
-+extern void set_current_security_context(security_context_t sid);
-+#endif 
- extern int run_parts(char **args, const unsigned char test_mode, char **env);
- extern int restricted_shell ( const char *shell );
- extern void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw );
-@@ -456,11 +459,7 @@
-       char short_cmd[16];
- } procps_status_t;
--extern procps_status_t * procps_scan(int save_user_arg0
--#ifdef CONFIG_SELINUX
--      , int use_selinux, security_id_t *sid
--#endif
--);
-+extern procps_status_t * procps_scan(int save_user_arg0);
- extern unsigned short compare_string_array(const char *string_array[], const char *key);
- extern int my_query_module(const char *name, int which, void **buf, size_t *bufsize, size_t *ret);
-diff -Nur busybox-1.00/include/usage.h busybox/include/usage.h
---- busybox-1.00/include/usage.h       2004-09-14 18:23:56.000000000 +0200
-+++ busybox/include/usage.h    2005-06-04 08:20:17.000000000 +0200
-@@ -46,7 +46,7 @@
-       "\t-v\t\tverbosely list files processed"
- #define arping_trivial_usage \
--      "[-fqbDUA] [-c count] [-w timeout] [-I device] [-s sender] target\n"
-+      "[-fqbDUA] [-c count] [-w timeout] [-I device] [-s sender] target"
- #define arping_full_usage \
-       "Ping hosts by ARP requests/replies.\n\n" \
-       "Options:\n" \
-@@ -64,7 +64,7 @@
- #define ash_trivial_usage \
-       "[FILE]...\n" \
--      "or: ash -c command [args]...\n"
-+      "or: ash -c command [args]..."
- #define ash_full_usage \
-       "The ash shell (command interpreter)"
-@@ -103,12 +103,12 @@
-       "Uncompress to stdout."
- #define cal_trivial_usage \
--       "[-jy] [[month] year]"
-+      "[-jy] [[month] year]"
- #define cal_full_usage \
--       "Display a calendar.\n" \
--       "\nOptions:\n" \
--       "\t-j\tUse julian dates.\n" \
--       "\t-y\tDisplay the entire year."
-+      "Display a calendar.\n" \
-+      "\nOptions:\n" \
-+      "\t-j\tUse julian dates\n" \
-+      "\t-y\tDisplay the entire year"
- #define cat_trivial_usage \
-       "[-u] [FILE]..."
-@@ -120,12 +120,36 @@
-       "$ cat /proc/uptime\n" \
-       "110716.72 17.67"
-+#define chattr_trivial_usage \
-+      "[-R] [-+=AacDdijsStTu] [-v version] files..."
-+#define chattr_full_usage \
-+      "change file attributes on an ext2 fs\n\n" \
-+      "Modifiers:\n" \
-+      "\t-\tremove attributes\n" \
-+      "\t+\tadd attributes\n" \
-+      "\t=\tset attributes\n" \
-+      "Attributes:\n" \
-+      "\tA\tdon't track atime\n" \
-+      "\ta\tappend mode only\n" \
-+      "\tc\tenable compress\n" \
-+      "\tD\twrite dir contents synchronously\n" \
-+      "\td\tdo not backup with dump\n" \
-+      "\ti\tcannot be modified (immutable)\n" \
-+      "\tj\twrite all data to journal first\n" \
-+      "\ts\tzero disk storage when deleted\n" \
-+      "\tS\twrite file contents synchronously\n" \
-+      "\tt\tdisable tail-merging of partial blocks with other files\n" \
-+      "\tu\tallow file to be undeleted\n" \
-+      "Options:\n" \
-+      "\t-R\trecursively list subdirectories\n" \
-+      "\t-v\tset the file's version/generation number"
-+
- #define chgrp_trivial_usage \
-       "[OPTION]... GROUP FILE..."
- #define chgrp_full_usage \
-       "Change the group membership of each FILE to GROUP.\n" \
-       "\nOptions:\n" \
--      "\t-R\tChanges files and directories recursively."
-+      "\t-R\tChanges files and directories recursively"
- #define chgrp_example_usage \
-       "$ ls -l /tmp/foo\n" \
-       "-r--r--r--    1 andersen andersen        0 Apr 12 18:25 /tmp/foo\n" \
-@@ -139,7 +163,7 @@
-       "Each MODE is one or more of the letters ugoa, one of the\n" \
-       "symbols +-= and one or more of the letters rwxst.\n\n" \
-       "Options:\n" \
--      "\t-R\tChanges files and directories recursively."
-+      "\t-R\tChanges files and directories recursively"
- #define chmod_example_usage \
-       "$ ls -l /tmp/foo\n" \
-       "-rw-rw-r--    1 root     root            0 Apr 12 18:25 /tmp/foo\n" \
-@@ -155,8 +179,8 @@
- #define chown_full_usage \
-       "Change the owner and/or group of each FILE to OWNER and/or GROUP.\n" \
-       "\nOptions:\n" \
--      "\t-R\tChanges files and directories recursively.\n" \
--      "\t-h\tDo not dereference symbolic links."
-+      "\t-R\tChanges files and directories recursively\n" \
-+      "\t-h\tDo not dereference symbolic links"
- #define chown_example_usage \
-       "$ ls -l /tmp/foo\n" \
-       "-r--r--r--    1 andersen andersen        0 Apr 12 18:25 /tmp/foo\n" \
-@@ -192,19 +216,29 @@
- #define cmp_trivial_usage \
-       "[-l] [-s] FILE1 [FILE2]"
- #define cmp_full_usage \
--      "Compare files.  Compares FILE1 vs stdin if FILE2 is not specified.\n\n" \
-+      "Compares FILE1 vs stdin if FILE2 is not specified.\n\n" \
-       "Options:\n" \
-       "\t-l\tWrite the byte numbers (decimal) and values (octal)\n" \
--      "\t\t  for all differing bytes.\n" \
-+      "\t\t  for all differing bytes\n" \
-       "\t-s\tquiet mode - do not print"
-+#define comm_trivial_usage \
-+      "[-123] FILE1 FILE2"
-+#define comm_full_usage \
-+      "Compares FILE1 to FILE2, or to stdin if = is specified.\n\n" \
-+      "Options:\n" \
-+      "\t-1\tSuppress lines unique to FILE1\n" \
-+      "\t-2\tSuppress lines unique to FILE2\n" \
-+      "\t-3\tSuppress lines common to both files"
-+
- #define cp_trivial_usage \
-       "[OPTION]... SOURCE DEST"
- #define cp_full_usage \
-       "Copies SOURCE to DEST, or multiple SOURCE(s) to DIRECTORY.\n" \
-       "\n" \
-       "\t-a\tSame as -dpR\n" \
--      "\t-d\tPreserves links\n" \
-+      "\t-d,-P\tPreserves links\n" \
-+      "\t-H,-L\tDereference all symlinks (implied by default)\n" \
-       "\t-p\tPreserves file attributes if possible\n" \
-       "\t-f\tforce (implied; ignored) - always set\n" \
-       "\t-i\tinteractive, prompt before overwrite\n" \
-@@ -259,9 +293,9 @@
-       "\t-f N\t\tPrint only these fields\n" \
-       "\t-n\t\tIgnored"
- #define cut_example_usage \
--      "$ echo "Hello world" | cut -f 1 -d ' '\n" \
-+      "$ echo \"Hello world\" | cut -f 1 -d ' '\n" \
-       "Hello\n" \
--      "$ echo "Hello world" | cut -f 2 -d ' '\n" \
-+      "$ echo \"Hello world\" | cut -f 2 -d ' '\n" \
-       "world\n"
- #ifdef CONFIG_FEATURE_DATE_ISOFMT
-@@ -277,10 +311,10 @@
-       "\nOptions:\n" \
-       "\t-R\t\tOutputs RFC-822 compliant date string\n" \
-       "\t-d STRING\tDisplays time described by STRING, not `now'\n" \
--      USAGE_DATE_ISOFMT("\t-I[TIMESPEC]\tOutputs an ISO-8601 compliant date/time string.\n" \
-+      USAGE_DATE_ISOFMT("\t-I[TIMESPEC]\tOutputs an ISO-8601 compliant date/time string\n" \
-       "\t\t\tTIMESPEC=`date' (or missing) for date only,\n" \
-       "\t\t\t`hours', `minutes', or `seconds' for date and,\n" \
--      "\t\t\ttime to the indicated precision.\n") \
-+      "\t\t\ttime to the indicated precision\n") \
-       "\t-s\t\tSets time described by STRING\n" \
-       "\t-r FILE\t\tDisplays the last modification time of FILE\n" \
-       "\t-u\t\tPrints or sets Coordinated Universal Time"
-@@ -292,14 +326,14 @@
-       "expression ..."
- #define dc_full_usage \
-       "This is a Tiny RPN calculator that understands the\n" \
--      "following operations: +, add, -, sub, *, mul, /, div, %, mod, "\
-+      "following operations: +, add, -, sub, *, mul, /, div, %, mod, " \
-       "**, exp, and, or, not, eor.\n" \
-       "For example: 'dc 2 2 add' -> 4, and 'dc 8 8 \\* 2 2 + /' -> 16.\n" \
-       "\nOptions:\n" \
--      "p - Prints the value on the top of the stack, without altering the stack.\n" \
--      "f - Prints the entire contents of the stack without altering anything.\n" \
--      "o - Pops the value off the top of the stack and uses it to set the output radix.\n" \
--      "    Only 10 and 16 are supported."
-+      "p - Prints the value on the top of the stack, without altering the stack\n" \
-+      "f - Prints the entire contents of the stack without altering anything\n" \
-+      "o - Pops the value off the top of the stack and uses it to set the output radix\n" \
-+      "    Only 10 and 16 are supported"
- #define dc_example_usage \
-       "$ dc 2 2 + p\n" \
-       "4\n" \
-@@ -328,7 +362,7 @@
-       "\tconv=sync\tpad blocks with zeros\n" \
-       "\n" \
-       "Numbers may be suffixed by c (x1), w (x2), b (x512), kD (x1000), k (x1024),\n" \
--      "MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)."
-+      "MD (x1000000), M (x1048576), GD (x1000000000) or G (x1073741824)"
- #define dd_example_usage \
-       "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n" \
-       "4+0 records in\n" \
-@@ -350,13 +384,13 @@
-        "Deletes user USER from the system"
- #ifdef CONFIG_DEVFSD_FG_NP
--  #define USAGE_DEVFSD_FG_NP(a) a
-+#  define USAGE_DEVFSD_FG_NP(a) a
- #else
--  #define USAGE_DEVFSD_FG_NP(a)
-+#  define USAGE_DEVFSD_FG_NP(a)
- #endif
- #define devfsd_trivial_usage \
--      "mntpnt [-v]"\
-+      "mntpnt [-v]" \
-       USAGE_DEVFSD_FG_NP("[-fg][-np]" )
- #define devfsd_full_usage \
-       "Optional daemon for managing devfs permissions and old device name symlinks.\n" \
-@@ -370,11 +404,11 @@
-       "\t\tDo not poll for events.")
- #ifdef CONFIG_FEATURE_HUMAN_READABLE
--  #define USAGE_HUMAN_READABLE(a) a
--  #define USAGE_NOT_HUMAN_READABLE(a)
-+#  define USAGE_HUMAN_READABLE(a) a
-+#  define USAGE_NOT_HUMAN_READABLE(a)
- #else
--  #define USAGE_HUMAN_READABLE(a)
--  #define USAGE_NOT_HUMAN_READABLE(a) a
-+#  define USAGE_HUMAN_READABLE(a)
-+#  define USAGE_NOT_HUMAN_READABLE(a) a
- #endif
- #define df_trivial_usage \
-       "[-" USAGE_HUMAN_READABLE("hm") USAGE_NOT_HUMAN_READABLE("") "k] [FILESYSTEM ...]"
-@@ -508,9 +542,9 @@
-       "\t-a,\t--absolute\tInterpret lease times as expire time"
- #ifdef CONFIG_FEATURE_FANCY_ECHO
--  #define USAGE_FANCY_ECHO(a) a
-+#  define USAGE_FANCY_ECHO(a) a
- #else
--  #define USAGE_FANCY_ECHO(a)
-+#  define USAGE_FANCY_ECHO(a)
- #endif
- #define echo_trivial_usage \
-@@ -522,15 +556,22 @@
-       "\t-e\tinterpret backslash-escaped characters (i.e., \\t=tab)\n" \
-       "\t-E\tdisable interpretation of backslash-escaped characters")
- #define echo_example_usage \
--      "$ echo "Erik is cool"\n" \
-+      "$ echo \"Erik is cool\"\n" \
-       "Erik is cool\n" \
--      USAGE_FANCY_ECHO("$  echo -e "Erik\\nis\\ncool"\n" \
-+      USAGE_FANCY_ECHO("$  echo -e \"Erik\\nis\\ncool\"\n" \
-       "Erik\n" \
-       "is\n" \
-       "cool\n" \
--      "$ echo "Erik\\nis\\ncool"\n" \
-+      "$ echo \"Erik\\nis\\ncool\"\n" \
-       "Erik\\nis\\ncool\n")
-+#define eject_trivial_usage \
-+      "[-t] [DEVICE]"
-+#define eject_full_usage \
-+      "Eject specified DEVICE (or default /dev/cdrom).\n\n" \
-+      "Options:\n" \
-+      "\t-t\tclose tray"
-+
- #define env_trivial_usage \
-       "[-iu] [-] [name=value]... [command]"
- #define env_full_usage \
-@@ -540,6 +581,17 @@
-       "\t-, -i\tstart with an empty environment\n" \
-       "\t-u\tremove variable from the environment"
-+#define ether_wake_trivial_usage \
-+      "[-b] [-i iface] [-p aa:bb:cc:dd[:ee:ff]] MAC"
-+#define ether_wake_full_usage \
-+      "Send a magic packet to wake up sleeping machines.\n" \
-+      "MAC must be a station address (00:11:22:33:44:55) or\n" \
-+      "    a hostname with a known 'ethers' entry.\n\n" \
-+      "Options:\n" \
-+      "\t-b\t\tSend wake-up packet to the broadcast address\n" \
-+      "\t-i iface\tUse interface ifname instead of the default \"eth0\"\n" \
-+      "\t-p pass\tAppend the four or six byte password PW to the packet\n"
-+
- #define expr_trivial_usage \
-       "EXPRESSION"
- #define expr_full_usage \
-@@ -574,6 +626,13 @@
-       "\\( and \\) or null; if \\( and \\) are not used, they return the number \n" \
-       "of characters matched or 0."
-+#define fakeidentd_trivial_usage \
-+      "[-b ip] [STRING]"
-+#define fakeidentd_full_usage \
-+      "Returns a set string to auth requests\n\n" \
-+      "\t-b\tBind to ip address\n" \
-+      "\tSTRING\tThe ident answer string (default is nobody)"
-+
- #define false_trivial_usage \
-       ""
- #define false_full_usage \
-@@ -589,7 +648,7 @@
-       "Show and modify frame buffer settings"
- #define fbset_example_usage \
-       "$ fbset\n" \
--      "mode "1024x768-76"\n" \
-+      "mode \"1024x768-76\"\n" \
-       "\t# D: 78.653 MHz, H: 59.949 kHz, V: 75.694 Hz\n" \
-       "\tgeometry 1024 768 1024 768 16\n" \
-       "\ttimings 12714 128 32 16 4 128 4\n" \
-@@ -624,29 +683,29 @@
-       "\t-v  Give fdisk version"
- #ifdef CONFIG_FEATURE_FIND_TYPE
--  #define USAGE_FIND_TYPE(a) a
-+#  define USAGE_FIND_TYPE(a) a
- #else
--  #define USAGE_FIND_TYPE(a)
-+#  define USAGE_FIND_TYPE(a)
- #endif
- #ifdef CONFIG_FEATURE_FIND_PERM
--  #define USAGE_FIND_PERM(a) a
-+#  define USAGE_FIND_PERM(a) a
- #else
--  #define USAGE_FIND_PERM(a)
-+#  define USAGE_FIND_PERM(a)
- #endif
- #ifdef CONFIG_FEATURE_FIND_MTIME
--  #define USAGE_FIND_MTIME(a) a
-+#  define USAGE_FIND_MTIME(a) a
- #else
--  #define USAGE_FIND_MTIME(a)
-+#  define USAGE_FIND_MTIME(a)
- #endif
- #ifdef CONFIG_FEATURE_FIND_NEWER
--  #define USAGE_FIND_NEWER(a) a
-+#  define USAGE_FIND_NEWER(a) a
- #else
--  #define USAGE_FIND_NEWER(a)
-+#  define USAGE_FIND_NEWER(a)
- #endif
- #ifdef CONFIG_FEATURE_FIND_INUM
--  #define USAGE_FIND_INUM(a) a
-+#  define USAGE_FIND_INUM(a) a
- #else
--  #define USAGE_FIND_INUM(a)
-+#  define USAGE_FIND_INUM(a)
- #endif
- #define find_trivial_usage \
-@@ -655,9 +714,9 @@
-       "Search for files in a directory hierarchy.  The default PATH is\n" \
-       "the current directory; default EXPRESSION is '-print'\n" \
-       "\nEXPRESSION may consist of:\n" \
--      "\t-follow\t\tDereference symbolic links.\n" \
--      "\t-name PATTERN\tFile name (leading directories removed) matches PATTERN.\n" \
--      "\t-print\t\tPrint (default and assumed).\n" \
-+      "\t-follow\t\tDereference symbolic links\n" \
-+      "\t-name PATTERN\tFile name (leading directories removed) matches PATTERN\n" \
-+      "\t-print\t\tPrint (default and assumed)\n" \
-       USAGE_FIND_TYPE( \
-       "\n\t-type X\t\tFiletype matches X (where X is one of: f,d,l,b,c,...)" \
- ) USAGE_FIND_PERM( \
-@@ -711,7 +770,7 @@
-       "\t-v\tverbose\n" \
-       "\t-s\tOutputs super-block information\n" \
-       "\t-m\tActivates MINIX-like \"mode not cleared\" warnings\n" \
--      "\t-f\tForce file system check."
-+      "\t-f\tForce file system check"
- #define ftpget_trivial_usage \
-       "[options] remote-host local-file remote-file"
-@@ -748,42 +807,42 @@
-       "\t-T, --test                   Test for getopt(1) version\n" \
-       "\t-u, --unquoted               Do not quote the output"
- #define getopt_example_usage \
--        "$ cat getopt.test\n" \
--        "#!/bin/sh\n" \
--        "GETOPT=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \\\n" \
--        "       -n 'example.busybox' -- "$@"`\n" \
--        "if [ $? != 0 ] ; then  exit 1 ; fi\n" \
--        "eval set -- "$GETOPT"\n" \
--        "while true ; do\n" \
--        " case $1 in\n" \
--        "   -a|--a-long) echo \"Option a\" ; shift ;;\n" \
--        "   -b|--b-long) echo \"Option b, argument `$2'\" ; shift 2 ;;\n" \
--        "   -c|--c-long)\n" \
--        "     case "$2" in\n" \
--        "       \"\") echo \"Option c, no argument\"; shift 2 ;;\n" \
--        "       *)  echo \"Option c, argument `$2'\" ; shift 2 ;;\n" \
--        "     esac ;;\n" \
--        "   --) shift ; break ;;\n" \
--        "   *) echo \"Internal error!\" ; exit 1 ;;\n" \
--        " esac\n" \
--        "done\n"
-+      "$ cat getopt.test\n" \
-+      "#!/bin/sh\n" \
-+      "GETOPT=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \\\n" \
-+      "       -n 'example.busybox' -- \"$@\"`\n" \
-+      "if [ $? != 0 ] ; then  exit 1 ; fi\n" \
-+      "eval set -- \"$GETOPT\"\n" \
-+      "while true ; do\n" \
-+      " case $1 in\n" \
-+      "   -a|--a-long) echo \"Option a\" ; shift ;;\n" \
-+      "   -b|--b-long) echo \"Option b, argument `$2'\" ; shift 2 ;;\n" \
-+      "   -c|--c-long)\n" \
-+      "     case \"$2\" in\n" \
-+      "       \"\") echo \"Option c, no argument\"; shift 2 ;;\n" \
-+      "       *)  echo \"Option c, argument `$2'\" ; shift 2 ;;\n" \
-+      "     esac ;;\n" \
-+      "   --) shift ; break ;;\n" \
-+      "   *) echo \"Internal error!\" ; exit 1 ;;\n" \
-+      " esac\n" \
-+      "done\n"
- #define getty_trivial_usage \
-       "[OPTIONS]... baud_rate,... line [termtype]"
- #define getty_full_usage \
-       "Opens a tty, prompts for a login name, then invokes /bin/login\n\n" \
-       "Options:\n" \
--      "\t-h\t\tEnable hardware (RTS/CTS) flow control.\n" \
--      "\t-i\t\tDo not display /etc/issue before running login.\n" \
--      "\t-L\t\tLocal line, so do not do carrier detect.\n" \
--      "\t-m\t\tGet baud rate from modem's CONNECT status message.\n" \
--      "\t-w\t\tWait for a CR or LF before sending /etc/issue.\n" \
--      "\t-n\t\tDo not prompt the user for a login name.\n" \
--      "\t-f issue_file\tDisplay issue_file instead of /etc/issue.\n" \
--      "\t-l login_app\tInvoke login_app instead of /bin/login.\n" \
--      "\t-t timeout\tTerminate after timeout if no username is read.\n" \
--      "\t-I initstring\tSets the init string to send before anything else.\n" \
--      "\t-H login_host\tLog login_host into the utmp file as the hostname."
-+      "\t-h\t\tEnable hardware (RTS/CTS) flow control\n" \
-+      "\t-i\t\tDo not display /etc/issue before running login\n" \
-+      "\t-L\t\tLocal line, so do not do carrier detect\n" \
-+      "\t-m\t\tGet baud rate from modem's CONNECT status message\n" \
-+      "\t-w\t\tWait for a CR or LF before sending /etc/issue\n" \
-+      "\t-n\t\tDo not prompt the user for a login name\n" \
-+      "\t-f issue_file\tDisplay issue_file instead of /etc/issue\n" \
-+      "\t-l login_app\tInvoke login_app instead of /bin/login\n" \
-+      "\t-t timeout\tTerminate after timeout if no username is read\n" \
-+      "\t-I initstring\tSets the init string to send before anything else\n" \
-+      "\t-H login_host\tLog login_host into the utmp file as the hostname"
- #define grep_trivial_usage \
-@@ -841,7 +900,7 @@
- #define halt_full_usage \
-       "Halt the system.\n" \
-       "Options:\n" \
--      "\t-d\t\tdelay interval for halting."
-+      "\t-d\t\tdelay interval for halting"
- #ifdef CONFIG_FEATURE_HDPARM_GET_IDENTITY
- #define USAGE_HDPARM_IDENT(a) a
-@@ -951,7 +1010,7 @@
-       "[-[bcdefnosvx]] [OPTION] FILE"
- #define hexdump_full_usage \
-       "The hexdump utility is a filter which displays the specified files,\n" \
--      "or the standard input, if no files are specified, in a user specified\n"\
-+      "or the standard input, if no files are specified, in a user specified\n" \
-       "format\n" \
-       "\t-b\t\tOne-byte octal display\n" \
-       "\t-c\t\tOne-byte character display\n" \
-@@ -985,26 +1044,26 @@
-       "sage\n"
- #ifdef CONFIG_FEATURE_HTTPD_BASIC_AUTH
--  #define USAGE_HTTPD_BASIC_AUTH(a) a
--  #ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
--    #define USAGE_HTTPD_AUTH_MD5(a) a
--  #else
--    #define USAGE_HTTPD_AUTH_MD5(a)
--  #endif
-+#  define USAGE_HTTPD_BASIC_AUTH(a) a
-+#  ifdef CONFIG_FEATURE_HTTPD_AUTH_MD5
-+#    define USAGE_HTTPD_AUTH_MD5(a) a
-+#  else
-+#    define USAGE_HTTPD_AUTH_MD5(a)
-+#  endif
- #else
--  #define USAGE_HTTPD_BASIC_AUTH(a)
--  #define USAGE_HTTPD_AUTH_MD5(a)
-+#  define USAGE_HTTPD_BASIC_AUTH(a)
-+#  define USAGE_HTTPD_AUTH_MD5(a)
- #endif
- #ifdef CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY
--  #define USAGE_HTTPD_STANDALONE(a)
--  #define USAGE_HTTPD_SETUID(a)
-+#  define USAGE_HTTPD_STANDALONE(a)
-+#  define USAGE_HTTPD_SETUID(a)
- #else
--  #define USAGE_HTTPD_STANDALONE(a) a
--  #ifdef CONFIG_FEATURE_HTTPD_SETUID
--    #define USAGE_HTTPD_SETUID(a) a
--  #else
--    #define USAGE_HTTPD_SETUID(a)
--  #endif
-+#  define USAGE_HTTPD_STANDALONE(a) a
-+#  ifdef CONFIG_FEATURE_HTTPD_SETUID
-+#    define USAGE_HTTPD_SETUID(a) a
-+#  else
-+#    define USAGE_HTTPD_SETUID(a)
-+#  endif
- #endif
- #define httpd_trivial_usage \
-       "[-c <conf file>]" \
-@@ -1015,16 +1074,16 @@
-       " [-h home]" \
-       " [-d/-e <string>]"
- #define httpd_full_usage \
--       "Listens for incoming http server requests.\n\n"\
--       "Options:\n" \
--       "\t-c FILE\t\tSpecifies configuration file. (default httpd.conf)\n" \
--       USAGE_HTTPD_STANDALONE("\t-p PORT\tServer port (default 80)\n") \
--       USAGE_HTTPD_SETUID("\t-u USER\tSet uid to USER after listening privileges port\n") \
--       USAGE_HTTPD_BASIC_AUTH("\t-r REALM\tAuthentication Realm for Basic Authentication\n") \
--       USAGE_HTTPD_AUTH_MD5("\t-m PASS\t\tCrypt PASS with md5 algorithm\n") \
--       "\t-h HOME  \tSpecifies http HOME directory (default ./)\n" \
--       "\t-e STRING\tHtml encode STRING\n" \
--       "\t-d STRING\tURL decode STRING"
-+      "Listens for incoming http server requests.\n\n" \
-+      "Options:\n" \
-+      "\t-c FILE\t\tSpecifies configuration file. (default httpd.conf)\n" \
-+      USAGE_HTTPD_STANDALONE("\t-p PORT\tServer port (default 80)\n") \
-+      USAGE_HTTPD_SETUID("\t-u USER\tSet uid to USER after listening privileges port\n") \
-+      USAGE_HTTPD_BASIC_AUTH("\t-r REALM\tAuthentication Realm for Basic Authentication\n") \
-+      USAGE_HTTPD_AUTH_MD5("\t-m PASS\t\tCrypt PASS with md5 algorithm\n") \
-+      "\t-h HOME  \tSpecifies http HOME directory (default ./)\n" \
-+      "\t-e STRING\tHtml encode STRING\n" \
-+      "\t-d STRING\tURL decode STRING"
- #define hwclock_trivial_usage \
-       "[-r|--show] [-s|--hctosys] [-w|--systohc] [-l|--localtime] [-u|--utc]"
-@@ -1038,9 +1097,9 @@
-       "\t-l\tthe hardware clock is kept in local time"
- #ifdef CONFIG_SELINUX
--  #define USAGE_SELINUX(a) a
-+#  define USAGE_SELINUX(a) a
- #else
--  #define USAGE_SELINUX(a)
-+#  define USAGE_SELINUX(a)
- #endif
- #define id_trivial_usage \
-@@ -1058,29 +1117,29 @@
-       "uid=1000(andersen) gid=1000(andersen)\n"
- #ifdef CONFIG_FEATURE_IFCONFIG_SLIP
--  #define USAGE_SIOCSKEEPALIVE(a) a
-+#  define USAGE_SIOCSKEEPALIVE(a) a
- #else
--  #define USAGE_SIOCSKEEPALIVE(a)
-+#  define USAGE_SIOCSKEEPALIVE(a)
- #endif
- #ifdef CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
--  #define USAGE_IFCONFIG_MII(a) a
-+#  define USAGE_IFCONFIG_MII(a) a
- #else
--  #define USAGE_IFCONFIG_MII(a)
-+#  define USAGE_IFCONFIG_MII(a)
- #endif
- #ifdef CONFIG_FEATURE_IFCONFIG_HW
--  #define USAGE_IFCONFIG_HW(a) a
-+#  define USAGE_IFCONFIG_HW(a) a
- #else
--  #define USAGE_IFCONFIG_HW(a)
-+#  define USAGE_IFCONFIG_HW(a)
- #endif
- #ifdef CONFIG_FEATURE_IFCONFIG_STATUS
--  #define USAGE_IFCONFIG_OPT_A(a) a
-+#  define USAGE_IFCONFIG_OPT_A(a) a
- #else
--  #define USAGE_IFCONFIG_OPT_A(a)
-+#  define USAGE_IFCONFIG_OPT_A(a)
- #endif
- #ifdef CONFIG_FEATURE_IPV6
--  #define USAGE_IPV6(a) a
-+#  define USAGE_IPV6(a) a
- #else
--  #define USAGE_IPV6(a)
-+#  define USAGE_IPV6(a)
- #endif
- #define ifconfig_trivial_usage \
-@@ -1094,7 +1153,7 @@
-       "\t[netmask <address>]  [dstaddr <address>]\n" \
-       USAGE_SIOCSKEEPALIVE("\t[outfill <NN>] [keepalive <NN>]\n") \
-       "\t" USAGE_IFCONFIG_HW("[hw ether <address>]  ") \
--    "[metric <NN>]  [mtu <NN>]\n" \
-+      "[metric <NN>]  [mtu <NN>]\n" \
-       "\t[[-]trailers]  [[-]arp]  [[-]allmulti]\n" \
-       "\t[multicast]  [[-]promisc]  [txqueuelen <NN>]  [[-]dynamic]\n" \
-       USAGE_IFCONFIG_MII("\t[mem_start <NN>]  [io_addr <NN>]  [irq <NN>]\n") \
-@@ -1134,7 +1193,7 @@
-       "Listens for network connections and launches programs\n\n" \
-       "Option:\n" \
-       "\t-q\tSets the size of the socket listen queue to\n" \
--      "\t\tthe specified value. Default is 128."
-+      "\t\tthe specified value. Default is 128"
- #define init_trivial_usage \
-       ""
-@@ -1172,7 +1231,7 @@
- "             WARNING: This field has a non-traditional meaning for BusyBox init!\n" \
- "             The id field is used by BusyBox init to specify the controlling tty for\n" \
- "             the specified process to run on.  The contents of this field are\n" \
--"             appended to "/dev/" and used as-is.  There is no need for this field to\n" \
-+"             appended to \"/dev/\" and used as-is.  There is no need for this field to\n" \
- "             be unique, although if it isn't you may have strange results.  If this\n" \
- "             field is left blank, the controlling tty is set to the console.  Also\n" \
- "             note that if BusyBox detects that a serial console is in use, then only\n" \
-@@ -1218,7 +1277,7 @@
- "                     it.  Unlike sysvinit, BusyBox init does not stop processes from\n" \
- "                     respawning out of control.  The 'askfirst' actions acts just like\n" \
- "                     respawn, except that before running the specified process it\n" \
--"                     displays the line "Please press Enter to activate this console."\n" \
-+"                     displays the line \"Please press Enter to activate this console.\"\n" \
- "                     and then waits for the user to press enter before starting the\n" \
- "                     specified process.\n" \
- "\n" \
-@@ -1238,9 +1297,9 @@
- "     \n" \
- "     # /bin/sh invocations on selected ttys\n" \
- "     #\n" \
--"     # Start an "askfirst" shell on the console (whatever that may be)\n" \
-+"     # Start an \"askfirst\" shell on the console (whatever that may be)\n" \
- "     ::askfirst:-/bin/sh\n" \
--"     # Start an "askfirst" shell on /dev/tty2-4\n" \
-+"     # Start an \"askfirst\" shell on /dev/tty2-4\n" \
- "     tty2::askfirst:-/bin/sh\n" \
- "     tty3::askfirst:-/bin/sh\n" \
- "     tty4::askfirst:-/bin/sh\n" \
-@@ -1268,17 +1327,17 @@
- "     ::shutdown:/sbin/swapoff -a\n"
- #ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP
--  #define USAGE_INSMOD_MAP(a) a
-+#  define USAGE_INSMOD_MAP(a) a
- #else
--  #define USAGE_INSMOD_MAP(a)
-+#  define USAGE_INSMOD_MAP(a)
- #endif
- #define insmod_trivial_usage \
-       "[OPTION]... MODULE [symbol=value]..."
- #define insmod_full_usage \
-       "Loads the specified kernel modules into the kernel.\n\n" \
-       "Options:\n" \
--      "\t-f\tForce module to load into the wrong kernel version.\n" \
--      "\t-k\tMake module autoclean-able.\n" \
-+      "\t-f\tForce module to load into the wrong kernel version\n" \
-+      "\t-k\tMake module autoclean-able\n" \
-       "\t-v\tverbose output\n"  \
-       "\t-q\tquiet output\n" \
-       "\t-L\tLock to prevent simultaneous loads of a module\n" \
-@@ -1319,21 +1378,21 @@
-       "\t\t\tSCOPE-ID := [ host | link | global | NUMBER ]"
- #ifdef CONFIG_FEATURE_IPCALC_FANCY
--  #define XUSAGE_IPCALC_FANCY(a) a
-+#  define XUSAGE_IPCALC_FANCY(a) a
- #else
--  #define XUSAGE_IPCALC_FANCY(a)
-+#  define XUSAGE_IPCALC_FANCY(a)
- #endif
- #define ipcalc_trivial_usage \
-       "[OPTION]... <ADDRESS>[[/]<NETMASK>] [NETMASK]"
- #define ipcalc_full_usage \
-       "Calculate IP network settings from a IP address\n\n" \
-       "Options:\n" \
--      "\t-b\t--broadcast\tDisplay calculated broadcast address.\n" \
--      "\t-n\t--network\tDisplay calculated network address.\n" \
-+      "\t-b\t--broadcast\tDisplay calculated broadcast address\n" \
-+      "\t-n\t--network\tDisplay calculated network address\n" \
-       "\t-m\t--netmask\tDisplay default netmask for IP." \
--      XUSAGE_IPCALC_FANCY(\
-+      XUSAGE_IPCALC_FANCY( \
-       "\n\t-p\t--prefix\tDisplay the prefix for IP/NETMASK." \
--      "\t-h\t--hostname\tDisplay first resolved host name.\n" \
-+      "\t-h\t--hostname\tDisplay first resolved host name\n" \
-       "\t-s\t--silent\tDon't ever display error messages.")
- #define iplink_trivial_usage \
-@@ -1368,9 +1427,9 @@
- #define kill_trivial_usage \
-       "[-signal] process-id [process-id ...]"
- #define kill_full_usage \
--      "Send a signal (default is SIGTERM) to the specified process(es).\n\n"\
-+      "Send a signal (default is SIGTERM) to the specified process(es).\n\n" \
-       "Options:\n" \
--      "\t-l\tList all signal names and numbers."
-+      "\t-l\tList all signal names and numbers"
- #define kill_example_usage \
-       "$ ps | grep apache\n" \
-       "252 root     root     S [apache]\n" \
-@@ -1384,20 +1443,20 @@
- #define killall_trivial_usage \
-       "[-q] [-signal] process-name [process-name ...]"
- #define killall_full_usage \
--      "Send a signal (default is SIGTERM) to the specified process(es).\n\n"\
-+      "Send a signal (default is SIGTERM) to the specified process(es).\n\n" \
-       "Options:\n" \
--      "\t-l\tList all signal names and numbers.\n"\
--      "\t-q\tDo not complain if no processes were killed."
-+      "\t-l\tList all signal names and numbers\n" \
-+      "\t-q\tDo not complain if no processes were killed"
- #define killall_example_usage \
-       "$ killall apache\n"
- #define klogd_trivial_usage \
-       "[-c n] [-n]"
- #define klogd_full_usage \
--      "Kernel logger.\n"\
--      "Options:\n"\
--      "\t-c n\tSets the default log level of console messages to n.\n"\
--      "\t-n\tRun as a foreground process."
-+      "Kernel logger.\n" \
-+      "Options:\n" \
-+      "\t-c n\tSets the default log level of console messages to n\n" \
-+      "\t-n\tRun as a foreground process"
- #define length_trivial_usage \
-       "STRING"
-@@ -1410,12 +1469,14 @@
- #define ln_trivial_usage \
-       "[OPTION] TARGET... LINK_NAME|DIRECTORY"
- #define ln_full_usage \
--      "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n"\
-+      "Create a link named LINK_NAME or DIRECTORY to the specified TARGET\n" \
-       "\nYou may use '--' to indicate that all following arguments are non-options.\n\n" \
-       "Options:\n" \
-       "\t-s\tmake symbolic links instead of hard links\n" \
-       "\t-f\tremove existing destination files\n" \
--      "\t-n\tno dereference symlinks - treat like normal file"
-+      "\t-n\tno dereference symlinks - treat like normal file\n" \
-+      "\t-b\tmake a backup of the target (if exists) before link operation\n" \
-+      "\t-S suffix\tuse suffix instead of ~ when making backup files"
- #define ln_example_usage \
-       "$ ln -s BusyBox /tmp/ls\n" \
-       "$ ls -l /tmp/ls\n" \
-@@ -1440,12 +1501,12 @@
- #define logger_full_usage \
-       "Write MESSAGE to the system log.  If MESSAGE is omitted, log stdin.\n\n" \
-       "Options:\n" \
--      "\t-s\tLog to stderr as well as the system log.\n" \
--      "\t-t TAG\tLog using the specified tag (defaults to user name).\n" \
--      "\t-p PRIORITY\tEnter the message with the specified priority.\n" \
--      "\t\tThis may be numerical or a ``facility.level'' pair."
-+      "\t-s\tLog to stderr as well as the system log\n" \
-+      "\t-t TAG\tLog using the specified tag (defaults to user name)\n" \
-+      "\t-p PRIORITY\tEnter the message with the specified priority\n" \
-+      "\t\tThis may be numerical or a ``facility.level'' pair"
- #define logger_example_usage \
--      "$ logger "hello"\n"
-+      "$ logger \"hello\"\n"
- #define login_trivial_usage \
-       "[OPTION]... [username] [ENV=VAR ...]"
-@@ -1453,8 +1514,8 @@
-       "Begin a new session on the system\n\n" \
-       "Options:\n" \
-       "\t-f\tDo not authenticate (user already authenticated)\n" \
--      "\t-h\tName of the remote host for this login.\n" \
--      "\t-p\tPreserve environment."
-+      "\t-h\tName of the remote host for this login\n" \
-+      "\t-p\tPreserve environment"
- #define logname_trivial_usage \
-       ""
-@@ -1467,7 +1528,7 @@
- #define logread_trivial_usage \
-       "[OPTION]..."
- #define logread_full_usage \
--        "Shows the messages from syslogd (using circular buffer).\n\n" \
-+      "Shows the messages from syslogd (using circular buffer).\n\n" \
-       "Options:\n" \
-       "\t-f\t\toutput data as the log grows"
-@@ -1477,38 +1538,38 @@
- #define losetup_full_usage \
-       "Associate LOOPDEVICE with FILE.\n\n" \
-       "Options:\n" \
--      "\t-d\t\tDisassociate LOOPDEVICE.\n" \
--      "\t-o OFFSET\tStart OFFSET bytes into FILE."
-+      "\t-d\t\tDisassociate LOOPDEVICE\n" \
-+      "\t-o OFFSET\tStart OFFSET bytes into FILE"
- #ifdef CONFIG_FEATURE_LS_TIMESTAMPS
--  #define USAGE_LS_TIMESTAMPS(a) a
-+#  define USAGE_LS_TIMESTAMPS(a) a
- #else
--  #define USAGE_LS_TIMESTAMPS(a)
-+#  define USAGE_LS_TIMESTAMPS(a)
- #endif
- #ifdef CONFIG_FEATURE_LS_FILETYPES
--  #define USAGE_LS_FILETYPES(a) a
-+#  define USAGE_LS_FILETYPES(a) a
- #else
--  #define USAGE_LS_FILETYPES(a)
-+#  define USAGE_LS_FILETYPES(a)
- #endif
- #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS
--  #define USAGE_LS_FOLLOWLINKS(a) a
-+#  define USAGE_LS_FOLLOWLINKS(a) a
- #else
--  #define USAGE_LS_FOLLOWLINKS(a)
-+#  define USAGE_LS_FOLLOWLINKS(a)
- #endif
- #ifdef CONFIG_FEATURE_LS_RECURSIVE
--  #define USAGE_LS_RECURSIVE(a) a
-+#  define USAGE_LS_RECURSIVE(a) a
- #else
--  #define USAGE_LS_RECURSIVE(a)
-+#  define USAGE_LS_RECURSIVE(a)
- #endif
- #ifdef CONFIG_FEATURE_LS_SORTFILES
--  #define USAGE_LS_SORTFILES(a) a
-+#  define USAGE_LS_SORTFILES(a) a
- #else
--  #define USAGE_LS_SORTFILES(a)
-+#  define USAGE_LS_SORTFILES(a)
- #endif
- #ifdef CONFIG_FEATURE_AUTOWIDTH
--  #define USAGE_AUTOWIDTH(a) a
-+#  define USAGE_AUTOWIDTH(a) a
- #else
--  #define USAGE_AUTOWIDTH(a)
-+#  define USAGE_AUTOWIDTH(a)
- #endif
- #define ls_trivial_usage \
-@@ -1545,6 +1606,17 @@
-       USAGE_SELINUX("\t-k\tprint security context\n") \
-       USAGE_SELINUX("\t-K\tprint security context in long format\n")
-+#define lsattr_trivial_usage \
-+      "[-Radlv] [files...]"
-+#define lsattr_full_usage \
-+      "list file attributes on an ext2 fs\n\n" \
-+      "Options:\n" \
-+      "\t-R\trecursively list subdirectories\n" \
-+      "\t-a\tdo not hide entries starting with .\n" \
-+      "\t-d\tlist directory entries instead of contents\n" \
-+      "\t-l\tprint long flag names\n" \
-+      "\t-v\tlist the file's version/generation number"
-+
- #define lsmod_trivial_usage \
-       ""
- #define lsmod_full_usage \
-@@ -1559,7 +1631,7 @@
-       "\tc or u:\tMake a character (un-buffered) device.\n" \
-       "\tp:\tMake a named pipe. MAJOR and MINOR are ignored for named pipes.\n\n" \
-       "FIRST specifies the number appended to NAME to create the first device.\n" \
--      "LAST specifies the number of the last item that should be created.\n" \
-+      "LAST specifies the number of the last item that should be created\n" \
-       "If 's' is the last argument, the base device is created as well.\n\n" \
-       "For example:\n" \
-       "\tmakedevs /dev/ttyS c 4 66 2 63   ->  ttyS2-ttyS63\n" \
-@@ -1602,8 +1674,8 @@
-       "[y|n]"
- #define mesg_full_usage \
-       "mesg controls write access to your terminal\n" \
--      "\ty\tAllow write access to your terminal.\n" \
--      "\tn\tDisallow write access to your terminal.\n"
-+      "\ty\tAllow write access to your terminal\n" \
-+      "\tn\tDisallow write access to your terminal"
- #define mkdir_trivial_usage \
-       "[OPTION] DIRECTORY..."
-@@ -1645,9 +1717,9 @@
-       "Options:\n" \
-       "\t-m\tcreate the special file using the specified mode (default a=rw)\n\n" \
-       "TYPEs include:\n" \
--      "\tb:\tMake a block (buffered) device.\n" \
--      "\tc or u:\tMake a character (un-buffered) device.\n" \
--      "\tp:\tMake a named pipe. MAJOR and MINOR are ignored for named pipes."
-+      "\tb:\tMake a block (buffered) device\n" \
-+      "\tc or u:\tMake a character (un-buffered) device\n" \
-+      "\tp:\tMake a named pipe. MAJOR and MINOR are ignored for named pipes"
- #define mknod_example_usage \
-       "$ mknod /dev/fd0 b 2 0\n" \
-       "$ mknod -m 644 /tmp/pipe p\n"
-@@ -1657,10 +1729,10 @@
- #define mkswap_full_usage \
-       "Prepare a disk partition to be used as a swap partition.\n\n" \
-       "Options:\n" \
--      "\t-c\t\tCheck for read-ability.\n" \
--      "\t-v0\t\tMake version 0 swap [max 128 Megs].\n" \
--      "\t-v1\t\tMake version 1 swap [big!] (default for kernels >\n\t\t\t2.1.117).\n" \
--      "\tblock-count\tNumber of block to use (default is entire partition)."
-+      "\t-c\t\tCheck for read-ability\n" \
-+      "\t-v0\t\tMake version 0 swap [max 128 Megs]\n" \
-+      "\t-v1\t\tMake version 1 swap [big!] (default for kernels >\n\t\t\t2.1.117)\n" \
-+      "\tblock-count\tNumber of block to use (default is entire partition)"
- #define mktemp_trivial_usage \
-       "[-dq] TEMPLATE"
-@@ -1681,12 +1753,12 @@
- #define modprobe_full_usage \
-       "Used for high level module loading and unloading.\n\n" \
-       "Options:\n" \
--      "\t-k\tMake module autoclean-able.\n" \
--      "\t-n\tJust show what would be done.\n" \
--      "\t-q\tQuiet output.\n" \
--      "\t-r\tRemove module (stacks) or do autoclean.\n" \
--      "\t-s\tReport via syslog instead of stderr.\n" \
--      "\t-v\tVerbose output."
-+      "\t-k\tMake module autoclean-able\n" \
-+      "\t-n\tJust show what would be done\n" \
-+      "\t-q\tQuiet output\n" \
-+      "\t-r\tRemove module (stacks) or do autoclean\n" \
-+      "\t-s\tReport via syslog instead of stderr\n" \
-+      "\t-v\tVerbose output"
- #define modprobe_example_usage \
-       "$ modprobe cdrom\n"
-@@ -1698,14 +1770,14 @@
-       "$ dmesg | more\n"
- #ifdef CONFIG_FEATURE_MOUNT_LOOP
--  #define USAGE_MOUNT_LOOP(a) a
-+#  define USAGE_MOUNT_LOOP(a) a
- #else
--  #define USAGE_MOUNT_LOOP(a)
-+#  define USAGE_MOUNT_LOOP(a)
- #endif
- #ifdef CONFIG_FEATURE_MTAB_SUPPORT
--  #define USAGE_MTAB(a) a
-+#  define USAGE_MTAB(a) a
- #else
--  #define USAGE_MTAB(a)
-+#  define USAGE_MTAB(a)
- #endif
- #define mount_trivial_usage \
-       "[flags] DEVICE NODE [-o options,more-options]"
-@@ -1713,30 +1785,30 @@
-       "Mount a filesystem.  Autodetection of filesystem type requires the\n" \
-       "/proc filesystem be already mounted.\n\n" \
-       "Flags:\n"  \
--      "\t-a:\t\tMount all filesystems in fstab.\n" \
-+      "\t-a:\t\tMount all filesystems in fstab\n" \
-       USAGE_MTAB( \
--      "\t-f:\t\t\"Fake\" Add entry to mount table but don't mount it.\n" \
--      "\t-n:\t\tDon't write a mount table entry.\n" \
-+      "\t-f:\t\t\"Fake\" Add entry to mount table but don't mount it\n" \
-+      "\t-n:\t\tDon't write a mount table entry\n" \
-       ) \
--      "\t-o option:\tOne of many filesystem options, listed below.\n" \
--      "\t-r:\t\tMount the filesystem read-only.\n" \
--      "\t-t fs-type:\tSpecify the filesystem type.\n" \
--      "\t-w:\t\tMount for reading and writing (default).\n" \
-+      "\t-o option:\tOne of many filesystem options, listed below\n" \
-+      "\t-r:\t\tMount the filesystem read-only\n" \
-+      "\t-t fs-type:\tSpecify the filesystem type\n" \
-+      "\t-w:\t\tMount for reading and writing (default)\n" \
-       "\n" \
-       "Options for use with the \"-o\" flag:\n" \
--      "\tasync/sync:\tWrites are asynchronous / synchronous.\n" \
--      "\tatime/noatime:\tEnable / disable updates to inode access times.\n" \
--      "\tdev/nodev:\tAllow use of special device files / disallow them.\n" \
--      "\texec/noexec:\tAllow use of executable files / disallow them.\n" \
-+      "\tasync/sync:\tWrites are asynchronous / synchronous\n" \
-+      "\tatime/noatime:\tEnable / disable updates to inode access times\n" \
-+      "\tdev/nodev:\tAllow use of special device files / disallow them\n" \
-+      "\texec/noexec:\tAllow use of executable files / disallow them\n" \
-       USAGE_MOUNT_LOOP( \
--      "\tloop:\t\tMounts a file via loop device.\n" \
-+      "\tloop:\t\tMounts a file via loop device\n" \
-       ) \
--      "\tsuid/nosuid:\tAllow set-user-id-root programs / disallow them.\n" \
--      "\tremount:\tRe-mount a mounted filesystem, changing its flags.\n" \
--      "\tro/rw:\t\tMount for read-only / read-write.\n" \
--      "\tbind:\t\tUse the linux 2.4.x \"bind\" feature.\n" \
--      "\nThere are EVEN MORE flags that are specific to each filesystem.\n" \
--      "You'll have to see the written documentation for those filesystems."
-+      "\tsuid/nosuid:\tAllow set-user-id-root programs / disallow them\n" \
-+      "\tremount:\tRe-mount a mounted filesystem, changing its flags\n" \
-+      "\tro/rw:\t\tMount for read-only / read-write\n" \
-+      "\tbind:\t\tUse the linux 2.4.x \"bind\" feature\n" \
-+      "\nThere are EVEN MORE flags that are specific to each filesystem\n" \
-+      "You'll have to see the written documentation for those filesystems"
- #define mount_example_usage \
-       "$ mount\n" \
-       "/dev/hda3 on / type minix (rw)\n" \
-@@ -1772,13 +1844,18 @@
-       "Nameif renaming network interface while it in the down state.\n\n" \
-       "Options:\n" \
-       "\t-c FILE\t\tUse configuration file (default is /etc/mactab)\n" \
--      "\t-s\t\tUse syslog (LOCAL0 facility).\n" \
-+      "\t-s\t\tUse syslog (LOCAL0 facility)\n" \
-       "\tIFNAME MACADDR\tnew_interface_name interface_mac_address"
- #define nameif_example_usage \
-       "$ nameif -s dmz0 00:A0:C9:8C:F6:3F\n" \
-       " or\n" \
-       "$ nameif -c /etc/my_mactab_file\n" \
-+#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
-+#  define USAGE_NC_EXEC(a) a
-+#else
-+#  define USAGE_NC_EXEC(a)
-+#endif
- #define nc_trivial_usage \
-       "[OPTIONS] [IP] [port]"
- #define nc_full_usage \
-@@ -1787,7 +1864,10 @@
-       "\t-l\t\tlisten mode, for inbound connects\n" \
-       "\t-p PORT\t\tlocal port number\n" \
-       "\t-i SECS\t\tdelay interval for lines sent\n" \
--      "\t-e PROG\t\tprogram to exec after connect (dangerous!)"
-+      USAGE_NC_EXEC( \
-+      "\t-e PROG\t\tprogram to exec after connect (dangerous!)\n" \
-+      ) \
-+      "\t-w SECS\t\ttimeout for connects and final net reads"
- #define nc_example_usage \
-       "$ nc foobar.somedomain.com 25\n" \
-       "220 foobar ESMTP Exim 3.12 #1 Sat, 15 Apr 2000 00:03:02 -0600\n" \
-@@ -1813,6 +1893,13 @@
-       "\t-w raw sockets\n" \
-       "\t-x unix sockets"
-+#define nice_trivial_usage \
-+      "[-n ADJUST] [COMMAND [ARG] ...]"
-+#define nice_full_usage \
-+      "Nice runs a program with modified scheduling priority.\n\n" \
-+      "Options:\n" \
-+      "\t-n ADJUST\tAdjust the scheduling priority by ADJUST"
-+
- #define nslookup_trivial_usage \
-       "[HOST] [SERVER]"
- #define nslookup_full_usage \
-@@ -1829,7 +1916,7 @@
- #define od_trivial_usage \
-       "[-aBbcDdeFfHhIiLlOovXx] [FILE]"
- #define od_full_usage \
--      "Write an unambiguous representation, octal bytes by default, of FILE\n"\
-+      "Write an unambiguous representation, octal bytes by default, of FILE\n" \
-       "to standard output.  With no FILE, or when FILE is -, read standard input."
- #define openvt_trivial_usage \
-@@ -1840,9 +1927,9 @@
-       "openvt 2 /bin/ash\n"
- #ifdef CONFIG_FEATURE_SHA1_PASSWORDS
--  #define PASSWORD_ALG_TYPES(a) a
-+#  define PASSWORD_ALG_TYPES(a) a
- #else
--  #define PASSWORD_ALG_TYPES(a)
-+#  define PASSWORD_ALG_TYPES(a)
- #endif
- #define passwd_trivial_usage \
-       "[OPTION] [name]"
-@@ -1850,12 +1937,12 @@
-       "Change a user password. If no name is specified,\n" \
-       "changes the password for the current user.\n" \
-       "Options:\n" \
--      "\t-a\tDefine which algorithm shall be used for the password.\n" \
-+      "\t-a\tDefine which algorithm shall be used for the password\n" \
-       "\t\t\t(Choices: des, md5" \
-       PASSWORD_ALG_TYPES(", sha1") \
--      ")\n\t-d\tDelete the password for the specified user account.\n" \
--      "\t-l\tLocks (disables) the specified user account.\n" \
--      "\t-u\tUnlocks (re-enables) the specified user account."
-+      ")\n\t-d\tDelete the password for the specified user account\n" \
-+      "\t-l\tLocks (disables) the specified user account\n" \
-+      "\t-u\tUnlocks (re-enables) the specified user account"
- #define patch_trivial_usage \
-       "[-p<num>]"
-@@ -1870,7 +1957,7 @@
-       "Lists the PIDs of all processes with names that match the\n" \
-       "names on the command line.\n" \
-       "Options:\n" \
--      "\t-s\t\tdisplay only a single PID."
-+      "\t-s\t\tdisplay only a single PID"
- #define pidof_example_usage \
-       "$ pidof init\n" \
-       "1\n"
-@@ -1884,10 +1971,10 @@
- #define ping_full_usage \
-       "Send ICMP ECHO_REQUEST packets to network hosts.\n\n" \
-       "Options:\n" \
--      "\t-c COUNT\tSend only COUNT pings.\n" \
--      "\t-s SIZE\t\tSend SIZE data bytes in packets (default=56).\n" \
-+      "\t-c COUNT\tSend only COUNT pings\n" \
-+      "\t-s SIZE\t\tSend SIZE data bytes in packets (default=56)\n" \
-       "\t-q\t\tQuiet mode, only displays output at start\n" \
--      "\t\t\tand when finished."
-+      "\t\t\tand when finished"
- #endif
- #define ping_example_usage \
-       "$ ping localhost\n" \
-@@ -1907,10 +1994,10 @@
- #define ping6_full_usage \
-       "Send ICMP ECHO_REQUEST packets to network hosts.\n\n" \
-       "Options:\n" \
--      "\t-c COUNT\tSend only COUNT pings.\n" \
--      "\t-s SIZE\t\tSend SIZE data bytes in packets (default=56).\n" \
-+      "\t-c COUNT\tSend only COUNT pings\n" \
-+      "\t-s SIZE\t\tSend SIZE data bytes in packets (default=56)\n" \
-       "\t-q\t\tQuiet mode, only displays output at start\n" \
--      "\t\t\tand when finished."
-+      "\t\t\tand when finished"
- #endif
- #define ping6_example_usage \
-       "$ ping6 ip6-localhost\n" \
-@@ -1932,7 +2019,13 @@
- #define poweroff_full_usage \
-       "Halt the system and request that the kernel shut off the power.\n" \
-       "Options:\n" \
--      "\t-d\t\tdelay interval for shutting off."
-+      "\t-d\t\tdelay interval for shutting off"
-+
-+#define printenv_trivial_usage \
-+      "[VARIABLES...]"
-+#define printenv_full_usage \
-+      "print all or part of environment\n\n" \
-+      "If no environment VARIABLE specified, print them all."
- #define printf_trivial_usage \
-       "FORMAT [ARGUMENT...]"
-@@ -1940,7 +2033,7 @@
-       "Formats and prints ARGUMENT(s) according to FORMAT,\n" \
-       "Where FORMAT controls the output exactly as in C printf."
- #define printf_example_usage \
--      "$ printf "Val=%d\\n" 5\n" \
-+      "$ printf \"Val=%d\\n\" 5\n" \
-       "Val=5\n"
- #ifdef CONFIG_SELINUX
-@@ -1982,13 +2075,36 @@
- #define rdate_full_usage \
-       "Get and possibly set the system date and time from a remote HOST.\n\n" \
-       "Options:\n" \
--      "\t-s\tSet the system date and time (default).\n" \
--      "\t-p\tPrint the date and time."
-+      "\t-s\tSet the system date and time (default)\n" \
-+      "\t-p\tPrint the date and time"
-+
-+#ifdef CONFIG_FEATURE_READLINK_FOLLOW
-+#define USAGE_READLINK_FOLLOW(a) a
-+#else
-+#define USAGE_READLINK_FOLLOW(a)
-+#endif
- #define readlink_trivial_usage \
--      ""
-+      USAGE_READLINK_FOLLOW("[-f] ") "FILE"
- #define readlink_full_usage \
--      "Displays the value of a symbolic link."
-+      "Displays the value of a symbolic link." \
-+      USAGE_READLINK_FOLLOW("\n\nOptions:\n" \
-+      "\t-f\tcanonicalize by following all symlinks")
-+
-+#define readprofile_trivial_usage \
-+      "[OPTIONS]..."
-+#define readprofile_full_usage \
-+      "Options:\n" \
-+      "\t -m <mapfile>  (default: /boot/System.map)\n" \
-+      "\t -p <profile>  (default: /proc/profile)\n" \
-+      "\t -M <mult>     set the profiling multiplier to <mult>\n" \
-+      "\t -i            print only info about the sampling step\n" \
-+      "\t -v            print verbose data\n" \
-+      "\t -a            print all symbols, even if count is 0\n" \
-+      "\t -b            print individual histogram-bin counts\n" \
-+      "\t -s            print individual counters within functions\n" \
-+      "\t -r            reset all the counters (root only)\n" \
-+      "\t -n            disable byte order auto-detection"
- #define realpath_trivial_usage \
-       "pathname  ..."
-@@ -2000,14 +2116,17 @@
- #define reboot_full_usage \
-       "Reboot the system.\n" \
-       "Options:\n" \
--      "\t-d\t\tdelay interval for rebooting."
-+      "\t-d\t\tdelay interval for rebooting"
- #define renice_trivial_usage \
--      "priority pid [pid ...]"
-+      "{{-n INCREMENT} | PRIORITY} [[ -p | -g | -u ] ID ...]"
- #define renice_full_usage \
--      "Changes priority of running processes. Allowed priorities range\n" \
--      "from 20 (the process runs only when nothing else is running) to 0\n" \
--      "(default priority) to -20 (almost nothing else ever gets to run)."
-+      "Changes priority of running processes.\n\n" \
-+      "Options:\n" \
-+      "\t-n\tadjusts current nice value (smaller is faster)\n" \
-+      "\t-p\tprocess id(s) (default)\n" \
-+      "\t-g\tprocess group id(s)\n" \
-+      "\t-u\tprocess user name(s) and/or id(s)"
- #define reset_trivial_usage \
-       ""
-@@ -2043,9 +2162,9 @@
-       "$ rmmod tulip\n"
- #ifdef CONFIG_FEATURE_IPV6
--  #define USAGE_ROUTE_IPV6(a) a
-+#  define USAGE_ROUTE_IPV6(a) a
- #else
--  #define USAGE_ROUTE_IPV6(a) "\t"
-+#  define USAGE_ROUTE_IPV6(a) "\t"
- #endif
-@@ -2054,9 +2173,9 @@
- #define route_full_usage \
-       "Edit the kernel's routing tables.\n\n" \
-       "Options:\n" \
--      "\t-n\t\tDont resolve names.\n" \
--      "\t-e\t\tDisplay other/more information.\n" \
--      "\t-A inet" USAGE_ROUTE_IPV6("{6}") "\tSelect address family."
-+      "\t-n\t\tDont resolve names\n" \
-+      "\t-e\t\tDisplay other/more information\n" \
-+      "\t-A inet" USAGE_ROUTE_IPV6("{6}") "\tSelect address family"
- #define rpm_trivial_usage \
-       "-i -q[ildc]p package.rpm"
-@@ -2081,9 +2200,9 @@
- #define run_parts_full_usage \
-       "Run a bunch of scripts in a directory.\n\n" \
-       "Options:\n" \
--      "\t-t\tPrints what would be run, but does not actually run anything.\n" \
--      "\t-a ARG\tPass ARG as an argument for every program invoked.\n" \
--      "\t-u MASK\tSet the umask to MASK before executing every program."
-+      "\t-t\tPrints what would be run, but does not actually run anything\n" \
-+      "\t-a ARG\tPass ARG as an argument for every program invoked\n" \
-+      "\t-u MASK\tSet the umask to MASK before executing every program"
- #define rx_trivial_usage \
-       "FILE"
-@@ -2098,18 +2217,18 @@
-       "Options:\n" \
-       "\t-e script\tadd the script to the commands to be executed\n" \
-       "\t-f scriptfile\tadd script-file contents to the\n" \
--          "\t\t\tcommands to be executed\n" \
-+      "\t\t\tcommands to be executed\n" \
-       "\t-i\t\tedit files in-place\n" \
-       "\t-n\t\tsuppress automatic printing of pattern space\n" \
-       "\t-r\t\tuse extended regular expression syntax\n" \
-       "\n" \
--      "If no -e or -f is given, the first non-option argument is taken as the sed\n"\
--      "script to interpret. All remaining arguments are names of input files; if no\n"\
-+      "If no -e or -f is given, the first non-option argument is taken as the sed\n" \
-+      "script to interpret. All remaining arguments are names of input files; if no\n" \
-       "input files are specified, then the standard input is read.  Source files\n" \
-       "will not be modified unless -i option is given."
- #define sed_example_usage \
--      "$ echo "foo" | sed -e 's/f[a-zA-Z]o/bar/g'\n" \
-+      "$ echo \"foo\" | sed -e 's/f[a-zA-Z]o/bar/g'\n" \
-       "bar\n"
- #define seq_trivial_usage \
-@@ -2142,7 +2261,7 @@
-       "Use lash just as you would use any other shell.  It properly handles pipes,\n" \
-       "redirects, job control, can be used as the shell for scripts, and has a\n" \
-       "sufficient set of builtins to do what is needed.  It does not (yet) support\n" \
--      "Bourne Shell syntax.  If you need things like "if-then-else", "while", and such\n" \
-+      "Bourne Shell syntax.  If you need things like \"if-then-else\", \"while\", and such\n" \
-       "use ash or bash.  If you just need a very simple and extremely small shell,\n" \
-       "this will do the job."
-@@ -2165,11 +2284,11 @@
-       "\t-w\twarn about improperly formated SHA1 checksum lines")
- #ifdef CONFIG_FEATURE_FANCY_SLEEP
--  #define USAGE_FANCY_SLEEP(a) a
--  #define USAGE_NOT_FANCY_SLEEP(a)
-+#  define USAGE_FANCY_SLEEP(a) a
-+#  define USAGE_NOT_FANCY_SLEEP(a)
- #else
--  #define USAGE_FANCY_SLEEP(a)
--  #define USAGE_NOT_FANCY_SLEEP(a) a
-+#  define USAGE_FANCY_SLEEP(a)
-+#  define USAGE_NOT_FANCY_SLEEP(a) a
- #endif
- #define sleep_trivial_usage \
-@@ -2185,24 +2304,39 @@
-       USAGE_FANCY_SLEEP("$ sleep 1d 3h 22m 8s\n" \
-       "[98528 second delay results]\n")
--#ifdef CONFIG_FEATURE_SORT_UNIQUE
--  #define USAGE_SORT_UNIQUE(a) a
--#else
--  #define USAGE_SORT_UNIQUE(a)
--#endif
--#ifdef CONFIG_FEATURE_SORT_REVERSE
--  #define USAGE_SORT_REVERSE(a) a
-+#ifdef CONFIG_SORT_BIG
-+#  define USAGE_SORT_BIG(a) a
- #else
--  #define USAGE_SORT_REVERSE(a)
-+#  define USAGE_SORT_BIG(a)
- #endif
-+
- #define sort_trivial_usage \
--      "[-n" USAGE_SORT_REVERSE("r") USAGE_SORT_UNIQUE("u") "] [FILE]..."
-+      "[-nru" USAGE_SORT_BIG("gMcszbdfimSTokt] [-o outfile] [-k start[.offset][opts][,end[.offset][opts]] [-t char") "] [FILE]..."
- #define sort_full_usage \
--      "Sorts lines of text in the specified files\n\n"\
-+      "Sorts lines of text in the specified files\n\n" \
-       "Options:\n" \
--      USAGE_SORT_UNIQUE("\t-u\tsuppress duplicate lines\n") \
--      USAGE_SORT_REVERSE("\t-r\tsort in reverse order\n") \
--      "\t-n\tsort numerics"
-+      USAGE_SORT_BIG( \
-+              "\t-b\tignore leading blanks\n" \
-+              "\t-c\tcheck whether input is sorted\n" \
-+              "\t-d\tdictionary order (blank or alphanumeric only)\n" \
-+              "\t-f\tignore case\n" \
-+              "\t-g\tgeneral numerical sort\n" \
-+              "\t-i\tignore unprintable characters\n" \
-+              "\t-k\tspecify sort key\n" \
-+              "\t-M\tsort month\n" \
-+      ) \
-+      "\t-n\tsort numbers\n" \
-+      USAGE_SORT_BIG( \
-+              "\t-o\toutput to file\n" \
-+              "\t-k\tsort by key\n" \
-+              "\t-t\tuse key separator other than whitespace\n" \
-+      ) \
-+      "\t-r\treverse sort order\n" \
-+      USAGE_SORT_BIG("\t-s\tstable (don't sort ties alphabetically)\n") \
-+      "\t-u\tsuppress duplicate lines" \
-+      USAGE_SORT_BIG("\n\t-z\tinput terminated by nulls, not newlines\n") \
-+      USAGE_SORT_BIG("\t-mST\tignored for GNU compatability") \
-+      ""
- #define sort_example_usage \
-       "$ echo -e \"e\\nf\\nb\\nd\\nc\\na\" | sort\n" \
-       "a\n" \
-@@ -2210,34 +2344,98 @@
-       "c\n" \
-       "d\n" \
-       "e\n" \
--      "f\n"
-+      "f\n" \
-+      USAGE_SORT_BIG( \
-+              "$ echo -e \"c 3\\nb 2\\nd 2\" | $SORT -k 2,2n -k 1,1r\n" \
-+              "d 2\n" \
-+              "b 2\n" \
-+              "c 3\n" \
-+      ) \
-+      ""
- #define start_stop_daemon_trivial_usage \
--      "[OPTIONS] [--start|--stop] ... [-- arguments...]\n"
-+      "[OPTIONS] [--start|--stop] ... [-- arguments...]"
- #define start_stop_daemon_full_usage \
--      "Program to start and stop services."\
--      "\n\nOptions:"\
--      "\n\t-S|--start\t\t\tstart"\
--      "\n\t-K|--stop\t\t\tstop"\
--      "\n\t-a|--startas <pathname>\t\tstarts process specified by pathname"\
--      "\n\t-b|--background\t\t\tforce process into background"\
--      "\n\t-u|--user <username>|<uid>\tstop this user's processes"\
--      "\n\t-x|--exec <executable>\t\tprogram to either start or check"\
--      "\n\t-m|--make-pidfile <filename>\tcreate the -p file and enter pid in it"\
--      "\n\t-n|--name <process-name>\tstop processes with this name"\
--      "\n\t-p|--pidfile <pid-file>\t\tsave or load pid using a pid-file"\
-+      "Program to start and stop services." \
-+      "\n\nOptions:" \
-+      "\n\t-S|--start\t\t\tstart" \
-+      "\n\t-K|--stop\t\t\tstop" \
-+      "\n\t-a|--startas <pathname>\t\tstarts process specified by pathname" \
-+      "\n\t-b|--background\t\t\tforce process into background" \
-+      "\n\t-u|--user <username>|<uid>\tstop this user's processes" \
-+      "\n\t-x|--exec <executable>\t\tprogram to either start or check" \
-+      "\n\t-m|--make-pidfile <filename>\tcreate the -p file and enter pid in it" \
-+      "\n\t-n|--name <process-name>\tstop processes with this name" \
-+      "\n\t-p|--pidfile <pid-file>\t\tsave or load pid using a pid-file" \
-       "\n\t-q|--quiet\t\t\tbe quiet" \
-       "\n\t-s|--signal <signal>\t\tsignal to send (default TERM)"
-+#ifdef CONFIG_FEATURE_STAT_FORMAT
-+#  define USAGE_STAT_FORMAT(a) a
-+#else
-+#  define USAGE_STAT_FORMAT(a)
-+#endif
-+#define stat_trivial_usage \
-+      "[OPTION] FILE..."
-+#define stat_full_usage \
-+      "display file (default) or filesystem status.\n\n" \
-+      "Options:\n" \
-+      USAGE_STAT_FORMAT("\t-c fmt\tuse the specified format\n") \
-+      "\t-f\tdisplay filesystem status\n" \
-+      "\t-L,-l\tdereference links\n" \
-+      "\t-t\tdisplay info in terse form\n" \
-+      USAGE_STAT_FORMAT( \
-+      "\nValid format sequences for files:\n" \
-+      "  %a   Access rights in octal\n" \
-+      "  %A   Access rights in human readable form\n" \
-+      "  %b   Number of blocks allocated (see %B)\n" \
-+      "  %B   The size in bytes of each block reported by %b\n" \
-+      "  %d   Device number in decimal\n" \
-+      "  %D   Device number in hex\n" \
-+      "  %f   Raw mode in hex\n" \
-+      "  %F   File type\n" \
-+      "  %g   Group ID of owner\n" \
-+      "  %G   Group name of owner\n" \
-+      "  %h   Number of hard links\n" \
-+      "  %i   Inode number\n" \
-+      "  %n   File name\n" \
-+      "  %N   Quoted file name with dereference if symbolic link\n" \
-+      "  %o   I/O block size\n" \
-+      "  %s   Total size, in bytes\n" \
-+      "  %t   Major device type in hex\n" \
-+      "  %T   Minor device type in hex\n" \
-+      "  %u   User ID of owner\n" \
-+      "  %U   User name of owner\n" \
-+      "  %x   Time of last access\n" \
-+      "  %X   Time of last access as seconds since Epoch\n" \
-+      "  %y   Time of last modification\n" \
-+      "  %Y   Time of last modification as seconds since Epoch\n" \
-+      "  %z   Time of last change\n" \
-+      "  %Z   Time of last change as seconds since Epoch\n" \
-+      "\nValid format sequences for file systems:\n" \
-+      "  %a   Free blocks available to non-superuser\n" \
-+      "  %b   Total data blocks in file system\n" \
-+      "  %c   Total file nodes in file system\n" \
-+      "  %d   Free file nodes in file system\n" \
-+      "  %f   Free blocks in file system\n" \
-+      "  %i   File System ID in hex\n" \
-+      "  %l   Maximum length of filenames\n" \
-+      "  %n   File name\n" \
-+      "  %s   Block size (for faster transfers)\n" \
-+      "  %S   Fundamental block size (for block counts)\n" \
-+      "  %t   Type in hex\n" \
-+      "  %T   Type in human readable form\n" \
-+      )
-+
- #define strings_trivial_usage \
-       "[-afo] [-n length] [file ... ]"
- #define strings_full_usage \
-       "Display printable strings in a binary file." \
-       "\n\nOptions:" \
--      "\n\t-a\tScan the whole files (this is the default)."\
-+      "\n\t-a\tScan the whole files (this is the default)." \
-       "\n\t-f\tPrecede each string with the name of the file where it was found." \
-       "\n\t-n N\tSpecifies that at least N characters forms a sequence (default 4)" \
--      "\n\t-o\tEach string is preceded by its decimal offset in the file."
-+      "\n\t-o\tEach string is preceded by its decimal offset in the file"
- #define stty_trivial_usage \
-       "[-a|g] [-F DEVICE] [SETTING]..."
-@@ -2263,8 +2461,16 @@
-       "Single user login\n" \
-       "Options:\n" \
-       "\t-f\tDo not authenticate (user already authenticated)\n" \
--      "\t-h\tName of the remote host for this login.\n" \
--      "\t-p\tPreserve environment."
-+      "\t-h\tName of the remote host for this login\n" \
-+      "\t-p\tPreserve environment"
-+
-+#define sum_trivial_usage \
-+      "[rs] [files...]"
-+#define sum_full_usage \
-+      "checksum and count the blocks in a file\n\n" \
-+      "Options:\n" \
-+      "\t-r\tuse BSD sum algorithm (1K blocks)\n" \
-+      "\t-s\tuse System V sum algorithm (512byte blocks)"
- #define swapoff_trivial_usage \
-       "[OPTION] [DEVICE]"
-@@ -2287,32 +2493,32 @@
- #ifdef CONFIG_FEATURE_ROTATE_LOGFILE
--      #define USAGE_ROTATE_LOGFILE(a) a
-+#  define USAGE_ROTATE_LOGFILE(a) a
- #else
--      #define USAGE_ROTATE_LOGFILE(a)
-+#  define USAGE_ROTATE_LOGFILE(a)
- #endif
- #ifdef CONFIG_FEATURE_REMOTE_LOG
--  #define USAGE_REMOTE_LOG(a) a
-+#  define USAGE_REMOTE_LOG(a) a
- #else
--  #define USAGE_REMOTE_LOG(a)
-+#  define USAGE_REMOTE_LOG(a)
- #endif
- #ifdef CONFIG_FEATURE_IPC_SYSLOG
--  #define USAGE_IPC_LOG(a) a
-+#  define USAGE_IPC_LOG(a) a
- #else
--  #define USAGE_IPC_LOG(a)
-+#  define USAGE_IPC_LOG(a)
- #endif
- #ifdef CONFIG_SYSCTL
- #define sysctl_trivial_usage \
--      "[OPTIONS]... [VALUE]...\n"
-+      "[OPTIONS]... [VALUE]..."
- #define sysctl_full_usage
-       "sysctl - configure kernel parameters at runtime\n\n" \
-       "Options:\n" \
--      "\t-n\tUse this option to disable printing of the key name when printing values.\n" \
--      "\t-w\tUse this option when you want to change a sysctl setting.\n" \
--      "\t-p\tLoad in sysctl settings from the file specified or /etc/sysctl.conf if none given.\n" \
--      "\t-a\tDisplay all values currently available.\n" \
--      "\t-A\tDisplay all values currently available in table form."
-+      "\t-n\tUse this option to disable printing of the key name when printing values\n" \
-+      "\t-w\tUse this option when you want to change a sysctl setting\n" \
-+      "\t-p\tLoad in sysctl settings from the file specified or /etc/sysctl.conf if none given\n" \
-+      "\t-a\tDisplay all values currently available\n" \
-+      "\t-A\tDisplay all values currently available in table form"
- #define sysctl_example_usage
-       "sysctl [-n] variable ...\n" \
-       "sysctl [-n] -w variable=value ...\n" \
-@@ -2345,9 +2551,9 @@
- #ifndef CONFIG_FEATURE_FANCY_TAIL
--  #define USAGE_UNSIMPLE_TAIL(a)
-+#  define USAGE_UNSIMPLE_TAIL(a)
- #else
--  #define USAGE_UNSIMPLE_TAIL(a) a
-+#  define USAGE_UNSIMPLE_TAIL(a) a
- #endif
- #define tail_trivial_usage \
-       "[OPTION]... [FILE]..."
-@@ -2370,29 +2576,29 @@
-       "nameserver 10.0.0.1\n"
- #ifdef CONFIG_FEATURE_TAR_CREATE
--  #define USAGE_TAR_CREATE(a) a
-+#  define USAGE_TAR_CREATE(a) a
- #else
--  #define USAGE_TAR_CREATE(a)
-+#  define USAGE_TAR_CREATE(a)
- #endif
- #ifdef CONFIG_FEATURE_TAR_EXCLUDE
--  #define USAGE_TAR_EXCLUDE(a) a
-+#  define USAGE_TAR_EXCLUDE(a) a
- #else
--  #define USAGE_TAR_EXCLUDE(a)
-+#  define USAGE_TAR_EXCLUDE(a)
- #endif
- #ifdef CONFIG_FEATURE_TAR_GZIP
--  #define USAGE_TAR_GZIP(a) a
-+#  define USAGE_TAR_GZIP(a) a
- #else
--  #define USAGE_TAR_GZIP(a)
-+#  define USAGE_TAR_GZIP(a)
- #endif
- #ifdef CONFIG_FEATURE_TAR_BZIP2
--  #define USAGE_TAR_BZIP2(a) a
-+#  define USAGE_TAR_BZIP2(a) a
- #else
--  #define USAGE_TAR_BZIP2(a)
-+#  define USAGE_TAR_BZIP2(a)
- #endif
- #ifdef CONFIG_FEATURE_TAR_COMPRESS
--  #define USAGE_TAR_COMPRESS(a) a
-+#  define USAGE_TAR_COMPRESS(a) a
- #else
--  #define USAGE_TAR_COMPRESS(a)
-+#  define USAGE_TAR_COMPRESS(a)
- #endif
- #define tar_trivial_usage \
-@@ -2430,7 +2636,7 @@
-       "\t-a\tappend to the given FILEs, do not overwrite\n" \
-       "\t-i\tignore interrupt signals (SIGINT)"
- #define tee_example_usage \
--      "$ echo "Hello" | tee /tmp/foo\n" \
-+      "$ echo \"Hello\" | tee /tmp/foo\n" \
-       "$ cat /tmp/foo\n" \
-       "Hello\n"
-@@ -2441,17 +2647,17 @@
-       "Telnet is used to establish interactive communication with another\n" \
-       "computer over a network using the TELNET protocol.\n\n" \
-       "Options:\n" \
--      "\t-a\t\tAttempt an automatic login with the USER variable.\n" \
--      "\t-l USER\t\tAttempt an automatic login with the USER argument.\n" \
-+      "\t-a\t\tAttempt an automatic login with the USER variable\n" \
-+      "\t-l USER\t\tAttempt an automatic login with the USER argument\n" \
-       "\tHOST\t\tThe official name, alias or the IP address of the\n" \
-       "\t\t\tremote host.\n" \
--      "\tPORT\t\tThe remote port number to connect to. If it is not\n" \
-+      "\tPORT\t\tThe remote port number to connect to.  If it is not\n" \
-       "\t\t\tspecified, the default telnet (23) port is used."
- #else
- #define telnet_trivial_usage \
-       "HOST [PORT]"
- #define telnet_full_usage \
--      "Telnet is used to establish interactive communication with another\n"\
-+      "Telnet is used to establish interactive communication with another\n" \
-       "computer over a network using the TELNET protocol."
- #endif
-@@ -2459,19 +2665,19 @@
- #define telnetd_trivial_usage \
-       "(inetd mode) [OPTION]"
- #define telnetd_full_usage \
--      "Telnetd uses incoming TELNET connections via inetd.\n"\
-+      "Telnetd uses incoming TELNET connections via inetd.\n" \
-       "Options:\n" \
-       "\t-l LOGIN\texec LOGIN on connect (default /bin/sh)\n" \
--      "\t-f issue_file\tDisplay issue_file instead of /etc/issue."
-+      "\t-f issue_file\tDisplay issue_file instead of /etc/issue"
- #else
- #define telnetd_trivial_usage \
-       "[OPTION]"
- #define telnetd_full_usage \
--      "Telnetd listens for incoming TELNET connections on PORT.\n"\
-+      "Telnetd listens for incoming TELNET connections on PORT.\n" \
-       "Options:\n" \
--      "\t-p PORT\tlisten for connections on PORT (default 23)\n"\
--      "\t-l LOGIN\texec LOGIN on connect (default /bin/sh)\n"\
--      "\t-f issue_file\tDisplay issue_file instead of /etc/issue."
-+      "\t-p PORT\tlisten for connections on PORT (default 23)\n" \
-+      "\t-l LOGIN\texec LOGIN on connect (default /bin/sh)\n" \
-+      "\t-f issue_file\tDisplay issue_file instead of /etc/issue"
- #endif
- #define test_trivial_usage \
-@@ -2494,19 +2700,19 @@
-       "1\n"
- #ifdef CONFIG_FEATURE_TFTP_GET
--  #define USAGE_TFTP_GET(a) a
-+#  define USAGE_TFTP_GET(a) a
- #else
--  #define USAGE_TFTP_GET(a)
-+#  define USAGE_TFTP_GET(a)
- #endif
- #ifdef CONFIG_FEATURE_TFTP_PUT
--  #define USAGE_TFTP_PUT(a) a
-+#  define USAGE_TFTP_PUT(a) a
- #else
--  #define USAGE_TFTP_PUT(a)
-+#  define USAGE_TFTP_PUT(a)
- #endif
- #ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
--  #define USAGE_TFTP_BS(a) a
-+#  define USAGE_TFTP_BS(a) a
- #else
--  #define USAGE_TFTP_BS(a)
-+#  define USAGE_TFTP_BS(a)
- #endif
- #define tftp_trivial_usage \
-@@ -2514,16 +2720,16 @@
- #define tftp_full_usage \
-       "Transfers a file from/to a tftp server using \"octet\" mode.\n\n" \
-       "Options:\n" \
--      "\t-l FILE\tLocal FILE.\n" \
--      "\t-r FILE\tRemote FILE." \
--        USAGE_TFTP_GET(       \
--        "\n\t-g\tGet file." \
--        ) \
--        USAGE_TFTP_PUT(       \
--      "\n\t-p\tPut file." \
-+      "\t-l FILE\tLocal FILE\n" \
-+      "\t-r FILE\tRemote FILE" \
-+      USAGE_TFTP_GET( \
-+      "\n\t-g\tGet file" \
-+      ) \
-+      USAGE_TFTP_PUT( \
-+      "\n\t-p\tPut file" \
-       ) \
-       USAGE_TFTP_BS( \
--      "\n\t-b SIZE\tTransfer blocks of SIZE octets." \
-+      "\n\t-b SIZE\tTransfer blocks of SIZE octets" \
-       )
- #define time_trivial_usage \
-       "[OPTION]... COMMAND [ARGS...]"
-@@ -2531,7 +2737,7 @@
-       "Runs the program COMMAND with arguments ARGS.  When COMMAND finishes,\n" \
-       "COMMAND's resource usage information is displayed\n\n" \
-       "Options:\n" \
--      "\t-v\tDisplays verbose resource usage information."
-+      "\t-v\tDisplays verbose resource usage information"
- #define top_trivial_usage \
-       "[-d <seconds>]"
-@@ -2565,11 +2771,11 @@
-       "\t-d\tdelete input characters coded STRING1\n" \
-       "\t-s\tsqueeze multiple output characters of STRING2 into one character"
- #define tr_example_usage \
--      "$ echo "gdkkn vnqkc" | tr [a-y] [b-z]\n" \
-+      "$ echo \"gdkkn vnqkc\" | tr [a-y] [b-z]\n" \
-       "hello world\n"
- #define traceroute_trivial_usage \
--      "[-dnrv] [-m max_ttl] [-p port#] [-q nqueries]\n"\
-+      "[-dnrv] [-m max_ttl] [-p port#] [-q nqueries]\n" \
-       "\t[-s src_addr] [-t tos] [-w wait] host [data size]"
- #define traceroute_full_usage \
-       "trace the route ip packets follow going to \"host\"\n" \
-@@ -2587,7 +2793,7 @@
-       "\t-t tos\tSet the type-of-service in probe packets to the following value\n" \
-       "\t\t(default 0)\n" \
-       "\t-w wait\tSet the time (in seconds) to wait for a response to a probe\n" \
--      "\t\t(default 3 sec.)."
-+      "\t\t(default 3 sec.)"
- #define true_trivial_usage \
-@@ -2602,7 +2808,7 @@
- #define tty_trivial_usage \
-       ""
- #define tty_full_usage \
--      "Print the file name of the terminal connected to standard input.\n\n"\
-+      "Print the file name of the terminal connected to standard input.\n\n" \
-       "Options:\n" \
-       "\t-s\tprint nothing, only return an exit status"
- #define tty_example_usage \
-@@ -2616,9 +2822,9 @@
-       "\t-H,\t--hostname=HOSTNAME\tClient hostname\n" \
-       "\t-h,\t                   \tAlias for -H\n" \
-       "\t-f,\t--foreground\tDo not fork after getting lease\n" \
--      "\t-b,\t--background\tFork to background if lease cannot be immediately negotiated.\n" \
-+      "\t-b,\t--background\tFork to background if lease cannot be immediately negotiated\n" \
-       "\t-i,\t--interface=INTERFACE\tInterface to use (default: eth0)\n" \
--      "\t-n,\t--now\tExit with failure if lease cannot be immediately negotiated.\n" \
-+      "\t-n,\t--now\tExit with failure if lease cannot be immediately negotiated\n" \
-       "\t-p,\t--pidfile=file\tStore process ID of daemon in file\n" \
-       "\t-q,\t--quit\tQuit after obtaining lease\n" \
-       "\t-r,\t--request=IP\tIP address to request (default: none)\n" \
-@@ -2632,9 +2838,9 @@
-       ""
- #ifdef CONFIG_FEATURE_MOUNT_FORCE
--  #define USAGE_MOUNT_FORCE(a) a
-+#  define USAGE_MOUNT_FORCE(a) a
- #else
--  #define USAGE_MOUNT_FORCE(a)
-+#  define USAGE_MOUNT_FORCE(a)
- #endif
- #define umount_trivial_usage \
-       "[flags] FILESYSTEM|DIRECTORY"
-@@ -2769,7 +2975,7 @@
- #define vi_full_usage \
-       "edit FILE.\n\n" \
-       "Options:\n" \
--      "\t-R\tRead-only- do not write to the file."
-+      "\t-R\tRead-only- do not write to the file"
- #define vlock_trivial_usage \
-       "[OPTIONS]"
-@@ -2783,7 +2989,7 @@
- #define watch_full_usage \
-       "Executes a program periodically.\n" \
-       "Options:\n" \
--      "\t-n\tLoop period in seconds - default is 2."
-+      "\t-n\tLoop period in seconds - default is 2"
- #define watch_example_usage \
-       "$ watch date\n" \
-       "Mon Dec 17 10:31:40 GMT 2000\n" \
-@@ -2795,7 +3001,7 @@
- #define watchdog_full_usage \
-       "Periodically write to watchdog device DEV.\n" \
-       "Options:\n" \
--      "\t-t\tTimer period in seconds - default is 30."
-+      "\t-t\tTimer period in seconds - default is 30"
- #define wc_trivial_usage \
-       "[OPTION]... [FILE]..."
-@@ -2832,9 +3038,9 @@
-       "/bin/login\n"
- #define who_trivial_usage \
--        " "
-+      " "
- #define who_full_usage \
--        "Prints the current user names and related information"
-+      "Prints the current user names and related information"
- #define whoami_trivial_usage \
-       ""
-@@ -2867,7 +3073,7 @@
-       "\t-r\tDo not run command for empty readed lines\n" \
-       USAGE_XARGS_TERMOPT("\t-x\tExit if the size is exceeded\n") \
-       USAGE_XARGS_ZERO_TERM("\t-0\tInput filenames are terminated by a null character\n") \
--      "\t-t\tPrint the command line on stderr before executing it."
-+      "\t-t\tPrint the command line on stderr before executing it"
- #define xargs_example_usage \
-       "$ ls | xargs gzip\n" \
-       "$ find . -name '*.c' -print | xargs rm\n"
-@@ -2882,4 +3088,14 @@
- #define zcat_full_usage \
-       "Uncompress to stdout."
-+#define zcip_trivial_usage \
-+      "[OPTIONS] ifname script"
-+#define zcip_full_usage \
-+      "zcip manages a ZeroConf IPv4 link-local address.\n" \
-+      "Options:\n" \
-+      "\t-f              foreground mode\n" \
-+      "\t-q              quit after address (no daemon)\n" \
-+      "\t-r 169.254.x.x  request this address first\n" \
-+      "\t-v              verbose; show version\n"
-+
- #endif /* __BB_USAGE_H__ */
-diff -Nur busybox-1.00/init/init.c busybox/init/init.c
---- busybox-1.00/init/init.c   2004-10-08 10:21:54.000000000 +0200
-+++ busybox/init/init.c        2005-06-04 08:20:20.000000000 +0200
-@@ -453,6 +453,7 @@
-               signal(SIGINT, SIG_DFL);
-               signal(SIGTERM, SIG_DFL);
-               signal(SIGHUP, SIG_DFL);
-+              signal(SIGQUIT, SIG_DFL);
-               signal(SIGCONT, SIG_DFL);
-               signal(SIGSTOP, SIG_DFL);
-               signal(SIGTSTP, SIG_DFL);
-@@ -693,6 +694,7 @@
-       /* first disable all our signals */
-       sigemptyset(&block_signals);
-       sigaddset(&block_signals, SIGHUP);
-+      sigaddset(&block_signals, SIGQUIT);
-       sigaddset(&block_signals, SIGCHLD);
-       sigaddset(&block_signals, SIGUSR1);
-       sigaddset(&block_signals, SIGUSR2);
-@@ -737,6 +739,7 @@
-                       /* unblock all signals, blocked in shutdown_system() */
-                       sigemptyset(&unblock_signals);
-                       sigaddset(&unblock_signals, SIGHUP);
-+                      sigaddset(&unblock_signals, SIGQUIT);
-                       sigaddset(&unblock_signals, SIGCHLD);
-                       sigaddset(&unblock_signals, SIGUSR1);
-                       sigaddset(&unblock_signals, SIGUSR2);
-@@ -1097,6 +1100,7 @@
-       /* Set up sig handlers  -- be sure to
-        * clear all of these in run() */
-       signal(SIGHUP, exec_signal);
-+      signal(SIGQUIT, exec_signal);
-       signal(SIGUSR1, halt_signal);
-       signal(SIGUSR2, halt_signal);
-       signal(SIGINT, ctrlaltdel_signal);
-diff -Nur busybox-1.00/libbb/Makefile.in busybox/libbb/Makefile.in
---- busybox-1.00/libbb/Makefile.in     2004-10-08 09:45:31.000000000 +0200
-+++ busybox/libbb/Makefile.in  2005-06-04 08:20:15.000000000 +0200
-@@ -53,7 +53,7 @@
- LIBBB_MSRC0:=$(srcdir)/messages.c
- LIBBB_MOBJ0:=full_version.o \
-       memory_exhausted.o invalid_date.o io_error.o \
--      write_error.o name_longer_than_foo.o unknown.o \
-+      read_error.o write_error.o name_longer_than_foo.o unknown.o \
-       can_not_create_raw_socket.o perm_denied_are_you_root.o \
-       shadow_file.o passwd_file.o group_file.o gshadow_file.o nologin_file.o \
-       securetty_file.o motd_file.o \
-diff -Nur busybox-1.00/libbb/concat_path_file.c busybox/libbb/concat_path_file.c
---- busybox-1.00/libbb/concat_path_file.c      2004-03-15 09:28:41.000000000 +0100
-+++ busybox/libbb/concat_path_file.c   2005-06-04 08:20:15.000000000 +0200
-@@ -34,11 +34,11 @@
-       char *lc;
-       if (!path)
--          path="";
-+              path = "";
-       lc = last_char_is(path, '/');
-       while (*filename == '/')
-               filename++;
--      bb_xasprintf(&outbuf, "%s%s%s", path, (lc==NULL)? "/" : "", filename);
-+      bb_xasprintf(&outbuf, "%s%s%s", path, (lc==NULL ? "/" : ""), filename);
-       return outbuf;
- }
-diff -Nur busybox-1.00/libbb/copy_file.c busybox/libbb/copy_file.c
---- busybox-1.00/libbb/copy_file.c     2004-04-19 14:28:02.000000000 +0200
-+++ busybox/libbb/copy_file.c  2005-06-04 08:20:15.000000000 +0200
-@@ -54,10 +54,11 @@
-               }
-       } else {
-               if (source_stat.st_dev == dest_stat.st_dev &&
--                      source_stat.st_ino == dest_stat.st_ino) {
--              bb_error_msg("`%s' and `%s' are the same file", source, dest);
--              return -1;
--      }
-+                      source_stat.st_ino == dest_stat.st_ino)
-+              {
-+                      bb_error_msg("`%s' and `%s' are the same file", source, dest);
-+                      return -1;
-+              }
-               dest_exists = 1;
-       }
-diff -Nur busybox-1.00/libbb/copyfd.c busybox/libbb/copyfd.c
---- busybox-1.00/libbb/copyfd.c        2004-03-15 09:28:41.000000000 +0100
-+++ busybox/libbb/copyfd.c     2005-06-04 08:20:15.000000000 +0200
-@@ -2,7 +2,7 @@
- /*
-  * Utility routines.
-  *
-- * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
-+ * Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -25,6 +25,7 @@
- #include <unistd.h>
- #include "busybox.h"
-+#include "libbb.h"
- #if BUFSIZ < 4096
-@@ -33,46 +34,59 @@
- #endif
--/* If size is 0 copy until EOF */
--static size_t bb_full_fd_action(int src_fd, int dst_fd, const size_t size)
-+static size_t bb_full_fd_action(int src_fd, int dst_fd, const size_t size2)
- {
--      size_t read_total = 0;
--      RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);
-+      int status;
-+      size_t xread, wrote, total, size = size2;
--      while ((size == 0) || (read_total < size)) {
--              size_t read_try;
--              ssize_t read_actual;
--
--              if ((size == 0) || (size - read_total > BUFSIZ)) {
--                      read_try = BUFSIZ;
--              } else {
--                      read_try = size - read_total;
--              }
-+      if (src_fd < 0) {
-+              return -1;
-+      }
--              read_actual = safe_read(src_fd, buffer, read_try);
--              if (read_actual > 0) {
--                      if ((dst_fd >= 0) && (bb_full_write(dst_fd, buffer, (size_t) read_actual) != read_actual)) {
--                              bb_perror_msg(bb_msg_write_error);      /* match Read error below */
-+      if (size == 0) {
-+              /* If size is 0 copy until EOF */
-+              size = ULONG_MAX;
-+      }
-+
-+      {
-+              RESERVE_CONFIG_BUFFER(buffer,BUFSIZ);
-+              total = 0;
-+              wrote = 0;
-+              status = -1;
-+              while (total < size)
-+              {
-+                      xread = BUFSIZ;
-+                      if (size < (total + BUFSIZ))
-+                              xread = size - total;
-+                      xread = bb_full_read(src_fd, buffer, xread);
-+                      if (xread > 0) {
-+                              if (dst_fd < 0) {
-+                                      /* A -1 dst_fd means we need to fake it... */
-+                                      wrote = xread;
-+                              } else {
-+                                      wrote = bb_full_write(dst_fd, buffer, xread);
-+                              }
-+                              if (wrote < xread) {
-+                                      bb_perror_msg(bb_msg_write_error);
-+                                      break;
-+                              }
-+                              total += wrote;
-+                      } else if (xread < 0) {
-+                              bb_perror_msg(bb_msg_read_error);
-+                              break;
-+                      } else if (xread == 0) {
-+                              /* All done. */
-+                              status = 0;
-                               break;
-                       }
-               }
--              else if (read_actual == 0) {
--                      if (size) {
--                              bb_error_msg("Unable to read all data");
--                      }
--                      break;
--              } else {
--                      /* read_actual < 0 */
--                      bb_perror_msg("Read error");
--                      break;
--              }
--
--              read_total += read_actual;
-+              RELEASE_CONFIG_BUFFER(buffer);
-       }
--      RELEASE_CONFIG_BUFFER(buffer);
--
--      return(read_total);
-+      if (status == 0 || total)
-+              return total;
-+      /* Some sortof error occured */
-+      return -1;
- }
-diff -Nur busybox-1.00/libbb/find_pid_by_name.c busybox/libbb/find_pid_by_name.c
---- busybox-1.00/libbb/find_pid_by_name.c      2004-03-15 09:28:42.000000000 +0100
-+++ busybox/libbb/find_pid_by_name.c   2005-06-04 08:20:15.000000000 +0200
-@@ -45,11 +45,8 @@
-       procps_status_t * p;
-       pidList = xmalloc(sizeof(long));
--#ifdef CONFIG_SELINUX
--      while ((p = procps_scan(0, 0, NULL)) != 0) {
--#else
--      while ((p = procps_scan(0)) != 0) {
--#endif
-+      while ((p = procps_scan(0)) != 0) 
-+      {
-               if (strncmp(p->short_cmd, pidName, COMM_LEN-1) == 0) {
-                       pidList=xrealloc( pidList, sizeof(long) * (i+2));
-                       pidList[i++]=p->pid;
-diff -Nur busybox-1.00/libbb/get_line_from_file.c busybox/libbb/get_line_from_file.c
---- busybox-1.00/libbb/get_line_from_file.c    2004-03-15 09:28:42.000000000 +0100
-+++ busybox/libbb/get_line_from_file.c 2005-06-04 08:20:15.000000000 +0200
-@@ -44,7 +44,8 @@
-                       linebuf = xrealloc(linebuf, linebufsz += GROWBY);
-               }
-               linebuf[idx++] = (char)ch;
--              if (ch == '\n' || ch == '\0') {
-+              if (!ch) return linebuf;
-+              if (c<2 && ch == '\n') {
-                       if (c) {
-                               --idx;
-                       }
-@@ -71,6 +72,11 @@
-       return private_get_line_from_file(file, 1);
- }
-+extern char *bb_get_chunk_from_file(FILE *file)
-+{
-+      return private_get_line_from_file(file, 2);
-+}
-+
- /* END CODE */
- /*
-diff -Nur busybox-1.00/libbb/getopt_ulflags.c busybox/libbb/getopt_ulflags.c
---- busybox-1.00/libbb/getopt_ulflags.c        2004-02-05 14:49:29.000000000 +0100
-+++ busybox/libbb/getopt_ulflags.c     2005-06-04 08:20:15.000000000 +0200
-@@ -26,146 +26,270 @@
- #include <stdlib.h>
- #include "libbb.h"
--/*
--You can set bb_opt_complementaly as string with one or more
--complementaly or incongruously options.
--If sequential founded option haved from this string
--then your incongruously pairs unsets and complementaly make add sets.
--Format:
--one char - option for check,
--chars - complementaly option for add sets.
--- chars - option triggered for unsets.
--~ chars - option incongruously.
--*       - option list, called add_to_list(*ptr_from_usaged, optarg)
--:       - separator.
--Example: du applet can have options "-s" and "-d size"
--If getopt found -s then -d option flag unset or if found -d then -s unset.
--For this result you must set bb_opt_complementaly = "s-d:d-s".
--Result have last option flag only from called arguments.
--Warning! You can check returned flag, pointer to "d:" argument seted
--to own optarg always.
--Example two: cut applet must only one type of list may be specified,
--and -b, -c and -f incongruously option, overwited option is error also.
--You must set bb_opt_complementaly = "b~cf:c~bf:f~bc".
--If called have more one specified, return value have error flag -
--high bite set (0x80000000UL).
--Example three: grep applet can have one or more "-e pattern" arguments.
--You should use bb_getopt_ulflags() as
--llist_t *paterns;
--bb_opt_complementaly = "e*";
--bb_getopt_ulflags (argc, argv, "e:", &paterns);
-+/*                  Documentation !
-+
-+unsigned long
-+bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...)
-+
-+          The command line options must be declared in const char
-+          *applet_opts as a string of chars, for example:
-+
-+          flags = bb_getopt_ulflags(argc, argv, "rnug");
-+
-+          If one of the given options is found, a flag value is added to
-+          the return value (an unsigned long).
-+
-+          The flag value is determined by the position of the char in
-+          applet_opts string.  For example, in the above case:
-+
-+          flags = bb_getopt_ulflags(argc, argv, "rnug");
-+
-+          "r" will add 1    (bit 1 : 0x01)
-+          "n" will add 2    (bit 2 : 0x02)
-+          "u  will add 4    (bit 3 : 0x03)
-+          "g" will add 8    (bit 4 : 0x04)
-+
-+           and so on.  You can also look at the return value as a bit 
-+           field and each option sets one of bits.
-+
-+   ":"     If one of the options requires an argument, then add a ":"
-+           after the char in applet_opts and provide a pointer to store
-+           the argument.  For example:
-+
-+           char *pointer_to_arg_for_a;
-+           char *pointer_to_arg_for_b;
-+           char *pointer_to_arg_for_c;
-+           char *pointer_to_arg_for_d;
-+
-+           flags = bb_getopt_ulflags(argc, argv, "a:b:c:d:",
-+                            &pointer_to_arg_for_a, &pointer_to_arg_for_b,
-+                            &pointer_to_arg_for_c, &pointer_to_arg_for_d);
-+
-+           The type of the pointer (char* or llist_t *) may be controlled
-+           by the "*" special character that is set in the external string
-+           bb_opt_complementaly (see below for more info).
-+
-+static const struct option bb_default_long_options[]
-+
-+           This struct allows you to define long options.  The syntax for
-+           declaring the array is just like that of getopt's longopts.
-+
-+           static const struct option applet_long_options[] = {
-+                   { "verbose", 0, 0, "v" },
-+                   { 0, 0, 0, 0 }
-+           };
-+           bb_applet_long_options = applet_long_options;
-+
-+           The first parameter is the long option name that you would pass
-+           to the applet (without the dashes).
-+
-+           The second field determines whether the option has an argument.
-+           You can set this to 0, 1, or 2, or you can use the long named
-+           defines of no_argument, required_argument, and optional_argument.
-+
-+           The third argument is used only when the long option does not 
-+           have a corresponding short option.  In that case, it should be 
-+           an integer pointer.  Otherwise (and normally), it should just
-+           bet set to NULL.
-+
-+           The last argument is the corresponding short option (if there
-+           is one of course).
-+
-+           Note: a good applet will make long options configurable via the
-+           config process and not a required feature.  The current standard
-+           is to name the config option CONFIG_FEATURE_<applet>_LONG_OPTIONS.
-+
-+const char *bb_opt_complementaly
-+
-+   ":"     The colon (":") is used to separate groups of two or more chars
-+           and/or groups of chars and special characters (stating some
-+           conditions to be checked).
-+
-+   "abc"   If groups of two or more chars are specified, the first char
-+           is the main option and the other chars are secondary options.
-+           Their flags will be turned on if the main option is found even
-+           if they are not specifed on the command line.  For example:
-+
-+           bb_opt_complementaly = "abc";
-+
-+           flags = bb_getopt_ulflags(argc, argv, "abcd")
-+
-+           If getopt() finds "-a" on the command line, then
-+           bb_getopt_ulflags's return value will be as if "-a -b -c" were
-+           found.
-+
-+Special characters:
-+
-+   "-"     A dash between two options causes the second of the two
-+           to be unset (and ignored) if it is given on the command line.
-+
-+           For example:
-+           The du applet has the options "-s" and "-d depth".  If
-+           bb_getopt_ulflags finds -s, then -d is unset or if it finds -d
-+           then -s is unset.  (Note:  busybox implements the GNU
-+           "--max-depth" option as "-d".)  To obtain this behavior, you 
-+           set bb_opt_complementaly = "s-d:d-s".  Only one flag value is 
-+           added to bb_getopt_ulflags's return value depending on the 
-+           position of the options on the command line.  If one of the 
-+           two options requires an argument pointer (":" in applet_opts 
-+           as in "d:") optarg is set accordingly.
-+
-+           char *smax_print_depth;
-+
-+           bb_opt_complementaly = "s-d:d-s";
-+           opt = bb_getopt_ulflags(argc, argv, "sd:", &smax_print_depth);
-+
-+           if (opt & 2) {
-+                    max_print_depth = bb_xgetularg10_bnd(smax_print_depth,
-+                                0, INT_MAX);
-+           }
-+
-+   "~"     A tilde between two options, or between an option and a group
-+           of options, means that they are mutually exclusive.  Unlike
-+           the "-" case above, an error will be forced if the options
-+           are used together.
-+
-+           For example:
-+           The cut applet must have only one type of list specified, so
-+           -b, -c and -f are mutally exclusive and should raise an error
-+           if specified together.  In this case you must set
-+           bb_opt_complementaly = "b~cf:c~bf:f~bc".  If two of the
-+           mutually exclusive options are found, bb_getopt_ulflags's
-+           return value will have the error flag set (BB_GETOPT_ERROR) so
-+           that we can check for it:
-+
-+           if (flags & BB_GETOPT_ERROR)
-+                   bb_show_usage();
-+
-+   "*"     A star after a char in bb_opt_complementaly means that the
-+           option can occur multiple times:
-+
-+           For example:
-+           The grep applet can have one or more "-e pattern" arguments.
-+           In this case you should use bb_getopt_ulflags() as follows:
-+
-+           llist_t *patterns = NULL;
-+
-+           (this pointer must be initializated to NULL if the list is empty
-+           as required by *llist_add_to(llist_t *old_head, char *new_item).)
-+
-+           bb_opt_complementaly = "e*";
-+
-+           bb_getopt_ulflags(argc, argv, "e:", &patterns);
-+           $ grep -e user -e root /etc/passwd
-+           root:x:0:0:root:/root:/bin/bash
-+           user:x:500:500::/home/user:/bin/bash
-+
- */
- const char *bb_opt_complementaly;
--typedef struct
--{
-+typedef struct {
-       unsigned char opt;
-       char list_flg;
-       unsigned long switch_on;
-       unsigned long switch_off;
-       unsigned long incongruously;
--      void **optarg;              /* char **optarg or llist_t **optarg */
-+      void **optarg;               /* char **optarg or llist_t **optarg */
- } t_complementaly;
- /* You can set bb_applet_long_options for parse called long options */
- static const struct option bb_default_long_options[] = {
--     /*   { "help", 0, NULL, '?' }, */
-+/*    { "help", 0, NULL, '?' }, */
-       { 0, 0, 0, 0 }
- };
- const struct option *bb_applet_long_options = bb_default_long_options;
--
- unsigned long
- bb_getopt_ulflags (int argc, char **argv, const char *applet_opts, ...)
- {
--  unsigned long flags = 0;
--  t_complementaly complementaly[sizeof(flags) * 8 + 1];
--  int c;
--  const unsigned char *s;
--  t_complementaly *on_off;
--  va_list p;
--
--  va_start (p, applet_opts);
--
--  /* skip GNU extension */
--  s = applet_opts;
--  if(*s == '+' || *s == '-')
--      s++;
--
--  c = 0;
--  on_off = complementaly;
--  for (; *s; s++) {
--      if(c >= (sizeof(flags)*8))
--              break;
--      on_off->opt = *s;
--      on_off->switch_on = (1 << c);
--      on_off->list_flg = 0;
--      on_off->switch_off = 0;
--      on_off->incongruously = 0;
--      on_off->optarg = NULL;
--      if (s[1] == ':') {
--        on_off->optarg = va_arg (p, void **);
--        do
-+      unsigned long flags = 0;
-+      t_complementaly complementaly[sizeof(flags) * 8 + 1];
-+      int c;
-+      const unsigned char *s;
-+      t_complementaly *on_off;
-+      va_list p;
-+
-+      va_start (p, applet_opts);
-+
-+      /* skip GNU extension */
-+      s = applet_opts;
-+      if(*s == '+' || *s == '-')
-               s++;
--        while (s[1] == ':');
-+
-+      c = 0;
-+      on_off = complementaly;
-+      for (; *s; s++) {
-+              if(c >= (sizeof(flags)*8))
-+                      break;
-+              on_off->opt = *s;
-+              on_off->switch_on = (1 << c);
-+              on_off->list_flg = 0;
-+              on_off->switch_off = 0;
-+              on_off->incongruously = 0;
-+              on_off->optarg = NULL;
-+              if (s[1] == ':') {
-+                      on_off->optarg = va_arg (p, void **);
-+                      do
-+                              s++;
-+                      while (s[1] == ':');
-+              }
-+              on_off++;
-+              c++;
-       }
--      on_off++;
--      c++;
--  }
--  on_off->opt = 0;
--  c = 0;
--  for (s = bb_opt_complementaly; s && *s; s++) {
--    t_complementaly *pair;
--
--    if (*s == ':') {
--        c = 0;
--        continue;
--    }
--    if (c)
--        continue;
--    for (on_off = complementaly; on_off->opt; on_off++)
--        if (on_off->opt == *s)
--          break;
--    pair = on_off;
--    for(s++; *s && *s != ':'; s++) {
--      if (*s == '-' || *s == '~') {
--        c = *s;
--      } else if(*s == '*') {
--      pair->list_flg++;
--      } else {
--        unsigned long *pair_switch = &(pair->switch_on);
--
--        if(c)
--          pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously);
--        for (on_off = complementaly; on_off->opt; on_off++)
--          if (on_off->opt == *s) {
--                *pair_switch |= on_off->switch_on;
--                break;
--          }
--      }
--    }
--    s--;
--  }
--
--  while ((c = getopt_long (argc, argv, applet_opts,
--                          bb_applet_long_options, NULL)) > 0) {
--      for (on_off = complementaly; on_off->opt != c; on_off++) {
--          if(!on_off->opt)
--                      bb_show_usage ();
-+      on_off->opt = 0;
-+      c = 0;
-+      for (s = bb_opt_complementaly; s && *s; s++) {
-+              t_complementaly *pair;
-+
-+              if (*s == ':') {
-+                      c = 0;
-+                      continue;
-+              }
-+              if (c)
-+                      continue;
-+              for (on_off = complementaly; on_off->opt; on_off++)
-+                      if (on_off->opt == *s)
-+                              break;
-+              pair = on_off;
-+              for(s++; *s && *s != ':'; s++) {
-+                      if (*s == '-' || *s == '~') {
-+                              c = *s;
-+                      } else if(*s == '*') {
-+                              pair->list_flg++;
-+                      } else {
-+                              unsigned long *pair_switch = &(pair->switch_on);
-+                              if(c)
-+                                      pair_switch = c == '-' ? &(pair->switch_off) : &(pair->incongruously);
-+                              for (on_off = complementaly; on_off->opt; on_off++)
-+                                      if (on_off->opt == *s) {
-+                                              *pair_switch |= on_off->switch_on;
-+                                              break;
-+                                      }
-+                      }
-+              }
-+              s--;
-       }
--      if(flags & on_off->incongruously)
--          flags |= 0x80000000UL;
--      flags &= ~on_off->switch_off;
--      flags |= on_off->switch_on;
--      if(on_off->list_flg) {
--         *(llist_t **)(on_off->optarg) =
--              llist_add_to(*(llist_t **)(on_off->optarg), optarg);
--      } else if (on_off->optarg) {
--          *(char **)(on_off->optarg) = optarg;
-+
-+      while ((c = getopt_long (argc, argv, applet_opts,
-+                               bb_applet_long_options, NULL)) > 0) {
-+              for (on_off = complementaly; on_off->opt != c; on_off++) {
-+                      if(!on_off->opt)
-+                              bb_show_usage ();
-+              }
-+              if(flags & on_off->incongruously)
-+                      flags |= BB_GETOPT_ERROR;
-+              flags &= ~on_off->switch_off;
-+              flags |= on_off->switch_on;
-+              if(on_off->list_flg) {
-+                      *(llist_t **)(on_off->optarg) =
-+                              llist_add_to(*(llist_t **)(on_off->optarg), optarg);
-+              } else if (on_off->optarg) {
-+                      *(char **)(on_off->optarg) = optarg;
-+              }
-       }
--  }
--  return flags;
-+
-+      return flags;
- }
-diff -Nur busybox-1.00/libbb/hash_fd.c busybox/libbb/hash_fd.c
---- busybox-1.00/libbb/hash_fd.c       2004-03-15 09:28:42.000000000 +0100
-+++ busybox/libbb/hash_fd.c    2005-06-04 08:20:15.000000000 +0200
-@@ -197,7 +197,7 @@
- static uint32_t bits[4] = { 0x80000000, 0x00800000, 0x00008000, 0x00000080 };
- # endif /* __BYTE_ORDER */
--void sha1_end(unsigned char hval[], struct sha1_ctx_t *ctx)
-+static void sha1_end(unsigned char hval[], struct sha1_ctx_t *ctx)
- {
-       uint32_t i, cnt = (uint32_t) (ctx->count[0] & SHA1_MASK);
-diff -Nur busybox-1.00/libbb/inet_common.c busybox/libbb/inet_common.c
---- busybox-1.00/libbb/inet_common.c   2004-03-10 08:42:38.000000000 +0100
-+++ busybox/libbb/inet_common.c        2005-06-04 08:20:15.000000000 +0200
-@@ -4,7 +4,7 @@
-  *
-  * Heavily modified by Manuel Novoa III       Mar 12, 2001
-  *
-- * Version:     $Id$
-+ * Version:     $Id$
-  *
-  */
-diff -Nur busybox-1.00/libbb/interface.c busybox/libbb/interface.c
---- busybox-1.00/libbb/interface.c     2004-08-26 23:45:21.000000000 +0200
-+++ busybox/libbb/interface.c  2005-06-04 08:20:15.000000000 +0200
-@@ -15,7 +15,7 @@
-  *              that either displays or sets the characteristics of
-  *              one or more of the system's networking interfaces.
-  *
-- * Version:     $Id$
-+ * Version:     $Id$
-  *
-  * Author:      Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
-  *              and others.  Copyright 1993 MicroWalt Corporation
-@@ -888,6 +888,20 @@
-       return sfd;
- }
-+#ifdef CONFIG_FEATURE_CLEAN_UP
-+static void sockets_close(void)
-+{
-+      struct aftype **aft;
-+      for (aft = aftypes; *aft != NULL; aft++) {
-+              struct aftype *af = *aft;
-+              if( af->fd != -1 ) {
-+                      close(af->fd);
-+                      af->fd = -1;
-+              }
-+      }
-+}
-+#endif
-+
- /* like strcmp(), but knows about numbers */
- static int nstrcmp(const char *a, const char *b)
- {
-@@ -986,7 +1000,7 @@
-       return err;
- }
--char *get_name(char *name, char *p)
-+static char *get_name(char *name, char *p)
- {
-       /* Extract <name>[:<alias>] from nul-terminated p where p matches
-          <name>[:<alias>]: after leading whitespace.
-@@ -1223,17 +1237,13 @@
-       }
- #endif
-+#ifdef SIOCGIFMAP
-       strcpy(ifr.ifr_name, ifname);
--      if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
--              memset(&ife->map, 0, sizeof(struct ifmap));
-+      if (ioctl(skfd, SIOCGIFMAP, &ifr) == 0)
-+              ife->map = ifr.ifr_map;
-       else
--              memcpy(&ife->map, &ifr.ifr_map, sizeof(struct ifmap));
--
--      strcpy(ifr.ifr_name, ifname);
--      if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
-+#endif
-               memset(&ife->map, 0, sizeof(struct ifmap));
--      else
--              ife->map = ifr.ifr_map;
- #ifdef HAVE_TXQUEUELEN
-       strcpy(ifr.ifr_name, ifname);
-@@ -1374,7 +1384,7 @@
- #if HAVE_HWETHER
- #include <net/if_arp.h>
--#if __GLIBC__ >=2 && __GLIBC_MINOR >= 1
-+#if (__GLIBC__ >=2 && __GLIBC_MINOR >= 1) || defined(_NEWLIB_VERSION)
- #include <net/ethernet.h>
- #else
- #include <linux/if_ether.h>
-@@ -2078,6 +2088,8 @@
-       /* Do we have to show the current setup? */
-       status = if_print(ifname);
--      close(skfd);
-+#ifdef CONFIG_FEATURE_CLEAN_UP
-+      sockets_close();
-+#endif
-       exit(status < 0);
- }
-diff -Nur busybox-1.00/libbb/loop.c busybox/libbb/loop.c
---- busybox-1.00/libbb/loop.c  2004-08-16 10:36:28.000000000 +0200
-+++ busybox/libbb/loop.c       2005-06-04 08:20:15.000000000 +0200
-@@ -19,6 +19,10 @@
-  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-  */
-+#include <features.h>
-+#if defined (__GLIBC__) && !defined(__UCLIBC__)
-+#include <linux/posix_types.h>
-+#endif
- #include <stdio.h>
- #include <errno.h>
- #include <fcntl.h>
-@@ -30,7 +34,6 @@
- /* Grumble...  The 2.6.x kernel breaks asm/posix_types.h
-  * so we get to try and cope as best we can... */
- #include <linux/version.h>
--#include <asm/posix_types.h>
- #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
- #define __bb_kernel_dev_t   __kernel_old_dev_t
-diff -Nur busybox-1.00/libbb/messages.c busybox/libbb/messages.c
---- busybox-1.00/libbb/messages.c      2004-03-15 09:28:42.000000000 +0100
-+++ busybox/libbb/messages.c   2005-06-04 08:20:15.000000000 +0200
-@@ -36,6 +36,9 @@
- #ifdef L_write_error
-       const char * const bb_msg_write_error = "Write Error";
- #endif
-+#ifdef L_read_error
-+      const char * const bb_msg_read_error = "Read Error";
-+#endif
- #ifdef L_name_longer_than_foo
-       const char * const bb_msg_name_longer_than_foo = "Names longer than %d chars not supported.";
- #endif
-diff -Nur busybox-1.00/libbb/procps.c busybox/libbb/procps.c
---- busybox-1.00/libbb/procps.c        2004-08-27 00:18:58.000000000 +0200
-+++ busybox/libbb/procps.c     2005-06-04 08:20:15.000000000 +0200
-@@ -16,11 +16,7 @@
- #include "libbb.h"
--extern procps_status_t * procps_scan(int save_user_arg0
--#ifdef CONFIG_SELINUX
--      , int use_selinux , security_id_t *sid
--#endif
--      )
-+extern procps_status_t * procps_scan(int save_user_arg0)
- {
-       static DIR *dir;
-       struct dirent *entry;
-@@ -60,16 +56,9 @@
-               my_getpwuid(curstatus.user, sb.st_uid, sizeof(curstatus.user));
-               sprintf(status, "/proc/%d/stat", pid);
-+
-               if((fp = fopen(status, "r")) == NULL)
-                       continue;
--#ifdef CONFIG_SELINUX
--              if(use_selinux)
--              {
--                      if(fstat_secure(fileno(fp), &sb, sid))
--                              continue;
--              }
--              else
--#endif
-               name = fgets(buf, sizeof(buf), fp);
-               fclose(fp);
-               if(name == NULL)
-diff -Nur busybox-1.00/libbb/run_shell.c busybox/libbb/run_shell.c
---- busybox-1.00/libbb/run_shell.c     2004-03-15 09:28:43.000000000 +0100
-+++ busybox/libbb/run_shell.c  2005-06-04 08:20:15.000000000 +0200
-@@ -37,7 +37,33 @@
- #include <ctype.h>
- #include "libbb.h"
- #ifdef CONFIG_SELINUX
--#include <proc_secure.h>
-+#include <selinux/selinux.h>  /* for setexeccon  */
-+#endif
-+
-+#ifdef CONFIG_SELINUX
-+static security_context_t current_sid=NULL;
-+
-+void
-+renew_current_security_context(void)
-+{
-+  if  (current_sid)  
-+    freecon(current_sid);  /* Release old context  */
-+
-+  getcon(&current_sid);  /* update */
-+
-+  return;
-+}
-+void
-+set_current_security_context(security_context_t sid)
-+{
-+  if  (current_sid)  
-+    freecon(current_sid);  /* Release old context  */
-+
-+  current_sid=sid;
-+
-+  return;
-+}
-+
- #endif
- /* Run SHELL, or DEFAULT_SHELL if SHELL is empty.
-@@ -45,11 +71,7 @@
-    If ADDITIONAL_ARGS is nonzero, pass it to the shell as more
-    arguments.  */
--void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args
--#ifdef CONFIG_SELINUX
--      , security_id_t sid
--#endif
--)
-+void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args)
- {
-       const char **args;
-       int argno = 1;
-@@ -78,10 +100,11 @@
-       }
-       args [argno] = 0;
- #ifdef CONFIG_SELINUX
--      if(sid)
--              execve_secure(shell, (char **) args, environ, sid);
--      else
-+      if ( (current_sid) && (!setexeccon(current_sid)) ) {
-+          freecon(current_sid);
-+          execve(shell, (char **) args, environ);
-+      } else
- #endif
--      execv ( shell, (char **) args );
-+        execv ( shell, (char **) args );
-       bb_perror_msg_and_die ( "cannot run %s", shell );
- }
-diff -Nur busybox-1.00/libbb/syscalls.c busybox/libbb/syscalls.c
---- busybox-1.00/libbb/syscalls.c      2004-03-15 09:28:43.000000000 +0100
-+++ busybox/libbb/syscalls.c   2005-06-04 08:20:15.000000000 +0200
-@@ -29,7 +29,7 @@
- #include <sys/syscall.h>
- #include "libbb.h"
--int sysfs( int option, unsigned int fs_index, char * buf)
-+int sysfs(int option, unsigned int fs_index, char * buf)
- {
-       return(syscall(__NR_sysfs, option, fs_index, buf));
- }
-@@ -39,60 +39,59 @@
- #ifndef __NR_pivot_root
- #warning This kernel does not support the pivot_root syscall
- #warning -> The pivot_root system call is being stubbed out...
--    /* BusyBox was compiled against a kernel that did not support
--     *  the pivot_root system call.  To make this application work,
--     *  you will need to recompile with a kernel supporting the
--     *  pivot_root system call.
--     */
--    bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
--          "BusyBox with a kernel supporting the pivot_root system call.\n");
--    errno=ENOSYS;
--    return -1;
-+      /* BusyBox was compiled against a kernel that did not support
-+       *  the pivot_root system call.  To make this application work,
-+       *  you will need to recompile with a kernel supporting the
-+       *  pivot_root system call.
-+       */
-+      bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
-+                   "BusyBox with a kernel supporting the pivot_root system call.\n");
-+      errno = ENOSYS;
-+      return -1;
- #else
--    return(syscall(__NR_pivot_root, new_root, put_old));
--#endif
-+      return(syscall(__NR_pivot_root, new_root, put_old));
-+#endif /* __NR_pivot_root */
- }
--
--/* These syscalls are not included in ancient glibc versions */
-+/* These syscalls are not included in ancient glibc versions,
-+   so we have to define them ourselves, whee ! */
- #if ((__GLIBC__ <= 2) && (__GLIBC_MINOR__ < 1))
- int bdflush(int func, int data)
- {
--    return(syscall(__NR_bdflush, func, data));
-+      return(syscall(__NR_bdflush, func, data));
- }
- #ifndef __alpha__
- # define __NR_klogctl __NR_syslog
- int klogctl(int type, char *b, int len)
- {
--    return(syscall(__NR_klogctl, type, b, len));
-+      return(syscall(__NR_klogctl, type, b, len));
- }
--#endif
-+#endif /* __alpha__ */
- int umount2(const char * special_file, int flags)
- {
--#ifndef __NR_pivot_root
-+#ifndef __NR_umount2
- #warning This kernel does not support the umount2 syscall
- #warning -> The umount2 system call is being stubbed out...
--    /* BusyBox was compiled against a kernel that did not support
--     *  the umount2 system call.  To make this application work,
--     *  you will need to recompile with a kernel supporting the
--     *  umount2 system call.
--     */
--    bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
--          "BusyBox with a kernel supporting the umount2 system call.\n");
--    errno=ENOSYS;
--    return -1;
-+      /* BusyBox was compiled against a kernel that did not support
-+       *  the umount2 system call.  To make this application work,
-+       *  you will need to recompile with a kernel supporting the
-+       *  umount2 system call.
-+       */
-+      bb_error_msg("\n\nTo make this application work, you will need to recompile\n"
-+                   "BusyBox with a kernel supporting the umount2 system call.\n");
-+      errno = ENOSYS;
-+      return -1;
- #else
--    return(syscall(__NR_umount2, special_file, flags));
--#endif
-+      return(syscall(__NR_umount2, special_file, flags));
-+#endif /* __NR_pivot_root */
- }
--
--#endif
-+#endif /* old glibc check */
- /* END CODE */
-diff -Nur busybox-1.00/loginutils/delgroup.c busybox/loginutils/delgroup.c
---- busybox-1.00/loginutils/delgroup.c 2003-07-14 23:50:51.000000000 +0200
-+++ busybox/loginutils/delgroup.c      2005-06-04 08:20:18.000000000 +0200
-@@ -59,4 +59,4 @@
-       return (EXIT_SUCCESS);
- }
--/* $Id$ */
-+/* $Id$ */
-diff -Nur busybox-1.00/loginutils/delline.c busybox/loginutils/delline.c
---- busybox-1.00/loginutils/delline.c  2003-07-14 23:50:51.000000000 +0200
-+++ busybox/loginutils/delline.c       2005-06-04 08:20:18.000000000 +0200
-@@ -110,4 +110,4 @@
- }
--/* $Id$ */
-+/* $Id$ */
-diff -Nur busybox-1.00/loginutils/deluser.c busybox/loginutils/deluser.c
---- busybox-1.00/loginutils/deluser.c  2003-07-14 22:20:45.000000000 +0200
-+++ busybox/loginutils/deluser.c       2005-06-04 08:20:18.000000000 +0200
-@@ -65,4 +65,4 @@
-       return (EXIT_SUCCESS);
- }
--/* $Id$ */
-+/* $Id$ */
-diff -Nur busybox-1.00/loginutils/getty.c busybox/loginutils/getty.c
---- busybox-1.00/loginutils/getty.c    2004-08-27 00:26:26.000000000 +0200
-+++ busybox/loginutils/getty.c 2005-06-04 08:20:18.000000000 +0200
-@@ -85,7 +85,7 @@
- #define DEF_QUIT      CTL('\\')       /* default quit char */
- #define DEF_KILL      CTL('U')        /* default kill char */
- #define DEF_EOF               CTL('D')        /* default EOF char */
--#define DEF_EOL               0
-+#define DEF_EOL               '\n'
- #define DEF_SWITCH    0                       /* default switch char */
-  /*
-@@ -151,7 +151,7 @@
- /* Storage for things detected while the login name was read. */
--struct chardata {
-+static struct chardata {
-       int erase;                                      /* erase character */
-       int kill;                                       /* kill character */
-       int eol;                                        /* end-of-line character */
-@@ -161,7 +161,7 @@
- /* Initial values for the above. */
--struct chardata init_chardata = {
-+static struct chardata init_chardata = {
-       DEF_ERASE,                                      /* default erase character */
-       DEF_KILL,                                       /* default kill character */
-       13,                                                     /* default eol char */
-diff -Nur busybox-1.00/loginutils/login.c busybox/loginutils/login.c
---- busybox-1.00/loginutils/login.c    2004-08-27 00:26:26.000000000 +0200
-+++ busybox/loginutils/login.c 2005-06-04 08:20:18.000000000 +0200
-@@ -17,10 +17,10 @@
- #include "busybox.h"
- #ifdef CONFIG_SELINUX
--#include <flask_util.h>
--#include <get_sid_list.h>
--#include <proc_secure.h>
--#include <fs_secure.h>
-+#include <selinux/selinux.h>  /* for is_selinux_enabled()  */
-+#include <selinux/get_context_list.h> /* for get_default_context() */
-+#include <selinux/flask.h> /* for security class definitions  */
-+#include <errno.h>
- #endif
- #ifdef CONFIG_FEATURE_U_W_TMP
-@@ -28,7 +28,7 @@
- static void checkutmp(int picky);
- static void setutmp(const char *name, const char *line);
- /* Stuff global to this file */
--struct utmp utent;
-+static struct utmp utent;
- #endif
- // login defines
-@@ -79,8 +79,7 @@
-       char *opt_host = 0;
-       int alarmstarted = 0;
- #ifdef CONFIG_SELINUX
--      int flask_enabled = is_flask_enabled();
--      security_id_t sid = 0, old_tty_sid, new_tty_sid;
-+      security_context_t stat_sid = NULL, sid = NULL, old_tty_sid=NULL, new_tty_sid=NULL;
- #endif
-       username[0]=0;
-@@ -225,41 +224,45 @@
- #ifdef CONFIG_FEATURE_U_W_TMP
-       setutmp ( username, tty );
- #endif
-+
-+      if ( *tty != '/' )
-+              snprintf ( full_tty, sizeof( full_tty ) - 1, "/dev/%s", tty);
-+      else
-+              safe_strncpy ( full_tty, tty, sizeof( full_tty ) - 1 );
-+
- #ifdef CONFIG_SELINUX
--      if (flask_enabled)
-+      if (is_selinux_enabled())
-       {
-               struct stat st;
-+              int rc;
--              if (get_default_sid(username, 0, &sid))
-+              if (get_default_context(username, NULL, &sid))
-               {
-                       fprintf(stderr, "Unable to get SID for %s\n", username);
-                       exit(1);
-               }
--              if (stat_secure(tty, &st, &old_tty_sid))
-+              rc = getfilecon(full_tty,&stat_sid);
-+              freecon(stat_sid);
-+              if ((rc<0) || (stat(full_tty, &st)<0))
-               {
--                      fprintf(stderr, "stat_secure(%.100s) failed: %.100s\n", tty, strerror(errno));
-+                      fprintf(stderr, "stat_secure(%.100s) failed: %.100s\n", full_tty, strerror(errno));
-                       return EXIT_FAILURE;
-               }
--              if (security_change_sid (sid, old_tty_sid, SECCLASS_CHR_FILE, &new_tty_sid) != 0)
-+              if (security_compute_relabel (sid, old_tty_sid, SECCLASS_CHR_FILE, &new_tty_sid) != 0)
-               {
--                      fprintf(stderr, "security_change_sid(%.100s) failed: %.100s\n", tty, strerror(errno));
-+                      fprintf(stderr, "security_change_sid(%.100s) failed: %.100s\n", full_tty, strerror(errno));
-                       return EXIT_FAILURE;
-               }
--              if(chsid(tty, new_tty_sid) != 0)
-+              if(setfilecon(full_tty, new_tty_sid) != 0)
-               {
--                      fprintf(stderr, "chsid(%.100s, %d) failed: %.100s\n", tty, new_tty_sid, strerror(errno));
-+                      fprintf(stderr, "chsid(%.100s, %s) failed: %.100s\n", full_tty, new_tty_sid, strerror(errno));
-                       return EXIT_FAILURE;
-               }
-+              freecon(sid);
-+              freecon(old_tty_sid);
-+              freecon(new_tty_sid);
-       }
--      else
--              sid = 0;
- #endif
--
--      if ( *tty != '/' )
--              snprintf ( full_tty, sizeof( full_tty ) - 1, "/dev/%s", tty);
--      else
--              safe_strncpy ( full_tty, tty, sizeof( full_tty ) - 1 );
--
-       if ( !is_my_tty ( full_tty ))
-               syslog ( LOG_ERR, "unable to determine TTY name, got %s\n", full_tty );
-@@ -279,11 +282,10 @@
-       if ( pw-> pw_uid == 0 )
-               syslog ( LOG_INFO, "root login %s\n", fromhost );
--      run_shell ( tmp, 1, 0, 0
- #ifdef CONFIG_SELINUX
--      , sid
-+      set_current_security_context(sid);
- #endif
--       );     /* exec the shell finally. */
-+      run_shell ( tmp, 1, 0, 0);      /* exec the shell finally. */
-       return EXIT_FAILURE;
- }
-@@ -387,7 +389,7 @@
- }
--static void motd ( )
-+static void motd (void)
- {
-       FILE *fp;
-       register int c;
-diff -Nur busybox-1.00/loginutils/passwd.c busybox/loginutils/passwd.c
---- busybox-1.00/loginutils/passwd.c   2004-09-15 04:39:09.000000000 +0200
-+++ busybox/loginutils/passwd.c        2005-06-04 08:20:18.000000000 +0200
-@@ -21,7 +21,7 @@
- static void set_filesize_limit(int blocks);
--int get_algo(char *a)
-+static int get_algo(char *a)
- {
-       int x = 1;                                      /* standard: MD5 */
-@@ -31,7 +31,7 @@
- }
--extern int update_passwd(const struct passwd *pw, char *crypt_pw)
-+static int update_passwd(const struct passwd *pw, char *crypt_pw)
- {
-       char filename[1024];
-       char buf[1025];
-diff -Nur busybox-1.00/loginutils/su.c busybox/loginutils/su.c
---- busybox-1.00/loginutils/su.c       2004-03-15 09:28:46.000000000 +0100
-+++ busybox/loginutils/su.c    2005-06-04 08:20:18.000000000 +0200
-@@ -147,11 +147,10 @@
-       change_identity ( pw );
-       setup_environment ( opt_shell, opt_loginshell, !opt_preserve, pw );
--      run_shell ( opt_shell, opt_loginshell, opt_command, (const char**)opt_args
- #ifdef CONFIG_SELINUX
--      , 0
-+       set_current_security_context(NULL);
- #endif
--      );
-+      run_shell ( opt_shell, opt_loginshell, opt_command, (const char**)opt_args);
-       return EXIT_FAILURE;
- }
-diff -Nur busybox-1.00/loginutils/sulogin.c busybox/loginutils/sulogin.c
---- busybox-1.00/loginutils/sulogin.c  2004-05-01 03:27:30.000000000 +0200
-+++ busybox/loginutils/sulogin.c       2005-06-04 08:20:18.000000000 +0200
-@@ -153,6 +153,12 @@
-       puts("Entering System Maintenance Mode\n");
-       fflush(stdout);
-       syslog(LOG_INFO, "System Maintenance Mode\n");
-+
-+#ifdef CONFIG_SELINUX
-+      renew_current_security_context();
-+#endif
-+
-       run_shell(pwent.pw_shell, 1, 0, 0);
-+
-       return (0);
- }
-diff -Nur busybox-1.00/loginutils/vlock.c busybox/loginutils/vlock.c
---- busybox-1.00/loginutils/vlock.c    2004-05-01 03:27:30.000000000 +0200
-+++ busybox/loginutils/vlock.c 2005-06-04 08:20:18.000000000 +0200
-@@ -51,7 +51,7 @@
- static struct spwd *spw;
- /* getspuid - get a shadow entry by uid */
--struct spwd *getspuid(uid_t uid)
-+static struct spwd *getspuid(uid_t uid)
- {
-       struct spwd *sp;
-       struct passwd *mypw;
-diff -Nur busybox-1.00/miscutils/Config.in busybox/miscutils/Config.in
---- busybox-1.00/miscutils/Config.in   2004-08-27 01:12:59.000000000 +0200
-+++ busybox/miscutils/Config.in        2005-06-04 08:20:16.000000000 +0200
-@@ -83,6 +83,12 @@
-       help
-         Increases logging to stderr or syslog.
-+config CONFIG_EJECT
-+      bool "eject"
-+      default n
-+      help
-+        Used to eject cdroms.  (defaults to /dev/cdrom)
-+
- config CONFIG_LAST
-       bool "last"
-       default n
-diff -Nur busybox-1.00/miscutils/Makefile.in busybox/miscutils/Makefile.in
---- busybox-1.00/miscutils/Makefile.in 2004-10-08 09:45:39.000000000 +0200
-+++ busybox/miscutils/Makefile.in      2005-06-04 08:20:16.000000000 +0200
-@@ -24,19 +24,20 @@
- srcdir=$(top_srcdir)/miscutils
- MISCUTILS-y:=
--MISCUTILS-$(CONFIG_ADJTIMEX)          += adjtimex.o
--MISCUTILS-$(CONFIG_CROND)               += crond.o
--MISCUTILS-$(CONFIG_CRONTAB)             += crontab.o
--MISCUTILS-$(CONFIG_DC)                        += dc.o
--MISCUTILS-$(CONFIG_DEVFSD)            += devfsd.o
--MISCUTILS-$(CONFIG_HDPARM)            += hdparm.o
--MISCUTILS-$(CONFIG_LAST)              += last.o
--MISCUTILS-$(CONFIG_MAKEDEVS)          += makedevs.o
--MISCUTILS-$(CONFIG_MT)                        += mt.o
--MISCUTILS-$(CONFIG_RX)                        += rx.o
--MISCUTILS-$(CONFIG_STRINGS)           += strings.o
--MISCUTILS-$(CONFIG_TIME)              += time.o
--MISCUTILS-$(CONFIG_WATCHDOG)          += watchdog.o
-+MISCUTILS-$(CONFIG_ADJTIMEX)    += adjtimex.o
-+MISCUTILS-$(CONFIG_CROND)       += crond.o
-+MISCUTILS-$(CONFIG_CRONTAB)     += crontab.o
-+MISCUTILS-$(CONFIG_DC)          += dc.o
-+MISCUTILS-$(CONFIG_DEVFSD)      += devfsd.o
-+MISCUTILS-$(CONFIG_EJECT)       += eject.o
-+MISCUTILS-$(CONFIG_HDPARM)      += hdparm.o
-+MISCUTILS-$(CONFIG_LAST)        += last.o
-+MISCUTILS-$(CONFIG_MAKEDEVS)    += makedevs.o
-+MISCUTILS-$(CONFIG_MT)          += mt.o
-+MISCUTILS-$(CONFIG_RX)          += rx.o
-+MISCUTILS-$(CONFIG_STRINGS)     += strings.o
-+MISCUTILS-$(CONFIG_TIME)        += time.o
-+MISCUTILS-$(CONFIG_WATCHDOG)    += watchdog.o
- libraries-y+=$(MISCUTILS_DIR)$(MISCUTILS_AR)
-diff -Nur busybox-1.00/miscutils/eject.c busybox/miscutils/eject.c
---- busybox-1.00/miscutils/eject.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/miscutils/eject.c  2005-06-04 08:20:16.000000000 +0200
-@@ -0,0 +1,63 @@
-+/*
-+ * eject implementation for busybox
-+ *
-+ * Copyright (C) 2004  Peter Willis <psyphreak@phreaker.net>
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+/*
-+ * This is a simple hack of eject based on something Erik posted in #uclibc.
-+ * Most of the dirty work blatantly ripped off from cat.c =)
-+ */
-+
-+#include <fcntl.h>
-+#include <sys/ioctl.h>
-+#include <unistd.h>
-+#include <sys/mount.h>
-+#include <mntent.h> 
-+#include "busybox.h"
-+
-+/* various defines swiped from linux/cdrom.h */
-+#define CDROMCLOSETRAY            0x5319  /* pendant of CDROMEJECT  */
-+#define CDROMEJECT                0x5309  /* Ejects the cdrom media */
-+#define DEFAULT_CDROM             "/dev/cdrom"
-+
-+extern int eject_main(int argc, char **argv)
-+{
-+      unsigned long flags;
-+      char *device;
-+      struct mntent *m;
-+      
-+      flags = bb_getopt_ulflags(argc, argv, "t");
-+      device=argv[optind] ? : DEFAULT_CDROM;
-+      
-+      if((m = find_mount_point(device, bb_path_mtab_file))) {
-+              if(umount(m->mnt_dir))
-+                      bb_error_msg_and_die("Can't umount");
-+#ifdef CONFIG_FEATURE_MTAB_SUPPORT
-+              else
-+                      erase_mtab(m->mnt_fsname);      
-+#endif
-+      }
-+      if (ioctl(bb_xopen( device, 
-+                         (O_RDONLY | O_NONBLOCK)), 
-+                ( flags ? CDROMCLOSETRAY : CDROMEJECT)))
-+      {
-+              bb_perror_msg_and_die(device);
-+      }
-+      return(EXIT_SUCCESS);
-+}
-diff -Nur busybox-1.00/miscutils/hdparm.c busybox/miscutils/hdparm.c
---- busybox-1.00/miscutils/hdparm.c    2004-07-21 00:53:59.000000000 +0200
-+++ busybox/miscutils/hdparm.c 2005-06-04 08:20:16.000000000 +0200
-@@ -467,8 +467,8 @@
- /* Busybox messages and functions */
--const char * const bb_msg_shared_mem  ="could not %s sharedmem buf";
--const char * const bb_msg_op_not_supp =" operation not supported on %s disks";
-+static const char * const bb_msg_shared_mem   ="could not %s sharedmem buf";
-+static const char * const bb_msg_op_not_supp  =" operation not supported on %s disks";
- static void bb_ioctl(int fd, int request, void *argp, const char *string)
- {
-diff -Nur busybox-1.00/miscutils/rx.c busybox/miscutils/rx.c
---- busybox-1.00/miscutils/rx.c        2004-03-15 09:28:46.000000000 +0100
-+++ busybox/miscutils/rx.c     2005-06-04 08:20:16.000000000 +0200
-@@ -1,6 +1,6 @@
- /*-------------------------------------------------------------------------
-  * Filename:      xmodem.c
-- * Version:       $Id$
-+ * Version:       $Id$
-  * Copyright:     Copyright (C) 2001, Hewlett-Packard Company
-  * Author:        Christopher Hoover <ch@hpl.hp.com>
-  * Description:   xmodem functionality for uploading of kernels
-diff -Nur busybox-1.00/modutils/Config.in busybox/modutils/Config.in
---- busybox-1.00/modutils/Config.in    2004-07-20 08:09:14.000000000 +0200
-+++ busybox/modutils/Config.in 2005-06-04 08:20:10.000000000 +0200
-@@ -21,7 +21,7 @@
- config CONFIG_FEATURE_2_6_MODULES
-       bool "  Support version 2.6.x Linux kernels"
-       default n
--      depends on CONFIG_INSMOD
-+      depends on CONFIG_INSMOD 
-       help
-         Support module loading for newer 2.6.x Linux kernels.
-@@ -80,6 +80,14 @@
-       help
-         lsmod is used to display a list of loaded modules.
-+config CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT
-+      bool "  lsmod pretty output for 2.6.x Linux kernels "
-+      default n
-+      depends on CONFIG_LSMOD 
-+      help
-+        This option makes output format of lsmod adjusted to 
-+        the format of module-init-tools for Linux kernel 2.6.
-+
- config CONFIG_FEATURE_QUERY_MODULE_INTERFACE
-       bool
-       default y
-diff -Nur busybox-1.00/modutils/insmod.c busybox/modutils/insmod.c
---- busybox-1.00/modutils/insmod.c     2004-09-03 01:03:25.000000000 +0200
-+++ busybox/modutils/insmod.c  2005-06-04 08:20:10.000000000 +0200
-@@ -109,6 +109,14 @@
- #endif
-+/* Alpha */
-+#if defined(__alpha__)   
-+#define MATCH_MACHINE(x) (x == EM_ALPHA)
-+#define SHT_RELM       SHT_RELA
-+#define Elf64_RelM     Elf64_Rela
-+#define ELFCLASSM      ELFCLASS64
-+#endif
-+
- /* ARM support */
- #if defined(__arm__)
- #define MATCH_MACHINE(x) (x == EM_ARM)
-@@ -135,6 +143,19 @@
- #endif
- #endif
-+/* PA-RISC / HP-PA */
-+#if defined(__hppa__)
-+#define MATCH_MACHINE(x) (x == EM_PARISC)
-+#define SHT_RELM       SHT_RELA
-+#if defined(__LP64__)
-+#define Elf64_RelM     Elf64_Rela
-+#define ELFCLASSM      ELFCLASS64
-+#else
-+#define Elf32_RelM     Elf32_Rela
-+#define ELFCLASSM      ELFCLASS32
-+#endif
-+#endif
-+
- /* H8/300 */
- #if defined(__H8300H__) || defined(__H8300S__)
- #define MATCH_MACHINE(x) (x == EM_H8_300)
-@@ -269,8 +290,8 @@
- /* X86_64  */
- #if defined(__x86_64__)
- #define MATCH_MACHINE(x) (x == EM_X86_64)
--#define SHT_RELM      SHT_REL
--#define Elf64_RelM    Elf64_Rel
-+#define SHT_RELM      SHT_RELA
-+#define Elf64_RelM    Elf64_Rela
- #define ELFCLASSM     ELFCLASS64
- #endif
-@@ -308,7 +329,7 @@
- #ifndef MODUTILS_MODULE_H
- static const int MODUTILS_MODULE_H = 1;
--#ident "$Id$"
-+#ident "$Id$"
- /*======================================================================*/
- /* For sizeof() which are related to the module platform and not to the
-@@ -466,7 +487,7 @@
- #ifndef MODUTILS_OBJ_H
- static const int MODUTILS_OBJ_H = 1;
--#ident "$Id$"
-+#ident "$Id$"
- /* The relocatable object is manipulated using elfin types.  */
-@@ -3432,8 +3453,8 @@
-               ".text",
-               ".rodata",
-               ".data",
--              ".bss"
--                      ".sbss"
-+              ".bss",
-+              ".sbss"
-       };
-       if (realpath(filename, real)) {
-diff -Nur busybox-1.00/modutils/lsmod.c busybox/modutils/lsmod.c
---- busybox-1.00/modutils/lsmod.c      2004-03-15 09:28:47.000000000 +0100
-+++ busybox/modutils/lsmod.c   2005-06-04 08:20:10.000000000 +0200
-@@ -164,10 +164,52 @@
- {
-       printf("Module                  Size  Used by");
-       check_tainted();
-+#if defined(CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT)
-+      {
-+        FILE *file;
-+        char line[4096];
-+        file = fopen("/proc/modules", "r");
-+
-+        if (!file) 
-+          bb_error_msg_and_die("Opening /proc/modules");
-+
-+        while (fgets(line, sizeof(line), file)) {
-+          char *tok;
-+          
-+          tok = strtok(line, " \t");
-+          printf("%-19s", tok);
-+          tok = strtok(NULL, " \t\n");
-+          printf(" %8s", tok);
-+          tok = strtok(NULL, " \t\n");
-+          /* Null if no module unloading support. */
-+          if (tok) {
-+            printf("  %s", tok);
-+            tok = strtok(NULL, "\n");
-+            if (!tok)
-+              tok = "";
-+            /* New-style has commas, or -.  If so,
-+               truncate (other fields might follow). */
-+            else if (strchr(tok, ',')) {
-+              tok = strtok(tok, "\t ");
-+              /* Strip trailing comma. */
-+              if (tok[strlen(tok)-1] == ',')
-+                tok[strlen(tok)-1] = '\0';
-+            } else if (tok[0] == '-'
-+                       && (tok[1] == '\0' || isspace(tok[1])))
-+              tok = "";
-+            printf(" %s", tok);
-+          }
-+          printf("\n");
-+        }
-+        fclose(file);
-+      }
-+      return 0;  /* Success  */
-+#else
-       if (bb_xprint_file_by_name("/proc/modules") < 0) {
-               return 0;
-       }
-+#endif  /*  CONFIG_FEATURE_2_6_MODULES  */
-       return 1;
- }
-diff -Nur busybox-1.00/modutils/modprobe.c busybox/modutils/modprobe.c
---- busybox-1.00/modutils/modprobe.c   2004-09-24 11:18:55.000000000 +0200
-+++ busybox/modutils/modprobe.c        2005-06-04 08:20:10.000000000 +0200
-@@ -61,7 +61,7 @@
- static int autoclean, show_only, quiet, do_syslog, verbose;
- static int k_version;
--int parse_tag_value ( char *buffer, char **ptag, char **pvalue )
-+static int parse_tag_value ( char *buffer, char **ptag, char **pvalue )
- {
-       char *tag, *value;
-diff -Nur busybox-1.00/networking/Config.in busybox/networking/Config.in
---- busybox-1.00/networking/Config.in  2004-09-23 22:08:46.000000000 +0200
-+++ busybox/networking/Config.in       2005-06-04 08:20:05.000000000 +0200
-@@ -18,6 +18,19 @@
-       help
-         Ping hosts by ARP packets
-+config CONFIG_ETHER_WAKE
-+      bool "ether-wake"
-+      default n
-+      help
-+        Send a magic packet to wake up sleeping machines.
-+
-+config CONFIG_FAKEIDENTD
-+      bool "fakeidentd"
-+      default n
-+      help
-+        fakeidentd listens to the ident port and returns a set fake 
-+        value whatever it gets.
-+
- config CONFIG_FTPGET
-       bool "ftpget"
-       default n
-@@ -415,6 +428,14 @@
-         A simple Unix utility which reads and writes data across network
-         connections.
-+config CONFIG_NC_GAPING_SECURITY_HOLE
-+      bool "gaping security hole"
-+      default n
-+      depends on CONFIG_NC
-+      help
-+        Add support for executing a program after making or receiving a
-+        successful connection (-e option).
-+
- config CONFIG_NETSTAT
-       bool "netstat"
-       default n
-@@ -630,5 +651,16 @@
- source networking/udhcp/Config.in
-+config CONFIG_ZCIP
-+      bool "zcip"
-+      default n
-+      help
-+        ZCIP provides ZeroConf IPv4 address selection, according to RFC 3927.
-+        It's a daemon that allocates and defends a dynamically assigned
-+        address on the 169.254/16 network, requiring no system administrator.
-+
-+        See http://www.zeroconf.org for further details, and "zcip.script"
-+        in the busybox examples.
-+
- endmenu
-diff -Nur busybox-1.00/networking/Makefile.in busybox/networking/Makefile.in
---- busybox-1.00/networking/Makefile.in        2004-10-08 09:45:43.000000000 +0200
-+++ busybox/networking/Makefile.in     2005-06-04 08:20:05.000000000 +0200
-@@ -23,33 +23,36 @@
- endif
- srcdir=$(top_srcdir)/networking
- NETWORKING-y:=
--NETWORKING-$(CONFIG_ARPING)   += arping.o
--NETWORKING-$(CONFIG_FTPGET)   += ftpgetput.o
--NETWORKING-$(CONFIG_FTPPUT)   += ftpgetput.o
--NETWORKING-$(CONFIG_HOSTNAME) += hostname.o
--NETWORKING-$(CONFIG_HTTPD)    += httpd.o
--NETWORKING-$(CONFIG_IFCONFIG) += ifconfig.o
--NETWORKING-$(CONFIG_IFUPDOWN) += ifupdown.o
--NETWORKING-$(CONFIG_INETD)      += inetd.o
--NETWORKING-$(CONFIG_IP)               += ip.o
--NETWORKING-$(CONFIG_IPCALC)   += ipcalc.o
--NETWORKING-$(CONFIG_IPADDR)   += ipaddr.o
--NETWORKING-$(CONFIG_IPLINK)   += iplink.o
--NETWORKING-$(CONFIG_IPROUTE)  += iproute.o
--NETWORKING-$(CONFIG_IPTUNNEL) += iptunnel.o
--NETWORKING-$(CONFIG_NAMEIF)   += nameif.o
--NETWORKING-$(CONFIG_NC)               += nc.o
--NETWORKING-$(CONFIG_NETSTAT)  += netstat.o
--NETWORKING-$(CONFIG_NSLOOKUP) += nslookup.o
--NETWORKING-$(CONFIG_PING)     += ping.o
--NETWORKING-$(CONFIG_PING6)    += ping6.o
--NETWORKING-$(CONFIG_ROUTE)    += route.o
--NETWORKING-$(CONFIG_TELNET)   += telnet.o
--NETWORKING-$(CONFIG_TELNETD)  += telnetd.o
--NETWORKING-$(CONFIG_TFTP)     += tftp.o
--NETWORKING-$(CONFIG_TRACEROUTE)       += traceroute.o
--NETWORKING-$(CONFIG_VCONFIG)  += vconfig.o
--NETWORKING-$(CONFIG_WGET)     += wget.o
-+NETWORKING-$(CONFIG_ARPING)       += arping.o
-+NETWORKING-$(CONFIG_ETHER_WAKE)   += ether-wake.o
-+NETWORKING-$(CONFIG_FAKEIDENTD)   += fakeidentd.o
-+NETWORKING-$(CONFIG_FTPGET)       += ftpgetput.o
-+NETWORKING-$(CONFIG_FTPPUT)       += ftpgetput.o
-+NETWORKING-$(CONFIG_HOSTNAME)     += hostname.o
-+NETWORKING-$(CONFIG_HTTPD)        += httpd.o
-+NETWORKING-$(CONFIG_IFCONFIG)     += ifconfig.o
-+NETWORKING-$(CONFIG_IFUPDOWN)     += ifupdown.o
-+NETWORKING-$(CONFIG_INETD)        += inetd.o
-+NETWORKING-$(CONFIG_IP)           += ip.o
-+NETWORKING-$(CONFIG_IPCALC)       += ipcalc.o
-+NETWORKING-$(CONFIG_IPADDR)       += ipaddr.o
-+NETWORKING-$(CONFIG_IPLINK)       += iplink.o
-+NETWORKING-$(CONFIG_IPROUTE)      += iproute.o
-+NETWORKING-$(CONFIG_IPTUNNEL)     += iptunnel.o
-+NETWORKING-$(CONFIG_NAMEIF)       += nameif.o
-+NETWORKING-$(CONFIG_NC)           += nc.o
-+NETWORKING-$(CONFIG_NETSTAT)      += netstat.o
-+NETWORKING-$(CONFIG_NSLOOKUP)     += nslookup.o
-+NETWORKING-$(CONFIG_PING)         += ping.o
-+NETWORKING-$(CONFIG_PING6)        += ping6.o
-+NETWORKING-$(CONFIG_ROUTE)        += route.o
-+NETWORKING-$(CONFIG_TELNET)       += telnet.o
-+NETWORKING-$(CONFIG_TELNETD)      += telnetd.o
-+NETWORKING-$(CONFIG_TFTP)         += tftp.o
-+NETWORKING-$(CONFIG_TRACEROUTE)   += traceroute.o
-+NETWORKING-$(CONFIG_VCONFIG)      += vconfig.o
-+NETWORKING-$(CONFIG_WGET)         += wget.o
-+NETWORKING-$(CONFIG_ZCIP)         += zcip.o
- libraries-y+=$(NETWORKING_DIR)$(NETWORKING_AR)
-@@ -57,7 +60,7 @@
- needcrypt-$(CONFIG_FEATURE_HTTPD_AUTH_MD5) := y
- ifeq ($(needcrypt-y),y)
--  LIBRARIES += -lcrypt
-+      LIBRARIES += -lcrypt
- endif
- $(NETWORKING_DIR)$(NETWORKING_AR): $(patsubst %,$(NETWORKING_DIR)%, $(NETWORKING-y))
-@@ -65,4 +68,3 @@
- $(NETWORKING_DIR)%.o: $(srcdir)/%.c
-       $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
--
-diff -Nur busybox-1.00/networking/arping.c busybox/networking/arping.c
---- busybox-1.00/networking/arping.c   2003-09-26 02:33:18.000000000 +0200
-+++ busybox/networking/arping.c        2005-06-04 08:20:05.000000000 +0200
-@@ -106,7 +106,7 @@
-       return err;
- }
--void finish(void)
-+static void finish(void)
- {
-       if (!quiet) {
-               printf("Sent %d probes (%d broadcast(s))\n", sent, brd_sent);
-@@ -129,7 +129,7 @@
-       exit(!received);
- }
--void catcher(void)
-+static void catcher(void)
- {
-       struct timeval tv;
-       static struct timeval start;
-@@ -151,7 +151,7 @@
-       alarm(1);
- }
--int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
-+static int recv_pack(unsigned char *buf, int len, struct sockaddr_ll *FROM)
- {
-       struct timeval tv;
-       struct arphdr *ah = (struct arphdr *) buf;
-diff -Nur busybox-1.00/networking/ether-wake.c busybox/networking/ether-wake.c
---- busybox-1.00/networking/ether-wake.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/networking/ether-wake.c    2005-06-04 08:20:05.000000000 +0200
-@@ -0,0 +1,300 @@
-+/*
-+ * ether-wake.c - Send a magic packet to wake up sleeping machines.
-+ *
-+ * 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.
-+ *
-+ * Author:      Donald Becker, http://www.scyld.com/"; http://www.scyld.com/wakeonlan.html
-+ * Busybox port: Christian Volkmann <haveaniceday@online.de>
-+ *               Used version of ether-wake.c: v1.09 11/12/2003 Donald Becker, http://www.scyld.com/";
-+ */
-+
-+/* full usage according Donald Becker
-+ * usage: ether-wake [-i <ifname>] [-p aa:bb:cc:dd[:ee:ff]] 00:11:22:33:44:55\n"
-+ *
-+ *    This program generates and transmits a Wake-On-LAN (WOL)\n"
-+ *    \"Magic Packet\", used for restarting machines that have been\n"
-+ *    soft-powered-down (ACPI D3-warm state).\n"
-+ *    It currently generates the standard AMD Magic Packet format, with\n"
-+ *    an optional password appended.\n"
-+ *
-+ *    The single required parameter is the Ethernet MAC (station) address\n"
-+ *    of the machine to wake or a host ID with known NSS 'ethers' entry.\n"
-+ *    The MAC address may be found with the 'arp' program while the target\n"
-+ *    machine is awake.\n"
-+ *
-+ *    Options:\n"
-+ *            -b      Send wake-up packet to the broadcast address.\n"
-+ *            -D      Increase the debug level.\n"
-+ *            -i ifname       Use interface IFNAME instead of the default 'eth0'.\n"
-+ *            -p <pw>         Append the four or six byte password PW to the packet.\n"
-+ *                                    A password is only required for a few adapter types.\n"
-+ *                                    The password may be specified in ethernet hex format\n"
-+ *                                    or dotted decimal (Internet address)\n"
-+ *            -p 00:22:44:66:88:aa\n"
-+ *            -p 192.168.1.1\n";
-+ * 
-+ *
-+ *    This program generates and transmits a Wake-On-LAN (WOL) "Magic Packet",
-+ *    used for restarting machines that have been soft-powered-down
-+ *    (ACPI D3-warm state).  It currently generates the standard AMD Magic Packet
-+ *    format, with an optional password appended.
-+ * 
-+ *    This software may be used and distributed according to the terms
-+ *    of the GNU Public License, incorporated herein by reference.
-+ *    Contact the author for use under other terms.
-+ * 
-+ *    This source file was originally part of the network tricks package, and
-+ *    is now distributed to support the Scyld Beowulf system.
-+ *    Copyright 1999-2003 Donald Becker and Scyld Computing Corporation.
-+ * 
-+ *    The author may be reached as becker@scyld, or C/O
-+ *     Scyld Computing Corporation
-+ *     914 Bay Ridge Road, Suite 220
-+ *     Annapolis MD 21403
-+ * 
-+ *   Notes:
-+ *   On some systems dropping root capability allows the process to be
-+ *   dumped, traced or debugged.
-+ *   If someone traces this program, they get control of a raw socket.
-+ *   Linux handles this safely, but beware when porting this program.
-+ * 
-+ *   An alternative to needing 'root' is using a UDP broadcast socket, however
-+ *   doing so only works with adapters configured for unicast+broadcast Rx
-+ *   filter.  That configuration consumes more power.
-+*/
-+
-+
-+#include <unistd.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <errno.h>
-+#include <ctype.h>
-+#include <string.h>
-+
-+#include <sys/socket.h>
-+#include <sys/types.h>
-+#include <sys/ioctl.h>
-+#include <features.h>
-+#include <netpacket/packet.h>
-+#include <net/ethernet.h>
-+#include <netdb.h>
-+#include <netinet/ether.h>
-+
-+#ifdef __linux__
-+#include <linux/if.h>
-+#endif
-+
-+#include "busybox.h"
-+
-+/* Note: PF_INET, SOCK_DGRAM, IPPROTO_UDP would allow SIOCGIFHWADDR to
-+ * work as non-root, but we need SOCK_PACKET to specify the Ethernet
-+ * destination address.
-+ */
-+#ifdef PF_PACKET
-+# define whereto_t sockaddr_ll
-+# define make_socket() socket(PF_PACKET, SOCK_RAW, 0)
-+#else
-+# define whereto_t sockaddr
-+# define make_socket() socket(AF_INET, SOCK_PACKET, SOCK_PACKET)
-+#endif
-+
-+#ifdef DEBUG
-+# define bb_debug_msg(fmt, args...) fprintf(stderr, fmt, ## args)
-+void bb_debug_dump_packet(unsigned char *outpack, int pktsize)
-+{
-+      int i;
-+      printf("packet dump:\n");
-+      for (i = 0; i < pktsize; ++i) {
-+              printf("%2.2x ", outpack[i]);
-+              if (i % 20 == 19) printf("\n");
-+      }
-+      printf("\n\n");
-+}
-+#else
-+# define bb_debug_msg(fmt, args...)
-+# define bb_debug_dump_packet(outpack, pktsize)
-+#endif
-+
-+static inline void get_dest_addr(const char *arg, struct ether_addr *eaddr);
-+static inline int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast);
-+static inline int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd);
-+
-+int etherwake_main(int argc, char *argv[])
-+{
-+      char *ifname = "eth0", *pass = NULL;
-+      unsigned long flags;
-+      unsigned char wol_passwd[6];
-+      int wol_passwd_sz = 0;
-+
-+      int s;                                          /* Raw socket */
-+      int pktsize;
-+      unsigned char outpack[1000];
-+
-+      struct ether_addr eaddr;
-+      struct whereto_t whereto;       /* who to wake up */
-+
-+      /* handle misc user options */
-+      flags = bb_getopt_ulflags(argc, argv, "bi:p:", &ifname, &pass);
-+      if (optind == argc)
-+              bb_show_usage();
-+      if (pass)
-+              wol_passwd_sz = get_wol_pw(pass, wol_passwd);
-+
-+      /* create the raw socket */
-+      s = make_socket();
-+      if (s < 0)
-+              bb_perror_msg_and_die(bb_msg_can_not_create_raw_socket);
-+
-+      /* now that we have a raw socket we can drop root */
-+      setuid(getuid());
-+
-+      /* look up the dest mac address */
-+      get_dest_addr(argv[optind], &eaddr);
-+
-+      /* fill out the header of the packet */
-+      pktsize = get_fill(outpack, &eaddr, flags /*& 1 [OPT_BROADCAST]*/);
-+
-+      bb_debug_dump_packet(outpack, pktsize);
-+
-+      /* Fill in the source address, if possible. */
-+#ifdef __linux__
-+      {
-+              struct ifreq if_hwaddr;
-+
-+              strcpy(if_hwaddr.ifr_name, ifname);
-+              if (ioctl(s, SIOCGIFHWADDR, &if_hwaddr) < 0)
-+                      bb_perror_msg_and_die("SIOCGIFHWADDR on %s failed", ifname);
-+
-+              memcpy(outpack+6, if_hwaddr.ifr_hwaddr.sa_data, 6);
-+
-+# ifdef DEBUG
-+              {
-+                      unsigned char *hwaddr = if_hwaddr.ifr_hwaddr.sa_data;
-+                      printf("The hardware address (SIOCGIFHWADDR) of %s is type %d  "
-+                                 "%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n\n", ifname,
-+                                 if_hwaddr.ifr_hwaddr.sa_family, hwaddr[0], hwaddr[1],
-+                                 hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);
-+              }
-+# endif
-+      }
-+#endif /* __linux__ */
-+
-+      bb_debug_dump_packet(outpack, pktsize);
-+
-+      /* append the password if specified */
-+      if (wol_passwd_sz > 0) {
-+              memcpy(outpack+pktsize, wol_passwd, wol_passwd_sz);
-+              pktsize += wol_passwd_sz;
-+      }
-+
-+      bb_debug_dump_packet(outpack, pktsize);
-+
-+      /* This is necessary for broadcasts to work */
-+      if (flags /*& 1 [OPT_BROADCAST]*/) {
-+              int one = 1;
-+              if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, (void *)&one, sizeof(one)) < 0)
-+                      bb_perror_msg("SO_BROADCAST");
-+      }
-+
-+#if defined(PF_PACKET)
-+      {
-+              struct ifreq ifr;
-+              strncpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
-+              if (ioctl(s, SIOCGIFINDEX, &ifr) == -1)
-+                      bb_perror_msg_and_die("SIOCGIFINDEX");
-+              memset(&whereto, 0, sizeof(whereto));
-+              whereto.sll_family = AF_PACKET;
-+              whereto.sll_ifindex = ifr.ifr_ifindex;
-+              /* The manual page incorrectly claims the address must be filled.
-+                 We do so because the code may change to match the docs. */
-+              whereto.sll_halen = ETH_ALEN;
-+              memcpy(whereto.sll_addr, outpack, ETH_ALEN);
-+      }
-+#else
-+      whereto.sa_family = 0;
-+      strcpy(whereto.sa_data, ifname);
-+#endif
-+
-+      if (sendto(s, outpack, pktsize, 0, (struct sockaddr *)&whereto, sizeof(whereto)) < 0)
-+              bb_perror_msg(bb_msg_write_error);
-+
-+      close(s);
-+
-+      return EXIT_SUCCESS;
-+}
-+
-+/* Convert the host ID string to a MAC address.
-+ * The string may be a:
-+ *    Host name
-+ *    IP address string
-+ *    MAC address string
-+*/
-+static inline void get_dest_addr(const char *hostid, struct ether_addr *eaddr)
-+{
-+      struct ether_addr *eap;
-+
-+      eap = ether_aton(hostid);
-+      if (eap) {
-+              *eaddr = *eap;
-+              bb_debug_msg("The target station address is %s\n\n", ether_ntoa(eaddr));
-+      } else if (ether_hostton(hostid, eaddr) == 0) {
-+              bb_debug_msg("Station address for hostname %s is %s\n\n", hostid, ether_ntoa(eaddr));
-+      } else
-+              bb_show_usage();
-+}
-+
-+static inline int get_fill(unsigned char *pkt, struct ether_addr *eaddr, int broadcast)
-+{
-+      int offset, i;
-+      unsigned char *station_addr = eaddr->ether_addr_octet;
-+
-+      if (broadcast)
-+              memset(pkt+0, 0xff, 6);
-+      else
-+              memcpy(pkt, station_addr, 6);
-+      memcpy(pkt+6, station_addr, 6);
-+      pkt[12] = 0x08;                         /* Or 0x0806 for ARP, 0x8035 for RARP */
-+      pkt[13] = 0x42;
-+      offset = 14;
-+
-+      memset(pkt+offset, 0xff, 6);
-+      offset += 6;
-+
-+      for (i = 0; i < 16; ++i) {
-+              memcpy(pkt+offset, station_addr, 6);
-+              offset += 6;
-+      }
-+
-+      return offset;
-+}
-+
-+static inline int get_wol_pw(const char *ethoptarg, unsigned char *wol_passwd)
-+{
-+      int passwd[6];
-+      int byte_cnt, i;
-+
-+      /* handle MAC format */
-+      byte_cnt = sscanf(ethoptarg, "%2x:%2x:%2x:%2x:%2x:%2x",
-+                        &passwd[0], &passwd[1], &passwd[2],
-+                        &passwd[3], &passwd[4], &passwd[5]);
-+      /* handle IP format */
-+      if (byte_cnt < 4)
-+              byte_cnt = sscanf(ethoptarg, "%d.%d.%d.%d",
-+                                &passwd[0], &passwd[1], &passwd[2], &passwd[3]);
-+      if (byte_cnt < 4) {
-+              bb_error_msg("Unable to read the Wake-On-LAN pass");
-+              return 0;
-+      }
-+
-+      for (i = 0; i < byte_cnt; ++i)
-+              wol_passwd[i] = passwd[i];
-+
-+      bb_debug_msg("password: %2.2x %2.2x %2.2x %2.2x (%d)\n\n",
-+                   wol_passwd[0], wol_passwd[1], wol_passwd[2], wol_passwd[3],
-+                   byte_cnt);
-+
-+      return byte_cnt;
-+}
-diff -Nur busybox-1.00/networking/fakeidentd.c busybox/networking/fakeidentd.c
---- busybox-1.00/networking/fakeidentd.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/networking/fakeidentd.c    2005-06-04 08:20:05.000000000 +0200
-@@ -0,0 +1,432 @@
-+/* vi: set sw=4 ts=4: */
-+/*
-+ * A fake identd server
-+ *
-+ * Adapted to busybox by Thomas Lundquist <thomasez@zelow.no>
-+ * Original Author: Tomi Ollila <too@iki.fi>
-+ *                  http://www.guru-group.fi/~too/sw/
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-+ *
-+ */
-+
-+#include <unistd.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <stdarg.h>
-+#include <string.h>
-+#include <fcntl.h>
-+#include <signal.h>
-+#include <sys/syslog.h>
-+
-+#include <pwd.h>
-+#include <netdb.h>
-+
-+#include <sys/syslog.h>
-+#include <sys/types.h>
-+#include <sys/time.h>
-+#include <time.h>
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <errno.h>
-+#include <arpa/inet.h>
-+#include <sys/uio.h>
-+
-+#include "busybox.h"
-+
-+#define IDENT_PORT  113
-+#define MAXCONNS    20
-+#define MAXIDLETIME 45
-+
-+static const char ident_substr[] = " : USERID : UNIX : ";
-+static const int ident_substr_len = sizeof(ident_substr) - 1;
-+#define PIDFILE "/var/run/identd.pid"
-+
-+/*
-+ * We have to track the 'first connection socket' so that we 
-+ * don't go around closing file descriptors for non-clients.
-+ *
-+ * descriptor setup normally
-+ *  0 = server socket
-+ *  1 = syslog fd (hopefully -- otherwise this won't work)
-+ *  2 = connection socket after detached from tty. standard error before that
-+ *  3 - 2 + MAXCONNS = rest connection sockets
-+ *
-+ * To try to make sure that syslog fd is what is "requested", the that fd
-+ * is closed before openlog() call.  It can only severely fail if fd 0
-+ * is initially closed.
-+ */
-+#define FCS 2
-+
-+/*
-+ * FD of the connection is always the index of the connection structure
-+ * in `conns' array + FCS
-+ */
-+static struct {
-+      char buf[20];
-+      int len;
-+      time_t lasttime;
-+} conns[MAXCONNS];
-+
-+/* When using global variables, bind those at least to a structure. */
-+static struct {
-+      const char *identuser;
-+      fd_set readfds;
-+      int conncnt;
-+} G;
-+
-+/*
-+ * Prototypes
-+ */
-+static void reply(int s, char *buf);
-+static void replyError(int s, char *buf);
-+
-+static const char *nobodystr = "nobody"; /* this needs to be declared like this */
-+static char *bind_ip_address = "0.0.0.0";
-+
-+static inline void movefd(int from, int to)
-+{
-+      if (from != to) {
-+              dup2(from, to);
-+              close(from);
-+      }
-+}
-+
-+static void inetbind(void)
-+{
-+      int s, port;
-+      struct sockaddr_in addr;
-+      int len = sizeof(addr);
-+      int one = 1;
-+      struct servent *se;
-+
-+      if ((se = getservbyname("identd", "tcp")) == NULL)
-+              port = IDENT_PORT;
-+      else
-+              port = se->s_port;
-+
-+      if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-+              bb_perror_msg_and_die("Cannot create server socket");
-+
-+      setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-+
-+      memset(&addr, 0, sizeof(addr));
-+      addr.sin_addr.s_addr = inet_addr(bind_ip_address);
-+      addr.sin_family = AF_INET;
-+      addr.sin_port = htons(port);
-+
-+      if (bind(s, (struct sockaddr *)&addr, len) < 0)
-+              bb_perror_msg_and_die("Cannot bind() port %i", IDENT_PORT);
-+
-+      if (listen(s, 5) < 0)
-+              bb_perror_msg_and_die("Cannot listen() on port %i", IDENT_PORT);
-+
-+      movefd(s, 0);
-+}
-+
-+static void delpidfile(void)
-+{
-+      /*
-+       * Usually nobody has no write/delete access to directory /var/run/
-+       * therefore if file cannot be deleted, it is truncated
-+       */
-+      if (unlink(PIDFILE) < 0)
-+              close(open(PIDFILE, O_WRONLY|O_CREAT|O_TRUNC, 0644));
-+}
-+
-+static void handlexitsigs(int signum)
-+{
-+      delpidfile();
-+      exit(0);
-+}
-+
-+/* May succeed. If not, won't care. */
-+static inline void writepid(uid_t nobody, uid_t nogrp)
-+{
-+      char buf[24];
-+      int fd = open(PIDFILE, O_WRONLY|O_CREAT|O_TRUNC, 0664);
-+
-+      if (fd < 0)
-+              return;
-+
-+      snprintf(buf, 23, "%d\n", getpid());
-+      write(fd, buf, strlen(buf));
-+      fchown(fd, nobody, nogrp);
-+      close(fd);
-+
-+      /* should this handle ILL, ... (see signal(7)) */
-+      signal(SIGTERM, handlexitsigs);
-+      signal(SIGINT,  handlexitsigs);
-+      signal(SIGQUIT, handlexitsigs);
-+}
-+
-+/* return 0 as parent, 1 as child */
-+static int godaemon(void)
-+{
-+      uid_t nobody, nogrp;
-+      struct passwd *pw;
-+
-+      switch (fork()) {
-+      case -1:
-+              bb_perror_msg_and_die("Could not fork");
-+
-+      case 0:
-+              pw = getpwnam(nobodystr);
-+              if (pw == NULL)
-+                      bb_error_msg_and_die("Cannot find uid/gid of user '%s'", nobodystr);
-+              nobody = pw->pw_uid;
-+              nogrp = pw->pw_gid;
-+              writepid(nobody, nogrp);
-+
-+              close(0);
-+              inetbind();
-+              if (setgid(nogrp))   bb_error_msg_and_die("Could not setgid()");
-+              if (setegid(nogrp))  bb_error_msg_and_die("Could not setegid()");
-+              if (setuid(nobody))  bb_error_msg_and_die("Could not setuid()");
-+              if (seteuid(nobody)) bb_error_msg_and_die("Could not seteuid()");
-+              close(1);
-+              close(2);
-+
-+              signal(SIGHUP, SIG_IGN);
-+              signal(SIGPIPE, SIG_IGN); /* connection closed when writing (raises ???) */
-+
-+              setsid();
-+
-+              openlog(bb_applet_name, 0, LOG_DAEMON);
-+              return 1;
-+      }
-+
-+      return 0;
-+}
-+
-+static void deleteConn(int s)
-+{
-+      int i = s - FCS;
-+
-+      close(s);
-+
-+      G.conncnt--;
-+
-+      /*
-+       * Most of the time there is 0 connections. Most often that there
-+       * is connections, there is just one connection. When this one connection
-+       * closes, i == G.conncnt = 0 -> no copying.
-+       * When there is more than one connection, the oldest connections closes
-+       * earlier on average. When this happens, the code below starts copying
-+       * the connection structure w/ highest index to the place which which is
-+       * just deleted. This means that the connection structures are no longer
-+       * in chronological order. I'd quess this means that when there is more
-+       * than 1 connection, on average every other connection structure needs
-+       * to be copied over the time all these connections are deleted.
-+       */
-+      if (i != G.conncnt) {
-+              memcpy(&conns[i], &conns[G.conncnt], sizeof(conns[0]));
-+              movefd(G.conncnt + FCS, s);
-+      }
-+
-+      FD_CLR(G.conncnt + FCS, &G.readfds);
-+}
-+
-+static int closeOldest(void)
-+{
-+      time_t min = conns[0].lasttime;
-+      int idx = 0;
-+      int i;
-+
-+      for (i = 1; i < MAXCONNS; i++)
-+              if (conns[i].lasttime < min)
-+                      idx = i;
-+
-+      replyError(idx + FCS, "X-SERVER-TOO-BUSY");
-+      close(idx + FCS);
-+
-+      return idx;
-+}
-+
-+static int checkInput(char *buf, int len, int l)
-+{
-+      int i;
-+      for (i = len; i < len + l; ++i)
-+              if (buf[i] == '\n')
-+                      return 1;
-+      return 0;
-+}
-+
-+int fakeidentd_main(int argc, char **argv)
-+{
-+      memset(conns, 0, sizeof(conns));
-+      memset(&G, 0, sizeof(G));
-+      FD_ZERO(&G.readfds);
-+      FD_SET(0, &G.readfds);
-+
-+      /* handle -b <ip> parameter */
-+      bb_getopt_ulflags(argc, argv, "b:", &bind_ip_address);
-+      /* handle optional REPLY STRING */
-+      if (optind < argc)
-+              G.identuser = argv[optind];
-+      else
-+              G.identuser = nobodystr;
-+
-+      /* daemonize and have the parent return */
-+      if (godaemon() == 0)
-+              return 0;
-+
-+      /* main loop where we process all events and never exit */
-+      while (1) {
-+      fd_set rfds = G.readfds;
-+      struct timeval tv = { 15, 0 };
-+      int i;
-+      int tim = time(NULL);
-+
-+      select(G.conncnt + FCS, &rfds, NULL, NULL, G.conncnt? &tv: NULL);
-+
-+      for (i = G.conncnt - 1; i >= 0; i--) {
-+              int s = i + FCS;
-+
-+              if (FD_ISSET(s, &rfds)) {
-+                      char *buf = conns[i].buf;
-+                      unsigned int len = conns[i].len;
-+                      unsigned int l;
-+
-+                      if ((l = read(s, buf + len, sizeof(conns[0].buf) - len)) > 0) {
-+                              if (checkInput(buf, len, l)) {
-+                                      reply(s, buf);
-+                                      goto deleteconn;
-+                              } else if (len + l >= sizeof(conns[0].buf)) {
-+                                      replyError(s, "X-INVALID-REQUEST");
-+                                      goto deleteconn;
-+                              } else {
-+                                      conns[i].len += l;
-+                              }
-+                      } else {
-+                              goto deleteconn;
-+                      }
-+
-+                      conns[i].lasttime = tim;
-+                      continue;
-+
-+deleteconn:
-+                      deleteConn(s);
-+              } else {
-+                      /* implement as time_after() in linux kernel sources ... */
-+                      if (conns[i].lasttime + MAXIDLETIME <= tim) {
-+                              replyError(s, "X-TIMEOUT");
-+                              deleteConn(s);
-+                      }
-+              }
-+      }
-+
-+      if (FD_ISSET(0, &rfds)) {
-+              int s = accept(0, NULL, 0);
-+
-+              if (s < 0) {
-+                      if (errno != EINTR) /* EINTR */
-+                              syslog(LOG_ERR, "accept: %s", strerror(errno));
-+              } else {
-+                      if (G.conncnt == MAXCONNS)
-+                              i = closeOldest();
-+                      else
-+                              i = G.conncnt++;
-+
-+                      movefd(s, i + FCS); /* move if not already there */
-+                      FD_SET(i + FCS, &G.readfds);
-+
-+                      conns[i].len = 0;
-+                      conns[i].lasttime = time(NULL);
-+              }
-+      }
-+      } /* end of while(1) */
-+
-+      return 0;
-+}
-+
-+static int parseAddrs(char *ptr, char **myaddr, char **heraddr);
-+static void reply(int s, char *buf)
-+{
-+      char *myaddr, *heraddr;
-+
-+      myaddr = heraddr = NULL;
-+
-+      if (parseAddrs(buf, &myaddr, &heraddr))
-+              replyError(s, "X-INVALID-REQUEST");
-+      else {
-+              struct iovec iv[6];
-+              iv[0].iov_base = myaddr;               iv[0].iov_len = strlen(myaddr);
-+              iv[1].iov_base = ", ";                 iv[1].iov_len = 2;
-+              iv[2].iov_base = heraddr;              iv[2].iov_len = strlen(heraddr);
-+              iv[3].iov_base = (void *)ident_substr; iv[3].iov_len = ident_substr_len;
-+              iv[4].iov_base = (void *)G.identuser;  iv[4].iov_len = strlen(G.identuser);
-+              iv[5].iov_base = "\r\n";               iv[5].iov_len = 2;
-+              writev(s, iv, 6);
-+      }
-+}
-+
-+static void replyError(int s, char *buf)
-+{
-+      struct iovec iv[3];
-+      iv[0].iov_base = "0, 0 : ERROR : ";   iv[0].iov_len = 15;
-+      iv[1].iov_base = buf;                 iv[1].iov_len = strlen(buf);
-+      iv[2].iov_base = "\r\n";              iv[2].iov_len = 2;
-+      writev(s, iv, 3);
-+}
-+
-+static int chmatch(char c, char *chars)
-+{
-+      for (; *chars; chars++)
-+              if (c == *chars)
-+                      return 1;
-+      return 0;
-+}
-+
-+static int skipchars(char **p, char *chars)
-+{
-+      while (chmatch(**p, chars))
-+              (*p)++;
-+      if (**p == '\r' || **p == '\n')
-+              return 0;
-+      return 1;
-+}
-+
-+static int parseAddrs(char *ptr, char **myaddr, char **heraddr)
-+{
-+      /* parse <port-on-server> , <port-on-client> */
-+
-+      if (!skipchars(&ptr, " \t"))
-+              return -1;
-+
-+      *myaddr = ptr;
-+
-+      if (!skipchars(&ptr, "1234567890"))
-+              return -1;
-+
-+      if (!chmatch(*ptr, " \t,"))
-+              return -1;
-+
-+      *ptr++ = '\0';
-+
-+      if (!skipchars(&ptr, " \t,") )
-+              return -1;
-+
-+      *heraddr = ptr;
-+
-+      skipchars(&ptr, "1234567890");
-+
-+      if (!chmatch(*ptr, " \n\r"))
-+              return -1;
-+
-+      *ptr = '\0';
-+
-+      return 0;
-+}
-diff -Nur busybox-1.00/networking/hostname.c busybox/networking/hostname.c
---- busybox-1.00/networking/hostname.c 2003-07-14 23:21:01.000000000 +0200
-+++ busybox/networking/hostname.c      2005-06-04 08:20:05.000000000 +0200
-@@ -1,6 +1,6 @@
- /* vi: set sw=4 ts=4: */
- /*
-- * $Id$
-+ * $Id$
-  * Mini hostname implementation for busybox
-  *
-  * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
-diff -Nur busybox-1.00/networking/ifconfig.c busybox/networking/ifconfig.c
---- busybox-1.00/networking/ifconfig.c 2004-03-31 13:30:08.000000000 +0200
-+++ busybox/networking/ifconfig.c      2005-06-04 08:20:05.000000000 +0200
-@@ -15,7 +15,7 @@
-  * Foundation;  either  version 2 of the License, or  (at
-  * your option) any later version.
-  *
-- * $Id$
-+ * $Id$
-  *
-  */
-@@ -46,8 +46,8 @@
- #include <netpacket/packet.h>
- #include <net/ethernet.h>
- #else
--#include <asm/types.h>
--#include <linux/if_ether.h>
-+#include <sys/types.h>
-+#include <netinet/if_ether.h>
- #endif
- #include "inet_common.h"
- #include "busybox.h"
-@@ -177,7 +177,7 @@
- struct arg1opt {
-       const char *name;
--      unsigned short selector;
-+      int selector;
-       unsigned short ifr_offset;
- };
-diff -Nur busybox-1.00/networking/ifupdown.c busybox/networking/ifupdown.c
---- busybox-1.00/networking/ifupdown.c 2004-09-14 19:24:58.000000000 +0200
-+++ busybox/networking/ifupdown.c      2005-06-04 08:20:05.000000000 +0200
-@@ -150,7 +150,7 @@
- static char no_act = 0;
- static char verbose = 0;
--static char **environ = NULL;
-+static char **__myenviron = NULL;
- #ifdef CONFIG_FEATURE_IFUPDOWN_IP
-@@ -460,7 +460,7 @@
-       { "loopback", loopback_up6, loopback_down6, },
- };
--struct address_family_t addr_inet6 = {
-+static struct address_family_t addr_inet6 = {
-       "inet6",
-       sizeof(methods6) / sizeof(struct method_t),
-       methods6
-@@ -609,7 +609,7 @@
-       { "loopback", loopback_up, loopback_down, },
- };
--struct address_family_t addr_inet =
-+static struct address_family_t addr_inet =
- {
-       "inet",
-       sizeof(methods) / sizeof(struct method_t),
-@@ -961,16 +961,16 @@
-       const int n_env_entries = iface->n_options + 5;
-       char **ppch;
--      if (environ != NULL) {
--              for (ppch = environ; *ppch; ppch++) {
-+      if (__myenviron != NULL) {
-+              for (ppch = __myenviron; *ppch; ppch++) {
-                       free(*ppch);
-                       *ppch = NULL;
-               }
--              free(environ);
--              environ = NULL;
-+              free(__myenviron);
-+              __myenviron = NULL;
-       }
--      environ = xmalloc(sizeof(char *) * (n_env_entries + 1 /* for final NULL */ ));
--      environend = environ;
-+      __myenviron = xmalloc(sizeof(char *) * (n_env_entries + 1 /* for final NULL */ ));
-+      environend = __myenviron;
-       *environend = NULL;
-       for (i = 0; i < iface->n_options; i++) {
-@@ -1010,7 +1010,7 @@
-                       case -1:                /* failure */
-                               return 0;
-                       case 0:         /* child */
--                              execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, NULL, environ);
-+                              execle(DEFAULT_SHELL, DEFAULT_SHELL, "-c", str, NULL, __myenviron);
-                               exit(127);
-               }
-               waitpid(child, &status, 0);
-diff -Nur busybox-1.00/networking/inetd.c busybox/networking/inetd.c
---- busybox-1.00/networking/inetd.c    2004-06-22 10:40:54.000000000 +0200
-+++ busybox/networking/inetd.c 2005-06-04 08:20:05.000000000 +0200
-@@ -560,7 +560,7 @@
-               if (sep != 0) {
-                       int i;
--#define SWAP(type, a, b) {type c=(type)a; (type)a=(type)b; (type)b=(type)c;}
-+#define SWAP(type, a, b) {type c=(type)(a); (a)=(type)(b); (b)=(type)c;}
-                       sigprocmask(SIG_BLOCK, &emptymask, &oldmask);
-                       /*
-diff -Nur busybox-1.00/networking/libiproute/ipaddress.c busybox/networking/libiproute/ipaddress.c
---- busybox-1.00/networking/libiproute/ipaddress.c     2004-03-15 09:28:56.000000000 +0100
-+++ busybox/networking/libiproute/ipaddress.c  2005-06-04 08:20:04.000000000 +0200
-@@ -48,7 +48,7 @@
-       struct rtnl_handle *rth;
- } filter;
--void print_link_flags(FILE *fp, unsigned flags, unsigned mdown)
-+static void print_link_flags(FILE *fp, unsigned flags, unsigned mdown)
- {
-       fprintf(fp, "<");
-       flags &= ~IFF_RUNNING;
-diff -Nur busybox-1.00/networking/libiproute/iptunnel.c busybox/networking/libiproute/iptunnel.c
---- busybox-1.00/networking/libiproute/iptunnel.c      2004-04-26 21:32:49.000000000 +0200
-+++ busybox/networking/libiproute/iptunnel.c   2005-06-04 08:20:04.000000000 +0200
-@@ -361,7 +361,7 @@
-       return -1;
- }
--int do_del(int argc, char **argv)
-+static int do_del(int argc, char **argv)
- {
-       struct ip_tunnel_parm p;
-@@ -381,7 +381,7 @@
-       return -1;
- }
--void print_tunnel(struct ip_tunnel_parm *p)
-+static void print_tunnel(struct ip_tunnel_parm *p)
- {
-       char s1[256];
-       char s2[256];
-diff -Nur busybox-1.00/networking/libiproute/ll_proto.c busybox/networking/libiproute/ll_proto.c
---- busybox-1.00/networking/libiproute/ll_proto.c      2004-03-15 09:28:56.000000000 +0100
-+++ busybox/networking/libiproute/ll_proto.c   2005-06-04 08:20:04.000000000 +0200
-@@ -90,7 +90,7 @@
- #undef __PF
--char * ll_proto_n2a(unsigned short id, char *buf, int len)
-+const char * ll_proto_n2a(unsigned short id, char *buf, int len)
- {
-         int i;
-diff -Nur busybox-1.00/networking/libiproute/ll_types.c busybox/networking/libiproute/ll_types.c
---- busybox-1.00/networking/libiproute/ll_types.c      2003-06-20 11:05:00.000000000 +0200
-+++ busybox/networking/libiproute/ll_types.c   2005-06-04 08:20:04.000000000 +0200
-@@ -13,7 +13,7 @@
- #include <linux/if_arp.h>
--char * ll_type_n2a(int type, char *buf, int len)
-+const char * ll_type_n2a(int type, char *buf, int len)
- {
- #define __PF(f,n) { ARPHRD_##f, #n },
- static struct {
-diff -Nur busybox-1.00/networking/libiproute/rt_names.c busybox/networking/libiproute/rt_names.c
---- busybox-1.00/networking/libiproute/rt_names.c      2002-12-16 08:37:21.000000000 +0100
-+++ busybox/networking/libiproute/rt_names.c   2005-06-04 08:20:04.000000000 +0200
-@@ -76,7 +76,7 @@
-                           rtnl_rtprot_tab, 256);
- }
--char * rtnl_rtprot_n2a(int id, char *buf, int len)
-+const char * rtnl_rtprot_n2a(int id, char *buf, int len)
- {
-       if (id<0 || id>=256) {
-               snprintf(buf, len, "%d", id);
-@@ -143,7 +143,7 @@
-                           rtnl_rtscope_tab, 256);
- }
--char * rtnl_rtscope_n2a(int id, char *buf, int len)
-+const char * rtnl_rtscope_n2a(int id, char *buf, int len)
- {
-       if (id<0 || id>=256) {
-               snprintf(buf, len, "%d", id);
-@@ -206,7 +206,7 @@
-                           rtnl_rtrealm_tab, 256);
- }
--char * rtnl_rtrealm_n2a(int id, char *buf, int len)
-+const char * rtnl_rtrealm_n2a(int id, char *buf, int len)
- {
-       if (id<0 || id>=256) {
-               snprintf(buf, len, "%d", id);
-@@ -272,7 +272,7 @@
-                           rtnl_rttable_tab, 256);
- }
--char * rtnl_rttable_n2a(int id, char *buf, int len)
-+const char * rtnl_rttable_n2a(int id, char *buf, int len)
- {
-       if (id<0 || id>=256) {
-               snprintf(buf, len, "%d", id);
-@@ -334,7 +334,7 @@
-                           rtnl_rtdsfield_tab, 256);
- }
--char * rtnl_dsfield_n2a(int id, char *buf, int len)
-+const char * rtnl_dsfield_n2a(int id, char *buf, int len)
- {
-       if (id<0 || id>=256) {
-               snprintf(buf, len, "%d", id);
-diff -Nur busybox-1.00/networking/libiproute/utils.c busybox/networking/libiproute/utils.c
---- busybox-1.00/networking/libiproute/utils.c 2003-03-19 10:12:42.000000000 +0100
-+++ busybox/networking/libiproute/utils.c      2005-06-04 08:20:04.000000000 +0200
-@@ -238,7 +238,7 @@
-       return addr.data[0];
- }
--void incomplete_command()
-+void incomplete_command(void)
- {
-       bb_error_msg("Command line is not complete. Try option \"help\"");
-       exit(-1);
-diff -Nur busybox-1.00/networking/nameif.c busybox/networking/nameif.c
---- busybox-1.00/networking/nameif.c   2004-04-25 07:11:17.000000000 +0200
-+++ busybox/networking/nameif.c        2005-06-04 08:20:05.000000000 +0200
-@@ -86,7 +86,7 @@
- }
- /* Check ascii str_macaddr, convert and copy to *mac */
--struct ether_addr *cc_macaddr(char *str_macaddr)
-+static struct ether_addr *cc_macaddr(char *str_macaddr)
- {
-       struct ether_addr *lmac, *mac;
-diff -Nur busybox-1.00/networking/nc.c busybox/networking/nc.c
---- busybox-1.00/networking/nc.c       2004-03-27 11:02:43.000000000 +0100
-+++ busybox/networking/nc.c    2005-06-04 08:20:05.000000000 +0200
-@@ -4,7 +4,7 @@
-     0.0.1   6K      It works.
-     0.0.2   5K      Smaller and you can also check the exit condition if you wish.
--    0.0.3         Uses select()
-+    0.0.3           Uses select()
-     19980918 Busy Boxed! Dave Cinege
-     19990512 Uses Select. Charles P. Wright
-@@ -23,13 +23,13 @@
-     You should have received a copy of the GNU General Public License
-     along with this program; if not, write to the Free Software
-     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
--
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
-+#include <signal.h>
- #include <sys/types.h>
- #include <sys/socket.h>
-@@ -40,14 +40,17 @@
- #include <sys/ioctl.h>
- #include "busybox.h"
--#define GAPING_SECURITY_HOLE
-+static void timeout(int signum)
-+{
-+      bb_error_msg_and_die("Timed out");
-+}
- int nc_main(int argc, char **argv)
- {
--      int do_listen = 0, lport = 0, delay = 0, tmpfd, opt, sfd, x;
-+      int do_listen = 0, lport = 0, delay = 0, wsecs = 0, tmpfd, opt, sfd, x;
-       char buf[BUFSIZ];
--#ifdef GAPING_SECURITY_HOLE
--      char * pr00gie = NULL;
-+#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
-+      char *pr00gie = NULL;
- #endif
-       struct sockaddr_in address;
-@@ -55,7 +58,7 @@
-       fd_set readfds, testfds;
--      while ((opt = getopt(argc, argv, "lp:i:e:")) > 0) {
-+      while ((opt = getopt(argc, argv, "lp:i:e:w:")) > 0) {
-               switch (opt) {
-                       case 'l':
-                               do_listen++;
-@@ -66,23 +69,25 @@
-                       case 'i':
-                               delay = atoi(optarg);
-                               break;
--#ifdef GAPING_SECURITY_HOLE
-+#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
-                       case 'e':
-                               pr00gie = optarg;
-                               break;
- #endif
-+                      case 'w':
-+                              wsecs = atoi(optarg);
-+                              break;
-                       default:
-                               bb_show_usage();
-               }
-       }
--#ifdef GAPING_SECURITY_HOLE
-+#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
-       if (pr00gie) {
-               /* won't need stdin */
--              close (STDIN_FILENO);      
-+              close(STDIN_FILENO);      
-       }
--#endif /* GAPING_SECURITY_HOLE */
--
-+#endif /* CONFIG_NC_GAPING_SECURITY_HOLE */
-       if ((do_listen && optind != argc) || (!do_listen && optind + 2 != argc))
-               bb_show_usage();
-@@ -90,10 +95,15 @@
-       if ((sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-               bb_perror_msg_and_die("socket");
-       x = 1;
--      if (setsockopt (sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1)
--              bb_perror_msg_and_die ("reuseaddr failed");
-+      if (setsockopt(sfd, SOL_SOCKET, SO_REUSEADDR, &x, sizeof (x)) == -1)
-+              bb_perror_msg_and_die("reuseaddr");
-       address.sin_family = AF_INET;
-+      if (wsecs) {
-+              signal(SIGALRM, timeout);
-+              alarm(wsecs);
-+      }
-+
-       if (lport != 0) {
-               memset(&address.sin_addr, 0, sizeof(address.sin_addr));
-               address.sin_port = lport;
-@@ -123,19 +133,23 @@
-                       bb_perror_msg_and_die("connect");
-       }
--#ifdef GAPING_SECURITY_HOLE
-+      if (wsecs) {
-+              alarm(0);
-+              signal(SIGALRM, SIG_DFL);
-+      }
-+
-+#ifdef CONFIG_NC_GAPING_SECURITY_HOLE
-       /* -e given? */
-       if (pr00gie) {
-               dup2(sfd, 0);
-               close(sfd);
--              dup2 (0, 1);
--              dup2 (0, 2);
--              execl (pr00gie, pr00gie, NULL);
-+              dup2(0, 1);
-+              dup2(0, 2);
-+              execl(pr00gie, pr00gie, NULL);
-               /* Don't print stuff or it will go over the wire.... */
-               _exit(-1);
-       }
--#endif /* GAPING_SECURITY_HOLE */
--
-+#endif /* CONFIG_NC_GAPING_SECURITY_HOLE */
-       FD_ZERO(&readfds);
-       FD_SET(sfd, &readfds);
-@@ -154,7 +168,7 @@
-               for (fd = 0; fd < FD_SETSIZE; fd++) {
-                       if (FD_ISSET(fd, &testfds)) {
-                               if ((nread = safe_read(fd, buf, sizeof(buf))) < 0)
--                                      bb_perror_msg_and_die("read");
-+                                      bb_perror_msg_and_die(bb_msg_read_error);
-                               if (fd == sfd) {
-                                       if (nread == 0)
-@@ -167,7 +181,7 @@
-                               }
-                               if (bb_full_write(ofd, buf, nread) < 0)
--                                      bb_perror_msg_and_die("write");
-+                                      bb_perror_msg_and_die(bb_msg_write_error);
-                               if (delay > 0) {
-                                       sleep(delay);
-                               }
-diff -Nur busybox-1.00/networking/nslookup.c busybox/networking/nslookup.c
---- busybox-1.00/networking/nslookup.c 2004-10-13 09:25:01.000000000 +0200
-+++ busybox/networking/nslookup.c      2005-06-04 08:20:05.000000000 +0200
-@@ -203,4 +203,4 @@
-       return EXIT_FAILURE;
- }
--/* $Id$ */
-+/* $Id$ */
-diff -Nur busybox-1.00/networking/ping.c busybox/networking/ping.c
---- busybox-1.00/networking/ping.c     2004-03-15 09:28:48.000000000 +0100
-+++ busybox/networking/ping.c  2005-06-04 08:20:05.000000000 +0200
-@@ -1,6 +1,6 @@
- /* vi: set sw=4 ts=4: */
- /*
-- * $Id$
-+ * $Id$
-  * Mini ping implementation for busybox
-  *
-  * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
-@@ -178,7 +178,10 @@
- static unsigned long tmin = ULONG_MAX, tmax, tsum;
- static char rcvd_tbl[MAX_DUP_CHK / 8];
--struct hostent *hostent;
-+#ifndef CONFIG_FEATURE_FANCY_PING6
-+static
-+#endif
-+      struct hostent *hostent;
- static void sendping(int);
- static void pingstats(int);
-diff -Nur busybox-1.00/networking/ping6.c busybox/networking/ping6.c
---- busybox-1.00/networking/ping6.c    2004-03-15 09:28:48.000000000 +0100
-+++ busybox/networking/ping6.c 2005-06-04 08:20:05.000000000 +0200
-@@ -1,6 +1,6 @@
- /* vi: set sw=4 ts=4: */
- /*
-- * $Id$
-+ * $Id$
-  * Mini ping implementation for busybox
-  *
-  * Copyright (C) 1999 by Randolph Chung <tausq@debian.org>
-diff -Nur busybox-1.00/networking/route.c busybox/networking/route.c
---- busybox-1.00/networking/route.c    2004-03-20 00:27:08.000000000 +0100
-+++ busybox/networking/route.c 2005-06-04 08:20:05.000000000 +0200
-@@ -15,7 +15,7 @@
-  * Foundation;  either  version 2 of the License, or  (at
-  * your option) any later version.
-  *
-- * $Id$
-+ * $Id$
-  *
-  * displayroute() code added by Vladimir N. Oleynik <dzo@simtreas.ru>
-  * adjustments by Larry Doolittle  <LRDoolittle@lbl.gov>
-@@ -485,6 +485,7 @@
-       }
- }
-+/* also used in netstat */
- void displayroutes(int noresolve, int netstatfmt)
- {
-       char devname[64], flags[16], sdest[16], sgw[16];
-diff -Nur busybox-1.00/networking/telnetd.c busybox/networking/telnetd.c
---- busybox-1.00/networking/telnetd.c  2004-09-14 19:24:58.000000000 +0200
-+++ busybox/networking/telnetd.c       2005-06-04 08:20:05.000000000 +0200
-@@ -1,4 +1,4 @@
--/* $Id$
-+/* $Id$
-  *
-  * Simple telnet server
-  * Bjorn Wesen, Axis Communications AB (bjornw@axis.com)
-@@ -49,6 +49,15 @@
- #define BUFSIZE 4000
-+#ifdef CONFIG_FEATURE_IPV6
-+#define SOCKET_TYPE   AF_INET6
-+typedef struct sockaddr_in6 sockaddr_type;
-+#else
-+#define SOCKET_TYPE   AF_INET
-+typedef struct sockaddr_in sockaddr_type;
-+#endif
-+
-+
- #ifdef CONFIG_LOGIN
- static const char *loginpath = "/bin/login";
- #else
-@@ -373,7 +382,7 @@
- telnetd_main(int argc, char **argv)
- {
- #ifndef CONFIG_FEATURE_TELNETD_INETD
--      struct sockaddr_in sa;
-+        sockaddr_type sa;
-       int master_fd;
- #endif /* CONFIG_FEATURE_TELNETD_INETD */
-       fd_set rdfdset, wrfdset;
-@@ -431,7 +440,7 @@
-       /* Grab a TCP socket.  */
--      master_fd = socket(AF_INET, SOCK_STREAM, 0);
-+        master_fd = socket(SOCKET_TYPE, SOCK_STREAM, 0);
-       if (master_fd < 0) {
-               bb_perror_msg_and_die("socket");
-       }
-@@ -440,8 +449,13 @@
-       /* Set it to listen to specified port.  */
-       memset((void *)&sa, 0, sizeof(sa));
-+#ifdef CONFIG_FEATURE_IPV6
-+      sa.sin6_family = AF_INET6;
-+      sa.sin6_port = htons(portnbr);
-+#else
-       sa.sin_family = AF_INET;
-       sa.sin_port = htons(portnbr);
-+#endif
-       if (bind(master_fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) {
-               bb_perror_msg_and_die("bind");
-diff -Nur busybox-1.00/networking/tftp.c busybox/networking/tftp.c
---- busybox-1.00/networking/tftp.c     2004-09-14 19:24:58.000000000 +0200
-+++ busybox/networking/tftp.c  2005-06-04 08:20:05.000000000 +0200
-@@ -71,8 +71,8 @@
-       "No such user"
- };
--const int tftp_cmd_get = 1;
--const int tftp_cmd_put = 2;
-+static const int tftp_cmd_get = 1;
-+static const int tftp_cmd_put = 2;
- #ifdef CONFIG_FEATURE_TFTP_BLOCKSIZE
-diff -Nur busybox-1.00/networking/udhcp/README.udhcpc busybox/networking/udhcp/README.udhcpc
---- busybox-1.00/networking/udhcp/README.udhcpc        2004-03-15 09:29:00.000000000 +0100
-+++ busybox/networking/udhcp/README.udhcpc     2005-06-04 08:20:05.000000000 +0200
-@@ -12,7 +12,8 @@
- -c, --clientid=CLIENTID         Client identifier
- -H, --hostname=HOSTNAME         Client hostname
---h,                           Alias for -H
-+-h,                             Alias for -H
-+-F, --fqdn=FQDN                 Client fully qualified domain name
- -f, --foreground                Do not fork after getting lease
- -b, --background                Fork to background if lease cannot be
-                                 immediately negotiated.
-diff -Nur busybox-1.00/networking/udhcp/clientpacket.c busybox/networking/udhcp/clientpacket.c
---- busybox-1.00/networking/udhcp/clientpacket.c       2004-04-14 19:51:25.000000000 +0200
-+++ busybox/networking/udhcp/clientpacket.c    2005-06-04 08:20:05.000000000 +0200
-@@ -78,6 +78,7 @@
-       memcpy(packet->chaddr, client_config.arp, 6);
-       add_option_string(packet->options, client_config.clientid);
-       if (client_config.hostname) add_option_string(packet->options, client_config.hostname);
-+      if (client_config.fqdn) add_option_string(packet->options, client_config.fqdn);
-       add_option_string(packet->options, (uint8_t *) &vendor_id);
- }
-diff -Nur busybox-1.00/networking/udhcp/dhcpc.c busybox/networking/udhcp/dhcpc.c
---- busybox-1.00/networking/udhcp/dhcpc.c      2004-05-19 10:29:05.000000000 +0200
-+++ busybox/networking/udhcp/dhcpc.c   2005-06-04 08:20:05.000000000 +0200
-@@ -58,17 +58,18 @@
- struct client_config_t client_config = {
-       /* Default options. */
--      abort_if_no_lease: 0,
--      foreground: 0,
--      quit_after_lease: 0,
--      background_if_no_lease: 0,
--      interface: "eth0",
--      pidfile: NULL,
--      script: DEFAULT_SCRIPT,
--      clientid: NULL,
--      hostname: NULL,
--      ifindex: 0,
--      arp: "\0\0\0\0\0\0",            /* appease gcc-3.0 */
-+      .abort_if_no_lease = 0,
-+      .foreground = 0,
-+      .quit_after_lease = 0,
-+      .background_if_no_lease = 0,
-+      .interface = "eth0",
-+      .pidfile = NULL,
-+      .script = DEFAULT_SCRIPT,
-+      .clientid = NULL,
-+      .hostname = NULL,
-+      .fqdn = NULL,
-+      .ifindex = 0,
-+      .arp = "\0\0\0\0\0\0",          /* appease gcc-3.0 */
- };
- #ifndef IN_BUSYBOX
-@@ -79,6 +80,7 @@
- "  -c, --clientid=CLIENTID         Client identifier\n"
- "  -H, --hostname=HOSTNAME         Client hostname\n"
- "  -h                              Alias for -H\n"
-+"  -F, --fqdn=FQDN                 Client fully qualified domain name\n"
- "  -f, --foreground                Do not fork after getting lease\n"
- "  -b, --background                Fork to background if lease cannot be\n"
- "                                  immediately negotiated.\n"
-@@ -197,7 +199,8 @@
-               {"foreground",  no_argument,            0, 'f'},
-               {"background",  no_argument,            0, 'b'},
-               {"hostname",    required_argument,      0, 'H'},
--              {"hostname",    required_argument,      0, 'h'},
-+              {"hostname",    required_argument,      0, 'h'},
-+              {"fqdn",        required_argument,      0, 'F'},
-               {"interface",   required_argument,      0, 'i'},
-               {"now",         no_argument,            0, 'n'},
-               {"pidfile",     required_argument,      0, 'p'},
-@@ -211,7 +214,7 @@
-       /* get options */
-       while (1) {
-               int option_index = 0;
--              c = getopt_long(argc, argv, "c:fbH:h:i:np:qr:s:v", arg_options, &option_index);
-+              c = getopt_long(argc, argv, "c:fbH:h:F:i:np:qr:s:v", arg_options, &option_index);
-               if (c == -1) break;
-               switch (c) {
-@@ -239,6 +242,23 @@
-                       client_config.hostname[OPT_LEN] = len;
-                       strncpy(client_config.hostname + 2, optarg, len);
-                       break;
-+              case 'F':
-+                      len = strlen(optarg) > 255 ? 255 : strlen(optarg);
-+                      if (client_config.fqdn) free(client_config.fqdn);
-+                      client_config.fqdn = xmalloc(len + 5);
-+                      client_config.fqdn[OPT_CODE] = DHCP_FQDN;
-+                      client_config.fqdn[OPT_LEN] = len + 3;
-+                      /* Flags: 0000NEOS
-+                      S: 1 => Client requests Server to update A RR in DNS as well as PTR
-+                      O: 1 => Server indicates to client that DNS has been updated regardless
-+                      E: 1 => Name data is DNS format, i.e. <4>host<6>domain<4>com<0> not "host.domain.com"
-+                      N: 1 => Client requests Server to not update DNS
-+                      */
-+                      client_config.fqdn[OPT_LEN + 1] = 0x1;
-+                      client_config.fqdn[OPT_LEN + 2] = 0;
-+                      client_config.fqdn[OPT_LEN + 3] = 0;
-+                      strncpy(client_config.fqdn + 5, optarg, len);
-+                      break;
-               case 'i':
-                       client_config.interface =  optarg;
-                       break;
-@@ -419,6 +439,9 @@
-                                       (unsigned long) packet.xid, xid);
-                               continue;
-                       }
-+                      /* Ignore packets that aren't for us */
-+                      if (memcmp(client_config.arp,packet.chaddr,6))
-+                              continue;
-                       if ((message = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) {
-                               DEBUG(LOG_ERR, "couldnt get option from packet -- ignoring");
-diff -Nur busybox-1.00/networking/udhcp/dhcpc.h busybox/networking/udhcp/dhcpc.h
---- busybox-1.00/networking/udhcp/dhcpc.h      2004-01-31 00:45:12.000000000 +0100
-+++ busybox/networking/udhcp/dhcpc.h   2005-06-04 08:20:05.000000000 +0200
-@@ -27,6 +27,7 @@
-       char *script;                   /* User script to run at dhcp events */
-       uint8_t *clientid;              /* Optional client id to use */
-       uint8_t *hostname;              /* Optional hostname to use */
-+      uint8_t *fqdn;                  /* Optional fully qualified domain name to use */
-       int ifindex;                    /* Index number of the interface to use */
-       uint8_t arp[6];                 /* Our arp address */
- };
-diff -Nur busybox-1.00/networking/udhcp/dhcpd.h busybox/networking/udhcp/dhcpd.h
---- busybox-1.00/networking/udhcp/dhcpd.h      2004-10-08 10:49:26.000000000 +0200
-+++ busybox/networking/udhcp/dhcpd.h   2005-06-04 08:20:05.000000000 +0200
-@@ -63,6 +63,7 @@
- #define DHCP_T2                       0x3b
- #define DHCP_VENDOR           0x3c
- #define DHCP_CLIENT_ID                0x3d
-+#define DHCP_FQDN             0x51
- #define DHCP_END              0xFF
-diff -Nur busybox-1.00/networking/udhcp/options.c busybox/networking/udhcp/options.c
---- busybox-1.00/networking/udhcp/options.c    2004-03-15 09:29:01.000000000 +0100
-+++ busybox/networking/udhcp/options.c 2005-06-04 08:20:05.000000000 +0200
-@@ -32,7 +32,9 @@
-       {"ipttl",       OPTION_U8,                              0x17},
-       {"mtu",         OPTION_U16,                             0x1a},
-       {"broadcast",   OPTION_IP | OPTION_REQ,                 0x1c},
--      {"ntpsrv",      OPTION_IP | OPTION_LIST,                0x2a},
-+      {"nisdomain",   OPTION_STRING | OPTION_REQ,             0x28},
-+      {"nissrv",      OPTION_IP | OPTION_LIST | OPTION_REQ,   0x29},
-+      {"ntpsrv",      OPTION_IP | OPTION_LIST | OPTION_REQ,   0x2a},
-       {"wins",        OPTION_IP | OPTION_LIST,                0x2c},
-       {"requestip",   OPTION_IP,                              0x32},
-       {"lease",       OPTION_U32,                             0x33},
-diff -Nur busybox-1.00/networking/udhcp/script.h busybox/networking/udhcp/script.h
---- busybox-1.00/networking/udhcp/script.h     2002-10-14 23:41:27.000000000 +0200
-+++ busybox/networking/udhcp/script.h  2005-06-04 08:20:05.000000000 +0200
-@@ -1,6 +1,6 @@
- #ifndef _SCRIPT_H
- #define _SCRIPT_H
--void run_script(struct dhcpMessage *packet, const char *name);
-+extern void run_script(struct dhcpMessage *packet, const char *name);
- #endif
-diff -Nur busybox-1.00/networking/wget.c busybox/networking/wget.c
---- busybox-1.00/networking/wget.c     2004-10-08 10:27:40.000000000 +0200
-+++ busybox/networking/wget.c  2005-06-04 08:20:05.000000000 +0200
-@@ -117,9 +117,9 @@
- /*
-  *  Base64-encode character string
-  *  oops... isn't something similar in uuencode.c?
-- *  It would be better to use already existing code
-+ *  XXX: It would be better to use already existing code
-  */
--char *base64enc(unsigned char *p, char *buf, int len) {
-+static char *base64enc(unsigned char *p, char *buf, int len) {
-         char al[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
-                     "0123456789+/";
-@@ -854,7 +854,7 @@
-  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-  * SUCH DAMAGE.
-  *
-- *    $Id$
-+ *    $Id$
-  */
-diff -Nur busybox-1.00/networking/zcip.c busybox/networking/zcip.c
---- busybox-1.00/networking/zcip.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/networking/zcip.c  2005-06-04 08:20:05.000000000 +0200
-@@ -0,0 +1,550 @@
-+/*
-+ * RFC3927 ZeroConf IPv4 Link-Local addressing
-+ * (see <http://www.zeroconf.org/>)
-+ *
-+ * Copyright (C) 2003 by Arthur van Hoff (avh@strangeberry.com)
-+ * Copyright (C) 2004 by David Brownell
-+ *
-+ * This program is free software; you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation; either version 2 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * This program is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-+ * General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with this program; if not, write to the Free Software
-+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-+ * 02111-1307 USA
-+ */
-+
-+/*
-+ * This can build as part of BusyBox or by itself:
-+ *
-+ *    $(CROSS_COMPILE)cc -Os -Wall -DNO_BUSYBOX -DDEBUG -o zcip zcip.c
-+ *
-+ * ZCIP just manages the 169.254.*.* addresses.  That network is not
-+ * routed at the IP level, though various proxies or bridges can
-+ * certainly be used.  Its naming is built over multicast DNS.
-+ */
-+
-+// #define      DEBUG
-+
-+// TODO:
-+// - more real-world usage/testing, especially daemon mode
-+// - kernel packet filters to reduce scheduling noise
-+// - avoid silent script failures, especially under load...
-+// - link status monitoring (restart on link-up; stop on link-down)
-+
-+#include <errno.h>
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <string.h>
-+#include <syslog.h>
-+#include <poll.h>
-+#include <time.h>
-+#include <unistd.h>
-+
-+#include <sys/ioctl.h>
-+#include <sys/types.h>
-+#include <sys/wait.h>
-+#include <sys/time.h>
-+#include <sys/socket.h>
-+
-+#include <arpa/inet.h>
-+#include <netinet/in.h>
-+#include <netinet/ether.h>
-+#include <net/ethernet.h>
-+#include <net/if.h>
-+#include <net/if_arp.h>
-+
-+#include <linux/if_packet.h>
-+#include <linux/sockios.h>
-+
-+
-+struct arp_packet {
-+      struct ether_header hdr;
-+      // FIXME this part is netinet/if_ether.h "struct ether_arp"
-+      struct arphdr arp;
-+      struct ether_addr source_addr;
-+      struct in_addr source_ip;
-+      struct ether_addr target_addr;
-+      struct in_addr target_ip;
-+} __attribute__ ((__packed__));
-+
-+/* 169.254.0.0 */
-+static const uint32_t LINKLOCAL_ADDR = 0xa9fe0000;
-+
-+/* protocol timeout parameters, specified in seconds */
-+static const unsigned PROBE_WAIT = 1;
-+static const unsigned PROBE_MIN = 1;
-+static const unsigned PROBE_MAX = 2;
-+static const unsigned PROBE_NUM = 3;
-+static const unsigned MAX_CONFLICTS = 10;
-+static const unsigned RATE_LIMIT_INTERVAL = 60;
-+static const unsigned ANNOUNCE_WAIT = 2;
-+static const unsigned ANNOUNCE_NUM = 2;
-+static const unsigned ANNOUNCE_INTERVAL = 2;
-+static const time_t DEFEND_INTERVAL = 10;
-+
-+static const unsigned char ZCIP_VERSION[] = "0.75 (18 April 2005)";
-+static char *prog;
-+
-+static const struct in_addr null_ip = { 0 };
-+static const struct ether_addr null_addr = { {0, 0, 0, 0, 0, 0} };
-+
-+static int verbose = 0;
-+
-+#ifdef DEBUG
-+
-+#define DBG(fmt,args...) \
-+      fprintf(stderr, "%s: " fmt , prog , ## args)
-+#define VDBG(fmt,args...) do { \
-+      if (verbose) fprintf(stderr, "%s: " fmt , prog ,## args); \
-+      } while (0)
-+#else
-+
-+#define DBG(fmt,args...) \
-+      do { } while (0)
-+#define VDBG  DBG
-+#endif                                /* DEBUG */
-+
-+/**
-+ * Pick a random link local IP address on 169.254/16, except that
-+ * the first and last 256 addresses are reserved.
-+ */
-+static void
-+pick(struct in_addr *ip)
-+{
-+      unsigned        tmp;
-+
-+      /* use cheaper math than lrand48() mod N */
-+      do {
-+              tmp = (lrand48() >> 16) & IN_CLASSB_HOST;
-+      } while (tmp > (IN_CLASSB_HOST - 0x0200));
-+      ip->s_addr = htonl((LINKLOCAL_ADDR + 0x0100) + tmp);
-+}
-+
-+/**
-+ * Broadcast an ARP packet.
-+ */
-+static int
-+arp(int fd, struct sockaddr *saddr, int op,
-+      const struct ether_addr *source_addr, struct in_addr source_ip,
-+      const struct ether_addr *target_addr, struct in_addr target_ip)
-+{
-+      struct arp_packet p;
-+
-+      // ether header
-+      p.hdr.ether_type = htons(ETHERTYPE_ARP);
-+      memcpy(p.hdr.ether_shost, source_addr, ETH_ALEN);
-+      memset(p.hdr.ether_dhost, 0xff, ETH_ALEN);
-+
-+      // arp request
-+      p.arp.ar_hrd = htons(ARPHRD_ETHER);
-+      p.arp.ar_pro = htons(ETHERTYPE_IP);
-+      p.arp.ar_hln = ETH_ALEN;
-+      p.arp.ar_pln = 4;
-+      p.arp.ar_op = htons(op);
-+      memcpy(&p.source_addr, source_addr, ETH_ALEN);
-+      memcpy(&p.source_ip, &source_ip, sizeof (p.source_ip));
-+      memcpy(&p.target_addr, target_addr, ETH_ALEN);
-+      memcpy(&p.target_ip, &target_ip, sizeof (p.target_ip));
-+
-+      // send it
-+      if (sendto(fd, &p, sizeof (p), 0, saddr, sizeof (*saddr)) < 0) {
-+              perror("sendto");
-+              return -errno;
-+      }
-+      return 0;
-+}
-+
-+/**
-+ * Run a script.
-+ */
-+static int
-+run(char *script, char *arg, char *intf, struct in_addr *ip)
-+{
-+      int pid, status;
-+      char *why;
-+
-+      if (script != NULL) {
-+              VDBG("%s run %s %s\n", intf, script, arg);
-+              if (ip != NULL) {
-+                      char *addr = inet_ntoa(*ip);
-+                      setenv("ip", addr, 1);
-+                      syslog(LOG_INFO, "%s %s %s", arg, intf, addr);
-+              }
-+
-+              pid = vfork();
-+              if (pid < 0) {                  // error
-+                      why = "vfork";
-+                      goto bad;
-+              } else if (pid == 0) {          // child
-+                      execl(script, script, arg, NULL);
-+                      perror("execl");
-+                      _exit(EXIT_FAILURE);
-+              } 
-+
-+              if (waitpid(pid, &status, 0) <= 0) {
-+                      why = "waitpid";
-+                      goto bad;
-+              }
-+              if (WEXITSTATUS(status) != 0) {
-+                      fprintf(stderr, "%s: script %s failed, exit=%d\n",
-+                                      prog, script, WEXITSTATUS(status));
-+                      return -errno;
-+              }
-+      }
-+      return 0;
-+bad:
-+      status = -errno;
-+      syslog(LOG_ERR, "%s %s, %s error: %s",
-+              arg, intf, why, strerror(errno));
-+      return status;
-+}
-+
-+#ifndef       NO_BUSYBOX
-+#include "busybox.h"
-+#endif
-+
-+/**
-+ * Print usage information.
-+ */
-+static void __attribute__ ((noreturn))
-+usage(const char *msg)
-+{
-+      fprintf(stderr, "%s: %s\n", prog, msg);
-+#ifdef        NO_BUSYBOX
-+      fprintf(stderr, "Usage: %s [OPTIONS] ifname script\n"
-+                      "\t-f              foreground mode (implied by -v)\n"
-+                      "\t-q              quit after address (no daemon)\n"
-+                      "\t-r 169.254.x.x  request this address first\n"
-+                      "\t-v              verbose; show version\n",
-+                      prog);
-+      exit(0);
-+#else
-+      bb_show_usage();
-+#endif
-+}
-+
-+/**
-+ * Return milliseconds of random delay, up to "secs" seconds.
-+ */
-+static inline unsigned
-+ms_rdelay(unsigned secs)
-+{
-+      return lrand48() % (secs * 1000);
-+}
-+
-+/**
-+ * main program
-+ */
-+int
-+main(int argc, char *argv[])
-+      __attribute__ ((weak, alias ("zcip_main")));
-+
-+int zcip_main(int argc, char *argv[])
-+{
-+      char *intf = NULL;
-+      char *script = NULL;
-+      int quit = 0;
-+      int foreground = 0;
-+
-+      char *why;
-+      struct sockaddr saddr;
-+      struct ether_addr addr;
-+      struct in_addr ip = { 0 };
-+      int fd;
-+      int ready = 0;
-+      suseconds_t timeout = 0;        // milliseconds
-+      time_t defend = 0;
-+      unsigned conflicts = 0;
-+      unsigned nprobes = 0;
-+      unsigned nclaims = 0;
-+      int t;
-+
-+      // parse commandline: prog [options] ifname script
-+      prog = argv[0];
-+      while ((t = getopt(argc, argv, "fqr:v")) != EOF) {
-+              switch (t) {
-+              case 'f':
-+                      foreground = 1;
-+                      continue;
-+              case 'q':
-+                      quit = 1;
-+                      continue;
-+              case 'r':
-+                      if (inet_aton(optarg, &ip) == 0
-+                                      || (ntohl(ip.s_addr) & IN_CLASSB_NET)
-+                                              != LINKLOCAL_ADDR) {
-+                              usage("invalid link address");
-+                      }
-+                      continue;
-+              case 'v':
-+                      if (!verbose)
-+                              printf("%s: version %s\n", prog, ZCIP_VERSION);
-+                      verbose++;
-+                      foreground = 1;
-+                      continue;
-+              default:
-+                      usage("bad option");
-+              }
-+      }
-+      if (optind < argc - 1) {
-+              intf = argv[optind++];
-+              setenv("interface", intf, 1);
-+              script = argv[optind++];
-+      }
-+      if (optind != argc || !intf)
-+              usage("wrong number of arguments");
-+      openlog(prog, 0, LOG_DAEMON);
-+
-+      // initialize the interface (modprobe, ifup, etc)
-+      if (run(script, "init", intf, NULL) < 0)
-+              return EXIT_FAILURE;
-+
-+      // initialize saddr
-+      memset(&saddr, 0, sizeof (saddr));
-+      strncpy(saddr.sa_data, intf, sizeof (saddr.sa_data));
-+
-+      // open an ARP socket
-+      if ((fd = socket(PF_PACKET, SOCK_PACKET, htons(ETH_P_ARP))) < 0) {
-+              why = "open";
-+fail:
-+              foreground = 1;
-+              goto bad;
-+      }
-+      // bind to the interface's ARP socket
-+      if (bind(fd, &saddr, sizeof (saddr)) < 0) {
-+              why = "bind";
-+              goto fail;
-+      } else {
-+              struct ifreq ifr;
-+              short seed[3];
-+
-+              // get the interface's ethernet address
-+              memset(&ifr, 0, sizeof (ifr));
-+              strncpy(ifr.ifr_name, intf, sizeof (ifr.ifr_name));
-+              if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
-+                      why = "get ethernet address";
-+                      goto fail;
-+              }
-+              memcpy(&addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
-+
-+              // start with some stable ip address, either a function of
-+              // the hardware address or else the last address we used.
-+              // NOTE: the sequence of addresses we try changes only
-+              // depending on when we detect conflicts.
-+              memcpy(seed, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
-+              seed48(seed);
-+              if (ip.s_addr == 0)
-+                      pick(&ip);
-+      }
-+
-+      // FIXME cases to handle:
-+      //  - zcip already running!
-+      //  - link already has local address... just defend/update
-+
-+      // daemonize now; don't delay system startup
-+      if (!foreground) {
-+              if (daemon(0, verbose) < 0) {
-+                      why = "daemon";
-+                      goto bad;
-+              }
-+              syslog(LOG_INFO, "start, interface %s", intf);
-+      }
-+
-+      // run the dynamic address negotiation protocol,
-+      // restarting after address conflicts:
-+      //  - start with some address we want to try
-+      //  - short random delay
-+      //  - arp probes to see if another host else uses it
-+      //  - arp announcements that we're claiming it
-+      //  - use it
-+      //  - defend it, within limits
-+      while (1) {
-+              struct pollfd fds[1];
-+              struct timeval tv1;
-+              struct arp_packet p;
-+
-+              fds[0].fd = fd;
-+              fds[0].events = POLLIN;
-+              fds[0].revents = 0;
-+
-+              // poll, being ready to adjust current timeout 
-+              if (timeout > 0) {
-+                      gettimeofday(&tv1, NULL);
-+                      tv1.tv_usec += (timeout % 1000) * 1000;
-+                      while (tv1.tv_usec > 1000000) {
-+                              tv1.tv_usec -= 1000000;
-+                              tv1.tv_sec++;
-+                      }
-+                      tv1.tv_sec += timeout / 1000;
-+              } else if (timeout == 0) {
-+                      timeout = ms_rdelay(PROBE_WAIT);
-+                      // FIXME setsockopt(fd, SO_ATTACH_FILTER, ...) to
-+                      // make the kernel filter out all packets except
-+                      // ones we'd care about.
-+              }
-+              VDBG("...wait %ld %s nprobes=%d, nclaims=%d\n",
-+                              timeout, intf, nprobes, nclaims);
-+              switch (poll(fds, 1, timeout)) {
-+
-+              // timeouts trigger protocol transitions
-+              case 0:
-+                      // probes
-+                      if (nprobes < PROBE_NUM) {
-+                              nprobes++;
-+                              VDBG("probe/%d %s@%s\n",
-+                                              nprobes, intf, inet_ntoa(ip));
-+                              (void)arp(fd, &saddr, ARPOP_REQUEST,
-+                                              &addr, null_ip,
-+                                              &null_addr, ip);
-+                              if (nprobes < PROBE_NUM) {
-+                                      timeout = PROBE_MIN * 1000;
-+                                      timeout += ms_rdelay(PROBE_MAX
-+                                                      - PROBE_MIN);
-+                              } else
-+                                      timeout = ANNOUNCE_WAIT * 1000;
-+                      }
-+                      // then announcements
-+                      else if (nclaims < ANNOUNCE_NUM) {
-+                              nclaims++;
-+                              VDBG("announce/%d %s@%s\n",
-+                                              nclaims, intf, inet_ntoa(ip));
-+                              (void)arp(fd, &saddr, ARPOP_REQUEST,
-+                                              &addr, ip,
-+                                              &addr, ip);
-+                              if (nclaims < ANNOUNCE_NUM) {
-+                                      timeout = ANNOUNCE_INTERVAL * 1000;
-+                              } else {
-+                                      // link is ok to use earlier
-+                                      run(script, "config", intf, &ip);
-+                                      ready = 1;
-+                                      conflicts = 0;
-+                                      timeout = -1;
-+
-+                                      // NOTE:  all other exit paths
-+                                      // should deconfig ...
-+                                      if (quit)
-+                                              return EXIT_SUCCESS;
-+                                      // FIXME update filters
-+                              }
-+                      }
-+                      break;
-+
-+              // packets arriving
-+              case 1:
-+                      // maybe adjust timeout
-+                      if (timeout > 0) {
-+                              struct timeval tv2;
-+
-+                              gettimeofday(&tv2, NULL);
-+                              if (timercmp(&tv1, &tv2, <)) {
-+                                      timeout = -1;
-+                              } else {
-+                                      timersub(&tv1, &tv2, &tv1);
-+                                      timeout = 1000 * tv1.tv_sec
-+                                                      + tv1.tv_usec / 1000;
-+                              }
-+                      }
-+                      if ((fds[0].revents & POLLIN) == 0) {
-+                              if (fds[0].revents & POLLERR) {
-+                                      // FIXME: links routinely go down;
-+                                      // this shouldn't necessarily exit.
-+                                      fprintf(stderr, "%s %s: poll error\n",
-+                                                      prog, intf);
-+                                      if (ready) {
-+                                              run(script, "deconfig",
-+                                                              intf, &ip);
-+                                      }
-+                                      return EXIT_FAILURE;
-+                              }
-+                              continue;
-+                      }
-+                      // read ARP packet
-+                      if (recv(fd, &p, sizeof (p), 0) < 0) {
-+                              why = "recv";
-+                              goto bad;
-+                      }
-+                      if (p.hdr.ether_type != htons(ETHERTYPE_ARP))
-+                              continue;
-+
-+                      VDBG("%s recv arp type=%d, op=%d,\n",
-+                                      intf, ntohs(p.hdr.ether_type),
-+                                      ntohs(p.arp.ar_op));
-+                      VDBG("\tsource=%s %s\n",
-+                                      ether_ntoa(&p.source_addr),
-+                                      inet_ntoa(p.source_ip));
-+                      VDBG("\ttarget=%s %s\n",
-+                                      ether_ntoa(&p.target_addr),
-+                                      inet_ntoa(p.target_ip));
-+                      if (p.arp.ar_op != htons(ARPOP_REQUEST)
-+                                      && p.arp.ar_op != htons(ARPOP_REPLY))
-+                              continue;
-+
-+                      // some cases are always conflicts 
-+                      if ((p.source_ip.s_addr == ip.s_addr)
-+                                      && (memcmp(&addr, &p.source_addr,
-+                                                      ETH_ALEN) != 0)) {
-+collision:
-+                              VDBG("%s ARP conflict from %s\n", intf,
-+                                              ether_ntoa(&p.source_addr));
-+                              if (ready) {
-+                                      time_t now = time(0);
-+
-+                                      if ((defend + DEFEND_INTERVAL)
-+                                                      < now) {
-+                                              defend = now;
-+                                              (void)arp(fd, &saddr,
-+                                                              ARPOP_REQUEST,
-+                                                              &addr, ip,
-+                                                              &addr, ip);
-+                                              VDBG("%s defend\n", intf);
-+                                              timeout = -1;
-+                                              continue;
-+                                      }
-+                                      defend = now;
-+                                      ready = 0;
-+                                      run(script, "deconfig", intf, &ip);
-+                                      // FIXME rm filters: setsockopt(fd,
-+                                      // SO_DETACH_FILTER, ...)
-+                              }
-+                              conflicts++;
-+                              if (conflicts >= MAX_CONFLICTS) {
-+                                      VDBG("%s ratelimit\n", intf);
-+                                      sleep(RATE_LIMIT_INTERVAL);
-+                              }
-+                              // restart the whole protocol
-+                              pick(&ip);
-+                              timeout = 0;
-+                              nprobes = 0;
-+                              nclaims = 0;
-+                      }
-+                      // two hosts probing one address is a collision too
-+                      else if (p.target_ip.s_addr == ip.s_addr
-+                                      && nclaims == 0
-+                                      && p.arp.ar_op == htons(ARPOP_REQUEST)
-+                                      && memcmp(&addr, &p.target_addr,
-+                                                      ETH_ALEN) != 0) {
-+                              goto collision;
-+                      }
-+                      break;
-+
-+              default:
-+                      why = "poll";
-+                      goto bad;
-+              }
-+      }
-+bad:
-+      if (foreground)
-+              perror(why);
-+      else 
-+              syslog(LOG_ERR, "%s %s, %s error: %s",
-+                      prog, intf, why, strerror(errno));
-+      return EXIT_FAILURE;
-+}
-diff -Nur busybox-1.00/patches/ed.patch busybox/patches/ed.patch
---- busybox-1.00/patches/ed.patch      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/patches/ed.patch   2005-06-04 08:20:03.000000000 +0200
-@@ -0,0 +1,1489 @@
-+Index: editors/Makefile.in
-+===================================================================
-+--- editors/Makefile.in       (revision 10144)
-++++ editors/Makefile.in       (working copy)
-+@@ -24,8 +24,9 @@
-+ srcdir=$(top_srcdir)/editors
-+ 
-+ EDITOR-y:=
-+-EDITOR-$(CONFIG_AWK)    += awk.o
-+-EDITOR-$(CONFIG_PATCH)          += patch.o
-++EDITOR-$(CONFIG_AWK)       += awk.o
-++EDITOR-$(CONFIG_ED)        += ed.o
-++EDITOR-$(CONFIG_PATCH)     += patch.o
-+ EDITOR-$(CONFIG_SED)       += sed.o
-+ EDITOR-$(CONFIG_VI)        += vi.o
-+ EDITOR_SRC:= $(EDITOR-y)
-+Index: editors/Config.in
-+===================================================================
-+--- editors/Config.in (revision 10144)
-++++ editors/Config.in (working copy)
-+@@ -20,6 +20,12 @@
-+        Enable math functions of the Awk programming language.
-+        NOTE: This will require libm to be present for linking.
-+ 
-++config CONFIG_ED
-++     bool "ed"
-++     default n
-++     help
-++       ed
-++
-+ config CONFIG_PATCH
-+      bool "patch"
-+      default n
-+Index: include/usage.h
-+===================================================================
-+--- include/usage.h   (revision 10151)
-++++ include/usage.h   (working copy)
-+@@ -556,6 +561,9 @@
-+      "$ echo \"Erik\\nis\\ncool\"\n" \
-+      "Erik\\nis\\ncool\n")
-+ 
-++#define ed_trivial_usage ""
-++#define ed_full_usage ""
-++
-+ #define env_trivial_usage \
-+      "[-iu] [-] [name=value]... [command]"
-+ #define env_full_usage \
-+Index: include/applets.h
-+===================================================================
-+--- include/applets.h (revision 10151)
-++++ include/applets.h (working copy)
-+@@ -179,6 +179,9 @@
-+ #ifdef CONFIG_ECHO
-+      APPLET(echo, echo_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-+ #endif
-++#ifdef CONFIG_ED
-++     APPLET(ed, ed_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-++#endif
-+ #if defined(CONFIG_FEATURE_GREP_EGREP_ALIAS)
-+      APPLET_NOUSAGE("egrep", grep_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-+ #endif
-+--- /dev/null 2005-04-24 01:00:01.350003056 -0400
-++++ ed.c      2005-04-24 01:38:51.000000000 -0400
-+@@ -0,0 +1,1425 @@
-++/*
-++ * Copyright (c) 2002 by David I. Bell
-++ * Permission is granted to use, distribute, or modify this source,
-++ * provided that this copyright notice remains intact.
-++ *
-++ * The "ed" built-in command (much simplified)
-++ */
-++
-++#include <stdio.h>
-++#include <stdlib.h>
-++#include <unistd.h>
-++#include <fcntl.h>
-++#include <string.h>
-++#include <memory.h>
-++#include <time.h>
-++#include <ctype.h>
-++#include <sys/param.h>
-++#include <malloc.h>
-++#include "busybox.h"
-++
-++#define      USERSIZE        1024    /* max line length typed in by user */
-++#define      INITBUF_SIZE    1024    /* initial buffer size */
-++
-++typedef      int     BOOL;
-++typedef      int     NUM;
-++typedef      int     LEN;
-++
-++typedef struct LINE LINE;
-++struct LINE {
-++     LINE *next;
-++     LINE *prev;
-++     LEN     len;
-++     char data[1];
-++};
-++
-++static LINE lines;
-++static LINE *curLine;
-++static NUM curNum;
-++static NUM lastNum;
-++static NUM marks[26];
-++static BOOL dirty;
-++static char *fileName;
-++static char searchString[USERSIZE];
-++
-++static char *bufBase;
-++static char *bufPtr;
-++static LEN bufUsed;
-++static LEN bufSize;
-++
-++static       void    doCommands(void);
-++static       void    subCommand(const char * cmd, NUM num1, NUM num2);
-++static       BOOL    getNum(const char ** retcp, BOOL * retHaveNum, NUM * retNum);
-++static       BOOL    setCurNum(NUM num);
-++static       BOOL    initEdit(void);
-++static       void    termEdit(void);
-++static       void    addLines(NUM num);
-++static       BOOL    insertLine(NUM num, const char * data, LEN len);
-++static       BOOL    deleteLines(NUM num1, NUM num2);
-++static       BOOL    printLines(NUM num1, NUM num2, BOOL expandFlag);
-++static       BOOL    writeLines(const char * file, NUM num1, NUM num2);
-++static       BOOL    readLines(const char * file, NUM num);
-++static       NUM     searchLines(const char * str, NUM num1, NUM num2);
-++static       LINE *  findLine(NUM num);
-++
-++static LEN findString(const LINE * lp, const char * str, LEN len, LEN offset);
-++
-++int ed_main(int argc, char **argv)
-++{
-++     if (!initEdit())
-++             return EXIT_FAILURE;
-++
-++     if (argc > 1) {
-++             fileName = strdup(argv[1]);
-++
-++             if (fileName == NULL) {
-++                     bb_error_msg("No memory");
-++                     termEdit();
-++                     return EXIT_SUCCESS;
-++             }
-++
-++             if (!readLines(fileName, 1)) {
-++                     termEdit();
-++                     return EXIT_SUCCESS;
-++             }
-++
-++             if (lastNum)
-++                     setCurNum(1);
-++
-++             dirty = FALSE;
-++     }
-++
-++     doCommands();
-++
-++     termEdit();
-++     return EXIT_SUCCESS;
-++}
-++
-++/*
-++ * Read commands until we are told to stop.
-++ */
-++static void doCommands(void)
-++{
-++     const char *    cp;
-++     char *          endbuf;
-++     char *          newname;
-++     int             len;
-++     NUM             num1;
-++     NUM             num2;
-++     BOOL            have1;
-++     BOOL            have2;
-++     char            buf[USERSIZE];
-++
-++     while (TRUE)
-++     {
-++             printf(": ");
-++             fflush(stdout);
-++
-++             if (fgets(buf, sizeof(buf), stdin) == NULL)
-++                     return;
-++
-++             len = strlen(buf);
-++
-++             if (len == 0)
-++                     return;
-++
-++             endbuf = &buf[len - 1];
-++
-++             if (*endbuf != '\n')
-++             {
-++                     bb_error_msg("Command line too long");
-++
-++                     do
-++                     {
-++                             len = fgetc(stdin);
-++                     }
-++                     while ((len != EOF) && (len != '\n'));
-++
-++                     continue;
-++             }
-++
-++             while ((endbuf > buf) && isblank(endbuf[-1]))
-++                     endbuf--;
-++
-++             *endbuf = '\0';
-++
-++             cp = buf;
-++
-++             while (isblank(*cp))
-++                     cp++;
-++
-++             have1 = FALSE;
-++             have2 = FALSE;
-++
-++             if ((curNum == 0) && (lastNum > 0))
-++             {
-++                     curNum = 1;
-++                     curLine = lines.next;
-++             }
-++
-++             if (!getNum(&cp, &have1, &num1))
-++                     continue;
-++
-++             while (isblank(*cp))
-++                     cp++;
-++
-++             if (*cp == ',')
-++             {
-++                     cp++;
-++
-++                     if (!getNum(&cp, &have2, &num2))
-++                             continue;
-++
-++                     if (!have1)
-++                             num1 = 1;
-++
-++                     if (!have2)
-++                             num2 = lastNum;
-++
-++                     have1 = TRUE;
-++                     have2 = TRUE;
-++             }
-++
-++             if (!have1)
-++                     num1 = curNum;
-++
-++             if (!have2)
-++                     num2 = num1;
-++
-++             switch (*cp++)
-++             {
-++                     case 'a':
-++                             addLines(num1 + 1);
-++                             break;
-++
-++                     case 'c':
-++                             deleteLines(num1, num2);
-++                             addLines(num1);
-++                             break;
-++
-++                     case 'd':
-++                             deleteLines(num1, num2);
-++                             break;
-++
-++                     case 'f':
-++                             if (*cp && !isblank(*cp))
-++                             {
-++                                     bb_error_msg("Bad file command");
-++                                     break;
-++                             }
-++
-++                             while (isblank(*cp))
-++                                     cp++;
-++
-++                             if (*cp == '\0')
-++                             {
-++                                     if (fileName)
-++                                             printf("\"%s\"\n", fileName);
-++                                     else
-++                                             printf("No file name\n");
-++
-++                                     break;
-++                             }
-++
-++                             newname = strdup(cp);
-++
-++                             if (newname == NULL)
-++                             {
-++                                     bb_error_msg("No memory for file name");
-++                                     break;
-++                             }
-++
-++                             if (fileName)
-++                                     free(fileName);
-++
-++                             fileName = newname;
-++                             break;
-++
-++                     case 'i':
-++                             addLines(num1);
-++                             break;
-++
-++                     case 'k':
-++                             while (isblank(*cp))
-++                                     cp++;
-++
-++                             if ((*cp < 'a') || (*cp > 'a') || cp[1])
-++                             {
-++                                     bb_error_msg("Bad mark name");
-++                                     break;
-++                             }
-++
-++                             marks[*cp - 'a'] = num2;
-++                             break;
-++
-++                     case 'l':
-++                             printLines(num1, num2, TRUE);
-++                             break;
-++
-++                     case 'p':
-++                             printLines(num1, num2, FALSE);
-++                             break;
-++
-++                     case 'q':
-++                             while (isblank(*cp))
-++                                     cp++;
-++
-++                             if (have1 || *cp)
-++                             {
-++                                     bb_error_msg("Bad quit command");
-++                                     break;
-++                             }
-++
-++                             if (!dirty)
-++                                     return;
-++
-++                             printf("Really quit? ");
-++                             fflush(stdout);
-++
-++                             buf[0] = '\0';
-++                             fgets(buf, sizeof(buf), stdin);
-++                             cp = buf;
-++
-++                             while (isblank(*cp))
-++                                     cp++;
-++
-++                             if ((*cp == 'y') || (*cp == 'Y'))
-++                                     return;
-++
-++                             break;
-++
-++                     case 'r':
-++                             if (*cp && !isblank(*cp))
-++                             {
-++                                     bb_error_msg("Bad read command");
-++                                     break;
-++                             }
-++
-++                             while (isblank(*cp))
-++                                     cp++;
-++
-++                             if (*cp == '\0')
-++                             {
-++                                     bb_error_msg("No file name");
-++                                     break;
-++                             }
-++
-++                             if (!have1)
-++                                     num1 = lastNum;
-++
-++                             if (readLines(cp, num1 + 1))
-++                                     break;
-++
-++                             if (fileName == NULL)
-++                                     fileName = strdup(cp);
-++
-++                             break;
-++
-++                     case 's':
-++                             subCommand(cp, num1, num2);
-++                             break;
-++
-++                     case 'w':
-++                             if (*cp && !isblank(*cp))
-++                             {
-++                                     bb_error_msg("Bad write command");
-++                                     break;
-++                             }
-++
-++                             while (isblank(*cp))
-++                                     cp++;
-++
-++                             if (!have1) {
-++                                     num1 = 1;
-++                                     num2 = lastNum;
-++                             }
-++
-++                             if (*cp == '\0')
-++                                     cp = fileName;
-++
-++                             if (cp == NULL)
-++                             {
-++                                     bb_error_msg("No file name specified");
-++                                     break;
-++                             }
-++     
-++                             writeLines(cp, num1, num2);
-++                             break;
-++
-++                     case 'z':
-++                             switch (*cp)
-++                             {
-++                             case '-':
-++                                     printLines(curNum-21, curNum, FALSE);
-++                                     break;
-++                             case '.':
-++                                     printLines(curNum-11, curNum+10, FALSE);
-++                                     break;
-++                             default:
-++                                     printLines(curNum, curNum+21, FALSE);
-++                                     break;
-++                             }
-++                             break;
-++
-++                     case '.':
-++                             if (have1)
-++                             {
-++                                     bb_error_msg("No arguments allowed");
-++                                     break;
-++                             }
-++
-++                             printLines(curNum, curNum, FALSE);
-++                             break;
-++     
-++                     case '-':
-++                             if (setCurNum(curNum - 1))
-++                                     printLines(curNum, curNum, FALSE);
-++
-++                             break;
-++
-++                     case '=':
-++                             printf("%d\n", num1);
-++                             break;
-++
-++                     case '\0':
-++                             if (have1)
-++                             {
-++                                     printLines(num2, num2, FALSE);
-++                                     break;
-++                             }
-++
-++                             if (setCurNum(curNum + 1))
-++                                     printLines(curNum, curNum, FALSE);
-++
-++                             break;
-++
-++                     default:
-++                             bb_error_msg("Unimplemented command");
-++                             break;
-++             }
-++     }
-++}
-++
-++
-++/*
-++ * Do the substitute command.
-++ * The current line is set to the last substitution done.
-++ */
-++static void
-++subCommand(const char * cmd, NUM num1, NUM num2)
-++{
-++     int     delim;
-++     char *  cp;
-++     char *  oldStr;
-++     char *  newStr;
-++     LEN     oldLen;
-++     LEN     newLen;
-++     LEN     deltaLen;
-++     LEN     offset;
-++     LINE *  lp;
-++     LINE *  nlp;
-++     BOOL    globalFlag;
-++     BOOL    printFlag;
-++     BOOL    didSub;
-++     BOOL    needPrint;
-++     char    buf[USERSIZE];
-++
-++     if ((num1 < 1) || (num2 > lastNum) || (num1 > num2))
-++     {
-++             bb_error_msg("Bad line range for substitute");
-++
-++             return;
-++     }
-++
-++     globalFlag = FALSE;
-++     printFlag = FALSE;
-++     didSub = FALSE;
-++     needPrint = FALSE;
-++
-++     /*
-++      * Copy the command so we can modify it.
-++      */
-++     strcpy(buf, cmd);
-++     cp = buf;
-++
-++     if (isblank(*cp) || (*cp == '\0'))
-++     {
-++             bb_error_msg("Bad delimiter for substitute");
-++
-++             return;
-++     }
-++
-++     delim = *cp++;
-++     oldStr = cp;
-++
-++     cp = strchr(cp, delim);
-++
-++     if (cp == NULL)
-++     {
-++             bb_error_msg("Missing 2nd delimiter for substitute");
-++
-++             return;
-++     }
-++
-++     *cp++ = '\0';
-++
-++     newStr = cp;
-++     cp = strchr(cp, delim);
-++
-++     if (cp)
-++             *cp++ = '\0';
-++     else
-++             cp = "";
-++
-++     while (*cp) switch (*cp++)
-++     {
-++             case 'g':
-++                     globalFlag = TRUE;
-++                     break;
-++
-++             case 'p':
-++                     printFlag = TRUE;
-++                     break;
-++
-++             default:
-++                     bb_error_msg("Unknown option for substitute");
-++
-++                     return;
-++     }
-++
-++     if (*oldStr == '\0')
-++     {
-++             if (searchString[0] == '\0')
-++             {
-++                     bb_error_msg("No previous search string");
-++
-++                     return;
-++             }
-++
-++             oldStr = searchString;
-++     }
-++
-++     if (oldStr != searchString)
-++             strcpy(searchString, oldStr);
-++
-++     lp = findLine(num1);
-++
-++     if (lp == NULL)
-++             return;
-++
-++     oldLen = strlen(oldStr);
-++     newLen = strlen(newStr);
-++     deltaLen = newLen - oldLen;
-++     offset = 0;
-++     nlp = NULL;
-++
-++     while (num1 <= num2)
-++     {
-++             offset = findString(lp, oldStr, oldLen, offset);
-++
-++             if (offset < 0)
-++             {
-++                     if (needPrint)
-++                     {
-++                             printLines(num1, num1, FALSE);
-++                             needPrint = FALSE;
-++                     }
-++
-++                     offset = 0;
-++                     lp = lp->next;
-++                     num1++;
-++
-++                     continue;
-++             }
-++
-++             needPrint = printFlag;
-++             didSub = TRUE;
-++             dirty = TRUE;
-++
-++             /*
-++              * If the replacement string is the same size or shorter
-++              * than the old string, then the substitution is easy.
-++              */
-++             if (deltaLen <= 0)
-++             {
-++                     memcpy(&lp->data[offset], newStr, newLen);
-++
-++                     if (deltaLen)
-++                     {
-++                             memcpy(&lp->data[offset + newLen],
-++                                     &lp->data[offset + oldLen],
-++                                     lp->len - offset - oldLen);
-++
-++                             lp->len += deltaLen;
-++                     }
-++
-++                     offset += newLen;
-++
-++                     if (globalFlag)
-++                             continue;
-++
-++                     if (needPrint)
-++                     {
-++                             printLines(num1, num1, FALSE);
-++                             needPrint = FALSE;
-++                     }
-++
-++                     lp = lp->next;
-++                     num1++;
-++
-++                     continue;
-++             }
-++
-++             /*
-++              * The new string is larger, so allocate a new line
-++              * structure and use that.  Link it in in place of
-++              * the old line structure.
-++              */
-++             nlp = (LINE *) malloc(sizeof(LINE) + lp->len + deltaLen);
-++
-++             if (nlp == NULL)
-++             {
-++                     bb_error_msg("Cannot get memory for line");
-++
-++                     return;
-++             }
-++
-++             nlp->len = lp->len + deltaLen;
-++
-++             memcpy(nlp->data, lp->data, offset);
-++
-++             memcpy(&nlp->data[offset], newStr, newLen);
-++
-++             memcpy(&nlp->data[offset + newLen],
-++                     &lp->data[offset + oldLen],
-++                     lp->len - offset - oldLen);
-++
-++             nlp->next = lp->next;
-++             nlp->prev = lp->prev;
-++             nlp->prev->next = nlp;
-++             nlp->next->prev = nlp;
-++
-++             if (curLine == lp)
-++                     curLine = nlp;
-++
-++             free(lp);
-++             lp = nlp;
-++
-++             offset += newLen;
-++
-++             if (globalFlag)
-++                     continue;
-++
-++             if (needPrint)
-++             {
-++                     printLines(num1, num1, FALSE);
-++                     needPrint = FALSE;
-++             }
-++
-++             lp = lp->next;
-++             num1++;
-++     }
-++
-++     if (!didSub)
-++             bb_error_msg("No substitutions found for \"%s\"", oldStr);
-++}
-++
-++
-++/*
-++ * Search a line for the specified string starting at the specified
-++ * offset in the line.  Returns the offset of the found string, or -1.
-++ */
-++static LEN
-++findString( const LINE * lp, const char * str, LEN len, LEN offset)
-++{
-++     LEN             left;
-++     const char *    cp;
-++     const char *    ncp;
-++
-++     cp = &lp->data[offset];
-++     left = lp->len - offset;
-++
-++     while (left >= len)
-++     {
-++             ncp = memchr(cp, *str, left);
-++
-++             if (ncp == NULL)
-++                     return -1;
-++
-++             left -= (ncp - cp);
-++
-++             if (left < len)
-++                     return -1;
-++
-++             cp = ncp;
-++
-++             if (memcmp(cp, str, len) == 0)
-++                     return (cp - lp->data);
-++
-++             cp++;
-++             left--;
-++     }
-++
-++     return -1;
-++}
-++
-++
-++/*
-++ * Add lines which are typed in by the user.
-++ * The lines are inserted just before the specified line number.
-++ * The lines are terminated by a line containing a single dot (ugly!),
-++ * or by an end of file.
-++ */
-++static void
-++addLines(NUM num)
-++{
-++     int     len;
-++     char    buf[USERSIZE + 1];
-++
-++     while (fgets(buf, sizeof(buf), stdin))
-++     {
-++             if ((buf[0] == '.') && (buf[1] == '\n') && (buf[2] == '\0'))
-++                     return;
-++
-++             len = strlen(buf);
-++
-++             if (len == 0)
-++                     return;
-++
-++             if (buf[len - 1] != '\n')
-++             {
-++                     bb_error_msg("Line too long");
-++
-++                     do
-++                     {
-++                             len = fgetc(stdin);
-++                     }
-++                     while ((len != EOF) && (len != '\n'));
-++
-++                     return;
-++             }
-++
-++             if (!insertLine(num++, buf, len))
-++                     return;
-++     }
-++}
-++
-++
-++/*
-++ * Parse a line number argument if it is present.  This is a sum
-++ * or difference of numbers, '.', '$', 'x, or a search string.
-++ * Returns TRUE if successful (whether or not there was a number). 
-++ * Returns FALSE if there was a parsing error, with a message output.
-++ * Whether there was a number is returned indirectly, as is the number.
-++ * The character pointer which stopped the scan is also returned.
-++ */
-++static BOOL
-++getNum(const char ** retcp, BOOL * retHaveNum, NUM * retNum)
-++{
-++     const char *    cp;
-++     char *          endStr;
-++     char            str[USERSIZE];
-++     BOOL            haveNum;
-++     NUM             value;
-++     NUM             num;
-++     NUM             sign;
-++
-++     cp = *retcp;
-++     haveNum = FALSE;
-++     value = 0;
-++     sign = 1;
-++
-++     while (TRUE)
-++     {
-++             while (isblank(*cp))
-++                     cp++;
-++
-++             switch (*cp)
-++             {
-++                     case '.':
-++                             haveNum = TRUE;
-++                             num = curNum;
-++                             cp++;
-++                             break;
-++
-++                     case '$':
-++                             haveNum = TRUE;
-++                             num = lastNum;
-++                             cp++;
-++                             break;
-++
-++                     case '\'':
-++                             cp++;
-++
-++                             if ((*cp < 'a') || (*cp > 'z'))
-++                             {
-++                                     bb_error_msg("Bad mark name");
-++
-++                                     return FALSE;
-++                             }
-++
-++                             haveNum = TRUE;
-++                             num = marks[*cp++ - 'a'];
-++                             break;
-++
-++                     case '/':
-++                             strcpy(str, ++cp);
-++                             endStr = strchr(str, '/');
-++
-++                             if (endStr)
-++                             {
-++                                     *endStr++ = '\0';
-++                                     cp += (endStr - str);
-++                             }
-++                             else
-++                                     cp = "";
-++
-++                             num = searchLines(str, curNum, lastNum);
-++
-++                             if (num == 0)
-++                                     return FALSE;
-++
-++                             haveNum = TRUE;
-++                             break;
-++
-++                     default:
-++                             if (!isdigit(*cp))
-++                             {
-++                                     *retcp = cp;
-++                                     *retHaveNum = haveNum;
-++                                     *retNum = value;
-++
-++                                     return TRUE;
-++                             }
-++
-++                             num = 0;
-++
-++                             while (isdigit(*cp))
-++                                     num = num * 10 + *cp++ - '0';
-++
-++                             haveNum = TRUE;
-++                             break;
-++             }
-++
-++             value += num * sign;
-++
-++             while (isblank(*cp))
-++                     cp++;
-++
-++             switch (*cp)
-++             {
-++                     case '-':
-++                             sign = -1;
-++                             cp++;
-++                             break;
-++
-++                     case '+':
-++                             sign = 1;
-++                             cp++;
-++                             break;
-++
-++                     default:
-++                             *retcp = cp;
-++                             *retHaveNum = haveNum;
-++                             *retNum = value;
-++
-++                             return TRUE;
-++             }
-++     }
-++}
-++
-++
-++/*
-++ * Initialize everything for editing.
-++ */
-++static BOOL
-++initEdit(void)
-++{
-++     int     i;
-++
-++     bufSize = INITBUF_SIZE;
-++     bufBase = malloc(bufSize);
-++
-++     if (bufBase == NULL)
-++     {
-++             bb_error_msg("No memory for buffer");
-++
-++             return FALSE;
-++     }
-++
-++     bufPtr = bufBase;
-++     bufUsed = 0;
-++
-++     lines.next = &lines;
-++     lines.prev = &lines;
-++
-++     curLine = NULL;
-++     curNum = 0;
-++     lastNum = 0;
-++     dirty = FALSE;
-++     fileName = NULL;
-++     searchString[0] = '\0';
-++
-++     for (i = 0; i < 26; i++)
-++             marks[i] = 0;
-++
-++     return TRUE;
-++}
-++
-++
-++/*
-++ * Finish editing.
-++ */
-++static void
-++termEdit(void)
-++{
-++     if (bufBase)
-++             free(bufBase);
-++
-++     bufBase = NULL;
-++     bufPtr = NULL;
-++     bufSize = 0;
-++     bufUsed = 0;
-++
-++     if (fileName)
-++             free(fileName);
-++
-++     fileName = NULL;
-++
-++     searchString[0] = '\0';
-++
-++     if (lastNum)
-++             deleteLines(1, lastNum);
-++
-++     lastNum = 0;
-++     curNum = 0;
-++     curLine = NULL;
-++}
-++
-++
-++/*
-++ * Read lines from a file at the specified line number.
-++ * Returns TRUE if the file was successfully read.
-++ */
-++static BOOL
-++readLines(const char * file, NUM num)
-++{
-++     int     fd;
-++     int     cc;
-++     LEN     len;
-++     LEN     lineCount;
-++     LEN     charCount;
-++     char *  cp;
-++
-++     if ((num < 1) || (num > lastNum + 1))
-++     {
-++             bb_error_msg("Bad line for read");
-++
-++             return FALSE;
-++     }
-++
-++     fd = open(file, 0);
-++
-++     if (fd < 0)
-++     {
-++             perror(file);
-++
-++             return FALSE;
-++     }
-++
-++     bufPtr = bufBase;
-++     bufUsed = 0;
-++     lineCount = 0;
-++     charCount = 0;
-++     cc = 0;
-++
-++     printf("\"%s\", ", file);
-++     fflush(stdout);
-++
-++     do
-++     {
-++             cp = memchr(bufPtr, '\n', bufUsed);
-++
-++             if (cp)
-++             {
-++                     len = (cp - bufPtr) + 1;
-++
-++                     if (!insertLine(num, bufPtr, len))
-++                     {
-++                             close(fd);
-++
-++                             return FALSE;
-++                     }
-++
-++                     bufPtr += len;
-++                     bufUsed -= len;
-++                     charCount += len;
-++                     lineCount++;
-++                     num++;
-++
-++                     continue;
-++             }
-++
-++             if (bufPtr != bufBase)
-++             {
-++                     memcpy(bufBase, bufPtr, bufUsed);
-++                     bufPtr = bufBase + bufUsed;
-++             }
-++
-++             if (bufUsed >= bufSize)
-++             {
-++                     len = (bufSize * 3) / 2;
-++                     cp = realloc(bufBase, len);
-++
-++                     if (cp == NULL)
-++                     {
-++                             bb_error_msg("No memory for buffer");
-++                             close(fd);
-++
-++                             return FALSE;
-++                     }
-++
-++                     bufBase = cp;
-++                     bufPtr = bufBase + bufUsed;
-++                     bufSize = len;
-++             }
-++
-++             cc = read(fd, bufPtr, bufSize - bufUsed);
-++             bufUsed += cc;
-++             bufPtr = bufBase;
-++
-++     }
-++     while (cc > 0);
-++
-++     if (cc < 0)
-++     {
-++             perror(file);
-++             close(fd);
-++
-++             return FALSE;
-++     }
-++
-++     if (bufUsed)
-++     {
-++             if (!insertLine(num, bufPtr, bufUsed))
-++             {
-++                     close(fd);
-++
-++                     return -1;
-++             }
-++
-++             lineCount++;
-++             charCount += bufUsed;
-++     }
-++
-++     close(fd);
-++
-++     printf("%d lines%s, %d chars\n", lineCount,
-++             (bufUsed ? " (incomplete)" : ""), charCount);
-++
-++     return TRUE;
-++}
-++
-++
-++/*
-++ * Write the specified lines out to the specified file.
-++ * Returns TRUE if successful, or FALSE on an error with a message output.
-++ */
-++static BOOL
-++writeLines(const char * file, NUM num1, NUM num2)
-++{
-++     int     fd;
-++     LINE *  lp;
-++     LEN     lineCount;
-++     LEN     charCount;
-++
-++     if ((num1 < 1) || (num2 > lastNum) || (num1 > num2))
-++     {
-++             bb_error_msg("Bad line range for write");
-++
-++             return FALSE;
-++     }
-++
-++     lineCount = 0;
-++     charCount = 0;
-++
-++     fd = creat(file, 0666);
-++
-++     if (fd < 0) {
-++             perror(file);
-++
-++             return FALSE;
-++     }
-++
-++     printf("\"%s\", ", file);
-++     fflush(stdout);
-++
-++     lp = findLine(num1);
-++
-++     if (lp == NULL)
-++     {
-++             close(fd);
-++
-++             return FALSE;
-++     }
-++
-++     while (num1++ <= num2)
-++     {
-++             if (write(fd, lp->data, lp->len) != lp->len)
-++             {
-++                     perror(file);
-++                     close(fd);
-++
-++                     return FALSE;
-++             }
-++
-++             charCount += lp->len;
-++             lineCount++;
-++             lp = lp->next;
-++     }
-++
-++     if (close(fd) < 0)
-++     {
-++             perror(file);
-++
-++             return FALSE;
-++     }
-++
-++     printf("%d lines, %d chars\n", lineCount, charCount);
-++
-++     return TRUE;
-++}
-++
-++
-++/*
-++ * Print lines in a specified range.
-++ * The last line printed becomes the current line.
-++ * If expandFlag is TRUE, then the line is printed specially to
-++ * show magic characters.
-++ */
-++static BOOL
-++printLines(NUM num1, NUM num2, BOOL expandFlag)
-++{
-++     const LINE *            lp;
-++     const unsigned char *   cp;
-++     int                     ch;
-++     LEN                     count;
-++
-++     if ((num1 < 1) || (num2 > lastNum) || (num1 > num2))
-++     {
-++             bb_error_msg("Bad line range for print");
-++
-++             return FALSE;
-++     }
-++
-++     lp = findLine(num1);
-++
-++     if (lp == NULL)
-++             return FALSE;
-++
-++     while (num1 <= num2)
-++     {
-++             if (!expandFlag)
-++             {
-++                     write(1, lp->data, lp->len);
-++                     setCurNum(num1++);
-++                     lp = lp->next;
-++
-++                     continue;
-++             }
-++
-++             /*
-++              * Show control characters and characters with the
-++              * high bit set specially.
-++              */
-++             cp = lp->data;
-++             count = lp->len;
-++
-++             if ((count > 0) && (cp[count - 1] == '\n'))
-++                     count--;
-++
-++             while (count-- > 0)
-++             {
-++                     ch = *cp++;
-++
-++                     if (ch & 0x80)
-++                     {
-++                             fputs("M-", stdout);
-++                             ch &= 0x7f;
-++                     }
-++
-++                     if (ch < ' ')
-++                     {
-++                             fputc('^', stdout);
-++                             ch += '@';
-++                     }
-++
-++                     if (ch == 0x7f)
-++                     {
-++                             fputc('^', stdout);
-++                             ch = '?';
-++                     }
-++
-++                     fputc(ch, stdout);
-++             }
-++
-++             fputs("$\n", stdout);
-++
-++             setCurNum(num1++);
-++             lp = lp->next;
-++     }
-++
-++     return TRUE;
-++}
-++
-++
-++/*
-++ * Insert a new line with the specified text.
-++ * The line is inserted so as to become the specified line,
-++ * thus pushing any existing and further lines down one.
-++ * The inserted line is also set to become the current line.
-++ * Returns TRUE if successful.
-++ */
-++static BOOL
-++insertLine(NUM num, const char * data, LEN len)
-++{
-++     LINE *  newLp;
-++     LINE *  lp;
-++
-++     if ((num < 1) || (num > lastNum + 1))
-++     {
-++             bb_error_msg("Inserting at bad line number");
-++
-++             return FALSE;
-++     }
-++
-++     newLp = (LINE *) malloc(sizeof(LINE) + len - 1);
-++
-++     if (newLp == NULL) 
-++     {
-++             bb_error_msg("Failed to allocate memory for line");
-++
-++             return FALSE;
-++     }
-++
-++     memcpy(newLp->data, data, len);
-++     newLp->len = len;
-++
-++     if (num > lastNum)
-++             lp = &lines;
-++     else
-++     {
-++             lp = findLine(num);
-++
-++             if (lp == NULL)
-++             {
-++                     free((char *) newLp);
-++
-++                     return FALSE;
-++             }
-++     }
-++
-++     newLp->next = lp;
-++     newLp->prev = lp->prev;
-++     lp->prev->next = newLp;
-++     lp->prev = newLp;
-++
-++     lastNum++;
-++     dirty = TRUE;
-++
-++     return setCurNum(num);
-++}
-++
-++
-++/*
-++ * Delete lines from the given range.
-++ */
-++static BOOL
-++deleteLines(NUM num1, NUM num2)
-++{
-++     LINE *  lp;
-++     LINE *  nlp;
-++     LINE *  plp;
-++     NUM     count;
-++
-++     if ((num1 < 1) || (num2 > lastNum) || (num1 > num2))
-++     {
-++             bb_error_msg("Bad line numbers for delete");
-++
-++             return FALSE;
-++     }
-++
-++     lp = findLine(num1);
-++
-++     if (lp == NULL)
-++             return FALSE;
-++
-++     if ((curNum >= num1) && (curNum <= num2))
-++     {
-++             if (num2 < lastNum)
-++                     setCurNum(num2 + 1);
-++             else if (num1 > 1)
-++                     setCurNum(num1 - 1);
-++             else
-++                     curNum = 0;
-++     }
-++
-++     count = num2 - num1 + 1;
-++
-++     if (curNum > num2)
-++             curNum -= count;
-++
-++     lastNum -= count;
-++
-++     while (count-- > 0)
-++     {
-++             nlp = lp->next;
-++             plp = lp->prev;
-++             plp->next = nlp;
-++             nlp->prev = plp;
-++             lp->next = NULL;
-++             lp->prev = NULL;
-++             lp->len = 0;
-++             free(lp);
-++             lp = nlp;
-++     }
-++
-++     dirty = TRUE;
-++
-++     return TRUE;
-++}
-++
-++
-++/*
-++ * Search for a line which contains the specified string.
-++ * If the string is NULL, then the previously searched for string
-++ * is used.  The currently searched for string is saved for future use.
-++ * Returns the line number which matches, or 0 if there was no match
-++ * with an error printed.
-++ */
-++static NUM
-++searchLines(const char * str, NUM num1, NUM num2)
-++{
-++     const LINE *    lp;
-++     int             len;
-++
-++     if ((num1 < 1) || (num2 > lastNum) || (num1 > num2))
-++     {
-++             bb_error_msg("Bad line numbers for search");
-++
-++             return 0;
-++     }
-++
-++     if (*str == '\0')
-++     {
-++             if (searchString[0] == '\0')
-++             {
-++                     bb_error_msg("No previous search string");
-++
-++                     return 0;
-++             }
-++
-++             str = searchString;
-++     }
-++
-++     if (str != searchString)
-++             strcpy(searchString, str);
-++
-++     len = strlen(str);
-++
-++     lp = findLine(num1);
-++
-++     if (lp == NULL)
-++             return 0;
-++
-++     while (num1 <= num2)
-++     {
-++             if (findString(lp, str, len, 0) >= 0)
-++                     return num1;
-++
-++             num1++;
-++             lp = lp->next;
-++     }
-++
-++     bb_error_msg("Cannot find string \"%s\"", str);
-++
-++     return 0;
-++}
-++
-++
-++/*
-++ * Return a pointer to the specified line number.
-++ */
-++static LINE *
-++findLine(NUM num)
-++{
-++     LINE *  lp;
-++     NUM     lnum;
-++
-++     if ((num < 1) || (num > lastNum))
-++     {
-++             bb_error_msg("Line number %d does not exist", num);
-++
-++             return NULL;
-++     }
-++
-++     if (curNum <= 0)
-++     {
-++             curNum = 1;
-++             curLine = lines.next;
-++     }
-++
-++     if (num == curNum)
-++             return curLine;
-++
-++     lp = curLine;
-++     lnum = curNum;
-++
-++     if (num < (curNum / 2))
-++     {
-++             lp = lines.next;
-++             lnum = 1;
-++     }
-++     else if (num > ((curNum + lastNum) / 2))
-++     {
-++             lp = lines.prev;
-++             lnum = lastNum;
-++     }
-++
-++     while (lnum < num)
-++     {
-++             lp = lp->next;
-++             lnum++;
-++     }
-++
-++     while (lnum > num)
-++     {
-++             lp = lp->prev;
-++             lnum--;
-++     }
-++
-++     return lp;
-++}
-++
-++
-++/*
-++ * Set the current line number.
-++ * Returns TRUE if successful.
-++ */
-++static BOOL
-++setCurNum(NUM num)
-++{
-++     LINE *  lp;
-++
-++     lp = findLine(num);
-++
-++     if (lp == NULL)
-++             return FALSE;
-++
-++     curNum = num;
-++     curLine = lp;
-++
-++     return TRUE;
-++}
-++
-++/* END CODE */
-diff -Nur busybox-1.00/patches/eject.diff busybox/patches/eject.diff
---- busybox-1.00/patches/eject.diff    2004-03-15 09:29:02.000000000 +0100
-+++ busybox/patches/eject.diff 1970-01-01 01:00:00.000000000 +0100
-@@ -1,164 +0,0 @@
--Index: AUTHORS
--===================================================================
--RCS file: /var/cvs/busybox/AUTHORS,v
--retrieving revision 1.40
--diff -u -r1.40 AUTHORS
----- a/AUTHORS 9 Oct 2003 21:19:21 -0000       1.40
--+++ b/AUTHORS 5 Mar 2004 07:23:17 -0000
--@@ -8,6 +8,9 @@
--
-- -----------
--
--+Peter Willis <psyphreak@phreaker.net>
--+    eject
--+
-- Emanuele Aina <emanuele.aina@tiscali.it>
--      run-parts
--
--Index: coreutils/Config.in
--===================================================================
--RCS file: /var/cvs/busybox/coreutils/Config.in,v
--retrieving revision 1.23
--diff -u -r1.23 Config.in
----- a/coreutils/Config.in     5 Mar 2004 06:47:25 -0000       1.23
--+++ b/coreutils/Config.in     5 Mar 2004 07:23:18 -0000
--@@ -164,6 +164,13 @@
--        a command; without options it displays the current
--        environment.
--
--+config CONFIG_EJECT
--+     bool "eject"
--+     default n
--+     help
--+       ejects a cdrom drive.
--+       defaults to /dev/cdrom
--+
-- config CONFIG_EXPR
--      bool "expr"
--      default n
--Index: coreutils/Makefile.in
--===================================================================
--RCS file: /var/cvs/busybox/coreutils/Makefile.in,v
--retrieving revision 1.8
--diff -u -r1.8 Makefile.in
----- a/coreutils/Makefile.in   27 Jan 2004 09:22:20 -0000      1.8
--+++ b/coreutils/Makefile.in   5 Mar 2004 07:23:18 -0000
--@@ -41,6 +41,7 @@
-- COREUTILS-$(CONFIG_DU)       += du.o
-- COREUTILS-$(CONFIG_ECHO)     += echo.o
-- COREUTILS-$(CONFIG_ENV)      += env.o
--+COREUTILS-$(CONFIG_EJECT)            += eject.o
-- COREUTILS-$(CONFIG_EXPR)     += expr.o
-- COREUTILS-$(CONFIG_FALSE)    += false.o
-- COREUTILS-$(CONFIG_FOLD)     += fold.o
--Index: coreutils/eject.c
--===================================================================
--RCS file: coreutils/eject.c
--diff -N coreutils/eject.c
----- /dev/null 1 Jan 1970 00:00:00 -0000
--+++ b/coreutils/eject.c       5 Mar 2004 07:23:21 -0000
--@@ -0,0 +1,66 @@
--+/*
--+ * eject implementation for busybox
--+ *
--+ * Copyright (C) 2004  Peter Willis <psyphreak@phreaker.net>
--+ *
--+ * This program is free software; you can redistribute it and/or modify
--+ * it under the terms of the GNU General Public License as published by
--+ * the Free Software Foundation; either version 2 of the License, or
--+ * (at your option) any later version.
--+ *
--+ * This program is distributed in the hope that it will be useful,
--+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
--+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
--+ * General Public License for more details.
--+ *
--+ * You should have received a copy of the GNU General Public License
--+ * along with this program; if not, write to the Free Software
--+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--+ *
--+ */
--+
--+/*
--+ * This is a simple hack of eject based on something Erik posted in #uclibc.
--+ * Most of the dirty work blatantly ripped off from cat.c =)
--+ */
--+
--+#include <stdio.h>
--+#include <string.h>
--+#include <sys/types.h>
--+#include <sys/stat.h>
--+#include <fcntl.h>
--+#include <sys/ioctl.h>
--+#include "busybox.h"
--+#include <linux/cdrom.h> // needs to be after busybox.h or compile problems arise
--+
--+#define DEFAULT_CDROM "/dev/cdrom"
--+
--+extern int eject_main(int argc, char **argv)
--+{
--+     int fd;
--+     int flag = CDROMEJECT;
--+     int i = 1;
--+     char *device = NULL;
--+
--+     /*
--+      * i'm too lazy to learn bb_getopt_ulflags and this is obscenely large
--+      * for just some argument parsing so mjn3 can clean it up later.
--+      * sorry, but PlumpOS 7.0-pre2 needs this asap :-/
--+      */
--+     while (++i <= argc) {
--+             if ( (! strncmp(argv[i-1],"-t",2)) || (! strncmp(argv[i-1],"--trayclose",11)) ) {
--+                     flag = CDROMCLOSETRAY;
--+             } else {
--+                     device = argv[i-1];
--+             }
--+     }
--+     if ( (fd = open(device == NULL ? DEFAULT_CDROM : device, O_RDONLY | O_NONBLOCK) ) < 0 ) {
--+             perror("eject: Can't open device");
--+             return(EXIT_FAILURE);
--+     }
--+     if (ioctl(fd, flag)) {
--+             perror("eject: Can't eject cdrom");
--+             return(EXIT_FAILURE);
--+     }
--+     return EXIT_SUCCESS;
--+}
--Index: include/applets.h
--===================================================================
--RCS file: /var/cvs/busybox/include/applets.h,v
--retrieving revision 1.111
--diff -u -r1.111 applets.h
----- a/include/applets.h       27 Jan 2004 09:22:20 -0000      1.111
--+++ b/include/applets.h       5 Mar 2004 07:23:21 -0000
--@@ -178,6 +178,9 @@
-- #if defined(CONFIG_FEATURE_GREP_EGREP_ALIAS)
--      APPLET_NOUSAGE("egrep", grep_main, _BB_DIR_BIN, _BB_SUID_NEVER)
-- #endif
--+#ifdef CONFIG_EJECT
--+     APPLET(eject, eject_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
--+#endif
-- #ifdef CONFIG_ENV
--      APPLET(env, env_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
-- #endif
--Index: include/usage.h
--===================================================================
--RCS file: /var/cvs/busybox/include/usage.h,v
--retrieving revision 1.191
--diff -u -r1.191 usage.h
----- a/include/usage.h 25 Feb 2004 10:35:55 -0000      1.191
--+++ b/include/usage.h 5 Mar 2004 07:23:29 -0000
--@@ -537,6 +537,13 @@
--      "\t-, -i\tstart with an empty environment\n" \
--      "\t-u\tremove variable from the environment\n"
--
--+#define eject_trivial_usage \
--+     "[-t] [FILE]"
--+#define eject_full_usage \
--+     "Ejects the specified FILE or /dev/cdrom if FILE is unspecified.\n\n" \
--+     "Options:\n" \
--+     "\t-t, --trayclose \tclose tray\n"
--+
-- #define expr_trivial_usage \
--      "EXPRESSION"
-- #define expr_full_usage \
-diff -Nur busybox-1.00/procps/ps.c busybox/procps/ps.c
---- busybox-1.00/procps/ps.c   2004-03-15 09:29:03.000000000 +0100
-+++ busybox/procps/ps.c        2005-06-04 08:20:20.000000000 +0200
-@@ -31,9 +31,7 @@
- #include <sys/ioctl.h>
- #include "busybox.h"
- #ifdef CONFIG_SELINUX
--#include <fs_secure.h>
--#include <ss.h>
--#include <flask_util.h>          /* for is_flask_enabled() */
-+#include <selinux/selinux.h>  /* for is_selinux_enabled()  */
- #endif
- static const int TERMINAL_WIDTH = 79;      /* not 80 in case terminal has linefold bug */
-@@ -48,8 +46,8 @@
- #ifdef CONFIG_SELINUX
-       int use_selinux = 0;
--      security_id_t sid;
--      if(is_flask_enabled() && argv[1] && !strcmp(argv[1], "-c") )
-+      security_context_t sid=NULL;
-+      if(is_selinux_enabled() && argv[1] && !strcmp(argv[1], "-c") )
-               use_selinux = 1;
- #endif
-@@ -58,34 +56,42 @@
-       terminal_width--;
- #ifdef CONFIG_SELINUX
--      if(use_selinux)
--              printf("  PID Context                          Stat Command\n");
-+      if (use_selinux)
-+        printf("  PID Context                          Stat Command\n");
-       else
- #endif
--      printf("  PID  Uid     VmSize Stat Command\n");
--#ifdef CONFIG_SELINUX
--      while ((p = procps_scan(1, use_selinux, &sid)) != 0) {
--#else
--      while ((p = procps_scan(1)) != 0) {
--#endif
--              char *namecmd = p->cmd;
-+        printf("  PID  Uid     VmSize Stat Command\n");
-+      while ((p = procps_scan(1)) != 0)  {
-+              char *namecmd = p->cmd;
- #ifdef CONFIG_SELINUX
--              if(use_selinux)
--              {
-+              if ( use_selinux )
-+                {
-                       char sbuf[128];
-                       len = sizeof(sbuf);
--                      if(security_sid_to_context(sid, (security_context_t)&sbuf, &len))
--                              strcpy(sbuf, "unknown");
-+                      if (is_selinux_enabled()) {
-+                        if (getpidcon(p->pid,&sid)<0)
-+                          sid=NULL;
-+                      }
-+
-+                      if (sid) {
-+                        /*  I assume sid initilized with NULL  */
-+                        len = strlen(sid)+1;
-+                        safe_strncpy(sbuf, sid, len);
-+                        freecon(sid);
-+                        sid=NULL;
-+                      }else {
-+                        safe_strncpy(sbuf, "unknown",7);
-+                      }
-                       len = printf("%5d %-32s %s ", p->pid, sbuf, p->state);
--              }
-+              } 
-               else
- #endif
--              if(p->rss == 0)
--                      len = printf("%5d %-8s        %s ", p->pid, p->user, p->state);
--              else
--                      len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state);
-+                if(p->rss == 0)
-+                  len = printf("%5d %-8s        %s ", p->pid, p->user, p->state);
-+                else
-+                  len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state);
-               i = terminal_width-len;
-               if(namecmd != 0 && namecmd[0] != 0) {
-diff -Nur busybox-1.00/procps/renice.c busybox/procps/renice.c
---- busybox-1.00/procps/renice.c       2004-03-15 09:29:03.000000000 +0100
-+++ busybox/procps/renice.c    2005-06-04 08:20:20.000000000 +0200
-@@ -1,8 +1,8 @@
-+/* vi: set sw=4 ts=4: */
- /*
-- * Mini renice implementation for busybox
-+ * renice implementation for busybox
-  *
-- *
-- * Copyright (C) 2000 Dave 'Kill a Cop' Cinege <dcinege@psychosis.com>
-+ * Copyright (C) 2005  Manuel Novoa III  <mjn3@codepoet.org>
-  *
-  * This program is free software; you can redistribute it and/or modify
-  * it under the terms of the GNU General Public License as published by
-@@ -20,35 +20,133 @@
-  *
-  */
-+/* Notes:
-+ *   Setting an absolute priority was obsoleted in SUSv2 and removed
-+ *   in SUSv3.  However, the common linux version of renice does
-+ *   absolute and not relative.  So we'll continue supporting absolute,
-+ *   although the stdout logging has been removed since both SUSv2 and
-+ *   SUSv3 specify that stdout isn't used.
-+ *
-+ *   This version is lenient in that it doesn't require any IDs.  The
-+ *   options -p, -g, and -u are treated as mode switches for the
-+ *   following IDs (if any).  Multiple switches are allowed.
-+ */
-+
- #include <stdio.h>
--#include <errno.h>
- #include <stdlib.h>
-+#include <string.h>
-+#include <limits.h>
-+#include <errno.h>
-+#include <unistd.h>
- #include <sys/time.h>
- #include <sys/resource.h>
- #include "busybox.h"
-+#if (PRIO_PROCESS < CHAR_MIN) || (PRIO_PROCESS > CHAR_MAX)
-+#error Assumption violated : PRIO_PROCESS value
-+#endif
-+#if (PRIO_PGRP < CHAR_MIN) || (PRIO_PGRP > CHAR_MAX)
-+#error Assumption violated : PRIO_PGRP value
-+#endif
-+#if (PRIO_USER < CHAR_MIN) || (PRIO_USER > CHAR_MAX)
-+#error Assumption violated : PRIO_USER value
-+#endif
--extern int renice_main(int argc, char **argv)
-+static inline int int_add_no_wrap(int a, int b)
- {
--      int prio, status = EXIT_SUCCESS;
-+      int s = a + b;
-+
-+      if (b < 0) {
-+              if (s > a) s = INT_MIN;
-+      } else {
-+              if (s < a) s = INT_MAX;
-+      }
-+
-+      return s;
-+}
--      if (argc < 3)   bb_show_usage();
-+int renice_main(int argc, char **argv)
-+{
-+      static const char Xetpriority_msg[] = "%d : %cetpriority";
--      prio = atoi(*++argv);
--      if (prio > 20)          prio = 20;
--      if (prio < -20)         prio = -20;
-+      int retval = EXIT_SUCCESS;
-+      int which = PRIO_PROCESS;       /* Default 'which' value. */
-+      int use_relative = 0;
-+      int adjustment, new_priority;
-+      id_t who;
-+
-+      ++argv;
-+
-+      /* Check if we are using a relative adjustment. */
-+      if (argv[0] && (argv[0][0] == '-') && (argv[0][1] == 'n') && !argv[0][2]) {
-+              use_relative = 1;
-+              ++argv;
-+      }
-+
-+      if (!*argv) {                           /* No args?  Then show usage. */
-+              bb_show_usage();
-+      }
-+
-+      /* Get the priority adjustment (absolute or relative). */
-+      adjustment = bb_xgetlarg(*argv, 10, INT_MIN, INT_MAX);
-       while (*++argv) {
--              int ps = atoi(*argv);
--              int oldp = getpriority(PRIO_PROCESS, ps);
-+              /* Check for a mode switch. */
-+              if ((argv[0][0] == '-') && argv[0][1] && !argv[0][2]) {
-+                      static const char opts[]
-+                              = { 'p', 'g', 'u', 0, PRIO_PROCESS, PRIO_PGRP, PRIO_USER };
-+                      const char *p;
-+                      if ((p = strchr(opts, argv[0][1]))) {
-+                              which = p[4];
-+                              continue;
-+                      }
-+              }
--              if (setpriority(PRIO_PROCESS, ps, prio) == 0) {
--                      printf("%d: old priority %d, new priority %d\n", ps, oldp, prio );
-+              /* Process an ID arg. */
-+              if (which == PRIO_USER) {
-+                      struct passwd *p;
-+                      if (!(p = getpwnam(*argv))) {
-+                              bb_error_msg("unknown user: %s", *argv);
-+                              goto HAD_ERROR;
-+                      }
-+                      who = p->pw_uid;
-               } else {
--                      bb_perror_msg("%d: setpriority", ps);
--                      status = EXIT_FAILURE;
-+                      char *e;
-+                      errno = 0;
-+                      who = strtoul(*argv, &e, 10);
-+                      if (*e || (*argv == e) || errno) {
-+                              bb_error_msg("bad value: %s", *argv);
-+                              goto HAD_ERROR;
-+                      }
-               }
-+
-+              /* Get priority to use, and set it. */
-+              if (use_relative) {
-+                      int old_priority;
-+
-+                      errno = 0;       /* Needed for getpriority error detection. */
-+                      old_priority = getpriority(which, who);
-+                      if (errno) {
-+                              bb_perror_msg(Xetpriority_msg, who, 'g');
-+                              goto HAD_ERROR;
-+                      }
-+
-+                      new_priority = int_add_no_wrap(old_priority, adjustment);
-+              } else {
-+                      new_priority = adjustment;
-+              }
-+
-+              if (setpriority(which, who, new_priority) == 0) {
-+                      continue;
-+              }
-+
-+              bb_perror_msg(Xetpriority_msg, who, 's');
-+      HAD_ERROR:
-+              retval = EXIT_FAILURE;
-       }
--      return status;
-+      /* No need to check for errors outputing to stderr since, if it
-+       * was used, the HAD_ERROR label was reached and retval was set. */
-+
-+      return retval;
- }
-diff -Nur busybox-1.00/procps/top.c busybox/procps/top.c
---- busybox-1.00/procps/top.c  2004-09-14 21:14:00.000000000 +0200
-+++ busybox/procps/top.c       2005-06-04 08:20:20.000000000 +0200
-@@ -78,7 +78,7 @@
-     return (int)((Q->stime + Q->utime) - (P->stime + P->utime));
- }
--int mult_lvl_cmp(void* a, void* b) {
-+static int mult_lvl_cmp(void* a, void* b) {
-     int i, cmp_val;
-     for(i = 0; i < sort_depth; i++) {
-@@ -510,11 +510,7 @@
-               /* read process IDs & status for all the processes */
-               procps_status_t * p;
--#ifdef CONFIG_SELINUX
--              while ((p = procps_scan(0, 0, NULL) ) != 0) {
--#else
-               while ((p = procps_scan(0)) != 0) {
--#endif
-                       int n = ntop;
-                       top = xrealloc(top, (++ntop)*sizeof(procps_status_t));
-diff -Nur busybox-1.00/scripts/config/Makefile busybox/scripts/config/Makefile
---- busybox-1.00/scripts/config/Makefile       2004-10-08 09:45:49.000000000 +0200
-+++ busybox/scripts/config/Makefile    2005-06-04 08:20:03.000000000 +0200
-@@ -9,7 +9,11 @@
- all: ncurses conf mconf
-+ifeq ($(shell uname),SunOS)
-+LIBS = -lcurses
-+else
- LIBS = -lncurses
-+endif
- ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h))
-       HOSTNCURSES += -I/usr/include/ncurses -DCURSES_LOC="<ncurses.h>"
- else
-@@ -32,14 +36,17 @@
- endif
- endif
--CONF_SRC  =conf.c
--MCONF_SRC =mconf.c checklist.c menubox.c textbox.c yesno.c inputbox.c util.c msgbox.c
--SHARED_SRC=zconf.tab.c
--SHARED_DEPS:=$(srcdir)/lkc.h $(srcdir)/lkc_proto.h \
--  lkc_defs.h $(srcdir)/expr.h zconf.tab.h
--CONF_OBJS =$(patsubst %.c,%.o, $(CONF_SRC))
--MCONF_OBJS=$(patsubst %.c,%.o, $(MCONF_SRC))
--SHARED_OBJS=$(patsubst %.c,%.o, $(SHARED_SRC))
-+CONF_SRC     = conf.c
-+MCONF_SRC    = mconf.c
-+LXD_SRC      = lxdialog/checklist.c lxdialog/menubox.c lxdialog/textbox.c \
-+               lxdialog/yesno.c lxdialog/inputbox.c lxdialog/util.c \
-+               lxdialog/msgbox.c
-+SHARED_SRC   = zconf.tab.c
-+SHARED_DEPS := $(srcdir)/lkc.h $(srcdir)/lkc_proto.h \
-+               lkc_defs.h $(srcdir)/expr.h zconf.tab.h
-+CONF_OBJS    = $(patsubst %.c,%.o, $(CONF_SRC))
-+MCONF_OBJS   = $(patsubst %.c,%.o, $(MCONF_SRC) $(LXD_SRC))
-+SHARED_OBJS  = $(patsubst %.c,%.o, $(SHARED_SRC))
- conf: $(CONF_OBJS) $(SHARED_OBJS)
-       $(HOSTCC) $(NATIVE_LDFLAGS) $^ -o $@
-diff -Nur busybox-1.00/scripts/config/checklist.c busybox/scripts/config/checklist.c
---- busybox-1.00/scripts/config/checklist.c    2004-07-15 08:01:05.000000000 +0200
-+++ busybox/scripts/config/checklist.c 1970-01-01 01:00:00.000000000 +0100
-@@ -1,372 +0,0 @@
--/*
-- *  checklist.c -- implements the checklist box
-- *
-- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-- *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
-- *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
-- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
-- *
-- *  This program is free software; you can redistribute it and/or
-- *  modify it under the terms of the GNU General Public License
-- *  as published by the Free Software Foundation; either version 2
-- *  of the License, or (at your option) any later version.
-- *
-- *  This program is distributed in the hope that it will be useful,
-- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- *  GNU General Public License for more details.
-- *
-- *  You should have received a copy of the GNU General Public License
-- *  along with this program; if not, write to the Free Software
-- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-- */
--
--#include "dialog.h"
--
--static int list_width, check_x, item_x, checkflag;
--
--/*
-- * Print list item
-- */
--static void
--print_item (WINDOW * win, const char *item, int status,
--          int choice, int selected)
--{
--    int i;
--
--    /* Clear 'residue' of last item */
--    wattrset (win, menubox_attr);
--    wmove (win, choice, 0);
--    for (i = 0; i < list_width; i++)
--      waddch (win, ' ');
--
--    wmove (win, choice, check_x);
--    wattrset (win, selected ? check_selected_attr : check_attr);
--    if (checkflag == FLAG_CHECK)
--      wprintw (win, "[%c]", status ? 'X' : ' ');
--    else
--      wprintw (win, "(%c)", status ? 'X' : ' ');
--
--    wattrset (win, selected ? tag_selected_attr : tag_attr);
--    mvwaddch(win, choice, item_x, item[0]);
--    wattrset (win, selected ? item_selected_attr : item_attr);
--    waddstr (win, (char *)item+1);
--    if (selected) {
--      wmove (win, choice, check_x+1);
--      wrefresh (win);
--    }
--}
--
--/*
-- * Print the scroll indicators.
-- */
--static void
--print_arrows (WINDOW * win, int choice, int item_no, int scroll,
--              int y, int x, int height)
--{
--    wmove(win, y, x);
--
--    if (scroll > 0) {
--      wattrset (win, uarrow_attr);
--      waddch (win, ACS_UARROW);
--      waddstr (win, "(-)");
--    }
--    else {
--      wattrset (win, menubox_attr);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--    }
--
--   y = y + height + 1;
--   wmove(win, y, x);
--
--   if ((height < item_no) && (scroll + choice < item_no - 1)) {
--      wattrset (win, darrow_attr);
--      waddch (win, ACS_DARROW);
--      waddstr (win, "(+)");
--    }
--    else {
--      wattrset (win, menubox_border_attr);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--   }
--}
--
--/*
-- *  Display the termination buttons
-- */
--static void
--print_buttons( WINDOW *dialog, int height, int width, int selected)
--{
--    int x = width / 2 - 11;
--    int y = height - 2;
--
--    print_button (dialog, "Select", y, x, selected == 0);
--    print_button (dialog, " Help ", y, x + 14, selected == 1);
--
--    wmove(dialog, y, x+1 + 14*selected);
--    wrefresh (dialog);
--}
--
--/*
-- * Display a dialog box with a list of options that can be turned on or off
-- * The `flag' parameter is used to select between radiolist and checklist.
-- */
--int
--dialog_checklist (const char *title, const char *prompt, int height, int width,
--      int list_height, int item_no, struct dialog_list_item ** items,
--      int flag)
--
--{
--    int i, x, y, box_x, box_y;
--    int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
--    WINDOW *dialog, *list;
--
--    checkflag = flag;
--
--    /* Allocate space for storing item on/off status */
--    if ((status = malloc (sizeof (int) * item_no)) == NULL) {
--      endwin ();
--      fprintf (stderr,
--               "\nCan't allocate memory in dialog_checklist().\n");
--      exit (-1);
--    }
--
--    /* Initializes status */
--    for (i = 0; i < item_no; i++) {
--      status[i] = (items[i]->selected == 1); /* ON */
--      if ((!choice && status[i]) || items[i]->selected == 2) /* SELECTED */
--            choice = i + 1;
--    }
--    if (choice)
--          choice--;
--
--    max_choice = MIN (list_height, item_no);
--
--    /* center dialog box on screen */
--    x = (COLS - width) / 2;
--    y = (LINES - height) / 2;
--
--    draw_shadow (stdscr, y, x, height, width);
--
--    dialog = newwin (height, width, y, x);
--    keypad (dialog, TRUE);
--
--    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
--    wattrset (dialog, border_attr);
--    mvwaddch (dialog, height-3, 0, ACS_LTEE);
--    for (i = 0; i < width - 2; i++)
--      waddch (dialog, ACS_HLINE);
--    wattrset (dialog, dialog_attr);
--    waddch (dialog, ACS_RTEE);
--
--    if (title != NULL && strlen(title) >= width-2 ) {
--      /* truncate long title -- mec */
--      char * title2 = malloc(width-2+1);
--      memcpy( title2, title, width-2 );
--      title2[width-2] = '\0';
--      title = title2;
--    }
--
--    if (title != NULL) {
--      wattrset (dialog, title_attr);
--      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
--      waddstr (dialog, (char *)title);
--      waddch (dialog, ' ');
--    }
--
--    wattrset (dialog, dialog_attr);
--    print_autowrap (dialog, prompt, width - 2, 1, 3);
--
--    list_width = width - 6;
--    box_y = height - list_height - 5;
--    box_x = (width - list_width) / 2 - 1;
--
--    /* create new window for the list */
--    list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
--
--    keypad (list, TRUE);
--
--    /* draw a box around the list items */
--    draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
--            menubox_border_attr, menubox_attr);
--
--    /* Find length of longest item in order to center checklist */
--    check_x = 0;
--    for (i = 0; i < item_no; i++)
--      check_x = MAX (check_x, + strlen (items[i]->name) + 4);
--
--    check_x = (list_width - check_x) / 2;
--    item_x = check_x + 4;
--
--    if (choice >= list_height) {
--      scroll = choice - list_height + 1;
--      choice -= scroll;
--    }
--
--    /* Print the list */
--    for (i = 0; i < max_choice; i++) {
--      print_item (list, items[scroll + i]->name,
--                  status[i+scroll], i, i == choice);
--    }
--
--    print_arrows(dialog, choice, item_no, scroll,
--                      box_y, box_x + check_x + 5, list_height);
--
--    print_buttons(dialog, height, width, 0);
--
--    wnoutrefresh (list);
--    wnoutrefresh (dialog);
--    doupdate ();
--
--    while (key != ESC) {
--      key = wgetch (dialog);
--
--      for (i = 0; i < max_choice; i++)
--            if (toupper(key) == toupper(items[scroll + i]->name[0]))
--                break;
--
--
--      if ( i < max_choice || key == KEY_UP || key == KEY_DOWN ||
--          key == '+' || key == '-' ) {
--          if (key == KEY_UP || key == '-') {
--              if (!choice) {
--                  if (!scroll)
--                      continue;
--                  /* Scroll list down */
--                  if (list_height > 1) {
--                      /* De-highlight current first item */
--                      print_item (list, items[scroll]->name,
--                                      status[scroll], 0, FALSE);
--                      scrollok (list, TRUE);
--                      wscrl (list, -1);
--                      scrollok (list, FALSE);
--                  }
--                  scroll--;
--                  print_item (list, items[scroll]->name,
--                              status[scroll], 0, TRUE);
--                  wnoutrefresh (list);
--
--                  print_arrows(dialog, choice, item_no, scroll,
--                              box_y, box_x + check_x + 5, list_height);
--
--                  wrefresh (dialog);
--
--                  continue;   /* wait for another key press */
--              } else
--                  i = choice - 1;
--          } else if (key == KEY_DOWN || key == '+') {
--              if (choice == max_choice - 1) {
--                  if (scroll + choice >= item_no - 1)
--                      continue;
--                  /* Scroll list up */
--                  if (list_height > 1) {
--                      /* De-highlight current last item before scrolling up */
--                      print_item (list, items[scroll + max_choice - 1]->name,
--                                  status[scroll + max_choice - 1],
--                                  max_choice - 1, FALSE);
--                      scrollok (list, TRUE);
--                      scroll (list);
--                      scrollok (list, FALSE);
--                  }
--                  scroll++;
--                  print_item (list, items[scroll + max_choice - 1]->name,
--                              status[scroll + max_choice - 1],
--                              max_choice - 1, TRUE);
--                  wnoutrefresh (list);
--
--                  print_arrows(dialog, choice, item_no, scroll,
--                              box_y, box_x + check_x + 5, list_height);
--
--                  wrefresh (dialog);
--
--                  continue;   /* wait for another key press */
--              } else
--                  i = choice + 1;
--          }
--          if (i != choice) {
--              /* De-highlight current item */
--              print_item (list, items[scroll + choice]->name,
--                          status[scroll + choice], choice, FALSE);
--              /* Highlight new item */
--              choice = i;
--              print_item (list, items[scroll + choice]->name,
--                          status[scroll + choice], choice, TRUE);
--              wnoutrefresh (list);
--              wrefresh (dialog);
--          }
--          continue;           /* wait for another key press */
--      }
--      switch (key) {
--      case 'H':
--      case 'h':
--      case '?':
--          for (i = 0; i < item_no; i++)
--              items[i]->selected = 0;
--          items[scroll + choice]->selected = 1;
--          delwin (dialog);
--          free (status);
--          return 1;
--      case TAB:
--      case KEY_LEFT:
--      case KEY_RIGHT:
--          button = ((key == KEY_LEFT ? --button : ++button) < 0)
--                      ? 1 : (button > 1 ? 0 : button);
--
--          print_buttons(dialog, height, width, button);
--          wrefresh (dialog);
--          break;
--      case 'S':
--      case 's':
--      case ' ':
--      case '\n':
--          if (!button) {
--              if (flag == FLAG_CHECK) {
--                  status[scroll + choice] = !status[scroll + choice];
--                  wmove (list, choice, check_x);
--                  wattrset (list, check_selected_attr);
--                  wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
--              } else {
--                  if (!status[scroll + choice]) {
--                      for (i = 0; i < item_no; i++)
--                          status[i] = 0;
--                      status[scroll + choice] = 1;
--                      for (i = 0; i < max_choice; i++)
--                          print_item (list, items[scroll + i]->name,
--                                      status[scroll + i], i, i == choice);
--                  }
--              }
--              wnoutrefresh (list);
--              wrefresh (dialog);
--
--              for (i = 0; i < item_no; i++) {
--                      items[i]->selected = status[i];
--              }
--            } else {
--                  for (i = 0; i < item_no; i++)
--                          items[i]->selected = 0;
--                  items[scroll + choice]->selected = 1;
--          }
--          delwin (dialog);
--          free (status);
--          return button;
--      case 'X':
--      case 'x':
--          key = ESC;
--      case ESC:
--          break;
--      }
--
--      /* Now, update everything... */
--      doupdate ();
--    }
--
--
--    delwin (dialog);
--    free (status);
--    return -1;                        /* ESC pressed */
--}
-diff -Nur busybox-1.00/scripts/config/colors.h busybox/scripts/config/colors.h
---- busybox-1.00/scripts/config/colors.h       2002-12-05 09:41:06.000000000 +0100
-+++ busybox/scripts/config/colors.h    1970-01-01 01:00:00.000000000 +0100
-@@ -1,161 +0,0 @@
--/*
-- *  colors.h -- color attribute definitions
-- *
-- *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-- *
-- *  This program is free software; you can redistribute it and/or
-- *  modify it under the terms of the GNU General Public License
-- *  as published by the Free Software Foundation; either version 2
-- *  of the License, or (at your option) any later version.
-- *
-- *  This program is distributed in the hope that it will be useful,
-- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- *  GNU General Public License for more details.
-- *
-- *  You should have received a copy of the GNU General Public License
-- *  along with this program; if not, write to the Free Software
-- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-- */
--
--
--/*
-- *   Default color definitions
-- *
-- *   *_FG = foreground
-- *   *_BG = background
-- *   *_HL = highlight?
-- */
--#define SCREEN_FG                    COLOR_CYAN
--#define SCREEN_BG                    COLOR_BLUE
--#define SCREEN_HL                    TRUE
--
--#define SHADOW_FG                    COLOR_BLACK
--#define SHADOW_BG                    COLOR_BLACK
--#define SHADOW_HL                    TRUE
--
--#define DIALOG_FG                    COLOR_BLACK
--#define DIALOG_BG                    COLOR_WHITE
--#define DIALOG_HL                    FALSE
--
--#define TITLE_FG                     COLOR_YELLOW
--#define TITLE_BG                     COLOR_WHITE
--#define TITLE_HL                     TRUE
--
--#define BORDER_FG                    COLOR_WHITE
--#define BORDER_BG                    COLOR_WHITE
--#define BORDER_HL                    TRUE
--
--#define BUTTON_ACTIVE_FG             COLOR_WHITE
--#define BUTTON_ACTIVE_BG             COLOR_BLUE
--#define BUTTON_ACTIVE_HL             TRUE
--
--#define BUTTON_INACTIVE_FG           COLOR_BLACK
--#define BUTTON_INACTIVE_BG           COLOR_WHITE
--#define BUTTON_INACTIVE_HL           FALSE
--
--#define BUTTON_KEY_ACTIVE_FG         COLOR_WHITE
--#define BUTTON_KEY_ACTIVE_BG         COLOR_BLUE
--#define BUTTON_KEY_ACTIVE_HL         TRUE
--
--#define BUTTON_KEY_INACTIVE_FG       COLOR_RED
--#define BUTTON_KEY_INACTIVE_BG       COLOR_WHITE
--#define BUTTON_KEY_INACTIVE_HL       FALSE
--
--#define BUTTON_LABEL_ACTIVE_FG       COLOR_YELLOW
--#define BUTTON_LABEL_ACTIVE_BG       COLOR_BLUE
--#define BUTTON_LABEL_ACTIVE_HL       TRUE
--
--#define BUTTON_LABEL_INACTIVE_FG     COLOR_BLACK
--#define BUTTON_LABEL_INACTIVE_BG     COLOR_WHITE
--#define BUTTON_LABEL_INACTIVE_HL     TRUE
--
--#define INPUTBOX_FG                  COLOR_BLACK
--#define INPUTBOX_BG                  COLOR_WHITE
--#define INPUTBOX_HL                  FALSE
--
--#define INPUTBOX_BORDER_FG           COLOR_BLACK
--#define INPUTBOX_BORDER_BG           COLOR_WHITE
--#define INPUTBOX_BORDER_HL           FALSE
--
--#define SEARCHBOX_FG                 COLOR_BLACK
--#define SEARCHBOX_BG                 COLOR_WHITE
--#define SEARCHBOX_HL                 FALSE
--
--#define SEARCHBOX_TITLE_FG           COLOR_YELLOW
--#define SEARCHBOX_TITLE_BG           COLOR_WHITE
--#define SEARCHBOX_TITLE_HL           TRUE
--
--#define SEARCHBOX_BORDER_FG          COLOR_WHITE
--#define SEARCHBOX_BORDER_BG          COLOR_WHITE
--#define SEARCHBOX_BORDER_HL          TRUE
--
--#define POSITION_INDICATOR_FG        COLOR_YELLOW
--#define POSITION_INDICATOR_BG        COLOR_WHITE
--#define POSITION_INDICATOR_HL        TRUE
--
--#define MENUBOX_FG                   COLOR_BLACK
--#define MENUBOX_BG                   COLOR_WHITE
--#define MENUBOX_HL                   FALSE
--
--#define MENUBOX_BORDER_FG            COLOR_WHITE
--#define MENUBOX_BORDER_BG            COLOR_WHITE
--#define MENUBOX_BORDER_HL            TRUE
--
--#define ITEM_FG                      COLOR_BLACK
--#define ITEM_BG                      COLOR_WHITE
--#define ITEM_HL                      FALSE
--
--#define ITEM_SELECTED_FG             COLOR_WHITE
--#define ITEM_SELECTED_BG             COLOR_BLUE
--#define ITEM_SELECTED_HL             TRUE
--
--#define TAG_FG                       COLOR_YELLOW
--#define TAG_BG                       COLOR_WHITE
--#define TAG_HL                       TRUE
--
--#define TAG_SELECTED_FG              COLOR_YELLOW
--#define TAG_SELECTED_BG              COLOR_BLUE
--#define TAG_SELECTED_HL              TRUE
--
--#define TAG_KEY_FG                   COLOR_YELLOW
--#define TAG_KEY_BG                   COLOR_WHITE
--#define TAG_KEY_HL                   TRUE
--
--#define TAG_KEY_SELECTED_FG          COLOR_YELLOW
--#define TAG_KEY_SELECTED_BG          COLOR_BLUE
--#define TAG_KEY_SELECTED_HL          TRUE
--
--#define CHECK_FG                     COLOR_BLACK
--#define CHECK_BG                     COLOR_WHITE
--#define CHECK_HL                     FALSE
--
--#define CHECK_SELECTED_FG            COLOR_WHITE
--#define CHECK_SELECTED_BG            COLOR_BLUE
--#define CHECK_SELECTED_HL            TRUE
--
--#define UARROW_FG                    COLOR_GREEN
--#define UARROW_BG                    COLOR_WHITE
--#define UARROW_HL                    TRUE
--
--#define DARROW_FG                    COLOR_GREEN
--#define DARROW_BG                    COLOR_WHITE
--#define DARROW_HL                    TRUE
--
--/* End of default color definitions */
--
--#define C_ATTR(x,y)                  ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
--#define COLOR_NAME_LEN               10
--#define COLOR_COUNT                  8
--
--/*
-- * Global variables
-- */
--
--typedef struct {
--    char name[COLOR_NAME_LEN];
--    int value;
--} color_names_st;
--
--extern color_names_st color_names[];
--extern int color_table[][3];
-diff -Nur busybox-1.00/scripts/config/conf.c busybox/scripts/config/conf.c
---- busybox-1.00/scripts/config/conf.c 2004-01-16 13:48:53.000000000 +0100
-+++ busybox/scripts/config/conf.c      2005-06-04 08:20:03.000000000 +0200
-@@ -31,14 +31,14 @@
- static int indent = 1;
- static int valid_stdin = 1;
- static int conf_cnt;
--static char line[128];
-+static signed char line[128];
- static struct menu *rootEntry;
- static char nohelp_text[] = "Sorry, no help available for this option yet.\n";
--static void strip(char *str)
-+static void strip(signed char *str)
- {
--      char *p = str;
-+      signed char *p = str;
-       int l;
-       while ((isspace(*p)))
-diff -Nur busybox-1.00/scripts/config/confdata.c busybox/scripts/config/confdata.c
---- busybox-1.00/scripts/config/confdata.c     2004-07-15 08:01:05.000000000 +0200
-+++ busybox/scripts/config/confdata.c  2005-06-04 08:20:03.000000000 +0200
-@@ -23,10 +23,10 @@
-       NULL,
- };
--static char *conf_expand_value(const char *in)
-+static char *conf_expand_value(const signed char *in)
- {
-       struct symbol *sym;
--      const char *src;
-+      const signed char *src;
-       static char res_value[SYMBOL_MAXLENGTH];
-       char *dst, name[SYMBOL_MAXLENGTH];
-@@ -287,7 +287,7 @@
-       } else
-               basename = conf_def_filename;
--      sprintf(newname, "%s.tmpconfig.%d", dirname, getpid());
-+      sprintf(newname, "%s.tmpconfig.%d", dirname, (int)getpid());
-       out = fopen(newname, "w");
-       if (!out)
-               return 1;
-diff -Nur busybox-1.00/scripts/config/dialog.h busybox/scripts/config/dialog.h
---- busybox-1.00/scripts/config/dialog.h       2004-03-15 09:29:08.000000000 +0100
-+++ busybox/scripts/config/dialog.h    1970-01-01 01:00:00.000000000 +0100
-@@ -1,196 +0,0 @@
--
--/*
-- *  dialog.h -- common declarations for all dialog modules
-- *
-- *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-- *
-- *  This program is free software; you can redistribute it and/or
-- *  modify it under the terms of the GNU General Public License
-- *  as published by the Free Software Foundation; either version 2
-- *  of the License, or (at your option) any later version.
-- *
-- *  This program is distributed in the hope that it will be useful,
-- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- *  GNU General Public License for more details.
-- *
-- *  You should have received a copy of the GNU General Public License
-- *  along with this program; if not, write to the Free Software
-- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-- */
--
--#include <sys/types.h>
--#include <fcntl.h>
--#include <unistd.h>
--#include <ctype.h>
--#include <stdlib.h>
--#include <string.h>
--
--#ifdef CURSES_LOC
--#include CURSES_LOC
--
--/*
-- * Colors in ncurses 1.9.9e do not work properly since foreground and
-- * background colors are OR'd rather than separately masked.  This version
-- * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
-- * with standard curses.  The simplest fix (to make this work with standard
-- * curses) uses the wbkgdset() function, not used in the original hack.
-- * Turn it off if we're building with 1.9.9e, since it just confuses things.
-- */
--#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
--#define OLD_NCURSES 1
--#undef  wbkgdset
--#define wbkgdset(w,p) /*nothing*/
--#else
--#define OLD_NCURSES 0
--#endif
--
--#define TR(params) _tracef params
--
--#define ESC 27
--#define TAB 9
--#define MAX_LEN 2048
--#define BUF_SIZE (10*1024)
--#define MIN(x,y) (x < y ? x : y)
--#define MAX(x,y) (x > y ? x : y)
--
--
--#ifndef ACS_ULCORNER
--#define ACS_ULCORNER '+'
--#endif
--#ifndef ACS_LLCORNER
--#define ACS_LLCORNER '+'
--#endif
--#ifndef ACS_URCORNER
--#define ACS_URCORNER '+'
--#endif
--#ifndef ACS_LRCORNER
--#define ACS_LRCORNER '+'
--#endif
--#ifndef ACS_HLINE
--#define ACS_HLINE '-'
--#endif
--#ifndef ACS_VLINE
--#define ACS_VLINE '|'
--#endif
--#ifndef ACS_LTEE
--#define ACS_LTEE '+'
--#endif
--#ifndef ACS_RTEE
--#define ACS_RTEE '+'
--#endif
--#ifndef ACS_UARROW
--#define ACS_UARROW '^'
--#endif
--#ifndef ACS_DARROW
--#define ACS_DARROW 'v'
--#endif
--
--/*
-- * Attribute names
-- */
--#define screen_attr                   attributes[0]
--#define shadow_attr                   attributes[1]
--#define dialog_attr                   attributes[2]
--#define title_attr                    attributes[3]
--#define border_attr                   attributes[4]
--#define button_active_attr            attributes[5]
--#define button_inactive_attr          attributes[6]
--#define button_key_active_attr        attributes[7]
--#define button_key_inactive_attr      attributes[8]
--#define button_label_active_attr      attributes[9]
--#define button_label_inactive_attr    attributes[10]
--#define inputbox_attr                 attributes[11]
--#define inputbox_border_attr          attributes[12]
--#define searchbox_attr                attributes[13]
--#define searchbox_title_attr          attributes[14]
--#define searchbox_border_attr         attributes[15]
--#define position_indicator_attr       attributes[16]
--#define menubox_attr                  attributes[17]
--#define menubox_border_attr           attributes[18]
--#define item_attr                     attributes[19]
--#define item_selected_attr            attributes[20]
--#define tag_attr                      attributes[21]
--#define tag_selected_attr             attributes[22]
--#define tag_key_attr                  attributes[23]
--#define tag_key_selected_attr         attributes[24]
--#define check_attr                    attributes[25]
--#define check_selected_attr           attributes[26]
--#define uarrow_attr                   attributes[27]
--#define darrow_attr                   attributes[28]
--
--/* number of attributes */
--#define ATTRIBUTE_COUNT               29
--
--/*
-- * Global variables
-- */
--extern bool use_colors;
--
--extern chtype attributes[];
--#endif
--
--extern char *backtitle;
--
--struct dialog_list_item {
--      char *name;
--      int namelen;
--      char *tag;
--      int selected; /* Set to 1 by dialog_*() function. */
--};
--
--/*
-- * Function prototypes
-- */
--
--void init_dialog (void);
--void end_dialog (void);
--void dialog_clear (void);
--#ifdef CURSES_LOC
--void attr_clear (WINDOW * win, int height, int width, chtype attr);
--void color_setup (void);
--void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
--void print_button (WINDOW * win, const char *label, int y, int x, int selected);
--void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
--              chtype border);
--void draw_shadow (WINDOW * win, int y, int x, int height, int width);
--#endif
--
--int first_alpha (const char *string, const char *exempt);
--int dialog_yesno (const char *title, const char *prompt, int height, int width);
--int dialog_msgbox (const char *title, const char *prompt, int height,
--              int width, int pause);
--int dialog_textbox (const char *title, const char *file, int height, int width);
--int dialog_menu (const char *title, const char *prompt, int height, int width,
--              int menu_height, const char *choice, int item_no,
--              struct dialog_list_item ** items);
--int dialog_checklist (const char *title, const char *prompt, int height,
--              int width, int list_height, int item_no,
--              struct dialog_list_item ** items, int flag);
--extern unsigned char dialog_input_result[];
--int dialog_inputbox (const char *title, const char *prompt, int height,
--              int width, const char *init);
--
--struct dialog_list_item *first_sel_item(int item_no,
--              struct dialog_list_item ** items);
--
--/*
-- * This is the base for fictitious keys, which activate
-- * the buttons.
-- *
-- * Mouse-generated keys are the following:
-- *   -- the first 32 are used as numbers, in addition to '0'-'9'
-- *   -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
-- *   -- uppercase chars are used to invoke the button (M_EVENT + 'O')
-- */
--#ifdef CURSES_LOC
--#define M_EVENT (KEY_MAX+1)
--#endif
--
--
--/*
-- * The `flag' parameter in checklist is used to select between
-- * radiolist and checklist
-- */
--#define FLAG_CHECK 1
--#define FLAG_RADIO 0
-diff -Nur busybox-1.00/scripts/config/expr.c busybox/scripts/config/expr.c
---- busybox-1.00/scripts/config/expr.c 2004-07-15 08:01:05.000000000 +0200
-+++ busybox/scripts/config/expr.c      2005-06-04 08:20:03.000000000 +0200
-@@ -1087,3 +1087,13 @@
- {
-       expr_print(e, expr_print_file_helper, out, E_NONE);
- }
-+
-+static void expr_print_gstr_helper(void *data, const char *str)
-+{
-+      str_append((struct gstr*)data, str);
-+}
-+
-+void expr_gstr_print(struct expr *e, struct gstr *gs)
-+{
-+      expr_print(e, expr_print_gstr_helper, gs, E_NONE);
-+}
-diff -Nur busybox-1.00/scripts/config/expr.h busybox/scripts/config/expr.h
---- busybox-1.00/scripts/config/expr.h 2004-07-15 08:01:05.000000000 +0200
-+++ busybox/scripts/config/expr.h      2005-06-04 08:20:03.000000000 +0200
-@@ -174,6 +174,8 @@
- struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym);
- void expr_fprint(struct expr *e, FILE *out);
-+struct gstr; /* forward */
-+void expr_gstr_print(struct expr *e, struct gstr *gs);
- static inline int expr_is_yes(struct expr *e)
- {
-diff -Nur busybox-1.00/scripts/config/inputbox.c busybox/scripts/config/inputbox.c
---- busybox-1.00/scripts/config/inputbox.c     2002-12-05 09:41:07.000000000 +0100
-+++ busybox/scripts/config/inputbox.c  1970-01-01 01:00:00.000000000 +0100
-@@ -1,240 +0,0 @@
--/*
-- *  inputbox.c -- implements the input box
-- *
-- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
-- *
-- *  This program is free software; you can redistribute it and/or
-- *  modify it under the terms of the GNU General Public License
-- *  as published by the Free Software Foundation; either version 2
-- *  of the License, or (at your option) any later version.
-- *
-- *  This program is distributed in the hope that it will be useful,
-- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- *  GNU General Public License for more details.
-- *
-- *  You should have received a copy of the GNU General Public License
-- *  along with this program; if not, write to the Free Software
-- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-- */
--
--#include "dialog.h"
--
--unsigned char dialog_input_result[MAX_LEN + 1];
--
--/*
-- *  Print the termination buttons
-- */
--static void
--print_buttons(WINDOW *dialog, int height, int width, int selected)
--{
--    int x = width / 2 - 11;
--    int y = height - 2;
--
--    print_button (dialog, "  Ok  ", y, x, selected==0);
--    print_button (dialog, " Help ", y, x + 14, selected==1);
--
--    wmove(dialog, y, x+1+14*selected);
--    wrefresh(dialog);
--}
--
--/*
-- * Display a dialog box for inputing a string
-- */
--int
--dialog_inputbox (const char *title, const char *prompt, int height, int width,
--               const char *init)
--{
--    int i, x, y, box_y, box_x, box_width;
--    int input_x = 0, scroll = 0, key = 0, button = -1;
--    unsigned char *instr = dialog_input_result;
--    WINDOW *dialog;
--
--    /* center dialog box on screen */
--    x = (COLS - width) / 2;
--    y = (LINES - height) / 2;
--
--
--    draw_shadow (stdscr, y, x, height, width);
--
--    dialog = newwin (height, width, y, x);
--    keypad (dialog, TRUE);
--
--    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
--    wattrset (dialog, border_attr);
--    mvwaddch (dialog, height-3, 0, ACS_LTEE);
--    for (i = 0; i < width - 2; i++)
--      waddch (dialog, ACS_HLINE);
--    wattrset (dialog, dialog_attr);
--    waddch (dialog, ACS_RTEE);
--
--    if (title != NULL && strlen(title) >= width-2 ) {
--      /* truncate long title -- mec */
--      char * title2 = malloc(width-2+1);
--      memcpy( title2, title, width-2 );
--      title2[width-2] = '\0';
--      title = title2;
--    }
--
--    if (title != NULL) {
--      wattrset (dialog, title_attr);
--      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
--      waddstr (dialog, (char *)title);
--      waddch (dialog, ' ');
--    }
--
--    wattrset (dialog, dialog_attr);
--    print_autowrap (dialog, prompt, width - 2, 1, 3);
--
--    /* Draw the input field box */
--    box_width = width - 6;
--    getyx (dialog, y, x);
--    box_y = y + 2;
--    box_x = (width - box_width) / 2;
--    draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
--            border_attr, dialog_attr);
--
--    print_buttons(dialog, height, width, 0);
--
--    /* Set up the initial value */
--    wmove (dialog, box_y, box_x);
--    wattrset (dialog, inputbox_attr);
--
--    if (!init)
--      instr[0] = '\0';
--    else
--      strcpy (instr, init);
--
--    input_x = strlen (instr);
--
--    if (input_x >= box_width) {
--      scroll = input_x - box_width + 1;
--      input_x = box_width - 1;
--      for (i = 0; i < box_width - 1; i++)
--          waddch (dialog, instr[scroll + i]);
--    } else
--      waddstr (dialog, instr);
--
--    wmove (dialog, box_y, box_x + input_x);
--
--    wrefresh (dialog);
--
--    while (key != ESC) {
--      key = wgetch (dialog);
--
--      if (button == -1) {     /* Input box selected */
--          switch (key) {
--          case TAB:
--          case KEY_UP:
--          case KEY_DOWN:
--              break;
--          case KEY_LEFT:
--              continue;
--          case KEY_RIGHT:
--              continue;
--          case KEY_BACKSPACE:
--          case 127:
--              if (input_x || scroll) {
--                  wattrset (dialog, inputbox_attr);
--                  if (!input_x) {
--                      scroll = scroll < box_width - 1 ?
--                          0 : scroll - (box_width - 1);
--                      wmove (dialog, box_y, box_x);
--                      for (i = 0; i < box_width; i++)
--                          waddch (dialog, instr[scroll + input_x + i] ?
--                                  instr[scroll + input_x + i] : ' ');
--                      input_x = strlen (instr) - scroll;
--                  } else
--                      input_x--;
--                  instr[scroll + input_x] = '\0';
--                  mvwaddch (dialog, box_y, input_x + box_x, ' ');
--                  wmove (dialog, box_y, input_x + box_x);
--                  wrefresh (dialog);
--              }
--              continue;
--          default:
--              if (key < 0x100 && isprint (key)) {
--                  if (scroll + input_x < MAX_LEN) {
--                      wattrset (dialog, inputbox_attr);
--                      instr[scroll + input_x] = key;
--                      instr[scroll + input_x + 1] = '\0';
--                      if (input_x == box_width - 1) {
--                          scroll++;
--                          wmove (dialog, box_y, box_x);
--                          for (i = 0; i < box_width - 1; i++)
--                              waddch (dialog, instr[scroll + i]);
--                      } else {
--                          wmove (dialog, box_y, input_x++ + box_x);
--                          waddch (dialog, key);
--                      }
--                      wrefresh (dialog);
--                  } else
--                      flash ();       /* Alarm user about overflow */
--                  continue;
--              }
--          }
--      }
--      switch (key) {
--      case 'O':
--      case 'o':
--          delwin (dialog);
--          return 0;
--      case 'H':
--      case 'h':
--          delwin (dialog);
--          return 1;
--      case KEY_UP:
--      case KEY_LEFT:
--          switch (button) {
--          case -1:
--              button = 1;     /* Indicates "Cancel" button is selected */
--              print_buttons(dialog, height, width, 1);
--              break;
--          case 0:
--              button = -1;    /* Indicates input box is selected */
--              print_buttons(dialog, height, width, 0);
--              wmove (dialog, box_y, box_x + input_x);
--              wrefresh (dialog);
--              break;
--          case 1:
--              button = 0;     /* Indicates "OK" button is selected */
--              print_buttons(dialog, height, width, 0);
--              break;
--          }
--          break;
--      case TAB:
--      case KEY_DOWN:
--      case KEY_RIGHT:
--          switch (button) {
--          case -1:
--              button = 0;     /* Indicates "OK" button is selected */
--              print_buttons(dialog, height, width, 0);
--              break;
--          case 0:
--              button = 1;     /* Indicates "Cancel" button is selected */
--              print_buttons(dialog, height, width, 1);
--              break;
--          case 1:
--              button = -1;    /* Indicates input box is selected */
--              print_buttons(dialog, height, width, 0);
--              wmove (dialog, box_y, box_x + input_x);
--              wrefresh (dialog);
--              break;
--          }
--          break;
--      case ' ':
--      case '\n':
--          delwin (dialog);
--          return (button == -1 ? 0 : button);
--      case 'X':
--      case 'x':
--          key = ESC;
--      case ESC:
--          break;
--      }
--    }
--
--    delwin (dialog);
--    return -1;                        /* ESC pressed */
--}
-diff -Nur busybox-1.00/scripts/config/lkc.h busybox/scripts/config/lkc.h
---- busybox-1.00/scripts/config/lkc.h  2003-08-05 04:18:24.000000000 +0200
-+++ busybox/scripts/config/lkc.h       2005-06-04 08:20:03.000000000 +0200
-@@ -56,11 +56,21 @@
- void menu_add_symbol(enum prop_type type, struct symbol *sym, struct expr *dep);
- void menu_finalize(struct menu *parent);
- void menu_set_type(int type);
-+
-+/* util.c */
- struct file *file_lookup(const char *name);
- int file_write_dep(const char *name);
--extern struct menu *current_entry;
--extern struct menu *current_menu;
-+struct gstr {
-+      size_t len;
-+      char  *s;
-+};
-+struct gstr str_new(void);
-+struct gstr str_assign(const char *s);
-+void str_free(struct gstr *gs);
-+void str_append(struct gstr *gs, const char *s);
-+void str_printf(struct gstr *gs, const char *fmt, ...);
-+const char *str_get(struct gstr *gs);
- /* symbol.c */
- void sym_init(void);
-diff -Nur busybox-1.00/scripts/config/lkc_proto.h busybox/scripts/config/lkc_proto.h
---- busybox-1.00/scripts/config/lkc_proto.h    2003-08-05 04:18:25.000000000 +0200
-+++ busybox/scripts/config/lkc_proto.h 2005-06-04 08:20:03.000000000 +0200
-@@ -18,6 +18,7 @@
- P(sym_lookup,struct symbol *,(const char *name, int isconst));
- P(sym_find,struct symbol *,(const char *name));
-+P(sym_re_search,struct symbol **,(const char *pattern));
- P(sym_type_name,const char *,(enum symbol_type type));
- P(sym_calc_value,void,(struct symbol *sym));
- P(sym_get_type,enum symbol_type,(struct symbol *sym));
-diff -Nur busybox-1.00/scripts/config/lxdialog/BIG.FAT.WARNING busybox/scripts/config/lxdialog/BIG.FAT.WARNING
---- busybox-1.00/scripts/config/lxdialog/BIG.FAT.WARNING       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/scripts/config/lxdialog/BIG.FAT.WARNING    2005-06-04 08:20:02.000000000 +0200
-@@ -0,0 +1,4 @@
-+This is NOT the official version of dialog.  This version has been
-+significantly modified from the original.  It is for use by the Linux
-+kernel configuration script.  Please do not bother Savio Lam with 
-+questions about this program.
-diff -Nur busybox-1.00/scripts/config/lxdialog/checklist.c busybox/scripts/config/lxdialog/checklist.c
---- busybox-1.00/scripts/config/lxdialog/checklist.c   1970-01-01 01:00:00.000000000 +0100
-+++ busybox/scripts/config/lxdialog/checklist.c        2005-06-04 08:20:02.000000000 +0200
-@@ -0,0 +1,372 @@
-+/*
-+ *  checklist.c -- implements the checklist box
-+ *
-+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-+ *     Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension
-+ *     Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two
-+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
-+ *
-+ *  This program is free software; you can redistribute it and/or
-+ *  modify it under the terms of the GNU General Public License
-+ *  as published by the Free Software Foundation; either version 2
-+ *  of the License, or (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include "dialog.h"
-+
-+static int list_width, check_x, item_x, checkflag;
-+
-+/*
-+ * Print list item
-+ */
-+static void
-+print_item (WINDOW * win, const char *item, int status,
-+          int choice, int selected)
-+{
-+    int i;
-+
-+    /* Clear 'residue' of last item */
-+    wattrset (win, menubox_attr);
-+    wmove (win, choice, 0);
-+    for (i = 0; i < list_width; i++)
-+      waddch (win, ' ');
-+
-+    wmove (win, choice, check_x);
-+    wattrset (win, selected ? check_selected_attr : check_attr);
-+    if (checkflag == FLAG_CHECK)
-+      wprintw (win, "[%c]", status ? 'X' : ' ');
-+    else
-+      wprintw (win, "(%c)", status ? 'X' : ' ');
-+
-+    wattrset (win, selected ? tag_selected_attr : tag_attr);
-+    mvwaddch(win, choice, item_x, item[0]);
-+    wattrset (win, selected ? item_selected_attr : item_attr);
-+    waddstr (win, (char *)item+1);
-+    if (selected) {
-+      wmove (win, choice, check_x+1);
-+      wrefresh (win);
-+    }
-+}
-+
-+/*
-+ * Print the scroll indicators.
-+ */
-+static void
-+print_arrows (WINDOW * win, int choice, int item_no, int scroll,
-+              int y, int x, int height)
-+{
-+    wmove(win, y, x);
-+
-+    if (scroll > 0) {
-+      wattrset (win, uarrow_attr);
-+      waddch (win, ACS_UARROW);
-+      waddstr (win, "(-)");
-+    }
-+    else {
-+      wattrset (win, menubox_attr);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+    }
-+
-+   y = y + height + 1;
-+   wmove(win, y, x);
-+
-+   if ((height < item_no) && (scroll + choice < item_no - 1)) {
-+      wattrset (win, darrow_attr);
-+      waddch (win, ACS_DARROW);
-+      waddstr (win, "(+)");
-+    }
-+    else {
-+      wattrset (win, menubox_border_attr);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+   }
-+}
-+
-+/*
-+ *  Display the termination buttons
-+ */
-+static void
-+print_buttons( WINDOW *dialog, int height, int width, int selected)
-+{
-+    int x = width / 2 - 11;
-+    int y = height - 2;
-+
-+    print_button (dialog, "Select", y, x, selected == 0);
-+    print_button (dialog, " Help ", y, x + 14, selected == 1);
-+
-+    wmove(dialog, y, x+1 + 14*selected);
-+    wrefresh (dialog);
-+}
-+
-+/*
-+ * Display a dialog box with a list of options that can be turned on or off
-+ * The `flag' parameter is used to select between radiolist and checklist.
-+ */
-+int
-+dialog_checklist (const char *title, const char *prompt, int height, int width,
-+      int list_height, int item_no, struct dialog_list_item ** items,
-+      int flag)
-+      
-+{
-+    int i, x, y, box_x, box_y;
-+    int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status;
-+    WINDOW *dialog, *list;
-+
-+    checkflag = flag;
-+
-+    /* Allocate space for storing item on/off status */
-+    if ((status = malloc (sizeof (int) * item_no)) == NULL) {
-+      endwin ();
-+      fprintf (stderr,
-+               "\nCan't allocate memory in dialog_checklist().\n");
-+      exit (-1);
-+    }
-+
-+    /* Initializes status */
-+    for (i = 0; i < item_no; i++) {
-+      status[i] = (items[i]->selected == 1); /* ON */
-+      if ((!choice && status[i]) || items[i]->selected == 2) /* SELECTED */
-+            choice = i + 1;
-+    }
-+    if (choice)
-+          choice--;
-+
-+    max_choice = MIN (list_height, item_no);
-+
-+    /* center dialog box on screen */
-+    x = (COLS - width) / 2;
-+    y = (LINES - height) / 2;
-+
-+    draw_shadow (stdscr, y, x, height, width);
-+
-+    dialog = newwin (height, width, y, x);
-+    keypad (dialog, TRUE);
-+
-+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-+    wattrset (dialog, border_attr);
-+    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-+    for (i = 0; i < width - 2; i++)
-+      waddch (dialog, ACS_HLINE);
-+    wattrset (dialog, dialog_attr);
-+    waddch (dialog, ACS_RTEE);
-+
-+    if (title != NULL && strlen(title) >= width-2 ) {
-+      /* truncate long title -- mec */
-+      char * title2 = malloc(width-2+1);
-+      memcpy( title2, title, width-2 );
-+      title2[width-2] = '\0';
-+      title = title2;
-+    }
-+
-+    if (title != NULL) {
-+      wattrset (dialog, title_attr);
-+      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-+      waddstr (dialog, (char *)title);
-+      waddch (dialog, ' ');
-+    }
-+
-+    wattrset (dialog, dialog_attr);
-+    print_autowrap (dialog, prompt, width - 2, 1, 3);
-+
-+    list_width = width - 6;
-+    box_y = height - list_height - 5;
-+    box_x = (width - list_width) / 2 - 1;
-+
-+    /* create new window for the list */
-+    list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1);
-+
-+    keypad (list, TRUE);
-+
-+    /* draw a box around the list items */
-+    draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2,
-+            menubox_border_attr, menubox_attr);
-+
-+    /* Find length of longest item in order to center checklist */
-+    check_x = 0;
-+    for (i = 0; i < item_no; i++) 
-+      check_x = MAX (check_x, + strlen (items[i]->name) + 4);
-+
-+    check_x = (list_width - check_x) / 2;
-+    item_x = check_x + 4;
-+
-+    if (choice >= list_height) {
-+      scroll = choice - list_height + 1;
-+      choice -= scroll;
-+    }
-+
-+    /* Print the list */
-+    for (i = 0; i < max_choice; i++) {
-+      print_item (list, items[scroll + i]->name,
-+                  status[i+scroll], i, i == choice);
-+    }
-+
-+    print_arrows(dialog, choice, item_no, scroll,
-+                      box_y, box_x + check_x + 5, list_height);
-+
-+    print_buttons(dialog, height, width, 0);
-+
-+    wnoutrefresh (list);
-+    wnoutrefresh (dialog);
-+    doupdate ();
-+
-+    while (key != ESC) {
-+      key = wgetch (dialog);
-+
-+      for (i = 0; i < max_choice; i++)
-+            if (toupper(key) == toupper(items[scroll + i]->name[0]))
-+                break;
-+
-+
-+      if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || 
-+          key == '+' || key == '-' ) {
-+          if (key == KEY_UP || key == '-') {
-+              if (!choice) {
-+                  if (!scroll)
-+                      continue;
-+                  /* Scroll list down */
-+                  if (list_height > 1) {
-+                      /* De-highlight current first item */
-+                      print_item (list, items[scroll]->name,
-+                                      status[scroll], 0, FALSE);
-+                      scrollok (list, TRUE);
-+                      wscrl (list, -1);
-+                      scrollok (list, FALSE);
-+                  }
-+                  scroll--;
-+                  print_item (list, items[scroll]->name,
-+                              status[scroll], 0, TRUE);
-+                  wnoutrefresh (list);
-+
-+                  print_arrows(dialog, choice, item_no, scroll,
-+                              box_y, box_x + check_x + 5, list_height);
-+
-+                  wrefresh (dialog);
-+
-+                  continue;   /* wait for another key press */
-+              } else
-+                  i = choice - 1;
-+          } else if (key == KEY_DOWN || key == '+') {
-+              if (choice == max_choice - 1) {
-+                  if (scroll + choice >= item_no - 1)
-+                      continue;
-+                  /* Scroll list up */
-+                  if (list_height > 1) {
-+                      /* De-highlight current last item before scrolling up */
-+                      print_item (list, items[scroll + max_choice - 1]->name,
-+                                  status[scroll + max_choice - 1],
-+                                  max_choice - 1, FALSE);
-+                      scrollok (list, TRUE);
-+                      scroll (list);
-+                      scrollok (list, FALSE);
-+                  }
-+                  scroll++;
-+                  print_item (list, items[scroll + max_choice - 1]->name,
-+                              status[scroll + max_choice - 1],
-+                              max_choice - 1, TRUE);
-+                  wnoutrefresh (list);
-+
-+                  print_arrows(dialog, choice, item_no, scroll,
-+                              box_y, box_x + check_x + 5, list_height);
-+
-+                  wrefresh (dialog);
-+
-+                  continue;   /* wait for another key press */
-+              } else
-+                  i = choice + 1;
-+          }
-+          if (i != choice) {
-+              /* De-highlight current item */
-+              print_item (list, items[scroll + choice]->name,
-+                          status[scroll + choice], choice, FALSE);
-+              /* Highlight new item */
-+              choice = i;
-+              print_item (list, items[scroll + choice]->name,
-+                          status[scroll + choice], choice, TRUE);
-+              wnoutrefresh (list);
-+              wrefresh (dialog);
-+          }
-+          continue;           /* wait for another key press */
-+      }
-+      switch (key) {
-+      case 'H':
-+      case 'h':
-+      case '?':
-+          for (i = 0; i < item_no; i++)
-+              items[i]->selected = 0;
-+          items[scroll + choice]->selected = 1;
-+          delwin (dialog);
-+          free (status);
-+          return 1;
-+      case TAB:
-+      case KEY_LEFT:
-+      case KEY_RIGHT:
-+          button = ((key == KEY_LEFT ? --button : ++button) < 0)
-+                      ? 1 : (button > 1 ? 0 : button);
-+
-+          print_buttons(dialog, height, width, button);
-+          wrefresh (dialog);
-+          break;
-+      case 'S':
-+      case 's':
-+      case ' ':
-+      case '\n':
-+          if (!button) {
-+              if (flag == FLAG_CHECK) {
-+                  status[scroll + choice] = !status[scroll + choice];
-+                  wmove (list, choice, check_x);
-+                  wattrset (list, check_selected_attr);
-+                  wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' ');
-+              } else {
-+                  if (!status[scroll + choice]) {
-+                      for (i = 0; i < item_no; i++)
-+                          status[i] = 0;
-+                      status[scroll + choice] = 1;
-+                      for (i = 0; i < max_choice; i++)
-+                          print_item (list, items[scroll + i]->name,
-+                                      status[scroll + i], i, i == choice);
-+                  }
-+              }
-+              wnoutrefresh (list);
-+              wrefresh (dialog);
-+            
-+              for (i = 0; i < item_no; i++) {
-+                      items[i]->selected = status[i];
-+              }
-+            } else {
-+                  for (i = 0; i < item_no; i++)
-+                          items[i]->selected = 0;
-+                  items[scroll + choice]->selected = 1;
-+          }
-+          delwin (dialog);
-+          free (status);
-+          return button;
-+      case 'X':
-+      case 'x':
-+          key = ESC;
-+      case ESC:
-+          break;
-+      }
-+
-+      /* Now, update everything... */
-+      doupdate ();
-+    }
-+    
-+
-+    delwin (dialog);
-+    free (status);
-+    return -1;                        /* ESC pressed */
-+}
-diff -Nur busybox-1.00/scripts/config/lxdialog/colors.h busybox/scripts/config/lxdialog/colors.h
---- busybox-1.00/scripts/config/lxdialog/colors.h      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/scripts/config/lxdialog/colors.h   2005-06-04 08:20:02.000000000 +0200
-@@ -0,0 +1,161 @@
-+/*
-+ *  colors.h -- color attribute definitions
-+ *
-+ *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-+ *
-+ *  This program is free software; you can redistribute it and/or
-+ *  modify it under the terms of the GNU General Public License
-+ *  as published by the Free Software Foundation; either version 2
-+ *  of the License, or (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+
-+/*
-+ *   Default color definitions
-+ *
-+ *   *_FG = foreground
-+ *   *_BG = background
-+ *   *_HL = highlight?
-+ */
-+#define SCREEN_FG                    COLOR_CYAN
-+#define SCREEN_BG                    COLOR_BLUE
-+#define SCREEN_HL                    TRUE
-+
-+#define SHADOW_FG                    COLOR_BLACK
-+#define SHADOW_BG                    COLOR_BLACK
-+#define SHADOW_HL                    TRUE
-+
-+#define DIALOG_FG                    COLOR_BLACK
-+#define DIALOG_BG                    COLOR_WHITE
-+#define DIALOG_HL                    FALSE
-+
-+#define TITLE_FG                     COLOR_YELLOW
-+#define TITLE_BG                     COLOR_WHITE
-+#define TITLE_HL                     TRUE
-+
-+#define BORDER_FG                    COLOR_WHITE
-+#define BORDER_BG                    COLOR_WHITE
-+#define BORDER_HL                    TRUE
-+
-+#define BUTTON_ACTIVE_FG             COLOR_WHITE
-+#define BUTTON_ACTIVE_BG             COLOR_BLUE
-+#define BUTTON_ACTIVE_HL             TRUE
-+
-+#define BUTTON_INACTIVE_FG           COLOR_BLACK
-+#define BUTTON_INACTIVE_BG           COLOR_WHITE
-+#define BUTTON_INACTIVE_HL           FALSE
-+
-+#define BUTTON_KEY_ACTIVE_FG         COLOR_WHITE
-+#define BUTTON_KEY_ACTIVE_BG         COLOR_BLUE
-+#define BUTTON_KEY_ACTIVE_HL         TRUE
-+
-+#define BUTTON_KEY_INACTIVE_FG       COLOR_RED
-+#define BUTTON_KEY_INACTIVE_BG       COLOR_WHITE
-+#define BUTTON_KEY_INACTIVE_HL       FALSE
-+
-+#define BUTTON_LABEL_ACTIVE_FG       COLOR_YELLOW
-+#define BUTTON_LABEL_ACTIVE_BG       COLOR_BLUE
-+#define BUTTON_LABEL_ACTIVE_HL       TRUE
-+
-+#define BUTTON_LABEL_INACTIVE_FG     COLOR_BLACK
-+#define BUTTON_LABEL_INACTIVE_BG     COLOR_WHITE
-+#define BUTTON_LABEL_INACTIVE_HL     TRUE
-+
-+#define INPUTBOX_FG                  COLOR_BLACK
-+#define INPUTBOX_BG                  COLOR_WHITE
-+#define INPUTBOX_HL                  FALSE
-+
-+#define INPUTBOX_BORDER_FG           COLOR_BLACK
-+#define INPUTBOX_BORDER_BG           COLOR_WHITE
-+#define INPUTBOX_BORDER_HL           FALSE
-+
-+#define SEARCHBOX_FG                 COLOR_BLACK
-+#define SEARCHBOX_BG                 COLOR_WHITE
-+#define SEARCHBOX_HL                 FALSE
-+
-+#define SEARCHBOX_TITLE_FG           COLOR_YELLOW
-+#define SEARCHBOX_TITLE_BG           COLOR_WHITE
-+#define SEARCHBOX_TITLE_HL           TRUE
-+
-+#define SEARCHBOX_BORDER_FG          COLOR_WHITE
-+#define SEARCHBOX_BORDER_BG          COLOR_WHITE
-+#define SEARCHBOX_BORDER_HL          TRUE
-+
-+#define POSITION_INDICATOR_FG        COLOR_YELLOW
-+#define POSITION_INDICATOR_BG        COLOR_WHITE
-+#define POSITION_INDICATOR_HL        TRUE
-+
-+#define MENUBOX_FG                   COLOR_BLACK
-+#define MENUBOX_BG                   COLOR_WHITE
-+#define MENUBOX_HL                   FALSE
-+
-+#define MENUBOX_BORDER_FG            COLOR_WHITE
-+#define MENUBOX_BORDER_BG            COLOR_WHITE
-+#define MENUBOX_BORDER_HL            TRUE
-+
-+#define ITEM_FG                      COLOR_BLACK
-+#define ITEM_BG                      COLOR_WHITE
-+#define ITEM_HL                      FALSE
-+
-+#define ITEM_SELECTED_FG             COLOR_WHITE
-+#define ITEM_SELECTED_BG             COLOR_BLUE
-+#define ITEM_SELECTED_HL             TRUE
-+
-+#define TAG_FG                       COLOR_YELLOW
-+#define TAG_BG                       COLOR_WHITE
-+#define TAG_HL                       TRUE
-+
-+#define TAG_SELECTED_FG              COLOR_YELLOW
-+#define TAG_SELECTED_BG              COLOR_BLUE
-+#define TAG_SELECTED_HL              TRUE
-+
-+#define TAG_KEY_FG                   COLOR_YELLOW
-+#define TAG_KEY_BG                   COLOR_WHITE
-+#define TAG_KEY_HL                   TRUE
-+
-+#define TAG_KEY_SELECTED_FG          COLOR_YELLOW
-+#define TAG_KEY_SELECTED_BG          COLOR_BLUE
-+#define TAG_KEY_SELECTED_HL          TRUE
-+
-+#define CHECK_FG                     COLOR_BLACK
-+#define CHECK_BG                     COLOR_WHITE
-+#define CHECK_HL                     FALSE
-+
-+#define CHECK_SELECTED_FG            COLOR_WHITE
-+#define CHECK_SELECTED_BG            COLOR_BLUE
-+#define CHECK_SELECTED_HL            TRUE
-+
-+#define UARROW_FG                    COLOR_GREEN
-+#define UARROW_BG                    COLOR_WHITE
-+#define UARROW_HL                    TRUE
-+
-+#define DARROW_FG                    COLOR_GREEN
-+#define DARROW_BG                    COLOR_WHITE
-+#define DARROW_HL                    TRUE
-+
-+/* End of default color definitions */
-+
-+#define C_ATTR(x,y)                  ((x ? A_BOLD : 0) | COLOR_PAIR((y)))
-+#define COLOR_NAME_LEN               10
-+#define COLOR_COUNT                  8
-+
-+/*
-+ * Global variables
-+ */
-+
-+typedef struct {
-+    char name[COLOR_NAME_LEN];
-+    int value;
-+} color_names_st;
-+
-+extern color_names_st color_names[];
-+extern int color_table[][3];
-diff -Nur busybox-1.00/scripts/config/lxdialog/dialog.h busybox/scripts/config/lxdialog/dialog.h
---- busybox-1.00/scripts/config/lxdialog/dialog.h      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/scripts/config/lxdialog/dialog.h   2005-06-04 08:20:02.000000000 +0200
-@@ -0,0 +1,199 @@
-+
-+/*
-+ *  dialog.h -- common declarations for all dialog modules
-+ *
-+ *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-+ *
-+ *  This program is free software; you can redistribute it and/or
-+ *  modify it under the terms of the GNU General Public License
-+ *  as published by the Free Software Foundation; either version 2
-+ *  of the License, or (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include <sys/types.h>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <ctype.h>
-+#include <stdlib.h>
-+#include <string.h>
-+
-+#ifdef CURSES_LOC
-+#ifdef __sun__
-+#define CURS_MACROS
-+#endif
-+#include CURSES_LOC
-+
-+/*
-+ * Colors in ncurses 1.9.9e do not work properly since foreground and
-+ * background colors are OR'd rather than separately masked.  This version
-+ * of dialog was hacked to work with ncurses 1.9.9e, making it incompatible
-+ * with standard curses.  The simplest fix (to make this work with standard
-+ * curses) uses the wbkgdset() function, not used in the original hack.
-+ * Turn it off if we're building with 1.9.9e, since it just confuses things.
-+ */
-+#if defined(NCURSES_VERSION) && defined(_NEED_WRAP) && !defined(GCC_PRINTFLIKE)
-+#define OLD_NCURSES 1
-+#undef  wbkgdset
-+#define wbkgdset(w,p) /*nothing*/
-+#else
-+#define OLD_NCURSES 0
-+#endif
-+
-+#define TR(params) _tracef params
-+
-+#define ESC 27
-+#define TAB 9
-+#define MAX_LEN 2048
-+#define BUF_SIZE (10*1024)
-+#define MIN(x,y) (x < y ? x : y)
-+#define MAX(x,y) (x > y ? x : y)
-+
-+
-+#ifndef ACS_ULCORNER
-+#define ACS_ULCORNER '+'
-+#endif
-+#ifndef ACS_LLCORNER
-+#define ACS_LLCORNER '+'
-+#endif
-+#ifndef ACS_URCORNER
-+#define ACS_URCORNER '+'
-+#endif
-+#ifndef ACS_LRCORNER
-+#define ACS_LRCORNER '+'
-+#endif
-+#ifndef ACS_HLINE
-+#define ACS_HLINE '-'
-+#endif
-+#ifndef ACS_VLINE
-+#define ACS_VLINE '|'
-+#endif
-+#ifndef ACS_LTEE
-+#define ACS_LTEE '+'
-+#endif
-+#ifndef ACS_RTEE
-+#define ACS_RTEE '+'
-+#endif
-+#ifndef ACS_UARROW
-+#define ACS_UARROW '^'
-+#endif
-+#ifndef ACS_DARROW
-+#define ACS_DARROW 'v'
-+#endif
-+
-+/* 
-+ * Attribute names
-+ */
-+#define screen_attr                   attributes[0]
-+#define shadow_attr                   attributes[1]
-+#define dialog_attr                   attributes[2]
-+#define title_attr                    attributes[3]
-+#define border_attr                   attributes[4]
-+#define button_active_attr            attributes[5]
-+#define button_inactive_attr          attributes[6]
-+#define button_key_active_attr        attributes[7]
-+#define button_key_inactive_attr      attributes[8]
-+#define button_label_active_attr      attributes[9]
-+#define button_label_inactive_attr    attributes[10]
-+#define inputbox_attr                 attributes[11]
-+#define inputbox_border_attr          attributes[12]
-+#define searchbox_attr                attributes[13]
-+#define searchbox_title_attr          attributes[14]
-+#define searchbox_border_attr         attributes[15]
-+#define position_indicator_attr       attributes[16]
-+#define menubox_attr                  attributes[17]
-+#define menubox_border_attr           attributes[18]
-+#define item_attr                     attributes[19]
-+#define item_selected_attr            attributes[20]
-+#define tag_attr                      attributes[21]
-+#define tag_selected_attr             attributes[22]
-+#define tag_key_attr                  attributes[23]
-+#define tag_key_selected_attr         attributes[24]
-+#define check_attr                    attributes[25]
-+#define check_selected_attr           attributes[26]
-+#define uarrow_attr                   attributes[27]
-+#define darrow_attr                   attributes[28]
-+
-+/* number of attributes */
-+#define ATTRIBUTE_COUNT               29
-+
-+/*
-+ * Global variables
-+ */
-+extern bool use_colors;
-+
-+extern chtype attributes[];
-+#endif
-+
-+extern const char *backtitle;
-+
-+struct dialog_list_item {
-+      char *name;
-+      int namelen;
-+      char *tag;
-+      int selected; /* Set to 1 by dialog_*() function. */
-+};
-+
-+/*
-+ * Function prototypes
-+ */
-+
-+void init_dialog (void);
-+void end_dialog (void);
-+void dialog_clear (void);
-+#ifdef CURSES_LOC
-+void attr_clear (WINDOW * win, int height, int width, chtype attr);
-+void color_setup (void);
-+void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x);
-+void print_button (WINDOW * win, const char *label, int y, int x, int selected);
-+void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box,
-+              chtype border);
-+void draw_shadow (WINDOW * win, int y, int x, int height, int width);
-+#endif
-+
-+int first_alpha (const char *string, const char *exempt);
-+int dialog_yesno (const char *title, const char *prompt, int height, int width);
-+int dialog_msgbox (const char *title, const char *prompt, int height,
-+              int width, int pause);
-+int dialog_textbox (const char *title, const char *file, int height, int width);
-+int dialog_menu (const char *title, const char *prompt, int height, int width,
-+              int menu_height, const char *choice, int item_no, 
-+              struct dialog_list_item ** items);
-+int dialog_checklist (const char *title, const char *prompt, int height,
-+              int width, int list_height, int item_no,
-+              struct dialog_list_item ** items, int flag);
-+extern unsigned char dialog_input_result[];
-+int dialog_inputbox (const char *title, const char *prompt, int height,
-+              int width, const char *init);
-+
-+struct dialog_list_item *first_sel_item(int item_no,
-+              struct dialog_list_item ** items);
-+
-+/*
-+ * This is the base for fictitious keys, which activate
-+ * the buttons.
-+ *
-+ * Mouse-generated keys are the following:
-+ *   -- the first 32 are used as numbers, in addition to '0'-'9'
-+ *   -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o')
-+ *   -- uppercase chars are used to invoke the button (M_EVENT + 'O')
-+ */
-+#ifdef CURSES_LOC
-+#define M_EVENT (KEY_MAX+1)
-+#endif
-+
-+
-+/*
-+ * The `flag' parameter in checklist is used to select between
-+ * radiolist and checklist
-+ */
-+#define FLAG_CHECK 1
-+#define FLAG_RADIO 0
-diff -Nur busybox-1.00/scripts/config/lxdialog/inputbox.c busybox/scripts/config/lxdialog/inputbox.c
---- busybox-1.00/scripts/config/lxdialog/inputbox.c    1970-01-01 01:00:00.000000000 +0100
-+++ busybox/scripts/config/lxdialog/inputbox.c 2005-06-04 08:20:02.000000000 +0200
-@@ -0,0 +1,240 @@
-+/*
-+ *  inputbox.c -- implements the input box
-+ *
-+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
-+ *
-+ *  This program is free software; you can redistribute it and/or
-+ *  modify it under the terms of the GNU General Public License
-+ *  as published by the Free Software Foundation; either version 2
-+ *  of the License, or (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include "dialog.h"
-+
-+unsigned char dialog_input_result[MAX_LEN + 1];
-+
-+/*
-+ *  Print the termination buttons
-+ */
-+static void
-+print_buttons(WINDOW *dialog, int height, int width, int selected)
-+{
-+    int x = width / 2 - 11;
-+    int y = height - 2;
-+
-+    print_button (dialog, "  Ok  ", y, x, selected==0);
-+    print_button (dialog, " Help ", y, x + 14, selected==1);
-+
-+    wmove(dialog, y, x+1+14*selected);
-+    wrefresh(dialog);
-+}
-+
-+/*
-+ * Display a dialog box for inputing a string
-+ */
-+int
-+dialog_inputbox (const char *title, const char *prompt, int height, int width,
-+               const char *init)
-+{
-+    int i, x, y, box_y, box_x, box_width;
-+    int input_x = 0, scroll = 0, key = 0, button = -1;
-+    unsigned char *instr = dialog_input_result;
-+    WINDOW *dialog;
-+
-+    /* center dialog box on screen */
-+    x = (COLS - width) / 2;
-+    y = (LINES - height) / 2;
-+
-+
-+    draw_shadow (stdscr, y, x, height, width);
-+
-+    dialog = newwin (height, width, y, x);
-+    keypad (dialog, TRUE);
-+
-+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-+    wattrset (dialog, border_attr);
-+    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-+    for (i = 0; i < width - 2; i++)
-+      waddch (dialog, ACS_HLINE);
-+    wattrset (dialog, dialog_attr);
-+    waddch (dialog, ACS_RTEE);
-+
-+    if (title != NULL && strlen(title) >= width-2 ) {
-+      /* truncate long title -- mec */
-+      char * title2 = malloc(width-2+1);
-+      memcpy( title2, title, width-2 );
-+      title2[width-2] = '\0';
-+      title = title2;
-+    }
-+
-+    if (title != NULL) {
-+      wattrset (dialog, title_attr);
-+      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-+      waddstr (dialog, (char *)title);
-+      waddch (dialog, ' ');
-+    }
-+
-+    wattrset (dialog, dialog_attr);
-+    print_autowrap (dialog, prompt, width - 2, 1, 3);
-+
-+    /* Draw the input field box */
-+    box_width = width - 6;
-+    getyx (dialog, y, x);
-+    box_y = y + 2;
-+    box_x = (width - box_width) / 2;
-+    draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2,
-+            border_attr, dialog_attr);
-+
-+    print_buttons(dialog, height, width, 0);
-+
-+    /* Set up the initial value */
-+    wmove (dialog, box_y, box_x);
-+    wattrset (dialog, inputbox_attr);
-+
-+    if (!init)
-+      instr[0] = '\0';
-+    else
-+      strcpy (instr, init);
-+
-+    input_x = strlen (instr);
-+
-+    if (input_x >= box_width) {
-+      scroll = input_x - box_width + 1;
-+      input_x = box_width - 1;
-+      for (i = 0; i < box_width - 1; i++)
-+          waddch (dialog, instr[scroll + i]);
-+    } else
-+      waddstr (dialog, instr);
-+
-+    wmove (dialog, box_y, box_x + input_x);
-+
-+    wrefresh (dialog);
-+
-+    while (key != ESC) {
-+      key = wgetch (dialog);
-+
-+      if (button == -1) {     /* Input box selected */
-+          switch (key) {
-+          case TAB:
-+          case KEY_UP:
-+          case KEY_DOWN:
-+              break;
-+          case KEY_LEFT:
-+              continue;
-+          case KEY_RIGHT:
-+              continue;
-+          case KEY_BACKSPACE:
-+          case 127:
-+              if (input_x || scroll) {
-+                  wattrset (dialog, inputbox_attr);
-+                  if (!input_x) {
-+                      scroll = scroll < box_width - 1 ?
-+                          0 : scroll - (box_width - 1);
-+                      wmove (dialog, box_y, box_x);
-+                      for (i = 0; i < box_width; i++)
-+                          waddch (dialog, instr[scroll + input_x + i] ?
-+                                  instr[scroll + input_x + i] : ' ');
-+                      input_x = strlen (instr) - scroll;
-+                  } else
-+                      input_x--;
-+                  instr[scroll + input_x] = '\0';
-+                  mvwaddch (dialog, box_y, input_x + box_x, ' ');
-+                  wmove (dialog, box_y, input_x + box_x);
-+                  wrefresh (dialog);
-+              }
-+              continue;
-+          default:
-+              if (key < 0x100 && isprint (key)) {
-+                  if (scroll + input_x < MAX_LEN) {
-+                      wattrset (dialog, inputbox_attr);
-+                      instr[scroll + input_x] = key;
-+                      instr[scroll + input_x + 1] = '\0';
-+                      if (input_x == box_width - 1) {
-+                          scroll++;
-+                          wmove (dialog, box_y, box_x);
-+                          for (i = 0; i < box_width - 1; i++)
-+                              waddch (dialog, instr[scroll + i]);
-+                      } else {
-+                          wmove (dialog, box_y, input_x++ + box_x);
-+                          waddch (dialog, key);
-+                      }
-+                      wrefresh (dialog);
-+                  } else
-+                      flash ();       /* Alarm user about overflow */
-+                  continue;
-+              }
-+          }
-+      }
-+      switch (key) {
-+      case 'O':
-+      case 'o':
-+          delwin (dialog);
-+          return 0;
-+      case 'H':
-+      case 'h':
-+          delwin (dialog);
-+          return 1;
-+      case KEY_UP:
-+      case KEY_LEFT:
-+          switch (button) {
-+          case -1:
-+              button = 1;     /* Indicates "Cancel" button is selected */
-+              print_buttons(dialog, height, width, 1);
-+              break;
-+          case 0:
-+              button = -1;    /* Indicates input box is selected */
-+              print_buttons(dialog, height, width, 0);
-+              wmove (dialog, box_y, box_x + input_x);
-+              wrefresh (dialog);
-+              break;
-+          case 1:
-+              button = 0;     /* Indicates "OK" button is selected */
-+              print_buttons(dialog, height, width, 0);
-+              break;
-+          }
-+          break;
-+      case TAB:
-+      case KEY_DOWN:
-+      case KEY_RIGHT:
-+          switch (button) {
-+          case -1:
-+              button = 0;     /* Indicates "OK" button is selected */
-+              print_buttons(dialog, height, width, 0);
-+              break;
-+          case 0:
-+              button = 1;     /* Indicates "Cancel" button is selected */
-+              print_buttons(dialog, height, width, 1);
-+              break;
-+          case 1:
-+              button = -1;    /* Indicates input box is selected */
-+              print_buttons(dialog, height, width, 0);
-+              wmove (dialog, box_y, box_x + input_x);
-+              wrefresh (dialog);
-+              break;
-+          }
-+          break;
-+      case ' ':
-+      case '\n':
-+          delwin (dialog);
-+          return (button == -1 ? 0 : button);
-+      case 'X':
-+      case 'x':
-+          key = ESC;
-+      case ESC:
-+          break;
-+      }
-+    }
-+
-+    delwin (dialog);
-+    return -1;                        /* ESC pressed */
-+}
-diff -Nur busybox-1.00/scripts/config/lxdialog/menubox.c busybox/scripts/config/lxdialog/menubox.c
---- busybox-1.00/scripts/config/lxdialog/menubox.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/scripts/config/lxdialog/menubox.c  2005-06-04 08:20:02.000000000 +0200
-@@ -0,0 +1,438 @@
-+/*
-+ *  menubox.c -- implements the menu box
-+ *
-+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
-+ *
-+ *  This program is free software; you can redistribute it and/or
-+ *  modify it under the terms of the GNU General Public License
-+ *  as published by the Free Software Foundation; either version 2
-+ *  of the License, or (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+/*
-+ *  Changes by Clifford Wolf (god@clifford.at)
-+ *
-+ *  [ 1998-06-13 ]
-+ *
-+ *    *)  A bugfix for the Page-Down problem
-+ *
-+ *    *)  Formerly when I used Page Down and Page Up, the cursor would be set 
-+ *        to the first position in the menu box.  Now lxdialog is a bit
-+ *        smarter and works more like other menu systems (just have a look at
-+ *        it).
-+ *
-+ *    *)  Formerly if I selected something my scrolling would be broken because
-+ *        lxdialog is re-invoked by the Menuconfig shell script, can't
-+ *        remember the last scrolling position, and just sets it so that the
-+ *        cursor is at the bottom of the box.  Now it writes the temporary file
-+ *        lxdialog.scrltmp which contains this information. The file is
-+ *        deleted by lxdialog if the user leaves a submenu or enters a new
-+ *        one, but it would be nice if Menuconfig could make another "rm -f"
-+ *        just to be sure.  Just try it out - you will recognise a difference!
-+ *
-+ *  [ 1998-06-14 ]
-+ *
-+ *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
-+ *        and menus change their size on the fly.
-+ *
-+ *    *)  If for some reason the last scrolling position is not saved by
-+ *        lxdialog, it sets the scrolling so that the selected item is in the
-+ *        middle of the menu box, not at the bottom.
-+ *
-+ * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
-+ * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
-+ * This fixes a bug in Menuconfig where using ' ' to descend into menus
-+ * would leave mis-synchronized lxdialog.scrltmp files lying around,
-+ * fscanf would read in 'scroll', and eventually that value would get used.
-+ */
-+
-+#include "dialog.h"
-+
-+static int menu_width, item_x;
-+
-+/*
-+ * Print menu item
-+ */
-+static void
-+print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
-+{
-+    int j;
-+    char menu_item[menu_width+1];
-+
-+    strncpy(menu_item, item, menu_width);
-+    menu_item[menu_width] = 0;
-+    j = first_alpha(menu_item, "YyNnMmHh");
-+
-+    /* Clear 'residue' of last item */
-+    wattrset (win, menubox_attr);
-+    wmove (win, choice, 0);
-+#if OLD_NCURSES
-+    {
-+        int i;
-+        for (i = 0; i < menu_width; i++)
-+          waddch (win, ' ');
-+    }
-+#else
-+    wclrtoeol(win);
-+#endif
-+    wattrset (win, selected ? item_selected_attr : item_attr);
-+    mvwaddstr (win, choice, item_x, menu_item);
-+    if (hotkey) {
-+      wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
-+      mvwaddch(win, choice, item_x+j, menu_item[j]);
-+    }
-+    if (selected) {
-+      wmove (win, choice, item_x+1);
-+      wrefresh (win);
-+    }
-+}
-+
-+/*
-+ * Print the scroll indicators.
-+ */
-+static void
-+print_arrows (WINDOW * win, int item_no, int scroll,
-+              int y, int x, int height)
-+{
-+    int cur_y, cur_x;
-+
-+    getyx(win, cur_y, cur_x);
-+
-+    wmove(win, y, x);
-+
-+    if (scroll > 0) {
-+      wattrset (win, uarrow_attr);
-+      waddch (win, ACS_UARROW);
-+      waddstr (win, "(-)");
-+    }
-+    else {
-+      wattrset (win, menubox_attr);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+    }
-+
-+   y = y + height + 1;
-+   wmove(win, y, x);
-+
-+   if ((height < item_no) && (scroll + height < item_no)) {
-+      wattrset (win, darrow_attr);
-+      waddch (win, ACS_DARROW);
-+      waddstr (win, "(+)");
-+    }
-+    else {
-+      wattrset (win, menubox_border_attr);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+      waddch (win, ACS_HLINE);
-+   }
-+
-+   wmove(win, cur_y, cur_x);
-+}
-+
-+/*
-+ * Display the termination buttons.
-+ */
-+static void
-+print_buttons (WINDOW *win, int height, int width, int selected)
-+{
-+    int x = width / 2 - 16;
-+    int y = height - 2;
-+
-+    print_button (win, "Select", y, x, selected == 0);
-+    print_button (win, " Exit ", y, x + 12, selected == 1);
-+    print_button (win, " Help ", y, x + 24, selected == 2);
-+
-+    wmove(win, y, x+1+12*selected);
-+    wrefresh (win);
-+}
-+
-+/*
-+ * Display a menu for choosing among a number of options
-+ */
-+int
-+dialog_menu (const char *title, const char *prompt, int height, int width,
-+              int menu_height, const char *current, int item_no,
-+              struct dialog_list_item ** items)
-+{
-+    int i, j, x, y, box_x, box_y;
-+    int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
-+    WINDOW *dialog, *menu;
-+    FILE *f;
-+
-+    max_choice = MIN (menu_height, item_no);
-+
-+    /* center dialog box on screen */
-+    x = (COLS - width) / 2;
-+    y = (LINES - height) / 2;
-+
-+    draw_shadow (stdscr, y, x, height, width);
-+
-+    dialog = newwin (height, width, y, x);
-+    keypad (dialog, TRUE);
-+
-+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-+    wattrset (dialog, border_attr);
-+    mvwaddch (dialog, height - 3, 0, ACS_LTEE);
-+    for (i = 0; i < width - 2; i++)
-+      waddch (dialog, ACS_HLINE);
-+    wattrset (dialog, dialog_attr);
-+    wbkgdset (dialog, dialog_attr & A_COLOR);
-+    waddch (dialog, ACS_RTEE);
-+
-+    if (title != NULL && strlen(title) >= width-2 ) {
-+      /* truncate long title -- mec */
-+      char * title2 = malloc(width-2+1);
-+      memcpy( title2, title, width-2 );
-+      title2[width-2] = '\0';
-+      title = title2;
-+    }
-+
-+    if (title != NULL) {
-+      wattrset (dialog, title_attr);
-+      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-+      waddstr (dialog, (char *)title);
-+      waddch (dialog, ' ');
-+    }
-+
-+    wattrset (dialog, dialog_attr);
-+    print_autowrap (dialog, prompt, width - 2, 1, 3);
-+
-+    menu_width = width - 6;
-+    box_y = height - menu_height - 5;
-+    box_x = (width - menu_width) / 2 - 1;
-+
-+    /* create new window for the menu */
-+    menu = subwin (dialog, menu_height, menu_width,
-+              y + box_y + 1, x + box_x + 1);
-+    keypad (menu, TRUE);
-+
-+    /* draw a box around the menu items */
-+    draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
-+            menubox_border_attr, menubox_attr);
-+
-+    /*
-+     * Find length of longest item in order to center menu.
-+     * Set 'choice' to default item. 
-+     */
-+    item_x = 0;
-+    for (i = 0; i < item_no; i++) {
-+      item_x = MAX (item_x, MIN(menu_width, strlen (items[i]->name) + 2));
-+      if (strcmp(current, items[i]->tag) == 0) choice = i;
-+    }
-+
-+    item_x = (menu_width - item_x) / 2;
-+
-+    /* get the scroll info from the temp file */
-+    if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
-+      if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
-+           (scroll+max_choice > choice) && (scroll >= 0) &&
-+           (scroll+max_choice <= item_no) ) {
-+          first_item = scroll;
-+          choice = choice - scroll;
-+          fclose(f);
-+      } else {
-+          scroll=0;
-+          remove("lxdialog.scrltmp");
-+          fclose(f);
-+          f=NULL;
-+      }
-+    }
-+    if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
-+      if (choice >= item_no-max_choice/2)
-+          scroll = first_item = item_no-max_choice;
-+      else
-+          scroll = first_item = choice - max_choice/2;
-+      choice = choice - scroll;
-+    }
-+
-+    /* Print the menu */
-+    for (i=0; i < max_choice; i++) {
-+      print_item (menu, items[first_item + i]->name, i, i == choice,
-+                    (items[first_item + i]->tag[0] != ':'));
-+    }
-+
-+    wnoutrefresh (menu);
-+
-+    print_arrows(dialog, item_no, scroll,
-+               box_y, box_x+item_x+1, menu_height);
-+
-+    print_buttons (dialog, height, width, 0);
-+    wmove (menu, choice, item_x+1);
-+    wrefresh (menu);
-+
-+    while (key != ESC) {
-+      key = wgetch(menu);
-+
-+      if (key < 256 && isalpha(key)) key = tolower(key);
-+
-+      if (strchr("ynmh", key))
-+              i = max_choice;
-+      else {
-+        for (i = choice+1; i < max_choice; i++) {
-+              j = first_alpha(items[scroll + i]->name, "YyNnMmHh");
-+              if (key == tolower(items[scroll + i]->name[j]))
-+                      break;
-+      }
-+      if (i == max_choice)
-+                      for (i = 0; i < max_choice; i++) {
-+                      j = first_alpha(items[scroll + i]->name, "YyNnMmHh");
-+                      if (key == tolower(items[scroll + i]->name[j]))
-+                              break;
-+              }
-+      }
-+
-+      if (i < max_choice || 
-+            key == KEY_UP || key == KEY_DOWN ||
-+            key == '-' || key == '+' ||
-+            key == KEY_PPAGE || key == KEY_NPAGE) {
-+
-+            print_item (menu, items[scroll + choice]->name, choice, FALSE,
-+                       (items[scroll + choice]->tag[0] != ':'));
-+
-+          if (key == KEY_UP || key == '-') {
-+                if (choice < 2 && scroll) {
-+                  /* Scroll menu down */
-+                    scrollok (menu, TRUE);
-+                    wscrl (menu, -1);
-+                    scrollok (menu, FALSE);
-+
-+                    scroll--;
-+
-+                    print_item (menu, items[scroll]->name, 0, FALSE,
-+                               (items[scroll]->tag[0] != ':'));
-+              } else
-+                  choice = MAX(choice - 1, 0);
-+
-+          } else if (key == KEY_DOWN || key == '+')  {
-+
-+              print_item (menu, items[scroll + choice]->name, choice, FALSE,
-+                                (items[scroll + choice]->tag[0] != ':'));
-+
-+                if ((choice > max_choice-3) &&
-+                    (scroll + max_choice < item_no)
-+                   ) {
-+                  /* Scroll menu up */
-+                  scrollok (menu, TRUE);
-+                    scroll (menu);
-+                    scrollok (menu, FALSE);
-+
-+                    scroll++;
-+
-+                    print_item (menu, items[scroll + max_choice - 1]->name,
-+                               max_choice-1, FALSE,
-+                               (items[scroll + max_choice - 1]->tag[0] != ':'));
-+                } else
-+                    choice = MIN(choice+1, max_choice-1);
-+
-+          } else if (key == KEY_PPAGE) {
-+              scrollok (menu, TRUE);
-+                for (i=0; (i < max_choice); i++) {
-+                    if (scroll > 0) {
-+                      wscrl (menu, -1);
-+                      scroll--;
-+                      print_item (menu, items[scroll]->name, 0, FALSE,
-+                      (items[scroll]->tag[0] != ':'));
-+                    } else {
-+                        if (choice > 0)
-+                            choice--;
-+                    }
-+                }
-+                scrollok (menu, FALSE);
-+
-+            } else if (key == KEY_NPAGE) {
-+                for (i=0; (i < max_choice); i++) {
-+                    if (scroll+max_choice < item_no) {
-+                      scrollok (menu, TRUE);
-+                      scroll(menu);
-+                      scrollok (menu, FALSE);
-+                      scroll++;
-+                      print_item (menu, items[scroll + max_choice - 1]->name,
-+                                  max_choice-1, FALSE,
-+                                  (items[scroll + max_choice - 1]->tag[0] != ':'));
-+                  } else {
-+                      if (choice+1 < max_choice)
-+                          choice++;
-+                  }
-+                }
-+
-+            } else
-+                choice = i;
-+
-+            print_item (menu, items[scroll + choice]->name, choice, TRUE,
-+                       (items[scroll + choice]->tag[0] != ':'));
-+
-+            print_arrows(dialog, item_no, scroll,
-+                         box_y, box_x+item_x+1, menu_height);
-+
-+            wnoutrefresh (dialog);
-+            wrefresh (menu);
-+
-+          continue;           /* wait for another key press */
-+        }
-+
-+      switch (key) {
-+      case KEY_LEFT:
-+      case TAB:
-+      case KEY_RIGHT:
-+          button = ((key == KEY_LEFT ? --button : ++button) < 0)
-+                      ? 2 : (button > 2 ? 0 : button);
-+
-+          print_buttons(dialog, height, width, button);
-+          wrefresh (menu);
-+          break;
-+      case ' ':
-+      case 's':
-+      case 'y':
-+      case 'n':
-+      case 'm':
-+      case '/':
-+          /* save scroll info */
-+          if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
-+              fprintf(f,"%d\n",scroll);
-+              fclose(f);
-+          }
-+          delwin (dialog);
-+            items[scroll + choice]->selected = 1;
-+            switch (key) {
-+            case 's': return 3;
-+            case 'y': return 3;
-+            case 'n': return 4;
-+            case 'm': return 5;
-+            case ' ': return 6;
-+            case '/': return 7;
-+            }
-+          return 0;
-+      case 'h':
-+      case '?':
-+          button = 2;
-+      case '\n':
-+          delwin (dialog);
-+          items[scroll + choice]->selected = 1;
-+
-+          remove("lxdialog.scrltmp");
-+          return button;
-+      case 'e':
-+      case 'x':
-+          key = ESC;
-+      case ESC:
-+          break;
-+      }
-+    }
-+
-+    delwin (dialog);
-+    remove("lxdialog.scrltmp");
-+    return -1;                        /* ESC pressed */
-+}
-diff -Nur busybox-1.00/scripts/config/lxdialog/msgbox.c busybox/scripts/config/lxdialog/msgbox.c
---- busybox-1.00/scripts/config/lxdialog/msgbox.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/scripts/config/lxdialog/msgbox.c   2005-06-04 08:20:02.000000000 +0200
-@@ -0,0 +1,85 @@
-+/*
-+ *  msgbox.c -- implements the message box and info box
-+ *
-+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
-+ *
-+ *  This program is free software; you can redistribute it and/or
-+ *  modify it under the terms of the GNU General Public License
-+ *  as published by the Free Software Foundation; either version 2
-+ *  of the License, or (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include "dialog.h"
-+
-+/*
-+ * Display a message box. Program will pause and display an "OK" button
-+ * if the parameter 'pause' is non-zero.
-+ */
-+int
-+dialog_msgbox (const char *title, const char *prompt, int height, int width,
-+              int pause)
-+{
-+    int i, x, y, key = 0;
-+    WINDOW *dialog;
-+
-+    /* center dialog box on screen */
-+    x = (COLS - width) / 2;
-+    y = (LINES - height) / 2;
-+
-+    draw_shadow (stdscr, y, x, height, width);
-+
-+    dialog = newwin (height, width, y, x);
-+    keypad (dialog, TRUE);
-+
-+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-+
-+    if (title != NULL && strlen(title) >= width-2 ) {
-+      /* truncate long title -- mec */
-+      char * title2 = malloc(width-2+1);
-+      memcpy( title2, title, width-2 );
-+      title2[width-2] = '\0';
-+      title = title2;
-+    }
-+
-+    if (title != NULL) {
-+      wattrset (dialog, title_attr);
-+      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-+      waddstr (dialog, (char *)title);
-+      waddch (dialog, ' ');
-+    }
-+    wattrset (dialog, dialog_attr);
-+    print_autowrap (dialog, prompt, width - 2, 1, 2);
-+
-+    if (pause) {
-+      wattrset (dialog, border_attr);
-+      mvwaddch (dialog, height - 3, 0, ACS_LTEE);
-+      for (i = 0; i < width - 2; i++)
-+          waddch (dialog, ACS_HLINE);
-+      wattrset (dialog, dialog_attr);
-+      waddch (dialog, ACS_RTEE);
-+
-+      print_button (dialog, "  Ok  ",
-+                    height - 2, width / 2 - 4, TRUE);
-+
-+      wrefresh (dialog);
-+      while (key != ESC && key != '\n' && key != ' ' &&
-+               key != 'O' && key != 'o' && key != 'X' && key != 'x')
-+          key = wgetch (dialog);
-+    } else {
-+      key = '\n';
-+      wrefresh (dialog);
-+    }
-+
-+    delwin (dialog);
-+    return key == ESC ? -1 : 0;
-+}
-diff -Nur busybox-1.00/scripts/config/lxdialog/textbox.c busybox/scripts/config/lxdialog/textbox.c
---- busybox-1.00/scripts/config/lxdialog/textbox.c     1970-01-01 01:00:00.000000000 +0100
-+++ busybox/scripts/config/lxdialog/textbox.c  2005-06-04 08:20:02.000000000 +0200
-@@ -0,0 +1,556 @@
-+/*
-+ *  textbox.c -- implements the text box
-+ *
-+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
-+ *
-+ *  This program is free software; you can redistribute it and/or
-+ *  modify it under the terms of the GNU General Public License
-+ *  as published by the Free Software Foundation; either version 2
-+ *  of the License, or (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include "dialog.h"
-+
-+static void back_lines (int n);
-+static void print_page (WINDOW * win, int height, int width);
-+static void print_line (WINDOW * win, int row, int width);
-+static char *get_line (void);
-+static void print_position (WINDOW * win, int height, int width);
-+
-+static int hscroll, fd, file_size, bytes_read;
-+static int begin_reached = 1, end_reached, page_length;
-+static char *buf, *page;
-+
-+/*
-+ * Display text from a file in a dialog box.
-+ */
-+int
-+dialog_textbox (const char *title, const char *file, int height, int width)
-+{
-+    int i, x, y, cur_x, cur_y, fpos, key = 0;
-+    int passed_end;
-+    char search_term[MAX_LEN + 1];
-+    WINDOW *dialog, *text;
-+
-+    search_term[0] = '\0';    /* no search term entered yet */
-+
-+    /* Open input file for reading */
-+    if ((fd = open (file, O_RDONLY)) == -1) {
-+      endwin ();
-+      fprintf (stderr,
-+               "\nCan't open input file in dialog_textbox().\n");
-+      exit (-1);
-+    }
-+    /* Get file size. Actually, 'file_size' is the real file size - 1,
-+       since it's only the last byte offset from the beginning */
-+    if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
-+      endwin ();
-+      fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
-+      exit (-1);
-+    }
-+    /* Restore file pointer to beginning of file after getting file size */
-+    if (lseek (fd, 0, SEEK_SET) == -1) {
-+      endwin ();
-+      fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
-+      exit (-1);
-+    }
-+    /* Allocate space for read buffer */
-+    if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
-+      endwin ();
-+      fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
-+      exit (-1);
-+    }
-+    if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-+      endwin ();
-+      fprintf (stderr, "\nError reading file in dialog_textbox().\n");
-+      exit (-1);
-+    }
-+    buf[bytes_read] = '\0';   /* mark end of valid data */
-+    page = buf;                       /* page is pointer to start of page to be displayed */
-+
-+    /* center dialog box on screen */
-+    x = (COLS - width) / 2;
-+    y = (LINES - height) / 2;
-+
-+
-+    draw_shadow (stdscr, y, x, height, width);
-+
-+    dialog = newwin (height, width, y, x);
-+    keypad (dialog, TRUE);
-+
-+    /* Create window for text region, used for scrolling text */
-+    text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
-+    wattrset (text, dialog_attr);
-+    wbkgdset (text, dialog_attr & A_COLOR);
-+
-+    keypad (text, TRUE);
-+
-+    /* register the new window, along with its borders */
-+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-+
-+    wattrset (dialog, border_attr);
-+    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-+    for (i = 0; i < width - 2; i++)
-+      waddch (dialog, ACS_HLINE);
-+    wattrset (dialog, dialog_attr);
-+    wbkgdset (dialog, dialog_attr & A_COLOR);
-+    waddch (dialog, ACS_RTEE);
-+
-+    if (title != NULL && strlen(title) >= width-2 ) {
-+      /* truncate long title -- mec */
-+      char * title2 = malloc(width-2+1);
-+      memcpy( title2, title, width-2 );
-+      title2[width-2] = '\0';
-+      title = title2;
-+    }
-+
-+    if (title != NULL) {
-+      wattrset (dialog, title_attr);
-+      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-+      waddstr (dialog, (char *)title);
-+      waddch (dialog, ' ');
-+    }
-+    print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
-+    wnoutrefresh (dialog);
-+    getyx (dialog, cur_y, cur_x);     /* Save cursor position */
-+
-+    /* Print first page of text */
-+    attr_clear (text, height - 4, width - 2, dialog_attr);
-+    print_page (text, height - 4, width - 2);
-+    print_position (dialog, height, width);
-+    wmove (dialog, cur_y, cur_x);     /* Restore cursor position */
-+    wrefresh (dialog);
-+
-+    while ((key != ESC) && (key != '\n')) {
-+      key = wgetch (dialog);
-+      switch (key) {
-+      case 'E':               /* Exit */
-+      case 'e':
-+      case 'X':
-+      case 'x':
-+          delwin (dialog);
-+          free (buf);
-+          close (fd);
-+          return 0;
-+      case 'g':               /* First page */
-+      case KEY_HOME:
-+          if (!begin_reached) {
-+              begin_reached = 1;
-+              /* First page not in buffer? */
-+              if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-+                  endwin ();
-+                  fprintf (stderr,
-+                    "\nError moving file pointer in dialog_textbox().\n");
-+                  exit (-1);
-+              }
-+              if (fpos > bytes_read) {        /* Yes, we have to read it in */
-+                  if (lseek (fd, 0, SEEK_SET) == -1) {
-+                      endwin ();
-+                      fprintf (stderr, "\nError moving file pointer in "
-+                               "dialog_textbox().\n");
-+                      exit (-1);
-+                  }
-+                  if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-+                      endwin ();
-+                      fprintf (stderr,
-+                           "\nError reading file in dialog_textbox().\n");
-+                      exit (-1);
-+                  }
-+                  buf[bytes_read] = '\0';
-+              }
-+              page = buf;
-+              print_page (text, height - 4, width - 2);
-+              print_position (dialog, height, width);
-+              wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
-+              wrefresh (dialog);
-+          }
-+          break;
-+      case 'G':               /* Last page */
-+      case KEY_END:
-+
-+          end_reached = 1;
-+          /* Last page not in buffer? */
-+          if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-+              endwin ();
-+              fprintf (stderr,
-+                    "\nError moving file pointer in dialog_textbox().\n");
-+              exit (-1);
-+          }
-+          if (fpos < file_size) {     /* Yes, we have to read it in */
-+              if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
-+                  endwin ();
-+                  fprintf (stderr,
-+                    "\nError moving file pointer in dialog_textbox().\n");
-+                  exit (-1);
-+              }
-+              if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-+                  endwin ();
-+                  fprintf (stderr,
-+                           "\nError reading file in dialog_textbox().\n");
-+                  exit (-1);
-+              }
-+              buf[bytes_read] = '\0';
-+          }
-+          page = buf + bytes_read;
-+          back_lines (height - 4);
-+          print_page (text, height - 4, width - 2);
-+          print_position (dialog, height, width);
-+          wmove (dialog, cur_y, cur_x);       /* Restore cursor position */
-+          wrefresh (dialog);
-+          break;
-+      case 'K':               /* Previous line */
-+      case 'k':
-+      case KEY_UP:
-+          if (!begin_reached) {
-+              back_lines (page_length + 1);
-+
-+              /* We don't call print_page() here but use scrolling to ensure
-+                 faster screen update. However, 'end_reached' and
-+                 'page_length' should still be updated, and 'page' should
-+                 point to start of next page. This is done by calling
-+                 get_line() in the following 'for' loop. */
-+              scrollok (text, TRUE);
-+              wscrl (text, -1);       /* Scroll text region down one line */
-+              scrollok (text, FALSE);
-+              page_length = 0;
-+              passed_end = 0;
-+              for (i = 0; i < height - 4; i++) {
-+                  if (!i) {
-+                      /* print first line of page */
-+                      print_line (text, 0, width - 2);
-+                      wnoutrefresh (text);
-+                  } else
-+                      /* Called to update 'end_reached' and 'page' */
-+                      get_line ();
-+                  if (!passed_end)
-+                      page_length++;
-+                  if (end_reached && !passed_end)
-+                      passed_end = 1;
-+              }
-+
-+              print_position (dialog, height, width);
-+              wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
-+              wrefresh (dialog);
-+          }
-+          break;
-+      case 'B':               /* Previous page */
-+      case 'b':
-+      case KEY_PPAGE:
-+          if (begin_reached)
-+              break;
-+          back_lines (page_length + height - 4);
-+          print_page (text, height - 4, width - 2);
-+          print_position (dialog, height, width);
-+          wmove (dialog, cur_y, cur_x);
-+          wrefresh (dialog);
-+          break;
-+      case 'J':               /* Next line */
-+      case 'j':
-+      case KEY_DOWN:
-+          if (!end_reached) {
-+              begin_reached = 0;
-+              scrollok (text, TRUE);
-+              scroll (text);  /* Scroll text region up one line */
-+              scrollok (text, FALSE);
-+              print_line (text, height - 5, width - 2);
-+              wnoutrefresh (text);
-+              print_position (dialog, height, width);
-+              wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
-+              wrefresh (dialog);
-+          }
-+          break;
-+      case KEY_NPAGE:         /* Next page */
-+      case ' ':
-+          if (end_reached)
-+              break;
-+
-+          begin_reached = 0;
-+          print_page (text, height - 4, width - 2);
-+          print_position (dialog, height, width);
-+          wmove (dialog, cur_y, cur_x);
-+          wrefresh (dialog);
-+          break;
-+      case '0':               /* Beginning of line */
-+      case 'H':               /* Scroll left */
-+      case 'h':
-+      case KEY_LEFT:
-+          if (hscroll <= 0)
-+              break;
-+
-+          if (key == '0')
-+              hscroll = 0;
-+          else
-+              hscroll--;
-+          /* Reprint current page to scroll horizontally */
-+          back_lines (page_length);
-+          print_page (text, height - 4, width - 2);
-+          wmove (dialog, cur_y, cur_x);
-+          wrefresh (dialog);
-+          break;
-+      case 'L':               /* Scroll right */
-+      case 'l':
-+      case KEY_RIGHT:
-+          if (hscroll >= MAX_LEN)
-+              break;
-+          hscroll++;
-+          /* Reprint current page to scroll horizontally */
-+          back_lines (page_length);
-+          print_page (text, height - 4, width - 2);
-+          wmove (dialog, cur_y, cur_x);
-+          wrefresh (dialog);
-+          break;
-+      case ESC:
-+          break;
-+      }
-+    }
-+
-+    delwin (dialog);
-+    free (buf);
-+    close (fd);
-+    return 1;                 /* ESC pressed */
-+}
-+
-+/*
-+ * Go back 'n' lines in text file. Called by dialog_textbox().
-+ * 'page' will be updated to point to the desired line in 'buf'.
-+ */
-+static void
-+back_lines (int n)
-+{
-+    int i, fpos;
-+
-+    begin_reached = 0;
-+    /* We have to distinguish between end_reached and !end_reached
-+       since at end of file, the line is not ended by a '\n'.
-+       The code inside 'if' basically does a '--page' to move one
-+       character backward so as to skip '\n' of the previous line */
-+    if (!end_reached) {
-+      /* Either beginning of buffer or beginning of file reached? */
-+      if (page == buf) {
-+          if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-+              endwin ();
-+              fprintf (stderr, "\nError moving file pointer in "
-+                       "back_lines().\n");
-+              exit (-1);
-+          }
-+          if (fpos > bytes_read) {    /* Not beginning of file yet */
-+              /* We've reached beginning of buffer, but not beginning of
-+                 file yet, so read previous part of file into buffer.
-+                 Note that we only move backward for BUF_SIZE/2 bytes,
-+                 but not BUF_SIZE bytes to avoid re-reading again in
-+                 print_page() later */
-+              /* Really possible to move backward BUF_SIZE/2 bytes? */
-+              if (fpos < BUF_SIZE / 2 + bytes_read) {
-+                  /* No, move less then */
-+                  if (lseek (fd, 0, SEEK_SET) == -1) {
-+                      endwin ();
-+                      fprintf (stderr, "\nError moving file pointer in "
-+                               "back_lines().\n");
-+                      exit (-1);
-+                  }
-+                  page = buf + fpos - bytes_read;
-+              } else {        /* Move backward BUF_SIZE/2 bytes */
-+                  if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
-+                      == -1) {
-+                      endwin ();
-+                      fprintf (stderr, "\nError moving file pointer "
-+                               "in back_lines().\n");
-+                      exit (-1);
-+                  }
-+                  page = buf + BUF_SIZE / 2;
-+              }
-+              if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-+                  endwin ();
-+                  fprintf (stderr, "\nError reading file in back_lines().\n");
-+                  exit (-1);
-+              }
-+              buf[bytes_read] = '\0';
-+          } else {            /* Beginning of file reached */
-+              begin_reached = 1;
-+              return;
-+          }
-+      }
-+      if (*(--page) != '\n') {        /* '--page' here */
-+          /* Something's wrong... */
-+          endwin ();
-+          fprintf (stderr, "\nInternal error in back_lines().\n");
-+          exit (-1);
-+      }
-+    }
-+    /* Go back 'n' lines */
-+    for (i = 0; i < n; i++)
-+      do {
-+          if (page == buf) {
-+              if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-+                  endwin ();
-+                  fprintf (stderr,
-+                        "\nError moving file pointer in back_lines().\n");
-+                  exit (-1);
-+              }
-+              if (fpos > bytes_read) {
-+                  /* Really possible to move backward BUF_SIZE/2 bytes? */
-+                  if (fpos < BUF_SIZE / 2 + bytes_read) {
-+                      /* No, move less then */
-+                      if (lseek (fd, 0, SEEK_SET) == -1) {
-+                          endwin ();
-+                          fprintf (stderr, "\nError moving file pointer "
-+                                   "in back_lines().\n");
-+                          exit (-1);
-+                      }
-+                      page = buf + fpos - bytes_read;
-+                  } else {    /* Move backward BUF_SIZE/2 bytes */
-+                      if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
-+                                 SEEK_CUR) == -1) {
-+                          endwin ();
-+                          fprintf (stderr, "\nError moving file pointer"
-+                                   " in back_lines().\n");
-+                          exit (-1);
-+                      }
-+                      page = buf + BUF_SIZE / 2;
-+                  }
-+                  if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-+                      endwin ();
-+                      fprintf (stderr, "\nError reading file in "
-+                               "back_lines().\n");
-+                      exit (-1);
-+                  }
-+                  buf[bytes_read] = '\0';
-+              } else {        /* Beginning of file reached */
-+                  begin_reached = 1;
-+                  return;
-+              }
-+          }
-+      } while (*(--page) != '\n');
-+    page++;
-+}
-+
-+/*
-+ * Print a new page of text. Called by dialog_textbox().
-+ */
-+static void
-+print_page (WINDOW * win, int height, int width)
-+{
-+    int i, passed_end = 0;
-+
-+    page_length = 0;
-+    for (i = 0; i < height; i++) {
-+      print_line (win, i, width);
-+      if (!passed_end)
-+          page_length++;
-+      if (end_reached && !passed_end)
-+          passed_end = 1;
-+    }
-+    wnoutrefresh (win);
-+}
-+
-+/*
-+ * Print a new line of text. Called by dialog_textbox() and print_page().
-+ */
-+static void
-+print_line (WINDOW * win, int row, int width)
-+{
-+    int y, x;
-+    char *line;
-+
-+    line = get_line ();
-+    line += MIN (strlen (line), hscroll);     /* Scroll horizontally */
-+    wmove (win, row, 0);      /* move cursor to correct line */
-+    waddch (win, ' ');
-+    waddnstr (win, line, MIN (strlen (line), width - 2));
-+
-+    getyx (win, y, x);
-+    /* Clear 'residue' of previous line */
-+#if OLD_NCURSES
-+    {
-+        int i;
-+        for (i = 0; i < width - x; i++)
-+          waddch (win, ' ');
-+    }
-+#else
-+    wclrtoeol(win);
-+#endif
-+}
-+
-+/*
-+ * Return current line of text. Called by dialog_textbox() and print_line().
-+ * 'page' should point to start of current line before calling, and will be
-+ * updated to point to start of next line.
-+ */
-+static char *
-+get_line (void)
-+{
-+    int i = 0, fpos;
-+    static char line[MAX_LEN + 1];
-+
-+    end_reached = 0;
-+    while (*page != '\n') {
-+      if (*page == '\0') {
-+          /* Either end of file or end of buffer reached */
-+          if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-+              endwin ();
-+              fprintf (stderr, "\nError moving file pointer in "
-+                       "get_line().\n");
-+              exit (-1);
-+          }
-+          if (fpos < file_size) {     /* Not end of file yet */
-+              /* We've reached end of buffer, but not end of file yet,
-+                 so read next part of file into buffer */
-+              if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
-+                  endwin ();
-+                  fprintf (stderr, "\nError reading file in get_line().\n");
-+                  exit (-1);
-+              }
-+              buf[bytes_read] = '\0';
-+              page = buf;
-+          } else {
-+              if (!end_reached)
-+                  end_reached = 1;
-+              break;
-+          }
-+      } else if (i < MAX_LEN)
-+          line[i++] = *(page++);
-+      else {
-+          /* Truncate lines longer than MAX_LEN characters */
-+          if (i == MAX_LEN)
-+              line[i++] = '\0';
-+          page++;
-+      }
-+    }
-+    if (i <= MAX_LEN)
-+      line[i] = '\0';
-+    if (!end_reached)
-+      page++;                 /* move pass '\n' */
-+
-+    return line;
-+}
-+
-+/*
-+ * Print current position
-+ */
-+static void
-+print_position (WINDOW * win, int height, int width)
-+{
-+    int fpos, percent;
-+
-+    if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
-+      endwin ();
-+      fprintf (stderr, "\nError moving file pointer in print_position().\n");
-+      exit (-1);
-+    }
-+    wattrset (win, position_indicator_attr);
-+    wbkgdset (win, position_indicator_attr & A_COLOR);
-+    percent = !file_size ?
-+      100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
-+    wmove (win, height - 3, width - 9);
-+    wprintw (win, "(%3d%%)", percent);
-+}
-diff -Nur busybox-1.00/scripts/config/lxdialog/util.c busybox/scripts/config/lxdialog/util.c
---- busybox-1.00/scripts/config/lxdialog/util.c        1970-01-01 01:00:00.000000000 +0100
-+++ busybox/scripts/config/lxdialog/util.c     2005-06-04 08:20:02.000000000 +0200
-@@ -0,0 +1,375 @@
-+/*
-+ *  util.c
-+ *
-+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
-+ *
-+ *  This program is free software; you can redistribute it and/or
-+ *  modify it under the terms of the GNU General Public License
-+ *  as published by the Free Software Foundation; either version 2
-+ *  of the License, or (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include "dialog.h"
-+
-+
-+/* use colors by default? */
-+bool use_colors = 1;
-+
-+const char *backtitle = NULL;
-+
-+const char *dialog_result;
-+
-+/* 
-+ * Attribute values, default is for mono display
-+ */
-+chtype attributes[] =
-+{
-+    A_NORMAL,                 /* screen_attr */
-+    A_NORMAL,                 /* shadow_attr */
-+    A_NORMAL,                 /* dialog_attr */
-+    A_BOLD,                   /* title_attr */
-+    A_NORMAL,                 /* border_attr */
-+    A_REVERSE,                        /* button_active_attr */
-+    A_DIM,                    /* button_inactive_attr */
-+    A_REVERSE,                        /* button_key_active_attr */
-+    A_BOLD,                   /* button_key_inactive_attr */
-+    A_REVERSE,                        /* button_label_active_attr */
-+    A_NORMAL,                 /* button_label_inactive_attr */
-+    A_NORMAL,                 /* inputbox_attr */
-+    A_NORMAL,                 /* inputbox_border_attr */
-+    A_NORMAL,                 /* searchbox_attr */
-+    A_BOLD,                   /* searchbox_title_attr */
-+    A_NORMAL,                 /* searchbox_border_attr */
-+    A_BOLD,                   /* position_indicator_attr */
-+    A_NORMAL,                 /* menubox_attr */
-+    A_NORMAL,                 /* menubox_border_attr */
-+    A_NORMAL,                 /* item_attr */
-+    A_REVERSE,                        /* item_selected_attr */
-+    A_BOLD,                   /* tag_attr */
-+    A_REVERSE,                        /* tag_selected_attr */
-+    A_BOLD,                   /* tag_key_attr */
-+    A_REVERSE,                        /* tag_key_selected_attr */
-+    A_BOLD,                   /* check_attr */
-+    A_REVERSE,                        /* check_selected_attr */
-+    A_BOLD,                   /* uarrow_attr */
-+    A_BOLD                    /* darrow_attr */
-+};
-+
-+
-+#include "colors.h"
-+
-+/*
-+ * Table of color values
-+ */
-+int color_table[][3] =
-+{
-+    {SCREEN_FG, SCREEN_BG, SCREEN_HL},
-+    {SHADOW_FG, SHADOW_BG, SHADOW_HL},
-+    {DIALOG_FG, DIALOG_BG, DIALOG_HL},
-+    {TITLE_FG, TITLE_BG, TITLE_HL},
-+    {BORDER_FG, BORDER_BG, BORDER_HL},
-+    {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
-+    {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
-+    {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
-+    {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
-+    {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
-+    {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
-+     BUTTON_LABEL_INACTIVE_HL},
-+    {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
-+    {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
-+    {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
-+    {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
-+    {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
-+    {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
-+    {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
-+    {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
-+    {ITEM_FG, ITEM_BG, ITEM_HL},
-+    {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
-+    {TAG_FG, TAG_BG, TAG_HL},
-+    {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
-+    {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
-+    {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
-+    {CHECK_FG, CHECK_BG, CHECK_HL},
-+    {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
-+    {UARROW_FG, UARROW_BG, UARROW_HL},
-+    {DARROW_FG, DARROW_BG, DARROW_HL},
-+};                            /* color_table */
-+
-+/*
-+ * Set window to attribute 'attr'
-+ */
-+void
-+attr_clear (WINDOW * win, int height, int width, chtype attr)
-+{
-+    int i, j;
-+
-+    wattrset (win, attr);
-+    for (i = 0; i < height; i++) {
-+      wmove (win, i, 0);
-+      for (j = 0; j < width; j++)
-+          waddch (win, ' ');
-+    }
-+    touchwin (win);
-+}
-+
-+void dialog_clear (void)
-+{
-+    attr_clear (stdscr, LINES, COLS, screen_attr);
-+    /* Display background title if it exists ... - SLH */
-+    if (backtitle != NULL) {
-+        int i;
-+
-+        wattrset (stdscr, screen_attr);
-+        mvwaddstr (stdscr, 0, 1, (char *)backtitle);
-+        wmove (stdscr, 1, 1);
-+        for (i = 1; i < COLS - 1; i++)
-+            waddch (stdscr, ACS_HLINE);
-+    }
-+    wnoutrefresh (stdscr);
-+}
-+
-+/*
-+ * Do some initialization for dialog
-+ */
-+void
-+init_dialog (void)
-+{
-+    initscr ();                       /* Init curses */
-+    keypad (stdscr, TRUE);
-+    cbreak ();
-+    noecho ();
-+
-+
-+    if (use_colors)   /* Set up colors */
-+      color_setup ();
-+
-+
-+    dialog_clear ();
-+}
-+
-+/*
-+ * Setup for color display
-+ */
-+void
-+color_setup (void)
-+{
-+    int i;
-+
-+    if (has_colors ()) {      /* Terminal supports color? */
-+      start_color ();
-+
-+      /* Initialize color pairs */
-+      for (i = 0; i < ATTRIBUTE_COUNT; i++)
-+          init_pair (i + 1, color_table[i][0], color_table[i][1]);
-+
-+      /* Setup color attributes */
-+      for (i = 0; i < ATTRIBUTE_COUNT; i++)
-+          attributes[i] = C_ATTR (color_table[i][2], i + 1);
-+    }
-+}
-+
-+/*
-+ * End using dialog functions.
-+ */
-+void
-+end_dialog (void)
-+{
-+    endwin ();
-+}
-+
-+
-+/*
-+ * Print a string of text in a window, automatically wrap around to the
-+ * next line if the string is too long to fit on one line. Newline
-+ * characters '\n' are replaced by spaces.  We start on a new line
-+ * if there is no room for at least 4 nonblanks following a double-space.
-+ */
-+void
-+print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
-+{
-+    int newl, cur_x, cur_y;
-+    int i, prompt_len, room, wlen;
-+    char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
-+
-+    strcpy (tempstr, prompt);
-+
-+    prompt_len = strlen(tempstr);
-+      
-+    /*
-+     * Remove newlines
-+     */
-+    for(i=0; i<prompt_len; i++) {
-+      if(tempstr[i] == '\n') tempstr[i] = ' ';
-+    }
-+
-+    if (prompt_len <= width - x * 2) {        /* If prompt is short */
-+      wmove (win, y, (width - prompt_len) / 2);
-+      waddstr (win, tempstr);
-+    } else {
-+      cur_x = x;
-+      cur_y = y;
-+      newl = 1;
-+      word = tempstr;
-+      while (word && *word) {
-+          sp = index(word, ' ');
-+          if (sp)
-+              *sp++ = 0;
-+
-+          /* Wrap to next line if either the word does not fit,
-+             or it is the first word of a new sentence, and it is
-+             short, and the next word does not fit. */
-+          room = width - cur_x;
-+          wlen = strlen(word);
-+          if (wlen > room ||
-+             (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
-+                   && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
-+              cur_y++;
-+              cur_x = x;
-+          }
-+          wmove (win, cur_y, cur_x);
-+          waddstr (win, word);
-+          getyx (win, cur_y, cur_x);
-+          cur_x++;
-+          if (sp && *sp == ' ') {
-+              cur_x++;        /* double space */
-+              while (*++sp == ' ');
-+              newl = 1;
-+          } else
-+              newl = 0;
-+          word = sp;
-+      }
-+    }
-+}
-+
-+/*
-+ * Print a button
-+ */
-+void
-+print_button (WINDOW * win, const char *label, int y, int x, int selected)
-+{
-+    int i, temp;
-+
-+    wmove (win, y, x);
-+    wattrset (win, selected ? button_active_attr : button_inactive_attr);
-+    waddstr (win, "<");
-+    temp = strspn (label, " ");
-+    label += temp;
-+    wattrset (win, selected ? button_label_active_attr
-+            : button_label_inactive_attr);
-+    for (i = 0; i < temp; i++)
-+      waddch (win, ' ');
-+    wattrset (win, selected ? button_key_active_attr
-+            : button_key_inactive_attr);
-+    waddch (win, label[0]);
-+    wattrset (win, selected ? button_label_active_attr
-+            : button_label_inactive_attr);
-+    waddstr (win, (char *)label + 1);
-+    wattrset (win, selected ? button_active_attr : button_inactive_attr);
-+    waddstr (win, ">");
-+    wmove (win, y, x + temp + 1);
-+}
-+
-+/*
-+ * Draw a rectangular box with line drawing characters
-+ */
-+void
-+draw_box (WINDOW * win, int y, int x, int height, int width,
-+        chtype box, chtype border)
-+{
-+    int i, j;
-+
-+    wattrset (win, 0);
-+    for (i = 0; i < height; i++) {
-+      wmove (win, y + i, x);
-+      for (j = 0; j < width; j++)
-+          if (!i && !j)
-+              waddch (win, border | ACS_ULCORNER);
-+          else if (i == height - 1 && !j)
-+              waddch (win, border | ACS_LLCORNER);
-+          else if (!i && j == width - 1)
-+              waddch (win, box | ACS_URCORNER);
-+          else if (i == height - 1 && j == width - 1)
-+              waddch (win, box | ACS_LRCORNER);
-+          else if (!i)
-+              waddch (win, border | ACS_HLINE);
-+          else if (i == height - 1)
-+              waddch (win, box | ACS_HLINE);
-+          else if (!j)
-+              waddch (win, border | ACS_VLINE);
-+          else if (j == width - 1)
-+              waddch (win, box | ACS_VLINE);
-+          else
-+              waddch (win, box | ' ');
-+    }
-+}
-+
-+/*
-+ * Draw shadows along the right and bottom edge to give a more 3D look
-+ * to the boxes
-+ */
-+void
-+draw_shadow (WINDOW * win, int y, int x, int height, int width)
-+{
-+    int i;
-+
-+    if (has_colors ()) {      /* Whether terminal supports color? */
-+      wattrset (win, shadow_attr);
-+      wmove (win, y + height, x + 2);
-+      for (i = 0; i < width; i++)
-+          waddch (win, winch (win) & A_CHARTEXT);
-+      for (i = y + 1; i < y + height + 1; i++) {
-+          wmove (win, i, x + width);
-+          waddch (win, winch (win) & A_CHARTEXT);
-+          waddch (win, winch (win) & A_CHARTEXT);
-+      }
-+      wnoutrefresh (win);
-+    }
-+}
-+
-+/*
-+ *  Return the position of the first alphabetic character in a string.
-+ */
-+int
-+first_alpha(const char *string, const char *exempt)
-+{
-+      int i, in_paren=0, c;
-+
-+      for (i = 0; i < strlen(string); i++) {
-+              c = tolower(string[i]);
-+
-+              if (strchr("<[(", c)) ++in_paren;
-+              if (strchr(">])", c) && in_paren > 0) --in_paren;
-+
-+              if ((! in_paren) && isalpha(c) && 
-+                   strchr(exempt, c) == 0)
-+                      return i;
-+      }
-+
-+      return 0;
-+}
-+
-+/*
-+ * Get the first selected item in the dialog_list_item list.
-+ */
-+struct dialog_list_item *
-+first_sel_item(int item_no, struct dialog_list_item ** items)
-+{
-+      int i;
-+
-+      for (i = 0; i < item_no; i++) {
-+              if (items[i]->selected)
-+                      return items[i];
-+      }
-+
-+      return NULL;
-+}
-diff -Nur busybox-1.00/scripts/config/lxdialog/yesno.c busybox/scripts/config/lxdialog/yesno.c
---- busybox-1.00/scripts/config/lxdialog/yesno.c       1970-01-01 01:00:00.000000000 +0100
-+++ busybox/scripts/config/lxdialog/yesno.c    2005-06-04 08:20:02.000000000 +0200
-@@ -0,0 +1,118 @@
-+/*
-+ *  yesno.c -- implements the yes/no box
-+ *
-+ *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-+ *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
-+ *
-+ *  This program is free software; you can redistribute it and/or
-+ *  modify it under the terms of the GNU General Public License
-+ *  as published by the Free Software Foundation; either version 2
-+ *  of the License, or (at your option) any later version.
-+ *
-+ *  This program is distributed in the hope that it will be useful,
-+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *  GNU General Public License for more details.
-+ *
-+ *  You should have received a copy of the GNU General Public License
-+ *  along with this program; if not, write to the Free Software
-+ *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+#include "dialog.h"
-+
-+/*
-+ * Display termination buttons
-+ */
-+static void
-+print_buttons(WINDOW *dialog, int height, int width, int selected)
-+{
-+    int x = width / 2 - 10;
-+    int y = height - 2;
-+
-+    print_button (dialog, " Yes ", y, x, selected == 0);
-+    print_button (dialog, "  No  ", y, x + 13, selected == 1);
-+
-+    wmove(dialog, y, x+1 + 13*selected );
-+    wrefresh (dialog);
-+}
-+
-+/*
-+ * Display a dialog box with two buttons - Yes and No
-+ */
-+int
-+dialog_yesno (const char *title, const char *prompt, int height, int width)
-+{
-+    int i, x, y, key = 0, button = 0;
-+    WINDOW *dialog;
-+
-+    /* center dialog box on screen */
-+    x = (COLS - width) / 2;
-+    y = (LINES - height) / 2;
-+
-+    draw_shadow (stdscr, y, x, height, width);
-+
-+    dialog = newwin (height, width, y, x);
-+    keypad (dialog, TRUE);
-+
-+    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
-+    wattrset (dialog, border_attr);
-+    mvwaddch (dialog, height-3, 0, ACS_LTEE);
-+    for (i = 0; i < width - 2; i++)
-+      waddch (dialog, ACS_HLINE);
-+    wattrset (dialog, dialog_attr);
-+    waddch (dialog, ACS_RTEE);
-+
-+    if (title != NULL && strlen(title) >= width-2 ) {
-+      /* truncate long title -- mec */
-+      char * title2 = malloc(width-2+1);
-+      memcpy( title2, title, width-2 );
-+      title2[width-2] = '\0';
-+      title = title2;
-+    }
-+
-+    if (title != NULL) {
-+      wattrset (dialog, title_attr);
-+      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
-+      waddstr (dialog, (char *)title);
-+      waddch (dialog, ' ');
-+    }
-+
-+    wattrset (dialog, dialog_attr);
-+    print_autowrap (dialog, prompt, width - 2, 1, 3);
-+
-+    print_buttons(dialog, height, width, 0);
-+
-+    while (key != ESC) {
-+      key = wgetch (dialog);
-+      switch (key) {
-+      case 'Y':
-+      case 'y':
-+          delwin (dialog);
-+          return 0;
-+      case 'N':
-+      case 'n':
-+          delwin (dialog);
-+          return 1;
-+
-+      case TAB:
-+      case KEY_LEFT:
-+      case KEY_RIGHT:
-+          button = ((key == KEY_LEFT ? --button : ++button) < 0)
-+                      ? 1 : (button > 1 ? 0 : button);
-+
-+          print_buttons(dialog, height, width, button);
-+          wrefresh (dialog);
-+          break;
-+      case ' ':
-+      case '\n':
-+          delwin (dialog);
-+          return button;
-+      case ESC:
-+          break;
-+      }
-+    }
-+
-+    delwin (dialog);
-+    return -1;                        /* ESC pressed */
-+}
-diff -Nur busybox-1.00/scripts/config/mconf.c busybox/scripts/config/mconf.c
---- busybox-1.00/scripts/config/mconf.c        2004-10-08 09:58:30.000000000 +0200
-+++ busybox/scripts/config/mconf.c     2005-06-04 08:20:03.000000000 +0200
-@@ -23,18 +23,150 @@
- #include <termios.h>
- #include <unistd.h>
--#include "dialog.h"
-+#include "lxdialog/dialog.h"
- #define LKC_DIRECT_LINK
- #include "lkc.h"
- static char menu_backtitle[128];
--static const char menu_instructions[] =
-+static const char mconf_readme[] =
-+"Overview\n"
-+"--------\n"
-+"Some features may be built directly into BusyBox.  Some features\n"
-+"may be completely removed altogether.  There are also certain\n"
-+"parameters which are not really features, but must be\n"
-+"entered in as decimal or hexadecimal numbers or possibly text.\n"
-+"\n"
-+"Menu items beginning with [*] or [ ] represent features\n"
-+"configured to be built in or removed respectively.\n"
-+"\n"
-+"To change any of these features, highlight it with the cursor\n"
-+"keys and press <Y> to build it in or <N> to removed it.\n"
-+"You may also press the <Space Bar> to cycle\n"
-+"through the available options (ie. Y->N->Y).\n"
-+"\n"
-+"Some additional keyboard hints:\n"
-+"\n"
-+"Menus\n"
-+"----------\n"
-+"o  Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
-+"   you wish to change or submenu wish to select and press <Enter>.\n"
-+"   Submenus are designated by \"--->\".\n"
-+"\n"
-+"   Shortcut: Press the option's highlighted letter (hotkey).\n"
-+"             Pressing a hotkey more than once will sequence\n"
-+"             through all visible items which use that hotkey.\n"
-+"\n"
-+"   You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
-+"   unseen options into view.\n"
-+"\n"
-+"o  To exit a menu use the cursor keys to highlight the <Exit> button\n"
-+"   and press <ENTER>.\n"
-+"\n"
-+"   Shortcut: Press <ESC><ESC> or <E> or <X> if there is no hotkey\n"
-+"             using those letters.  You may press a single <ESC>, but\n"
-+"             there is a delayed response which you may find annoying.\n"
-+"\n"
-+"   Also, the <TAB> and cursor keys will cycle between <Select>,\n"
-+"   <Exit> and <Help>\n"
-+"\n"
-+"o  To get help with an item, use the cursor keys to highlight <Help>\n"
-+"   and Press <ENTER>.\n"
-+"\n"
-+"   Shortcut: Press <H> or <?>.\n"
-+"\n"
-+"\n"
-+"Radiolists  (Choice lists)\n"
-+"-----------\n"
-+"o  Use the cursor keys to select the option you wish to set and press\n"
-+"   <S> or the <SPACE BAR>.\n"
-+"\n"
-+"   Shortcut: Press the first letter of the option you wish to set then\n"
-+"             press <S> or <SPACE BAR>.\n"
-+"\n"
-+"o  To see available help for the item, use the cursor keys to highlight\n"
-+"   <Help> and Press <ENTER>.\n"
-+"\n"
-+"   Shortcut: Press <H> or <?>.\n"
-+"\n"
-+"   Also, the <TAB> and cursor keys will cycle between <Select> and\n"
-+"   <Help>\n"
-+"\n"
-+"\n"
-+"Data Entry\n"
-+"-----------\n"
-+"o  Enter the requested information and press <ENTER>\n"
-+"   If you are entering hexadecimal values, it is not necessary to\n"
-+"   add the '0x' prefix to the entry.\n"
-+"\n"
-+"o  For help, use the <TAB> or cursor keys to highlight the help option\n"
-+"   and press <ENTER>.  You can try <TAB><H> as well.\n"
-+"\n"
-+"\n"
-+"Text Box    (Help Window)\n"
-+"--------\n"
-+"o  Use the cursor keys to scroll up/down/left/right.  The VI editor\n"
-+"   keys h,j,k,l function here as do <SPACE BAR> and <B> for those\n"
-+"   who are familiar with less and lynx.\n"
-+"\n"
-+"o  Press <E>, <X>, <Enter> or <Esc><Esc> to exit.\n"
-+"\n"
-+"\n"
-+"Alternate Configuration Files\n"
-+"-----------------------------\n"
-+"Menuconfig supports the use of alternate configuration files for\n"
-+"those who, for various reasons, find it necessary to switch\n"
-+"between different configurations.\n"
-+"\n"
-+"At the end of the main menu you will find two options.  One is\n"
-+"for saving the current configuration to a file of your choosing.\n"
-+"The other option is for loading a previously saved alternate\n"
-+"configuration.\n"
-+"\n"
-+"Even if you don't use alternate configuration files, but you\n"
-+"find during a Menuconfig session that you have completely messed\n"
-+"up your settings, you may use the \"Load Alternate...\" option to\n"
-+"restore your previously saved settings from \".config\" without\n"
-+"restarting Menuconfig.\n"
-+"\n"
-+"Other information\n"
-+"-----------------\n"
-+"If you use Menuconfig in an XTERM window make sure you have your\n"
-+"$TERM variable set to point to a xterm definition which supports color.\n"
-+"Otherwise, Menuconfig will look rather bad.  Menuconfig will not\n"
-+"display correctly in a RXVT window because rxvt displays only one\n"
-+"intensity of color, bright.\n"
-+"\n"
-+"Menuconfig will display larger menus on screens or xterms which are\n"
-+"set to display more than the standard 25 row by 80 column geometry.\n"
-+"In order for this to work, the \"stty size\" command must be able to\n"
-+"display the screen's current row and column geometry.  I STRONGLY\n"
-+"RECOMMEND that you make sure you do NOT have the shell variables\n"
-+"LINES and COLUMNS exported into your environment.  Some distributions\n"
-+"export those variables via /etc/profile.  Some ncurses programs can\n"
-+"become confused when those variables (LINES & COLUMNS) don't reflect\n"
-+"the true screen size.\n"
-+"\n"
-+"Optional personality available\n"
-+"------------------------------\n"
-+"If you prefer to have all of the options listed in a single\n"
-+"menu, rather than the default multimenu hierarchy, run the menuconfig\n"
-+"with MENUCONFIG_MODE environment variable set to single_menu. Example:\n"
-+"\n"
-+"make MENUCONFIG_MODE=single_menu menuconfig\n"
-+"\n"
-+"<Enter> will then unroll the appropriate category, or enfold it if it\n"
-+"is already unrolled.\n"
-+"\n"
-+"Note that this mode can eventually be a little more CPU expensive\n"
-+"(especially with a larger number of unrolled categories) than the\n"
-+"default mode.\n",
-+menu_instructions[] =
-       "Arrow keys navigate the menu.  "
-       "<Enter> selects submenus --->.  "
-       "Highlighted letters are hotkeys.  "
-       "Pressing <Y> selectes a feature, while <N> will exclude a feature.  "
--      "Press <Esc><Esc> to exit, <?> for Help.  "
-+      "Press <Esc><Esc> to exit, <?> for Help, </> for Search.  "
-       "Legend: [*] feature is selected  [ ] feature is excluded",
- radiolist_instructions[] =
-       "Use the arrow keys to navigate this window or "
-@@ -85,23 +217,50 @@
-       "\n"
-       "If you are uncertain what all this means then you should probably\n"
-       "leave this blank.\n",
--top_menu_help[] =
-+search_help[] =
-       "\n"
--      "Use the Up/Down arrow keys (cursor keys) to highlight the item\n"
--      "you wish to change or submenu wish to select and press <Enter>.\n"
--      "Submenus are designated by \"--->\".\n"
-+      "Search for CONFIG_ symbols and display their relations.\n"
-+      "Example: search for \"^FOO\"\n"
-+      "Result:\n"
-+      "-----------------------------------------------------------------\n"
-+      "Symbol: FOO [=m]\n"
-+      "Prompt: Foo bus is used to drive the bar HW\n"
-+      "Defined at drivers/pci/Kconfig:47\n"
-+      "Depends on: X86_LOCAL_APIC && X86_IO_APIC || IA64\n"
-+      "Location:\n"
-+      "  -> Bus options (PCI, PCMCIA, EISA, MCA, ISA)\n"
-+      "    -> PCI support (PCI [=y])\n"
-+      "      -> PCI access mode (<choice> [=y])\n"
-+      "Selects: LIBCRC32\n"
-+      "Selected by: BAR\n"
-+      "-----------------------------------------------------------------\n"
-+      "o The line 'Prompt:' shows the text used in the menu structure for\n"
-+      "  this CONFIG_ symbol\n"
-+      "o The 'Defined at' line tell at what file / line number the symbol\n"
-+      "  is defined\n"
-+      "o The 'Depends on:' line tell what symbols needs to be defined for\n"
-+      "  this symbol to be visible in the menu (selectable)\n"
-+      "o The 'Location:' lines tell where in the menu structure this symbol\n"
-+      "  is located\n"
-+      "    A location followed by a [=y] indicate that this is a selectable\n"
-+      "    menu item - and current value is displayed inside brackets.\n"
-+      "o The 'Selects:' line tell what symbol will be automatically\n"
-+      "  selected if this symbol is selected (y or m)\n"
-+      "o The 'Selected by' line tell what symbol has selected this symbol\n"
-       "\n"
--      "Shortcut: Press the option's highlighted letter (hotkey).\n"
--      "\n"
--      "You may also use the <PAGE UP> and <PAGE DOWN> keys to scroll\n"
--      "unseen options into view.\n"
--;
-+      "Only relevant lines are shown.\n"
-+      "\n\n"
-+      "Search examples:\n"
-+      "Examples: USB  => find all CONFIG_ symbols containing USB\n"
-+      "          ^USB => find all CONFIG_ symbols starting with USB\n"
-+      "          USB$ => find all CONFIG_ symbols ending with USB\n"
-+      "\n";
- static char filename[PATH_MAX+1] = ".config";
--static int indent = 0;
-+static int indent;
- static struct termios ios_org;
--static int rows, cols;
--struct menu *current_menu;
-+static int rows = 0, cols = 0;
-+static struct menu *current_menu;
- static int child_count;
- static int single_menu_mode;
-@@ -116,33 +275,31 @@
- static void show_textbox(const char *title, const char *text, int r, int c);
- static void show_helptext(const char *title, const char *text);
- static void show_help(struct menu *menu);
--static void show_readme(void);
-+static void show_file(const char *filename, const char *title, int r, int c);
- static void init_wsize(void)
- {
-       struct winsize ws;
-       char *env;
--      if (ioctl(1, TIOCGWINSZ, &ws) == -1) {
--              rows = 24;
--              cols = 80;
--      } else {
-+      if (!ioctl(STDIN_FILENO, TIOCGWINSZ, &ws)) {
-               rows = ws.ws_row;
-               cols = ws.ws_col;
--              if (!rows) {
--                      env = getenv("LINES");
--                      if (env)
--                              rows = atoi(env);
--                      if (!rows)
--                              rows = 24;
--              }
--              if (!cols) {
--                      env = getenv("COLUMNS");
--                      if (env)
--                              cols = atoi(env);
--                      if (!cols)
--                              cols = 80;
--              }
-+      }
-+
-+      if (!rows) {
-+              env = getenv("LINES");
-+              if (env)
-+                      rows = atoi(env);
-+              if (!rows)
-+                      rows = 24;
-+      }
-+      if (!cols) {
-+              env = getenv("COLUMNS");
-+              if (env)
-+                      cols = atoi(env);
-+              if (!cols)
-+                      cols = 80;
-       }
-       if (rows < 19 || cols < 80) {
-@@ -214,6 +371,103 @@
-       item_no = 0;
- }
-+static void get_prompt_str(struct gstr *r, struct property *prop)
-+{
-+      int i, j;
-+      struct menu *submenu[8], *menu;
-+
-+      str_printf(r, "Prompt: %s\n", prop->text);
-+      str_printf(r, "  Defined at %s:%d\n", prop->menu->file->name,
-+              prop->menu->lineno);
-+      if (!expr_is_yes(prop->visible.expr)) {
-+              str_append(r, "  Depends on: ");
-+              expr_gstr_print(prop->visible.expr, r);
-+              str_append(r, "\n");
-+      }
-+      menu = prop->menu->parent;
-+      for (i = 0; menu != &rootmenu && i < 8; menu = menu->parent)
-+              submenu[i++] = menu;
-+      if (i > 0) {
-+              str_printf(r, "  Location:\n");
-+              for (j = 4; --i >= 0; j += 2) {
-+                      menu = submenu[i];
-+                      str_printf(r, "%*c-> %s", j, ' ', menu_get_prompt(menu));
-+                      if (menu->sym) {
-+                              str_printf(r, " (%s [=%s])", menu->sym->name ?
-+                                      menu->sym->name : "<choice>",
-+                                      sym_get_string_value(menu->sym));
-+                      }
-+                      str_append(r, "\n");
-+              }
-+      }
-+}
-+
-+static void get_symbol_str(struct gstr *r, struct symbol *sym)
-+{
-+      bool hit;
-+      struct property *prop;
-+
-+      str_printf(r, "Symbol: %s [=%s]\n", sym->name,
-+                                     sym_get_string_value(sym));
-+      for_all_prompts(sym, prop)
-+              get_prompt_str(r, prop);
-+      hit = false;
-+      for_all_properties(sym, prop, P_SELECT) {
-+              if (!hit) {
-+                      str_append(r, "  Selects: ");
-+                      hit = true;
-+              } else
-+                      str_printf(r, " && ");
-+              expr_gstr_print(prop->expr, r);
-+      }
-+      if (hit)
-+              str_append(r, "\n");
-+      if (sym->rev_dep.expr) {
-+              str_append(r, "  Selected by: ");
-+              expr_gstr_print(sym->rev_dep.expr, r);
-+              str_append(r, "\n");
-+      }
-+      str_append(r, "\n\n");
-+}
-+
-+static struct gstr get_relations_str(struct symbol **sym_arr)
-+{
-+      struct symbol *sym;
-+      struct gstr res = str_new();
-+      int i;
-+
-+      for (i = 0; sym_arr && (sym = sym_arr[i]); i++)
-+              get_symbol_str(&res, sym);
-+      if (!i)
-+              str_append(&res, "No matches found.\n");
-+      return res;
-+}
-+
-+static void search_conf(void)
-+{
-+      struct symbol **sym_arr;
-+      struct gstr res;
-+
-+again:
-+      switch (dialog_inputbox("Search Configuration Parameter",
-+                              "Enter Keyword", 10, 75,
-+                              NULL)) {
-+      case 0:
-+              break;
-+      case 1:
-+              show_helptext("Search Configuration", search_help);
-+              goto again;
-+      default:
-+              return;
-+      }
-+
-+      sym_arr = sym_re_search(dialog_input_result);
-+      res = get_relations_str(sym_arr);
-+      free(sym_arr);
-+      show_textbox("Search Results", str_get(&res), 0, 0);
-+      str_free(&res);
-+}
-+
- static void build_conf(struct menu *menu)
- {
-       struct symbol *sym;
-@@ -308,6 +562,11 @@
-                       return;
-               }
-       } else {
-+              if (menu == current_menu) {
-+                      cprint_tag(":%p", menu);
-+                      cprint_name("---%*c%s", indent + 1, ' ', menu_get_prompt(menu));
-+                      goto conf_childs;
-+              }
-               child_count++;
-               val = sym_get_tristate_value(sym);
-               if (sym_is_choice_value(sym) && val == yes) {
-@@ -376,7 +635,7 @@
-       while (1) {
-               indent = 0;
-               child_count = 0;
--              current_menu = menu;
-+              current_menu = menu;
-               cdone(); cinit();
-               build_conf(menu);
-               if (!child_count)
-@@ -441,7 +700,7 @@
-                       if (sym)
-                               show_help(submenu);
-                       else
--                              show_readme();
-+                              show_helptext("README", mconf_readme);
-                       break;
-               case 3:
-                       if (type == 't') {
-@@ -465,6 +724,9 @@
-                       else if (type == 'm')
-                               conf(submenu);
-                       break;
-+              case 7:
-+                      search_conf();
-+                      break;
-               }
-       }
- }
-@@ -476,37 +738,39 @@
-       fd = creat(".help.tmp", 0777);
-       write(fd, text, strlen(text));
-       close(fd);
--      while (dialog_textbox(title, ".help.tmp", r, c) < 0)
--              ;
-+      show_file(".help.tmp", title, r, c);
-       unlink(".help.tmp");
- }
- static void show_helptext(const char *title, const char *text)
- {
--      show_textbox(title, text, rows, cols);
-+      show_textbox(title, text, 0, 0);
- }
- static void show_help(struct menu *menu)
- {
--      const char *help;
--      char *helptext;
-+      struct gstr help = str_new();
-       struct symbol *sym = menu->sym;
--      help = sym->help;
--      if (!help)
--              help = nohelp_text;
--      if (sym->name) {
--              helptext = malloc(strlen(sym->name) + strlen(help) + 16);
--              sprintf(helptext, "%s:\n\n%s", sym->name, help);
--              show_helptext(menu_get_prompt(menu), helptext);
--              free(helptext);
--      } else
--              show_helptext(menu_get_prompt(menu), help);
-+      if (sym->help)
-+      {
-+              if (sym->name) {
-+                      str_printf(&help, "%s:\n\n", sym->name);
-+                      str_append(&help, sym->help);
-+                      str_append(&help, "\n");
-+              }
-+      } else {
-+              str_append(&help, nohelp_text);
-+      }
-+      get_symbol_str(&help, sym);
-+      show_helptext(menu_get_prompt(menu), str_get(&help));
-+      str_free(&help);
- }
--static void show_readme(void)
-+static void show_file(const char *filename, const char *title, int r, int c)
- {
--      show_helptext("Help", top_menu_help);
-+      while (dialog_textbox(title, filename, r ? r : rows, c ? c : cols) < 0)
-+              ;
- }
- static void conf_choice(struct menu *menu)
-@@ -667,9 +931,9 @@
- int main(int ac, char **av)
- {
--      int stat;
--      char *mode;
-       struct symbol *sym;
-+      char *mode;
-+      int stat;
-       conf_parse(av[1]);
-       conf_read(NULL);
-@@ -697,7 +961,7 @@
-       init_dialog();
-       do {
-               stat = dialog_yesno(NULL,
--                              "Do you wish to save your new BusyBox configuration?", 5, 60);
-+                                  "Do you wish to save your new BusyBox configuration?", 5, 60);
-       } while (stat < 0);
-       end_dialog();
-diff -Nur busybox-1.00/scripts/config/menu.c busybox/scripts/config/menu.c
---- busybox-1.00/scripts/config/menu.c 2004-07-15 08:01:05.000000000 +0200
-+++ busybox/scripts/config/menu.c      2005-06-04 08:20:03.000000000 +0200
-@@ -10,7 +10,6 @@
- #include "lkc.h"
- struct menu rootmenu;
--struct menu *current_menu, *current_entry;
- static struct menu **last_entry_ptr;
- struct file *file_list;
-@@ -389,43 +388,3 @@
-       return menu;
- }
--struct file *file_lookup(const char *name)
--{
--      struct file *file;
--
--      for (file = file_list; file; file = file->next) {
--              if (!strcmp(name, file->name))
--                      return file;
--      }
--
--      file = malloc(sizeof(*file));
--      memset(file, 0, sizeof(*file));
--      file->name = strdup(name);
--      file->next = file_list;
--      file_list = file;
--      return file;
--}
--
--int file_write_dep(const char *name)
--{
--      struct file *file;
--      FILE *out;
--
--      if (!name)
--              name = ".config.cmd";
--      out = fopen(".config.tmp", "w");
--      if (!out)
--              return 1;
--      fprintf(out, "deps_config := \\\n");
--      for (file = file_list; file; file = file->next) {
--              if (file->next)
--                      fprintf(out, "\t%s \\\n", file->name);
--              else
--                      fprintf(out, "\t%s\n", file->name);
--      }
--      fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n");
--      fclose(out);
--      rename(".config.tmp", name);
--      return 0;
--}
--
-diff -Nur busybox-1.00/scripts/config/menubox.c busybox/scripts/config/menubox.c
---- busybox-1.00/scripts/config/menubox.c      2004-03-15 09:29:08.000000000 +0100
-+++ busybox/scripts/config/menubox.c   1970-01-01 01:00:00.000000000 +0100
-@@ -1,436 +0,0 @@
--/*
-- *  menubox.c -- implements the menu box
-- *
-- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
-- *
-- *  This program is free software; you can redistribute it and/or
-- *  modify it under the terms of the GNU General Public License
-- *  as published by the Free Software Foundation; either version 2
-- *  of the License, or (at your option) any later version.
-- *
-- *  This program is distributed in the hope that it will be useful,
-- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- *  GNU General Public License for more details.
-- *
-- *  You should have received a copy of the GNU General Public License
-- *  along with this program; if not, write to the Free Software
-- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-- */
--
--/*
-- *  Changes by Clifford Wolf (god@clifford.at)
-- *
-- *  [ 1998-06-13 ]
-- *
-- *    *)  A bugfix for the Page-Down problem
-- *
-- *    *)  Formerly when I used Page Down and Page Up, the cursor would be set
-- *        to the first position in the menu box.  Now lxdialog is a bit
-- *        smarter and works more like other menu systems (just have a look at
-- *        it).
-- *
-- *    *)  Formerly if I selected something my scrolling would be broken because
-- *        lxdialog is re-invoked by the Menuconfig shell script, can't
-- *        remember the last scrolling position, and just sets it so that the
-- *        cursor is at the bottom of the box.  Now it writes the temporary file
-- *        lxdialog.scrltmp which contains this information. The file is
-- *        deleted by lxdialog if the user leaves a submenu or enters a new
-- *        one, but it would be nice if Menuconfig could make another "rm -f"
-- *        just to be sure.  Just try it out - you will recognise a difference!
-- *
-- *  [ 1998-06-14 ]
-- *
-- *    *)  Now lxdialog is crash-safe against broken "lxdialog.scrltmp" files
-- *        and menus change their size on the fly.
-- *
-- *    *)  If for some reason the last scrolling position is not saved by
-- *        lxdialog, it sets the scrolling so that the selected item is in the
-- *        middle of the menu box, not at the bottom.
-- *
-- * 02 January 1999, Michael Elizabeth Chastain (mec@shout.net)
-- * Reset 'scroll' to 0 if the value from lxdialog.scrltmp is bogus.
-- * This fixes a bug in Menuconfig where using ' ' to descend into menus
-- * would leave mis-synchronized lxdialog.scrltmp files lying around,
-- * fscanf would read in 'scroll', and eventually that value would get used.
-- */
--
--#include "dialog.h"
--
--static int menu_width, item_x;
--
--/*
-- * Print menu item
-- */
--static void
--print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey)
--{
--    int j;
--    char menu_item[menu_width+1];
--
--    strncpy(menu_item, item, menu_width);
--    menu_item[menu_width] = 0;
--    j = first_alpha(menu_item, "YyNnMm");
--
--    /* Clear 'residue' of last item */
--    wattrset (win, menubox_attr);
--    wmove (win, choice, 0);
--#if OLD_NCURSES
--    {
--        int i;
--        for (i = 0; i < menu_width; i++)
--          waddch (win, ' ');
--    }
--#else
--    wclrtoeol(win);
--#endif
--    wattrset (win, selected ? item_selected_attr : item_attr);
--    mvwaddstr (win, choice, item_x, menu_item);
--    if (hotkey) {
--      wattrset (win, selected ? tag_key_selected_attr : tag_key_attr);
--      mvwaddch(win, choice, item_x+j, menu_item[j]);
--    }
--    if (selected) {
--      wmove (win, choice, item_x+1);
--      wrefresh (win);
--    }
--}
--
--/*
-- * Print the scroll indicators.
-- */
--static void
--print_arrows (WINDOW * win, int item_no, int scroll,
--              int y, int x, int height)
--{
--    int cur_y, cur_x;
--
--    getyx(win, cur_y, cur_x);
--
--    wmove(win, y, x);
--
--    if (scroll > 0) {
--      wattrset (win, uarrow_attr);
--      waddch (win, ACS_UARROW);
--      waddstr (win, "(-)");
--    }
--    else {
--      wattrset (win, menubox_attr);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--    }
--
--   y = y + height + 1;
--   wmove(win, y, x);
--
--   if ((height < item_no) && (scroll + height < item_no)) {
--      wattrset (win, darrow_attr);
--      waddch (win, ACS_DARROW);
--      waddstr (win, "(+)");
--    }
--    else {
--      wattrset (win, menubox_border_attr);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--      waddch (win, ACS_HLINE);
--   }
--
--   wmove(win, cur_y, cur_x);
--}
--
--/*
-- * Display the termination buttons.
-- */
--static void
--print_buttons (WINDOW *win, int height, int width, int selected)
--{
--    int x = width / 2 - 16;
--    int y = height - 2;
--
--    print_button (win, "Select", y, x, selected == 0);
--    print_button (win, " Exit ", y, x + 12, selected == 1);
--    print_button (win, " Help ", y, x + 24, selected == 2);
--
--    wmove(win, y, x+1+12*selected);
--    wrefresh (win);
--}
--
--/*
-- * Display a menu for choosing among a number of options
-- */
--int
--dialog_menu (const char *title, const char *prompt, int height, int width,
--              int menu_height, const char *current, int item_no,
--              struct dialog_list_item ** items)
--{
--    int i, j, x, y, box_x, box_y;
--    int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice;
--    WINDOW *dialog, *menu;
--    FILE *f;
--
--    max_choice = MIN (menu_height, item_no);
--
--    /* center dialog box on screen */
--    x = (COLS - width) / 2;
--    y = (LINES - height) / 2;
--
--    draw_shadow (stdscr, y, x, height, width);
--
--    dialog = newwin (height, width, y, x);
--    keypad (dialog, TRUE);
--
--    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
--    wattrset (dialog, border_attr);
--    mvwaddch (dialog, height - 3, 0, ACS_LTEE);
--    for (i = 0; i < width - 2; i++)
--      waddch (dialog, ACS_HLINE);
--    wattrset (dialog, dialog_attr);
--    wbkgdset (dialog, dialog_attr & A_COLOR);
--    waddch (dialog, ACS_RTEE);
--
--    if (title != NULL && strlen(title) >= width-2 ) {
--      /* truncate long title -- mec */
--      char * title2 = malloc(width-2+1);
--      memcpy( title2, title, width-2 );
--      title2[width-2] = '\0';
--      title = title2;
--    }
--
--    if (title != NULL) {
--      wattrset (dialog, title_attr);
--      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
--      waddstr (dialog, (char *)title);
--      waddch (dialog, ' ');
--    }
--
--    wattrset (dialog, dialog_attr);
--    print_autowrap (dialog, prompt, width - 2, 1, 3);
--
--    menu_width = width - 6;
--    box_y = height - menu_height - 5;
--    box_x = (width - menu_width) / 2 - 1;
--
--    /* create new window for the menu */
--    menu = subwin (dialog, menu_height, menu_width,
--              y + box_y + 1, x + box_x + 1);
--    keypad (menu, TRUE);
--
--    /* draw a box around the menu items */
--    draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2,
--            menubox_border_attr, menubox_attr);
--
--    /*
--     * Find length of longest item in order to center menu.
--     * Set 'choice' to default item.
--     */
--    item_x = 0;
--    for (i = 0; i < item_no; i++) {
--      item_x = MAX (item_x, MIN(menu_width, strlen (items[i]->name) + 2));
--      if (strcmp(current, items[i]->tag) == 0) choice = i;
--    }
--
--    item_x = (menu_width - item_x) / 2;
--
--    /* get the scroll info from the temp file */
--    if ( (f=fopen("lxdialog.scrltmp","r")) != NULL ) {
--      if ( (fscanf(f,"%d\n",&scroll) == 1) && (scroll <= choice) &&
--           (scroll+max_choice > choice) && (scroll >= 0) &&
--           (scroll+max_choice <= item_no) ) {
--          first_item = scroll;
--          choice = choice - scroll;
--          fclose(f);
--      } else {
--          scroll=0;
--          remove("lxdialog.scrltmp");
--          fclose(f);
--          f=NULL;
--      }
--    }
--    if ( (choice >= max_choice) || (f==NULL && choice >= max_choice/2) ) {
--      if (choice >= item_no-max_choice/2)
--          scroll = first_item = item_no-max_choice;
--      else
--          scroll = first_item = choice - max_choice/2;
--      choice = choice - scroll;
--    }
--
--    /* Print the menu */
--    for (i=0; i < max_choice; i++) {
--      print_item (menu, items[first_item + i]->name, i, i == choice,
--                    (items[first_item + i]->tag[0] != ':'));
--    }
--
--    wnoutrefresh (menu);
--
--    print_arrows(dialog, item_no, scroll,
--               box_y, box_x+item_x+1, menu_height);
--
--    print_buttons (dialog, height, width, 0);
--    wmove (menu, choice, item_x+1);
--    wrefresh (menu);
--
--    while (key != ESC) {
--      key = wgetch(menu);
--
--      if (key < 256 && isalpha(key)) key = tolower(key);
--
--      if (strchr("ynm", key))
--              i = max_choice;
--      else {
--        for (i = choice+1; i < max_choice; i++) {
--              j = first_alpha(items[scroll + i]->name, "YyNnMm>");
--              if (key == tolower(items[scroll + i]->name[j]))
--                      break;
--      }
--      if (i == max_choice)
--                      for (i = 0; i < max_choice; i++) {
--                      j = first_alpha(items[scroll + i]->name, "YyNnMm>");
--                      if (key == tolower(items[scroll + i]->name[j]))
--                              break;
--              }
--      }
--
--      if (i < max_choice ||
--            key == KEY_UP || key == KEY_DOWN ||
--            key == '-' || key == '+' ||
--            key == KEY_PPAGE || key == KEY_NPAGE) {
--
--            print_item (menu, items[scroll + choice]->name, choice, FALSE,
--                       (items[scroll + choice]->tag[0] != ':'));
--
--          if (key == KEY_UP || key == '-') {
--                if (choice < 2 && scroll) {
--                  /* Scroll menu down */
--                    scrollok (menu, TRUE);
--                    wscrl (menu, -1);
--                    scrollok (menu, FALSE);
--
--                    scroll--;
--
--                    print_item (menu, items[scroll]->name, 0, FALSE,
--                               (items[scroll]->tag[0] != ':'));
--              } else
--                  choice = MAX(choice - 1, 0);
--
--          } else if (key == KEY_DOWN || key == '+')  {
--
--              print_item (menu, items[scroll + choice]->name, choice, FALSE,
--                                (items[scroll + choice]->tag[0] != ':'));
--
--                if ((choice > max_choice-3) &&
--                    (scroll + max_choice < item_no)
--                   ) {
--                  /* Scroll menu up */
--                  scrollok (menu, TRUE);
--                    scroll (menu);
--                    scrollok (menu, FALSE);
--
--                    scroll++;
--
--                    print_item (menu, items[scroll + max_choice - 1]->name,
--                               max_choice-1, FALSE,
--                               (items[scroll + max_choice - 1]->tag[0] != ':'));
--                } else
--                    choice = MIN(choice+1, max_choice-1);
--
--          } else if (key == KEY_PPAGE) {
--              scrollok (menu, TRUE);
--                for (i=0; (i < max_choice); i++) {
--                    if (scroll > 0) {
--                      wscrl (menu, -1);
--                      scroll--;
--                      print_item (menu, items[scroll]->name, 0, FALSE,
--                      (items[scroll]->tag[0] != ':'));
--                    } else {
--                        if (choice > 0)
--                            choice--;
--                    }
--                }
--                scrollok (menu, FALSE);
--
--            } else if (key == KEY_NPAGE) {
--                for (i=0; (i < max_choice); i++) {
--                    if (scroll+max_choice < item_no) {
--                      scrollok (menu, TRUE);
--                      scroll(menu);
--                      scrollok (menu, FALSE);
--                      scroll++;
--                      print_item (menu, items[scroll + max_choice - 1]->name,
--                                  max_choice-1, FALSE,
--                                  (items[scroll + max_choice - 1]->tag[0] != ':'));
--                  } else {
--                      if (choice+1 < max_choice)
--                          choice++;
--                  }
--                }
--
--            } else
--                choice = i;
--
--            print_item (menu, items[scroll + choice]->name, choice, TRUE,
--                       (items[scroll + choice]->tag[0] != ':'));
--
--            print_arrows(dialog, item_no, scroll,
--                         box_y, box_x+item_x+1, menu_height);
--
--            wnoutrefresh (dialog);
--            wrefresh (menu);
--
--          continue;           /* wait for another key press */
--        }
--
--      switch (key) {
--      case KEY_LEFT:
--      case TAB:
--      case KEY_RIGHT:
--          button = ((key == KEY_LEFT ? --button : ++button) < 0)
--                      ? 2 : (button > 2 ? 0 : button);
--
--          print_buttons(dialog, height, width, button);
--          wrefresh (menu);
--          break;
--      case ' ':
--      case 's':
--      case 'y':
--      case 'n':
--      case 'm':
--          /* save scroll info */
--          if ( (f=fopen("lxdialog.scrltmp","w")) != NULL ) {
--              fprintf(f,"%d\n",scroll);
--              fclose(f);
--          }
--          delwin (dialog);
--            items[scroll + choice]->selected = 1;
--            switch (key) {
--            case 's': return 3;
--            case 'y': return 3;
--            case 'n': return 4;
--            case 'm': return 5;
--            case ' ': return 6;
--            }
--          return 0;
--      case 'h':
--      case '?':
--          button = 2;
--      case '\n':
--          delwin (dialog);
--          items[scroll + choice]->selected = 1;
--
--          remove("lxdialog.scrltmp");
--          return button;
--      case 'e':
--      case 'x':
--          key = ESC;
--      case ESC:
--          break;
--      }
--    }
--
--    delwin (dialog);
--    remove("lxdialog.scrltmp");
--    return -1;                        /* ESC pressed */
--}
-diff -Nur busybox-1.00/scripts/config/msgbox.c busybox/scripts/config/msgbox.c
---- busybox-1.00/scripts/config/msgbox.c       2002-12-05 09:41:07.000000000 +0100
-+++ busybox/scripts/config/msgbox.c    1970-01-01 01:00:00.000000000 +0100
-@@ -1,85 +0,0 @@
--/*
-- *  msgbox.c -- implements the message box and info box
-- *
-- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com)
-- *
-- *  This program is free software; you can redistribute it and/or
-- *  modify it under the terms of the GNU General Public License
-- *  as published by the Free Software Foundation; either version 2
-- *  of the License, or (at your option) any later version.
-- *
-- *  This program is distributed in the hope that it will be useful,
-- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- *  GNU General Public License for more details.
-- *
-- *  You should have received a copy of the GNU General Public License
-- *  along with this program; if not, write to the Free Software
-- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-- */
--
--#include "dialog.h"
--
--/*
-- * Display a message box. Program will pause and display an "OK" button
-- * if the parameter 'pause' is non-zero.
-- */
--int
--dialog_msgbox (const char *title, const char *prompt, int height, int width,
--              int pause)
--{
--    int i, x, y, key = 0;
--    WINDOW *dialog;
--
--    /* center dialog box on screen */
--    x = (COLS - width) / 2;
--    y = (LINES - height) / 2;
--
--    draw_shadow (stdscr, y, x, height, width);
--
--    dialog = newwin (height, width, y, x);
--    keypad (dialog, TRUE);
--
--    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
--
--    if (title != NULL && strlen(title) >= width-2 ) {
--      /* truncate long title -- mec */
--      char * title2 = malloc(width-2+1);
--      memcpy( title2, title, width-2 );
--      title2[width-2] = '\0';
--      title = title2;
--    }
--
--    if (title != NULL) {
--      wattrset (dialog, title_attr);
--      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
--      waddstr (dialog, (char *)title);
--      waddch (dialog, ' ');
--    }
--    wattrset (dialog, dialog_attr);
--    print_autowrap (dialog, prompt, width - 2, 1, 2);
--
--    if (pause) {
--      wattrset (dialog, border_attr);
--      mvwaddch (dialog, height - 3, 0, ACS_LTEE);
--      for (i = 0; i < width - 2; i++)
--          waddch (dialog, ACS_HLINE);
--      wattrset (dialog, dialog_attr);
--      waddch (dialog, ACS_RTEE);
--
--      print_button (dialog, "  Ok  ",
--                    height - 2, width / 2 - 4, TRUE);
--
--      wrefresh (dialog);
--      while (key != ESC && key != '\n' && key != ' ' &&
--               key != 'O' && key != 'o' && key != 'X' && key != 'x')
--          key = wgetch (dialog);
--    } else {
--      key = '\n';
--      wrefresh (dialog);
--    }
--
--    delwin (dialog);
--    return key == ESC ? -1 : 0;
--}
-diff -Nur busybox-1.00/scripts/config/symbol.c busybox/scripts/config/symbol.c
---- busybox-1.00/scripts/config/symbol.c       2004-07-15 08:01:05.000000000 +0200
-+++ busybox/scripts/config/symbol.c    2005-06-04 08:20:03.000000000 +0200
-@@ -6,6 +6,7 @@
- #include <ctype.h>
- #include <stdlib.h>
- #include <string.h>
-+#include <regex.h>
- #include <sys/utsname.h>
- #define LKC_DIRECT_LINK
-@@ -414,7 +415,7 @@
- bool sym_string_valid(struct symbol *sym, const char *str)
- {
--      char ch;
-+      signed char ch;
-       switch (sym->type) {
-       case S_STRING:
-@@ -649,6 +650,43 @@
-       return symbol;
- }
-+struct symbol **sym_re_search(const char *pattern)
-+{
-+      struct symbol *sym, **sym_arr = NULL;
-+      int i, cnt, size;
-+      regex_t re;
-+
-+      cnt = size = 0;
-+      /* Skip if empty */
-+      if (strlen(pattern) == 0)
-+              return NULL;
-+      if (regcomp(&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE))
-+              return NULL;
-+
-+      for_all_symbols(i, sym) {
-+              if (sym->flags & SYMBOL_CONST || !sym->name)
-+                      continue;
-+              if (regexec(&re, sym->name, 0, NULL, 0))
-+                      continue;
-+              if (cnt + 1 >= size) {
-+                      void *tmp = sym_arr;
-+                      size += 16;
-+                      sym_arr = realloc(sym_arr, size * sizeof(struct symbol *));
-+                      if (!sym_arr) {
-+                              free(tmp);
-+                              return NULL;
-+                      }
-+              }
-+              sym_arr[cnt++] = sym;
-+      }
-+      if (sym_arr)
-+              sym_arr[cnt] = NULL;
-+      regfree(&re);
-+
-+      return sym_arr;
-+}
-+
-+
- struct symbol *sym_check_deps(struct symbol *sym);
- static struct symbol *sym_check_expr_deps(struct expr *e)
-diff -Nur busybox-1.00/scripts/config/textbox.c busybox/scripts/config/textbox.c
---- busybox-1.00/scripts/config/textbox.c      2004-07-15 08:01:05.000000000 +0200
-+++ busybox/scripts/config/textbox.c   1970-01-01 01:00:00.000000000 +0100
-@@ -1,556 +0,0 @@
--/*
-- *  textbox.c -- implements the text box
-- *
-- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
-- *
-- *  This program is free software; you can redistribute it and/or
-- *  modify it under the terms of the GNU General Public License
-- *  as published by the Free Software Foundation; either version 2
-- *  of the License, or (at your option) any later version.
-- *
-- *  This program is distributed in the hope that it will be useful,
-- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- *  GNU General Public License for more details.
-- *
-- *  You should have received a copy of the GNU General Public License
-- *  along with this program; if not, write to the Free Software
-- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-- */
--
--#include "dialog.h"
--
--static void back_lines (int n);
--static void print_page (WINDOW * win, int height, int width);
--static void print_line (WINDOW * win, int row, int width);
--static char *get_line (void);
--static void print_position (WINDOW * win, int height, int width);
--
--static int hscroll, fd, file_size, bytes_read;
--static int begin_reached = 1, end_reached, page_length;
--static char *buf, *page;
--
--/*
-- * Display text from a file in a dialog box.
-- */
--int
--dialog_textbox (const char *title, const char *file, int height, int width)
--{
--    int i, x, y, cur_x, cur_y, fpos, key = 0;
--    int passed_end;
--    char search_term[MAX_LEN + 1];
--    WINDOW *dialog, *text;
--
--    search_term[0] = '\0';    /* no search term entered yet */
--
--    /* Open input file for reading */
--    if ((fd = open (file, O_RDONLY)) == -1) {
--      endwin ();
--      fprintf (stderr,
--               "\nCan't open input file in dialog_textbox().\n");
--      exit (-1);
--    }
--    /* Get file size. Actually, 'file_size' is the real file size - 1,
--       since it's only the last byte offset from the beginning */
--    if ((file_size = lseek (fd, 0, SEEK_END)) == -1) {
--      endwin ();
--      fprintf (stderr, "\nError getting file size in dialog_textbox().\n");
--      exit (-1);
--    }
--    /* Restore file pointer to beginning of file after getting file size */
--    if (lseek (fd, 0, SEEK_SET) == -1) {
--      endwin ();
--      fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n");
--      exit (-1);
--    }
--    /* Allocate space for read buffer */
--    if ((buf = malloc (BUF_SIZE + 1)) == NULL) {
--      endwin ();
--      fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n");
--      exit (-1);
--    }
--    if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
--      endwin ();
--      fprintf (stderr, "\nError reading file in dialog_textbox().\n");
--      exit (-1);
--    }
--    buf[bytes_read] = '\0';   /* mark end of valid data */
--    page = buf;                       /* page is pointer to start of page to be displayed */
--
--    /* center dialog box on screen */
--    x = (COLS - width) / 2;
--    y = (LINES - height) / 2;
--
--
--    draw_shadow (stdscr, y, x, height, width);
--
--    dialog = newwin (height, width, y, x);
--    keypad (dialog, TRUE);
--
--    /* Create window for text region, used for scrolling text */
--    text = subwin (dialog, height - 4, width - 2, y + 1, x + 1);
--    wattrset (text, dialog_attr);
--    wbkgdset (text, dialog_attr & A_COLOR);
--
--    keypad (text, TRUE);
--
--    /* register the new window, along with its borders */
--    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
--
--    wattrset (dialog, border_attr);
--    mvwaddch (dialog, height-3, 0, ACS_LTEE);
--    for (i = 0; i < width - 2; i++)
--      waddch (dialog, ACS_HLINE);
--    wattrset (dialog, dialog_attr);
--    wbkgdset (dialog, dialog_attr & A_COLOR);
--    waddch (dialog, ACS_RTEE);
--
--    if (title != NULL && strlen(title) >= width-2 ) {
--      /* truncate long title -- mec */
--      char * title2 = malloc(width-2+1);
--      memcpy( title2, title, width-2 );
--      title2[width-2] = '\0';
--      title = title2;
--    }
--
--    if (title != NULL) {
--      wattrset (dialog, title_attr);
--      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
--      waddstr (dialog, (char *)title);
--      waddch (dialog, ' ');
--    }
--    print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE);
--    wnoutrefresh (dialog);
--    getyx (dialog, cur_y, cur_x);     /* Save cursor position */
--
--    /* Print first page of text */
--    attr_clear (text, height - 4, width - 2, dialog_attr);
--    print_page (text, height - 4, width - 2);
--    print_position (dialog, height, width);
--    wmove (dialog, cur_y, cur_x);     /* Restore cursor position */
--    wrefresh (dialog);
--
--    while ((key != ESC) && (key != '\n')) {
--      key = wgetch (dialog);
--      switch (key) {
--      case 'E':               /* Exit */
--      case 'e':
--      case 'X':
--      case 'x':
--          delwin (dialog);
--          free (buf);
--          close (fd);
--          return 0;
--      case 'g':               /* First page */
--      case KEY_HOME:
--          if (!begin_reached) {
--              begin_reached = 1;
--              /* First page not in buffer? */
--              if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
--                  endwin ();
--                  fprintf (stderr,
--                    "\nError moving file pointer in dialog_textbox().\n");
--                  exit (-1);
--              }
--              if (fpos > bytes_read) {        /* Yes, we have to read it in */
--                  if (lseek (fd, 0, SEEK_SET) == -1) {
--                      endwin ();
--                      fprintf (stderr, "\nError moving file pointer in "
--                               "dialog_textbox().\n");
--                      exit (-1);
--                  }
--                  if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
--                      endwin ();
--                      fprintf (stderr,
--                           "\nError reading file in dialog_textbox().\n");
--                      exit (-1);
--                  }
--                  buf[bytes_read] = '\0';
--              }
--              page = buf;
--              print_page (text, height - 4, width - 2);
--              print_position (dialog, height, width);
--              wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
--              wrefresh (dialog);
--          }
--          break;
--      case 'G':               /* Last page */
--      case KEY_END:
--
--          end_reached = 1;
--          /* Last page not in buffer? */
--          if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
--              endwin ();
--              fprintf (stderr,
--                    "\nError moving file pointer in dialog_textbox().\n");
--              exit (-1);
--          }
--          if (fpos < file_size) {     /* Yes, we have to read it in */
--              if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) {
--                  endwin ();
--                  fprintf (stderr,
--                    "\nError moving file pointer in dialog_textbox().\n");
--                  exit (-1);
--              }
--              if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
--                  endwin ();
--                  fprintf (stderr,
--                           "\nError reading file in dialog_textbox().\n");
--                  exit (-1);
--              }
--              buf[bytes_read] = '\0';
--          }
--          page = buf + bytes_read;
--          back_lines (height - 4);
--          print_page (text, height - 4, width - 2);
--          print_position (dialog, height, width);
--          wmove (dialog, cur_y, cur_x);       /* Restore cursor position */
--          wrefresh (dialog);
--          break;
--      case 'K':               /* Previous line */
--      case 'k':
--      case KEY_UP:
--          if (!begin_reached) {
--              back_lines (page_length + 1);
--
--              /* We don't call print_page() here but use scrolling to ensure
--                 faster screen update. However, 'end_reached' and
--                 'page_length' should still be updated, and 'page' should
--                 point to start of next page. This is done by calling
--                 get_line() in the following 'for' loop. */
--              scrollok (text, TRUE);
--              wscrl (text, -1);       /* Scroll text region down one line */
--              scrollok (text, FALSE);
--              page_length = 0;
--              passed_end = 0;
--              for (i = 0; i < height - 4; i++) {
--                  if (!i) {
--                      /* print first line of page */
--                      print_line (text, 0, width - 2);
--                      wnoutrefresh (text);
--                  } else
--                      /* Called to update 'end_reached' and 'page' */
--                      get_line ();
--                  if (!passed_end)
--                      page_length++;
--                  if (end_reached && !passed_end)
--                      passed_end = 1;
--              }
--
--              print_position (dialog, height, width);
--              wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
--              wrefresh (dialog);
--          }
--          break;
--      case 'B':               /* Previous page */
--      case 'b':
--      case KEY_PPAGE:
--          if (begin_reached)
--              break;
--          back_lines (page_length + height - 4);
--          print_page (text, height - 4, width - 2);
--          print_position (dialog, height, width);
--          wmove (dialog, cur_y, cur_x);
--          wrefresh (dialog);
--          break;
--      case 'J':               /* Next line */
--      case 'j':
--      case KEY_DOWN:
--          if (!end_reached) {
--              begin_reached = 0;
--              scrollok (text, TRUE);
--              scroll (text);  /* Scroll text region up one line */
--              scrollok (text, FALSE);
--              print_line (text, height - 5, width - 2);
--              wnoutrefresh (text);
--              print_position (dialog, height, width);
--              wmove (dialog, cur_y, cur_x);   /* Restore cursor position */
--              wrefresh (dialog);
--          }
--          break;
--      case KEY_NPAGE:         /* Next page */
--      case ' ':
--          if (end_reached)
--              break;
--
--          begin_reached = 0;
--          print_page (text, height - 4, width - 2);
--          print_position (dialog, height, width);
--          wmove (dialog, cur_y, cur_x);
--          wrefresh (dialog);
--          break;
--      case '0':               /* Beginning of line */
--      case 'H':               /* Scroll left */
--      case 'h':
--      case KEY_LEFT:
--          if (hscroll <= 0)
--              break;
--
--          if (key == '0')
--              hscroll = 0;
--          else
--              hscroll--;
--          /* Reprint current page to scroll horizontally */
--          back_lines (page_length);
--          print_page (text, height - 4, width - 2);
--          wmove (dialog, cur_y, cur_x);
--          wrefresh (dialog);
--          break;
--      case 'L':               /* Scroll right */
--      case 'l':
--      case KEY_RIGHT:
--          if (hscroll >= MAX_LEN)
--              break;
--          hscroll++;
--          /* Reprint current page to scroll horizontally */
--          back_lines (page_length);
--          print_page (text, height - 4, width - 2);
--          wmove (dialog, cur_y, cur_x);
--          wrefresh (dialog);
--          break;
--      case ESC:
--          break;
--      }
--    }
--
--    delwin (dialog);
--    free (buf);
--    close (fd);
--    return 1;                 /* ESC pressed */
--}
--
--/*
-- * Go back 'n' lines in text file. Called by dialog_textbox().
-- * 'page' will be updated to point to the desired line in 'buf'.
-- */
--static void
--back_lines (int n)
--{
--    int i, fpos;
--
--    begin_reached = 0;
--    /* We have to distinguish between end_reached and !end_reached
--       since at end of file, the line is not ended by a '\n'.
--       The code inside 'if' basically does a '--page' to move one
--       character backward so as to skip '\n' of the previous line */
--    if (!end_reached) {
--      /* Either beginning of buffer or beginning of file reached? */
--      if (page == buf) {
--          if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
--              endwin ();
--              fprintf (stderr, "\nError moving file pointer in "
--                       "back_lines().\n");
--              exit (-1);
--          }
--          if (fpos > bytes_read) {    /* Not beginning of file yet */
--              /* We've reached beginning of buffer, but not beginning of
--                 file yet, so read previous part of file into buffer.
--                 Note that we only move backward for BUF_SIZE/2 bytes,
--                 but not BUF_SIZE bytes to avoid re-reading again in
--                 print_page() later */
--              /* Really possible to move backward BUF_SIZE/2 bytes? */
--              if (fpos < BUF_SIZE / 2 + bytes_read) {
--                  /* No, move less then */
--                  if (lseek (fd, 0, SEEK_SET) == -1) {
--                      endwin ();
--                      fprintf (stderr, "\nError moving file pointer in "
--                               "back_lines().\n");
--                      exit (-1);
--                  }
--                  page = buf + fpos - bytes_read;
--              } else {        /* Move backward BUF_SIZE/2 bytes */
--                  if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR)
--                      == -1) {
--                      endwin ();
--                      fprintf (stderr, "\nError moving file pointer "
--                               "in back_lines().\n");
--                      exit (-1);
--                  }
--                  page = buf + BUF_SIZE / 2;
--              }
--              if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
--                  endwin ();
--                  fprintf (stderr, "\nError reading file in back_lines().\n");
--                  exit (-1);
--              }
--              buf[bytes_read] = '\0';
--          } else {            /* Beginning of file reached */
--              begin_reached = 1;
--              return;
--          }
--      }
--      if (*(--page) != '\n') {        /* '--page' here */
--          /* Something's wrong... */
--          endwin ();
--          fprintf (stderr, "\nInternal error in back_lines().\n");
--          exit (-1);
--      }
--    }
--    /* Go back 'n' lines */
--    for (i = 0; i < n; i++)
--      do {
--          if (page == buf) {
--              if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
--                  endwin ();
--                  fprintf (stderr,
--                        "\nError moving file pointer in back_lines().\n");
--                  exit (-1);
--              }
--              if (fpos > bytes_read) {
--                  /* Really possible to move backward BUF_SIZE/2 bytes? */
--                  if (fpos < BUF_SIZE / 2 + bytes_read) {
--                      /* No, move less then */
--                      if (lseek (fd, 0, SEEK_SET) == -1) {
--                          endwin ();
--                          fprintf (stderr, "\nError moving file pointer "
--                                   "in back_lines().\n");
--                          exit (-1);
--                      }
--                      page = buf + fpos - bytes_read;
--                  } else {    /* Move backward BUF_SIZE/2 bytes */
--                      if (lseek (fd, -(BUF_SIZE / 2 + bytes_read),
--                                 SEEK_CUR) == -1) {
--                          endwin ();
--                          fprintf (stderr, "\nError moving file pointer"
--                                   " in back_lines().\n");
--                          exit (-1);
--                      }
--                      page = buf + BUF_SIZE / 2;
--                  }
--                  if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
--                      endwin ();
--                      fprintf (stderr, "\nError reading file in "
--                               "back_lines().\n");
--                      exit (-1);
--                  }
--                  buf[bytes_read] = '\0';
--              } else {        /* Beginning of file reached */
--                  begin_reached = 1;
--                  return;
--              }
--          }
--      } while (*(--page) != '\n');
--    page++;
--}
--
--/*
-- * Print a new page of text. Called by dialog_textbox().
-- */
--static void
--print_page (WINDOW * win, int height, int width)
--{
--    int i, passed_end = 0;
--
--    page_length = 0;
--    for (i = 0; i < height; i++) {
--      print_line (win, i, width);
--      if (!passed_end)
--          page_length++;
--      if (end_reached && !passed_end)
--          passed_end = 1;
--    }
--    wnoutrefresh (win);
--}
--
--/*
-- * Print a new line of text. Called by dialog_textbox() and print_page().
-- */
--static void
--print_line (WINDOW * win, int row, int width)
--{
--    int y, x;
--    char *line;
--
--    line = get_line ();
--    line += MIN (strlen (line), hscroll);     /* Scroll horizontally */
--    wmove (win, row, 0);      /* move cursor to correct line */
--    waddch (win, ' ');
--    waddnstr (win, line, MIN (strlen (line), width - 2));
--
--    getyx (win, y, x);
--    /* Clear 'residue' of previous line */
--#if OLD_NCURSES
--    {
--        int i;
--        for (i = 0; i < width - x; i++)
--          waddch (win, ' ');
--    }
--#else
--    wclrtoeol(win);
--#endif
--}
--
--/*
-- * Return current line of text. Called by dialog_textbox() and print_line().
-- * 'page' should point to start of current line before calling, and will be
-- * updated to point to start of next line.
-- */
--static char *
--get_line (void)
--{
--    int i = 0, fpos;
--    static char line[MAX_LEN + 1];
--
--    end_reached = 0;
--    while (*page != '\n') {
--      if (*page == '\0') {
--          /* Either end of file or end of buffer reached */
--          if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
--              endwin ();
--              fprintf (stderr, "\nError moving file pointer in "
--                       "get_line().\n");
--              exit (-1);
--          }
--          if (fpos < file_size) {     /* Not end of file yet */
--              /* We've reached end of buffer, but not end of file yet,
--                 so read next part of file into buffer */
--              if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) {
--                  endwin ();
--                  fprintf (stderr, "\nError reading file in get_line().\n");
--                  exit (-1);
--              }
--              buf[bytes_read] = '\0';
--              page = buf;
--          } else {
--              if (!end_reached)
--                  end_reached = 1;
--              break;
--          }
--      } else if (i < MAX_LEN)
--          line[i++] = *(page++);
--      else {
--          /* Truncate lines longer than MAX_LEN characters */
--          if (i == MAX_LEN)
--              line[i++] = '\0';
--          page++;
--      }
--    }
--    if (i <= MAX_LEN)
--      line[i] = '\0';
--    if (!end_reached)
--      page++;                 /* move pass '\n' */
--
--    return line;
--}
--
--/*
-- * Print current position
-- */
--static void
--print_position (WINDOW * win, int height, int width)
--{
--    int fpos, percent;
--
--    if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) {
--      endwin ();
--      fprintf (stderr, "\nError moving file pointer in print_position().\n");
--      exit (-1);
--    }
--    wattrset (win, position_indicator_attr);
--    wbkgdset (win, position_indicator_attr & A_COLOR);
--    percent = !file_size ?
--      100 : ((fpos - bytes_read + page - buf) * 100) / file_size;
--    wmove (win, height - 3, width - 9);
--    wprintw (win, "(%3d%%)", percent);
--}
-diff -Nur busybox-1.00/scripts/config/util.c busybox/scripts/config/util.c
---- busybox-1.00/scripts/config/util.c 2004-07-15 08:01:05.000000000 +0200
-+++ busybox/scripts/config/util.c      2005-06-04 08:20:03.000000000 +0200
-@@ -1,375 +1,109 @@
- /*
-- *  util.c
-+ * Copyright (C) 2002-2005 Roman Zippel <zippel@linux-m68k.org>
-+ * Copyright (C) 2002-2005 Sam Ravnborg <sam@ravnborg.org>
-  *
-- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
-- *
-- *  This program is free software; you can redistribute it and/or
-- *  modify it under the terms of the GNU General Public License
-- *  as published by the Free Software Foundation; either version 2
-- *  of the License, or (at your option) any later version.
-- *
-- *  This program is distributed in the hope that it will be useful,
-- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- *  GNU General Public License for more details.
-- *
-- *  You should have received a copy of the GNU General Public License
-- *  along with this program; if not, write to the Free Software
-- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-- */
--
--#include "dialog.h"
--
--
--/* use colors by default? */
--bool use_colors = 1;
--
--char *backtitle = NULL;
--
--const char *dialog_result;
--
--/*
-- * Attribute values, default is for mono display
-+ * Released under the terms of the GNU GPL v2.0.
-  */
--chtype attributes[] =
--{
--    A_NORMAL,                 /* screen_attr */
--    A_NORMAL,                 /* shadow_attr */
--    A_NORMAL,                 /* dialog_attr */
--    A_BOLD,                   /* title_attr */
--    A_NORMAL,                 /* border_attr */
--    A_REVERSE,                        /* button_active_attr */
--    A_DIM,                    /* button_inactive_attr */
--    A_REVERSE,                        /* button_key_active_attr */
--    A_BOLD,                   /* button_key_inactive_attr */
--    A_REVERSE,                        /* button_label_active_attr */
--    A_NORMAL,                 /* button_label_inactive_attr */
--    A_NORMAL,                 /* inputbox_attr */
--    A_NORMAL,                 /* inputbox_border_attr */
--    A_NORMAL,                 /* searchbox_attr */
--    A_BOLD,                   /* searchbox_title_attr */
--    A_NORMAL,                 /* searchbox_border_attr */
--    A_BOLD,                   /* position_indicator_attr */
--    A_NORMAL,                 /* menubox_attr */
--    A_NORMAL,                 /* menubox_border_attr */
--    A_NORMAL,                 /* item_attr */
--    A_REVERSE,                        /* item_selected_attr */
--    A_BOLD,                   /* tag_attr */
--    A_REVERSE,                        /* tag_selected_attr */
--    A_BOLD,                   /* tag_key_attr */
--    A_REVERSE,                        /* tag_key_selected_attr */
--    A_BOLD,                   /* check_attr */
--    A_REVERSE,                        /* check_selected_attr */
--    A_BOLD,                   /* uarrow_attr */
--    A_BOLD                    /* darrow_attr */
--};
-+#include <string.h>
-+#include "lkc.h"
--#include "colors.h"
--
--/*
-- * Table of color values
-- */
--int color_table[][3] =
-+/* file already present in list? If not add it */
-+struct file *file_lookup(const char *name)
- {
--    {SCREEN_FG, SCREEN_BG, SCREEN_HL},
--    {SHADOW_FG, SHADOW_BG, SHADOW_HL},
--    {DIALOG_FG, DIALOG_BG, DIALOG_HL},
--    {TITLE_FG, TITLE_BG, TITLE_HL},
--    {BORDER_FG, BORDER_BG, BORDER_HL},
--    {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL},
--    {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL},
--    {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL},
--    {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL},
--    {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL},
--    {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG,
--     BUTTON_LABEL_INACTIVE_HL},
--    {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL},
--    {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL},
--    {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL},
--    {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL},
--    {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL},
--    {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL},
--    {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL},
--    {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL},
--    {ITEM_FG, ITEM_BG, ITEM_HL},
--    {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL},
--    {TAG_FG, TAG_BG, TAG_HL},
--    {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL},
--    {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL},
--    {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL},
--    {CHECK_FG, CHECK_BG, CHECK_HL},
--    {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL},
--    {UARROW_FG, UARROW_BG, UARROW_HL},
--    {DARROW_FG, DARROW_BG, DARROW_HL},
--};                            /* color_table */
-+      struct file *file;
--/*
-- * Set window to attribute 'attr'
-- */
--void
--attr_clear (WINDOW * win, int height, int width, chtype attr)
--{
--    int i, j;
-+      for (file = file_list; file; file = file->next) {
-+              if (!strcmp(name, file->name))
-+                      return file;
-+      }
--    wattrset (win, attr);
--    for (i = 0; i < height; i++) {
--      wmove (win, i, 0);
--      for (j = 0; j < width; j++)
--          waddch (win, ' ');
--    }
--    touchwin (win);
-+      file = malloc(sizeof(*file));
-+      memset(file, 0, sizeof(*file));
-+      file->name = strdup(name);
-+      file->next = file_list;
-+      file_list = file;
-+      return file;
-+}
-+
-+/* write a dependency file as used by kbuild to track dependencies */
-+int file_write_dep(const char *name)
-+{
-+      struct file *file;
-+      FILE *out;
-+
-+      if (!name)
-+              name = ".config.cmd";
-+      out = fopen(".config.tmp", "w");
-+      if (!out)
-+              return 1;
-+      fprintf(out, "deps_config := \\\n");
-+      for (file = file_list; file; file = file->next) {
-+              if (file->next)
-+                      fprintf(out, "\t%s \\\n", file->name);
-+              else
-+                      fprintf(out, "\t%s\n", file->name);
-+      }
-+      fprintf(out, "\n.config include/config.h: $(deps_config)\n\n$(deps_config):\n");
-+      fclose(out);
-+      rename(".config.tmp", name);
-+      return 0;
- }
--void dialog_clear (void)
--{
--    attr_clear (stdscr, LINES, COLS, screen_attr);
--    /* Display background title if it exists ... - SLH */
--    if (backtitle != NULL) {
--        int i;
--
--        wattrset (stdscr, screen_attr);
--        mvwaddstr (stdscr, 0, 1, (char *)backtitle);
--        wmove (stdscr, 1, 1);
--        for (i = 1; i < COLS - 1; i++)
--            waddch (stdscr, ACS_HLINE);
--    }
--    wnoutrefresh (stdscr);
--}
--/*
-- * Do some initialization for dialog
-- */
--void
--init_dialog (void)
-+/* Allocate initial growable sting */
-+struct gstr str_new(void)
- {
--    initscr ();                       /* Init curses */
--    keypad (stdscr, TRUE);
--    cbreak ();
--    noecho ();
--
--
--    if (use_colors)   /* Set up colors */
--      color_setup ();
--
--
--    dialog_clear ();
-+      struct gstr gs;
-+      gs.s = malloc(sizeof(char) * 64);
-+      gs.len = 16;
-+      strcpy(gs.s, "\0");
-+      return gs;
- }
--/*
-- * Setup for color display
-- */
--void
--color_setup (void)
-+/* Allocate and assign growable string */
-+struct gstr str_assign(const char *s)
- {
--    int i;
--
--    if (has_colors ()) {      /* Terminal supports color? */
--      start_color ();
--
--      /* Initialize color pairs */
--      for (i = 0; i < ATTRIBUTE_COUNT; i++)
--          init_pair (i + 1, color_table[i][0], color_table[i][1]);
--
--      /* Setup color attributes */
--      for (i = 0; i < ATTRIBUTE_COUNT; i++)
--          attributes[i] = C_ATTR (color_table[i][2], i + 1);
--    }
-+      struct gstr gs;
-+      gs.s = strdup(s);
-+      gs.len = strlen(s) + 1;
-+      return gs;
- }
--/*
-- * End using dialog functions.
-- */
--void
--end_dialog (void)
-+/* Free storage for growable string */
-+void str_free(struct gstr *gs)
- {
--    endwin ();
-+      if (gs->s)
-+              free(gs->s);
-+      gs->s = NULL;
-+      gs->len = 0;
- }
--
--/*
-- * Print a string of text in a window, automatically wrap around to the
-- * next line if the string is too long to fit on one line. Newline
-- * characters '\n' are replaced by spaces.  We start on a new line
-- * if there is no room for at least 4 nonblanks following a double-space.
-- */
--void
--print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x)
-+/* Append to growable string */
-+void str_append(struct gstr *gs, const char *s)
- {
--    int newl, cur_x, cur_y;
--    int i, prompt_len, room, wlen;
--    char tempstr[MAX_LEN + 1], *word, *sp, *sp2;
--
--    strcpy (tempstr, prompt);
--
--    prompt_len = strlen(tempstr);
--
--    /*
--     * Remove newlines
--     */
--    for(i=0; i<prompt_len; i++) {
--      if(tempstr[i] == '\n') tempstr[i] = ' ';
--    }
--
--    if (prompt_len <= width - x * 2) {        /* If prompt is short */
--      wmove (win, y, (width - prompt_len) / 2);
--      waddstr (win, tempstr);
--    } else {
--      cur_x = x;
--      cur_y = y;
--      newl = 1;
--      word = tempstr;
--      while (word && *word) {
--          sp = index(word, ' ');
--          if (sp)
--              *sp++ = 0;
--
--          /* Wrap to next line if either the word does not fit,
--             or it is the first word of a new sentence, and it is
--             short, and the next word does not fit. */
--          room = width - cur_x;
--          wlen = strlen(word);
--          if (wlen > room ||
--             (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room
--                   && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) {
--              cur_y++;
--              cur_x = x;
--          }
--          wmove (win, cur_y, cur_x);
--          waddstr (win, word);
--          getyx (win, cur_y, cur_x);
--          cur_x++;
--          if (sp && *sp == ' ') {
--              cur_x++;        /* double space */
--              while (*++sp == ' ');
--              newl = 1;
--          } else
--              newl = 0;
--          word = sp;
-+      size_t l = strlen(gs->s) + strlen(s) + 1;
-+      if (l > gs->len) {
-+              gs->s   = realloc(gs->s, l);
-+              gs->len = l;
-       }
--    }
--}
--
--/*
-- * Print a button
-- */
--void
--print_button (WINDOW * win, const char *label, int y, int x, int selected)
--{
--    int i, temp;
--
--    wmove (win, y, x);
--    wattrset (win, selected ? button_active_attr : button_inactive_attr);
--    waddstr (win, "<");
--    temp = strspn (label, " ");
--    label += temp;
--    wattrset (win, selected ? button_label_active_attr
--            : button_label_inactive_attr);
--    for (i = 0; i < temp; i++)
--      waddch (win, ' ');
--    wattrset (win, selected ? button_key_active_attr
--            : button_key_inactive_attr);
--    waddch (win, label[0]);
--    wattrset (win, selected ? button_label_active_attr
--            : button_label_inactive_attr);
--    waddstr (win, (char *)label + 1);
--    wattrset (win, selected ? button_active_attr : button_inactive_attr);
--    waddstr (win, ">");
--    wmove (win, y, x + temp + 1);
-+      strcat(gs->s, s);
- }
--/*
-- * Draw a rectangular box with line drawing characters
-- */
--void
--draw_box (WINDOW * win, int y, int x, int height, int width,
--        chtype box, chtype border)
--{
--    int i, j;
--
--    wattrset (win, 0);
--    for (i = 0; i < height; i++) {
--      wmove (win, y + i, x);
--      for (j = 0; j < width; j++)
--          if (!i && !j)
--              waddch (win, border | ACS_ULCORNER);
--          else if (i == height - 1 && !j)
--              waddch (win, border | ACS_LLCORNER);
--          else if (!i && j == width - 1)
--              waddch (win, box | ACS_URCORNER);
--          else if (i == height - 1 && j == width - 1)
--              waddch (win, box | ACS_LRCORNER);
--          else if (!i)
--              waddch (win, border | ACS_HLINE);
--          else if (i == height - 1)
--              waddch (win, box | ACS_HLINE);
--          else if (!j)
--              waddch (win, border | ACS_VLINE);
--          else if (j == width - 1)
--              waddch (win, box | ACS_VLINE);
--          else
--              waddch (win, box | ' ');
--    }
--}
--
--/*
-- * Draw shadows along the right and bottom edge to give a more 3D look
-- * to the boxes
-- */
--void
--draw_shadow (WINDOW * win, int y, int x, int height, int width)
-+/* Append printf formatted string to growable string */
-+void str_printf(struct gstr *gs, const char *fmt, ...)
- {
--    int i;
--
--    if (has_colors ()) {      /* Whether terminal supports color? */
--      wattrset (win, shadow_attr);
--      wmove (win, y + height, x + 2);
--      for (i = 0; i < width; i++)
--          waddch (win, winch (win) & A_CHARTEXT);
--      for (i = y + 1; i < y + height + 1; i++) {
--          wmove (win, i, x + width);
--          waddch (win, winch (win) & A_CHARTEXT);
--          waddch (win, winch (win) & A_CHARTEXT);
--      }
--      wnoutrefresh (win);
--    }
-+      va_list ap;
-+      char s[10000]; /* big enough... */
-+      va_start(ap, fmt);
-+      vsnprintf(s, sizeof(s), fmt, ap);
-+      str_append(gs, s);
-+      va_end(ap);
- }
--/*
-- *  Return the position of the first alphabetic character in a string.
-- */
--int
--first_alpha(const char *string, const char *exempt)
-+/* Retreive value of growable string */
-+const char *str_get(struct gstr *gs)
- {
--      int i, in_paren=0, c;
--
--      for (i = 0; i < strlen(string); i++) {
--              c = tolower(string[i]);
--
--              if (strchr("<[(", c)) ++in_paren;
--              if (strchr(">])", c) && in_paren > 0) --in_paren;
--
--              if ((! in_paren) && isalpha(c) &&
--                   strchr(exempt, c) == 0)
--                      return i;
--      }
--
--      return 0;
-+      return gs->s;
- }
--/*
-- * Get the first selected item in the dialog_list_item list.
-- */
--struct dialog_list_item *
--first_sel_item(int item_no, struct dialog_list_item ** items)
--{
--      int i;
--
--      for (i = 0; i < item_no; i++) {
--              if (items[i]->selected)
--                      return items[i];
--      }
--
--      return NULL;
--}
-diff -Nur busybox-1.00/scripts/config/yesno.c busybox/scripts/config/yesno.c
---- busybox-1.00/scripts/config/yesno.c        2002-12-05 09:41:08.000000000 +0100
-+++ busybox/scripts/config/yesno.c     1970-01-01 01:00:00.000000000 +0100
-@@ -1,118 +0,0 @@
--/*
-- *  yesno.c -- implements the yes/no box
-- *
-- *  ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
-- *  MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com)
-- *
-- *  This program is free software; you can redistribute it and/or
-- *  modify it under the terms of the GNU General Public License
-- *  as published by the Free Software Foundation; either version 2
-- *  of the License, or (at your option) any later version.
-- *
-- *  This program is distributed in the hope that it will be useful,
-- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
-- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- *  GNU General Public License for more details.
-- *
-- *  You should have received a copy of the GNU General Public License
-- *  along with this program; if not, write to the Free Software
-- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-- */
--
--#include "dialog.h"
--
--/*
-- * Display termination buttons
-- */
--static void
--print_buttons(WINDOW *dialog, int height, int width, int selected)
--{
--    int x = width / 2 - 10;
--    int y = height - 2;
--
--    print_button (dialog, " Yes ", y, x, selected == 0);
--    print_button (dialog, "  No  ", y, x + 13, selected == 1);
--
--    wmove(dialog, y, x+1 + 13*selected );
--    wrefresh (dialog);
--}
--
--/*
-- * Display a dialog box with two buttons - Yes and No
-- */
--int
--dialog_yesno (const char *title, const char *prompt, int height, int width)
--{
--    int i, x, y, key = 0, button = 0;
--    WINDOW *dialog;
--
--    /* center dialog box on screen */
--    x = (COLS - width) / 2;
--    y = (LINES - height) / 2;
--
--    draw_shadow (stdscr, y, x, height, width);
--
--    dialog = newwin (height, width, y, x);
--    keypad (dialog, TRUE);
--
--    draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr);
--    wattrset (dialog, border_attr);
--    mvwaddch (dialog, height-3, 0, ACS_LTEE);
--    for (i = 0; i < width - 2; i++)
--      waddch (dialog, ACS_HLINE);
--    wattrset (dialog, dialog_attr);
--    waddch (dialog, ACS_RTEE);
--
--    if (title != NULL && strlen(title) >= width-2 ) {
--      /* truncate long title -- mec */
--      char * title2 = malloc(width-2+1);
--      memcpy( title2, title, width-2 );
--      title2[width-2] = '\0';
--      title = title2;
--    }
--
--    if (title != NULL) {
--      wattrset (dialog, title_attr);
--      mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' ');
--      waddstr (dialog, (char *)title);
--      waddch (dialog, ' ');
--    }
--
--    wattrset (dialog, dialog_attr);
--    print_autowrap (dialog, prompt, width - 2, 1, 3);
--
--    print_buttons(dialog, height, width, 0);
--
--    while (key != ESC) {
--      key = wgetch (dialog);
--      switch (key) {
--      case 'Y':
--      case 'y':
--          delwin (dialog);
--          return 0;
--      case 'N':
--      case 'n':
--          delwin (dialog);
--          return 1;
--
--      case TAB:
--      case KEY_LEFT:
--      case KEY_RIGHT:
--          button = ((key == KEY_LEFT ? --button : ++button) < 0)
--                      ? 1 : (button > 1 ? 0 : button);
--
--          print_buttons(dialog, height, width, button);
--          wrefresh (dialog);
--          break;
--      case ' ':
--      case '\n':
--          delwin (dialog);
--          return button;
--      case ESC:
--          break;
--      }
--    }
--
--    delwin (dialog);
--    return -1;                        /* ESC pressed */
--}
-diff -Nur busybox-1.00/scripts/config/zconf.tab.c_shipped busybox/scripts/config/zconf.tab.c_shipped
---- busybox-1.00/scripts/config/zconf.tab.c_shipped    2004-03-15 09:29:08.000000000 +0100
-+++ busybox/scripts/config/zconf.tab.c_shipped 2005-06-04 08:20:03.000000000 +0200
-@@ -175,6 +175,8 @@
- struct symbol *symbol_hash[257];
-+static struct menu *current_menu, *current_entry;
-+
- #define YYERROR_VERBOSE
-@@ -227,7 +229,7 @@
- #  define YYSTACK_ALLOC alloca
- # else
- #  ifndef YYSTACK_USE_ALLOCA
--#   if defined (alloca) || defined (_ALLOCA_H)
-+#   if defined (alloca) || (defined (_ALLOCA_H) && defined (__GNUC__))
- #    define YYSTACK_ALLOC alloca
- #   else
- #    ifdef __GNUC__
-@@ -2119,6 +2121,7 @@
- }
- #include "lex.zconf.c"
-+#include "util.c"
- #include "confdata.c"
- #include "expr.c"
- #include "symbol.c"
-diff -Nur busybox-1.00/scripts/config/zconf.y busybox/scripts/config/zconf.y
---- busybox-1.00/scripts/config/zconf.y        2003-08-05 07:59:48.000000000 +0200
-+++ busybox/scripts/config/zconf.y     2005-06-04 08:20:03.000000000 +0200
-@@ -25,6 +25,8 @@
- struct symbol *symbol_hash[257];
-+static struct menu *current_menu, *current_entry;
-+
- #define YYERROR_VERBOSE
- %}
- %expect 40
-@@ -681,6 +683,7 @@
- }
- #include "lex.zconf.c"
-+#include "util.c"
- #include "confdata.c"
- #include "expr.c"
- #include "symbol.c"
-diff -Nur busybox-1.00/shell/Config.in busybox/shell/Config.in
---- busybox-1.00/shell/Config.in       2004-09-24 11:09:44.000000000 +0200
-+++ busybox/shell/Config.in    2005-06-04 08:20:11.000000000 +0200
-@@ -53,6 +53,17 @@
-       help
-         Enable job control in the ash shell.
-+config CONFIG_ASH_TIMEOUT
-+        bool "  Enable read timeout support."
-+        default n
-+        depends on CONFIG_ASH_JOB_CONTROL
-+        help
-+          This option provides read -t <seconds> support.
-+
-+        read builtin which allows the function to pass control back 
-+        if no character input is read from the terminal within a set
-+        number of seconds.
-+
- config CONFIG_ASH_ALIAS
-       bool "  Enable alias support"
-       default y
-diff -Nur busybox-1.00/shell/ash.c busybox/shell/ash.c
---- busybox-1.00/shell/ash.c   2004-10-08 11:43:34.000000000 +0200
-+++ busybox/shell/ash.c        2005-06-04 08:20:11.000000000 +0200
-@@ -3722,27 +3722,13 @@
- {
-       int repeated = 0;
- #ifdef CONFIG_FEATURE_SH_STANDALONE_SHELL
--      int flg_bb = 0;
--      char *name = cmd;
--
--      if(strchr(name, '/') == NULL && find_applet_by_name(name) != NULL) {
--              flg_bb = 1;
--      }
--      if(flg_bb) {
--              char **ap;
--              char **new;
--
--              *argv = name;
--              if(strcmp(name, "busybox")) {
--                      for (ap = argv; *ap; ap++);
--                      ap = new = xmalloc((ap - argv + 2) * sizeof(char *));
--                      *ap++ = cmd = "/bin/busybox";
--                      while ((*ap++ = *argv++));
--                      argv = new;
--                      repeated++;
--              } else {
--                      cmd = "/bin/busybox";
--              }
-+      if(find_applet_by_name(cmd) != NULL) {
-+              /* re-exec ourselves with the new arguments */
-+              execve("/proc/self/exe",argv,envp);
-+              /* If proc isn't mounted, try hardcoded path to busybox binary*/
-+              execve("/bin/busybox",argv,envp);
-+              /* If they called chroot or otherwise made the binary no longer
-+               * executable, fall through */
-       }
- #endif
-@@ -12583,17 +12569,34 @@
-       char *prompt;
-       const char *ifs;
-       char *p;
-+#if defined(CONFIG_ASH_TIMEOUT)
-+      fd_set set;
-+      int timeout;
-+      struct timeval timeout_struct;
-+      struct termios tty, old_tty;
-+#endif
-       int startword;
-       int status;
-       int i;
-       rflag = 0;
-       prompt = NULL;
--      while ((i = nextopt("p:r")) != '\0') {
-+#if defined(CONFIG_ASH_TIMEOUT)
-+      timeout = 0;
-+
-+      while ((i = nextopt("p:rt:")) != '\0')
-+#else
-+      while ((i = nextopt("p:r")) != '\0')
-+#endif
-+      {
-               if (i == 'p')
-                       prompt = optionarg;
--              else
-+              else if (i == 'r')
-                       rflag = 1;
-+#if defined(CONFIG_ASH_TIMEOUT)
-+              else
-+                      timeout = atoi(optionarg);
-+#endif
-       }
-       if (prompt && isatty(0)) {
-               out2str(prompt);
-@@ -12602,11 +12605,53 @@
-               error("arg count");
-       if ((ifs = bltinlookup("IFS")) == NULL)
-               ifs = defifs;
-+#if defined(CONFIG_ASH_TIMEOUT)
-+      c = 0;
-+#endif
-       status = 0;
-       startword = 1;
-       backslash = 0;
-+
-       STARTSTACKSTR(p);
--      for (;;) {
-+#if defined(CONFIG_ASH_TIMEOUT)
-+      if (timeout > 0) {
-+              tcgetattr(0, &tty);
-+              old_tty = tty;
-+
-+              /* cfmakeraw(...) disables too much; we just do this instead. */
-+              tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN);
-+              tcsetattr(0, TCSANOW, &tty);
-+
-+              FD_ZERO (&set);
-+              FD_SET (0, &set);
-+
-+              timeout_struct.tv_sec = timeout;
-+              timeout_struct.tv_usec = 0;
-+
-+              if ((i = select (FD_SETSIZE, &set, NULL, NULL, &timeout_struct)) == 1)
-+              {
-+                      read(0, &c, 1);
-+                      if(c == '\n' || c == 4) /* Handle newlines and EOF */
-+                              i = 0; /* Don't read further... */
-+                      else
-+                              STPUTC(c, p); /* Keep reading... */
-+              }
-+              tcsetattr(0, TCSANOW, &old_tty);
-+
-+              /* Echo the character so the user knows it was read...
-+                 Yes, this can be done by setting the ECHO flag, but that
-+                 echoes ^D and other control characters at this state */
-+              if(c != 0)
-+                      write(1, &c, 1);
-+
-+      } else
-+              i = 1;
-+
-+      for (;i == 1;)
-+#else
-+      for (;;)
-+#endif
-+      {
-               if (read(0, &c, 1) != 1) {
-                       status = 1;
-                       break;
-diff -Nur busybox-1.00/shell/lash.c busybox/shell/lash.c
---- busybox-1.00/shell/lash.c  2004-08-16 10:38:34.000000000 +0200
-+++ busybox/shell/lash.c       2005-06-04 08:20:11.000000000 +0200
-@@ -1277,11 +1277,17 @@
-       name = child->argv[0];
-       {
--          char** argv_l=child->argv;
--          int argc_l;
--          for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
--          optind = 1;
--          run_applet_by_name(name, argc_l, child->argv);
-+              char** argv_l=child->argv;
-+              int argc_l;
-+#ifdef _NEWLIB_VERSION
-+              /* newlib uses __getopt_initialized for getopt() in 
-+               * addition to optind, see newlib/libc/sys/linux/getopt.c
-+               */
-+              extern int __getopt_initialized = 0;
-+#endif
-+              for(argc_l=0;*argv_l!=NULL; argv_l++, argc_l++);
-+              optind = 1;
-+              run_applet_by_name(name, argc_l, child->argv);
-       }
- #endif
-diff -Nur busybox-1.00/sysdeps/linux/Config.in busybox/sysdeps/linux/Config.in
---- busybox-1.00/sysdeps/linux/Config.in       2004-05-25 13:30:22.000000000 +0200
-+++ busybox/sysdeps/linux/Config.in    2005-06-04 08:20:20.000000000 +0200
-@@ -113,6 +113,13 @@
-         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 >.
-@@ -221,6 +228,7 @@
- source coreutils/Config.in
- source console-tools/Config.in
- source debianutils/Config.in
-+source e2fsprogs/Config.in
- source editors/Config.in
- source findutils/Config.in
- source init/Config.in
-@@ -291,4 +299,3 @@
- endmenu
--
-diff -Nur busybox-1.00/sysklogd/Makefile busybox/sysklogd/Makefile
---- busybox-1.00/sysklogd/Makefile     2004-10-08 09:45:51.000000000 +0200
-+++ busybox/sysklogd/Makefile  2005-06-04 08:20:09.000000000 +0200
-@@ -1,6 +1,6 @@
- # Makefile for busybox
- #
--# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
-+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
-@@ -18,7 +18,7 @@
- #
- top_srcdir=..
--top_buildddir=..
-+top_builddir=..
- srcdir=$(top_srcdir)/sysklogd
- SYSKLOGD_DIR:=./
- include $(top_builddir)/Rules.mak
-@@ -29,4 +29,3 @@
- clean:
-       rm -f *.o *.a $(AR_TARGET)
--
-diff -Nur busybox-1.00/sysklogd/logger.c busybox/sysklogd/logger.c
---- busybox-1.00/sysklogd/logger.c     2004-08-27 00:18:59.000000000 +0200
-+++ busybox/sysklogd/logger.c  2005-06-04 08:20:09.000000000 +0200
-@@ -127,7 +127,7 @@
-               }
-       }
--      openlog(name, option, (pri | LOG_FACMASK));
-+      openlog(name, option, 0);
-       if (optind == argc) {
-               do {
-                       /* read from stdin */
-@@ -152,8 +152,8 @@
-                       message = xrealloc(message, len);
-                       if(!i)
-                               message[0] = 0;
--                       else
--                      strcat(message, " ");
-+                      else
-+                              strcat(message, " ");
-                       strcat(message, *argv);
-                       argv++;
-               }
-diff -Nur busybox-1.00/testsuite/sed/sed-branch-conditional-inverted busybox/testsuite/sed/sed-branch-conditional-inverted
---- busybox-1.00/testsuite/sed/sed-branch-conditional-inverted 1970-01-01 01:00:00.000000000 +0100
-+++ busybox/testsuite/sed/sed-branch-conditional-inverted      2005-06-04 08:20:19.000000000 +0200
-@@ -0,0 +1,14 @@
-+busybox sed 's/a/1/;T notone;p;: notone;p'>output <<EOF
-+a
-+b
-+c
-+EOF
-+cmp -s output - <<EOF
-+1
-+1
-+1
-+b
-+b
-+c
-+c
-+EOF
-diff -Nur busybox-1.00/util-linux/Config.in busybox/util-linux/Config.in
---- busybox-1.00/util-linux/Config.in  2004-05-19 13:06:20.000000000 +0200
-+++ busybox/util-linux/Config.in       2005-06-04 08:20:22.000000000 +0200
-@@ -5,7 +5,6 @@
- menu "Linux System Utilities"
--
- config CONFIG_DMESG
-       bool "dmesg"
-       default n
-@@ -27,7 +26,6 @@
-         interface to access a graphics display.  Enable this option
-         if you wish to enable the 'fbset' utility.
--
- config CONFIG_FEATURE_FBSET_FANCY
-       bool "  Turn on extra fbset options"
-       default n
-@@ -353,5 +351,11 @@
-         value is /etc/mtab, which is where this file is located on most desktop
-         Linux systems.
-+config CONFIG_READPROFILE
-+      bool "readprofile"
-+      default n
-+      help
-+        This allows you to parse /proc/profile for basic profiling.
-+
- endmenu
-diff -Nur busybox-1.00/util-linux/Makefile busybox/util-linux/Makefile
---- busybox-1.00/util-linux/Makefile   2004-10-08 09:46:08.000000000 +0200
-+++ busybox/util-linux/Makefile        2005-06-04 08:20:22.000000000 +0200
-@@ -1,6 +1,6 @@
- # Makefile for busybox
- #
--# Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org>
-+# Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org>
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
-@@ -18,7 +18,7 @@
- #
- top_srcdir=..
--top_buildddir=..
-+top_builddir=..
- srcdir=$(top_srcdir)/util-linux
- UTILLINUX_DIR:=./
- include $(top_builddir)/Rules.mak
-@@ -29,4 +29,3 @@
- clean:
-       rm -f *.o *.a $(AR_TARGET)
--
-diff -Nur busybox-1.00/util-linux/Makefile.in busybox/util-linux/Makefile.in
---- busybox-1.00/util-linux/Makefile.in        2004-10-08 09:46:08.000000000 +0200
-+++ busybox/util-linux/Makefile.in     2005-06-04 08:20:22.000000000 +0200
-@@ -44,6 +44,7 @@
- UTILLINUX-$(CONFIG_RDATE)             +=rdate.o
- UTILLINUX-$(CONFIG_SWAPONOFF)         +=swaponoff.o
- UTILLINUX-$(CONFIG_UMOUNT)            +=umount.o
-+UTILLINUX-$(CONFIG_READPROFILE)               +=readprofile.o
- libraries-y+=$(UTILLINUX_DIR)$(UTILLINUX_AR)
-@@ -63,4 +64,3 @@
- endif
- endif
--
-diff -Nur busybox-1.00/util-linux/hwclock.c busybox/util-linux/hwclock.c
---- busybox-1.00/util-linux/hwclock.c  2004-04-14 19:51:38.000000000 +0200
-+++ busybox/util-linux/hwclock.c       2005-06-04 08:20:22.000000000 +0200
-@@ -46,7 +46,7 @@
-       int tm_yday;
-       int tm_isdst;
- };
--                
-+
- #define RTC_SET_TIME   _IOW('p', 0x0a, struct linux_rtc_time) /* Set RTC time    */
- #define RTC_RD_TIME    _IOR('p', 0x09, struct linux_rtc_time) /* Read RTC time   */
-@@ -182,11 +182,11 @@
-       return utc;
- }
--#define HWCLOCK_OPT_LOCALTIME 1
--#define HWCLOCK_OPT_UTC       2
--#define HWCLOCK_OPT_SHOW      4
--#define HWCLOCK_OPT_HCTOSYS   8
--#define HWCLOCK_OPT_SYSTOHC   16
-+#define HWCLOCK_OPT_LOCALTIME 0x01
-+#define HWCLOCK_OPT_UTC       0x02
-+#define HWCLOCK_OPT_SHOW      0x04
-+#define HWCLOCK_OPT_HCTOSYS   0x08
-+#define HWCLOCK_OPT_SYSTOHC   0x10
- extern int hwclock_main ( int argc, char **argv )
- {
-@@ -208,16 +208,16 @@
-       bb_opt_complementaly = "r~ws:w~rs:s~wr:l~u:u~l";
-       opt = bb_getopt_ulflags(argc, argv, "lursw");
-       /* Check only one mode was given */
--      if(opt & 0x80000000UL) {
-+      if(opt & BB_GETOPT_ERROR) {
-               bb_show_usage();
-       }
-       /* If -u or -l wasn't given check if we are using utc */
--      if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME)) 
-+      if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME))
-               utc = opt & HWCLOCK_OPT_UTC;
-       else
-               utc = check_utc();
--      
-+
-       if (opt & HWCLOCK_OPT_HCTOSYS) {
-               return to_sys_clock ( utc );
-       }
-diff -Nur busybox-1.00/util-linux/readprofile.c busybox/util-linux/readprofile.c
---- busybox-1.00/util-linux/readprofile.c      1970-01-01 01:00:00.000000000 +0100
-+++ busybox/util-linux/readprofile.c   2005-06-04 08:20:22.000000000 +0200
-@@ -0,0 +1,302 @@
-+/*
-+ *  readprofile.c - used to read /proc/profile
-+ *
-+ *  Copyright (C) 1994,1996 Alessandro Rubini (rubini@ipvvis.unipv.it)
-+ *
-+ *   This program is free software; you can redistribute it and/or modify
-+ *   it under the terms of the GNU General Public License as published by
-+ *   the Free Software Foundation; either version 2 of the License, or
-+ *   (at your option) any later version.
-+ *
-+ *   This program is distributed in the hope that it will be useful,
-+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-+ *   GNU General Public License for more details.
-+ *
-+ *   You should have received a copy of the GNU General Public License
-+ *   along with this program; if not, write to the Free Software
-+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-+ */
-+
-+/*
-+ * 1999-02-22 Arkadiusz Mi¶kiewicz <misiek@pld.ORG.PL>
-+ * - added Native Language Support
-+ * 1999-09-01 Stephane Eranian <eranian@cello.hpl.hp.com>
-+ * - 64bit clean patch
-+ * 3Feb2001 Andrew Morton <andrewm@uow.edu.au>
-+ * - -M option to write profile multiplier.
-+ * 2001-11-07 Werner Almesberger <wa@almesberger.net>
-+ * - byte order auto-detection and -n option
-+ * 2001-11-09 Werner Almesberger <wa@almesberger.net>
-+ * - skip step size (index 0)
-+ * 2002-03-09 John Levon <moz@compsoc.man.ac.uk>
-+ * - make maplineno do something
-+ * 2002-11-28 Mads Martin Joergensen +
-+ * - also try /boot/System.map-`uname -r`
-+ * 2003-04-09 Werner Almesberger <wa@almesberger.net>
-+ * - fixed off-by eight error and improved heuristics in byte order detection
-+ * 2003-08-12 Nikita Danilov <Nikita@Namesys.COM>
-+ * - added -s option; example of use:
-+ * "readprofile -s -m /boot/System.map-test | grep __d_lookup | sort -n -k3"
-+ *
-+ * Taken from util-linux and adapted for busybox by
-+ * Paul Mundt <lethal@linux-sh.org>.
-+ */
-+
-+#include <errno.h>
-+#include <stdio.h>
-+#include <fcntl.h>
-+#include <stdlib.h>
-+#include <unistd.h>
-+#include <string.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <sys/utsname.h>
-+
-+#include "busybox.h"
-+
-+#define S_LEN 128
-+
-+/* These are the defaults */
-+static char defaultmap[]="/boot/System.map";
-+static char defaultpro[]="/proc/profile";
-+
-+int readprofile_main(int argc, char **argv)
-+{
-+      FILE *map;
-+      int proFd;
-+      char *mapFile, *proFile, *mult=0;
-+      unsigned long len=0, indx=1;
-+      unsigned long long add0=0;
-+      unsigned int step;
-+      unsigned int *buf, total, fn_len;
-+      unsigned long long fn_add, next_add;          /* current and next address */
-+      char fn_name[S_LEN], next_name[S_LEN];   /* current and next name */
-+      char mode[8];
-+      int c;
-+      int optAll=0, optInfo=0, optReset=0, optVerbose=0, optNative=0;
-+      int optBins=0, optSub=0;
-+      char mapline[S_LEN];
-+      int maplineno=1;
-+      int header_printed;
-+
-+#define next (current^1)
-+
-+      proFile = defaultpro;
-+      mapFile = defaultmap;
-+
-+      while ((c = getopt(argc, argv, "M:m:np:itvarVbs")) != -1) {
-+              switch(c) {
-+              case 'm':
-+                      mapFile = optarg;
-+                      break;
-+              case 'n':
-+                      optNative++;
-+                      break;
-+              case 'p':
-+                      proFile = optarg;
-+                      break;
-+              case 'a':
-+                      optAll++;
-+                      break;
-+              case 'b':
-+                      optBins++;
-+                      break;
-+              case 's':
-+                      optSub++;
-+                      break;
-+              case 'i':
-+                      optInfo++;
-+                      break;
-+              case 'M':
-+                      mult = optarg;
-+                      break;
-+              case 'r':
-+                      optReset++;
-+                      break;
-+              case 'v':
-+                      optVerbose++;
-+                      break;
-+              default:
-+                      bb_show_usage();
-+              }
-+      }
-+
-+      if (optReset || mult) {
-+              int multiplier, fd, to_write;
-+
-+              /*
-+               * When writing the multiplier, if the length of the write is
-+               * not sizeof(int), the multiplier is not changed
-+               */
-+              if (mult) {
-+                      multiplier = strtoul(mult, 0, 10);
-+                      to_write = sizeof(int);
-+              } else {
-+                      multiplier = 0;
-+                      to_write = 1;   /* sth different from sizeof(int) */
-+              }
-+
-+              fd = bb_xopen(defaultpro,O_WRONLY);
-+              if (fd < 0)
-+                      bb_perror_msg_and_die(defaultpro);
-+
-+              if (write(fd, &multiplier, to_write) != to_write)
-+                      bb_perror_msg_and_die("error writing %s", defaultpro);
-+
-+              close(fd);
-+              return EXIT_SUCCESS;
-+      }
-+
-+      /*
-+       * Use an fd for the profiling buffer, to skip stdio overhead
-+       */
-+      if (((proFd = bb_xopen(proFile,O_RDONLY)) < 0)
-+          || ((int)(len=lseek(proFd,0,SEEK_END)) < 0)
-+          || (lseek(proFd,0,SEEK_SET) < 0))
-+              bb_perror_msg_and_die(proFile);
-+
-+      if (!(buf = xmalloc(len)))
-+              bb_perror_nomsg_and_die();
-+
-+      if (read(proFd,buf,len) != len)
-+              bb_perror_msg_and_die(proFile);
-+
-+      close(proFd);
-+
-+      if (!optNative) {
-+              int entries = len/sizeof(*buf);
-+              int big = 0,small = 0,i;
-+              unsigned *p;
-+
-+              for (p = buf+1; p < buf+entries; p++) {
-+                      if (*p & ~0U << (sizeof(*buf)*4))
-+                              big++;
-+                      if (*p & ((1 << (sizeof(*buf)*4))-1))
-+                              small++;
-+              }
-+              if (big > small) {
-+                      fprintf(stderr,"Assuming reversed byte order. "
-+                              "Use -n to force native byte order.\n");
-+                      for (p = buf; p < buf+entries; p++)
-+                              for (i = 0; i < sizeof(*buf)/2; i++) {
-+                                      unsigned char *b = (unsigned char *) p;
-+                                      unsigned char tmp;
-+
-+                                      tmp = b[i];
-+                                      b[i] = b[sizeof(*buf)-i-1];
-+                                      b[sizeof(*buf)-i-1] = tmp;
-+                              }
-+              }
-+      }
-+
-+      step = buf[0];
-+      if (optInfo) {
-+              printf("Sampling_step: %i\n", step);
-+              return EXIT_SUCCESS;
-+      }
-+
-+      total = 0;
-+
-+      map = bb_xfopen(mapFile, "r");
-+      if (map == NULL)
-+              bb_perror_msg_and_die(mapFile);
-+
-+      while (fgets(mapline,S_LEN,map)) {
-+              if (sscanf(mapline,"%llx %s %s",&fn_add,mode,fn_name) != 3)
-+                      bb_error_msg_and_die("%s(%i): wrong map line",
-+                                           mapFile, maplineno);
-+
-+              if (!strcmp(fn_name,"_stext")) /* only elf works like this */ {
-+                      add0 = fn_add;
-+                      break;
-+              }
-+              maplineno++;
-+      }
-+
-+      if (!add0)
-+              bb_error_msg_and_die("can't find \"_stext\" in %s\n", mapFile);
-+
-+      /*
-+       * Main loop.
-+       */
-+      while (fgets(mapline,S_LEN,map)) {
-+              unsigned int this = 0;
-+
-+              if (sscanf(mapline,"%llx %s %s",&next_add,mode,next_name) != 3)
-+                      bb_error_msg_and_die("%s(%i): wrong map line\n",
-+                                           mapFile, maplineno);
-+
-+              header_printed = 0;
-+
-+              /* ignore any LEADING (before a '[tT]' symbol is found)
-+                 Absolute symbols */
-+              if ((*mode == 'A' || *mode == '?') && total == 0) continue;
-+              if (*mode != 'T' && *mode != 't' &&
-+                  *mode != 'W' && *mode != 'w')
-+                      break;  /* only text is profiled */
-+
-+              if (indx >= len / sizeof(*buf))
-+                      bb_error_msg_and_die("profile address out of range. "
-+                                           "Wrong map file?");
-+
-+              while (indx < (next_add-add0)/step) {
-+                      if (optBins && (buf[indx] || optAll)) {
-+                              if (!header_printed) {
-+                                      printf ("%s:\n", fn_name);
-+                                      header_printed = 1;
-+                              }
-+                              printf ("\t%llx\t%u\n", (indx - 1)*step + add0, buf[indx]);
-+                      }
-+                      this += buf[indx++];
-+              }
-+              total += this;
-+
-+              if (optBins) {
-+                      if (optVerbose || this > 0)
-+                              printf ("  total\t\t\t\t%u\n", this);
-+              } else if ((this || optAll) &&
-+                         (fn_len = next_add-fn_add) != 0) {
-+                      if (optVerbose)
-+                              printf("%016llx %-40s %6i %8.4f\n", fn_add,
-+                                     fn_name,this,this/(double)fn_len);
-+                      else
-+                              printf("%6i %-40s %8.4f\n",
-+                                     this,fn_name,this/(double)fn_len);
-+                      if (optSub) {
-+                              unsigned long long scan;
-+
-+                              for (scan = (fn_add-add0)/step + 1;
-+                                   scan < (next_add-add0)/step; scan++) {
-+                                      unsigned long long addr;
-+
-+                                      addr = (scan - 1)*step + add0;
-+                                      printf("\t%#llx\t%s+%#llx\t%u\n",
-+                                             addr, fn_name, addr - fn_add,
-+                                             buf[scan]);
-+                              }
-+                      }
-+              }
-+
-+              fn_add = next_add;
-+              strcpy(fn_name,next_name);
-+
-+              maplineno++;
-+      }
-+
-+      /* clock ticks, out of kernel text - probably modules */
-+      printf("%6i %s\n", buf[len/sizeof(*buf)-1], "*unknown*");
-+
-+      /* trailer */
-+      if (optVerbose)
-+              printf("%016x %-40s %6i %8.4f\n",
-+                     0,"total",total,total/(double)(fn_add-add0));
-+      else
-+              printf("%6i %-40s %8.4f\n",
-+                     total,"total",total/(double)(fn_add-add0));
-+
-+      fclose(map);
-+      free(buf);
-+
-+      return EXIT_SUCCESS;
-+}
This page took 1.730132 seconds and 4 git commands to generate.