+++ /dev/null
-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 <favorite feature> 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 <favorite feature>! Are the BusyBox developers willing to
- be paid in order to fix bugs or add in <favorite feature>? 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 < module name ></pre>
-- <dd>Will checkout the named module
-- <dt><pre>cvs co < module name ></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 < file name ></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 < file name ></pre>
--
-- <dd>Adds the named file/directory into CVS
-- <dt><pre>cvs remove < file name ></pre>
-- <dd>Removes the named file/directory from the upstream repository.
-- <dt><pre>cvs rm < file name ></pre>
-- <dd>Same thing
-- <dt><pre>cvs log < file name ></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 © 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 © 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 = ⁡
-+ } 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(¤t_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;
-+}