From e83a818003617a36bf1abe3ce862077e4fc79503 Mon Sep 17 00:00:00 2001 From: Xindong Xu Date: Wed, 24 May 2017 06:18:47 +0000 Subject: merge with busybox 1.26.2 Change-Id: I07e5a570500246f79180975fa02e2e084e1435b4 --- diff --git a/AUTHORS b/AUTHORS index 0908fc7..fa58697 100644 --- a/AUTHORS +++ b/AUTHORS @@ -146,6 +146,10 @@ Rob Sullivan Linus Torvalds mkswap, fsck.minix, mkfs.minix +Linus Walleij + fbset and fbsplash config RGBA parsing + rewrite of mdev helper to create devices from /sys/dev + Mark Whitley grep, sed, cut, xargs(previous), style-guide, new-applet-HOWTO, bug fixes, etc. diff --git a/Config.in b/Config.in index 2c4be2e..924a197 100644 --- a/Config.in +++ b/Config.in @@ -11,15 +11,18 @@ config HAVE_DOT_CONFIG menu "Busybox Settings" -menu "General Configuration" - config DESKTOP bool "Enable options for full-blown desktop systems" default y help Enable options and features which are not essential. - Select this only if you plan to use busybox on full-blown - desktop machine with common Linux distro, not on an embedded box. + Select this if you plan to use busybox on full-blown desktop machine + with common Linux distro, which needs higher level of command-line + compatibility. + + If you are preparing your build to be used on an embedded box + where you have tighter control over the entire set of userspace + tools, you can unselect this option for smaller code size. config EXTRA_COMPAT bool "Provide compatible behavior for rare corner cases (bigger code)" @@ -58,30 +61,6 @@ config PLATFORM_LINUX Answering 'N' here will disable such applets and hide the corresponding configuration options. -choice - prompt "Buffer allocation policy" - default FEATURE_BUFFERS_USE_MALLOC - help - There are 3 ways BusyBox can handle buffer allocations: - - Use malloc. This costs code size for the call to xmalloc. - - Put them on stack. For some very small machines with limited stack - space, this can be deadly. For most folks, this works just fine. - - Put them in BSS. This works beautifully for computers with a real - MMU (and OS support), but wastes runtime RAM for uCLinux. This - behavior was the only one available for BusyBox versions 0.48 and - earlier. - -config FEATURE_BUFFERS_USE_MALLOC - bool "Allocate with Malloc" - -config FEATURE_BUFFERS_GO_ON_STACK - bool "Allocate on the Stack" - -config FEATURE_BUFFERS_GO_IN_BSS - bool "Allocate in the .bss section" - -endchoice - config SHOW_USAGE bool "Show applet usage messages" default y @@ -116,9 +95,21 @@ config FEATURE_COMPRESS_USAGE and have very little memory, this might not be a win. Otherwise, you probably want this. +config BUSYBOX + bool "Include busybox applet" + default y + help + The busybox applet provides general help regarding busybox and + allows the included applets to be listed. It's also required + if applet links are to be installed at runtime. + + If you can live without these features disabling this will save + some space. + config FEATURE_INSTALLER bool "Support --install [-s] to install applet links at runtime" default y + depends on BUSYBOX help Enable 'busybox --install [-s]' support. This will allow you to use busybox at runtime to create hard links or symlinks for all the @@ -132,130 +123,12 @@ config INSTALL_NO_USR will install applets only to /bin and /sbin, never to /usr/bin or /usr/sbin. -config LOCALE_SUPPORT - bool "Enable locale support (system needs locale for this to work)" +config PAM + bool "Support for PAM (Pluggable Authentication Modules)" default n help - Enable this if your system has locale support and you would like - busybox to support locale settings. - -config UNICODE_SUPPORT - bool "Support Unicode" - default y - help - This makes various applets aware that one byte is not - one character on screen. - - Busybox aims to eventually work correctly with Unicode displays. - Any older encodings are not guaranteed to work. - Probably by the time when busybox will be fully Unicode-clean, - other encodings will be mainly of historic interest. - -config UNICODE_USING_LOCALE - bool "Use libc routines for Unicode (else uses internal ones)" - default n - depends on UNICODE_SUPPORT && LOCALE_SUPPORT - help - With this option on, Unicode support is implemented using libc - routines. Otherwise, internal implementation is used. - Internal implementation is smaller. - -config FEATURE_CHECK_UNICODE_IN_ENV - bool "Check $LC_ALL, $LC_CTYPE and $LANG environment variables" - default n - depends on UNICODE_SUPPORT && !UNICODE_USING_LOCALE - help - With this option on, Unicode support is activated - only if locale-related variables have the value of the form - "xxxx.utf8" - - Otherwise, Unicode support will be always enabled and active. - -config SUBST_WCHAR - int "Character code to substitute unprintable characters with" - depends on UNICODE_SUPPORT - default 63 - help - Typical values are 63 for '?' (works with any output device), - 30 for ASCII substitute control code, - 65533 (0xfffd) for Unicode replacement character. - -config LAST_SUPPORTED_WCHAR - int "Range of supported Unicode characters" - depends on UNICODE_SUPPORT - default 767 - help - Any character with Unicode value bigger than this is assumed - to be non-printable on output device. Many applets replace - such chars with substitution character. - - The idea is that many valid printable Unicode chars are - nevertheless are not displayed correctly. Think about - combining charachers, double-wide hieroglyphs, obscure - characters in dozens of ancient scripts... - Many terminals, terminal emulators, xterms etc will fail - to handle them correctly. Choose the smallest value - which suits your needs. - - Typical values are: - 126 - ASCII only - 767 (0x2ff) - there are no combining chars in [0..767] range - (the range includes Latin 1, Latin Ext. A and B), - code is ~700 bytes smaller for this case. - 4351 (0x10ff) - there are no double-wide chars in [0..4351] range, - code is ~300 bytes smaller for this case. - 12799 (0x31ff) - nearly all non-ideographic characters are - available in [0..12799] range, including - East Asian scripts like katakana, hiragana, hangul, - bopomofo... - 0 - off, any valid printable Unicode character will be printed. - -config UNICODE_COMBINING_WCHARS - bool "Allow zero-width Unicode characters on output" - default n - depends on UNICODE_SUPPORT - help - With this option off, any Unicode char with width of 0 - is substituted on output. - -config UNICODE_WIDE_WCHARS - bool "Allow wide Unicode characters on output" - default n - depends on UNICODE_SUPPORT - help - With this option off, any Unicode char with width > 1 - is substituted on output. - -config UNICODE_BIDI_SUPPORT - bool "Bidirectional character-aware line input" - default n - depends on UNICODE_SUPPORT && !UNICODE_USING_LOCALE - help - With this option on, right-to-left Unicode characters - are treated differently on input (e.g. cursor movement). - -config UNICODE_NEUTRAL_TABLE - bool "In bidi input, support non-ASCII neutral chars too" - default n - depends on UNICODE_BIDI_SUPPORT - help - In most cases it's enough to treat only ASCII non-letters - (i.e. punctuation, numbers and space) as characters - with neutral directionality. - With this option on, more extensive (and bigger) table - of neutral chars will be used. - -config UNICODE_PRESERVE_BROKEN - bool "Make it possible to enter sequences of chars which are not Unicode" - default n - depends on UNICODE_SUPPORT - help - With this option on, on line-editing input (such as used by shells) - invalid UTF-8 bytes are not substituted with the selected - substitution character. - For example, this means that entering 'l', 's', ' ', 0xff, [Enter] - at shell prompt will list file named 0xff (single char name - with char value 255), not file named '?'. + Use PAM in some busybox applets (currently login and httpd) instead + of direct access to password database. config LONG_OPTS bool "Support for --long-options" @@ -416,10 +289,7 @@ config SELINUX the option of compiling in SELinux applets. If you do not have a complete SELinux userland installed, this stuff - will not compile. Go visit - http://www.nsa.gov/selinux/index.html - to download the necessary stuff to allow busybox to compile with - this option enabled. Specifially, libselinux 1.28 or better is + will not compile. Specifially, libselinux 1.28 or better is directly required by busybox. If the installation is located in a non-standard directory, provide it by invoking make as follows: CFLAGS=-I \ @@ -468,9 +338,7 @@ config FEATURE_HAVE_RPC # This is automatically selected if any of enabled applets need it. # You do not need to select it manually. -endmenu - -menu 'Build Options' +comment 'Build Options' config STATIC bool "Build BusyBox as a static binary (no shared libs)" @@ -645,9 +513,73 @@ config EXTRA_LDLIBS help Additional LDLIBS to pass to the linker with -l. -endmenu +comment 'Installation Options ("make install" behavior)' + +choice + prompt "What kind of applet links to install" + default INSTALL_APPLET_SYMLINKS + help + Choose what kind of links to applets are created by "make install". + +config INSTALL_APPLET_SYMLINKS + bool "as soft-links" + help + Install applets as soft-links to the busybox binary. This needs some + free inodes on the filesystem, but might help with filesystem + generators that can't cope with hard-links. + +config INSTALL_APPLET_HARDLINKS + bool "as hard-links" + help + Install applets as hard-links to the busybox binary. This might + count on a filesystem with few inodes. + +config INSTALL_APPLET_SCRIPT_WRAPPERS + bool "as script wrappers" + help + Install applets as script wrappers that call the busybox binary. + +config INSTALL_APPLET_DONT + bool "not installed" + help + Do not install applet links. Useful when you plan to use + busybox --install for installing links, or plan to use + a standalone shell and thus don't need applet links. + +endchoice + +choice + prompt "/bin/sh applet link" + default INSTALL_SH_APPLET_SYMLINK + depends on INSTALL_APPLET_SCRIPT_WRAPPERS + help + Choose how you install /bin/sh applet link. + +config INSTALL_SH_APPLET_SYMLINK + bool "as soft-link" + help + Install /bin/sh applet as soft-link to the busybox binary. + +config INSTALL_SH_APPLET_HARDLINK + bool "as hard-link" + help + Install /bin/sh applet as hard-link to the busybox binary. -menu 'Debugging Options' +config INSTALL_SH_APPLET_SCRIPT_WRAPPER + bool "as script wrapper" + help + Install /bin/sh applet as script wrapper that calls + the busybox binary. + +endchoice + +config PREFIX + string "BusyBox installation prefix" + default "./_install" + help + Define your directory to install BusyBox files/subdirs in. + +comment 'Debugging Options' config DEBUG bool "Build BusyBox with extra Debugging symbols" @@ -671,6 +603,24 @@ config DEBUG_PESSIMIZE in a much bigger executable that more closely matches the source code. +config DEBUG_SANITIZE + bool "Enable runtime sanitizers (ASAN/LSAN/USAN/etc...)" + default n + help + Say Y here if you want to enable runtime sanitizers. These help + catch bad memory accesses (e.g. buffer overflows), but will make + the executable larger and slow down runtime a bit. + + If you aren't developing/testing busybox, say N here. + +config UNIT_TEST + bool "Build unit tests" + default n + help + Say Y here if you want to build unit tests (both the framework and + test cases) as a Busybox applet. This results in bigger code, so you + probably don't want this option in production builds. + config WERROR bool "Abort compilation on any warning" default n @@ -723,78 +673,8 @@ endchoice endmenu -menu 'Installation Options ("make install" behavior)' - -choice - prompt "What kind of applet links to install" - default INSTALL_APPLET_SYMLINKS - help - Choose what kind of links to applets are created by "make install". - -config INSTALL_APPLET_SYMLINKS - bool "as soft-links" - help - Install applets as soft-links to the busybox binary. This needs some - free inodes on the filesystem, but might help with filesystem - generators that can't cope with hard-links. - -config INSTALL_APPLET_HARDLINKS - bool "as hard-links" - help - Install applets as hard-links to the busybox binary. This might - count on a filesystem with few inodes. - -config INSTALL_APPLET_SCRIPT_WRAPPERS - bool "as script wrappers" - help - Install applets as script wrappers that call the busybox binary. - -config INSTALL_APPLET_DONT - bool "not installed" - help - Do not install applet links. Useful when you plan to use - busybox --install for installing links, or plan to use - a standalone shell and thus don't need applet links. - -endchoice - -choice - prompt "/bin/sh applet link" - default INSTALL_SH_APPLET_SYMLINK - depends on INSTALL_APPLET_SCRIPT_WRAPPERS - help - Choose how you install /bin/sh applet link. - -config INSTALL_SH_APPLET_SYMLINK - bool "as soft-link" - help - Install /bin/sh applet as soft-link to the busybox binary. - -config INSTALL_SH_APPLET_HARDLINK - bool "as hard-link" - help - Install /bin/sh applet as hard-link to the busybox binary. - -config INSTALL_SH_APPLET_SCRIPT_WRAPPER - bool "as script wrapper" - help - Install /bin/sh applet as script wrapper that calls - the busybox binary. - -endchoice - -config PREFIX - string "BusyBox installation prefix" - default "./_install" - help - Define your directory to install BusyBox files/subdirs in. - -endmenu - source libbb/Config.in -endmenu - comment "Applets" source archival/Config.in diff --git a/Makefile b/Makefile index 111adc0..971e68e 100644 --- a/Makefile +++ b/Makefile @@ -1,14 +1,8 @@ VERSION = 1 -PATCHLEVEL = 22 -SUBLEVEL = 1 +PATCHLEVEL = 26 +SUBLEVEL = 2 EXTRAVERSION = -NAME = bionic - -# prevent local tree builds in bionic, -# but allow initial version check (SUBMAKE) -ifeq (,$(filter s, $(MAKEFLAGS))) - KBUILD_OUTPUT ?= $(OUT)/obj/busybox -endif +NAME = Unnamed # *DOCUMENTATION* # To see a list of typical targets execute "make help" @@ -110,8 +104,7 @@ ifneq ($(KBUILD_OUTPUT),) saved-output := $(KBUILD_OUTPUT) KBUILD_OUTPUT := $(shell cd $(KBUILD_OUTPUT) && /bin/pwd) $(if $(KBUILD_OUTPUT),, \ - $(warning output directory "$(saved-output)" does not exist) \ - $(error On AOSP repo, type 'mma' to build or set O=out/ )) + $(error output directory "$(saved-output)" does not exist)) PHONY += $(MAKECMDGOALS) @@ -559,7 +552,7 @@ export INSTALL_PATH ?= /boot # # INSTALL_MOD_PATH specifies a prefix to MODLIB for module directory # relocations required by build roots. This is not defined in the -# makefile but the arguement can be passed to make if needed. +# makefile but the argument can be passed to make if needed. # MODLIB = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) @@ -617,7 +610,8 @@ quiet_cmd_busybox__ ?= LINK $@ "$(LDFLAGS) $(EXTRA_LDFLAGS)" \ "$(core-y)" \ "$(libs-y)" \ - "$(LDLIBS)" + "$(LDLIBS)" \ + && $(srctree)/scripts/generate_BUFSIZ.sh --post include/common_bufsiz.h # Generate System.map quiet_cmd_sysmap = SYSMAP @@ -851,12 +845,15 @@ export CPPFLAGS_busybox.lds += -P -C -U$(ARCH) # Split autoconf.h into include/linux/config/* quiet_cmd_gen_bbconfigopts = GEN include/bbconfigopts.h cmd_gen_bbconfigopts = $(srctree)/scripts/mkconfigs include/bbconfigopts.h include/bbconfigopts_bz2.h +quiet_cmd_gen_common_bufsiz = GEN include/common_bufsiz.h + cmd_gen_common_bufsiz = $(srctree)/scripts/generate_BUFSIZ.sh include/common_bufsiz.h quiet_cmd_split_autoconf = SPLIT include/autoconf.h -> include/config/* cmd_split_autoconf = scripts/basic/split-include include/autoconf.h include/config #bbox# piggybacked generation of few .h files include/config/MARKER: scripts/basic/split-include include/autoconf.h $(call cmd,split_autoconf) $(call cmd,gen_bbconfigopts) + $(call cmd,gen_common_bufsiz) @touch $@ # Generate some files @@ -972,6 +969,7 @@ CLEAN_FILES += busybox busybox_unstripped* busybox.links \ MRPROPER_DIRS += include/config include2 MRPROPER_FILES += .config .config.old include/asm .version .old_version \ include/NUM_APPLETS.h \ + include/common_bufsiz.h \ include/autoconf.h \ include/bbconfigopts.h \ include/bbconfigopts_bz2.h \ @@ -983,9 +981,6 @@ MRPROPER_FILES += .config .config.old include/asm .version .old_version \ .kernelrelease Module.symvers tags TAGS cscope* \ busybox_old -MRPROPER_FILES += include-full/*.h \ - include-minimal/*.h - # clean - Delete most, but leave enough to build external modules # clean: rm-dirs := $(CLEAN_DIRS) @@ -1175,24 +1170,7 @@ endif ALLSOURCE_ARCHS := $(ARCH) define all-sources - ( find $(__srctree) $(RCS_FIND_IGNORE) \ - \( -name include -o -name arch \) -prune -o \ - -name '*.[chS]' -print; \ - for ARCH in $(ALLSOURCE_ARCHS) ; do \ - find $(__srctree)arch/$${ARCH} $(RCS_FIND_IGNORE) \ - -name '*.[chS]' -print; \ - done ; \ - find $(__srctree)security/selinux/include $(RCS_FIND_IGNORE) \ - -name '*.[chS]' -print; \ - find $(__srctree)include $(RCS_FIND_IGNORE) \ - \( -name config -o -name 'asm-*' \) -prune \ - -o -name '*.[chS]' -print; \ - for ARCH in $(ALLINCLUDE_ARCHS) ; do \ - find $(__srctree)include/asm-$${ARCH} $(RCS_FIND_IGNORE) \ - -name '*.[chS]' -print; \ - done ; \ - find $(__srctree)include/asm-generic $(RCS_FIND_IGNORE) \ - -name '*.[chS]' -print ) + ( find -regex '.*\.[ch]$$' ) endef quiet_cmd_cscope-file = FILELST cscope.files @@ -1345,11 +1323,6 @@ endif # skip-makefile PHONY += FORCE FORCE: -show-sources: - @for f in $(busybox-dirs) ; do \ - $(MAKE) $(build)=$$f show-src ; \ - done - -include $(srctree)/Makefile.custom # Declare the contents of the .PHONY variable as phony. We keep that diff --git a/Makefile.custom b/Makefile.custom index 8c95ef2..891c9ce 100644 --- a/Makefile.custom +++ b/Makefile.custom @@ -28,6 +28,10 @@ ifeq ($(CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER),y) INSTALL_OPTS:= --scriptwrapper endif endif +ifeq ($(CONFIG_FEATURE_INDIVIDUAL),y) +INSTALL_OPTS:= --binaries +LIBBUSYBOX_SONAME:= 0_lib/libbusybox.so.$(BB_VER) +endif install: $(srctree)/applets/install.sh busybox busybox.links $(Q)DO_INSTALL_LIBS="$(strip $(LIBBUSYBOX_SONAME) $(DO_INSTALL_LIBS))" \ $(SHELL) $< $(CONFIG_PREFIX) $(INSTALL_OPTS) @@ -55,7 +59,11 @@ endif # (cp -pPR is POSIX-compliant (cp -dpR or cp -a would not be)) .PHONY: check .PHONY: test +ifeq ($(CONFIG_UNIT_TEST),y) +UNIT_CMD = ./busybox unit +endif check test: busybox busybox.links + $(UNIT_CMD) test -d $(objtree)/testsuite || cp -pPR $(srctree)/testsuite $(objtree) bindir=$(objtree) srcdir=$(srctree)/testsuite \ $(SHELL) -c "cd $(objtree)/testsuite && $(srctree)/testsuite/runtest $(if $(KBUILD_VERBOSE:0=),-v)" diff --git a/Makefile.flags b/Makefile.flags index 640eeec..89d599c 100644 --- a/Makefile.flags +++ b/Makefile.flags @@ -56,6 +56,9 @@ CFLAGS += $(call cc-option,-falign-functions=1 -falign-jumps=1 -falign-labels=1 # Defeat .eh_frame bloat (gcc 4.6.3 x86-32 defconfig: 20% smaller busybox binary): CFLAGS += $(call cc-option,-fno-unwind-tables,) CFLAGS += $(call cc-option,-fno-asynchronous-unwind-tables,) +# No automatic printf->puts,putchar conversions +# (try disabling this and comparing assembly, it's instructive) +CFLAGS += $(call cc-option,-fno-builtin-printf,) # FIXME: These warnings are at least partially to be concerned about and should # be fixed.. @@ -72,6 +75,11 @@ else CFLAGS += $(call cc-option,-Os,$(call cc-option,-O2,)) endif endif +ifeq ($(CONFIG_DEBUG_SANITIZE),y) +CFLAGS += $(call cc-option,-fsanitize=address,) +CFLAGS += $(call cc-option,-fsanitize=leak,) +CFLAGS += $(call cc-option,-fsanitize=undefined,) +endif # If arch/$(ARCH)/Makefile did not override it (with, say, -fPIC)... ARCH_FPIC ?= -fpic @@ -126,15 +134,19 @@ else LDLIBS += m endif +# libpam may use libpthread, libdl and/or libaudit. +# On some platforms that requires an explicit -lpthread, -ldl, -laudit. +# However, on *other platforms* it fails when some of those flags +# given needlessly. On some systems, crypt needs pthread. +# +# I even had a system where a runtime test for pthread +# (similar to CRYPT_AVAILABLE test above) was not reliable. +# +# Do not propagate this mess by adding libraries to CONFIG_PAM/CRYPT_AVAILABLE blocks. +# Add libraries you need to CONFIG_EXTRA_LDLIBS instead. + ifeq ($(CONFIG_PAM),y) -# libpam uses libpthread, so for static builds busybox must be linked to -# libpthread. On some platforms that requires an explicit -lpthread, so -# it should be in LDLIBS. For non-static builds, scripts/trylink will -# take care of removing -lpthread if possible. (Not bothering to check -# CONFIG_STATIC because even in a non-static build it could be that the -# only libpam available is libpam.a, so -lpthread could still be -# needed.) -LDLIBS += pam pam_misc pthread +LDLIBS += pam pam_misc endif ifeq ($(CONFIG_SELINUX),y) @@ -165,7 +177,7 @@ SKIP_STRIP = y endif ifneq ($(CONFIG_EXTRA_LDFLAGS),) -EXTRA_LDFLAGS += $(strip $(subst ",,$(CONFIG_EXTRA_LDFLAGS))) +LDFLAGS += $(strip $(subst ",,$(CONFIG_EXTRA_LDFLAGS))) #")) endif diff --git a/Makefile.help b/Makefile.help index 119dd6f..6a23e2a 100644 --- a/Makefile.help +++ b/Makefile.help @@ -21,10 +21,6 @@ help: @echo ' defconfig - set .config to largest generic configuration' @echo ' menuconfig - interactive curses-based configurator' @echo ' oldconfig - resolve any unresolved symbols in .config' - @echo ' hosttools - build sed for the host.' - @echo ' You can use these commands if the commands on the host' - @echo ' is unusable. Afterwards use it like:' - @echo ' make SED="$(objtree)/sed"' @$(if $(boards), \ $(foreach b, $(boards), \ printf " %-21s - Build for %s\\n" $(b) $(subst _defconfig,,$(b));) \ diff --git a/README b/README index 4814372..ebdda73 100644 --- a/README +++ b/README @@ -211,7 +211,7 @@ Supported hardware: Under 2.4 Linux kernels, kernel module loading was implemented in a platform-specific manner. Busybox's insmod utility has been reported to work under ARM, CRIS, H8/300, x86, ia64, x86_64, m68k, MIPS, PowerPC, S390, - SH3/4/5, Sparc, v850e, and x86_64. Anything else probably won't work. + SH3/4/5, Sparc, and v850e. Anything else probably won't work. The module loading mechanism for the 2.6 kernel is much more generic, and we believe 2.6.x kernel module loading support should work on all diff --git a/TODO b/TODO index dcf48c2..8904b21 100644 --- a/TODO +++ b/TODO @@ -258,5 +258,3 @@ vdprintf() -> similar sized functionality * more support for advanced linux 2.6.x features, see: iotop most likely there is more - -* even more support for statistics: mpstat, iostat, powertop.... diff --git a/android/librpc/libintl.h b/android/librpc/libintl.h deleted file mode 100644 index e69de29..0000000 --- a/android/librpc/libintl.h +++ b/dev/null diff --git a/applets/Kbuild.src b/applets/Kbuild.src index b612399..3aedbbf 100644 --- a/applets/Kbuild.src +++ b/applets/Kbuild.src @@ -29,7 +29,7 @@ applets/applets.o: include/usage_compressed.h include/applet_tables.h applets/applet_tables: .config include/applets.h applets/usage: .config include/applets.h -applets/usage_pod: .config include/applet_tables.h include/applets.h +applets/usage_pod: .config include/applets.h include/applet_tables.h quiet_cmd_gen_usage_compressed = GEN include/usage_compressed.h cmd_gen_usage_compressed = $(srctree_slash)applets/usage_compressed include/usage_compressed.h applets @@ -37,11 +37,21 @@ quiet_cmd_gen_usage_compressed = GEN include/usage_compressed.h include/usage_compressed.h: applets/usage $(srctree_slash)applets/usage_compressed $(call cmd,gen_usage_compressed) -quiet_cmd_gen_applet_tables = GEN include/applet_tables.h +quiet_cmd_gen_applet_tables = GEN include/applet_tables.h include/NUM_APPLETS.h cmd_gen_applet_tables = applets/applet_tables include/applet_tables.h include/NUM_APPLETS.h -include/applet_tables.h: applets/applet_tables +include/NUM_APPLETS.h: applets/applet_tables $(call cmd,gen_applet_tables) -include/NUM_APPLETS.h: applets/applet_tables +# In fact, include/applet_tables.h depends only on applets/applet_tables, +# and is generated by it. But specifying only it can run +# applets/applet_tables twice, possibly in parallel. +# We say that it also needs NUM_APPLETS.h +# +# Unfortunately, we need to list the same command, +# and it can be executed twice (sequentially). +# The alternative is to not list any command, +# and then if include/applet_tables.h is deleted, it won't be rebuilt. +# +include/applet_tables.h: include/NUM_APPLETS.h applets/applet_tables $(call cmd,gen_applet_tables) diff --git a/applets/applet_tables.c b/applets/applet_tables.c index 94b974e..ef911a4 100644 --- a/applets/applet_tables.c +++ b/applets/applet_tables.c @@ -14,6 +14,7 @@ #include #include #include +#include #undef ARRAY_SIZE #define ARRAY_SIZE(x) ((unsigned)(sizeof(x) / sizeof((x)[0]))) @@ -40,8 +41,6 @@ struct bb_applet { enum { NUM_APPLETS = ARRAY_SIZE(applets) }; -static int offset[NUM_APPLETS]; - static int cmp_name(const void *a, const void *b) { const struct bb_applet *aa = a; @@ -49,26 +48,42 @@ static int cmp_name(const void *a, const void *b) return strcmp(aa->name, bb->name); } +static int str_isalnum_(const char *s) +{ + while (*s) { + if (!isalnum(*s) && *s != '_') + return 0; + s++; + } + return 1; +} + int main(int argc, char **argv) { - int i; - int ofs; -// unsigned MAX_APPLET_NAME_LEN = 1; + int i, j; + + // In find_applet_by_name(), before linear search, narrow it down + // by looking at N "equidistant" names. With ~350 applets: + // KNOWN_APPNAME_OFFSETS cycles + // 0 9057 + // 2 4604 + ~100 bytes of code + // 4 2407 + 4 bytes + // 8 1342 + 8 bytes + // 16 908 + 16 bytes + // 32 884 + 32 bytes + // With 8, int16_t applet_nameofs[] table has 7 elements. + int KNOWN_APPNAME_OFFSETS = 8; + // With 128 applets we do two linear searches, with 1..7 strcmp's in the first one + // and 1..16 strcmp's in the second. With 256 apps, second search does 1..32 strcmp's. + if (NUM_APPLETS < 128) + KNOWN_APPNAME_OFFSETS = 4; + if (NUM_APPLETS < 32) + KNOWN_APPNAME_OFFSETS = 0; qsort(applets, NUM_APPLETS, sizeof(applets[0]), cmp_name); - ofs = 0; - for (i = 0; i < NUM_APPLETS; i++) { - offset[i] = ofs; - ofs += strlen(applets[i].name) + 1; - } - /* We reuse 4 high-order bits of offset array for other purposes, - * so if they are indeed needed, refuse to proceed */ - if (ofs > 0xfff) - return 1; if (!argv[1]) return 1; - i = open(argv[1], O_WRONLY | O_TRUNC | O_CREAT, 0666); if (i < 0) return 1; @@ -83,7 +98,27 @@ int main(int argc, char **argv) printf("#define SINGLE_APPLET_STR \"%s\"\n", applets[0].name); printf("#define SINGLE_APPLET_MAIN %s_main\n", applets[0].main); } - printf("\n"); + + printf("#define KNOWN_APPNAME_OFFSETS %u\n\n", KNOWN_APPNAME_OFFSETS); + if (KNOWN_APPNAME_OFFSETS > 0) { + int ofs, offset[KNOWN_APPNAME_OFFSETS], index[KNOWN_APPNAME_OFFSETS]; + for (i = 0; i < KNOWN_APPNAME_OFFSETS; i++) + index[i] = i * NUM_APPLETS / KNOWN_APPNAME_OFFSETS; + ofs = 0; + for (i = 0; i < NUM_APPLETS; i++) { + for (j = 0; j < KNOWN_APPNAME_OFFSETS; j++) + if (i == index[j]) + offset[j] = ofs; + ofs += strlen(applets[i].name) + 1; + } + /* If the list of names is too long refuse to proceed */ + if (ofs > 0xffff) + return 1; + printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); + for (i = 1; i < KNOWN_APPNAME_OFFSETS; i++) + printf("%d,\n", offset[i]); + printf("};\n\n"); + } //printf("#ifndef SKIP_definitions\n"); printf("const char applet_names[] ALIGN1 = \"\"\n"); @@ -94,6 +129,12 @@ int main(int argc, char **argv) } printf(";\n\n"); + for (i = 0; i < NUM_APPLETS; i++) { + if (str_isalnum_(applets[i].name)) + printf("#define APPLET_NO_%s %d\n", applets[i].name, i); + } + printf("\n"); + printf("#ifndef SKIP_applet_main\n"); printf("int (*const applet_main[])(int argc, char **argv) = {\n"); for (i = 0; i < NUM_APPLETS; i++) { @@ -102,20 +143,41 @@ int main(int argc, char **argv) printf("};\n"); printf("#endif\n\n"); - printf("const uint16_t applet_nameofs[] ALIGN2 = {\n"); - for (i = 0; i < NUM_APPLETS; i++) { - printf("0x%04x,\n", - offset[i] -#if ENABLE_FEATURE_PREFER_APPLETS - + (applets[i].nofork << 12) - + (applets[i].noexec << 13) +#if ENABLE_FEATURE_PREFER_APPLETS \ + || ENABLE_FEATURE_SH_STANDALONE \ + || ENABLE_FEATURE_SH_NOFORK + printf("const uint8_t applet_flags[] ALIGN1 = {\n"); + i = 0; + while (i < NUM_APPLETS) { + int v = applets[i].nofork + (applets[i].noexec << 1); + if (++i < NUM_APPLETS) + v |= (applets[i].nofork + (applets[i].noexec << 1)) << 2; + if (++i < NUM_APPLETS) + v |= (applets[i].nofork + (applets[i].noexec << 1)) << 4; + if (++i < NUM_APPLETS) + v |= (applets[i].nofork + (applets[i].noexec << 1)) << 6; + printf("0x%02x,\n", v); + i++; + } + printf("};\n\n"); #endif + #if ENABLE_FEATURE_SUID - + (applets[i].need_suid << 14) /* 2 bits */ -#endif - ); + printf("const uint8_t applet_suid[] ALIGN1 = {\n"); + i = 0; + while (i < NUM_APPLETS) { + int v = applets[i].need_suid; /* 2 bits */ + if (++i < NUM_APPLETS) + v |= applets[i].need_suid << 2; + if (++i < NUM_APPLETS) + v |= applets[i].need_suid << 4; + if (++i < NUM_APPLETS) + v |= applets[i].need_suid << 6; + printf("0x%02x,\n", v); + i++; } printf("};\n\n"); +#endif #if ENABLE_FEATURE_INSTALLER printf("const uint8_t applet_install_loc[] ALIGN1 = {\n"); @@ -130,27 +192,28 @@ int main(int argc, char **argv) printf("};\n"); #endif //printf("#endif /* SKIP_definitions */\n"); + // printf("\n"); // printf("#define MAX_APPLET_NAME_LEN %u\n", MAX_APPLET_NAME_LEN); if (argv[2]) { - char line_old[80]; - char line_new[80]; FILE *fp; + char line_new[80]; +// char line_old[80]; - line_old[0] = 0; - fp = fopen(argv[2], "r"); - if (fp) { - fgets(line_old, sizeof(line_old), fp); - fclose(fp); - } sprintf(line_new, "#define NUM_APPLETS %u\n", NUM_APPLETS); - if (strcmp(line_old, line_new) != 0) { +// line_old[0] = 0; +// fp = fopen(argv[2], "r"); +// if (fp) { +// fgets(line_old, sizeof(line_old), fp); +// fclose(fp); +// } +// if (strcmp(line_old, line_new) != 0) { fp = fopen(argv[2], "w"); if (!fp) return 1; fputs(line_new, fp); - } +// } } return 0; diff --git a/applets/install.sh b/applets/install.sh index 95b4719..f6c097e 100755 --- a/applets/install.sh +++ b/applets/install.sh @@ -5,19 +5,26 @@ export LC_CTYPE=POSIX prefix=$1 if [ -z "$prefix" ]; then - echo "usage: applets/install.sh DESTINATION [--symlinks/--hardlinks/--scriptwrapper]" + echo "usage: applets/install.sh DESTINATION [--symlinks/--hardlinks/--binaries/--scriptwrapper]" exit 1 fi +# Source the configuration +. ./.config + h=`sort busybox.links | uniq` +sharedlib_dir="0_lib" + linkopts="" scriptwrapper="n" +binaries="n" cleanup="0" noclobber="0" case "$2" in --hardlinks) linkopts="-f";; --symlinks) linkopts="-fs";; + --binaries) binaries="y";; --scriptwrapper) scriptwrapper="y";swrapall="y";; --sw-sh-hard) scriptwrapper="y";linkopts="-f";; --sw-sh-sym) scriptwrapper="y";linkopts="-fs";; @@ -40,8 +47,9 @@ if [ -n "$DO_INSTALL_LIBS" ] && [ "$DO_INSTALL_LIBS" != "n" ]; then for i in $DO_INSTALL_LIBS; do rm -f "$prefix/$libdir/$i" || exit 1 if [ -f "$i" ]; then + echo " Installing $i to the target at $prefix/$libdir/" cp -pPR "$i" "$prefix/$libdir/" || exit 1 - chmod 0644 "$prefix/$libdir/$i" || exit 1 + chmod 0644 "$prefix/$libdir/`basename $i`" || exit 1 fi done fi @@ -68,6 +76,7 @@ install -m 755 busybox "$prefix/bin/busybox" || exit 1 for i in $h; do appdir=`dirname "$i"` + app=`basename "$i"` mkdir -p "$prefix/$appdir" || exit 1 if [ "$scriptwrapper" = "y" ]; then if [ "$swrapall" != "y" ] && [ "$i" = "/bin/sh" ]; then @@ -78,6 +87,19 @@ for i in $h; do chmod +x "$prefix/$i" fi echo " $prefix/$i" + elif [ "$binaries" = "y" ]; then + # Copy the binary over rather + if [ -e $sharedlib_dir/$app ]; then + if [ "$noclobber" = "0" ] || [ ! -e "$prefix/$i" ]; then + echo " Copying $sharedlib_dir/$app to $prefix/$i" + cp -pPR $sharedlib_dir/$app $prefix/$i || exit 1 + else + echo " $prefix/$i already exists" + fi + else + echo "Error: Could not find $sharedlib_dir/$app" + exit 1 + fi else if [ "$2" = "--hardlinks" ]; then bb_path="$prefix/bin/busybox" diff --git a/applets/usage_compressed b/applets/usage_compressed index fb6e1c2..186fcde 100755 --- a/applets/usage_compressed +++ b/applets/usage_compressed @@ -20,6 +20,7 @@ exec >"$target.$$" echo '#define UNPACKED_USAGE "" \' "$loc/usage" | od -v -b \ +| grep -v '^ ' \ | $SED -e 's/^[^ ]*//' \ -e 's/ //g' \ -e '/^$/d' \ @@ -27,6 +28,13 @@ echo '#define UNPACKED_USAGE "" \' -e 's/^/"/' \ -e 's/$/" \\/' echo '' +# "grep -v '^ '" is for toybox's od bug: od -b prints some extra lines: +#0000000 010 000 010 000 133 055 144 146 135 040 133 055 143 040 103 117 +# 000010 000010 026533 063144 020135 026533 020143 047503 +#0000020 116 106 104 111 122 135 040 133 055 154 040 114 117 107 106 111 +# 043116 044504 056522 055440 066055 046040 043517 044506 +#0000040 114 105 135 040 133 055 141 040 101 103 124 111 117 116 106 111 +# 042514 020135 026533 020141 041501 044524 047117 044506 echo '#define PACKED_USAGE \' ## Breaks on big-endian systems! @@ -40,6 +48,7 @@ echo '#define PACKED_USAGE \' ## -e 's/\(..\)\(..\)/0x\2,0x\1,/g' ## -e 's/$/ \\/' "$loc/usage" | bzip2 -1 | $DD bs=2 skip=1 2>/dev/null | od -v -b \ +| grep -v '^ ' \ | $SED -e 's/^[^ ]*//' \ -e 's/ //g' \ -e '/^$/d' \ diff --git a/applets/usage_pod.c b/applets/usage_pod.c index a67e8b4..9e6d3f0 100644 --- a/applets/usage_pod.c +++ b/applets/usage_pod.c @@ -90,6 +90,8 @@ int main(void) printf("%s\n\n", usage_array[i].aname); } } + printf("=back\n\n"); + return 0; } diff --git a/archival/Config.src b/archival/Config.src index 76635ba..5e7cfc0 100644 --- a/archival/Config.src +++ b/archival/Config.src @@ -30,8 +30,8 @@ config FEATURE_SEAMLESS_GZ Make tar, rpm, modprobe etc understand .gz data. config FEATURE_SEAMLESS_Z - bool "tar, rpm, modprobe etc understand .Z data" - default n + bool "Make tar, rpm, modprobe etc understand .Z data" + default n # it is ancient help Make tar, rpm, modprobe etc understand .Z data. diff --git a/archival/Kbuild.src b/archival/Kbuild.src index a6fd2ea..b3a7d53 100644 --- a/archival/Kbuild.src +++ b/archival/Kbuild.src @@ -4,7 +4,7 @@ # # Licensed under GPLv2, see file LICENSE in this source tree. -libs-y += libarchive/ +libs-y += libarchive/ lib-y:= diff --git a/archival/ar.c b/archival/ar.c index f86c52d..e49d5cb 100644 --- a/archival/ar.c +++ b/archival/ar.c @@ -22,23 +22,13 @@ //config: default n # needs to be improved to be able to replace binutils ar //config: help //config: ar is an archival utility program used to create, modify, and -//config: extract contents from archives. An archive is a single file holding -//config: a collection of other files in a structure that makes it possible to -//config: retrieve the original individual files (called archive members). -//config: The original files' contents, mode (permissions), timestamp, owner, -//config: and group are preserved in the archive, and can be restored on -//config: extraction. +//config: extract contents from archives. In practice, it is used exclusively +//config: for object module archives used by compilers. //config: -//config: The stored filename is limited to 15 characters. (for more information -//config: see long filename support). -//config: ar has 60 bytes of overheads for every stored file. -//config: -//config: This implementation of ar can extract archives, it cannot create or -//config: modify them. //config: On an x86 system, the ar applet adds about 1K. //config: //config: Unless you have a specific application which requires ar, you should -//config: probably say N here. +//config: probably say N here: most compilers come with their own ar utility. //config: //config:config FEATURE_AR_LONG_FILENAMES //config: bool "Support for long filenames (not needed for debs)" diff --git a/archival/bbunzip.c b/archival/bbunzip.c index fce5ab9..60a837e 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c @@ -9,6 +9,12 @@ /* lzop_main() uses bbunpack(), need this: */ //kbuild:lib-$(CONFIG_LZOP) += bbunzip.o +//kbuild:lib-$(CONFIG_LZOPCAT) += bbunzip.o +//kbuild:lib-$(CONFIG_UNLZOP) += bbunzip.o +/* bzip2_main() too: */ +//kbuild:lib-$(CONFIG_BZIP2) += bbunzip.o +/* gzip_main() too: */ +//kbuild:lib-$(CONFIG_GZIP) += bbunzip.o /* Note: must be kept in sync with archival/lzop.c */ enum { @@ -39,7 +45,7 @@ char* FAST_FUNC append_ext(char *filename, const char *expected_ext) } int FAST_FUNC bbunpack(char **argv, - IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_aux_data_t *aux), + IF_DESKTOP(long long) int FAST_FUNC (*unpacker)(transformer_state_t *xstate), char* FAST_FUNC (*make_new_name)(char *filename, const char *expected_ext), const char *expected_ext ) @@ -48,7 +54,7 @@ int FAST_FUNC bbunpack(char **argv, IF_DESKTOP(long long) int status = 0; char *filename, *new_name; smallint exitcode = 0; - transformer_aux_data_t aux; + transformer_state_t xstate; do { /* NB: new_name is *maybe* malloc'ed! */ @@ -120,9 +126,11 @@ int FAST_FUNC bbunpack(char **argv, } if (!(option_mask32 & SEAMLESS_MAGIC)) { - init_transformer_aux_data(&aux); - aux.check_signature = 1; - status = unpacker(&aux); + init_transformer_state(&xstate); + xstate.signature_skipped = 0; + /*xstate.src_fd = STDIN_FILENO; - already is */ + xstate.dst_fd = STDOUT_FILENO; + status = unpacker(&xstate); if (status < 0) exitcode = 1; } else { @@ -141,10 +149,10 @@ int FAST_FUNC bbunpack(char **argv, unsigned new_name_len; /* TODO: restore other things? */ - if (aux.mtime != 0) { + if (xstate.mtime != 0) { struct timeval times[2]; - times[1].tv_sec = times[0].tv_sec = aux.mtime; + times[1].tv_sec = times[0].tv_sec = xstate.mtime; times[1].tv_usec = times[0].tv_usec = 0; /* Note: we closed it first. * On some systems calling utimes @@ -188,7 +196,10 @@ int FAST_FUNC bbunpack(char **argv, return exitcode; } -#if ENABLE_UNCOMPRESS || ENABLE_BUNZIP2 || ENABLE_UNLZMA || ENABLE_UNXZ +#if ENABLE_UNCOMPRESS \ + || ENABLE_BUNZIP2 || ENABLE_BZCAT \ + || ENABLE_UNLZMA || ENABLE_LZCAT || ENABLE_LZMA \ + || ENABLE_UNXZ || ENABLE_XZCAT || ENABLE_XZ static char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) { @@ -218,7 +229,7 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) //config:config UNCOMPRESS //config: bool "uncompress" -//config: default n +//config: default n # ancient //config: help //config: uncompress is used to decompress archives created by compress. //config: Not much used anymore, replaced by gzip/gunzip. @@ -226,18 +237,13 @@ char* FAST_FUNC make_new_name_generic(char *filename, const char *expected_ext) //applet:IF_UNCOMPRESS(APPLET(uncompress, BB_DIR_BIN, BB_SUID_DROP)) //kbuild:lib-$(CONFIG_UNCOMPRESS) += bbunzip.o #if ENABLE_UNCOMPRESS -static -IF_DESKTOP(long long) int FAST_FUNC unpack_uncompress(transformer_aux_data_t *aux) -{ - return unpack_Z_stream(aux, STDIN_FILENO, STDOUT_FILENO); -} int uncompress_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int uncompress_main(int argc UNUSED_PARAM, char **argv) { getopt32(argv, "cf"); argv += optind; - return bbunpack(argv, unpack_uncompress, make_new_name_generic, "Z"); + return bbunpack(argv, unpack_Z_stream, make_new_name_generic, "Z"); } #endif @@ -293,12 +299,25 @@ int uncompress_main(int argc UNUSED_PARAM, char **argv) //config: gunzip is used to decompress archives created by gzip. //config: You can use the `-t' option to test the integrity of //config: an archive, without decompressing it. +//config: +//config:config ZCAT +//config: bool "zcat" +//config: default y +//config: help +//config: Alias to "gunzip -c". +//config: +//config:config FEATURE_GUNZIP_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on (GUNZIP || ZCAT) && LONG_OPTS +//config: help +//config: Enable use of long options. //applet:IF_GUNZIP(APPLET(gunzip, BB_DIR_BIN, BB_SUID_DROP)) -//applet:IF_GUNZIP(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) -//kbuild:lib-$(CONFIG_GZIP) += bbunzip.o +//applet:IF_ZCAT(APPLET_ODDNAME(zcat, gunzip, BB_DIR_BIN, BB_SUID_DROP, zcat)) //kbuild:lib-$(CONFIG_GUNZIP) += bbunzip.o -#if ENABLE_GUNZIP +//kbuild:lib-$(CONFIG_ZCAT) += bbunzip.o +#if ENABLE_GUNZIP || ENABLE_ZCAT static char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UNUSED_PARAM) { @@ -324,11 +343,17 @@ char* FAST_FUNC make_new_name_gunzip(char *filename, const char *expected_ext UN } return filename; } -static -IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(transformer_aux_data_t *aux) -{ - return unpack_gz_stream(aux, STDIN_FILENO, STDOUT_FILENO); -} + +#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS +static const char gunzip_longopts[] ALIGN1 = + "stdout\0" No_argument "c" + "to-stdout\0" No_argument "c" + "force\0" No_argument "f" + "test\0" No_argument "t" + "no-name\0" No_argument "n" + ; +#endif + /* * Linux kernel build uses gzip -d -n. We accept and ignore it. * Man page says: @@ -345,6 +370,9 @@ IF_DESKTOP(long long) int FAST_FUNC unpack_gunzip(transformer_aux_data_t *aux) int gunzip_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int gunzip_main(int argc UNUSED_PARAM, char **argv) { +#if ENABLE_FEATURE_GUNZIP_LONG_OPTIONS + applet_long_options = gunzip_longopts; +#endif getopt32(argv, "cfvqdtn"); argv += optind; @@ -352,10 +380,10 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) * Normally, "zcat" is just "gunzip -c". * But if seamless magic is enabled, then we are much more clever. */ - if (applet_name[1] == 'c') + if (ENABLE_ZCAT && applet_name[1] == 'c') option_mask32 |= OPT_STDOUT | SEAMLESS_MAGIC; - return bbunpack(argv, unpack_gunzip, make_new_name_gunzip, /*unused:*/ NULL); + return bbunpack(argv, unpack_gz_stream, make_new_name_gunzip, /*unused:*/ NULL); } #endif @@ -389,26 +417,27 @@ int gunzip_main(int argc UNUSED_PARAM, char **argv) //config: //config: Unless you have a specific application which requires bunzip2, you //config: should probably say N here. +//config: +//config:config BZCAT +//config: bool "bzcat" +//config: default y +//config: help +//config: Alias to "bunzip2 -c". //applet:IF_BUNZIP2(APPLET(bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP)) -//applet:IF_BUNZIP2(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) -//kbuild:lib-$(CONFIG_BZIP2) += bbunzip.o +//applet:IF_BZCAT(APPLET_ODDNAME(bzcat, bunzip2, BB_DIR_USR_BIN, BB_SUID_DROP, bzcat)) //kbuild:lib-$(CONFIG_BUNZIP2) += bbunzip.o -#if ENABLE_BUNZIP2 -static -IF_DESKTOP(long long) int FAST_FUNC unpack_bunzip2(transformer_aux_data_t *aux) -{ - return unpack_bz2_stream(aux, STDIN_FILENO, STDOUT_FILENO); -} +//kbuild:lib-$(CONFIG_BZCAT) += bbunzip.o +#if ENABLE_BUNZIP2 || ENABLE_BZCAT int bunzip2_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int bunzip2_main(int argc UNUSED_PARAM, char **argv) { getopt32(argv, "cfvqdt"); argv += optind; - if (applet_name[2] == 'c') /* bzcat */ + if (ENABLE_BZCAT && applet_name[2] == 'c') /* bzcat */ option_mask32 |= OPT_STDOUT; - return bbunpack(argv, unpack_bunzip2, make_new_name_generic, "bz2"); + return bbunpack(argv, unpack_bz2_stream, make_new_name_generic, "bz2"); } #endif @@ -473,32 +502,40 @@ int bunzip2_main(int argc UNUSED_PARAM, char **argv) //config: The BusyBox unlzma applet is limited to decompression only. //config: On an x86 system, this applet adds about 4K. //config: -//config:config FEATURE_LZMA_FAST -//config: bool "Optimize unlzma for speed" -//config: default n -//config: depends on UNLZMA +//config:config LZCAT +//config: bool "lzcat" +//config: default y //config: help -//config: This option reduces decompression time by about 25% at the cost of -//config: a 1K bigger binary. +//config: unlzma is a compression utility using the Lempel-Ziv-Markov chain +//config: compression algorithm, and range coding. Compression +//config: is generally considerably better than that achieved by the bzip2 +//config: compressors. +//config: +//config: The BusyBox unlzma applet is limited to decompression only. +//config: On an x86 system, this applet adds about 4K. //config: //config:config LZMA -//config: bool "Provide lzma alias which supports only unpacking" +//config: bool "lzma -d" //config: default y -//config: depends on UNLZMA //config: help //config: Enable this option if you want commands like "lzma -d" to work. //config: IOW: you'll get lzma applet, but it will always require -d option. +//config: +//config:config FEATURE_LZMA_FAST +//config: bool "Optimize unlzma for speed" +//config: default n +//config: depends on UNLZMA || LZCAT || LZMA +//config: help +//config: This option reduces decompression time by about 25% at the cost of +//config: a 1K bigger binary. //applet:IF_UNLZMA(APPLET(unlzma, BB_DIR_USR_BIN, BB_SUID_DROP)) -//applet:IF_UNLZMA(APPLET_ODDNAME(lzcat, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzcat)) +//applet:IF_LZCAT(APPLET_ODDNAME(lzcat, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzcat)) //applet:IF_LZMA(APPLET_ODDNAME(lzma, unlzma, BB_DIR_USR_BIN, BB_SUID_DROP, lzma)) //kbuild:lib-$(CONFIG_UNLZMA) += bbunzip.o -#if ENABLE_UNLZMA -static -IF_DESKTOP(long long) int FAST_FUNC unpack_unlzma(transformer_aux_data_t *aux) -{ - return unpack_lzma_stream(aux, STDIN_FILENO, STDOUT_FILENO); -} +//kbuild:lib-$(CONFIG_LZCAT) += bbunzip.o +//kbuild:lib-$(CONFIG_LZMA) += bbunzip.o +#if ENABLE_UNLZMA || ENABLE_LZCAT || ENABLE_LZMA int unlzma_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int unlzma_main(int argc UNUSED_PARAM, char **argv) { @@ -509,11 +546,11 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) bb_show_usage(); # endif /* lzcat? */ - if (applet_name[2] == 'c') + if (ENABLE_LZCAT && applet_name[2] == 'c') option_mask32 |= OPT_STDOUT; argv += optind; - return bbunpack(argv, unpack_unlzma, make_new_name_generic, "lzma"); + return bbunpack(argv, unpack_lzma_stream, make_new_name_generic, "lzma"); } #endif @@ -524,24 +561,26 @@ int unlzma_main(int argc UNUSED_PARAM, char **argv) //config: help //config: unxz is a unlzma successor. //config: +//config:config XZCAT +//config: bool "xzcat" +//config: default y +//config: help +//config: Alias to "unxz -c". +//config: //config:config XZ -//config: bool "Provide xz alias which supports only unpacking" +//config: bool "xz -d" //config: default y -//config: depends on UNXZ //config: help //config: Enable this option if you want commands like "xz -d" to work. //config: IOW: you'll get xz applet, but it will always require -d option. //applet:IF_UNXZ(APPLET(unxz, BB_DIR_USR_BIN, BB_SUID_DROP)) -//applet:IF_UNXZ(APPLET_ODDNAME(xzcat, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xzcat)) +//applet:IF_XZCAT(APPLET_ODDNAME(xzcat, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xzcat)) //applet:IF_XZ(APPLET_ODDNAME(xz, unxz, BB_DIR_USR_BIN, BB_SUID_DROP, xz)) //kbuild:lib-$(CONFIG_UNXZ) += bbunzip.o -#if ENABLE_UNXZ -static -IF_DESKTOP(long long) int FAST_FUNC unpack_unxz(transformer_aux_data_t *aux) -{ - return unpack_xz_stream(aux, STDIN_FILENO, STDOUT_FILENO); -} +//kbuild:lib-$(CONFIG_XZCAT) += bbunzip.o +//kbuild:lib-$(CONFIG_XZ) += bbunzip.o +#if ENABLE_UNXZ || ENABLE_XZCAT || ENABLE_XZ int unxz_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int unxz_main(int argc UNUSED_PARAM, char **argv) { @@ -552,10 +591,10 @@ int unxz_main(int argc UNUSED_PARAM, char **argv) bb_show_usage(); # endif /* xzcat? */ - if (applet_name[2] == 'c') + if (ENABLE_XZCAT && applet_name[2] == 'c') option_mask32 |= OPT_STDOUT; argv += optind; - return bbunpack(argv, unpack_unxz, make_new_name_generic, "xz"); + return bbunpack(argv, unpack_xz_stream, make_new_name_generic, "xz"); } #endif diff --git a/archival/bzip2.c b/archival/bzip2.c index f7718b4..47fa29a 100644 --- a/archival/bzip2.c +++ b/archival/bzip2.c @@ -127,7 +127,7 @@ IF_DESKTOP(long long) int bz_write(bz_stream *strm, void* rbuf, ssize_t rlen, vo } static -IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_aux_data_t *aux UNUSED_PARAM) +IF_DESKTOP(long long) int FAST_FUNC compressStream(transformer_state_t *xstate UNUSED_PARAM) { IF_DESKTOP(long long) int total; ssize_t count; diff --git a/archival/cpio.c b/archival/cpio.c index 5fb5327..be98b42 100644 --- a/archival/cpio.c +++ b/archival/cpio.c @@ -11,6 +11,7 @@ * Only supports new ASCII and CRC formats */ #include "libbb.h" +#include "common_bufsiz.h" #include "bb_archive.h" //config:config CPIO @@ -22,7 +23,7 @@ //config: cpio has 110 bytes of overheads for every stored file. //config: //config: This implementation of cpio can extract cpio archives created in the -//config: "newc" or "crc" format, it cannot create or modify them. +//config: "newc" or "crc" format. //config: //config: Unless you have a specific application which requires cpio, you //config: should probably say N here. @@ -46,14 +47,14 @@ //kbuild:lib-$(CONFIG_CPIO) += cpio.o //usage:#define cpio_trivial_usage -//usage: "[-dmvu] [-F FILE]" IF_FEATURE_CPIO_O(" [-H newc]") +//usage: "[-dmvu] [-F FILE] [-R USER[:GRP]]" IF_FEATURE_CPIO_O(" [-H newc]") //usage: " [-ti"IF_FEATURE_CPIO_O("o")"]" IF_FEATURE_CPIO_P(" [-p DIR]") //usage: " [EXTR_FILE]..." //usage:#define cpio_full_usage "\n\n" -//usage: "Extract or list files from a cpio archive" +//usage: "Extract (-i) or list (-t) files from a cpio archive" //usage: IF_FEATURE_CPIO_O(", or" -//usage: "\ncreate an archive" IF_FEATURE_CPIO_P(" (-o) or copy files (-p)") -//usage: " using file list on stdin" +//usage: "\ntake file list from stdin and create an archive (-o)" +//usage: IF_FEATURE_CPIO_P(" or copy files (-p)") //usage: ) //usage: "\n" //usage: "\nMain operation mode:" @@ -65,11 +66,13 @@ //usage: IF_FEATURE_CPIO_P( //usage: "\n -p DIR Copy files to DIR" //usage: ) +//usage: "\nOptions:" //usage: "\n -d Make leading directories" //usage: "\n -m Preserve mtime" //usage: "\n -v Verbose" //usage: "\n -u Overwrite" //usage: "\n -F FILE Input (-t,-i,-p) or output (-o) file" +//usage: "\n -R USER[:GRP] Set owner of created files" //usage: IF_FEATURE_CPIO_O( //usage: "\n -H newc Archive format" //usage: ) @@ -129,7 +132,7 @@ -I FILE File to use instead of standard input -L, --dereference Dereference symbolic links (copy the files that they point to instead of copying the links) - -R, --owner=[USER][:.][GROUP] Set owner of created files + -R, --owner=[USER][:.][GRP] Set owner of created files Options valid in --extract and --pass-through modes: -d, --make-directories Create leading directories where needed @@ -149,7 +152,8 @@ enum { OPT_PRESERVE_MTIME = (1 << 6), OPT_DEREF = (1 << 7), OPT_FILE = (1 << 8), - OPTBIT_FILE = 8, + OPT_OWNER = (1 << 9), + OPTBIT_OWNER = 9, IF_FEATURE_CPIO_O(OPTBIT_CREATE ,) IF_FEATURE_CPIO_O(OPTBIT_FORMAT ,) IF_FEATURE_CPIO_P(OPTBIT_PASSTHROUGH,) @@ -162,7 +166,18 @@ enum { OPT_2STDOUT = IF_LONG_OPTS( (1 << OPTBIT_2STDOUT )) + 0, }; -#define OPTION_STR "it0uvdmLF:" +#define OPTION_STR "it0uvdmLF:R:" + +struct globals { + struct bb_uidgid_t owner_ugid; +} FIX_ALIASING; +#define G (*(struct globals*)bb_common_bufsiz1) +void BUG_cpio_globals_too_big(void); +#define INIT_G() do { \ + setup_common_bufsiz(); \ + G.owner_ugid.uid = -1L; \ + G.owner_ugid.gid = -1L; \ +} while (0) #if ENABLE_FEATURE_CPIO_O static off_t cpio_pad4(off_t size) @@ -180,7 +195,6 @@ static off_t cpio_pad4(off_t size) * It's ok to exit instead of return. */ static NOINLINE int cpio_o(void) { - static const char trailer[] ALIGN1 = "TRAILER!!!"; struct name_s { struct name_s *next; char name[1]; @@ -222,6 +236,11 @@ static NOINLINE int cpio_o(void) bb_simple_perror_msg_and_die(name); } + if (G.owner_ugid.uid != (uid_t)-1L) + st.st_uid = G.owner_ugid.uid; + if (G.owner_ugid.gid != (gid_t)-1L) + st.st_gid = G.owner_ugid.gid; + if (!(S_ISLNK(st.st_mode) || S_ISREG(st.st_mode))) st.st_size = 0; /* paranoia */ @@ -256,7 +275,6 @@ static NOINLINE int cpio_o(void) free(line); continue; } - } else { /* line == NULL: EOF */ next_link: if (links) { @@ -275,7 +293,7 @@ static NOINLINE int cpio_o(void) } else { /* If no (more) hardlinks to output, * output "trailer" entry */ - name = trailer; + name = cpio_TRAILER; /* st.st_size == 0 is a must, but for uniformity * in the output, we zero out everything */ memset(&st, 0, sizeof(st)); @@ -323,7 +341,7 @@ static NOINLINE int cpio_o(void) } if (!line) { - if (name != trailer) + if (name != cpio_TRAILER) goto next_link; /* TODO: GNU cpio pads trailer to 512 bytes, do we want that? */ return EXIT_SUCCESS; @@ -339,6 +357,7 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) { archive_handle_t *archive_handle; char *cpio_filename; + char *cpio_owner; IF_FEATURE_CPIO_O(const char *cpio_fmt = "";) unsigned opt; @@ -353,12 +372,14 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) "pass-through\0" No_argument "p" #endif #endif + "owner\0" Required_argument "R" "verbose\0" No_argument "v" "quiet\0" No_argument "\xff" "to-stdout\0" No_argument "\xfe" ; #endif + INIT_G(); archive_handle = init_handle(); /* archive_handle->src_fd = STDIN_FILENO; - done by init_handle */ archive_handle->ah_flags = ARCHIVE_EXTRACT_NEWER; @@ -369,14 +390,21 @@ int cpio_main(int argc UNUSED_PARAM, char **argv) /* -L makes sense only with -o or -p */ #if !ENABLE_FEATURE_CPIO_O - opt = getopt32(argv, OPTION_STR, &cpio_filename); + opt = getopt32(argv, OPTION_STR, &cpio_filename, &cpio_owner); +#else + opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), + &cpio_filename, &cpio_owner, &cpio_fmt); +#endif argv += optind; + if (opt & OPT_OWNER) { /* -R */ + parse_chown_usergroup_or_die(&G.owner_ugid, cpio_owner); + archive_handle->cpio__owner = G.owner_ugid; + } +#if !ENABLE_FEATURE_CPIO_O if (opt & OPT_FILE) { /* -F */ xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); } #else - opt = getopt32(argv, OPTION_STR "oH:" IF_FEATURE_CPIO_P("p"), &cpio_filename, &cpio_fmt); - argv += optind; if ((opt & (OPT_FILE|OPT_CREATE)) == OPT_FILE) { /* -F without -o */ xmove_fd(xopen(cpio_filename, O_RDONLY), STDIN_FILENO); } diff --git a/archival/dpkg.c b/archival/dpkg.c index 2893cfc..f133299 100644 --- a/archival/dpkg.c +++ b/archival/dpkg.c @@ -28,7 +28,7 @@ //config:config DPKG //config: bool "dpkg" -//config: default n +//config: default y //config: select FEATURE_SEAMLESS_GZ //config: help //config: dpkg is a medium-level tool to install, build, remove and manage @@ -1151,13 +1151,13 @@ static int check_deps(deb_file_t **deb_file, int deb_start /*, int dep_max_count if (result && number_of_alternatives == 0) { if (root_of_alternatives) bb_error_msg_and_die( - "package %s %sdepends on %s, " - "which cannot be satisfied", + "package %s %sdepends on %s, which %s", name_hashtable[package_node->name], package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", - name_hashtable[root_of_alternatives->name]); + name_hashtable[root_of_alternatives->name], + "cannot be satisfied"); bb_error_msg_and_die( - "package %s %sdepends on %s, which %s\n", + "package %s %sdepends on %s, which %s", name_hashtable[package_node->name], package_edge->type == EDGE_PRE_DEPENDS ? "pre-" : "", name_hashtable[package_edge->name], @@ -1472,12 +1472,16 @@ static void init_archive_deb_control(archive_handle_t *ar_handle) tar_handle->src_fd = ar_handle->src_fd; /* We don't care about data.tar.* or debian-binary, just control.tar.* */ + llist_add_to(&(ar_handle->accept), (char*)"control.tar"); #if ENABLE_FEATURE_SEAMLESS_GZ llist_add_to(&(ar_handle->accept), (char*)"control.tar.gz"); #endif #if ENABLE_FEATURE_SEAMLESS_BZ2 llist_add_to(&(ar_handle->accept), (char*)"control.tar.bz2"); #endif +#if ENABLE_FEATURE_SEAMLESS_XZ + llist_add_to(&(ar_handle->accept), (char*)"control.tar.xz"); +#endif /* Assign the tar handle as a subarchive of the ar handle */ ar_handle->dpkg__sub_archive = tar_handle; @@ -1492,12 +1496,19 @@ static void init_archive_deb_data(archive_handle_t *ar_handle) tar_handle->src_fd = ar_handle->src_fd; /* We don't care about control.tar.* or debian-binary, just data.tar.* */ + llist_add_to(&(ar_handle->accept), (char*)"data.tar"); #if ENABLE_FEATURE_SEAMLESS_GZ llist_add_to(&(ar_handle->accept), (char*)"data.tar.gz"); #endif #if ENABLE_FEATURE_SEAMLESS_BZ2 llist_add_to(&(ar_handle->accept), (char*)"data.tar.bz2"); #endif +#if ENABLE_FEATURE_SEAMLESS_LZMA + llist_add_to(&(ar_handle->accept), (char*)"data.tar.lzma"); +#endif +#if ENABLE_FEATURE_SEAMLESS_XZ + llist_add_to(&(ar_handle->accept), (char*)"data.tar.xz"); +#endif /* Assign the tar handle as a subarchive of the ar handle */ ar_handle->dpkg__sub_archive = tar_handle; diff --git a/archival/dpkg_deb.c b/archival/dpkg_deb.c index 13f9db9..ebbc7f0 100644 --- a/archival/dpkg_deb.c +++ b/archival/dpkg_deb.c @@ -7,7 +7,7 @@ //config:config DPKG_DEB //config: bool "dpkg_deb" -//config: default n +//config: default y //config: select FEATURE_SEAMLESS_GZ //config: help //config: dpkg-deb unpacks and provides information about Debian archives. @@ -16,29 +16,20 @@ //config: //config: Unless you have a specific application which requires dpkg-deb, //config: say N here. -//config: -//config:config FEATURE_DPKG_DEB_EXTRACT_ONLY -//config: bool "Extract only (-x)" -//config: default n -//config: depends on DPKG_DEB -//config: help -//config: This reduces dpkg-deb to the equivalent of -//config: "ar -p data.tar.gz | tar -zx". However it saves space as none -//config: of the extra dpkg-deb, ar or tar options are needed, they are linked -//config: to internally. //applet:IF_DPKG_DEB(APPLET_ODDNAME(dpkg-deb, dpkg_deb, BB_DIR_USR_BIN, BB_SUID_DROP, dpkg_deb)) + //kbuild:lib-$(CONFIG_DPKG_DEB) += dpkg_deb.o //usage:#define dpkg_deb_trivial_usage -//usage: "[-cefxX] FILE [argument]" +//usage: "[-cefxX] FILE [DIR]" //usage:#define dpkg_deb_full_usage "\n\n" -//usage: "Perform actions on Debian packages (.debs)\n" -//usage: "\n -c List contents of filesystem tree" -//usage: "\n -e Extract control files to [argument] directory" -//usage: "\n -f Display control field name starting with [argument]" -//usage: "\n -x Extract packages filesystem tree to directory" -//usage: "\n -X Verbose extract" +//usage: "Perform actions on Debian packages (.deb)\n" +//usage: "\n -c List files" +//usage: "\n -f Print control fields" +//usage: "\n -e Extract control files to DIR (default: ./DEBIAN)" +//usage: "\n -x Extract files to DIR (no default)" +//usage: "\n -X Verbose -x" //usage: //usage:#define dpkg_deb_example_usage //usage: "$ dpkg-deb -X ./busybox_0.48-1_i386.deb /tmp\n" @@ -49,18 +40,17 @@ #define DPKG_DEB_OPT_CONTENTS 1 #define DPKG_DEB_OPT_CONTROL 2 #define DPKG_DEB_OPT_FIELD 4 -#define DPKG_DEB_OPT_EXTRACT 8 -#define DPKG_DEB_OPT_EXTRACT_VERBOSE 16 +#define DPKG_DEB_OPT_EXTRACT_VERBOSE 8 +#define DPKG_DEB_OPT_EXTRACT 16 int dpkg_deb_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int dpkg_deb_main(int argc, char **argv) +int dpkg_deb_main(int argc UNUSED_PARAM, char **argv) { archive_handle_t *ar_archive; archive_handle_t *tar_archive; llist_t *control_tar_llist = NULL; unsigned opt; const char *extract_dir; - int need_args; /* Setup the tar archive handle */ tar_archive = init_handle(); @@ -70,6 +60,8 @@ int dpkg_deb_main(int argc, char **argv) ar_archive->dpkg__sub_archive = tar_archive; ar_archive->filter = filter_accept_list_reassign; + llist_add_to(&ar_archive->accept, (char*)"data.tar"); + llist_add_to(&control_tar_llist, (char*)"control.tar"); #if ENABLE_FEATURE_SEAMLESS_GZ llist_add_to(&ar_archive->accept, (char*)"data.tar.gz"); llist_add_to(&control_tar_llist, (char*)"control.tar.gz"); @@ -82,54 +74,50 @@ int dpkg_deb_main(int argc, char **argv) llist_add_to(&ar_archive->accept, (char*)"data.tar.lzma"); llist_add_to(&control_tar_llist, (char*)"control.tar.lzma"); #endif +#if ENABLE_FEATURE_SEAMLESS_XZ + llist_add_to(&ar_archive->accept, (char*)"data.tar.xz"); + llist_add_to(&control_tar_llist, (char*)"control.tar.xz"); +#endif - opt_complementary = "c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; + /* Must have 1 or 2 args */ + opt_complementary = "-1:?2:c--efXx:e--cfXx:f--ceXx:X--cefx:x--cefX"; opt = getopt32(argv, "cefXx"); argv += optind; - argc -= optind; + //argc -= optind; - if (opt & DPKG_DEB_OPT_CONTENTS) { + extract_dir = argv[1]; + if (opt & DPKG_DEB_OPT_CONTENTS) { // -c tar_archive->action_header = header_verbose_list; + if (extract_dir) + bb_show_usage(); } - extract_dir = NULL; - need_args = 1; - if (opt & DPKG_DEB_OPT_CONTROL) { - ar_archive->accept = control_tar_llist; - tar_archive->action_data = data_extract_all; - if (1 == argc) { - extract_dir = "./DEBIAN"; - } else { - need_args++; - } - } - if (opt & DPKG_DEB_OPT_FIELD) { - /* Print the entire control file - * it should accept a second argument which specifies a - * specific field to print */ + if (opt & DPKG_DEB_OPT_FIELD) { // -f + /* Print the entire control file */ +//TODO: standard tool accepts an optional list of fields to print ar_archive->accept = control_tar_llist; llist_add_to(&(tar_archive->accept), (char*)"./control"); tar_archive->filter = filter_accept_list; tar_archive->action_data = data_extract_to_stdout; + if (extract_dir) + bb_show_usage(); } - if (opt & DPKG_DEB_OPT_EXTRACT) { - tar_archive->action_header = header_list; - } - if (opt & (DPKG_DEB_OPT_EXTRACT_VERBOSE | DPKG_DEB_OPT_EXTRACT)) { + if (opt & DPKG_DEB_OPT_CONTROL) { // -e + ar_archive->accept = control_tar_llist; tar_archive->action_data = data_extract_all; - need_args = 2; + if (!extract_dir) + extract_dir = "./DEBIAN"; } - - if (need_args != argc) { - bb_show_usage(); + if (opt & (DPKG_DEB_OPT_EXTRACT_VERBOSE | DPKG_DEB_OPT_EXTRACT)) { // -Xx + if (opt & DPKG_DEB_OPT_EXTRACT_VERBOSE) + tar_archive->action_header = header_list; + tar_archive->action_data = data_extract_all; + if (!extract_dir) + bb_show_usage(); } - tar_archive->src_fd = ar_archive->src_fd = xopen(argv[0], O_RDONLY); + /* Standard tool supports "-" */ + tar_archive->src_fd = ar_archive->src_fd = xopen_stdin(argv[0]); - /* Work out where to extract the files */ - /* 2nd argument is a dir name */ - if (argv[1]) { - extract_dir = argv[1]; - } if (extract_dir) { mkdir(extract_dir, 0777); /* bb_make_directory(extract_dir, 0777, 0) */ xchdir(extract_dir); diff --git a/archival/gzip.c b/archival/gzip.c index 1e779c9..1f0b70f 100644 --- a/archival/gzip.c +++ b/archival/gzip.c @@ -62,15 +62,30 @@ aa: 85.1% -- replaced with aa.gz //config: 1: larger buffers, larger hash-tables //config: 2: larger buffers, largest hash-tables //config: Larger models may give slightly better compression +//config: +//config:config FEATURE_GZIP_LEVELS +//config: bool "Enable compression levels" +//config: default n +//config: depends on GZIP +//config: help +//config: Enable support for compression levels 4-9. The default level +//config: is 6. If levels 1-3 are specified, 4 is used. +//config: If this option is not selected, -N options are ignored and -9 +//config: is used. //applet:IF_GZIP(APPLET(gzip, BB_DIR_BIN, BB_SUID_DROP)) //kbuild:lib-$(CONFIG_GZIP) += gzip.o //usage:#define gzip_trivial_usage -//usage: "[-cfd] [FILE]..." +//usage: "[-cf" IF_GUNZIP("d") IF_FEATURE_GZIP_LEVELS("123456789") "] [FILE]..." //usage:#define gzip_full_usage "\n\n" //usage: "Compress FILEs (or stdin)\n" +//usage: IF_FEATURE_GZIP_LEVELS( +//usage: "\n -1..9 Compression level" +//usage: ) +//usage: IF_GUNZIP( //usage: "\n -d Decompress" +//usage: ) //usage: "\n -c Write to stdout" //usage: "\n -f Force" //usage: @@ -83,6 +98,7 @@ aa: 85.1% -- replaced with aa.gz #include "libbb.h" #include "bb_archive.h" +#include /* =========================================================================== @@ -252,6 +268,8 @@ enum { * input file length plus MIN_LOOKAHEAD. */ +#ifndef ENABLE_FEATURE_GZIP_LEVELS + max_chain_length = 4096, /* To speed up deflation, hash chains are never searched beyond this length. * A higher limit improves compression ratio but degrades the speed. @@ -283,11 +301,23 @@ enum { * For deflate_fast() (levels <= 3) good is ignored and lazy has a different * meaning. */ +#endif /* ENABLE_FEATURE_GZIP_LEVELS */ }; struct globals { +#ifdef ENABLE_FEATURE_GZIP_LEVELS + unsigned max_chain_length; + unsigned max_lazy_match; + unsigned good_match; + unsigned nice_match; +#define max_chain_length (G1.max_chain_length) +#define max_lazy_match (G1.max_lazy_match) +#define good_match (G1.good_match) +#define nice_match (G1.nice_match) +#endif + lng block_start; /* window position at the beginning of the current output block. Gets @@ -417,19 +447,46 @@ static void flush_outbuf(void) #define put_8bit(c) \ do { \ G1.outbuf[G1.outcnt++] = (c); \ - if (G1.outcnt == OUTBUFSIZ) flush_outbuf(); \ + if (G1.outcnt == OUTBUFSIZ) \ + flush_outbuf(); \ } while (0) /* Output a 16 bit value, lsb first */ static void put_16bit(ush w) { - if (G1.outcnt < OUTBUFSIZ - 2) { - G1.outbuf[G1.outcnt++] = w; - G1.outbuf[G1.outcnt++] = w >> 8; - } else { - put_8bit(w); - put_8bit(w >> 8); + /* GCC 4.2.1 won't optimize out redundant loads of G1.outcnt + * (probably because of fear of aliasing with G1.outbuf[] + * stores), do it explicitly: + */ + unsigned outcnt = G1.outcnt; + uch *dst = &G1.outbuf[outcnt]; + +#if BB_UNALIGNED_MEMACCESS_OK && BB_LITTLE_ENDIAN + if (outcnt < OUTBUFSIZ-2) { + /* Common case */ + ush *dst16 = (void*) dst; + *dst16 = w; /* unalinged LSB 16-bit store */ + G1.outcnt = outcnt + 2; + return; } + *dst = (uch)w; + w >>= 8; +#else + *dst = (uch)w; + w >>= 8; + if (outcnt < OUTBUFSIZ-2) { + /* Common case */ + dst[1] = w; + G1.outcnt = outcnt + 2; + return; + } +#endif + + /* Slowpath: we will need to do flush_outbuf() */ + G1.outcnt = ++outcnt; + if (outcnt == OUTBUFSIZ) + flush_outbuf(); + put_8bit(w); } static void put_32bit(ulg n) @@ -1318,7 +1375,6 @@ static void build_tree(tree_desc * desc) /* and insert the new node in the heap */ G2.heap[SMALLEST] = node++; pqdownheap(tree, SMALLEST); - } while (G2.heap_len >= 2); G2.heap[--G2.heap_max] = G2.heap[SMALLEST]; @@ -1666,7 +1722,6 @@ static ulg flush_block(char *buf, ulg stored_len, int eof) copy_block(buf, (unsigned) stored_len, 0); /* without header */ G2.compressed_len = stored_len << 3; - } else if (stored_len + 4 <= opt_lenb && buf != NULL) { /* 4: two words for the lengths */ /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. @@ -1680,7 +1735,6 @@ static ulg flush_block(char *buf, ulg stored_len, int eof) G2.compressed_len += (stored_len + 4) << 3; copy_block(buf, (unsigned) stored_len, 1); /* with header */ - } else if (static_lenb == opt_lenb) { send_bits((STATIC_TREES << 1) + eof, 3); compress_block((ct_data *) G2.static_ltree, (ct_data *) G2.static_dtree); @@ -2007,7 +2061,7 @@ static void ct_init(void) * IN assertions: the input and output buffers are cleared. */ -static void zip(ulg time_stamp) +static void zip(void) { ush deflate_flags = 0; /* pkzip -es, -en or -ex equivalent */ @@ -2018,7 +2072,7 @@ static void zip(ulg time_stamp) /* compression method: 8 (DEFLATED) */ /* general flags: 0 */ put_32bit(0x00088b1f); - put_32bit(time_stamp); + put_32bit(0); /* Unix timestamp */ /* Write deflated file to zip file */ G1.crc = ~0; @@ -2042,10 +2096,8 @@ static void zip(ulg time_stamp) /* ======================================================================== */ static -IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_aux_data_t *aux UNUSED_PARAM) +IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_state_t *xstate UNUSED_PARAM) { - struct stat s; - /* Clear input and output buffers */ G1.outcnt = 0; #ifdef DEBUG @@ -2077,9 +2129,23 @@ IF_DESKTOP(long long) int FAST_FUNC pack_gzip(transformer_aux_data_t *aux UNUSED G2.bl_desc.max_length = MAX_BL_BITS; //G2.bl_desc.max_code = 0; +#if 0 + /* Saving of timestamp is disabled. Why? + * - it is not Y2038-safe. + * - some people want deterministic results + * (normally they'd use -n, but our -n is a nop). + * - it's bloat. + * Per RFC 1952, gzfile.time=0 is "no timestamp". + * If users will demand this to be reinstated, + * implement -n "don't save timestamp". + */ + struct stat s; s.st_ctime = 0; fstat(STDIN_FILENO, &s); zip(s.st_ctime); +#else + zip(); +#endif return 0; } @@ -2097,6 +2163,7 @@ static const char gzip_longopts[] ALIGN1 = "quiet\0" No_argument "q" "fast\0" No_argument "1" "best\0" No_argument "9" + "no-name\0" No_argument "n" ; #endif @@ -2122,24 +2189,45 @@ int gzip_main(int argc UNUSED_PARAM, char **argv) #endif { unsigned opt; +#ifdef ENABLE_FEATURE_GZIP_LEVELS + static const struct { + uint8_t good; + uint8_t chain_shift; + uint8_t lazy2; + uint8_t nice2; + } gzip_level_config[6] = { + {4, 4, 4/2, 16/2}, /* Level 4 */ + {8, 5, 16/2, 32/2}, /* Level 5 */ + {8, 7, 16/2, 128/2}, /* Level 6 */ + {8, 8, 32/2, 128/2}, /* Level 7 */ + {32, 10, 128/2, 258/2}, /* Level 8 */ + {32, 12, 258/2, 258/2}, /* Level 9 */ + }; +#endif + + SET_PTR_TO_GLOBALS((char *)xzalloc(sizeof(struct globals)+sizeof(struct globals2)) + + sizeof(struct globals)); #if ENABLE_FEATURE_GZIP_LONG_OPTIONS applet_long_options = gzip_longopts; #endif /* Must match bbunzip's constants OPT_STDOUT, OPT_FORCE! */ - opt = getopt32(argv, "cfv" IF_GUNZIP("dt") "q123456789n"); + opt = getopt32(argv, "cfv" IF_GUNZIP("dt") "qn123456789"); #if ENABLE_GUNZIP /* gunzip_main may not be visible... */ if (opt & 0x18) // -d and/or -t return gunzip_main(argc, argv); #endif - option_mask32 &= 0x7; /* ignore -q, -0..9 */ - //if (opt & 0x1) // -c - //if (opt & 0x2) // -f - //if (opt & 0x4) // -v - argv += optind; - - SET_PTR_TO_GLOBALS((char *)xzalloc(sizeof(struct globals)+sizeof(struct globals2)) - + sizeof(struct globals)); +#ifdef ENABLE_FEATURE_GZIP_LEVELS + opt >>= ENABLE_GUNZIP ? 7 : 5; /* drop cfv[dt]qn bits */ + if (opt == 0) + opt = 1 << 6; /* default: 6 */ + opt = ffs(opt >> 4); /* Maps -1..-4 to [0], -5 to [1] ... -9 to [5] */ + max_chain_length = 1 << gzip_level_config[opt].chain_shift; + good_match = gzip_level_config[opt].good; + max_lazy_match = gzip_level_config[opt].lazy2 * 2; + nice_match = gzip_level_config[opt].nice2 * 2; +#endif + option_mask32 &= 0x7; /* retain only -cfv */ /* Allocate all global buffers (for DYN_ALLOC option) */ ALLOC(uch, G1.l_buf, INBUFSIZ); @@ -2151,5 +2239,6 @@ int gzip_main(int argc UNUSED_PARAM, char **argv) /* Initialize the CRC32 table */ global_crc32_table = crc32_filltable(NULL, 0); + argv += optind; return bbunpack(argv, pack_gzip, append_ext, "gz"); } diff --git a/archival/libarchive/Kbuild.src b/archival/libarchive/Kbuild.src index 968fdf8..ad5c5c4 100644 --- a/archival/libarchive/Kbuild.src +++ b/archival/libarchive/Kbuild.src @@ -4,7 +4,7 @@ # # Licensed under GPLv2 or later, see file LICENSE in this source tree. -lib-y:= +lib-y:= common.o COMMON_FILES:= \ \ @@ -30,11 +30,13 @@ COMMON_FILES:= \ DPKG_FILES:= \ unpack_ar_archive.o \ filter_accept_list_reassign.o \ + unsafe_prefix.o \ get_header_ar.o \ get_header_tar.o \ get_header_tar_gz.o \ get_header_tar_bz2.o \ get_header_tar_lzma.o \ + get_header_tar_xz.o \ INSERT @@ -43,19 +45,26 @@ lib-$(CONFIG_DPKG_DEB) += $(DPKG_FILES) lib-$(CONFIG_AR) += get_header_ar.o unpack_ar_archive.o lib-$(CONFIG_CPIO) += get_header_cpio.o -lib-$(CONFIG_TAR) += get_header_tar.o +lib-$(CONFIG_TAR) += get_header_tar.o unsafe_prefix.o lib-$(CONFIG_FEATURE_TAR_TO_COMMAND) += data_extract_to_command.o lib-$(CONFIG_LZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o +lib-$(CONFIG_UNLZOP) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o +lib-$(CONFIG_LZOPCAT) += lzo1x_1.o lzo1x_1o.o lzo1x_d.o lib-$(CONFIG_LZOP_COMPR_HIGH) += lzo1x_9x.o lib-$(CONFIG_BUNZIP2) += open_transformer.o decompress_bunzip2.o +lib-$(CONFIG_BZCAT) += open_transformer.o decompress_bunzip2.o lib-$(CONFIG_UNLZMA) += open_transformer.o decompress_unlzma.o +lib-$(CONFIG_LZCAT) += open_transformer.o decompress_unlzma.o +lib-$(CONFIG_LZMA) += open_transformer.o decompress_unlzma.o lib-$(CONFIG_UNXZ) += open_transformer.o decompress_unxz.o +lib-$(CONFIG_XZCAT) += open_transformer.o decompress_unxz.o +lib-$(CONFIG_XZ) += open_transformer.o decompress_unxz.o lib-$(CONFIG_GUNZIP) += open_transformer.o decompress_gunzip.o +lib-$(CONFIG_ZCAT) += open_transformer.o decompress_gunzip.o lib-$(CONFIG_UNCOMPRESS) += open_transformer.o decompress_uncompress.o -lib-$(CONFIG_UNZIP) += open_transformer.o decompress_gunzip.o +lib-$(CONFIG_UNZIP) += open_transformer.o decompress_gunzip.o unsafe_prefix.o lib-$(CONFIG_RPM2CPIO) += open_transformer.o decompress_gunzip.o get_header_cpio.o lib-$(CONFIG_RPM) += open_transformer.o decompress_gunzip.o get_header_cpio.o - lib-$(CONFIG_GZIP) += open_transformer.o lib-$(CONFIG_BZIP2) += open_transformer.o lib-$(CONFIG_LZOP) += open_transformer.o diff --git a/archival/libarchive/bz/compress.c b/archival/libarchive/bz/compress.c index 23de9d3..2d99468 100644 --- a/archival/libarchive/bz/compress.c +++ b/archival/libarchive/bz/compress.c @@ -385,7 +385,6 @@ void sendMTFValues(EState* s) cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; - } else #endif { diff --git a/archival/libarchive/common.c b/archival/libarchive/common.c new file mode 100644 index 0000000..389cb78 --- a/dev/null +++ b/archival/libarchive/common.c @@ -0,0 +1,9 @@ +/* vi: set sw=4 ts=4: */ +/* + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +#include "libbb.h" +#include "bb_archive.h" + +const char cpio_TRAILER[] ALIGN1 = "TRAILER!!!"; diff --git a/archival/libarchive/data_extract_all.c b/archival/libarchive/data_extract_all.c index 2e18ffb..5d8e57a 100644 --- a/archival/libarchive/data_extract_all.c +++ b/archival/libarchive/data_extract_all.c @@ -11,6 +11,12 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) file_header_t *file_header = archive_handle->file_header; int dst_fd; int res; + char *hard_link; +#if ENABLE_FEATURE_TAR_LONG_OPTIONS + char *dst_name; +#else +# define dst_name (file_header->name) +#endif #if ENABLE_FEATURE_TAR_SELINUX char *sctx = archive_handle->tar__sctx[PAX_NEXT_FILE]; @@ -26,11 +32,49 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) } #endif + /* Hard links are encoded as regular files of size 0 + * with a nonempty link field */ + hard_link = NULL; + if (S_ISREG(file_header->mode) && file_header->size == 0) + hard_link = file_header->link_target; + +#if ENABLE_FEATURE_TAR_LONG_OPTIONS + dst_name = file_header->name; + if (archive_handle->tar__strip_components) { + unsigned n = archive_handle->tar__strip_components; + do { + dst_name = strchr(dst_name, '/'); + if (!dst_name || dst_name[1] == '\0') { + data_skip(archive_handle); + goto ret; + } + dst_name++; + /* + * Link target is shortened only for hardlinks: + * softlinks restored unchanged. + */ + if (hard_link) { +// GNU tar 1.26 does not check that we reached end of link name: +// if "dir/hardlink" is hardlinked to "file", +// tar xvf a.tar --strip-components=1 says: +// tar: hardlink: Cannot hard link to '': No such file or directory +// and continues processing. We silently skip such entries. + hard_link = strchr(hard_link, '/'); + if (!hard_link || hard_link[1] == '\0') { + data_skip(archive_handle); + goto ret; + } + hard_link++; + } + } while (--n != 0); + } +#endif + if (archive_handle->ah_flags & ARCHIVE_CREATE_LEADING_DIRS) { - char *slash = strrchr(file_header->name, '/'); + char *slash = strrchr(dst_name, '/'); if (slash) { *slash = '\0'; - bb_make_directory(file_header->name, -1, FILEUTILS_RECUR); + bb_make_directory(dst_name, -1, FILEUTILS_RECUR); *slash = '/'; } } @@ -38,12 +82,7 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) if (archive_handle->ah_flags & ARCHIVE_UNLINK_OLD) { /* Remove the entry if it exists */ if (!S_ISDIR(file_header->mode)) { - /* Is it hardlink? - * We encode hard links as regular files of size 0 with a symlink */ - if (S_ISREG(file_header->mode) - && file_header->link_target - && file_header->size == 0 - ) { + if (hard_link) { /* Ugly special case: * tar cf t.tar hardlink1 hardlink2 hardlink1 * results in this tarball structure: @@ -51,22 +90,22 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) * hardlink2 -> hardlink1 * hardlink1 -> hardlink1 <== !!! */ - if (strcmp(file_header->link_target, file_header->name) == 0) + if (strcmp(hard_link, dst_name) == 0) goto ret; } /* Proceed with deleting */ - if (unlink(file_header->name) == -1 + if (unlink(dst_name) == -1 && errno != ENOENT ) { bb_perror_msg_and_die("can't remove old file %s", - file_header->name); + dst_name); } } } else if (archive_handle->ah_flags & ARCHIVE_EXTRACT_NEWER) { /* Remove the existing entry if its older than the extracted entry */ struct stat existing_sb; - if (lstat(file_header->name, &existing_sb) == -1) { + if (lstat(dst_name, &existing_sb) == -1) { if (errno != ENOENT) { bb_perror_msg_and_die("can't stat old file"); } @@ -76,30 +115,25 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) && !S_ISDIR(file_header->mode) ) { bb_error_msg("%s not created: newer or " - "same age file exists", file_header->name); + "same age file exists", dst_name); } data_skip(archive_handle); goto ret; } - else if ((unlink(file_header->name) == -1) && (errno != EISDIR)) { + else if ((unlink(dst_name) == -1) && (errno != EISDIR)) { bb_perror_msg_and_die("can't remove old file %s", - file_header->name); + dst_name); } } - /* Handle hard links separately - * We encode hard links as regular files of size 0 with a symlink */ - if (S_ISREG(file_header->mode) - && file_header->link_target - && file_header->size == 0 - ) { - /* hard link */ - res = link(file_header->link_target, file_header->name); - if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { + /* Handle hard links separately */ + if (hard_link) { + res = link(hard_link, dst_name); + if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET)) { bb_perror_msg("can't create %slink " "from %s to %s", "hard", - file_header->name, - file_header->link_target); + dst_name, + hard_link); } /* Hardlinks have no separate mode/ownership, skip chown/chmod */ goto ret; @@ -109,17 +143,17 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) switch (file_header->mode & S_IFMT) { case S_IFREG: { /* Regular file */ - char *dst_name; + char *dst_nameN; int flags = O_WRONLY | O_CREAT | O_EXCL; if (archive_handle->ah_flags & ARCHIVE_O_TRUNC) flags = O_WRONLY | O_CREAT | O_TRUNC; - dst_name = file_header->name; + dst_nameN = dst_name; #ifdef ARCHIVE_REPLACE_VIA_RENAME if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) /* rpm-style temp file name */ - dst_name = xasprintf("%s;%x", dst_name, (int)getpid()); + dst_nameN = xasprintf("%s;%x", dst_name, (int)getpid()); #endif - dst_fd = xopen3(dst_name, + dst_fd = xopen3(dst_nameN, flags, file_header->mode ); @@ -127,32 +161,32 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) close(dst_fd); #ifdef ARCHIVE_REPLACE_VIA_RENAME if (archive_handle->ah_flags & ARCHIVE_REPLACE_VIA_RENAME) { - xrename(dst_name, file_header->name); - free(dst_name); + xrename(dst_nameN, dst_name); + free(dst_nameN); } #endif break; } case S_IFDIR: - res = mkdir(file_header->name, file_header->mode); + res = mkdir(dst_name, file_header->mode); if ((res == -1) && (errno != EISDIR) /* btw, Linux doesn't return this */ && (errno != EEXIST) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) ) { - bb_perror_msg("can't make dir %s", file_header->name); + bb_perror_msg("can't make dir %s", dst_name); } break; case S_IFLNK: /* Symlink */ //TODO: what if file_header->link_target == NULL (say, corrupted tarball?) - res = symlink(file_header->link_target, file_header->name); - if ((res == -1) + res = symlink(file_header->link_target, dst_name); + if (res != 0 && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) ) { bb_perror_msg("can't create %slink " "from %s to %s", "sym", - file_header->name, + dst_name, file_header->link_target); } break; @@ -160,11 +194,11 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) case S_IFBLK: case S_IFCHR: case S_IFIFO: - res = mknod(file_header->name, file_header->mode, file_header->device); + res = mknod(dst_name, file_header->mode, file_header->device); if ((res == -1) && !(archive_handle->ah_flags & ARCHIVE_EXTRACT_QUIET) ) { - bb_perror_msg("can't create node %s", file_header->name); + bb_perror_msg("can't create node %s", dst_name); } break; default: @@ -189,20 +223,20 @@ void FAST_FUNC data_extract_all(archive_handle_t *archive_handle) } #endif /* GNU tar 1.15.1 uses chown, not lchown */ - chown(file_header->name, uid, gid); + chown(dst_name, uid, gid); } /* uclibc has no lchmod, glibc is even stranger - * it has lchmod which seems to do nothing! * so we use chmod... */ if (!(archive_handle->ah_flags & ARCHIVE_DONT_RESTORE_PERM)) { - chmod(file_header->name, file_header->mode); + chmod(dst_name, file_header->mode); } if (archive_handle->ah_flags & ARCHIVE_RESTORE_DATE) { struct timeval t[2]; t[1].tv_sec = t[0].tv_sec = file_header->mtime; t[1].tv_usec = t[0].tv_usec = 0; - utimes(file_header->name, t); + utimes(dst_name, t); } } diff --git a/archival/libarchive/data_extract_to_command.c b/archival/libarchive/data_extract_to_command.c index 599288d..3b7d1ea 100644 --- a/archival/libarchive/data_extract_to_command.c +++ b/archival/libarchive/data_extract_to_command.c @@ -112,13 +112,12 @@ void FAST_FUNC data_extract_to_command(archive_handle_t *archive_handle) bb_copyfd_exact_size(archive_handle->src_fd, p[1], -file_header->size); close(p[1]); - if (safe_waitpid(pid, &status, 0) == -1) - bb_perror_msg_and_die("waitpid"); + status = wait_for_exitstatus(pid); if (WIFEXITED(status) && WEXITSTATUS(status)) bb_error_msg_and_die("'%s' returned status %d", archive_handle->tar__to_command, WEXITSTATUS(status)); if (WIFSIGNALED(status)) - bb_error_msg_and_die("'%s' terminated on signal %d", + bb_error_msg_and_die("'%s' terminated by signal %d", archive_handle->tar__to_command, WTERMSIG(status)); if (!BB_MMU) { diff --git a/archival/libarchive/decompress_bunzip2.c b/archival/libarchive/decompress_bunzip2.c index 0e3ab43..fe5953d 100644 --- a/archival/libarchive/decompress_bunzip2.c +++ b/archival/libarchive/decompress_bunzip2.c @@ -159,7 +159,7 @@ static int get_next_block(bunzip_data *bd) struct group_data *hufGroup; int dbufCount, dbufSize, groupCount, *base, *limit, selector, i, j, t, runPos, symCount, symTotal, nSelectors, byteCount[256]; - int runCnt = 0; + int runCnt = runCnt; /* for compiler */ uint8_t uc, symToByte[256], mtfSymbol[256], *selectors; uint32_t *dbuf; unsigned origPtr; @@ -731,7 +731,7 @@ void FAST_FUNC dealloc_bunzip(bunzip_data *bd) /* Decompress src_fd to dst_fd. Stops at end of bzip data, not end of file. */ IF_DESKTOP(long long) int FAST_FUNC -unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) +unpack_bz2_stream(transformer_state_t *xstate) { IF_DESKTOP(long long total_written = 0;) bunzip_data *bd; @@ -739,14 +739,14 @@ unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) int i; unsigned len; - if (check_signature16(aux, src_fd, BZIP2_MAGIC)) + if (check_signature16(xstate, BZIP2_MAGIC)) return -1; outbuf = xmalloc(IOBUF_SIZE); len = 0; while (1) { /* "Process one BZ... stream" loop */ - i = start_bunzip(&bd, src_fd, outbuf + 2, len); + i = start_bunzip(&bd, xstate->src_fd, outbuf + 2, len); if (i == 0) { while (1) { /* "Produce some output bytes" loop */ @@ -756,8 +756,7 @@ unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) i = IOBUF_SIZE - i; /* number of bytes produced */ if (i == 0) /* EOF? */ break; - if (i != full_write(dst_fd, outbuf, i)) { - bb_error_msg("short write"); + if (i != transformer_write(xstate, outbuf, i)) { i = RETVAL_SHORT_WRITE; goto release_mem; } @@ -790,7 +789,7 @@ unpack_bz2_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) len = bd->inbufCount - bd->inbufPos; memcpy(outbuf, &bd->inbuf[bd->inbufPos], len); if (len < 2) { - if (safe_read(src_fd, outbuf + len, 2 - len) != (int)(2 - len)) + if (safe_read(xstate->src_fd, outbuf + len, 2 - len) != 2 - len) break; len = 2; } diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index d27f428..b1d4989 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c @@ -305,11 +305,11 @@ static int huft_build(const unsigned *b, const unsigned n, unsigned i; /* counter, current code */ unsigned j; /* counter */ int k; /* number of bits in current code */ - unsigned *p; /* pointer into c[], b[], or v[] */ + const unsigned *p; /* pointer into c[], b[], or v[] */ huft_t *q; /* points to current table */ huft_t r; /* table entry for structure assignment */ huft_t *u[BMAX]; /* table stack */ - unsigned v[N_MAX]; /* values in order of bit length */ + unsigned v[N_MAX + 1]; /* values in order of bit length. last v[] is never used */ int ws[BMAX + 1]; /* bits decoded stack */ int w; /* bits decoded */ unsigned x[BMAX + 1]; /* bit offsets, then code stack */ @@ -324,7 +324,7 @@ static int huft_build(const unsigned *b, const unsigned n, /* Generate counts for each bit length */ memset(c, 0, sizeof(c)); - p = (unsigned *) b; /* cast allows us to reuse p for pointing to b */ + p = b; i = n; do { c[*p]++; /* assume all entries <= BMAX */ @@ -364,8 +364,12 @@ static int huft_build(const unsigned *b, const unsigned n, *xp++ = j; } - /* Make a table of values in order of bit lengths */ - p = (unsigned *) b; + /* Make a table of values in order of bit lengths. + * To detect bad input, unused v[i]'s are set to invalid value UINT_MAX. + * In particular, last v[i] is never filled and must not be accessed. + */ + memset(v, 0xff, sizeof(v)); + p = b; i = 0; do { j = *p++; @@ -432,7 +436,9 @@ static int huft_build(const unsigned *b, const unsigned n, /* set up table entry in r */ r.b = (unsigned char) (k - w); - if (p >= v + n) { + if (/*p >= v + n || -- redundant, caught by the second check: */ + *p == UINT_MAX /* do we access uninited v[i]? (see memset(v))*/ + ) { r.e = 99; /* out of values--invalid code */ } else if (*p < s) { r.e = (unsigned char) (*p < 256 ? 16 : 15); /* 256 is EOB code */ @@ -517,8 +523,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY) e = t->e; if (e > 16) do { - if (e == 99) - abort_unzip(PASS_STATE_ONLY);; + if (e == 99) { + abort_unzip(PASS_STATE_ONLY); + } bb >>= t->b; k -= t->b; e -= 16; @@ -554,8 +561,9 @@ static NOINLINE int inflate_codes(STATE_PARAM_ONLY) e = t->e; if (e > 16) do { - if (e == 99) + if (e == 99) { abort_unzip(PASS_STATE_ONLY); + } bb >>= t->b; k -= t->b; e -= 16; @@ -821,8 +829,9 @@ static int inflate_block(STATE_PARAM smallint *e) b_dynamic >>= 4; k_dynamic -= 4; - if (nl > 286 || nd > 30) + if (nl > 286 || nd > 30) { abort_unzip(PASS_STATE_ONLY); /* bad lengths */ + } /* read in bit-length-code lengths */ for (j = 0; j < nb; j++) { @@ -903,12 +912,14 @@ static int inflate_block(STATE_PARAM smallint *e) bl = lbits; i = huft_build(ll, nl, 257, cplens, cplext, &inflate_codes_tl, &bl); - if (i != 0) + if (i != 0) { abort_unzip(PASS_STATE_ONLY); + } bd = dbits; i = huft_build(ll + nl, nd, 0, cpdist, cpdext, &inflate_codes_td, &bd); - if (i != 0) + if (i != 0) { abort_unzip(PASS_STATE_ONLY); + } /* set up data for inflate_codes() */ inflate_codes_setup(PASS_STATE bl, bd); @@ -971,7 +982,7 @@ static int inflate_get_next_window(STATE_PARAM_ONLY) /* Called from unpack_gz_stream() and inflate_unzip() */ static IF_DESKTOP(long long) int -inflate_unzip_internal(STATE_PARAM int in, int out) +inflate_unzip_internal(STATE_PARAM transformer_state_t *xstate) { IF_DESKTOP(long long) int n = 0; ssize_t nwrote; @@ -980,7 +991,7 @@ inflate_unzip_internal(STATE_PARAM int in, int out) gunzip_window = xmalloc(GUNZIP_WSIZE); gunzip_outbuf_count = 0; gunzip_bytes_out = 0; - gunzip_src_fd = in; + gunzip_src_fd = xstate->src_fd; /* (re) initialize state */ method = -1; @@ -1002,9 +1013,8 @@ inflate_unzip_internal(STATE_PARAM int in, int out) while (1) { int r = inflate_get_next_window(PASS_STATE_ONLY); - nwrote = full_write(out, gunzip_window, gunzip_outbuf_count); - if (nwrote != (ssize_t)gunzip_outbuf_count) { - bb_perror_msg("write"); + nwrote = transformer_write(xstate, gunzip_window, gunzip_outbuf_count); + if (nwrote == (ssize_t)-1) { n = -1; goto ret; } @@ -1034,22 +1044,22 @@ inflate_unzip_internal(STATE_PARAM int in, int out) /* For unzip */ IF_DESKTOP(long long) int FAST_FUNC -inflate_unzip(transformer_aux_data_t *aux, int in, int out) +inflate_unzip(transformer_state_t *xstate) { IF_DESKTOP(long long) int n; DECLARE_STATE; ALLOC_STATE; - to_read = aux->bytes_in; + to_read = xstate->bytes_in; // bytebuffer_max = 0x8000; bytebuffer_offset = 4; bytebuffer = xmalloc(bytebuffer_max); - n = inflate_unzip_internal(PASS_STATE in, out); + n = inflate_unzip_internal(PASS_STATE xstate); free(bytebuffer); - aux->crc32 = gunzip_crc; - aux->bytes_out = gunzip_bytes_out; + xstate->crc32 = gunzip_crc; + xstate->bytes_out = gunzip_bytes_out; DEALLOC_STATE; return n; } @@ -1107,7 +1117,7 @@ static uint32_t buffer_read_le_u32(STATE_PARAM_ONLY) return res; } -static int check_header_gzip(STATE_PARAM transformer_aux_data_t *aux) +static int check_header_gzip(STATE_PARAM transformer_state_t *xstate) { union { unsigned char raw[8]; @@ -1119,9 +1129,8 @@ static int check_header_gzip(STATE_PARAM transformer_aux_data_t *aux) uint8_t os_flags_UNUSED; } PACKED formatted; } header; - struct BUG_header { - char BUG_header[sizeof(header) == 8 ? 1 : -1]; - }; + + BUILD_BUG_ON(sizeof(header) != 8); /* * Rewind bytebuffer. We use the beginning because the header has 8 @@ -1169,8 +1178,7 @@ static int check_header_gzip(STATE_PARAM transformer_aux_data_t *aux) } } - if (aux) - aux->mtime = SWAP_LE32(header.formatted.mtime); + xstate->mtime = SWAP_LE32(header.formatted.mtime); /* Read the header checksum */ if (header.formatted.flags & 0x02) { @@ -1182,27 +1190,27 @@ static int check_header_gzip(STATE_PARAM transformer_aux_data_t *aux) } IF_DESKTOP(long long) int FAST_FUNC -unpack_gz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) +unpack_gz_stream(transformer_state_t *xstate) { uint32_t v32; IF_DESKTOP(long long) int total, n; DECLARE_STATE; #if !ENABLE_FEATURE_SEAMLESS_Z - if (check_signature16(aux, src_fd, GZIP_MAGIC)) + if (check_signature16(xstate, GZIP_MAGIC)) return -1; #else - if (aux && aux->check_signature) { + if (!xstate->signature_skipped) { uint16_t magic2; - if (full_read(src_fd, &magic2, 2) != 2) { + if (full_read(xstate->src_fd, &magic2, 2) != 2) { bad_magic: bb_error_msg("invalid magic"); return -1; } if (magic2 == COMPRESS_MAGIC) { - aux->check_signature = 0; - return unpack_Z_stream(aux, src_fd, dst_fd); + xstate->signature_skipped = 2; + return unpack_Z_stream(xstate); } if (magic2 != GZIP_MAGIC) goto bad_magic; @@ -1215,16 +1223,16 @@ unpack_gz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) to_read = -1; // bytebuffer_max = 0x8000; bytebuffer = xmalloc(bytebuffer_max); - gunzip_src_fd = src_fd; + gunzip_src_fd = xstate->src_fd; again: - if (!check_header_gzip(PASS_STATE aux)) { + if (!check_header_gzip(PASS_STATE xstate)) { bb_error_msg("corrupted data"); total = -1; goto ret; } - n = inflate_unzip_internal(PASS_STATE src_fd, dst_fd); + n = inflate_unzip_internal(PASS_STATE xstate); if (n < 0) { total = -1; goto ret; diff --git a/archival/libarchive/decompress_uncompress.c b/archival/libarchive/decompress_uncompress.c index 53c2708..034ed50 100644 --- a/archival/libarchive/decompress_uncompress.c +++ b/archival/libarchive/decompress_uncompress.c @@ -73,7 +73,7 @@ */ IF_DESKTOP(long long) int FAST_FUNC -unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) +unpack_Z_stream(transformer_state_t *xstate) { IF_DESKTOP(long long total_written = 0;) IF_DESKTOP(long long) int retval = -1; @@ -102,7 +102,7 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) /* block compress mode -C compatible with 2.0 */ int block_mode; /* = BLOCK_MODE; */ - if (check_signature16(aux, src_fd, COMPRESS_MAGIC)) + if (check_signature16(xstate, COMPRESS_MAGIC)) return -1; inbuf = xzalloc(IBUFSIZ + 64); @@ -114,7 +114,7 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) /* xread isn't good here, we have to return - caller may want * to do some cleanup (e.g. delete incomplete unpacked file etc) */ - if (full_read(src_fd, inbuf, 1) != 1) { + if (full_read(xstate->src_fd, inbuf, 1) != 1) { bb_error_msg("short read"); goto err; } @@ -166,7 +166,7 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) } if (insize < (int) (IBUFSIZ + 64) - IBUFSIZ) { - rsize = safe_read(src_fd, inbuf + insize, IBUFSIZ); + rsize = safe_read(xstate->src_fd, inbuf + insize, IBUFSIZ); if (rsize < 0) bb_error_msg_and_die(bb_msg_read_error); insize += rsize; @@ -274,7 +274,7 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) } if (outpos >= OBUFSIZ) { - xwrite(dst_fd, outbuf, outpos); + xtransformer_write(xstate, outbuf, outpos); IF_DESKTOP(total_written += outpos;) outpos = 0; } @@ -297,11 +297,10 @@ unpack_Z_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) /* Remember previous code. */ oldcode = incode; } - } while (rsize > 0); if (outpos > 0) { - xwrite(dst_fd, outbuf, outpos); + xtransformer_write(xstate, outbuf, outpos); IF_DESKTOP(total_written += outpos;) } diff --git a/archival/libarchive/decompress_unlzma.c b/archival/libarchive/decompress_unlzma.c index ca32bd8..c8622f9 100644 --- a/archival/libarchive/decompress_unlzma.c +++ b/archival/libarchive/decompress_unlzma.c @@ -206,7 +206,7 @@ enum { IF_DESKTOP(long long) int FAST_FUNC -unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst_fd) +unpack_lzma_stream(transformer_state_t *xstate) { IF_DESKTOP(long long total_written = 0;) lzma_header_t header; @@ -214,8 +214,6 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst uint32_t pos_state_mask; uint32_t literal_pos_mask; uint16_t *p; - int num_bits; - int num_probs; rc_t *rc; int i; uint8_t *buffer; @@ -225,7 +223,7 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst int state = 0; uint32_t rep0 = 1, rep1 = 1, rep2 = 1, rep3 = 1; - if (full_read(src_fd, &header, sizeof(header)) != sizeof(header) + if (full_read(xstate->src_fd, &header, sizeof(header)) != sizeof(header) || header.pos >= (9 * 5 * 5) ) { bb_error_msg("bad lzma header"); @@ -239,6 +237,9 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst pos_state_mask = (1 << pb) - 1; literal_pos_mask = (1 << lp) - 1; + /* Example values from linux-3.3.4.tar.lzma: + * dict_size: 64M, dst_size: 2^64-1 + */ header.dict_size = SWAP_LE32(header.dict_size); header.dst_size = SWAP_LE64(header.dst_size); @@ -247,13 +248,17 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst buffer = xmalloc(MIN(header.dst_size, header.dict_size)); - num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); - p = xmalloc(num_probs * sizeof(*p)); - num_probs += LZMA_LITERAL - LZMA_BASE_SIZE; - for (i = 0; i < num_probs; i++) - p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; + { + int num_probs; + + num_probs = LZMA_BASE_SIZE + (LZMA_LIT_SIZE << (lc + lp)); + p = xmalloc(num_probs * sizeof(*p)); + num_probs += LZMA_LITERAL - LZMA_BASE_SIZE; + for (i = 0; i < num_probs; i++) + p[i] = (1 << RC_MODEL_TOTAL_BITS) >> 1; + } - rc = rc_init(src_fd); /*, RC_BUFFER_SIZE); */ + rc = rc_init(xstate->src_fd); /*, RC_BUFFER_SIZE); */ while (global_pos + buffer_pos < header.dst_size) { int pos_state = (buffer_pos + global_pos) & pos_state_mask; @@ -301,7 +306,7 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst if (buffer_pos == header.dict_size) { buffer_pos = 0; global_pos += header.dict_size; - if (full_write(dst_fd, buffer, header.dict_size) != (ssize_t)header.dict_size) + if (transformer_write(xstate, buffer, header.dict_size) != (ssize_t)header.dict_size) goto bad; IF_DESKTOP(total_written += header.dict_size;) } @@ -310,6 +315,7 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst goto one_byte2; #endif } else { + int num_bits; int offset; uint16_t *prob2; #define prob_len prob2 @@ -434,19 +440,22 @@ unpack_lzma_stream(transformer_aux_data_t *aux UNUSED_PARAM, int src_fd, int dst if (buffer_pos == header.dict_size) { buffer_pos = 0; global_pos += header.dict_size; - if (full_write(dst_fd, buffer, header.dict_size) != (ssize_t)header.dict_size) + if (transformer_write(xstate, buffer, header.dict_size) != (ssize_t)header.dict_size) goto bad; IF_DESKTOP(total_written += header.dict_size;) } len--; } while (len != 0 && buffer_pos < header.dst_size); + /* FIXME: ...........^^^^^ + * shouldn't it be "global_pos + buffer_pos < header.dst_size"? + */ } } { IF_NOT_DESKTOP(int total_written = 0; /* success */) IF_DESKTOP(total_written += buffer_pos;) - if (full_write(dst_fd, buffer, buffer_pos) != (ssize_t)buffer_pos) { + if (transformer_write(xstate, buffer, buffer_pos) != (ssize_t)buffer_pos) { bad: total_written = -1; /* failure */ } diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c index 986b7b1..cd32cc7 100644 --- a/archival/libarchive/decompress_unxz.c +++ b/archival/libarchive/decompress_unxz.c @@ -38,7 +38,7 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) #include "unxz/xz_dec_stream.c" IF_DESKTOP(long long) int FAST_FUNC -unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) +unpack_xz_stream(transformer_state_t *xstate) { enum xz_ret xz_result; struct xz_buf iobuf; @@ -55,7 +55,7 @@ unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) iobuf.out = membuf + BUFSIZ; iobuf.out_size = BUFSIZ; - if (!aux || aux->check_signature == 0) { + if (!xstate || xstate->signature_skipped) { /* Preload XZ file signature */ strcpy((char*)membuf, HEADER_MAGIC); iobuf.in_size = HEADER_MAGIC_SIZE; @@ -67,7 +67,7 @@ unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) xz_result = X_OK; while (1) { if (iobuf.in_pos == iobuf.in_size) { - int rd = safe_read(src_fd, membuf, BUFSIZ); + int rd = safe_read(xstate->src_fd, membuf, BUFSIZ); if (rd < 0) { bb_error_msg(bb_msg_read_error); total = -1; @@ -104,7 +104,7 @@ unpack_xz_stream(transformer_aux_data_t *aux, int src_fd, int dst_fd) // bb_error_msg("dpkg__action_data_subarchive = get_header_tar; + return EXIT_SUCCESS; + } if (ENABLE_FEATURE_SEAMLESS_GZ && strcmp(name_ptr, "gz") == 0 ) { @@ -46,6 +50,12 @@ char FAST_FUNC filter_accept_list_reassign(archive_handle_t *archive_handle) archive_handle->dpkg__action_data_subarchive = get_header_tar_lzma; return EXIT_SUCCESS; } + if (ENABLE_FEATURE_SEAMLESS_XZ + && strcmp(name_ptr, "xz") == 0 + ) { + archive_handle->dpkg__action_data_subarchive = get_header_tar_xz; + return EXIT_SUCCESS; + } } return EXIT_FAILURE; } diff --git a/archival/libarchive/get_header_cpio.c b/archival/libarchive/get_header_cpio.c index 1a0058b..badd4a8 100644 --- a/archival/libarchive/get_header_cpio.c +++ b/archival/libarchive/get_header_cpio.c @@ -37,7 +37,7 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) } archive_handle->offset += 110; - if (strncmp(&cpio_header[0], "07070", 5) != 0 + if (!is_prefixed_with(&cpio_header[0], "07070") || (cpio_header[5] != '1' && cpio_header[5] != '2') ) { bb_error_msg_and_die("unsupported cpio format, use newc or crc"); @@ -52,6 +52,11 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) &major, &minor, &namesize) != 10) bb_error_msg_and_die("damaged cpio file"); file_header->mode = mode; + /* "cpio -R USER:GRP" support: */ + if (archive_handle->cpio__owner.uid != (uid_t)-1L) + uid = archive_handle->cpio__owner.uid; + if (archive_handle->cpio__owner.gid != (gid_t)-1L) + gid = archive_handle->cpio__owner.gid; file_header->uid = uid; file_header->gid = gid; file_header->mtime = mtime; @@ -75,7 +80,7 @@ char FAST_FUNC get_header_cpio(archive_handle_t *archive_handle) /* Update offset amount and skip padding before file contents */ data_align(archive_handle, 4); - if (strcmp(file_header->name, "TRAILER!!!") == 0) { + if (strcmp(file_header->name, cpio_TRAILER) == 0) { /* Always round up. ">> 9" divides by 512 */ archive_handle->cpio__blocks = (uoff_t)(archive_handle->offset + 511) >> 9; goto create_hardlinks; diff --git a/archival/libarchive/get_header_tar.c b/archival/libarchive/get_header_tar.c index 278c8fb..c7e3bc1 100644 --- a/archival/libarchive/get_header_tar.c +++ b/archival/libarchive/get_header_tar.c @@ -17,36 +17,6 @@ typedef uint32_t aliased_uint32_t FIX_ALIASING; typedef off_t aliased_off_t FIX_ALIASING; - -const char* FAST_FUNC strip_unsafe_prefix(const char *str) -{ - const char *cp = str; - while (1) { - char *cp2; - if (*cp == '/') { - cp++; - continue; - } - if (strncmp(cp, "/../"+1, 3) == 0) { - cp += 3; - continue; - } - cp2 = strstr(cp, "/../"); - if (!cp2) - break; - cp = cp2 + 4; - } - if (cp != str) { - static smallint warned = 0; - if (!warned) { - warned = 1; - bb_error_msg("removing leading '%.*s' from member names", - (int)(cp - str), str); - } - } - return cp; -} - /* NB: _DESTROYS_ str[len] character! */ static unsigned long long getOctal(char *str, int len) { @@ -90,13 +60,21 @@ static unsigned long long getOctal(char *str, int len) } #define GET_OCTAL(a) getOctal((a), sizeof(a)) +#define TAR_EXTD (ENABLE_FEATURE_TAR_GNU_EXTENSIONS || ENABLE_FEATURE_TAR_SELINUX) +#if !TAR_EXTD +#define process_pax_hdr(archive_handle, sz, global) \ + process_pax_hdr(archive_handle, sz) +#endif /* "global" is 0 or 1 */ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int global) { +#if !TAR_EXTD + unsigned blk_sz = (sz + 511) & (~511); + seek_by_read(archive_handle->src_fd, blk_sz); +#else + unsigned blk_sz = (sz + 511) & (~511); char *buf, *p; - unsigned blk_sz; - blk_sz = (sz + 511) & (~511); p = buf = xmalloc(blk_sz + 1); xread(archive_handle->src_fd, buf, blk_sz); archive_handle->offset += blk_sz; @@ -115,7 +93,9 @@ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int g */ p += len; sz -= len; - if ((int)sz < 0 + if ( + /** (int)sz < 0 - not good enough for huge malicious VALUE of 2^32-1 */ + (int)(sz|len) < 0 /* this works */ || len == 0 || errno != EINVAL || *end != ' ' @@ -132,30 +112,39 @@ static void process_pax_hdr(archive_handle_t *archive_handle, unsigned sz, int g p[-1] = '\0'; value = end + 1; -#if ENABLE_FEATURE_TAR_GNU_EXTENSIONS - if (!global && strncmp(value, "path=", sizeof("path=") - 1) == 0) { - value += sizeof("path=") - 1; - free(archive_handle->tar__longname); - archive_handle->tar__longname = xstrdup(value); - continue; +# if ENABLE_FEATURE_TAR_GNU_EXTENSIONS + if (!global) { + if (is_prefixed_with(value, "path=")) { + value += sizeof("path=") - 1; + free(archive_handle->tar__longname); + archive_handle->tar__longname = xstrdup(value); + continue; + } + if (is_prefixed_with(value, "linkpath=")) { + value += sizeof("linkpath=") - 1; + free(archive_handle->tar__linkname); + archive_handle->tar__linkname = xstrdup(value); + continue; + } } -#endif +# endif -#if ENABLE_FEATURE_TAR_SELINUX +# if ENABLE_FEATURE_TAR_SELINUX /* Scan for SELinux contexts, via "RHT.security.selinux" keyword. * This is what Red Hat's patched version of tar uses. */ -# define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux" - if (strncmp(value, SELINUX_CONTEXT_KEYWORD"=", sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1) == 0) { +# define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux" + if (is_prefixed_with(value, SELINUX_CONTEXT_KEYWORD"=")) { value += sizeof(SELINUX_CONTEXT_KEYWORD"=") - 1; free(archive_handle->tar__sctx[global]); archive_handle->tar__sctx[global] = xstrdup(value); continue; } -#endif +# endif } free(buf); +#endif } char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) @@ -198,7 +187,13 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) * the message and we don't check whether we indeed * saw zero block directly before this. */ if (i == 0) { - bb_error_msg("short read"); + /* GNU tar 1.29 will be silent if tar archive ends abruptly + * (if there are no zero blocks at all, and last read returns zero, + * not short read 0 < len < 512). Complain only if + * the very first read fails. Grrr. + */ + if (archive_handle->offset == 0) + bb_error_msg("short read"); /* this merely signals end of archive, not exit(1): */ return EXIT_FAILURE; } @@ -214,7 +209,11 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) archive_handle->offset += i; /* If there is no filename its an empty header */ - if (tar.name[0] == 0 && tar.prefix[0] == 0) { + if (tar.name[0] == 0 && tar.prefix[0] == 0 + /* Have seen a tar archive with pax 'x' header supplying UTF8 filename, + * with actual file having all name fields NUL-filled. Check this: */ + && !p_longname + ) { if (archive_handle->tar__end) { /* Second consecutive empty header - end of archive. * Read until the end to empty the pipe from gz or bz2 @@ -230,7 +229,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) /* Check header has valid magic, "ustar" is for the proper tar, * five NULs are for the old tar format */ - if (strncmp(tar.magic, "ustar", 5) != 0 + if (!is_prefixed_with(tar.magic, "ustar") && (!ENABLE_FEATURE_TAR_OLDGNU_COMPATIBILITY || memcmp(tar.magic, "\0\0\0\0", 5) != 0) ) { @@ -378,7 +377,14 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) case '6': file_header->mode |= S_IFIFO; goto size0; + case 'g': /* pax global header */ + case 'x': { /* pax extended header */ + if ((uoff_t)file_header->size > 0xfffff) /* paranoia */ + goto skip_ext_hdr; + process_pax_hdr(archive_handle, file_header->size, (tar.typeflag == 'g')); + goto again_after_align; #if ENABLE_FEATURE_TAR_GNU_EXTENSIONS +/* See http://www.gnu.org/software/tar/manual/html_node/Extensions.html */ case 'L': /* free: paranoia: tar with several consecutive longnames */ free(p_longname); @@ -398,18 +404,17 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) archive_handle->offset += file_header->size; /* return get_header_tar(archive_handle); */ goto again; - case 'D': /* GNU dump dir */ - case 'M': /* Continuation of multi volume archive */ - case 'N': /* Old GNU for names > 100 characters */ - case 'S': /* Sparse file */ - case 'V': /* Volume header */ +/* + * case 'S': // Sparse file + * Was seen in the wild. Not supported (yet?). + * See https://www.gnu.org/software/tar/manual/html_section/tar_92.html + * for the format. (An "Old GNU Format" was seen, not PAX formats). + */ +// case 'D': /* GNU dump dir */ +// case 'M': /* Continuation of multi volume archive */ +// case 'N': /* Old GNU for names > 100 characters */ +// case 'V': /* Volume header */ #endif - case 'g': /* pax global header */ - case 'x': { /* pax extended header */ - if ((uoff_t)file_header->size > 0xfffff) /* paranoia */ - goto skip_ext_hdr; - process_pax_hdr(archive_handle, file_header->size, (tar.typeflag == 'g')); - goto again_after_align; } skip_ext_hdr: { @@ -440,6 +445,7 @@ char FAST_FUNC get_header_tar(archive_handle_t *archive_handle) /* Everything up to and including last ".." component is stripped */ overlapping_strcpy(file_header->name, strip_unsafe_prefix(file_header->name)); +//TODO: do the same for file_header->link_target? /* Strip trailing '/' in directories */ /* Must be done after mode is set as '/' is used to check if it's a directory */ diff --git a/archival/libarchive/get_header_tar_bz2.c b/archival/libarchive/get_header_tar_bz2.c index 0ee00df..78f78a8 100644 --- a/archival/libarchive/get_header_tar_bz2.c +++ b/archival/libarchive/get_header_tar_bz2.c @@ -11,7 +11,7 @@ char FAST_FUNC get_header_tar_bz2(archive_handle_t *archive_handle) /* Can't lseek over pipes */ archive_handle->seek = seek_by_read; - open_transformer_with_sig(archive_handle->src_fd, unpack_bz2_stream, "bunzip2"); + fork_transformer_with_sig(archive_handle->src_fd, unpack_bz2_stream, "bunzip2"); archive_handle->offset = 0; while (get_header_tar(archive_handle) == EXIT_SUCCESS) continue; diff --git a/archival/libarchive/get_header_tar_gz.c b/archival/libarchive/get_header_tar_gz.c index 0328434..b11f503 100644 --- a/archival/libarchive/get_header_tar_gz.c +++ b/archival/libarchive/get_header_tar_gz.c @@ -11,7 +11,7 @@ char FAST_FUNC get_header_tar_gz(archive_handle_t *archive_handle) /* Can't lseek over pipes */ archive_handle->seek = seek_by_read; - open_transformer_with_sig(archive_handle->src_fd, unpack_gz_stream, "gunzip"); + fork_transformer_with_sig(archive_handle->src_fd, unpack_gz_stream, "gunzip"); archive_handle->offset = 0; while (get_header_tar(archive_handle) == EXIT_SUCCESS) continue; diff --git a/archival/libarchive/get_header_tar_lzma.c b/archival/libarchive/get_header_tar_lzma.c index d565a21..d228cbc 100644 --- a/archival/libarchive/get_header_tar_lzma.c +++ b/archival/libarchive/get_header_tar_lzma.c @@ -14,7 +14,7 @@ char FAST_FUNC get_header_tar_lzma(archive_handle_t *archive_handle) /* Can't lseek over pipes */ archive_handle->seek = seek_by_read; - open_transformer_with_sig(archive_handle->src_fd, unpack_lzma_stream, "unlzma"); + fork_transformer_with_sig(archive_handle->src_fd, unpack_lzma_stream, "unlzma"); archive_handle->offset = 0; while (get_header_tar(archive_handle) == EXIT_SUCCESS) continue; diff --git a/archival/libarchive/get_header_tar_xz.c b/archival/libarchive/get_header_tar_xz.c new file mode 100644 index 0000000..7bf3b3b --- a/dev/null +++ b/archival/libarchive/get_header_tar_xz.c @@ -0,0 +1,21 @@ +/* vi: set sw=4 ts=4: */ +/* + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +#include "libbb.h" +#include "bb_archive.h" + +char FAST_FUNC get_header_tar_xz(archive_handle_t *archive_handle) +{ + /* Can't lseek over pipes */ + archive_handle->seek = seek_by_read; + + fork_transformer_with_sig(archive_handle->src_fd, unpack_xz_stream, "unxz"); + archive_handle->offset = 0; + while (get_header_tar(archive_handle) == EXIT_SUCCESS) + continue; + + /* Can only do one file at a time */ + return EXIT_FAILURE; +} diff --git a/archival/libarchive/init_handle.c b/archival/libarchive/init_handle.c index cbae06a..dcba666 100644 --- a/archival/libarchive/init_handle.c +++ b/archival/libarchive/init_handle.c @@ -17,6 +17,10 @@ archive_handle_t* FAST_FUNC init_handle(void) archive_handle->action_data = data_skip; archive_handle->filter = filter_accept_all; archive_handle->seek = seek_by_jump; +#if ENABLE_CPIO || ENABLE_RPM2CPIO || ENABLE_RPM + archive_handle->cpio__owner.uid = (uid_t)-1L; + archive_handle->cpio__owner.gid = (gid_t)-1L; +#endif return archive_handle; } diff --git a/archival/libarchive/lzo1x_9x.c b/archival/libarchive/lzo1x_9x.c index 2b490ae..09ee4ba 100644 --- a/archival/libarchive/lzo1x_9x.c +++ b/archival/libarchive/lzo1x_9x.c @@ -71,7 +71,6 @@ typedef struct { uint8_t *out; unsigned r1_lit; - } lzo1x_999_t; #define getbyte(c) ((c).ip < (c).in_end ? *((c).ip)++ : (-1)) diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index 1986630..ac7e5db 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c @@ -6,27 +6,65 @@ #include "libbb.h" #include "bb_archive.h" -void FAST_FUNC init_transformer_aux_data(transformer_aux_data_t *aux) +void FAST_FUNC init_transformer_state(transformer_state_t *xstate) { - memset(aux, 0, sizeof(*aux)); + memset(xstate, 0, sizeof(*xstate)); } -int FAST_FUNC check_signature16(transformer_aux_data_t *aux, int src_fd, unsigned magic16) +int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16) { - if (aux && aux->check_signature) { + if (!xstate->signature_skipped) { uint16_t magic2; - if (full_read(src_fd, &magic2, 2) != 2 || magic2 != magic16) { + if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) { bb_error_msg("invalid magic"); -#if 0 /* possible future extension */ - if (aux->check_signature > 1) - xfunc_die(); -#endif return -1; } + xstate->signature_skipped = 2; } return 0; } +ssize_t FAST_FUNC transformer_write(transformer_state_t *xstate, const void *buf, size_t bufsize) +{ + ssize_t nwrote; + + if (xstate->mem_output_size_max != 0) { + size_t pos = xstate->mem_output_size; + size_t size; + + size = (xstate->mem_output_size += bufsize); + if (size > xstate->mem_output_size_max) { + free(xstate->mem_output_buf); + xstate->mem_output_buf = NULL; + bb_perror_msg("buffer %u too small", (unsigned)xstate->mem_output_size_max); + nwrote = -1; + goto ret; + } + xstate->mem_output_buf = xrealloc(xstate->mem_output_buf, size + 1); + memcpy(xstate->mem_output_buf + pos, buf, bufsize); + xstate->mem_output_buf[size] = '\0'; + nwrote = bufsize; + } else { + nwrote = full_write(xstate->dst_fd, buf, bufsize); + if (nwrote != (ssize_t)bufsize) { + bb_perror_msg("write"); + nwrote = -1; + goto ret; + } + } + ret: + return nwrote; +} + +ssize_t FAST_FUNC xtransformer_write(transformer_state_t *xstate, const void *buf, size_t bufsize) +{ + ssize_t nwrote = transformer_write(xstate, buf, bufsize); + if (nwrote != (ssize_t)bufsize) { + xfunc_die(); + } + return nwrote; +} + void check_errors_in_children(int signo) { int status; @@ -60,12 +98,12 @@ void check_errors_in_children(int signo) /* transformer(), more than meets the eye */ #if BB_MMU -void FAST_FUNC open_transformer(int fd, - int check_signature, - IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd) +void FAST_FUNC fork_transformer(int fd, + int signature_skipped, + IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate) ) #else -void FAST_FUNC open_transformer(int fd, const char *transform_prog) +void FAST_FUNC fork_transformer(int fd, const char *transform_prog) #endif { struct fd_pair fd_pipe; @@ -80,10 +118,12 @@ void FAST_FUNC open_transformer(int fd, const char *transform_prog) #if BB_MMU { IF_DESKTOP(long long) int r; - transformer_aux_data_t aux; - init_transformer_aux_data(&aux); - aux.check_signature = check_signature; - r = transformer(&aux, fd, fd_pipe.wr); + transformer_state_t xstate; + init_transformer_state(&xstate); + xstate.signature_skipped = signature_skipped; + xstate.src_fd = fd; + xstate.dst_fd = fd_pipe.wr; + r = transformer(&xstate); if (ENABLE_FEATURE_CLEAN_UP) { close(fd_pipe.wr); /* send EOF */ close(fd); @@ -118,16 +158,18 @@ void FAST_FUNC open_transformer(int fd, const char *transform_prog) /* Used by e.g. rpm which gives us a fd without filename, * thus we can't guess the format from filename's extension. */ -int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) +static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_compressed) { union { uint8_t b[4]; uint16_t b16[2]; uint32_t b32[1]; } magic; - int offset = -2; - USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) - USE_FOR_NOMMU(const char *xformer_prog;) + transformer_state_t *xstate; + + xstate = xzalloc(sizeof(*xstate)); + xstate->src_fd = fd; + xstate->signature_skipped = 2; /* .gz and .bz2 both have 2-byte signature, and their * unpack_XXX_stream wants this header skipped. */ @@ -135,25 +177,32 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) if (ENABLE_FEATURE_SEAMLESS_GZ && magic.b16[0] == GZIP_MAGIC ) { - USE_FOR_MMU(xformer = unpack_gz_stream;) - USE_FOR_NOMMU(xformer_prog = "gunzip";) + xstate->xformer = unpack_gz_stream; + USE_FOR_NOMMU(xstate->xformer_prog = "gunzip";) + goto found_magic; + } + if (ENABLE_FEATURE_SEAMLESS_Z + && magic.b16[0] == COMPRESS_MAGIC + ) { + xstate->xformer = unpack_Z_stream; + USE_FOR_NOMMU(xstate->xformer_prog = "uncompress";) goto found_magic; } if (ENABLE_FEATURE_SEAMLESS_BZ2 && magic.b16[0] == BZIP2_MAGIC ) { - USE_FOR_MMU(xformer = unpack_bz2_stream;) - USE_FOR_NOMMU(xformer_prog = "bunzip2";) + xstate->xformer = unpack_bz2_stream; + USE_FOR_NOMMU(xstate->xformer_prog = "bunzip2";) goto found_magic; } if (ENABLE_FEATURE_SEAMLESS_XZ && magic.b16[0] == XZ_MAGIC1 ) { - offset = -6; + xstate->signature_skipped = 6; xread(fd, magic.b32, sizeof(magic.b32[0])); if (magic.b32[0] == XZ_MAGIC2) { - USE_FOR_MMU(xformer = unpack_xz_stream;) - USE_FOR_NOMMU(xformer_prog = "unxz";) + xstate->xformer = unpack_xz_stream; + USE_FOR_NOMMU(xstate->xformer_prog = "unxz";) goto found_magic; } } @@ -164,52 +213,137 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) IF_FEATURE_SEAMLESS_BZ2("/bzip2") IF_FEATURE_SEAMLESS_XZ("/xz") " magic"); - xlseek(fd, offset, SEEK_CUR); - return 1; + + /* Some callers expect this function to "consume" fd + * even if data is not compressed. In this case, + * we return a state with trivial transformer. + */ +// USE_FOR_MMU(xstate->xformer = copy_stream;) +// USE_FOR_NOMMU(xstate->xformer_prog = "cat";) found_magic: + return xstate; +} + +/* Used by e.g. rpm which gives us a fd without filename, + * thus we can't guess the format from filename's extension. + */ +int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) +{ + transformer_state_t *xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); + + if (!xstate || !xstate->xformer) { + free(xstate); + return 1; + } + # if BB_MMU - open_transformer_with_no_sig(fd, xformer); + fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); # else - /* NOMMU version of open_transformer execs + /* NOMMU version of fork_transformer execs * an external unzipper that wants - * file position at the start of the file */ - xlseek(fd, offset, SEEK_CUR); - open_transformer_with_sig(fd, xformer, xformer_prog); + * file position at the start of the file. + */ + xlseek(fd, - xstate->signature_skipped, SEEK_CUR); + xstate->signature_skipped = 0; + fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); # endif + free(xstate); return 0; } -int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) +static transformer_state_t *open_transformer(const char *fname, int fail_if_not_compressed) { + transformer_state_t *xstate; int fd; fd = open(fname, O_RDONLY); if (fd < 0) - return fd; + return NULL; if (ENABLE_FEATURE_SEAMLESS_LZMA) { /* .lzma has no header/signature, can only detect it by extension */ char *sfx = strrchr(fname, '.'); if (sfx && strcmp(sfx+1, "lzma") == 0) { - open_transformer_with_sig(fd, unpack_lzma_stream, "unlzma"); - return fd; + xstate = xzalloc(sizeof(*xstate)); + xstate->src_fd = fd; + xstate->xformer = unpack_lzma_stream; + USE_FOR_NOMMU(xstate->xformer_prog = "unlzma";) + return xstate; } } - if ((ENABLE_FEATURE_SEAMLESS_GZ) - || (ENABLE_FEATURE_SEAMLESS_BZ2) - || (ENABLE_FEATURE_SEAMLESS_XZ) - ) { - setup_unzip_on_fd(fd, fail_if_not_compressed); + + xstate = setup_transformer_on_fd(fd, fail_if_not_compressed); + + return xstate; +} + +int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) +{ + int fd; + transformer_state_t *xstate; + + xstate = open_transformer(fname, fail_if_not_compressed); + if (!xstate) + return -1; + + fd = xstate->src_fd; +# if BB_MMU + if (xstate->xformer) { + fork_transformer_with_no_sig(fd, xstate->xformer); + } else { + /* the file is not compressed */ + xlseek(fd, - xstate->signature_skipped, SEEK_CUR); + xstate->signature_skipped = 0; } +# else + /* NOMMU can't avoid the seek :( */ + xlseek(fd, - xstate->signature_skipped, SEEK_CUR); + xstate->signature_skipped = 0; + if (xstate->xformer) { + fork_transformer_with_sig(fd, xstate->xformer, xstate->xformer_prog); + } /* else: the file is not compressed */ +# endif + free(xstate); return fd; } -#endif /* SEAMLESS_COMPRESSION */ - void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_p) { +# if 1 + transformer_state_t *xstate; + char *image; + + xstate = open_transformer(fname, /*fail_if_not_compressed:*/ 0); + if (!xstate) /* file open error */ + return NULL; + + image = NULL; + if (xstate->xformer) { + /* In-memory decompression */ + xstate->mem_output_size_max = maxsz_p ? *maxsz_p : (size_t)(INT_MAX - 4095); + xstate->xformer(xstate); + if (xstate->mem_output_buf) { + image = xstate->mem_output_buf; + if (maxsz_p) + *maxsz_p = xstate->mem_output_size; + } + } else { + /* File is not compressed */ +//FIXME: avoid seek + xlseek(xstate->src_fd, - xstate->signature_skipped, SEEK_CUR); + xstate->signature_skipped = 0; + image = xmalloc_read(xstate->src_fd, maxsz_p); + } + + if (!image) + bb_perror_msg("read error from '%s'", fname); + close(xstate->src_fd); + free(xstate); + return image; +# else + /* This version forks a subprocess - much more expensive */ int fd; char *image; @@ -221,6 +355,8 @@ void* FAST_FUNC xmalloc_open_zipped_read_close(const char *fname, size_t *maxsz_ if (!image) bb_perror_msg("read error from '%s'", fname); close(fd); - return image; +# endif } + +#endif /* SEAMLESS_COMPRESSION */ diff --git a/archival/libarchive/unpack_ar_archive.c b/archival/libarchive/unpack_ar_archive.c index 214d17e..0bc0303 100644 --- a/archival/libarchive/unpack_ar_archive.c +++ b/archival/libarchive/unpack_ar_archive.c @@ -12,7 +12,7 @@ void FAST_FUNC unpack_ar_archive(archive_handle_t *ar_archive) char magic[7]; xread(ar_archive->src_fd, magic, AR_MAGIC_LEN); - if (strncmp(magic, AR_MAGIC, AR_MAGIC_LEN) != 0) { + if (!is_prefixed_with(magic, AR_MAGIC)) { bb_error_msg_and_die("invalid ar magic"); } ar_archive->offset += AR_MAGIC_LEN; diff --git a/archival/libarchive/unsafe_prefix.c b/archival/libarchive/unsafe_prefix.c new file mode 100644 index 0000000..9994f4d --- a/dev/null +++ b/archival/libarchive/unsafe_prefix.c @@ -0,0 +1,36 @@ +/* vi: set sw=4 ts=4: */ +/* + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +#include "libbb.h" +#include "bb_archive.h" + +const char* FAST_FUNC strip_unsafe_prefix(const char *str) +{ + const char *cp = str; + while (1) { + char *cp2; + if (*cp == '/') { + cp++; + continue; + } + if (is_prefixed_with(cp, "/../"+1)) { + cp += 3; + continue; + } + cp2 = strstr(cp, "/../"); + if (!cp2) + break; + cp = cp2 + 4; + } + if (cp != str) { + static smallint warned = 0; + if (!warned) { + warned = 1; + bb_error_msg("removing leading '%.*s' from member names", + (int)(cp - str), str); + } + } + return cp; +} diff --git a/archival/libarchive/unxz/xz_dec_lzma2.c b/archival/libarchive/unxz/xz_dec_lzma2.c index 3c2dc88..351251f 100644 --- a/archival/libarchive/unxz/xz_dec_lzma2.c +++ b/archival/libarchive/unxz/xz_dec_lzma2.c @@ -995,10 +995,8 @@ XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run( s->lzma2.need_props = false; s->lzma2.next_sequence = SEQ_PROPERTIES; - } else if (s->lzma2.need_props) { return XZ_DATA_ERROR; - } else { s->lzma2.next_sequence = SEQ_LZMA_PREPARE; @@ -1080,7 +1078,6 @@ XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run( rc_reset(&s->rc); s->lzma2.sequence = SEQ_CONTROL; - } else if (b->out_pos == b->out_size || (b->in_pos == b->in_size && s->temp.size diff --git a/archival/libarchive/unxz/xz_dec_stream.c b/archival/libarchive/unxz/xz_dec_stream.c index bdcbf1b..bf79105 100644 --- a/archival/libarchive/unxz/xz_dec_stream.c +++ b/archival/libarchive/unxz/xz_dec_stream.c @@ -353,7 +353,6 @@ static enum xz_ret XZ_FUNC crc32_validate(struct xz_dec *s, struct xz_buf *b) return XZ_DATA_ERROR; s->pos += 8; - } while (s->pos < 32); s->crc32 = 0; @@ -753,7 +752,6 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b) b->in_pos = in_start; b->out_pos = out_start; } - } else if (ret == XZ_OK && in_start == b->in_pos && out_start == b->out_pos) { if (s->allow_buf_error) diff --git a/archival/lzop.c b/archival/lzop.c index 5062d93..e0e90ac 100644 --- a/archival/lzop.c +++ b/archival/lzop.c @@ -31,19 +31,33 @@ //config: help //config: Lzop compression/decompresion. //config: +//config:config UNLZOP +//config: bool "unlzop" +//config: default y +//config: help +//config: Lzop decompresion. +//config: +//config:config LZOPCAT +//config: bool "lzopcat" +//config: default y +//config: help +//config: Alias to "unlzop -c". +//config: //config:config LZOP_COMPR_HIGH //config: bool "lzop compression levels 7,8,9 (not very useful)" //config: default n -//config: depends on LZOP +//config: depends on LZOP || UNLZOP || LZOPCAT //config: help //config: High levels (7,8,9) of lzop compression. These levels //config: are actually slower than gzip at equivalent compression ratios //config: and take up 3.2K of code. //applet:IF_LZOP(APPLET(lzop, BB_DIR_BIN, BB_SUID_DROP)) -//applet:IF_LZOP(APPLET_ODDNAME(lzopcat, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, lzopcat)) -//applet:IF_LZOP(APPLET_ODDNAME(unlzop, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, unlzop)) +//applet:IF_UNLZOP(APPLET_ODDNAME(unlzop, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, unlzop)) +//applet:IF_LZOPCAT(APPLET_ODDNAME(lzopcat, lzop, BB_DIR_USR_BIN, BB_SUID_DROP, lzopcat)) //kbuild:lib-$(CONFIG_LZOP) += lzop.o +//kbuild:lib-$(CONFIG_UNLZOP) += lzop.o +//kbuild:lib-$(CONFIG_LZOPCAT) += lzop.o //usage:#define lzop_trivial_usage //usage: "[-cfvd123456789CF] [FILE]..." @@ -57,20 +71,21 @@ //usage: "\n -C Also write checksum of compressed block" //usage: //usage:#define lzopcat_trivial_usage -//usage: "[-vCF] [FILE]..." +//usage: "[-vF] [FILE]..." //usage:#define lzopcat_full_usage "\n\n" //usage: " -v Verbose" -//usage: "\n -F Don't store or verify checksum" +//usage: "\n -F Don't verify checksum" //usage: //usage:#define unlzop_trivial_usage -//usage: "[-cfvCF] [FILE]..." +//usage: "[-cfvF] [FILE]..." //usage:#define unlzop_full_usage "\n\n" //usage: " -c Write to stdout" //usage: "\n -f Force" //usage: "\n -v Verbose" -//usage: "\n -F Don't store or verify checksum" +//usage: "\n -F Don't verify checksum" #include "libbb.h" +#include "common_bufsiz.h" #include "bb_archive.h" #include "liblzo_interface.h" @@ -443,8 +458,8 @@ struct globals { chksum_t chksum_in; chksum_t chksum_out; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define G (*(struct globals*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) //#define G (*ptr_to_globals) //#define INIT_G() do { // SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); @@ -640,7 +655,7 @@ static int lzo_get_method(header_t *h) /**********************************************************************/ // compress a file /**********************************************************************/ -static NOINLINE smallint lzo_compress(const header_t *h) +static NOINLINE int lzo_compress(const header_t *h) { unsigned block_size = LZO_BLOCK_SIZE; int r = 0; /* LZO_E_OK */ @@ -650,7 +665,6 @@ static NOINLINE smallint lzo_compress(const header_t *h) uint32_t d_adler32 = ADLER32_INIT_VALUE; uint32_t d_crc32 = CRC32_INIT_VALUE; int l; - smallint ok = 1; uint8_t *wrk_mem = NULL; if (h->method == M_LZO1X_1) @@ -732,7 +746,7 @@ static NOINLINE smallint lzo_compress(const header_t *h) free(wrk_mem); free(b1); free(b2); - return ok; + return 1; } static FAST_FUNC void lzo_check( @@ -753,7 +767,7 @@ static FAST_FUNC void lzo_check( /**********************************************************************/ // decompress a file /**********************************************************************/ -static NOINLINE smallint lzo_decompress(const header_t *h) +static NOINLINE int lzo_decompress(const header_t *h) { unsigned block_size = LZO_BLOCK_SIZE; int r; @@ -761,7 +775,6 @@ static NOINLINE smallint lzo_decompress(const header_t *h) uint32_t c_adler32 = ADLER32_INIT_VALUE; uint32_t d_adler32 = ADLER32_INIT_VALUE; uint32_t c_crc32 = CRC32_INIT_VALUE, d_crc32 = CRC32_INIT_VALUE; - smallint ok = 1; uint8_t *b1; uint32_t mcs_block_size = MAX_COMPRESSED_SIZE(block_size); uint8_t *b2 = NULL; @@ -865,7 +878,7 @@ static NOINLINE smallint lzo_decompress(const header_t *h) } free(b2); - return ok; + return 1; } /**********************************************************************/ @@ -897,7 +910,7 @@ static NOINLINE smallint lzo_decompress(const header_t *h) * chksum_out * The rest is identical. */ -static const unsigned char lzop_magic[9] = { +static const unsigned char lzop_magic[9] ALIGN1 = { 0x89, 0x4c, 0x5a, 0x4f, 0x00, 0x0d, 0x0a, 0x1a, 0x0a }; @@ -1050,7 +1063,7 @@ static void lzo_set_method(header_t *h) h->level = level; } -static smallint do_lzo_compress(void) +static int do_lzo_compress(void) { header_t header; @@ -1078,7 +1091,7 @@ static smallint do_lzo_compress(void) /**********************************************************************/ // decompress /**********************************************************************/ -static smallint do_lzo_decompress(void) +static int do_lzo_decompress(void) { header_t header; @@ -1099,7 +1112,7 @@ static char* FAST_FUNC make_new_name_lzop(char *filename, const char *expected_e return xasprintf("%s.lzo", filename); } -static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(transformer_aux_data_t *aux UNUSED_PARAM) +static IF_DESKTOP(long long) int FAST_FUNC pack_lzop(transformer_state_t *xstate UNUSED_PARAM) { if (option_mask32 & OPT_DECOMPRESS) return do_lzo_decompress(); @@ -1112,10 +1125,10 @@ int lzop_main(int argc UNUSED_PARAM, char **argv) getopt32(argv, OPTION_STRING); argv += optind; /* lzopcat? */ - if (applet_name[4] == 'c') + if (ENABLE_LZOPCAT && applet_name[4] == 'c') option_mask32 |= (OPT_STDOUT | OPT_DECOMPRESS); /* unlzop? */ - if (applet_name[4] == 'o') + if (ENABLE_UNLZOP && applet_name[4] == 'o') option_mask32 |= OPT_DECOMPRESS; global_crc32_table = crc32_filltable(NULL, 0); diff --git a/archival/rpm.c b/archival/rpm.c index 1053944..83160f9 100644 --- a/archival/rpm.c +++ b/archival/rpm.c @@ -29,6 +29,7 @@ //usage: "\n -qpc List config files" #include "libbb.h" +#include "common_bufsiz.h" #include "bb_archive.h" #include "rpm.h" @@ -93,8 +94,8 @@ struct globals { rpm_index **mytags; int tagcount; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define G (*(struct globals*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void extract_cpio(int fd, const char *source_rpm) { diff --git a/archival/tar.c b/archival/tar.c index cdc6067..8e315c6 100644 --- a/archival/tar.c +++ b/archival/tar.c @@ -146,25 +146,23 @@ #include #include "libbb.h" +#include "common_bufsiz.h" #include "bb_archive.h" /* FIXME: Stop using this non-standard feature */ #ifndef FNM_LEADING_DIR # define FNM_LEADING_DIR 0 #endif - -//#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) -#define DBG(...) ((void)0) +#if 0 +# define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) +#else +# define DBG(...) ((void)0) +#endif +#define DBG_OPTION_PARSING 0 #define block_buf bb_common_bufsiz1 - - -#if !ENABLE_FEATURE_SEAMLESS_GZ && !ENABLE_FEATURE_SEAMLESS_BZ2 -/* Do not pass gzip flag to writeTarFile() */ -#define writeTarFile(tar_fd, verboseFlag, optFlags, recurseFlags, include, exclude, gzip) \ - writeTarFile(tar_fd, verboseFlag, optFlags, recurseFlags, include, exclude) -#endif +#define INIT_G() do { setup_common_bufsiz(); } while (0) #if ENABLE_FEATURE_TAR_CREATE @@ -187,8 +185,6 @@ typedef struct TarBallInfo { int tarFd; /* Open-for-write file descriptor * for the tarball */ int verboseFlag; /* Whether to print extra stuff or not */ - unsigned optFlags; /* all command line flags */ - const llist_t *excludeList; /* List of files to not include */ HardLinkInfo *hlInfoHead; /* Hard Link Tracking Information */ HardLinkInfo *hlInfo; /* Hard Link Info for the current file */ @@ -212,7 +208,6 @@ enum { CONTTYPE = '7', /* reserved */ GNULONGLINK = 'K', /* GNU long (>100 chars) link name */ GNULONGNAME = 'L', /* GNU long (>100 chars) file name */ - EXTTYPE = 'x', /* ext metadata for next file, store selinux_context */ }; /* Might be faster (and bigger) if the dev/ino were stored in numeric order;) */ @@ -354,34 +349,6 @@ static void writeLongname(int fd, int type, const char *name, int dir) } #endif -#if ENABLE_FEATURE_TAR_SELINUX -# define SELINUX_CONTEXT_KEYWORD "RHT.security.selinux" -/* Write 2 blocks : extended file header + selinux context */ -static int writeSeHeader(int fd, const char *con, struct tar_header_t *header) -{ - char block[TAR_BLOCK_SIZE]; - struct tar_header_t hd; - - int sz = sizeof(SELINUX_CONTEXT_KEYWORD) + 4 + strlen(con); - if (sz >= 100) sz++; /* another ascii digit for size */ - if (sz > TAR_BLOCK_SIZE) - return FALSE; - - memset(&block, 0, TAR_BLOCK_SIZE); - sprintf(block, "%d %s=%s\n", sz, SELINUX_CONTEXT_KEYWORD, con); - - /* write duplicated file entry */ - memcpy(&hd, header, sizeof(hd)); - hd.typeflag = EXTTYPE; - PUT_OCTAL(hd.size, sz); - chksum_and_xwrite(fd, &hd); - - /* write selinux context */ - xwrite(fd, &block, TAR_BLOCK_SIZE); - return TRUE; -} -#endif - /* Write out a tar header for the specified file/directory/whatever */ static int writeTarHeader(struct TarBallInfo *tbInfo, const char *header_name, const char *fileName, struct stat *statbuf) @@ -397,7 +364,8 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, PUT_OCTAL(header.uid, statbuf->st_uid); PUT_OCTAL(header.gid, statbuf->st_gid); memset(header.size, '0', sizeof(header.size)-1); /* Regular file size is handled later */ - PUT_OCTAL(header.mtime, statbuf->st_mtime); + /* users report that files with negative st_mtime cause trouble, so: */ + PUT_OCTAL(header.mtime, statbuf->st_mtime >= 0 ? statbuf->st_mtime : 0); /* Enter the user and group names */ safe_strncpy(header.uname, get_cached_username(statbuf->st_uid), sizeof(header.uname)); @@ -481,7 +449,7 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, *p8 |= 0x80; } else { bb_error_msg_and_die("can't store file '%s' " - "of size %"FILESIZE_FMT"u, aborting", + "of size %"OFF_FMT"u, aborting", fileName, statbuf->st_size); } header.typeflag = REGTYPE; @@ -498,18 +466,6 @@ static int writeTarHeader(struct TarBallInfo *tbInfo, header_name, S_ISDIR(statbuf->st_mode)); #endif -#if ENABLE_FEATURE_TAR_SELINUX - if (is_selinux_enabled() && (tbInfo->optFlags & ARCHIVE_STORE_SELINUX)) { - security_context_t sid; - lgetfilecon(fileName, &sid); - if (sid) { - // optional extended block - writeSeHeader(tbInfo->tarFd, sid, &header); - freecon(sid); - } - } -#endif - /* Now write the header out to disk */ chksum_and_xwrite(tbInfo->tarFd, &header); @@ -663,21 +619,12 @@ static int FAST_FUNC writeFileToTarball(const char *fileName, struct stat *statb return TRUE; } -#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 -# if !(ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2) -# define vfork_compressor(tar_fd, gzip) vfork_compressor(tar_fd) -# endif +#if SEAMLESS_COMPRESSION /* Don't inline: vfork scares gcc and pessimizes code */ -static void NOINLINE vfork_compressor(int tar_fd, int gzip) +static void NOINLINE vfork_compressor(int tar_fd, const char *gzip) { pid_t gzipPid; -# if ENABLE_FEATURE_SEAMLESS_GZ && ENABLE_FEATURE_SEAMLESS_BZ2 - const char *zip_exec = (gzip == 1) ? "gzip" : "bzip2"; -# elif ENABLE_FEATURE_SEAMLESS_GZ - const char *zip_exec = "gzip"; -# else /* only ENABLE_FEATURE_SEAMLESS_BZ2 */ - const char *zip_exec = "bzip2"; -# endif + // On Linux, vfork never unpauses parent early, although standard // allows for that. Do we want to waste bytes checking for it? # define WAIT_FOR_CHILD 0 @@ -691,11 +638,6 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip) signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ -# if defined(__GNUC__) && __GNUC__ - /* Avoid vfork clobbering */ - (void) &zip_exec; -# endif - gzipPid = xvfork(); if (gzipPid == 0) { @@ -711,7 +653,7 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip) xmove_fd(gzipDataPipe.rd, 0); xmove_fd(tar_fd, 1); /* exec gzip/bzip2 program/applet */ - BB_EXECLP(zip_exec, zip_exec, "-f", (char *)0); + BB_EXECLP(gzip, gzip, "-f", (char *)0); vfork_exec_errno = errno; _exit(EXIT_FAILURE); } @@ -734,17 +676,21 @@ static void NOINLINE vfork_compressor(int tar_fd, int gzip) # endif if (vfork_exec_errno) { errno = vfork_exec_errno; - bb_perror_msg_and_die("can't execute '%s'", zip_exec); + bb_perror_msg_and_die("can't execute '%s'", gzip); } } -#endif /* ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 */ +#endif /* SEAMLESS_COMPRESSION */ +#if !SEAMLESS_COMPRESSION +/* Do not pass gzip flag to writeTarFile() */ +#define writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude, gzip) \ + writeTarFile(tar_fd, verboseFlag, recurseFlags, include, exclude) +#endif /* gcc 4.2.1 inlines it, making code bigger */ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, - unsigned optFlags, int recurseFlags, const llist_t *include, - const llist_t *exclude, int gzip) + const llist_t *exclude, const char *gzip) { int errorFlag = FALSE; struct TarBallInfo tbInfo; @@ -752,13 +698,12 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, tbInfo.hlInfoHead = NULL; tbInfo.tarFd = tar_fd; tbInfo.verboseFlag = verboseFlag; - tbInfo.optFlags = optFlags; /* Store the stat info for the tarball's file, so * can avoid including the tarball into itself.... */ xfstat(tbInfo.tarFd, &tbInfo.tarFileStatBuf, "can't stat tar file"); -#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 +#if SEAMLESS_COMPRESSION if (gzip) vfork_compressor(tbInfo.tarFd, gzip); #endif @@ -793,7 +738,7 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, if (errorFlag) bb_error_msg("error exit delayed from previous errors"); -#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 +#if SEAMLESS_COMPRESSION if (gzip) { int status; if (safe_waitpid(-1, &status, 0) == -1) @@ -805,12 +750,9 @@ static NOINLINE int writeTarFile(int tar_fd, int verboseFlag, #endif return errorFlag; } -#else -int writeTarFile(int tar_fd, int verboseFlag, - unsigned optFlags, - int recurseFlags, const llist_t *include, - const llist_t *exclude, int gzip); -#endif /* FEATURE_TAR_CREATE */ +#else /* !FEATURE_TAR_CREATE */ +# define writeTarFile(...) 0 +#endif #if ENABLE_FEATURE_TAR_FROM static llist_t *append_file_list_to_list(llist_t *list) @@ -843,7 +785,6 @@ static llist_t *append_file_list_to_list(llist_t *list) //usage: IF_FEATURE_SEAMLESS_LZMA("a") //usage: IF_FEATURE_TAR_CREATE("h") //usage: IF_FEATURE_TAR_NOPRESERVE_TIME("m") -//usage: IF_FEATURE_TAR_SELINUX("p") //usage: "vO] " //usage: IF_FEATURE_TAR_FROM("[-X FILE] [-T FILE] ") //usage: "[-f TARFILE] [-C DIR] [FILE]..." @@ -889,9 +830,6 @@ static llist_t *append_file_list_to_list(llist_t *list) //usage: "\n X File with names to exclude" //usage: "\n T File with names to include" //usage: ) -//usage: IF_FEATURE_TAR_SELINUX( -//usage: "\n p Store SELinux contexts" -//usage: ) //usage: //usage:#define tar_example_usage //usage: "$ zcat /tmp/tarball.tar.gz | tar -xf -\n" @@ -922,6 +860,7 @@ enum { IF_FEATURE_SEAMLESS_Z( OPTBIT_COMPRESS ,) IF_FEATURE_TAR_NOPRESERVE_TIME(OPTBIT_NOPRESERVE_TIME,) #if ENABLE_FEATURE_TAR_LONG_OPTIONS + OPTBIT_STRIP_COMPONENTS, OPTBIT_NORECURSION, IF_FEATURE_TAR_TO_COMMAND(OPTBIT_2COMMAND ,) OPTBIT_NUMERIC_OWNER, @@ -946,12 +885,13 @@ enum { OPT_GZIP = IF_FEATURE_SEAMLESS_GZ( (1 << OPTBIT_GZIP )) + 0, // z OPT_XZ = IF_FEATURE_SEAMLESS_XZ( (1 << OPTBIT_XZ )) + 0, // J OPT_COMPRESS = IF_FEATURE_SEAMLESS_Z( (1 << OPTBIT_COMPRESS )) + 0, // Z - OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m - OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion - OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command - OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner - OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions - OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite + OPT_NOPRESERVE_TIME = IF_FEATURE_TAR_NOPRESERVE_TIME((1 << OPTBIT_NOPRESERVE_TIME)) + 0, // m + OPT_STRIP_COMPONENTS = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_STRIP_COMPONENTS)) + 0, // strip-components + OPT_NORECURSION = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NORECURSION )) + 0, // no-recursion + OPT_2COMMAND = IF_FEATURE_TAR_TO_COMMAND( (1 << OPTBIT_2COMMAND )) + 0, // to-command + OPT_NUMERIC_OWNER = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NUMERIC_OWNER )) + 0, // numeric-owner + OPT_NOPRESERVE_PERM = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_NOPRESERVE_PERM)) + 0, // no-same-permissions + OPT_OVERWRITE = IF_FEATURE_TAR_LONG_OPTIONS((1 << OPTBIT_OVERWRITE )) + 0, // overwrite OPT_ANY_COMPRESS = (OPT_BZIP2 | OPT_LZMA | OPT_GZIP | OPT_XZ | OPT_COMPRESS), }; @@ -995,6 +935,7 @@ static const char tar_longopts[] ALIGN1 = # if ENABLE_FEATURE_TAR_NOPRESERVE_TIME "touch\0" No_argument "m" # endif + "strip-components\0" Required_argument "\xf9" "no-recursion\0" No_argument "\xfa" # if ENABLE_FEATURE_TAR_TO_COMMAND "to-command\0" Required_argument "\xfb" @@ -1024,6 +965,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM llist_t *excludes = NULL; #endif + INIT_G(); /* Initialise default values */ tar_handle = init_handle(); @@ -1038,17 +980,29 @@ int tar_main(int argc UNUSED_PARAM, char **argv) /* Prepend '-' to the first argument if required */ opt_complementary = "--:" // first arg is options "tt:vv:" // count -t,-v - IF_FEATURE_TAR_FROM("X::T::") // cumulative lists #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM - "\xff::" // cumulative lists for --exclude + "\xff::" // --exclude=PATTERN is a list #endif IF_FEATURE_TAR_CREATE("c:") "t:x:" // at least one of these is reqd IF_FEATURE_TAR_CREATE("c--tx:t--cx:x--ct") // mutually exclusive - IF_NOT_FEATURE_TAR_CREATE("t--x:x--t"); // mutually exclusive + IF_NOT_FEATURE_TAR_CREATE("t--x:x--t") // mutually exclusive +#if ENABLE_FEATURE_TAR_LONG_OPTIONS + ":\xf9+" // --strip-components=NUM +#endif + ; #if ENABLE_FEATURE_TAR_LONG_OPTIONS applet_long_options = tar_longopts; #endif #if ENABLE_DESKTOP + /* Lie to buildroot when it starts asking stupid questions. */ + if (argv[1] && strcmp(argv[1], "--version") == 0) { + // Output of 'tar --version' examples: + // tar (GNU tar) 1.15.1 + // tar (GNU tar) 1.25 + // bsdtar 2.8.3 - libarchive 2.8.3 + puts("tar (busybox) " BB_VER); + return 0; + } if (argv[1] && argv[1][0] != '-') { /* Compat: * 1st argument without dash handles options with parameters @@ -1077,18 +1031,22 @@ int tar_main(int argc UNUSED_PARAM, char **argv) #endif opt = getopt32(argv, "txC:f:Oopvk" - IF_FEATURE_TAR_CREATE( "ch" ) - IF_FEATURE_SEAMLESS_BZ2( "j" ) - IF_FEATURE_SEAMLESS_LZMA("a" ) - IF_FEATURE_TAR_FROM( "T:X:") - IF_FEATURE_SEAMLESS_GZ( "z" ) - IF_FEATURE_SEAMLESS_XZ( "J" ) - IF_FEATURE_SEAMLESS_Z( "Z" ) + IF_FEATURE_TAR_CREATE( "ch" ) + IF_FEATURE_SEAMLESS_BZ2( "j" ) + IF_FEATURE_SEAMLESS_LZMA("a" ) + IF_FEATURE_TAR_FROM( "T:*X:*") + IF_FEATURE_SEAMLESS_GZ( "z" ) + IF_FEATURE_SEAMLESS_XZ( "J" ) + IF_FEATURE_SEAMLESS_Z( "Z" ) IF_FEATURE_TAR_NOPRESERVE_TIME("m") + IF_FEATURE_TAR_LONG_OPTIONS("\xf9:") // --strip-components , &base_dir // -C dir , &tar_filename // -f filename IF_FEATURE_TAR_FROM(, &(tar_handle->accept)) // T IF_FEATURE_TAR_FROM(, &(tar_handle->reject)) // X +#if ENABLE_FEATURE_TAR_LONG_OPTIONS + , &tar_handle->tar__strip_components // --strip-components +#endif IF_FEATURE_TAR_TO_COMMAND(, &(tar_handle->tar__to_command)) // --to-command #if ENABLE_FEATURE_TAR_LONG_OPTIONS && ENABLE_FEATURE_TAR_FROM , &excludes // --exclude @@ -1096,11 +1054,49 @@ int tar_main(int argc UNUSED_PARAM, char **argv) , &verboseFlag // combined count for -t and -v , &verboseFlag // combined count for -t and -v ); - //bb_error_msg("opt:%08x", opt); +#if DBG_OPTION_PARSING + bb_error_msg("opt: 0x%08x", opt); +# define showopt(o) bb_error_msg("opt & %s(%x): %x", #o, o, opt & o); + showopt(OPT_TEST ); + showopt(OPT_EXTRACT ); + showopt(OPT_BASEDIR ); + showopt(OPT_TARNAME ); + showopt(OPT_2STDOUT ); + showopt(OPT_NOPRESERVE_OWNER); + showopt(OPT_P ); + showopt(OPT_VERBOSE ); + showopt(OPT_KEEP_OLD ); + showopt(OPT_CREATE ); + showopt(OPT_DEREFERENCE ); + showopt(OPT_BZIP2 ); + showopt(OPT_LZMA ); + showopt(OPT_INCLUDE_FROM ); + showopt(OPT_EXCLUDE_FROM ); + showopt(OPT_GZIP ); + showopt(OPT_XZ ); + showopt(OPT_COMPRESS ); + showopt(OPT_NOPRESERVE_TIME ); + showopt(OPT_STRIP_COMPONENTS); + showopt(OPT_NORECURSION ); + showopt(OPT_2COMMAND ); + showopt(OPT_NUMERIC_OWNER ); + showopt(OPT_NOPRESERVE_PERM ); + showopt(OPT_OVERWRITE ); + showopt(OPT_ANY_COMPRESS ); + bb_error_msg("base_dir:'%s'", base_dir); + bb_error_msg("tar_filename:'%s'", tar_filename); + bb_error_msg("verboseFlag:%d", verboseFlag); + bb_error_msg("tar_handle->tar__to_command:'%s'", tar_handle->tar__to_command); + bb_error_msg("tar_handle->tar__strip_components:%u", tar_handle->tar__strip_components); + return 0; +# undef showopt +#endif argv += optind; - if (verboseFlag) tar_handle->action_header = header_verbose_list; - if (verboseFlag == 1) tar_handle->action_header = header_list; + if (verboseFlag) + tar_handle->action_header = header_verbose_list; + if (verboseFlag == 1) + tar_handle->action_header = header_list; if (opt & OPT_EXTRACT) tar_handle->action_data = data_extract_all; @@ -1127,11 +1123,6 @@ int tar_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_NOPRESERVE_PERM) tar_handle->ah_flags |= ARCHIVE_DONT_RESTORE_PERM; -#if ENABLE_FEATURE_TAR_SELINUX - if (opt & OPT_P) - tar_handle->ah_flags |= ARCHIVE_STORE_SELINUX; -#endif - if (opt & OPT_OVERWRITE) { tar_handle->ah_flags &= ~ARCHIVE_UNLINK_OLD; tar_handle->ah_flags |= ARCHIVE_O_TRUNC; @@ -1203,30 +1194,37 @@ int tar_main(int argc UNUSED_PARAM, char **argv) if (base_dir) xchdir(base_dir); - //if (SEAMLESS_COMPRESSION || OPT_COMPRESS) + //if (SEAMLESS_COMPRESSION) // /* We need to know whether child (gzip/bzip/etc) exits abnormally */ // signal(SIGCHLD, check_errors_in_children); +#if ENABLE_FEATURE_TAR_CREATE /* Create an archive */ if (opt & OPT_CREATE) { -#if ENABLE_FEATURE_SEAMLESS_GZ || ENABLE_FEATURE_SEAMLESS_BZ2 - int zipMode = 0; - if (ENABLE_FEATURE_SEAMLESS_GZ && (opt & OPT_GZIP)) - zipMode = 1; - if (ENABLE_FEATURE_SEAMLESS_BZ2 && (opt & OPT_BZIP2)) - zipMode = 2; -#endif +# if SEAMLESS_COMPRESSION + const char *zipMode = NULL; + if (opt & OPT_COMPRESS) + zipMode = "compress"; + if (opt & OPT_GZIP) + zipMode = "gzip"; + if (opt & OPT_BZIP2) + zipMode = "bzip2"; + if (opt & OPT_LZMA) + zipMode = "lzma"; + if (opt & OPT_XZ) + zipMode = "xz"; +# endif /* NB: writeTarFile() closes tar_handle->src_fd */ return writeTarFile(tar_handle->src_fd, verboseFlag, - tar_handle->ah_flags, (opt & OPT_DEREFERENCE ? ACTION_FOLLOWLINKS : 0) | (opt & OPT_NORECURSION ? 0 : ACTION_RECURSE), tar_handle->accept, tar_handle->reject, zipMode); } +#endif if (opt & OPT_ANY_COMPRESS) { - USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_aux_data_t *aux, int src_fd, int dst_fd);) + USE_FOR_MMU(IF_DESKTOP(long long) int FAST_FUNC (*xformer)(transformer_state_t *xstate);) USE_FOR_NOMMU(const char *xformer_prog;) if (opt & OPT_COMPRESS) @@ -1245,7 +1243,7 @@ int tar_main(int argc UNUSED_PARAM, char **argv) USE_FOR_MMU(xformer = unpack_xz_stream;) USE_FOR_NOMMU(xformer_prog = "unxz";) - open_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog); + fork_transformer_with_sig(tar_handle->src_fd, xformer, xformer_prog); /* Can't lseek over pipes */ tar_handle->seek = seek_by_read; /*tar_handle->offset = 0; - already is */ diff --git a/archival/unzip.c b/archival/unzip.c index 1cde28d..c540485 100644 --- a/archival/unzip.c +++ b/archival/unzip.c @@ -45,10 +45,10 @@ #include "libbb.h" #include "bb_archive.h" -#if defined(ANDROID) || defined(__ANDROID__) -/* Needed to ensure we can extract signed Android OTA packages */ -#undef ENABLE_DESKTOP -#define ENABLE_DESKTOP 1 +#if 0 +# define dbg(...) bb_error_msg(__VA_ARGS__) +#else +# define dbg(...) ((void)0) #endif enum { @@ -199,15 +199,17 @@ static uint32_t find_cdf_offset(void) unsigned char *p; off_t end; unsigned char *buf = xzalloc(PEEK_FROM_END); + uint32_t found; end = xlseek(zip_fd, 0, SEEK_END); end -= PEEK_FROM_END; if (end < 0) end = 0; - xlseek(zip_fd, end, SEEK_SET); + dbg("Looking for cdf_offset starting from 0x%"OFF_FMT"x", end); + xlseek(zip_fd, end, SEEK_SET); full_read(zip_fd, buf, PEEK_FROM_END); - cde_header.formatted.cdf_offset = BAD_CDF_OFFSET; + found = BAD_CDF_OFFSET; p = buf; while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) { if (*p != 'P') { @@ -226,14 +228,25 @@ static uint32_t find_cdf_offset(void) /* * I've seen .ZIP files with seemingly valid CDEs * where cdf_offset points past EOF - ?? - * Ignore such CDEs: + * This check ignores such CDEs: */ - if ((int64_t) cde_header.formatted.cdf_offset < end + (p - buf)) - break; - cde_header.formatted.cdf_offset = BAD_CDF_OFFSET; + if (cde_header.formatted.cdf_offset < end + (p - buf)) { + found = cde_header.formatted.cdf_offset; + dbg("Possible cdf_offset:0x%x at 0x%"OFF_FMT"x", + (unsigned)found, end + (p-3 - buf)); + dbg(" cdf_offset+cdf_size:0x%x", + (unsigned)(found + SWAP_LE32(cde_header.formatted.cdf_size))); + /* + * We do not "break" here because only the last CDE is valid. + * I've seen a .zip archive which contained a .zip file, + * uncompressed, and taking the first CDE was using + * the CDE inside that file! + */ + } } free(buf); - return cde_header.formatted.cdf_offset; + dbg("Found cdf_offset:0x%x", (unsigned)found); + return found; }; static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) @@ -246,15 +259,22 @@ static uint32_t read_next_cdf(uint32_t cdf_offset, cdf_header_t *cdf_ptr) cdf_offset = find_cdf_offset(); if (cdf_offset != BAD_CDF_OFFSET) { + dbg("Reading CDF at 0x%x", (unsigned)cdf_offset); xlseek(zip_fd, cdf_offset + 4, SEEK_SET); xread(zip_fd, cdf_ptr->raw, CDF_HEADER_LEN); FIX_ENDIANNESS_CDF(*cdf_ptr); + dbg(" file_name_length:%u extra_field_length:%u file_comment_length:%u", + (unsigned)cdf_ptr->formatted.file_name_length, + (unsigned)cdf_ptr->formatted.extra_field_length, + (unsigned)cdf_ptr->formatted.file_comment_length + ); cdf_offset += 4 + CDF_HEADER_LEN + cdf_ptr->formatted.file_name_length + cdf_ptr->formatted.extra_field_length + cdf_ptr->formatted.file_comment_length; } + dbg("Returning file position to 0x%"OFF_FMT"x", org); xlseek(zip_fd, org, SEEK_SET); return cdf_offset; }; @@ -286,17 +306,19 @@ static void unzip_extract(zip_header_t *zip_header, int dst_fd) bb_copyfd_exact_size(zip_fd, dst_fd, size); } else { /* Method 8 - inflate */ - transformer_aux_data_t aux; - init_transformer_aux_data(&aux); - aux.bytes_in = zip_header->formatted.cmpsize; - if (inflate_unzip(&aux, zip_fd, dst_fd) < 0) + transformer_state_t xstate; + init_transformer_state(&xstate); + xstate.bytes_in = zip_header->formatted.cmpsize; + xstate.src_fd = zip_fd; + xstate.dst_fd = dst_fd; + if (inflate_unzip(&xstate) < 0) bb_error_msg_and_die("inflate error"); /* Validate decompression - crc */ - if (zip_header->formatted.crc32 != (aux.crc32 ^ 0xffffffffL)) { + if (zip_header->formatted.crc32 != (xstate.crc32 ^ 0xffffffffL)) { bb_error_msg_and_die("crc error"); } /* Validate decompression - size */ - if (zip_header->formatted.ucmpsize != (uint32_t) aux.bytes_out) { + if (zip_header->formatted.ucmpsize != xstate.bytes_out) { /* Don't die. Who knows, maybe len calculation * was botched somewhere. After all, crc matched! */ bb_error_msg("bad length"); @@ -465,7 +487,7 @@ int unzip_main(int argc, char **argv) if (overwrite == O_PROMPT) overwrite = O_NEVER; } else { - static const char extn[][5] = { ".zip", ".ZIP" }; + static const char extn[][5] ALIGN1 = { ".zip", ".ZIP" }; char *ext = src_fn + strlen(src_fn); int src_fd; @@ -492,11 +514,11 @@ int unzip_main(int argc, char **argv) printf("Archive: %s\n", src_fn); if (listing) { puts(verbose ? - " Length Method Size Ratio Date Time CRC-32 Name\n" - "-------- ------ ------- ----- ---- ---- ------ ----" + " Length Method Size Cmpr Date Time CRC-32 Name\n" + "-------- ------ ------- ---- ---------- ----- -------- ----" : - " Length Date Time Name\n" - " -------- ---- ---- ----" + " Length Date Time Name\n" + "--------- ---------- ----- ----" ); } } @@ -536,11 +558,14 @@ int unzip_main(int argc, char **argv) /* Check magic number */ xread(zip_fd, &magic, 4); /* Central directory? It's at the end, so exit */ - if (magic == ZIP_CDF_MAGIC) + if (magic == ZIP_CDF_MAGIC) { + dbg("got ZIP_CDF_MAGIC"); break; + } #if ENABLE_DESKTOP /* Data descriptor? It was a streaming file, go on */ if (magic == ZIP_DD_MAGIC) { + dbg("got ZIP_DD_MAGIC"); /* skip over duplicate crc32, cmpsize and ucmpsize */ unzip_skip(3 * 4); continue; @@ -548,6 +573,7 @@ int unzip_main(int argc, char **argv) #endif if (magic != ZIP_FILEHEADER_MAGIC) bb_error_msg_and_die("invalid zip magic %08X", (int)magic); + dbg("got ZIP_FILEHEADER_MAGIC"); /* Read the file header */ xread(zip_fd, zip_header.raw, ZIP_HEADER_LEN); @@ -591,6 +617,11 @@ int unzip_main(int argc, char **argv) bb_error_msg_and_die("can't find file table"); } #endif + dbg("File cmpsize:0x%x extra_len:0x%x ucmpsize:0x%x", + (unsigned)zip_header.formatted.cmpsize, + (unsigned)zip_header.formatted.extra_len, + (unsigned)zip_header.formatted.ucmpsize + ); /* Read filename */ free(dst_fn); @@ -600,52 +631,72 @@ int unzip_main(int argc, char **argv) /* Skip extra header bytes */ unzip_skip(zip_header.formatted.extra_len); + /* Guard against "/abspath", "/../" and similar attacks */ + overlapping_strcpy(dst_fn, strip_unsafe_prefix(dst_fn)); + /* Filter zip entries */ if (find_list_entry(zreject, dst_fn) || (zaccept && !find_list_entry(zaccept, dst_fn)) ) { /* Skip entry */ i = 'n'; - - } else { /* Extract entry */ - if (listing) { /* List entry */ - unsigned dostime = zip_header.formatted.modtime | (zip_header.formatted.moddate << 16); + } else { + if (listing) { + /* List entry */ + char dtbuf[sizeof("mm-dd-yyyy hh:mm")]; + sprintf(dtbuf, "%02u-%02u-%04u %02u:%02u", + (zip_header.formatted.moddate >> 5) & 0xf, // mm: 0x01e0 + (zip_header.formatted.moddate) & 0x1f, // dd: 0x001f + (zip_header.formatted.moddate >> 9) + 1980, // yy: 0xfe00 + (zip_header.formatted.modtime >> 11), // hh: 0xf800 + (zip_header.formatted.modtime >> 5) & 0x3f // mm: 0x07e0 + // seconds/2 are not shown, encoded in ----------- 0x001f + ); if (!verbose) { - // " Length Date Time Name\n" - // " -------- ---- ---- ----" - printf( "%9u %02u-%02u-%02u %02u:%02u %s\n", + // " Length Date Time Name\n" + // "--------- ---------- ----- ----" + printf( "%9u " "%s " "%s\n", (unsigned)zip_header.formatted.ucmpsize, - (dostime & 0x01e00000) >> 21, - (dostime & 0x001f0000) >> 16, - (((dostime & 0xfe000000) >> 25) + 1980) % 100, - (dostime & 0x0000f800) >> 11, - (dostime & 0x000007e0) >> 5, + dtbuf, dst_fn); - total_usize += zip_header.formatted.ucmpsize; } else { unsigned long percents = zip_header.formatted.ucmpsize - zip_header.formatted.cmpsize; + if ((int32_t)percents < 0) + percents = 0; /* happens if ucmpsize < cmpsize */ percents = percents * 100; if (zip_header.formatted.ucmpsize) percents /= zip_header.formatted.ucmpsize; - // " Length Method Size Ratio Date Time CRC-32 Name\n" - // "-------- ------ ------- ----- ---- ---- ------ ----" - printf( "%8u Defl:N" "%9u%4u%% %02u-%02u-%02u %02u:%02u %08x %s\n", + // " Length Method Size Cmpr Date Time CRC-32 Name\n" + // "-------- ------ ------- ---- ---------- ----- -------- ----" + printf( "%8u %s" "%9u%4u%% " "%s " "%08x " "%s\n", (unsigned)zip_header.formatted.ucmpsize, + zip_header.formatted.method == 0 ? "Stored" : "Defl:N", /* Defl is method 8 */ +/* TODO: show other methods? + * 1 - Shrunk + * 2 - Reduced with compression factor 1 + * 3 - Reduced with compression factor 2 + * 4 - Reduced with compression factor 3 + * 5 - Reduced with compression factor 4 + * 6 - Imploded + * 7 - Reserved for Tokenizing compression algorithm + * 9 - Deflate64 + * 10 - PKWARE Data Compression Library Imploding + * 11 - Reserved by PKWARE + * 12 - BZIP2 + */ (unsigned)zip_header.formatted.cmpsize, (unsigned)percents, - (dostime & 0x01e00000) >> 21, - (dostime & 0x001f0000) >> 16, - (((dostime & 0xfe000000) >> 25) + 1980) % 100, - (dostime & 0x0000f800) >> 11, - (dostime & 0x000007e0) >> 5, + dtbuf, zip_header.formatted.crc32, dst_fn); - total_usize += zip_header.formatted.ucmpsize; total_size += zip_header.formatted.cmpsize; } + total_usize += zip_header.formatted.ucmpsize; i = 'n'; - } else if (dst_fd == STDOUT_FILENO) { /* Extracting to STDOUT */ + } else if (dst_fd == STDOUT_FILENO) { + /* Extracting to STDOUT */ i = -1; - } else if (last_char_is(dst_fn, '/')) { /* Extract directory */ + } else if (last_char_is(dst_fn, '/')) { + /* Extract directory */ if (stat(dst_fn, &stat_buf) == -1) { if (errno != ENOENT) { bb_perror_msg_and_die("can't stat '%s'", dst_fn); @@ -659,22 +710,26 @@ int unzip_main(int argc, char **argv) } } else { if (!S_ISDIR(stat_buf.st_mode)) { - bb_error_msg_and_die("'%s' exists but is not directory", dst_fn); + bb_error_msg_and_die("'%s' exists but is not a %s", + dst_fn, "directory"); } } i = 'n'; - - } else { /* Extract file */ + } else { + /* Extract file */ check_file: - if (stat(dst_fn, &stat_buf) == -1) { /* File does not exist */ + if (stat(dst_fn, &stat_buf) == -1) { + /* File does not exist */ if (errno != ENOENT) { bb_perror_msg_and_die("can't stat '%s'", dst_fn); } i = 'y'; - } else { /* File already exists */ + } else { + /* File already exists */ if (overwrite == O_NEVER) { i = 'n'; - } else if (S_ISREG(stat_buf.st_mode)) { /* File is regular file */ + } else if (S_ISREG(stat_buf.st_mode)) { + /* File is regular file */ if (overwrite == O_ALWAYS) { i = 'y'; } else { @@ -682,8 +737,10 @@ int unzip_main(int argc, char **argv) my_fgets80(key_buf); i = key_buf[0]; } - } else { /* File is not regular file */ - bb_error_msg_and_die("'%s' exists but is not regular file", dst_fn); + } else { + /* File is not regular file */ + bb_error_msg_and_die("'%s' exists but is not a %s", + dst_fn, "regular file"); } } } @@ -736,21 +793,25 @@ int unzip_main(int argc, char **argv) if (listing && quiet <= 1) { if (!verbose) { - // " Length Date Time Name\n" - // " -------- ---- ---- ----" - printf( " -------- -------\n" - "%9lu" " %u files\n", - total_usize, total_entries); + // " Length Date Time Name\n" + // "--------- ---------- ----- ----" + printf( " --------%21s" "-------\n" + "%9lu%21s" "%u files\n", + "", + total_usize, "", total_entries); } else { unsigned long percents = total_usize - total_size; + if ((long)percents < 0) + percents = 0; /* happens if usize < size */ percents = percents * 100; if (total_usize) percents /= total_usize; - // " Length Method Size Ratio Date Time CRC-32 Name\n" - // "-------- ------ ------- ----- ---- ---- ------ ----" - printf( "-------- ------- --- -------\n" - "%8lu" "%17lu%4u%% %u files\n", - total_usize, total_size, (unsigned)percents, + // " Length Method Size Cmpr Date Time CRC-32 Name\n" + // "-------- ------ ------- ---- ---------- ----- -------- ----" + printf( "-------- ------- ----%28s" "----\n" + "%8lu" "%17lu%4u%%%28s" "%u files\n", + "", + total_usize, total_size, (unsigned)percents, "", total_entries); } } diff --git a/busybox-full.config b/busybox-full.config index d64b351..8668d6d 100644 --- a/busybox-full.config +++ b/busybox-full.config @@ -1,41 +1,25 @@ # # Automatically generated make config: don't edit -# Busybox version: 1.22.1 -# Wed Aug 6 13:27:12 2014 +# Busybox version: 1.26.2 +# Thu May 18 16:36:09 2017 # CONFIG_HAVE_DOT_CONFIG=y # # Busybox Settings # - -# -# General Configuration -# CONFIG_DESKTOP=y # CONFIG_EXTRA_COMPAT is not set # CONFIG_INCLUDE_SUSv2 is not set # CONFIG_USE_PORTABLE_CODE is not set CONFIG_PLATFORM_LINUX=y -CONFIG_FEATURE_BUFFERS_USE_MALLOC=y -# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set -# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set CONFIG_SHOW_USAGE=y CONFIG_FEATURE_VERBOSE_USAGE=y CONFIG_FEATURE_COMPRESS_USAGE=y +CONFIG_BUSYBOX=y CONFIG_FEATURE_INSTALLER=y CONFIG_INSTALL_NO_USR=y -# CONFIG_LOCALE_SUPPORT is not set -CONFIG_UNICODE_SUPPORT=y -# CONFIG_UNICODE_USING_LOCALE is not set -# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set -CONFIG_SUBST_WCHAR=63 -CONFIG_LAST_SUPPORTED_WCHAR=0 -# CONFIG_UNICODE_COMBINING_WCHARS is not set -CONFIG_UNICODE_WIDE_WCHARS=y -# CONFIG_UNICODE_BIDI_SUPPORT is not set -# CONFIG_UNICODE_NEUTRAL_TABLE is not set -CONFIG_UNICODE_PRESERVE_BROKEN=y +# CONFIG_PAM is not set CONFIG_LONG_OPTS=y CONFIG_FEATURE_DEVPTS=y # CONFIG_FEATURE_CLEAN_UP is not set @@ -62,22 +46,13 @@ CONFIG_FEATURE_HAVE_RPC=y # CONFIG_FEATURE_INDIVIDUAL is not set # CONFIG_FEATURE_SHARED_BUSYBOX is not set # CONFIG_LFS is not set +CONFIG_CROSS_COMPILER_PREFIX="" CONFIG_SYSROOT="" CONFIG_EXTRA_CFLAGS="-Os -fno-short-enums -fgcse-after-reload -frerun-cse-after-loop -frename-registers" CONFIG_EXTRA_LDFLAGS="" CONFIG_EXTRA_LDLIBS="" # -# Debugging Options -# -# CONFIG_DEBUG is not set -# CONFIG_DEBUG_PESSIMIZE is not set -# CONFIG_WERROR is not set -CONFIG_NO_DEBUG_LIB=y -# CONFIG_DMALLOC is not set -# CONFIG_EFENCE is not set - -# # Installation Options ("make install" behavior) # CONFIG_INSTALL_APPLET_SYMLINKS=y @@ -90,34 +65,61 @@ CONFIG_INSTALL_APPLET_SYMLINKS=y CONFIG_PREFIX="./_install" # +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# # Busybox Library Tuning # -# CONFIG_FEATURE_SYSTEMD is not set +# CONFIG_FEATURE_USE_BSS_TAIL is not set CONFIG_FEATURE_RTMINMAX=y +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 CONFIG_SHA3_SMALL=1 -CONFIG_FEATURE_FAST_TOP=y +# CONFIG_FEATURE_FAST_TOP is not set # CONFIG_FEATURE_ETC_NETWORKS is not set CONFIG_FEATURE_USE_TERMIOS=y CONFIG_FEATURE_EDITING=y CONFIG_FEATURE_EDITING_MAX_LEN=1024 -CONFIG_FEATURE_EDITING_VI=y +# CONFIG_FEATURE_EDITING_VI is not set CONFIG_FEATURE_EDITING_HISTORY=256 CONFIG_FEATURE_EDITING_SAVEHISTORY=y # CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set CONFIG_FEATURE_REVERSE_SEARCH=y CONFIG_FEATURE_TAB_COMPLETION=y -# CONFIG_FEATURE_USERNAME_COMPLETION is not set +CONFIG_FEATURE_USERNAME_COMPLETION=y CONFIG_FEATURE_EDITING_FANCY_PROMPT=y -CONFIG_FEATURE_EDITING_ASK_TERMINAL=y +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +# CONFIG_LOCALE_SUPPORT is not set +CONFIG_UNICODE_SUPPORT=y +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=63 +CONFIG_LAST_SUPPORTED_WCHAR=767 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set CONFIG_FEATURE_NON_POSIX_CP=y # CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +CONFIG_FEATURE_USE_SENDFILE=y CONFIG_FEATURE_COPYBUF_KB=4 CONFIG_FEATURE_SKIP_ROOTFS=y CONFIG_MONOTONIC_SYSCALL=y CONFIG_IOCTL_HEX2STR_ERROR=y -# CONFIG_FEATURE_HWIB is not set +CONFIG_FEATURE_HWIB=y # # Applets @@ -136,11 +138,16 @@ CONFIG_FEATURE_SEAMLESS_GZ=y # CONFIG_FEATURE_AR_CREATE is not set CONFIG_UNCOMPRESS=y CONFIG_GUNZIP=y +CONFIG_ZCAT=y +CONFIG_FEATURE_GUNZIP_LONG_OPTIONS=y CONFIG_BUNZIP2=y +CONFIG_BZCAT=y CONFIG_UNLZMA=y -CONFIG_FEATURE_LZMA_FAST=y +CONFIG_LZCAT=y CONFIG_LZMA=y +CONFIG_FEATURE_LZMA_FAST=y CONFIG_UNXZ=y +CONFIG_XZCAT=y CONFIG_XZ=y CONFIG_BZIP2=y CONFIG_CPIO=y @@ -148,11 +155,13 @@ CONFIG_FEATURE_CPIO_O=y CONFIG_FEATURE_CPIO_P=y # CONFIG_DPKG is not set # CONFIG_DPKG_DEB is not set -# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set CONFIG_GZIP=y CONFIG_FEATURE_GZIP_LONG_OPTIONS=y CONFIG_GZIP_FAST=2 +# CONFIG_FEATURE_GZIP_LEVELS is not set CONFIG_LZOP=y +CONFIG_UNLZOP=y +CONFIG_LZOPCAT=y CONFIG_LZOP_COMPR_HIGH=y # CONFIG_RPM is not set # CONFIG_RPM2CPIO is not set @@ -174,26 +183,8 @@ CONFIG_UNZIP=y # Coreutils # CONFIG_BASENAME=y -CONFIG_CAT=y -CONFIG_DATE=y -CONFIG_FEATURE_DATE_ISOFMT=y -# CONFIG_FEATURE_DATE_NANO is not set -CONFIG_FEATURE_DATE_COMPAT=y -# CONFIG_HOSTID is not set -CONFIG_ID=y -CONFIG_GROUPS=y -CONFIG_TEST=y -# CONFIG_FEATURE_TEST_64 is not set -CONFIG_TOUCH=y -# CONFIG_FEATURE_TOUCH_NODEREF is not set -CONFIG_FEATURE_TOUCH_SUSV3=y -CONFIG_TR=y -CONFIG_FEATURE_TR_CLASSES=y -# CONFIG_FEATURE_TR_EQUIV is not set -CONFIG_BASE64=y -# CONFIG_WHO is not set -# CONFIG_USERS is not set CONFIG_CAL=y +CONFIG_CAT=y CONFIG_CATV=y CONFIG_CHGRP=y CONFIG_CHMOD=y @@ -205,10 +196,15 @@ CONFIG_COMM=y CONFIG_CP=y CONFIG_FEATURE_CP_LONG_OPTIONS=y CONFIG_CUT=y +CONFIG_DATE=y +CONFIG_FEATURE_DATE_ISOFMT=y +# CONFIG_FEATURE_DATE_NANO is not set +CONFIG_FEATURE_DATE_COMPAT=y CONFIG_DD=y CONFIG_FEATURE_DD_SIGNAL_HANDLING=y CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y CONFIG_FEATURE_DD_IBS_OBS=y +CONFIG_FEATURE_DD_STATUS=y CONFIG_DF=y CONFIG_FEATURE_DF_FANCY=y CONFIG_DIRNAME=y @@ -222,6 +218,8 @@ CONFIG_ENV=y CONFIG_FEATURE_ENV_LONG_OPTIONS=y CONFIG_EXPAND=y CONFIG_FEATURE_EXPAND_LONG_OPTIONS=y +CONFIG_UNEXPAND=y +CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS=y CONFIG_EXPR=y CONFIG_EXPR_MATH_SUPPORT_64=y CONFIG_FALSE=y @@ -229,6 +227,9 @@ CONFIG_FOLD=y CONFIG_FSYNC=y CONFIG_HEAD=y CONFIG_FEATURE_FANCY_HEAD=y +# CONFIG_HOSTID is not set +CONFIG_ID=y +CONFIG_GROUPS=y CONFIG_INSTALL=y CONFIG_FEATURE_INSTALL_LONG_OPTIONS=y CONFIG_LN=y @@ -243,6 +244,15 @@ CONFIG_FEATURE_LS_USERNAME=y CONFIG_FEATURE_LS_COLOR=y # CONFIG_FEATURE_LS_COLOR_IS_DEFAULT is not set CONFIG_MD5SUM=y +CONFIG_SHA1SUM=y +CONFIG_SHA256SUM=y +CONFIG_SHA512SUM=y +CONFIG_SHA3SUM=y + +# +# Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum +# +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y CONFIG_MKDIR=y CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y CONFIG_MKFIFO=y @@ -262,10 +272,7 @@ CONFIG_RM=y CONFIG_RMDIR=y CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y CONFIG_SEQ=y -CONFIG_SHA1SUM=y -CONFIG_SHA256SUM=y -CONFIG_SHA512SUM=y -CONFIG_SHA3SUM=y +CONFIG_SHUF=y CONFIG_SLEEP=y CONFIG_FEATURE_FANCY_SLEEP=y CONFIG_FEATURE_FLOAT_SLEEP=y @@ -275,29 +282,50 @@ CONFIG_SPLIT=y CONFIG_FEATURE_SPLIT_FANCY=y CONFIG_STAT=y # CONFIG_FEATURE_STAT_FORMAT is not set +CONFIG_FEATURE_STAT_FILESYSTEM=y CONFIG_STTY=y CONFIG_SUM=y CONFIG_SYNC=y +CONFIG_FEATURE_SYNC_FANCY=y CONFIG_TAC=y CONFIG_TAIL=y CONFIG_FEATURE_FANCY_TAIL=y CONFIG_TEE=y CONFIG_FEATURE_TEE_USE_BLOCK_IO=y +CONFIG_TEST=y +CONFIG_TEST1=y +CONFIG_TEST2=y +# CONFIG_FEATURE_TEST_64 is not set +CONFIG_TOUCH=y +# CONFIG_FEATURE_TOUCH_NODEREF is not set +CONFIG_FEATURE_TOUCH_SUSV3=y +CONFIG_TR=y +CONFIG_FEATURE_TR_CLASSES=y +# CONFIG_FEATURE_TR_EQUIV is not set CONFIG_TRUE=y +CONFIG_TRUNCATE=y # CONFIG_TTY is not set CONFIG_UNAME=y -CONFIG_UNEXPAND=y -CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS=y +CONFIG_UNAME_OSNAME="GNU/Linux" CONFIG_UNIQ=y +CONFIG_UNLINK=y CONFIG_USLEEP=y CONFIG_UUDECODE=y +CONFIG_BASE64=y CONFIG_UUENCODE=y CONFIG_WC=y CONFIG_FEATURE_WC_LARGE=y +# CONFIG_WHO is not set +# CONFIG_USERS is not set CONFIG_WHOAMI=y CONFIG_YES=y # +# Common options +# +CONFIG_FEATURE_VERBOSE=y + +# # Common options for cp and mv # CONFIG_FEATURE_PRESERVE_HARDLINKS=y @@ -313,20 +341,20 @@ CONFIG_FEATURE_AUTOWIDTH=y CONFIG_FEATURE_HUMAN_READABLE=y # -# Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum -# -CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y - -# # Console Utilities # CONFIG_CHVT=y -CONFIG_FGCONSOLE=y CONFIG_CLEAR=y CONFIG_DEALLOCVT=y # CONFIG_DUMPKMAP is not set +CONFIG_FGCONSOLE=y # CONFIG_KBD_MODE is not set # CONFIG_LOADFONT is not set +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set # CONFIG_LOADKMAP is not set CONFIG_OPENVT=y CONFIG_RESET=y @@ -334,14 +362,9 @@ CONFIG_RESIZE=y # CONFIG_FEATURE_RESIZE_PRINT is not set CONFIG_SETCONSOLE=y # CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS is not set -# CONFIG_SETFONT is not set -# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set -CONFIG_DEFAULT_SETFONT_DIR="" CONFIG_SETKEYCODES=y # CONFIG_SETLOGCONS is not set # CONFIG_SHOWKEY is not set -# CONFIG_FEATURE_LOADFONT_PSF2 is not set -# CONFIG_FEATURE_LOADFONT_RAW is not set # # Debian Utilities @@ -383,6 +406,9 @@ CONFIG_FEATURE_VI_SETOPTS=y CONFIG_FEATURE_VI_SET=y CONFIG_FEATURE_VI_WIN_RESIZE=y CONFIG_FEATURE_VI_ASK_TERMINAL=y +CONFIG_FEATURE_VI_UNDO=y +CONFIG_FEATURE_VI_UNDO_QUEUE=y +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 CONFIG_FEATURE_ALLOW_EXEC=y # @@ -399,6 +425,7 @@ CONFIG_FEATURE_FIND_MAXDEPTH=y CONFIG_FEATURE_FIND_NEWER=y CONFIG_FEATURE_FIND_INUM=y CONFIG_FEATURE_FIND_EXEC=y +CONFIG_FEATURE_FIND_EXEC_PLUS=y CONFIG_FEATURE_FIND_USER=y CONFIG_FEATURE_FIND_GROUP=y CONFIG_FEATURE_FIND_NOT=y @@ -412,14 +439,15 @@ CONFIG_FEATURE_FIND_REGEX=y # CONFIG_FEATURE_FIND_CONTEXT is not set CONFIG_FEATURE_FIND_LINKS=y CONFIG_GREP=y -CONFIG_FEATURE_GREP_EGREP_ALIAS=y -CONFIG_FEATURE_GREP_FGREP_ALIAS=y +CONFIG_EGREP=y +CONFIG_FGREP=y CONFIG_FEATURE_GREP_CONTEXT=y CONFIG_XARGS=y CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y +CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR=y # # Init Utilities @@ -428,9 +456,12 @@ CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y # CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER is not set # CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE is not set CONFIG_HALT=y +CONFIG_POWEROFF=y +CONFIG_REBOOT=y # CONFIG_FEATURE_CALL_TELINIT is not set CONFIG_TELINIT_PATH="" # CONFIG_INIT is not set +CONFIG_LINUXRC=y # CONFIG_FEATURE_USE_INITTAB is not set # CONFIG_FEATURE_KILL_REMOVED is not set CONFIG_FEATURE_KILL_DELAY=0 @@ -438,44 +469,45 @@ CONFIG_FEATURE_KILL_DELAY=0 # CONFIG_FEATURE_INIT_SYSLOG is not set # CONFIG_FEATURE_EXTRA_QUIET is not set # CONFIG_FEATURE_INIT_COREDUMPS is not set -# CONFIG_FEATURE_INITRD is not set CONFIG_INIT_TERMINAL_TYPE="" +CONFIG_FEATURE_INIT_MODIFY_CMDLINE=y CONFIG_MESG=y CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y # # Login/Password Management Utilities # -# CONFIG_ADD_SHELL is not set -# CONFIG_REMOVE_SHELL is not set # CONFIG_FEATURE_SHADOWPASSWDS is not set # CONFIG_USE_BB_PWD_GRP is not set # CONFIG_USE_BB_SHADOW is not set CONFIG_USE_BB_CRYPT=y CONFIG_USE_BB_CRYPT_SHA=y +# CONFIG_ADD_SHELL is not set +# CONFIG_REMOVE_SHELL is not set +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set # CONFIG_ADDUSER is not set # CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set # CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 CONFIG_FIRST_SYSTEM_ID=0 CONFIG_LAST_SYSTEM_ID=0 -# CONFIG_ADDGROUP is not set -# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set -# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_CHPASSWD is not set +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" +# CONFIG_CRYPTPW is not set +CONFIG_MKPASSWD=y # CONFIG_DELUSER is not set # CONFIG_DELGROUP is not set # CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set # CONFIG_GETTY is not set # CONFIG_LOGIN is not set # CONFIG_LOGIN_SESSION_AS_CHILD is not set -# CONFIG_PAM is not set # CONFIG_LOGIN_SCRIPTS is not set # CONFIG_FEATURE_NOLOGIN is not set # CONFIG_FEATURE_SECURETTY is not set # CONFIG_PASSWD is not set # CONFIG_FEATURE_PASSWD_WEAK_CHECK is not set -# CONFIG_CRYPTPW is not set -# CONFIG_CHPASSWD is not set -CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="" # CONFIG_SU is not set # CONFIG_FEATURE_SU_SYSLOG is not set # CONFIG_FEATURE_SU_CHECKS_SHELLS is not set @@ -493,17 +525,17 @@ CONFIG_TUNE2FS=y # # Linux Module Utilities # -CONFIG_MODINFO=y # CONFIG_MODPROBE_SMALL is not set -CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE=y -CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y +CONFIG_DEPMOD=y CONFIG_INSMOD=y -CONFIG_RMMOD=y CONFIG_LSMOD=y CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT=y +CONFIG_MODINFO=y +# CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE is not set +# CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED is not set CONFIG_MODPROBE=y CONFIG_FEATURE_MODPROBE_BLACKLIST=y -CONFIG_DEPMOD=y +CONFIG_RMMOD=y # # Options common to multiple modutils @@ -518,31 +550,24 @@ CONFIG_FEATURE_INSMOD_TRY_MMAP=y CONFIG_FEATURE_CHECK_TAINTED_MODULE=y CONFIG_FEATURE_MODUTILS_ALIAS=y CONFIG_FEATURE_MODUTILS_SYMBOLS=y +CONFIG_DEFAULT_MODULES_DIR="/lib/modules" CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" # # Linux System Utilities # -CONFIG_BLOCKDEV=y -CONFIG_FSTRIM=y -# CONFIG_MDEV is not set -# CONFIG_FEATURE_MDEV_CONF is not set -# CONFIG_FEATURE_MDEV_RENAME is not set -# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set -# CONFIG_FEATURE_MDEV_EXEC is not set -# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set -CONFIG_REV=y # CONFIG_ACPID is not set # CONFIG_FEATURE_ACPID_COMPAT is not set +CONFIG_BLKDISCARD=y CONFIG_BLKID=y CONFIG_FEATURE_BLKID_TYPE=y +CONFIG_BLOCKDEV=y CONFIG_DMESG=y # CONFIG_FEATURE_DMESG_PRETTY is not set +CONFIG_FATATTR=y CONFIG_FBSET=y CONFIG_FEATURE_FBSET_FANCY=y -CONFIG_FEATURE_DMESG_COLOR=y # CONFIG_FEATURE_FBSET_READMODE is not set -# CONFIG_FDFLUSH is not set # CONFIG_FDFORMAT is not set CONFIG_FDISK=y # CONFIG_FDISK_SUPPORT_LARGE_DISKS is not set @@ -555,13 +580,10 @@ CONFIG_FEATURE_GPT_LABEL=y CONFIG_FEATURE_FDISK_ADVANCED=y CONFIG_FINDFS=y CONFIG_FLOCK=y +# CONFIG_FDFLUSH is not set CONFIG_FREERAMDISK=y # CONFIG_FSCK_MINIX is not set -CONFIG_MKFS_EXT2=y -# CONFIG_MKFS_MINIX is not set -# CONFIG_FEATURE_MINIX2 is not set -# CONFIG_MKFS_REISER is not set -CONFIG_MKFS_VFAT=y +CONFIG_FSTRIM=y CONFIG_GETOPT=y CONFIG_FEATURE_GETOPT_LONG=y CONFIG_HEXDUMP=y @@ -575,6 +597,19 @@ CONFIG_HWCLOCK=y CONFIG_LOSETUP=y CONFIG_LSPCI=y CONFIG_LSUSB=y +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +CONFIG_MKE2FS=y +CONFIG_MKFS_EXT2=y +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +CONFIG_MKDOSFS=y +CONFIG_MKFS_VFAT=y CONFIG_MKSWAP=y # CONFIG_FEATURE_MKSWAP_UUID is not set CONFIG_MORE=y @@ -587,19 +622,29 @@ CONFIG_FEATURE_MOUNT_NFS=y CONFIG_FEATURE_MOUNT_CIFS=y CONFIG_FEATURE_MOUNT_FLAGS=y CONFIG_FEATURE_MOUNT_FSTAB=y +CONFIG_FEATURE_MOUNT_OTHERTAB=y +CONFIG_NSENTER=y +CONFIG_FEATURE_NSENTER_LONG_OPTS=y # CONFIG_PIVOT_ROOT is not set CONFIG_RDATE=y CONFIG_RDEV=y # CONFIG_READPROFILE is not set +CONFIG_REV=y # CONFIG_RTCWAKE is not set # CONFIG_SCRIPT is not set # CONFIG_SCRIPTREPLAY is not set # CONFIG_SETARCH is not set -CONFIG_SWAPONOFF=y +CONFIG_LINUX32=y +CONFIG_LINUX64=y +CONFIG_SWAPON=y +CONFIG_FEATURE_SWAPON_DISCARD=y CONFIG_FEATURE_SWAPON_PRI=y +CONFIG_SWAPOFF=y CONFIG_SWITCH_ROOT=y +CONFIG_UEVENT=y CONFIG_UMOUNT=y CONFIG_FEATURE_UMOUNT_ALL=y +CONFIG_UNSHARE=y # # Common options for mount/umount @@ -612,6 +657,7 @@ CONFIG_VOLUMEID=y # # Filesystem/Volume identification # +CONFIG_FEATURE_VOLUMEID_BCACHE=y # CONFIG_FEATURE_VOLUMEID_BTRFS is not set # CONFIG_FEATURE_VOLUMEID_CRAMFS is not set CONFIG_FEATURE_VOLUMEID_EXFAT=y @@ -631,34 +677,13 @@ CONFIG_FEATURE_VOLUMEID_NTFS=y # CONFIG_FEATURE_VOLUMEID_ROMFS is not set CONFIG_FEATURE_VOLUMEID_SQUASHFS=y # CONFIG_FEATURE_VOLUMEID_SYSV is not set +CONFIG_FEATURE_VOLUMEID_UBIFS=y # CONFIG_FEATURE_VOLUMEID_UDF is not set # CONFIG_FEATURE_VOLUMEID_XFS is not set # # Miscellaneous Utilities # -# CONFIG_CONSPY is not set -CONFIG_LESS=y -CONFIG_FEATURE_LESS_MAXLINES=65536 -# CONFIG_FEATURE_LESS_BRACKETS is not set -# CONFIG_FEATURE_LESS_FLAGS is not set -CONFIG_FEATURE_LESS_MARKS=y -CONFIG_FEATURE_LESS_REGEXP=y -CONFIG_FEATURE_LESS_WINCH=y -CONFIG_FEATURE_LESS_ASK_TERMINAL=y -# CONFIG_FEATURE_LESS_DASHCMD is not set -# CONFIG_FEATURE_LESS_LINENUMS is not set -CONFIG_NANDWRITE=y -CONFIG_NANDDUMP=y -# CONFIG_RFKILL is not set -CONFIG_SETSERIAL=y -# CONFIG_UBIATTACH is not set -# CONFIG_UBIDETACH is not set -# CONFIG_UBIMKVOL is not set -# CONFIG_UBIRMVOL is not set -# CONFIG_UBIRSVOL is not set -# CONFIG_UBIUPDATEVOL is not set -# CONFIG_WALL is not set CONFIG_ADJTIMEX=y CONFIG_BBCONFIG=y CONFIG_FEATURE_COMPRESS_BBCONFIG=y @@ -674,6 +699,7 @@ CONFIG_FEATURE_BEEP_LENGTH_MS=0 # CONFIG_FEATURE_CHAT_VAR_ABORT_LEN is not set # CONFIG_FEATURE_CHAT_CLR_ABORT is not set # CONFIG_CHRT is not set +# CONFIG_CONSPY is not set CONFIG_CROND=y CONFIG_FEATURE_CROND_D=y # CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set @@ -690,15 +716,10 @@ CONFIG_DEVMEM=y # CONFIG_EJECT is not set # CONFIG_FEATURE_EJECT_SCSI is not set CONFIG_FBSPLASH=y -CONFIG_FLASHCP=y +# CONFIG_FLASH_ERASEALL is not set CONFIG_FLASH_LOCK=y CONFIG_FLASH_UNLOCK=y -# CONFIG_FLASH_ERASEALL is not set -CONFIG_IONICE=y -# CONFIG_INOTIFYD is not set -# CONFIG_LAST is not set -# CONFIG_FEATURE_LAST_SMALL is not set -# CONFIG_FEATURE_LAST_FANCY is not set +CONFIG_FLASHCP=y # CONFIG_HDPARM is not set # CONFIG_FEATURE_HDPARM_GET_IDENTITY is not set # CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF is not set @@ -706,6 +727,25 @@ CONFIG_IONICE=y # CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET is not set # CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF is not set # CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA is not set +CONFIG_I2CGET=y +CONFIG_I2CSET=y +CONFIG_I2CDUMP=y +CONFIG_I2CDETECT=y +# CONFIG_INOTIFYD is not set +CONFIG_IONICE=y +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +CONFIG_LESS=y +CONFIG_FEATURE_LESS_MAXLINES=65536 +# CONFIG_FEATURE_LESS_BRACKETS is not set +# CONFIG_FEATURE_LESS_FLAGS is not set +CONFIG_FEATURE_LESS_TRUNCATE=y +CONFIG_FEATURE_LESS_MARKS=y +CONFIG_FEATURE_LESS_REGEXP=y +CONFIG_FEATURE_LESS_WINCH=y +CONFIG_FEATURE_LESS_ASK_TERMINAL=y +# CONFIG_FEATURE_LESS_DASHCMD is not set +# CONFIG_FEATURE_LESS_LINENUMS is not set # CONFIG_MAKEDEVS is not set # CONFIG_FEATURE_MAKEDEVS_LEAF is not set # CONFIG_FEATURE_MAKEDEVS_TABLE is not set @@ -713,10 +753,14 @@ CONFIG_MAN=y # CONFIG_MICROCOM is not set CONFIG_MOUNTPOINT=y # CONFIG_MT is not set +CONFIG_NANDWRITE=y +CONFIG_NANDDUMP=y # CONFIG_RAIDAUTORUN is not set # CONFIG_READAHEAD is not set +# CONFIG_RFKILL is not set # CONFIG_RUNLEVEL is not set CONFIG_RX=y +CONFIG_SETSERIAL=y CONFIG_SETSID=y CONFIG_STRINGS=y CONFIG_TASKSET=y @@ -724,23 +768,20 @@ CONFIG_FEATURE_TASKSET_FANCY=y CONFIG_TIME=y CONFIG_TIMEOUT=y CONFIG_TTYSIZE=y +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +CONFIG_UBIRENAME=y # CONFIG_VOLNAME is not set +# CONFIG_WALL is not set # CONFIG_WATCHDOG is not set # # Networking Utilities # -# CONFIG_NAMEIF is not set -# CONFIG_FEATURE_NAMEIF_EXTENDED is not set -CONFIG_NBDCLIENT=y -CONFIG_NC=y -CONFIG_NC_SERVER=y -CONFIG_NC_EXTRA=y -# CONFIG_NC_110_COMPAT is not set -CONFIG_PING=y -# CONFIG_PING6 is not set -CONFIG_FEATURE_FANCY_PING=y -# CONFIG_WHOIS is not set CONFIG_FEATURE_IPV6=y # CONFIG_FEATURE_UNIX_LOCAL is not set CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y @@ -752,17 +793,17 @@ CONFIG_FEATURE_BRCTL_FANCY=y CONFIG_FEATURE_BRCTL_SHOW=y CONFIG_DNSD=y # CONFIG_ETHER_WAKE is not set -# CONFIG_FAKEIDENTD is not set # CONFIG_FTPD is not set -# CONFIG_FEATURE_FTP_WRITE is not set +# CONFIG_FEATURE_FTPD_WRITE is not set # CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST is not set +# CONFIG_FEATURE_FTPD_AUTHENTICATION is not set CONFIG_FTPGET=y CONFIG_FTPPUT=y CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS=y # CONFIG_HOSTNAME is not set +CONFIG_DNSDOMAINNAME=y # CONFIG_HTTPD is not set # CONFIG_FEATURE_HTTPD_RANGES is not set -# CONFIG_FEATURE_HTTPD_USE_SENDFILE is not set # CONFIG_FEATURE_HTTPD_SETUID is not set # CONFIG_FEATURE_HTTPD_BASIC_AUTH is not set # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set @@ -781,11 +822,10 @@ CONFIG_FEATURE_IFCONFIG_HW=y # CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set # CONFIG_IFENSLAVE is not set # CONFIG_IFPLUGD is not set -# CONFIG_IFUPDOWN is not set +CONFIG_IFUP=y +CONFIG_IFDOWN=y CONFIG_IFUPDOWN_IFSTATE_PATH="" # CONFIG_FEATURE_IFUPDOWN_IP is not set -# CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN is not set -# CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set # CONFIG_FEATURE_IFUPDOWN_IPV4 is not set # CONFIG_FEATURE_IFUPDOWN_IPV6 is not set # CONFIG_FEATURE_IFUPDOWN_MAPPING is not set @@ -798,31 +838,46 @@ CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME=y # CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN is not set # CONFIG_FEATURE_INETD_RPC is not set CONFIG_IP=y +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_IPRULE is not set +CONFIG_IPNEIGH=y CONFIG_FEATURE_IP_ADDRESS=y CONFIG_FEATURE_IP_LINK=y CONFIG_FEATURE_IP_ROUTE=y +CONFIG_FEATURE_IP_ROUTE_DIR="/etc/iproute2" # CONFIG_FEATURE_IP_TUNNEL is not set CONFIG_FEATURE_IP_RULE=y -# CONFIG_FEATURE_IP_SHORT_FORMS is not set +CONFIG_FEATURE_IP_NEIGH=y # CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set -# CONFIG_IPADDR is not set -# CONFIG_IPLINK is not set -# CONFIG_IPROUTE is not set -# CONFIG_IPTUNNEL is not set -# CONFIG_IPRULE is not set # CONFIG_IPCALC is not set # CONFIG_FEATURE_IPCALC_FANCY is not set # CONFIG_FEATURE_IPCALC_LONG_OPTIONS is not set +# CONFIG_FAKEIDENTD is not set +# CONFIG_NAMEIF is not set +# CONFIG_FEATURE_NAMEIF_EXTENDED is not set +CONFIG_NBDCLIENT=y +CONFIG_NC=y +CONFIG_NC_SERVER=y +CONFIG_NC_EXTRA=y +# CONFIG_NC_110_COMPAT is not set CONFIG_NETSTAT=y CONFIG_FEATURE_NETSTAT_WIDE=y CONFIG_FEATURE_NETSTAT_PRG=y CONFIG_NSLOOKUP=y CONFIG_NTPD=y # CONFIG_FEATURE_NTPD_SERVER is not set +CONFIG_FEATURE_NTPD_CONF=y +CONFIG_PING=y +# CONFIG_PING6 is not set +CONFIG_FEATURE_FANCY_PING=y # CONFIG_PSCAN is not set CONFIG_ROUTE=y # CONFIG_SLATTACH is not set # CONFIG_TCPSVD is not set +# CONFIG_UDPSVD is not set CONFIG_TELNET=y CONFIG_FEATURE_TELNET_TTYPE=y # CONFIG_FEATURE_TELNET_AUTOLOGIN is not set @@ -843,10 +898,19 @@ CONFIG_FEATURE_TFTP_PUT=y CONFIG_TRACEROUTE=y # CONFIG_TRACEROUTE6 is not set CONFIG_FEATURE_TRACEROUTE_VERBOSE=y -# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set # CONFIG_TUNCTL is not set # CONFIG_FEATURE_TUNCTL_UG is not set +# CONFIG_VCONFIG is not set +CONFIG_WGET=y +CONFIG_FEATURE_WGET_STATUSBAR=y +CONFIG_FEATURE_WGET_AUTHENTICATION=y +CONFIG_FEATURE_WGET_LONG_OPTIONS=y +CONFIG_FEATURE_WGET_TIMEOUT=y +CONFIG_FEATURE_WGET_OPENSSL=y +CONFIG_FEATURE_WGET_SSL_HELPER=y +# CONFIG_WHOIS is not set +# CONFIG_ZCIP is not set # CONFIG_UDHCPC6 is not set # CONFIG_UDHCPD is not set # CONFIG_DHCPRELAY is not set @@ -856,6 +920,7 @@ CONFIG_FEATURE_TRACEROUTE_VERBOSE=y CONFIG_DHCPD_LEASES_FILE="" # CONFIG_UDHCPC is not set # CONFIG_FEATURE_UDHCPC_ARPING is not set +# CONFIG_FEATURE_UDHCPC_SANITIZEOPT is not set # CONFIG_FEATURE_UDHCP_PORT is not set CONFIG_UDHCP_DEBUG=0 # CONFIG_FEATURE_UDHCP_RFC3397 is not set @@ -863,14 +928,6 @@ CONFIG_UDHCP_DEBUG=0 CONFIG_UDHCPC_DEFAULT_SCRIPT="" CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=0 CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="" -# CONFIG_UDPSVD is not set -# CONFIG_VCONFIG is not set -CONFIG_WGET=y -CONFIG_FEATURE_WGET_STATUSBAR=y -CONFIG_FEATURE_WGET_AUTHENTICATION=y -CONFIG_FEATURE_WGET_LONG_OPTIONS=y -CONFIG_FEATURE_WGET_TIMEOUT=y -# CONFIG_ZCIP is not set # # Print Utilities @@ -883,25 +940,43 @@ CONFIG_FEATURE_WGET_TIMEOUT=y # Mail Utilities # # CONFIG_MAKEMIME is not set -CONFIG_FEATURE_MIME_CHARSET="" # CONFIG_POPMAILDIR is not set # CONFIG_FEATURE_POPMAILDIR_DELIVERY is not set # CONFIG_REFORMIME is not set # CONFIG_FEATURE_REFORMIME_COMPAT is not set # CONFIG_SENDMAIL is not set +CONFIG_FEATURE_MIME_CHARSET="" # # Process Utilities # +CONFIG_FREE=y +CONFIG_FUSER=y CONFIG_IOSTAT=y +CONFIG_KILL=y +CONFIG_KILLALL=y +CONFIG_KILLALL5=y CONFIG_LSOF=y CONFIG_MPSTAT=y CONFIG_NMETER=y +CONFIG_PGREP=y +CONFIG_PKILL=y +CONFIG_PIDOF=y +CONFIG_FEATURE_PIDOF_SINGLE=y +CONFIG_FEATURE_PIDOF_OMIT=y CONFIG_PMAP=y # CONFIG_POWERTOP is not set +CONFIG_PS=y +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +CONFIG_FEATURE_PS_TIME=y +CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set CONFIG_PSTREE=y CONFIG_PWDX=y +CONFIG_RENICE=y CONFIG_SMEMCAP=y +CONFIG_BB_SYSCTL=y CONFIG_TOP=y CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y @@ -911,41 +986,24 @@ CONFIG_FEATURE_TOP_SMP_PROCESS=y CONFIG_FEATURE_TOPMEM=y CONFIG_UPTIME=y # CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set -CONFIG_FREE=y -CONFIG_FUSER=y -CONFIG_KILL=y -CONFIG_KILLALL=y -CONFIG_KILLALL5=y -CONFIG_PGREP=y -CONFIG_PIDOF=y -CONFIG_FEATURE_PIDOF_SINGLE=y -CONFIG_FEATURE_PIDOF_OMIT=y -CONFIG_PKILL=y -CONFIG_PS=y -# CONFIG_FEATURE_PS_WIDE is not set -# CONFIG_FEATURE_PS_LONG is not set -CONFIG_FEATURE_PS_TIME=y -CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y -# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set -CONFIG_RENICE=y -CONFIG_BB_SYSCTL=y -CONFIG_FEATURE_SHOW_THREADS=y CONFIG_WATCH=y +CONFIG_FEATURE_SHOW_THREADS=y # # Runit Utilities # +# CONFIG_CHPST is not set +# CONFIG_SETUIDGID is not set +# CONFIG_ENVUIDGID is not set +# CONFIG_ENVDIR is not set +# CONFIG_SOFTLIMIT is not set # CONFIG_RUNSV is not set # CONFIG_RUNSVDIR is not set # CONFIG_FEATURE_RUNSVDIR_LOG is not set # CONFIG_SV is not set CONFIG_SV_DEFAULT_SERVICE_DIR="" +CONFIG_SVC=y # CONFIG_SVLOGD is not set -# CONFIG_CHPST is not set -# CONFIG_SETUIDGID is not set -# CONFIG_ENVUIDGID is not set -# CONFIG_ENVDIR is not set -# CONFIG_SOFTLIMIT is not set # # SELinux Utilities @@ -956,20 +1014,30 @@ CONFIG_GETENFORCE=y CONFIG_GETSEBOOL=y # CONFIG_LOAD_POLICY is not set CONFIG_MATCHPATHCON=y -CONFIG_RESTORECON=y CONFIG_RUNCON=y CONFIG_FEATURE_RUNCON_LONG_OPTIONS=y CONFIG_SELINUXENABLED=y +CONFIG_SESTATUS=y CONFIG_SETENFORCE=y CONFIG_SETFILES=y # CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +CONFIG_RESTORECON=y CONFIG_SETSEBOOL=y -CONFIG_SESTATUS=y # # Shells # +CONFIG_SH_IS_ASH=y +# CONFIG_SH_IS_HUSH is not set +# CONFIG_SH_IS_NONE is not set +# CONFIG_BASH_IS_ASH is not set +# CONFIG_BASH_IS_HUSH is not set +CONFIG_BASH_IS_NONE=y CONFIG_ASH=y +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +CONFIG_ASH_INTERNAL_GLOB=y +CONFIG_ASH_RANDOM_SUPPORT=y +CONFIG_ASH_EXPAND_PRMT=y CONFIG_ASH_BASH_COMPAT=y # CONFIG_ASH_IDLE_TIMEOUT is not set CONFIG_ASH_JOB_CONTROL=y @@ -978,11 +1046,9 @@ CONFIG_ASH_ALIAS=y CONFIG_ASH_BUILTIN_ECHO=y CONFIG_ASH_BUILTIN_PRINTF=y CONFIG_ASH_BUILTIN_TEST=y +CONFIG_ASH_HELP=y CONFIG_ASH_CMDCMD=y # CONFIG_ASH_MAIL is not set -CONFIG_ASH_OPTIMIZE_FOR_SIZE=y -CONFIG_ASH_RANDOM_SUPPORT=y -CONFIG_ASH_EXPAND_PRMT=y # CONFIG_CTTYHACK is not set # CONFIG_HUSH is not set # CONFIG_HUSH_BASH_COMPAT is not set @@ -1001,14 +1067,8 @@ CONFIG_ASH_EXPAND_PRMT=y # CONFIG_HUSH_EXPORT_N is not set # CONFIG_HUSH_MODE_X is not set # CONFIG_MSH is not set -CONFIG_FEATURE_SH_IS_ASH=y -# CONFIG_FEATURE_SH_IS_HUSH is not set -# CONFIG_FEATURE_SH_IS_NONE is not set -# CONFIG_FEATURE_BASH_IS_ASH is not set -# CONFIG_FEATURE_BASH_IS_HUSH is not set -CONFIG_FEATURE_BASH_IS_NONE=y -CONFIG_SH_MATH_SUPPORT=y -CONFIG_SH_MATH_SUPPORT_64=y +CONFIG_FEATURE_SH_MATH=y +CONFIG_FEATURE_SH_MATH_64=y CONFIG_FEATURE_SH_EXTRA_QUIET=y # CONFIG_FEATURE_SH_STANDALONE is not set # CONFIG_FEATURE_SH_NOFORK is not set @@ -1017,6 +1077,11 @@ CONFIG_FEATURE_SH_EXTRA_QUIET=y # # System Logging Utilities # +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set # CONFIG_SYSLOGD is not set # CONFIG_FEATURE_ROTATE_LOGFILE is not set # CONFIG_FEATURE_REMOTE_LOG is not set @@ -1025,9 +1090,4 @@ CONFIG_FEATURE_SH_EXTRA_QUIET=y CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 # CONFIG_FEATURE_IPC_SYSLOG is not set CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 -# CONFIG_LOGREAD is not set -# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set # CONFIG_FEATURE_KMSG_SYSLOG is not set -# CONFIG_KLOGD is not set -# CONFIG_FEATURE_KLOGD_KLOGCTL is not set -# CONFIG_LOGGER is not set diff --git a/busybox-full.sources b/busybox-full.sources index 64e80cc..307e78d 100644 --- a/busybox-full.sources +++ b/busybox-full.sources @@ -11,6 +11,7 @@ archival/libarchive/find_list_entry.c archival/libarchive/get_header_cpio.c arch archival/libarchive/get_header_tar_bz2.c archival/libarchive/get_header_tar_gz.c archival/libarchive/get_header_tar_lzma.c archival/libarchive/header_list.c archival/libarchive/header_skip.c archival/libarchive/header_verbose_list.c archival/libarchive/init_handle.c archival/libarchive/open_transformer.c archival/libarchive/seek_by_jump.c archival/libarchive/seek_by_read.c +archival/libarchive/common.c archival/libarchive/get_header_tar_xz.c archival/libarchive/unsafe_prefix.c console-tools/chvt.c console-tools/clear.c console-tools/deallocvt.c console-tools/fgconsole.c console-tools/openvt.c console-tools/reset.c console-tools/resize.c console-tools/setconsole.c console-tools/setkeycodes.c @@ -18,6 +19,7 @@ console-tools/reset.c console-tools/resize.c console-tools/setconsole.c console- coreutils/basename.c coreutils/cal.c coreutils/cat.c coreutils/catv.c coreutils/chgrp.c coreutils/chmod.c coreutils/chown.c coreutils/chroot.c coreutils/cp.c coreutils/cut.c coreutils/date.c coreutils/dd.c coreutils/df.c coreutils/dirname.c coreutils/dos2unix.c coreutils/du.c coreutils/echo.c coreutils/env.c coreutils/expr.c coreutils/false.c coreutils/fold.c coreutils/head.c coreutils/id.c coreutils/install.c coreutils/ln.c coreutils/ls.c coreutils/md5_sha1_sum.c coreutils/mkdir.c coreutils/mkfifo.c coreutils/mknod.c coreutils/mv.c coreutils/nice.c coreutils/nohup.c coreutils/od.c coreutils/printenv.c coreutils/printf.c coreutils/pwd.c coreutils/readlink.c coreutils/realpath.c coreutils/rm.c coreutils/rmdir.c coreutils/seq.c coreutils/sleep.c coreutils/sort.c coreutils/split.c coreutils/stat.c coreutils/stty.c coreutils/sync.c coreutils/tac.c coreutils/tail.c coreutils/tee.c coreutils/test.c coreutils/test_ptr_hack.c coreutils/touch.c coreutils/tr.c coreutils/true.c coreutils/uname.c coreutils/uniq.c coreutils/usleep.c coreutils/uudecode.c coreutils/uuencode.c coreutils/wc.c coreutils/whoami.c coreutils/yes.c coreutils/libcoreutils/cp_mv_stat.c coreutils/libcoreutils/getopt_mk_fifo_nod.c coreutils/comm.c coreutils/expand.c coreutils/sum.c coreutils/fsync.c +coreutils/shuf.c coreutils/truncate.c coreutils/unlink.c debianutils/mktemp.c debianutils/run_parts.c debianutils/which.c debianutils/pipe_progress.c @@ -25,16 +27,16 @@ editors/awk.c editors/cmp.c editors/diff.c editors/ed.c editors/patch.c editors/ e2fsprogs/e2fs_lib.c e2fsprogs/chattr.c e2fsprogs/lsattr.c e2fsprogs/tune2fs.c findutils/find.c findutils/grep.c findutils/xargs.c -init/halt.c init/mesg.c +init/halt.c init/mesg.c init/init.c libbb/missing_syscalls.c libbb/appletlib.c libbb/ask_confirmation.c libbb/bb_askpass.c libbb/bb_do_delay.c libbb/bb_pwd.c libbb/bb_qsort.c libbb/bb_strtonum.c libbb/change_identity.c libbb/chomp.c libbb/compare_string_array.c libbb/concat_path_file.c libbb/concat_subpath_file.c libbb/copy_file.c libbb/copyfd.c -libbb/crc32.c libbb/percent_decode.c libbb/default_error_retval.c libbb/device_open.c libbb/dump.c libbb/execable.c libbb/fclose_nonstdin.c +libbb/crc32.c libbb/percent_decode.c libbb/default_error_retval.c libbb/device_open.c libbb/dump.c libbb/executable.c libbb/fclose_nonstdin.c libbb/fflush_stdout_and_exit.c libbb/fgets_str.c libbb/find_mount_point.c libbb/find_pid_by_name.c libbb/find_root_device.c libbb/full_write.c libbb/get_console.c libbb/get_cpu_count.c libbb/get_last_path_component.c libbb/get_line_from_file.c libbb/get_volsize.c libbb/getopt32.c libbb/getpty.c libbb/get_shell_name.c -libbb/herror_msg.c libbb/human_readable.c libbb/inet_cksum.c libbb/inet_common.c libbb/info_msg.c libbb/inode_hash.c libbb/isdirectory.c +libbb/herror_msg.c libbb/human_readable.c libbb/inet_cksum.c libbb/inet_common.c libbb/inode_hash.c libbb/isdirectory.c libbb/kernel_version.c libbb/last_char_is.c libbb/lineedit.c libbb/lineedit_ptr_hack.c libbb/llist.c libbb/login.c libbb/loop.c libbb/make_directory.c libbb/makedev.c libbb/match_fstype.c libbb/hash_md5_sha.c libbb/bb_bswap_64.c libbb/messages.c libbb/mode_string.c libbb/mtab.c libbb/parse_config.c libbb/parse_mode.c libbb/perror_msg.c libbb/perror_nomsg.c libbb/perror_nomsg_and_die.c libbb/pidfile.c libbb/platform.c @@ -47,15 +49,21 @@ libbb/vdprintf.c libbb/verror_msg.c libbb/vfork_daemon_rexec.c libbb/warn_ignori libbb/write.c libbb/xatonum.c libbb/xconnect.c libbb/xfunc_die.c libbb/xfuncs.c libbb/xfuncs_printf.c libbb/xgetcwd.c libbb/xgethostbyname.c libbb/xreadlink.c libbb/xrealloc_vector.c libbb/xregcomp.c libbb/endofname.c libbb/in_ether.c libbb/nuke_str.c +libbb/auto_string.c libbb/bbunit.c libbb/common_bufsiz.c libbb/logenv.c libbb/replace.c libbb/sysconf.c libbb/ubi.c +libbb/pw_encrypt.c libpwdgrp/uidgid_get.c +loginutils/cryptpw.c + miscutils/adjtimex.c miscutils/bbconfig.c miscutils/crond.c miscutils/crontab.c miscutils/dc.c miscutils/devmem.c miscutils/fbsplash.c miscutils/flash_lock_unlock.c miscutils/flashcp.c miscutils/ionice.c miscutils/less.c miscutils/man.c miscutils/mountpoint.c miscutils/nandwrite.c miscutils/rx.c miscutils/setserial.c miscutils/setsid.c miscutils/strings.c miscutils/taskset.c miscutils/time.c miscutils/timeout.c miscutils/ttysize.c +miscutils/i2c_tools.c miscutils/ubirename.c modutils/depmod.c modutils/insmod.c modutils/lsmod.c modutils/modinfo.c modutils/modprobe.c modutils/modutils.c modutils/rmmod.c networking/arp.c networking/brctl.c networking/dnsd.c networking/ftpgetput.c networking/ifconfig.c networking/inetd.c networking/interface.c networking/ip.c networking/nbd-client.c networking/nc.c networking/netstat.c networking/nslookup.c networking/ntpd.c networking/ping.c networking/route.c networking/telnet.c networking/telnetd.c networking/tftp.c networking/traceroute.c networking/wget.c networking/libiproute/ip_parse_common_args.c networking/libiproute/ipaddress.c networking/libiproute/iplink.c networking/libiproute/iproute.c networking/libiproute/iprule.c networking/libiproute/libnetlink.c networking/libiproute/ll_addr.c networking/libiproute/ll_map.c networking/libiproute/ll_proto.c networking/libiproute/ll_types.c networking/libiproute/rt_names.c networking/libiproute/rtm_map.c networking/libiproute/utils.c - +networking/libiproute/ipneigh.c +networking/hostname.c networking/ifupdown.c procps/free.c procps/fuser.c procps/kill.c procps/pgrep.c procps/pidof.c procps/ps.c procps/renice.c procps/sysctl.c procps/top.c procps/uptime.c procps/watch.c procps/pmap.c procps/iostat.c procps/mpstat.c @@ -68,6 +76,8 @@ selinux/chcon.c selinux/selinuxenabled.c selinux/getenforce.c selinux/sestatus.c selinux/setsebool.c selinux/getsebool.c selinux/runcon.c selinux/setenforce.c selinux/setfiles.c selinux/matchpathcon.c +runit/sv.c + util-linux/blkid.c util-linux/blockdev.c util-linux/dmesg.c util-linux/fdisk.c util-linux/findfs.c util-linux/flock.c util-linux/freeramdisk.c util-linux/fstrim.c util-linux/getopt.c util-linux/hexdump.c util-linux/hwclock.c util-linux/losetup.c util-linux/lspci.c util-linux/lsusb.c @@ -78,5 +88,7 @@ util-linux/swaponoff.c util-linux/switch_root.c util-linux/umount.c util-linux/volume_id/get_devname.c util-linux/volume_id/volume_id.c util-linux/volume_id/util.c util-linux/volume_id/ext.c util-linux/volume_id/fat.c util-linux/volume_id/iso9660.c util-linux/volume_id/ntfs.c util-linux/volume_id/linux_swap.c util-linux/volume_id/exfat.c util-linux/volume_id/squashfs.c util-linux/volume_id/f2fs.c +util-linux/volume_id/bcache.c util-linux/volume_id/ubifs.c -util-linux/fbset.c +util-linux/fbset.c util-linux/setarch.c util-linux/nsenter.c util-linux/unshare.c +util-linux/blkdiscard.c util-linux/fatattr.c util-linux/uevent.c \ No newline at end of file diff --git a/busybox-minimal.sources b/busybox-minimal.sources index 3ea4129..01da3e5 100644 --- a/busybox-minimal.sources +++ b/busybox-minimal.sources @@ -13,10 +13,10 @@ findutils/find.c findutils/grep.c findutils/xargs.c libbb/missing_syscalls.c libbb/appletlib.c libbb/ask_confirmation.c libbb/bb_askpass.c libbb/bb_do_delay.c libbb/bb_pwd.c libbb/bb_qsort.c libbb/bb_strtonum.c libbb/change_identity.c libbb/chomp.c libbb/compare_string_array.c libbb/concat_path_file.c libbb/concat_subpath_file.c libbb/copy_file.c libbb/copyfd.c -libbb/crc32.c libbb/default_error_retval.c libbb/device_open.c libbb/dump.c libbb/execable.c libbb/fclose_nonstdin.c +libbb/crc32.c libbb/default_error_retval.c libbb/device_open.c libbb/dump.c libbb/executable.c libbb/fclose_nonstdin.c libbb/fflush_stdout_and_exit.c libbb/fgets_str.c libbb/find_mount_point.c libbb/find_pid_by_name.c libbb/find_root_device.c libbb/full_write.c libbb/get_console.c libbb/get_last_path_component.c libbb/get_line_from_file.c libbb/get_shell_name.c libbb/endofname.c libbb/in_ether.c libbb/get_volsize.c -libbb/getopt32.c libbb/getpty.c libbb/herror_msg.c libbb/human_readable.c libbb/inet_common.c libbb/info_msg.c libbb/inode_hash.c libbb/isdirectory.c +libbb/getopt32.c libbb/getpty.c libbb/herror_msg.c libbb/human_readable.c libbb/inet_common.c libbb/inode_hash.c libbb/isdirectory.c libbb/kernel_version.c libbb/last_char_is.c libbb/lineedit.c libbb/lineedit_ptr_hack.c libbb/llist.c libbb/login.c libbb/loop.c libbb/make_directory.c libbb/makedev.c libbb/match_fstype.c libbb/hash_md5_sha.c libbb/bb_bswap_64.c libbb/messages.c libbb/mode_string.c libbb/mtab.c libbb/parse_config.c libbb/parse_mode.c libbb/perror_msg.c libbb/perror_nomsg.c libbb/perror_nomsg_and_die.c libbb/pidfile.c libbb/platform.c diff --git a/configs/TEST_nommu_defconfig b/configs/TEST_nommu_defconfig index b45afd9..08351a2 100644 --- a/configs/TEST_nommu_defconfig +++ b/configs/TEST_nommu_defconfig @@ -118,7 +118,6 @@ CONFIG_FEATURE_CPIO_O=y CONFIG_FEATURE_CPIO_P=y CONFIG_DPKG=y CONFIG_DPKG_DEB=y -CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY=y CONFIG_GUNZIP=y CONFIG_GZIP=y CONFIG_FEATURE_GZIP_LONG_OPTIONS=y @@ -390,7 +389,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_HALT=y # CONFIG_FEATURE_CALL_TELINIT is not set CONFIG_TELINIT_PATH="" @@ -760,7 +759,6 @@ CONFIG_TFTP_DEBUG=y CONFIG_TRACEROUTE=y CONFIG_TRACEROUTE6=y CONFIG_FEATURE_TRACEROUTE_VERBOSE=y -CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE=y CONFIG_FEATURE_TRACEROUTE_USE_ICMP=y CONFIG_UDHCPD=y CONFIG_DHCPRELAY=y diff --git a/configs/TEST_noprintf_defconfig b/configs/TEST_noprintf_defconfig index 809b60c..70dacec 100644 --- a/configs/TEST_noprintf_defconfig +++ b/configs/TEST_noprintf_defconfig @@ -130,7 +130,6 @@ CONFIG_FEATURE_SEAMLESS_Z=y # CONFIG_FEATURE_CPIO_P is not set # CONFIG_DPKG is not set # CONFIG_DPKG_DEB is not set -# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set # CONFIG_GUNZIP is not set # CONFIG_GZIP is not set # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set @@ -395,7 +394,7 @@ CONFIG_FEATURE_KILL_DELAY=0 # CONFIG_FEATURE_INIT_SYSLOG is not set # CONFIG_FEATURE_EXTRA_QUIET is not set # CONFIG_FEATURE_INIT_COREDUMPS is not set -# CONFIG_FEATURE_INITRD is not set +# CONFIG_LINUXRC is not set # CONFIG_HALT is not set # CONFIG_FEATURE_CALL_TELINIT is not set CONFIG_TELINIT_PATH="" @@ -762,7 +761,6 @@ CONFIG_IFUPDOWN_IFSTATE_PATH="" # CONFIG_TRACEROUTE is not set # CONFIG_TRACEROUTE6 is not set # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set -# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set # CONFIG_TUNCTL is not set # CONFIG_FEATURE_TUNCTL_UG is not set diff --git a/configs/TEST_rh9_defconfig b/configs/TEST_rh9_defconfig index 565b826..4a5fad3 100644 --- a/configs/TEST_rh9_defconfig +++ b/configs/TEST_rh9_defconfig @@ -128,7 +128,6 @@ CONFIG_FEATURE_CPIO_O=y CONFIG_FEATURE_CPIO_P=y # CONFIG_DPKG is not set # CONFIG_DPKG_DEB is not set -# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set CONFIG_GUNZIP=y CONFIG_GZIP=y CONFIG_FEATURE_GZIP_LONG_OPTIONS=y @@ -407,7 +406,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_HALT=y # CONFIG_FEATURE_CALL_TELINIT is not set CONFIG_TELINIT_PATH="" @@ -778,7 +777,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y CONFIG_TRACEROUTE=y CONFIG_TRACEROUTE6=y CONFIG_FEATURE_TRACEROUTE_VERBOSE=y -# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set CONFIG_TUNCTL=y CONFIG_FEATURE_TUNCTL_UG=y diff --git a/configs/android2_defconfig b/configs/android2_defconfig index 4dfbdb5..754f612 100644 --- a/configs/android2_defconfig +++ b/configs/android2_defconfig @@ -89,7 +89,6 @@ CONFIG_PREFIX="./_install" # # Busybox Library Tuning # -# CONFIG_FEATURE_SYSTEMD is not set # CONFIG_FEATURE_RTMINMAX is not set CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 @@ -135,7 +134,6 @@ CONFIG_FEATURE_CPIO_O=y CONFIG_FEATURE_CPIO_P=y CONFIG_DPKG=y CONFIG_DPKG_DEB=y -# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set CONFIG_GUNZIP=y CONFIG_GZIP=y # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set @@ -426,7 +424,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_INIT_TERMINAL_TYPE="linux" CONFIG_MESG=y CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y @@ -815,7 +813,6 @@ CONFIG_TCPSVD=y # CONFIG_TRACEROUTE is not set # CONFIG_TRACEROUTE6 is not set # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set -# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set CONFIG_TUNCTL=y CONFIG_FEATURE_TUNCTL_UG=y diff --git a/configs/android_502_defconfig b/configs/android_502_defconfig new file mode 100644 index 0000000..8ea6c29 --- a/dev/null +++ b/configs/android_502_defconfig @@ -0,0 +1,1140 @@ +## This config was successfully used to build busybox on +## Samsung SM-T700 tablet +## Android 5.0.2 +## gcc/toolchain from https://termux.com/ +## binutils 2.26.20160125 +## gcc 4.9.3 +## bionic ANDROID_API 21 +## +## Static build did not work (static libraries not installed?): +## # CONFIG_STATIC is not set +## syslog() requires an additional library: +## CONFIG_EXTRA_LDLIBS="log" +## Bionic's botched off_t: +## # CONFIG_LFS is not set +## +## Incompatible password database API: +## # CONFIG_FEATURE_SHADOWPASSWDS is not set +## # CONFIG_USE_BB_PWD_GRP is not set +## # CONFIG_USE_BB_SHADOW is not set +## # CONFIG_ADDUSER is not set +## # CONFIG_ADDGROUP is not set +## # CONFIG_DELUSER is not set +## # CONFIG_DELGROUP is not set +## +## No utmp/wtmp: +## # CONFIG_FEATURE_UTMP is not set +## # CONFIG_FEATURE_WTMP is not set +## # CONFIG_WHO is not set +## # CONFIG_LAST is not set +## # CONFIG_USERS is not set +## # CONFIG_WALL is not set +## +## Assorted header problems: +## # CONFIG_HOSTID is not set +## # CONFIG_FEATURE_SYNC_FANCY is not set - syncfs() +## # CONFIG_FEATURE_TOUCH_NODEREF is not set - lutimes() +## # CONFIG_LOGNAME is not set - getlogin_r() +## # CONFIG_LOADFONT is not set +## # CONFIG_SETFONT is not set +## # CONFIG_MDEV is not set +## # CONFIG_FSCK_MINIX is not set +## # CONFIG_MKFS_MINIX is not set +## # CONFIG_IPCRM is not set +## # CONFIG_IPCS is not set +## # CONFIG_SWAPONOFF is not set +## # CONFIG_CONSPY is not set +## # CONFIG_NANDWRITE is not set +## # CONFIG_NANDDUMP is not set +## # CONFIG_RFKILL is not set +## # CONFIG_UBIATTACH is not set +## # CONFIG_UBIDETACH is not set +## # CONFIG_UBIMKVOL is not set +## # CONFIG_UBIRMVOL is not set +## # CONFIG_UBIRSVOL is not set +## # CONFIG_UBIUPDATEVOL is not set +## # CONFIG_FEATURE_EJECT_SCSI is not set - scsi headers +## # CONFIG_ARP is not set +## # CONFIG_ARPING is not set +## # CONFIG_ETHER_WAKE is not set +## # CONFIG_IFCONFIG is not set +## # CONFIG_IFENSLAVE is not set +## # CONFIG_NSLOOKUP is not set +## # CONFIG_ROUTE is not set +## # CONFIG_ZCIP is not set +## # CONFIG_HUSH is not set - glob.h +## # CONFIG_KLOGD is not set +## # CONFIG_LOGGER is not set +## # CONFIG_LOGREAD is not set +## # CONFIG_SYSLOGD is not set +##----------------------------------------------- + +# +# Automatically generated make config: don't edit +# Busybox version: 1.25.0.git +# Mon Mar 14 20:43:42 2016 +# +CONFIG_HAVE_DOT_CONFIG=y + +# +# Busybox Settings +# + +# +# General Configuration +# +CONFIG_DESKTOP=y +# CONFIG_EXTRA_COMPAT is not set +CONFIG_INCLUDE_SUSv2=y +# CONFIG_USE_PORTABLE_CODE is not set +CONFIG_PLATFORM_LINUX=y +CONFIG_FEATURE_BUFFERS_USE_MALLOC=y +# CONFIG_FEATURE_BUFFERS_GO_ON_STACK is not set +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_SHOW_USAGE=y +CONFIG_FEATURE_VERBOSE_USAGE=y +CONFIG_FEATURE_COMPRESS_USAGE=y +CONFIG_FEATURE_INSTALLER=y +# CONFIG_INSTALL_NO_USR is not set +# CONFIG_LOCALE_SUPPORT is not set +CONFIG_UNICODE_SUPPORT=y +# CONFIG_UNICODE_USING_LOCALE is not set +# CONFIG_FEATURE_CHECK_UNICODE_IN_ENV is not set +CONFIG_SUBST_WCHAR=63 +CONFIG_LAST_SUPPORTED_WCHAR=767 +# CONFIG_UNICODE_COMBINING_WCHARS is not set +# CONFIG_UNICODE_WIDE_WCHARS is not set +# CONFIG_UNICODE_BIDI_SUPPORT is not set +# CONFIG_UNICODE_NEUTRAL_TABLE is not set +# CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_PAM is not set +CONFIG_FEATURE_USE_SENDFILE=y +CONFIG_LONG_OPTS=y +CONFIG_FEATURE_DEVPTS=y +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_UTMP is not set +# CONFIG_FEATURE_WTMP is not set +CONFIG_FEATURE_PIDFILE=y +CONFIG_PID_FILE_PATH="/var/run" +CONFIG_FEATURE_SUID=y +CONFIG_FEATURE_SUID_CONFIG=y +CONFIG_FEATURE_SUID_CONFIG_QUIET=y +# CONFIG_SELINUX is not set +# CONFIG_FEATURE_PREFER_APPLETS is not set +CONFIG_BUSYBOX_EXEC_PATH="/proc/self/exe" +CONFIG_FEATURE_SYSLOG=y +# CONFIG_FEATURE_HAVE_RPC is not set + +# +# Build Options +# +# CONFIG_STATIC is not set +# CONFIG_PIE is not set +# CONFIG_NOMMU is not set +# CONFIG_BUILD_LIBBUSYBOX is not set +# CONFIG_FEATURE_INDIVIDUAL is not set +# CONFIG_FEATURE_SHARED_BUSYBOX is not set +# CONFIG_LFS is not set +CONFIG_CROSS_COMPILER_PREFIX="" +CONFIG_SYSROOT="" +CONFIG_EXTRA_CFLAGS="" +CONFIG_EXTRA_LDFLAGS="" +CONFIG_EXTRA_LDLIBS="log" + +# +# Debugging Options +# +# CONFIG_DEBUG is not set +# CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_DEBUG_SANITIZE is not set +# CONFIG_UNIT_TEST is not set +# CONFIG_WERROR is not set +CONFIG_NO_DEBUG_LIB=y +# CONFIG_DMALLOC is not set +# CONFIG_EFENCE is not set + +# +# Installation Options ("make install" behavior) +# +CONFIG_INSTALL_APPLET_SYMLINKS=y +# CONFIG_INSTALL_APPLET_HARDLINKS is not set +# CONFIG_INSTALL_APPLET_SCRIPT_WRAPPERS is not set +# CONFIG_INSTALL_APPLET_DONT is not set +# CONFIG_INSTALL_SH_APPLET_SYMLINK is not set +# CONFIG_INSTALL_SH_APPLET_HARDLINK is not set +# CONFIG_INSTALL_SH_APPLET_SCRIPT_WRAPPER is not set +CONFIG_PREFIX="./_install" + +# +# Busybox Library Tuning +# +CONFIG_FEATURE_RTMINMAX=y +CONFIG_PASSWORD_MINLEN=6 +CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 +# CONFIG_FEATURE_FAST_TOP is not set +# CONFIG_FEATURE_ETC_NETWORKS is not set +CONFIG_FEATURE_USE_TERMIOS=y +CONFIG_FEATURE_EDITING=y +CONFIG_FEATURE_EDITING_MAX_LEN=1024 +# CONFIG_FEATURE_EDITING_VI is not set +CONFIG_FEATURE_EDITING_HISTORY=255 +CONFIG_FEATURE_EDITING_SAVEHISTORY=y +# CONFIG_FEATURE_EDITING_SAVE_ON_EXIT is not set +CONFIG_FEATURE_REVERSE_SEARCH=y +CONFIG_FEATURE_TAB_COMPLETION=y +# CONFIG_FEATURE_USERNAME_COMPLETION is not set +CONFIG_FEATURE_EDITING_FANCY_PROMPT=y +# CONFIG_FEATURE_EDITING_ASK_TERMINAL is not set +CONFIG_FEATURE_NON_POSIX_CP=y +# CONFIG_FEATURE_VERBOSE_CP_MESSAGE is not set +CONFIG_FEATURE_COPYBUF_KB=4 +CONFIG_FEATURE_SKIP_ROOTFS=y +CONFIG_MONOTONIC_SYSCALL=y +CONFIG_IOCTL_HEX2STR_ERROR=y +CONFIG_FEATURE_HWIB=y + +# +# Applets +# + +# +# Archival Utilities +# +CONFIG_FEATURE_SEAMLESS_XZ=y +CONFIG_FEATURE_SEAMLESS_LZMA=y +CONFIG_FEATURE_SEAMLESS_BZ2=y +CONFIG_FEATURE_SEAMLESS_GZ=y +# CONFIG_FEATURE_SEAMLESS_Z is not set +# CONFIG_AR is not set +# CONFIG_FEATURE_AR_LONG_FILENAMES is not set +# CONFIG_FEATURE_AR_CREATE is not set +# CONFIG_UNCOMPRESS is not set +CONFIG_GUNZIP=y +CONFIG_FEATURE_GUNZIP_LONG_OPTIONS=y +CONFIG_BUNZIP2=y +CONFIG_UNLZMA=y +# CONFIG_FEATURE_LZMA_FAST is not set +CONFIG_LZMA=y +CONFIG_UNXZ=y +CONFIG_XZ=y +CONFIG_BZIP2=y +CONFIG_CPIO=y +CONFIG_FEATURE_CPIO_O=y +CONFIG_FEATURE_CPIO_P=y +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +CONFIG_GZIP=y +CONFIG_FEATURE_GZIP_LONG_OPTIONS=y +CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set +CONFIG_LZOP=y +# CONFIG_LZOP_COMPR_HIGH is not set +CONFIG_RPM=y +CONFIG_RPM2CPIO=y +CONFIG_TAR=y +CONFIG_FEATURE_TAR_CREATE=y +CONFIG_FEATURE_TAR_AUTODETECT=y +CONFIG_FEATURE_TAR_FROM=y +CONFIG_FEATURE_TAR_OLDGNU_COMPATIBILITY=y +CONFIG_FEATURE_TAR_OLDSUN_COMPATIBILITY=y +CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y +CONFIG_FEATURE_TAR_LONG_OPTIONS=y +CONFIG_FEATURE_TAR_TO_COMMAND=y +CONFIG_FEATURE_TAR_UNAME_GNAME=y +CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y +# CONFIG_FEATURE_TAR_SELINUX is not set +CONFIG_UNZIP=y + +# +# Coreutils +# +CONFIG_BASENAME=y +CONFIG_CAT=y +CONFIG_DATE=y +CONFIG_FEATURE_DATE_ISOFMT=y +# CONFIG_FEATURE_DATE_NANO is not set +CONFIG_FEATURE_DATE_COMPAT=y +CONFIG_DD=y +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y +CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y +CONFIG_FEATURE_DD_IBS_OBS=y +CONFIG_FEATURE_DD_STATUS=y +# CONFIG_HOSTID is not set +CONFIG_ID=y +CONFIG_GROUPS=y +CONFIG_SHUF=y +CONFIG_STAT=y +CONFIG_FEATURE_STAT_FORMAT=y +CONFIG_FEATURE_STAT_FILESYSTEM=y +CONFIG_SYNC=y +# CONFIG_FEATURE_SYNC_FANCY is not set +CONFIG_TEST=y +CONFIG_FEATURE_TEST_64=y +CONFIG_TOUCH=y +# CONFIG_FEATURE_TOUCH_NODEREF is not set +CONFIG_FEATURE_TOUCH_SUSV3=y +CONFIG_TR=y +CONFIG_FEATURE_TR_CLASSES=y +CONFIG_FEATURE_TR_EQUIV=y +CONFIG_TRUNCATE=y +CONFIG_UNLINK=y +CONFIG_BASE64=y +# CONFIG_WHO is not set +# CONFIG_USERS is not set +CONFIG_CAL=y +CONFIG_CATV=y +CONFIG_CHGRP=y +CONFIG_CHMOD=y +CONFIG_CHOWN=y +CONFIG_FEATURE_CHOWN_LONG_OPTIONS=y +CONFIG_CHROOT=y +CONFIG_CKSUM=y +CONFIG_COMM=y +CONFIG_CP=y +CONFIG_FEATURE_CP_LONG_OPTIONS=y +CONFIG_CUT=y +CONFIG_DF=y +CONFIG_FEATURE_DF_FANCY=y +CONFIG_DIRNAME=y +CONFIG_DOS2UNIX=y +CONFIG_UNIX2DOS=y +CONFIG_DU=y +CONFIG_FEATURE_DU_DEFAULT_BLOCKSIZE_1K=y +CONFIG_ECHO=y +CONFIG_FEATURE_FANCY_ECHO=y +CONFIG_ENV=y +CONFIG_FEATURE_ENV_LONG_OPTIONS=y +CONFIG_EXPAND=y +CONFIG_FEATURE_EXPAND_LONG_OPTIONS=y +CONFIG_EXPR=y +CONFIG_EXPR_MATH_SUPPORT_64=y +CONFIG_FALSE=y +CONFIG_FOLD=y +CONFIG_FSYNC=y +CONFIG_HEAD=y +CONFIG_FEATURE_FANCY_HEAD=y +CONFIG_INSTALL=y +CONFIG_FEATURE_INSTALL_LONG_OPTIONS=y +CONFIG_LN=y +# CONFIG_LOGNAME is not set +CONFIG_LS=y +CONFIG_FEATURE_LS_FILETYPES=y +CONFIG_FEATURE_LS_FOLLOWLINKS=y +CONFIG_FEATURE_LS_RECURSIVE=y +CONFIG_FEATURE_LS_SORTFILES=y +CONFIG_FEATURE_LS_TIMESTAMPS=y +CONFIG_FEATURE_LS_USERNAME=y +CONFIG_FEATURE_LS_COLOR=y +CONFIG_FEATURE_LS_COLOR_IS_DEFAULT=y +CONFIG_MD5SUM=y +CONFIG_MKDIR=y +CONFIG_FEATURE_MKDIR_LONG_OPTIONS=y +CONFIG_MKFIFO=y +CONFIG_MKNOD=y +CONFIG_MV=y +CONFIG_FEATURE_MV_LONG_OPTIONS=y +CONFIG_NICE=y +CONFIG_NOHUP=y +CONFIG_OD=y +CONFIG_PRINTENV=y +CONFIG_PRINTF=y +CONFIG_PWD=y +CONFIG_READLINK=y +CONFIG_FEATURE_READLINK_FOLLOW=y +CONFIG_REALPATH=y +CONFIG_RM=y +CONFIG_RMDIR=y +CONFIG_FEATURE_RMDIR_LONG_OPTIONS=y +CONFIG_SEQ=y +CONFIG_SHA1SUM=y +CONFIG_SHA256SUM=y +CONFIG_SHA512SUM=y +CONFIG_SHA3SUM=y +CONFIG_SLEEP=y +CONFIG_FEATURE_FANCY_SLEEP=y +CONFIG_FEATURE_FLOAT_SLEEP=y +CONFIG_SORT=y +CONFIG_FEATURE_SORT_BIG=y +CONFIG_SPLIT=y +CONFIG_FEATURE_SPLIT_FANCY=y +CONFIG_STTY=y +CONFIG_SUM=y +CONFIG_TAC=y +CONFIG_TAIL=y +CONFIG_FEATURE_FANCY_TAIL=y +CONFIG_TEE=y +CONFIG_FEATURE_TEE_USE_BLOCK_IO=y +CONFIG_TRUE=y +CONFIG_TTY=y +CONFIG_UNAME=y +CONFIG_UNAME_OSNAME="GNU/Linux" +CONFIG_UNEXPAND=y +CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS=y +CONFIG_UNIQ=y +CONFIG_USLEEP=y +CONFIG_UUDECODE=y +CONFIG_UUENCODE=y +CONFIG_WC=y +CONFIG_FEATURE_WC_LARGE=y +CONFIG_WHOAMI=y +CONFIG_YES=y + +# +# Common options +# +CONFIG_FEATURE_VERBOSE=y + +# +# Common options for cp and mv +# +CONFIG_FEATURE_PRESERVE_HARDLINKS=y + +# +# Common options for ls, more and telnet +# +CONFIG_FEATURE_AUTOWIDTH=y + +# +# Common options for df, du, ls +# +CONFIG_FEATURE_HUMAN_READABLE=y + +# +# Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum +# +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y + +# +# Console Utilities +# +CONFIG_CHVT=y +CONFIG_FGCONSOLE=y +CONFIG_CLEAR=y +CONFIG_DEALLOCVT=y +CONFIG_DUMPKMAP=y +CONFIG_KBD_MODE=y +# CONFIG_LOADFONT is not set +CONFIG_LOADKMAP=y +CONFIG_OPENVT=y +CONFIG_RESET=y +CONFIG_RESIZE=y +CONFIG_FEATURE_RESIZE_PRINT=y +CONFIG_SETCONSOLE=y +CONFIG_FEATURE_SETCONSOLE_LONG_OPTIONS=y +# CONFIG_SETFONT is not set +# CONFIG_FEATURE_SETFONT_TEXTUAL_MAP is not set +CONFIG_DEFAULT_SETFONT_DIR="" +CONFIG_SETKEYCODES=y +CONFIG_SETLOGCONS=y +CONFIG_SHOWKEY=y +# CONFIG_FEATURE_LOADFONT_PSF2 is not set +# CONFIG_FEATURE_LOADFONT_RAW is not set + +# +# Debian Utilities +# +CONFIG_MKTEMP=y +CONFIG_PIPE_PROGRESS=y +CONFIG_RUN_PARTS=y +CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS=y +CONFIG_FEATURE_RUN_PARTS_FANCY=y +CONFIG_START_STOP_DAEMON=y +CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y +CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS=y +CONFIG_WHICH=y + +# +# Editors +# +CONFIG_AWK=y +CONFIG_FEATURE_AWK_LIBM=y +CONFIG_FEATURE_AWK_GNU_EXTENSIONS=y +CONFIG_CMP=y +CONFIG_DIFF=y +CONFIG_FEATURE_DIFF_LONG_OPTIONS=y +CONFIG_FEATURE_DIFF_DIR=y +CONFIG_ED=y +CONFIG_PATCH=y +CONFIG_SED=y +CONFIG_VI=y +CONFIG_FEATURE_VI_MAX_LEN=4096 +# CONFIG_FEATURE_VI_8BIT is not set +CONFIG_FEATURE_VI_COLON=y +CONFIG_FEATURE_VI_YANKMARK=y +CONFIG_FEATURE_VI_SEARCH=y +# CONFIG_FEATURE_VI_REGEX_SEARCH is not set +CONFIG_FEATURE_VI_USE_SIGNALS=y +CONFIG_FEATURE_VI_DOT_CMD=y +CONFIG_FEATURE_VI_READONLY=y +CONFIG_FEATURE_VI_SETOPTS=y +CONFIG_FEATURE_VI_SET=y +CONFIG_FEATURE_VI_WIN_RESIZE=y +CONFIG_FEATURE_VI_ASK_TERMINAL=y +CONFIG_FEATURE_VI_UNDO=y +CONFIG_FEATURE_VI_UNDO_QUEUE=y +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 +CONFIG_FEATURE_ALLOW_EXEC=y + +# +# Finding Utilities +# +CONFIG_FIND=y +CONFIG_FEATURE_FIND_PRINT0=y +CONFIG_FEATURE_FIND_MTIME=y +CONFIG_FEATURE_FIND_MMIN=y +CONFIG_FEATURE_FIND_PERM=y +CONFIG_FEATURE_FIND_TYPE=y +CONFIG_FEATURE_FIND_XDEV=y +CONFIG_FEATURE_FIND_MAXDEPTH=y +CONFIG_FEATURE_FIND_NEWER=y +CONFIG_FEATURE_FIND_INUM=y +CONFIG_FEATURE_FIND_EXEC=y +CONFIG_FEATURE_FIND_EXEC_PLUS=y +CONFIG_FEATURE_FIND_USER=y +CONFIG_FEATURE_FIND_GROUP=y +CONFIG_FEATURE_FIND_NOT=y +CONFIG_FEATURE_FIND_DEPTH=y +CONFIG_FEATURE_FIND_PAREN=y +CONFIG_FEATURE_FIND_SIZE=y +CONFIG_FEATURE_FIND_PRUNE=y +CONFIG_FEATURE_FIND_DELETE=y +CONFIG_FEATURE_FIND_PATH=y +CONFIG_FEATURE_FIND_REGEX=y +# CONFIG_FEATURE_FIND_CONTEXT is not set +CONFIG_FEATURE_FIND_LINKS=y +CONFIG_GREP=y +CONFIG_FEATURE_GREP_EGREP_ALIAS=y +CONFIG_FEATURE_GREP_FGREP_ALIAS=y +CONFIG_FEATURE_GREP_CONTEXT=y +CONFIG_XARGS=y +CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y +CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y +CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y +CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y +CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR=y + +# +# Init Utilities +# +CONFIG_BOOTCHARTD=y +CONFIG_FEATURE_BOOTCHARTD_BLOATED_HEADER=y +CONFIG_FEATURE_BOOTCHARTD_CONFIG_FILE=y +CONFIG_HALT=y +# CONFIG_FEATURE_CALL_TELINIT is not set +CONFIG_TELINIT_PATH="" +CONFIG_INIT=y +CONFIG_FEATURE_USE_INITTAB=y +# CONFIG_FEATURE_KILL_REMOVED is not set +CONFIG_FEATURE_KILL_DELAY=0 +CONFIG_FEATURE_INIT_SCTTY=y +CONFIG_FEATURE_INIT_SYSLOG=y +CONFIG_FEATURE_EXTRA_QUIET=y +CONFIG_FEATURE_INIT_COREDUMPS=y +CONFIG_LINUXRC=y +CONFIG_INIT_TERMINAL_TYPE="linux" +CONFIG_FEATURE_INIT_MODIFY_CMDLINE=y +CONFIG_MESG=y +CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y + +# +# Login/Password Management Utilities +# +# CONFIG_FEATURE_SHADOWPASSWDS is not set +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_USE_BB_SHADOW is not set +CONFIG_USE_BB_CRYPT=y +CONFIG_USE_BB_CRYPT_SHA=y +CONFIG_ADD_SHELL=y +CONFIG_REMOVE_SHELL=y +# CONFIG_ADDGROUP is not set +# CONFIG_FEATURE_ADDGROUP_LONG_OPTIONS is not set +# CONFIG_FEATURE_ADDUSER_TO_GROUP is not set +# CONFIG_ADDUSER is not set +# CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set +# CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 +CONFIG_FIRST_SYSTEM_ID=0 +CONFIG_LAST_SYSTEM_ID=0 +CONFIG_CHPASSWD=y +CONFIG_FEATURE_DEFAULT_PASSWD_ALGO="des" +CONFIG_CRYPTPW=y +# CONFIG_DELUSER is not set +# CONFIG_DELGROUP is not set +# CONFIG_FEATURE_DEL_USER_FROM_GROUP is not set +CONFIG_GETTY=y +CONFIG_LOGIN=y +# CONFIG_LOGIN_SESSION_AS_CHILD is not set +CONFIG_LOGIN_SCRIPTS=y +CONFIG_FEATURE_NOLOGIN=y +CONFIG_FEATURE_SECURETTY=y +CONFIG_PASSWD=y +CONFIG_FEATURE_PASSWD_WEAK_CHECK=y +CONFIG_SU=y +CONFIG_FEATURE_SU_SYSLOG=y +CONFIG_FEATURE_SU_CHECKS_SHELLS=y +CONFIG_SULOGIN=y +CONFIG_VLOCK=y + +# +# Linux Ext2 FS Progs +# +CONFIG_CHATTR=y +CONFIG_FSCK=y +CONFIG_LSATTR=y +# CONFIG_TUNE2FS is not set + +# +# Linux Module Utilities +# +CONFIG_MODINFO=y +CONFIG_MODPROBE_SMALL=y +CONFIG_FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE=y +CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y +# CONFIG_INSMOD is not set +# CONFIG_RMMOD is not set +# CONFIG_LSMOD is not set +# CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT is not set +# CONFIG_MODPROBE is not set +# CONFIG_FEATURE_MODPROBE_BLACKLIST is not set +# CONFIG_DEPMOD is not set + +# +# Options common to multiple modutils +# +# CONFIG_FEATURE_2_4_MODULES is not set +# CONFIG_FEATURE_INSMOD_TRY_MMAP is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL is not set +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set +# CONFIG_FEATURE_MODUTILS_ALIAS is not set +# CONFIG_FEATURE_MODUTILS_SYMBOLS is not set +CONFIG_DEFAULT_MODULES_DIR="/lib/modules" +CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" + +# +# Linux System Utilities +# +CONFIG_BLKDISCARD=y +CONFIG_BLOCKDEV=y +CONFIG_FATATTR=y +CONFIG_FSTRIM=y +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +CONFIG_MOUNT=y +CONFIG_FEATURE_MOUNT_FAKE=y +CONFIG_FEATURE_MOUNT_VERBOSE=y +# CONFIG_FEATURE_MOUNT_HELPERS is not set +CONFIG_FEATURE_MOUNT_LABEL=y +# CONFIG_FEATURE_MOUNT_NFS is not set +CONFIG_FEATURE_MOUNT_CIFS=y +CONFIG_FEATURE_MOUNT_FLAGS=y +CONFIG_FEATURE_MOUNT_FSTAB=y +CONFIG_FEATURE_MOUNT_OTHERTAB=y +CONFIG_REV=y +CONFIG_SETARCH=y +CONFIG_UEVENT=y +CONFIG_ACPID=y +CONFIG_FEATURE_ACPID_COMPAT=y +CONFIG_BLKID=y +# CONFIG_FEATURE_BLKID_TYPE is not set +CONFIG_DMESG=y +CONFIG_FEATURE_DMESG_PRETTY=y +CONFIG_FBSET=y +CONFIG_FEATURE_FBSET_FANCY=y +CONFIG_FEATURE_FBSET_READMODE=y +CONFIG_FDFLUSH=y +CONFIG_FDFORMAT=y +CONFIG_FDISK=y +CONFIG_FDISK_SUPPORT_LARGE_DISKS=y +CONFIG_FEATURE_FDISK_WRITABLE=y +# CONFIG_FEATURE_AIX_LABEL is not set +# CONFIG_FEATURE_SGI_LABEL is not set +# CONFIG_FEATURE_SUN_LABEL is not set +# CONFIG_FEATURE_OSF_LABEL is not set +# CONFIG_FEATURE_GPT_LABEL is not set +CONFIG_FEATURE_FDISK_ADVANCED=y +CONFIG_FINDFS=y +CONFIG_FLOCK=y +CONFIG_FREERAMDISK=y +# CONFIG_FSCK_MINIX is not set +CONFIG_MKFS_EXT2=y +# CONFIG_MKFS_MINIX is not set +# CONFIG_FEATURE_MINIX2 is not set +# CONFIG_MKFS_REISER is not set +CONFIG_MKFS_VFAT=y +CONFIG_GETOPT=y +CONFIG_FEATURE_GETOPT_LONG=y +CONFIG_HEXDUMP=y +CONFIG_FEATURE_HEXDUMP_REVERSE=y +CONFIG_HD=y +CONFIG_HWCLOCK=y +CONFIG_FEATURE_HWCLOCK_LONG_OPTIONS=y +# CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS is not set +# CONFIG_IPCRM is not set +# CONFIG_IPCS is not set +CONFIG_LOSETUP=y +CONFIG_LSPCI=y +CONFIG_LSUSB=y +CONFIG_MKSWAP=y +CONFIG_FEATURE_MKSWAP_UUID=y +CONFIG_MORE=y +CONFIG_PIVOT_ROOT=y +CONFIG_RDATE=y +CONFIG_RDEV=y +CONFIG_READPROFILE=y +CONFIG_RTCWAKE=y +CONFIG_SCRIPT=y +CONFIG_SCRIPTREPLAY=y +# CONFIG_SWAPONOFF is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set +# CONFIG_FEATURE_SWAPON_PRI is not set +CONFIG_SWITCH_ROOT=y +CONFIG_UMOUNT=y +CONFIG_FEATURE_UMOUNT_ALL=y + +# +# Common options for mount/umount +# +CONFIG_FEATURE_MOUNT_LOOP=y +CONFIG_FEATURE_MOUNT_LOOP_CREATE=y +# CONFIG_FEATURE_MTAB_SUPPORT is not set +CONFIG_VOLUMEID=y + +# +# Filesystem/Volume identification +# +CONFIG_FEATURE_VOLUMEID_BCACHE=y +CONFIG_FEATURE_VOLUMEID_BTRFS=y +CONFIG_FEATURE_VOLUMEID_CRAMFS=y +CONFIG_FEATURE_VOLUMEID_EXFAT=y +CONFIG_FEATURE_VOLUMEID_EXT=y +CONFIG_FEATURE_VOLUMEID_F2FS=y +CONFIG_FEATURE_VOLUMEID_FAT=y +CONFIG_FEATURE_VOLUMEID_HFS=y +CONFIG_FEATURE_VOLUMEID_ISO9660=y +CONFIG_FEATURE_VOLUMEID_JFS=y +CONFIG_FEATURE_VOLUMEID_LINUXRAID=y +CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y +CONFIG_FEATURE_VOLUMEID_LUKS=y +CONFIG_FEATURE_VOLUMEID_NILFS=y +CONFIG_FEATURE_VOLUMEID_NTFS=y +CONFIG_FEATURE_VOLUMEID_OCFS2=y +CONFIG_FEATURE_VOLUMEID_REISERFS=y +CONFIG_FEATURE_VOLUMEID_ROMFS=y +# CONFIG_FEATURE_VOLUMEID_SQUASHFS is not set +CONFIG_FEATURE_VOLUMEID_SYSV=y +CONFIG_FEATURE_VOLUMEID_UDF=y +CONFIG_FEATURE_VOLUMEID_XFS=y + +# +# Miscellaneous Utilities +# +# CONFIG_CONSPY is not set +CONFIG_CROND=y +CONFIG_FEATURE_CROND_D=y +CONFIG_FEATURE_CROND_CALL_SENDMAIL=y +CONFIG_FEATURE_CROND_DIR="/var/spool/cron" +CONFIG_I2CGET=y +CONFIG_I2CSET=y +CONFIG_I2CDUMP=y +CONFIG_I2CDETECT=y +CONFIG_LESS=y +CONFIG_FEATURE_LESS_MAXLINES=9999999 +CONFIG_FEATURE_LESS_BRACKETS=y +CONFIG_FEATURE_LESS_FLAGS=y +CONFIG_FEATURE_LESS_TRUNCATE=y +CONFIG_FEATURE_LESS_MARKS=y +CONFIG_FEATURE_LESS_REGEXP=y +CONFIG_FEATURE_LESS_WINCH=y +CONFIG_FEATURE_LESS_ASK_TERMINAL=y +CONFIG_FEATURE_LESS_DASHCMD=y +CONFIG_FEATURE_LESS_LINENUMS=y +# CONFIG_NANDWRITE is not set +# CONFIG_NANDDUMP is not set +# CONFIG_RFKILL is not set +CONFIG_SETSERIAL=y +CONFIG_TASKSET=y +CONFIG_FEATURE_TASKSET_FANCY=y +# CONFIG_UBIATTACH is not set +# CONFIG_UBIDETACH is not set +# CONFIG_UBIMKVOL is not set +# CONFIG_UBIRMVOL is not set +# CONFIG_UBIRSVOL is not set +# CONFIG_UBIUPDATEVOL is not set +# CONFIG_WALL is not set +CONFIG_ADJTIMEX=y +# CONFIG_BBCONFIG is not set +# CONFIG_FEATURE_COMPRESS_BBCONFIG is not set +CONFIG_BEEP=y +CONFIG_FEATURE_BEEP_FREQ=4000 +CONFIG_FEATURE_BEEP_LENGTH_MS=30 +CONFIG_CHAT=y +CONFIG_FEATURE_CHAT_NOFAIL=y +# CONFIG_FEATURE_CHAT_TTY_HIFI is not set +CONFIG_FEATURE_CHAT_IMPLICIT_CR=y +CONFIG_FEATURE_CHAT_SWALLOW_OPTS=y +CONFIG_FEATURE_CHAT_SEND_ESCAPES=y +CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y +CONFIG_FEATURE_CHAT_CLR_ABORT=y +CONFIG_CHRT=y +CONFIG_CRONTAB=y +CONFIG_DC=y +CONFIG_FEATURE_DC_LIBM=y +# CONFIG_DEVFSD is not set +# CONFIG_DEVFSD_MODLOAD is not set +# CONFIG_DEVFSD_FG_NP is not set +# CONFIG_DEVFSD_VERBOSE is not set +# CONFIG_FEATURE_DEVFS is not set +CONFIG_DEVMEM=y +CONFIG_EJECT=y +# CONFIG_FEATURE_EJECT_SCSI is not set +CONFIG_FBSPLASH=y +# CONFIG_FLASHCP is not set +# CONFIG_FLASH_LOCK is not set +# CONFIG_FLASH_UNLOCK is not set +# CONFIG_FLASH_ERASEALL is not set +CONFIG_IONICE=y +# CONFIG_INOTIFYD is not set +# CONFIG_LAST is not set +# CONFIG_FEATURE_LAST_FANCY is not set +CONFIG_HDPARM=y +CONFIG_FEATURE_HDPARM_GET_IDENTITY=y +CONFIG_FEATURE_HDPARM_HDIO_SCAN_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_UNREGISTER_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_DRIVE_RESET=y +CONFIG_FEATURE_HDPARM_HDIO_TRISTATE_HWIF=y +CONFIG_FEATURE_HDPARM_HDIO_GETSET_DMA=y +CONFIG_MAKEDEVS=y +# CONFIG_FEATURE_MAKEDEVS_LEAF is not set +CONFIG_FEATURE_MAKEDEVS_TABLE=y +CONFIG_MAN=y +CONFIG_MICROCOM=y +CONFIG_MOUNTPOINT=y +# CONFIG_MT is not set +CONFIG_RAIDAUTORUN=y +# CONFIG_READAHEAD is not set +# CONFIG_RUNLEVEL is not set +CONFIG_RX=y +CONFIG_SETSID=y +CONFIG_STRINGS=y +CONFIG_TIME=y +CONFIG_TIMEOUT=y +CONFIG_TTYSIZE=y +CONFIG_VOLNAME=y +CONFIG_WATCHDOG=y + +# +# Networking Utilities +# +CONFIG_NAMEIF=y +CONFIG_FEATURE_NAMEIF_EXTENDED=y +CONFIG_NBDCLIENT=y +CONFIG_NC=y +CONFIG_NC_SERVER=y +CONFIG_NC_EXTRA=y +# CONFIG_NC_110_COMPAT is not set +CONFIG_PING=y +CONFIG_PING6=y +CONFIG_FEATURE_FANCY_PING=y +CONFIG_WGET=y +CONFIG_FEATURE_WGET_STATUSBAR=y +CONFIG_FEATURE_WGET_AUTHENTICATION=y +CONFIG_FEATURE_WGET_LONG_OPTIONS=y +CONFIG_FEATURE_WGET_TIMEOUT=y +CONFIG_FEATURE_WGET_OPENSSL=y +CONFIG_FEATURE_WGET_SSL_HELPER=y +CONFIG_WHOIS=y +CONFIG_FEATURE_IPV6=y +# CONFIG_FEATURE_UNIX_LOCAL is not set +CONFIG_FEATURE_PREFER_IPV4_ADDRESS=y +# CONFIG_VERBOSE_RESOLUTION_ERRORS is not set +# CONFIG_ARP is not set +# CONFIG_ARPING is not set +CONFIG_BRCTL=y +CONFIG_FEATURE_BRCTL_FANCY=y +CONFIG_FEATURE_BRCTL_SHOW=y +CONFIG_DNSD=y +# CONFIG_ETHER_WAKE is not set +CONFIG_FAKEIDENTD=y +CONFIG_FTPD=y +CONFIG_FEATURE_FTP_WRITE=y +CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y +CONFIG_FEATURE_FTP_AUTHENTICATION=y +CONFIG_FTPGET=y +CONFIG_FTPPUT=y +CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS=y +CONFIG_HOSTNAME=y +CONFIG_HTTPD=y +CONFIG_FEATURE_HTTPD_RANGES=y +CONFIG_FEATURE_HTTPD_SETUID=y +CONFIG_FEATURE_HTTPD_BASIC_AUTH=y +CONFIG_FEATURE_HTTPD_AUTH_MD5=y +CONFIG_FEATURE_HTTPD_CGI=y +CONFIG_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR=y +CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y +CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y +CONFIG_FEATURE_HTTPD_ERROR_PAGES=y +CONFIG_FEATURE_HTTPD_PROXY=y +CONFIG_FEATURE_HTTPD_GZIP=y +# CONFIG_IFCONFIG is not set +# CONFIG_FEATURE_IFCONFIG_STATUS is not set +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +# CONFIG_FEATURE_IFCONFIG_HW is not set +# CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS is not set +# CONFIG_IFENSLAVE is not set +CONFIG_IFPLUGD=y +CONFIG_IFUPDOWN=y +CONFIG_IFUPDOWN_IFSTATE_PATH="/var/run/ifstate" +CONFIG_FEATURE_IFUPDOWN_IP=y +CONFIG_FEATURE_IFUPDOWN_IP_BUILTIN=y +# CONFIG_FEATURE_IFUPDOWN_IFCONFIG_BUILTIN is not set +CONFIG_FEATURE_IFUPDOWN_IPV4=y +CONFIG_FEATURE_IFUPDOWN_IPV6=y +CONFIG_FEATURE_IFUPDOWN_MAPPING=y +# CONFIG_FEATURE_IFUPDOWN_EXTERNAL_DHCP is not set +CONFIG_INETD=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_ECHO=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DISCARD=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_TIME=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_DAYTIME=y +CONFIG_FEATURE_INETD_SUPPORT_BUILTIN_CHARGEN=y +# CONFIG_FEATURE_INETD_RPC is not set +CONFIG_IP=y +CONFIG_FEATURE_IP_ADDRESS=y +CONFIG_FEATURE_IP_LINK=y +CONFIG_FEATURE_IP_ROUTE=y +CONFIG_FEATURE_IP_ROUTE_DIR="/etc/iproute2" +CONFIG_FEATURE_IP_TUNNEL=y +CONFIG_FEATURE_IP_RULE=y +CONFIG_FEATURE_IP_NEIGH=y +CONFIG_FEATURE_IP_SHORT_FORMS=y +# CONFIG_FEATURE_IP_RARE_PROTOCOLS is not set +CONFIG_IPADDR=y +CONFIG_IPLINK=y +CONFIG_IPROUTE=y +CONFIG_IPTUNNEL=y +CONFIG_IPRULE=y +CONFIG_IPNEIGH=y +CONFIG_IPCALC=y +CONFIG_FEATURE_IPCALC_FANCY=y +CONFIG_FEATURE_IPCALC_LONG_OPTIONS=y +CONFIG_NETSTAT=y +CONFIG_FEATURE_NETSTAT_WIDE=y +CONFIG_FEATURE_NETSTAT_PRG=y +# CONFIG_NSLOOKUP is not set +CONFIG_NTPD=y +CONFIG_FEATURE_NTPD_SERVER=y +CONFIG_FEATURE_NTPD_CONF=y +CONFIG_PSCAN=y +# CONFIG_ROUTE is not set +CONFIG_SLATTACH=y +CONFIG_TCPSVD=y +CONFIG_TELNET=y +CONFIG_FEATURE_TELNET_TTYPE=y +CONFIG_FEATURE_TELNET_AUTOLOGIN=y +CONFIG_TELNETD=y +CONFIG_FEATURE_TELNETD_STANDALONE=y +CONFIG_FEATURE_TELNETD_INETD_WAIT=y +CONFIG_TFTP=y +CONFIG_TFTPD=y + +# +# Common options for tftp/tftpd +# +CONFIG_FEATURE_TFTP_GET=y +CONFIG_FEATURE_TFTP_PUT=y +CONFIG_FEATURE_TFTP_BLOCKSIZE=y +CONFIG_FEATURE_TFTP_PROGRESS_BAR=y +# CONFIG_TFTP_DEBUG is not set +CONFIG_TRACEROUTE=y +CONFIG_TRACEROUTE6=y +CONFIG_FEATURE_TRACEROUTE_VERBOSE=y +# CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set +CONFIG_TUNCTL=y +CONFIG_FEATURE_TUNCTL_UG=y +# CONFIG_UDHCPC6 is not set +CONFIG_UDHCPD=y +CONFIG_DHCPRELAY=y +CONFIG_DUMPLEASES=y +CONFIG_FEATURE_UDHCPD_WRITE_LEASES_EARLY=y +# CONFIG_FEATURE_UDHCPD_BASE_IP_ON_MAC is not set +CONFIG_DHCPD_LEASES_FILE="/var/lib/misc/udhcpd.leases" +CONFIG_UDHCPC=y +CONFIG_FEATURE_UDHCPC_ARPING=y +CONFIG_FEATURE_UDHCPC_SANITIZEOPT=y +# CONFIG_FEATURE_UDHCP_PORT is not set +CONFIG_UDHCP_DEBUG=9 +CONFIG_FEATURE_UDHCP_RFC3397=y +CONFIG_FEATURE_UDHCP_8021Q=y +CONFIG_UDHCPC_DEFAULT_SCRIPT="/usr/share/udhcpc/default.script" +CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS=80 +CONFIG_IFUPDOWN_UDHCPC_CMD_OPTIONS="-R -n" +CONFIG_UDPSVD=y +CONFIG_VCONFIG=y +# CONFIG_ZCIP is not set + +# +# Print Utilities +# +CONFIG_LPD=y +CONFIG_LPR=y +CONFIG_LPQ=y + +# +# Mail Utilities +# +CONFIG_MAKEMIME=y +CONFIG_FEATURE_MIME_CHARSET="us-ascii" +CONFIG_POPMAILDIR=y +CONFIG_FEATURE_POPMAILDIR_DELIVERY=y +CONFIG_REFORMIME=y +CONFIG_FEATURE_REFORMIME_COMPAT=y +CONFIG_SENDMAIL=y + +# +# Process Utilities +# +CONFIG_IOSTAT=y +CONFIG_LSOF=y +CONFIG_MPSTAT=y +CONFIG_NMETER=y +CONFIG_PMAP=y +CONFIG_POWERTOP=y +CONFIG_PSTREE=y +CONFIG_PWDX=y +CONFIG_SMEMCAP=y +CONFIG_TOP=y +CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y +CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y +CONFIG_FEATURE_TOP_SMP_CPU=y +CONFIG_FEATURE_TOP_DECIMALS=y +CONFIG_FEATURE_TOP_SMP_PROCESS=y +CONFIG_FEATURE_TOPMEM=y +CONFIG_UPTIME=y +# CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set +CONFIG_FREE=y +CONFIG_FUSER=y +CONFIG_KILL=y +CONFIG_KILLALL=y +CONFIG_KILLALL5=y +CONFIG_PGREP=y +CONFIG_PIDOF=y +CONFIG_FEATURE_PIDOF_SINGLE=y +CONFIG_FEATURE_PIDOF_OMIT=y +CONFIG_PKILL=y +CONFIG_PS=y +# CONFIG_FEATURE_PS_WIDE is not set +# CONFIG_FEATURE_PS_LONG is not set +CONFIG_FEATURE_PS_TIME=y +CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y +# CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set +CONFIG_RENICE=y +CONFIG_BB_SYSCTL=y +CONFIG_FEATURE_SHOW_THREADS=y +CONFIG_WATCH=y + +# +# Runit Utilities +# +CONFIG_CHPST=y +CONFIG_SETUIDGID=y +CONFIG_ENVUIDGID=y +CONFIG_ENVDIR=y +CONFIG_SOFTLIMIT=y +CONFIG_RUNSV=y +CONFIG_RUNSVDIR=y +# CONFIG_FEATURE_RUNSVDIR_LOG is not set +CONFIG_SV=y +CONFIG_SV_DEFAULT_SERVICE_DIR="/var/service" +CONFIG_SVLOGD=y +# CONFIG_CHCON is not set +# CONFIG_FEATURE_CHCON_LONG_OPTIONS is not set +# CONFIG_GETENFORCE is not set +# CONFIG_GETSEBOOL is not set +# CONFIG_LOAD_POLICY is not set +# CONFIG_MATCHPATHCON is not set +# CONFIG_RESTORECON is not set +# CONFIG_RUNCON is not set +# CONFIG_FEATURE_RUNCON_LONG_OPTIONS is not set +# CONFIG_SELINUXENABLED is not set +# CONFIG_SETENFORCE is not set +# CONFIG_SETFILES is not set +# CONFIG_FEATURE_SETFILES_CHECK_OPTION is not set +# CONFIG_SETSEBOOL is not set +# CONFIG_SESTATUS is not set + +# +# Shells +# +CONFIG_ASH=y +CONFIG_ASH_BASH_COMPAT=y +# CONFIG_ASH_IDLE_TIMEOUT is not set +CONFIG_ASH_JOB_CONTROL=y +CONFIG_ASH_ALIAS=y +CONFIG_ASH_GETOPTS=y +CONFIG_ASH_BUILTIN_ECHO=y +CONFIG_ASH_BUILTIN_PRINTF=y +CONFIG_ASH_BUILTIN_TEST=y +CONFIG_ASH_HELP=y +CONFIG_ASH_CMDCMD=y +# CONFIG_ASH_MAIL is not set +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +CONFIG_ASH_RANDOM_SUPPORT=y +CONFIG_ASH_EXPAND_PRMT=y +CONFIG_CTTYHACK=y +# CONFIG_HUSH is not set +# CONFIG_HUSH_BASH_COMPAT is not set +# CONFIG_HUSH_BRACE_EXPANSION is not set +# CONFIG_HUSH_HELP is not set +# CONFIG_HUSH_INTERACTIVE is not set +# CONFIG_HUSH_SAVEHISTORY is not set +# CONFIG_HUSH_JOB is not set +# CONFIG_HUSH_TICK is not set +# CONFIG_HUSH_IF is not set +# CONFIG_HUSH_LOOPS is not set +# CONFIG_HUSH_CASE is not set +# CONFIG_HUSH_FUNCTIONS is not set +# CONFIG_HUSH_LOCAL is not set +# CONFIG_HUSH_RANDOM_SUPPORT is not set +# CONFIG_HUSH_EXPORT_N is not set +# CONFIG_HUSH_MODE_X is not set +# CONFIG_MSH is not set +CONFIG_FEATURE_SH_IS_ASH=y +# CONFIG_FEATURE_SH_IS_HUSH is not set +# CONFIG_FEATURE_SH_IS_NONE is not set +# CONFIG_FEATURE_BASH_IS_ASH is not set +# CONFIG_FEATURE_BASH_IS_HUSH is not set +CONFIG_FEATURE_BASH_IS_NONE=y +CONFIG_SH_MATH_SUPPORT=y +CONFIG_SH_MATH_SUPPORT_64=y +CONFIG_FEATURE_SH_EXTRA_QUIET=y +# CONFIG_FEATURE_SH_STANDALONE is not set +# CONFIG_FEATURE_SH_NOFORK is not set +CONFIG_FEATURE_SH_HISTFILESIZE=y + +# +# System Logging Utilities +# +# CONFIG_KLOGD is not set +# CONFIG_FEATURE_KLOGD_KLOGCTL is not set +# CONFIG_LOGGER is not set +# CONFIG_LOGREAD is not set +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_SYSLOGD is not set +# CONFIG_FEATURE_ROTATE_LOGFILE is not set +# CONFIG_FEATURE_REMOTE_LOG is not set +# CONFIG_FEATURE_SYSLOGD_DUP is not set +# CONFIG_FEATURE_SYSLOGD_CFG is not set +CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 +# CONFIG_FEATURE_IPC_SYSLOG is not set +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 +# CONFIG_FEATURE_KMSG_SYSLOG is not set diff --git a/configs/android_defconfig b/configs/android_defconfig index e35830e..30e888a 100644 --- a/configs/android_defconfig +++ b/configs/android_defconfig @@ -107,7 +107,6 @@ CONFIG_PREFIX="./_install" # # Busybox Library Tuning # -# CONFIG_FEATURE_SYSTEMD is not set # CONFIG_FEATURE_RTMINMAX is not set CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 @@ -155,7 +154,6 @@ CONFIG_FEATURE_CPIO_O=y CONFIG_FEATURE_CPIO_P=y CONFIG_DPKG=y CONFIG_DPKG_DEB=y -# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set CONFIG_GUNZIP=y CONFIG_GZIP=y # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set @@ -449,7 +447,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_INIT_TERMINAL_TYPE="linux" CONFIG_MESG=y CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y @@ -844,7 +842,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y CONFIG_TRACEROUTE=y # CONFIG_TRACEROUTE6 is not set CONFIG_FEATURE_TRACEROUTE_VERBOSE=y -# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set CONFIG_TUNCTL=y CONFIG_FEATURE_TUNCTL_UG=y diff --git a/configs/android_ndk_defconfig b/configs/android_ndk_defconfig index 01cc2dd..bdcadc7 100644 --- a/configs/android_ndk_defconfig +++ b/configs/android_ndk_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Busybox version: 1.21.0.git -# Mon May 28 21:51:18 2012 +# Busybox version: 1.24.0.git +# Fri Sep 18 20:39:29 2015 # CONFIG_HAVE_DOT_CONFIG=y @@ -36,12 +36,15 @@ CONFIG_LAST_SUPPORTED_WCHAR=0 # CONFIG_UNICODE_BIDI_SUPPORT is not set # CONFIG_UNICODE_NEUTRAL_TABLE is not set # CONFIG_UNICODE_PRESERVE_BROKEN is not set +# CONFIG_PAM is not set +CONFIG_FEATURE_USE_SENDFILE=y CONFIG_LONG_OPTS=y # CONFIG_FEATURE_DEVPTS is not set # CONFIG_FEATURE_CLEAN_UP is not set # CONFIG_FEATURE_UTMP is not set # CONFIG_FEATURE_WTMP is not set # CONFIG_FEATURE_PIDFILE is not set +CONFIG_PID_FILE_PATH="" # CONFIG_FEATURE_SUID is not set # CONFIG_FEATURE_SUID_CONFIG is not set # CONFIG_FEATURE_SUID_CONFIG_QUIET is not set @@ -63,7 +66,7 @@ CONFIG_FEATURE_SYSLOG=y # CONFIG_LFS is not set CONFIG_CROSS_COMPILER_PREFIX="arm-linux-androideabi-" CONFIG_SYSROOT="/opt/android-ndk/platforms/android-9/arch-arm" -CONFIG_EXTRA_CFLAGS="-DANDROID -D__ANDROID__ -DSK_RELEASE -nostdlib -march=armv7-a -msoft-float -mfloat-abi=softfp -mfpu=neon -mthumb -mthumb-interwork -fpic -fno-short-enums -fgcse-after-reload -frename-registers" +CONFIG_EXTRA_CFLAGS="-DANDROID -D__ANDROID__ -DSK_RELEASE -nostdlib -march=armv7-a -msoft-float -mfloat-abi=softfp -mfpu=neon -mthumb -mthumb-interwork -fpic -fno-short-enums -fgcse-after-reload -frename-registers -fuse-ld=bfd" CONFIG_EXTRA_LDFLAGS="-Xlinker -z -Xlinker muldefs -nostdlib -Bdynamic -Xlinker -dynamic-linker -Xlinker /system/bin/linker -Xlinker -z -Xlinker nocopyreloc -Xlinker --no-undefined ${SYSROOT}/usr/lib/crtbegin_dynamic.o ${SYSROOT}/usr/lib/crtend_android.o" CONFIG_EXTRA_LDLIBS="dl m c gcc" @@ -72,6 +75,7 @@ CONFIG_EXTRA_LDLIBS="dl m c gcc" # # CONFIG_DEBUG is not set # CONFIG_DEBUG_PESSIMIZE is not set +# CONFIG_UNIT_TEST is not set # CONFIG_WERROR is not set CONFIG_NO_DEBUG_LIB=y # CONFIG_DMALLOC is not set @@ -92,10 +96,10 @@ CONFIG_PREFIX="./_install" # # Busybox Library Tuning # -# CONFIG_FEATURE_SYSTEMD is not set # CONFIG_FEATURE_RTMINMAX is not set CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 +CONFIG_SHA3_SMALL=1 # CONFIG_FEATURE_FAST_TOP is not set # CONFIG_FEATURE_ETC_NETWORKS is not set CONFIG_FEATURE_USE_TERMIOS=y @@ -133,22 +137,28 @@ CONFIG_FEATURE_SEAMLESS_Z=y CONFIG_AR=y CONFIG_FEATURE_AR_LONG_FILENAMES=y CONFIG_FEATURE_AR_CREATE=y +CONFIG_UNCOMPRESS=y +CONFIG_GUNZIP=y CONFIG_BUNZIP2=y +CONFIG_UNLZMA=y +CONFIG_FEATURE_LZMA_FAST=y +CONFIG_LZMA=y +CONFIG_UNXZ=y +CONFIG_XZ=y CONFIG_BZIP2=y CONFIG_CPIO=y CONFIG_FEATURE_CPIO_O=y CONFIG_FEATURE_CPIO_P=y CONFIG_DPKG=y CONFIG_DPKG_DEB=y -# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set -CONFIG_GUNZIP=y CONFIG_GZIP=y # CONFIG_FEATURE_GZIP_LONG_OPTIONS is not set CONFIG_GZIP_FAST=0 +# CONFIG_FEATURE_GZIP_LEVELS is not set CONFIG_LZOP=y CONFIG_LZOP_COMPR_HIGH=y -CONFIG_RPM2CPIO=y CONFIG_RPM=y +CONFIG_RPM2CPIO=y CONFIG_TAR=y CONFIG_FEATURE_TAR_CREATE=y CONFIG_FEATURE_TAR_AUTODETECT=y @@ -161,12 +171,6 @@ CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y CONFIG_FEATURE_TAR_UNAME_GNAME=y CONFIG_FEATURE_TAR_NOPRESERVE_TIME=y # CONFIG_FEATURE_TAR_SELINUX is not set -CONFIG_UNCOMPRESS=y -CONFIG_UNLZMA=y -CONFIG_FEATURE_LZMA_FAST=y -CONFIG_LZMA=y -CONFIG_UNXZ=y -CONFIG_XZ=y CONFIG_UNZIP=y # @@ -178,16 +182,27 @@ CONFIG_CAT=y # CONFIG_FEATURE_DATE_ISOFMT is not set # CONFIG_FEATURE_DATE_NANO is not set # CONFIG_FEATURE_DATE_COMPAT is not set +CONFIG_DD=y +CONFIG_FEATURE_DD_SIGNAL_HANDLING=y +CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y +CONFIG_FEATURE_DD_IBS_OBS=y +CONFIG_FEATURE_DD_STATUS=y # CONFIG_HOSTID is not set # CONFIG_ID is not set # CONFIG_GROUPS is not set +CONFIG_SHUF=y +CONFIG_SYNC=y +# CONFIG_FEATURE_SYNC_FANCY is not set CONFIG_TEST=y CONFIG_FEATURE_TEST_64=y CONFIG_TOUCH=y +# CONFIG_FEATURE_TOUCH_NODEREF is not set CONFIG_FEATURE_TOUCH_SUSV3=y CONFIG_TR=y CONFIG_FEATURE_TR_CLASSES=y CONFIG_FEATURE_TR_EQUIV=y +CONFIG_TRUNCATE=y +CONFIG_UNLINK=y CONFIG_BASE64=y # CONFIG_WHO is not set # CONFIG_USERS is not set @@ -203,10 +218,6 @@ CONFIG_COMM=y CONFIG_CP=y # CONFIG_FEATURE_CP_LONG_OPTIONS is not set CONFIG_CUT=y -CONFIG_DD=y -CONFIG_FEATURE_DD_SIGNAL_HANDLING=y -CONFIG_FEATURE_DD_THIRD_STATUS_LINE=y -CONFIG_FEATURE_DD_IBS_OBS=y # CONFIG_DF is not set # CONFIG_FEATURE_DF_FANCY is not set CONFIG_DIRNAME=y @@ -263,6 +274,7 @@ CONFIG_SEQ=y CONFIG_SHA1SUM=y CONFIG_SHA256SUM=y CONFIG_SHA512SUM=y +CONFIG_SHA3SUM=y CONFIG_SLEEP=y CONFIG_FEATURE_FANCY_SLEEP=y CONFIG_FEATURE_FLOAT_SLEEP=y @@ -274,7 +286,6 @@ CONFIG_FEATURE_SPLIT_FANCY=y # CONFIG_FEATURE_STAT_FORMAT is not set CONFIG_STTY=y CONFIG_SUM=y -CONFIG_SYNC=y CONFIG_TAC=y CONFIG_TAIL=y CONFIG_FEATURE_FANCY_TAIL=y @@ -283,6 +294,7 @@ CONFIG_FEATURE_TEE_USE_BLOCK_IO=y CONFIG_TRUE=y # CONFIG_TTY is not set CONFIG_UNAME=y +CONFIG_UNAME_OSNAME="GNU/Linux" CONFIG_UNEXPAND=y # CONFIG_FEATURE_UNEXPAND_LONG_OPTIONS is not set CONFIG_UNIQ=y @@ -295,6 +307,11 @@ CONFIG_WHOAMI=y CONFIG_YES=y # +# Common options +# +CONFIG_FEATURE_VERBOSE=y + +# # Common options for cp and mv # CONFIG_FEATURE_PRESERVE_HARDLINKS=y @@ -310,7 +327,7 @@ CONFIG_FEATURE_AUTOWIDTH=y CONFIG_FEATURE_HUMAN_READABLE=y # -# Common options for md5sum, sha1sum, sha256sum, sha512sum +# Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum # CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y @@ -356,7 +373,16 @@ CONFIG_WHICH=y # # Editors # +CONFIG_AWK=y +CONFIG_FEATURE_AWK_LIBM=y +CONFIG_FEATURE_AWK_GNU_EXTENSIONS=y +CONFIG_CMP=y +CONFIG_DIFF=y +# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set +CONFIG_FEATURE_DIFF_DIR=y +CONFIG_ED=y CONFIG_PATCH=y +CONFIG_SED=y CONFIG_VI=y CONFIG_FEATURE_VI_MAX_LEN=4096 CONFIG_FEATURE_VI_8BIT=y @@ -371,14 +397,9 @@ CONFIG_FEATURE_VI_SETOPTS=y CONFIG_FEATURE_VI_SET=y CONFIG_FEATURE_VI_WIN_RESIZE=y CONFIG_FEATURE_VI_ASK_TERMINAL=y -CONFIG_AWK=y -CONFIG_FEATURE_AWK_LIBM=y -CONFIG_CMP=y -CONFIG_DIFF=y -# CONFIG_FEATURE_DIFF_LONG_OPTIONS is not set -CONFIG_FEATURE_DIFF_DIR=y -CONFIG_ED=y -CONFIG_SED=y +CONFIG_FEATURE_VI_UNDO=y +CONFIG_FEATURE_VI_UNDO_QUEUE=y +CONFIG_FEATURE_VI_UNDO_QUEUE_MAX=256 CONFIG_FEATURE_ALLOW_EXEC=y # @@ -395,6 +416,7 @@ CONFIG_FEATURE_FIND_MAXDEPTH=y CONFIG_FEATURE_FIND_NEWER=y CONFIG_FEATURE_FIND_INUM=y CONFIG_FEATURE_FIND_EXEC=y +CONFIG_FEATURE_FIND_EXEC_PLUS=y CONFIG_FEATURE_FIND_USER=y CONFIG_FEATURE_FIND_GROUP=y CONFIG_FEATURE_FIND_NOT=y @@ -416,6 +438,7 @@ CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y +CONFIG_FEATURE_XARGS_SUPPORT_REPL_STR=y # # Init Utilities @@ -434,7 +457,7 @@ CONFIG_FEATURE_INIT_SCTTY=y CONFIG_FEATURE_INIT_SYSLOG=y CONFIG_FEATURE_EXTRA_QUIET=y CONFIG_FEATURE_INIT_COREDUMPS=y -CONFIG_FEATURE_INITRD=y +CONFIG_LINUXRC=y CONFIG_INIT_TERMINAL_TYPE="linux" CONFIG_MESG=y CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y @@ -447,11 +470,12 @@ CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y # CONFIG_FEATURE_SHADOWPASSWDS is not set # CONFIG_USE_BB_PWD_GRP is not set # CONFIG_USE_BB_SHADOW is not set -# CONFIG_USE_BB_CRYPT is not set -# CONFIG_USE_BB_CRYPT_SHA is not set +CONFIG_USE_BB_CRYPT=y +CONFIG_USE_BB_CRYPT_SHA=y # CONFIG_ADDUSER is not set # CONFIG_FEATURE_ADDUSER_LONG_OPTIONS is not set # CONFIG_FEATURE_CHECK_NAMES is not set +CONFIG_LAST_ID=0 CONFIG_FIRST_SYSTEM_ID=0 CONFIG_LAST_SYSTEM_ID=0 # CONFIG_ADDGROUP is not set @@ -463,7 +487,6 @@ CONFIG_LAST_SYSTEM_ID=0 # CONFIG_GETTY is not set # CONFIG_LOGIN is not set # CONFIG_LOGIN_SESSION_AS_CHILD is not set -# CONFIG_PAM is not set # CONFIG_LOGIN_SCRIPTS is not set # CONFIG_FEATURE_NOLOGIN is not set # CONFIG_FEATURE_SECURETTY is not set @@ -514,20 +537,33 @@ CONFIG_FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED=y # CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set # CONFIG_FEATURE_MODUTILS_ALIAS is not set # CONFIG_FEATURE_MODUTILS_SYMBOLS is not set -CONFIG_DEFAULT_MODULES_DIR="/system/lib/modules" +CONFIG_DEFAULT_MODULES_DIR="/lib/modules" CONFIG_DEFAULT_DEPMOD_FILE="modules.dep" # # Linux System Utilities # CONFIG_BLOCKDEV=y -CONFIG_MDEV=y -CONFIG_FEATURE_MDEV_CONF=y -CONFIG_FEATURE_MDEV_RENAME=y -CONFIG_FEATURE_MDEV_RENAME_REGEXP=y -CONFIG_FEATURE_MDEV_EXEC=y -CONFIG_FEATURE_MDEV_LOAD_FIRMWARE=y +CONFIG_FATATTR=y +CONFIG_FSTRIM=y +# CONFIG_MDEV is not set +# CONFIG_FEATURE_MDEV_CONF is not set +# CONFIG_FEATURE_MDEV_RENAME is not set +# CONFIG_FEATURE_MDEV_RENAME_REGEXP is not set +# CONFIG_FEATURE_MDEV_EXEC is not set +# CONFIG_FEATURE_MDEV_LOAD_FIRMWARE is not set +# CONFIG_MOUNT is not set +# CONFIG_FEATURE_MOUNT_FAKE is not set +# CONFIG_FEATURE_MOUNT_VERBOSE is not set +# CONFIG_FEATURE_MOUNT_HELPERS is not set +# CONFIG_FEATURE_MOUNT_LABEL is not set +# CONFIG_FEATURE_MOUNT_NFS is not set +# CONFIG_FEATURE_MOUNT_CIFS is not set +# CONFIG_FEATURE_MOUNT_FLAGS is not set +# CONFIG_FEATURE_MOUNT_FSTAB is not set +# CONFIG_FEATURE_MOUNT_OTHERTAB is not set CONFIG_REV=y +CONFIG_UEVENT=y # CONFIG_ACPID is not set # CONFIG_FEATURE_ACPID_COMPAT is not set CONFIG_BLKID=y @@ -573,15 +609,6 @@ CONFIG_LSUSB=y CONFIG_MKSWAP=y CONFIG_FEATURE_MKSWAP_UUID=y CONFIG_MORE=y -# CONFIG_MOUNT is not set -# CONFIG_FEATURE_MOUNT_FAKE is not set -# CONFIG_FEATURE_MOUNT_VERBOSE is not set -# CONFIG_FEATURE_MOUNT_HELPERS is not set -# CONFIG_FEATURE_MOUNT_LABEL is not set -# CONFIG_FEATURE_MOUNT_NFS is not set -# CONFIG_FEATURE_MOUNT_CIFS is not set -# CONFIG_FEATURE_MOUNT_FLAGS is not set -# CONFIG_FEATURE_MOUNT_FSTAB is not set # CONFIG_PIVOT_ROOT is not set # CONFIG_RDATE is not set CONFIG_RDEV=y @@ -591,6 +618,7 @@ CONFIG_SCRIPT=y CONFIG_SCRIPTREPLAY=y # CONFIG_SETARCH is not set # CONFIG_SWAPONOFF is not set +# CONFIG_FEATURE_SWAPON_DISCARD is not set # CONFIG_FEATURE_SWAPON_PRI is not set CONFIG_SWITCH_ROOT=y # CONFIG_UMOUNT is not set @@ -603,32 +631,45 @@ CONFIG_VOLUMEID=y # # Filesystem/Volume identification # -CONFIG_FEATURE_VOLUMEID_EXT=y CONFIG_FEATURE_VOLUMEID_BTRFS=y -CONFIG_FEATURE_VOLUMEID_REISERFS=y +CONFIG_FEATURE_VOLUMEID_CRAMFS=y +CONFIG_FEATURE_VOLUMEID_EXFAT=y +CONFIG_FEATURE_VOLUMEID_EXT=y +CONFIG_FEATURE_VOLUMEID_F2FS=y CONFIG_FEATURE_VOLUMEID_FAT=y CONFIG_FEATURE_VOLUMEID_HFS=y -CONFIG_FEATURE_VOLUMEID_JFS=y -CONFIG_FEATURE_VOLUMEID_XFS=y -CONFIG_FEATURE_VOLUMEID_NTFS=y CONFIG_FEATURE_VOLUMEID_ISO9660=y -CONFIG_FEATURE_VOLUMEID_UDF=y -CONFIG_FEATURE_VOLUMEID_LUKS=y +CONFIG_FEATURE_VOLUMEID_JFS=y +CONFIG_FEATURE_VOLUMEID_LINUXRAID=y CONFIG_FEATURE_VOLUMEID_LINUXSWAP=y -CONFIG_FEATURE_VOLUMEID_CRAMFS=y +CONFIG_FEATURE_VOLUMEID_LUKS=y +CONFIG_FEATURE_VOLUMEID_NILFS=y +CONFIG_FEATURE_VOLUMEID_NTFS=y +CONFIG_FEATURE_VOLUMEID_OCFS2=y +CONFIG_FEATURE_VOLUMEID_REISERFS=y CONFIG_FEATURE_VOLUMEID_ROMFS=y +CONFIG_FEATURE_VOLUMEID_SQUASHFS=y CONFIG_FEATURE_VOLUMEID_SYSV=y -CONFIG_FEATURE_VOLUMEID_OCFS2=y -CONFIG_FEATURE_VOLUMEID_LINUXRAID=y +CONFIG_FEATURE_VOLUMEID_UDF=y +CONFIG_FEATURE_VOLUMEID_XFS=y # # Miscellaneous Utilities # # CONFIG_CONSPY is not set +CONFIG_CROND=y +CONFIG_FEATURE_CROND_D=y +CONFIG_FEATURE_CROND_CALL_SENDMAIL=y +CONFIG_FEATURE_CROND_DIR="/var/spool/cron" +CONFIG_I2CGET=y +CONFIG_I2CSET=y +CONFIG_I2CDUMP=y +CONFIG_I2CDETECT=y CONFIG_LESS=y CONFIG_FEATURE_LESS_MAXLINES=9999999 CONFIG_FEATURE_LESS_BRACKETS=y CONFIG_FEATURE_LESS_FLAGS=y +CONFIG_FEATURE_LESS_TRUNCATE=y CONFIG_FEATURE_LESS_MARKS=y CONFIG_FEATURE_LESS_REGEXP=y CONFIG_FEATURE_LESS_WINCH=y @@ -637,13 +678,17 @@ CONFIG_FEATURE_LESS_DASHCMD=y CONFIG_FEATURE_LESS_LINENUMS=y # CONFIG_NANDWRITE is not set CONFIG_NANDDUMP=y +# CONFIG_RFKILL is not set CONFIG_SETSERIAL=y +# CONFIG_TASKSET is not set +# CONFIG_FEATURE_TASKSET_FANCY is not set # CONFIG_UBIATTACH is not set # CONFIG_UBIDETACH is not set # CONFIG_UBIMKVOL is not set # CONFIG_UBIRMVOL is not set # CONFIG_UBIRSVOL is not set # CONFIG_UBIUPDATEVOL is not set +# CONFIG_WALL is not set # CONFIG_ADJTIMEX is not set CONFIG_BBCONFIG=y CONFIG_FEATURE_COMPRESS_BBCONFIG=y @@ -659,10 +704,6 @@ CONFIG_FEATURE_CHAT_SEND_ESCAPES=y CONFIG_FEATURE_CHAT_VAR_ABORT_LEN=y CONFIG_FEATURE_CHAT_CLR_ABORT=y CONFIG_CHRT=y -CONFIG_CROND=y -CONFIG_FEATURE_CROND_D=y -CONFIG_FEATURE_CROND_CALL_SENDMAIL=y -CONFIG_FEATURE_CROND_DIR="/var/spool/cron" CONFIG_CRONTAB=y CONFIG_DC=y CONFIG_FEATURE_DC_LIBM=y @@ -700,18 +741,14 @@ CONFIG_MAN=y # CONFIG_MT is not set CONFIG_RAIDAUTORUN=y # CONFIG_READAHEAD is not set -# CONFIG_RFKILL is not set # CONFIG_RUNLEVEL is not set CONFIG_RX=y CONFIG_SETSID=y CONFIG_STRINGS=y -# CONFIG_TASKSET is not set -# CONFIG_FEATURE_TASKSET_FANCY is not set CONFIG_TIME=y CONFIG_TIMEOUT=y CONFIG_TTYSIZE=y CONFIG_VOLNAME=y -# CONFIG_WALL is not set # CONFIG_WATCHDOG is not set # @@ -743,13 +780,13 @@ CONFIG_FAKEIDENTD=y CONFIG_FTPD=y CONFIG_FEATURE_FTP_WRITE=y CONFIG_FEATURE_FTPD_ACCEPT_BROKEN_LIST=y +CONFIG_FEATURE_FTP_AUTHENTICATION=y CONFIG_FTPGET=y CONFIG_FTPPUT=y # CONFIG_FEATURE_FTPGETPUT_LONG_OPTIONS is not set # CONFIG_HOSTNAME is not set CONFIG_HTTPD=y CONFIG_FEATURE_HTTPD_RANGES=y -CONFIG_FEATURE_HTTPD_USE_SENDFILE=y CONFIG_FEATURE_HTTPD_SETUID=y CONFIG_FEATURE_HTTPD_BASIC_AUTH=y # CONFIG_FEATURE_HTTPD_AUTH_MD5 is not set @@ -806,6 +843,7 @@ CONFIG_FEATURE_NETSTAT_PRG=y # CONFIG_NSLOOKUP is not set # CONFIG_NTPD is not set # CONFIG_FEATURE_NTPD_SERVER is not set +# CONFIG_FEATURE_NTPD_CONF is not set CONFIG_PSCAN=y CONFIG_ROUTE=y # CONFIG_SLATTACH is not set @@ -830,7 +868,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y CONFIG_TRACEROUTE=y # CONFIG_TRACEROUTE6 is not set CONFIG_FEATURE_TRACEROUTE_VERBOSE=y -# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set CONFIG_TUNCTL=y CONFIG_FEATURE_TUNCTL_UG=y @@ -843,6 +880,7 @@ CONFIG_FEATURE_TUNCTL_UG=y CONFIG_DHCPD_LEASES_FILE="" CONFIG_UDHCPC=y CONFIG_FEATURE_UDHCPC_ARPING=y +CONFIG_FEATURE_UDHCPC_SANITIZEOPT=y CONFIG_FEATURE_UDHCP_PORT=y CONFIG_UDHCP_DEBUG=9 CONFIG_FEATURE_UDHCP_RFC3397=y @@ -889,6 +927,13 @@ CONFIG_POWERTOP=y CONFIG_PSTREE=y CONFIG_PWDX=y CONFIG_SMEMCAP=y +CONFIG_TOP=y +CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y +CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y +CONFIG_FEATURE_TOP_SMP_CPU=y +CONFIG_FEATURE_TOP_DECIMALS=y +CONFIG_FEATURE_TOP_SMP_PROCESS=y +CONFIG_FEATURE_TOPMEM=y CONFIG_UPTIME=y # CONFIG_FEATURE_UPTIME_UTMP_SUPPORT is not set CONFIG_FREE=y @@ -909,13 +954,6 @@ CONFIG_FEATURE_PS_ADDITIONAL_COLUMNS=y # CONFIG_FEATURE_PS_UNUSUAL_SYSTEMS is not set CONFIG_RENICE=y CONFIG_BB_SYSCTL=y -CONFIG_TOP=y -CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE=y -CONFIG_FEATURE_TOP_CPU_GLOBAL_PERCENTS=y -CONFIG_FEATURE_TOP_SMP_CPU=y -CONFIG_FEATURE_TOP_DECIMALS=y -CONFIG_FEATURE_TOP_SMP_PROCESS=y -CONFIG_FEATURE_TOPMEM=y CONFIG_FEATURE_SHOW_THREADS=y CONFIG_WATCH=y @@ -961,6 +999,7 @@ CONFIG_SOFTLIMIT=y # CONFIG_ASH_BUILTIN_ECHO is not set # CONFIG_ASH_BUILTIN_PRINTF is not set # CONFIG_ASH_BUILTIN_TEST is not set +# CONFIG_ASH_HELP is not set # CONFIG_ASH_CMDCMD is not set # CONFIG_ASH_MAIL is not set # CONFIG_ASH_OPTIMIZE_FOR_SIZE is not set @@ -1010,6 +1049,7 @@ CONFIG_FEATURE_SYSLOGD_READ_BUFFER_SIZE=0 CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=0 # CONFIG_LOGREAD is not set # CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +# CONFIG_FEATURE_KMSG_SYSLOG is not set CONFIG_KLOGD=y CONFIG_FEATURE_KLOGD_KLOGCTL=y # CONFIG_LOGGER is not set diff --git a/configs/cygwin_defconfig b/configs/cygwin_defconfig index aa346e3..b856482 100644 --- a/configs/cygwin_defconfig +++ b/configs/cygwin_defconfig @@ -89,7 +89,6 @@ CONFIG_PREFIX="./_install" # # Busybox Library Tuning # -# CONFIG_FEATURE_SYSTEMD is not set CONFIG_FEATURE_RTMINMAX=y CONFIG_PASSWORD_MINLEN=6 CONFIG_MD5_SMALL=1 @@ -135,7 +134,6 @@ CONFIG_FEATURE_CPIO_O=y CONFIG_FEATURE_CPIO_P=y # CONFIG_DPKG is not set # CONFIG_DPKG_DEB is not set -# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set CONFIG_GUNZIP=y CONFIG_GZIP=y CONFIG_FEATURE_GZIP_LONG_OPTIONS=y @@ -426,7 +424,7 @@ CONFIG_FEATURE_KILL_DELAY=0 # CONFIG_FEATURE_INIT_SYSLOG is not set # CONFIG_FEATURE_EXTRA_QUIET is not set # CONFIG_FEATURE_INIT_COREDUMPS is not set -# CONFIG_FEATURE_INITRD is not set +# CONFIG_LINUXRC is not set CONFIG_INIT_TERMINAL_TYPE="" CONFIG_MESG=y CONFIG_FEATURE_MESG_ENABLE_ONLY_GROUP=y @@ -815,7 +813,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y # CONFIG_TRACEROUTE is not set # CONFIG_TRACEROUTE6 is not set # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set -# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set # CONFIG_TUNCTL is not set # CONFIG_FEATURE_TUNCTL_UG is not set diff --git a/configs/freebsd_defconfig b/configs/freebsd_defconfig index ec3ed03..4f14d3b 100644 --- a/configs/freebsd_defconfig +++ b/configs/freebsd_defconfig @@ -132,7 +132,6 @@ CONFIG_CPIO=y # CONFIG_FEATURE_CPIO_P is not set # CONFIG_DPKG is not set # CONFIG_DPKG_DEB is not set -# CONFIG_FEATURE_DPKG_DEB_EXTRACT_ONLY is not set CONFIG_GUNZIP=y CONFIG_GZIP=y CONFIG_FEATURE_GZIP_LONG_OPTIONS=y @@ -422,7 +421,7 @@ CONFIG_FEATURE_KILL_DELAY=0 # CONFIG_FEATURE_INIT_SYSLOG is not set # CONFIG_FEATURE_EXTRA_QUIET is not set # CONFIG_FEATURE_INIT_COREDUMPS is not set -# CONFIG_FEATURE_INITRD is not set +# CONFIG_LINUXRC is not set CONFIG_INIT_TERMINAL_TYPE="" # CONFIG_MESG is not set @@ -795,7 +794,6 @@ CONFIG_FEATURE_TFTP_PROGRESS_BAR=y # CONFIG_TRACEROUTE is not set # CONFIG_TRACEROUTE6 is not set # CONFIG_FEATURE_TRACEROUTE_VERBOSE is not set -# CONFIG_FEATURE_TRACEROUTE_SOURCE_ROUTE is not set # CONFIG_FEATURE_TRACEROUTE_USE_ICMP is not set # CONFIG_TUNCTL is not set # CONFIG_FEATURE_TUNCTL_UG is not set diff --git a/console-tools/Config.src b/console-tools/Config.src index c657044..e6587ad 100644 --- a/console-tools/Config.src +++ b/console-tools/Config.src @@ -7,170 +7,4 @@ menu "Console Utilities" INSERT -config CHVT - bool "chvt" - default y - select PLATFORM_LINUX - help - This program is used to change to another terminal. - Example: chvt 4 (change to terminal /dev/tty4) - -config FGCONSOLE - bool "fgconsole" - default y - select PLATFORM_LINUX - help - This program prints active (foreground) console number. - -config CLEAR - bool "clear" - default y - help - This program clears the terminal screen. - -config DEALLOCVT - bool "deallocvt" - default y - select PLATFORM_LINUX - help - This program deallocates unused virtual consoles. - -config DUMPKMAP - bool "dumpkmap" - default y - select PLATFORM_LINUX - help - This program dumps the kernel's keyboard translation table to - stdout, in binary format. You can then use loadkmap to load it. - -config KBD_MODE - bool "kbd_mode" - default y - select PLATFORM_LINUX - help - This program reports and sets keyboard mode. - -config LOADFONT - bool "loadfont" - default y - select PLATFORM_LINUX - help - This program loads a console font from standard input. - -config LOADKMAP - bool "loadkmap" - default y - select PLATFORM_LINUX - help - This program loads a keyboard translation table from - standard input. - -config OPENVT - bool "openvt" - default y - select PLATFORM_LINUX - help - This program is used to start a command on an unused - virtual terminal. - -config RESET - bool "reset" - default y - help - This program is used to reset the terminal screen, if it - gets messed up. - -config RESIZE - bool "resize" - default y - help - This program is used to (re)set the width and height of your current - terminal. - -config FEATURE_RESIZE_PRINT - bool "Print environment variables" - default y - depends on RESIZE - help - Prints the newly set size (number of columns and rows) of - the terminal. - E.g.: - COLUMNS=80;LINES=44;export COLUMNS LINES; - -config SETCONSOLE - bool "setconsole" - default y - select PLATFORM_LINUX - help - This program redirects the system console to another device, - like the current tty while logged in via telnet. - -config FEATURE_SETCONSOLE_LONG_OPTIONS - bool "Enable long options" - default y - depends on SETCONSOLE && LONG_OPTS - help - Support long options for the setconsole applet. - -config SETFONT - bool "setfont" - default y - select PLATFORM_LINUX - help - Allows to load console screen map. Useful for i18n. - -config FEATURE_SETFONT_TEXTUAL_MAP - bool "Support reading textual screen maps" - default y - depends on SETFONT - help - Support reading textual screen maps. - -config DEFAULT_SETFONT_DIR - string "Default directory for console-tools files" - default "" - depends on SETFONT - help - Directory to use if setfont's params are simple filenames - (not /path/to/file or ./file). Default is "" (no default directory). - -config SETKEYCODES - bool "setkeycodes" - default y - select PLATFORM_LINUX - help - This program loads entries into the kernel's scancode-to-keycode - map, allowing unusual keyboards to generate usable keycodes. - -config SETLOGCONS - bool "setlogcons" - default y - select PLATFORM_LINUX - help - This program redirects the output console of kernel messages. - -config SHOWKEY - bool "showkey" - default y - select PLATFORM_LINUX - help - Shows keys pressed. - -comment "Common options for loadfont and setfont" - depends on LOADFONT || SETFONT - -config FEATURE_LOADFONT_PSF2 - bool "Support for PSF2 console fonts" - default y - depends on LOADFONT || SETFONT - help - Support PSF2 console fonts. - -config FEATURE_LOADFONT_RAW - bool "Support for old (raw) console fonts" - default y - depends on LOADFONT || SETFONT - help - Support old (raw) console fonts. - endmenu diff --git a/console-tools/Kbuild.src b/console-tools/Kbuild.src index 94de9ad..6b4fb74 100644 --- a/console-tools/Kbuild.src +++ b/console-tools/Kbuild.src @@ -7,19 +7,3 @@ lib-y:= INSERT -lib-$(CONFIG_CHVT) += chvt.o -lib-$(CONFIG_FGCONSOLE) += fgconsole.o -lib-$(CONFIG_CLEAR) += clear.o -lib-$(CONFIG_DEALLOCVT) += deallocvt.o -lib-$(CONFIG_DUMPKMAP) += dumpkmap.o -lib-$(CONFIG_SETCONSOLE) += setconsole.o -lib-$(CONFIG_KBD_MODE) += kbd_mode.o -lib-$(CONFIG_LOADFONT) += loadfont.o -lib-$(CONFIG_LOADKMAP) += loadkmap.o -lib-$(CONFIG_OPENVT) += openvt.o -lib-$(CONFIG_RESET) += reset.o -lib-$(CONFIG_RESIZE) += resize.o -lib-$(CONFIG_SETFONT) += loadfont.o -lib-$(CONFIG_SETKEYCODES) += setkeycodes.o -lib-$(CONFIG_SETLOGCONS) += setlogcons.o -lib-$(CONFIG_SHOWKEY) += showkey.o diff --git a/console-tools/chvt.c b/console-tools/chvt.c index b9c974f..2b993eb 100644 --- a/console-tools/chvt.c +++ b/console-tools/chvt.c @@ -6,6 +6,17 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config CHVT +//config: bool "chvt" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program is used to change to another terminal. +//config: Example: chvt 4 (change to terminal /dev/tty4) + +//applet:IF_CHVT(APPLET(chvt, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_CHVT) += chvt.o //usage:#define chvt_trivial_usage //usage: "N" diff --git a/console-tools/clear.c b/console-tools/clear.c index ac22b78..b360d34 100644 --- a/console-tools/clear.c +++ b/console-tools/clear.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config CLEAR +//config: bool "clear" +//config: default y +//config: help +//config: This program clears the terminal screen. + +//applet:IF_CLEAR(APPLET(clear, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_CLEAR) += clear.o //usage:#define clear_trivial_usage //usage: "" diff --git a/console-tools/deallocvt.c b/console-tools/deallocvt.c index b131c0a..37c966a 100644 --- a/console-tools/deallocvt.c +++ b/console-tools/deallocvt.c @@ -7,8 +7,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config DEALLOCVT +//config: bool "deallocvt" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program deallocates unused virtual consoles. -/* no options, no getopt */ +//applet:IF_DEALLOCVT(APPLET(deallocvt, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_DEALLOCVT) += deallocvt.o //usage:#define deallocvt_trivial_usage //usage: "[N]" diff --git a/console-tools/dumpkmap.c b/console-tools/dumpkmap.c index bf8d690..4a24986 100644 --- a/console-tools/dumpkmap.c +++ b/console-tools/dumpkmap.c @@ -7,7 +7,17 @@ * Licensed under GPLv2 or later, see file LICENSE in this source tree. * */ -/* no options, no getopt */ +//config:config DUMPKMAP +//config: bool "dumpkmap" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program dumps the kernel's keyboard translation table to +//config: stdout, in binary format. You can then use loadkmap to load it. + +//applet:IF_DUMPKMAP(APPLET(dumpkmap, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_DUMPKMAP) += dumpkmap.o //usage:#define dumpkmap_trivial_usage //usage: "> keymap" @@ -18,6 +28,7 @@ //usage: "$ dumpkmap > keymap\n" #include "libbb.h" +#include "common_bufsiz.h" /* From */ struct kbentry { @@ -37,6 +48,7 @@ int dumpkmap_main(int argc UNUSED_PARAM, char **argv) struct kbentry ke; int i, j, fd; #define flags bb_common_bufsiz1 + setup_common_bufsiz(); /* When user accidentally runs "dumpkmap FILE" * instead of "dumpkmap >FILE", we'd dump binary stuff to tty. diff --git a/console-tools/fgconsole.c b/console-tools/fgconsole.c index 54355be..0197617 100644 --- a/console-tools/fgconsole.c +++ b/console-tools/fgconsole.c @@ -6,6 +6,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config FGCONSOLE +//config: bool "fgconsole" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program prints active (foreground) console number. + +//applet:IF_FGCONSOLE(APPLET(fgconsole, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_FGCONSOLE) += fgconsole.o //usage:#define fgconsole_trivial_usage //usage: "" diff --git a/console-tools/kbd_mode.c b/console-tools/kbd_mode.c index 1385367..f1238c6 100644 --- a/console-tools/kbd_mode.c +++ b/console-tools/kbd_mode.c @@ -8,6 +8,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config KBD_MODE +//config: bool "kbd_mode" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program reports and sets keyboard mode. + +//applet:IF_KBD_MODE(APPLET(kbd_mode, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_KBD_MODE) += kbd_mode.o //usage:#define kbd_mode_trivial_usage //usage: "[-a|k|s|u] [-C TTY]" diff --git a/console-tools/loadfont.c b/console-tools/loadfont.c index 032506d..52605ba 100644 --- a/console-tools/loadfont.c +++ b/console-tools/loadfont.c @@ -9,6 +9,57 @@ * * Licensed under GPLv2, see file LICENSE in this source tree. */ +//config:config LOADFONT +//config: bool "loadfont" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program loads a console font from standard input. +//config: +//config:config SETFONT +//config: bool "setfont" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: Allows to load console screen map. Useful for i18n. +//config: +//config:config FEATURE_SETFONT_TEXTUAL_MAP +//config: bool "Support reading textual screen maps" +//config: default y +//config: depends on SETFONT +//config: help +//config: Support reading textual screen maps. +//config: +//config:config DEFAULT_SETFONT_DIR +//config: string "Default directory for console-tools files" +//config: default "" +//config: depends on SETFONT +//config: help +//config: Directory to use if setfont's params are simple filenames +//config: (not /path/to/file or ./file). Default is "" (no default directory). +//config: +//config:comment "Common options for loadfont and setfont" +//config: depends on LOADFONT || SETFONT +//config: +//config:config FEATURE_LOADFONT_PSF2 +//config: bool "Support for PSF2 console fonts" +//config: default y +//config: depends on LOADFONT || SETFONT +//config: help +//config: Support PSF2 console fonts. +//config: +//config:config FEATURE_LOADFONT_RAW +//config: bool "Support for old (raw) console fonts" +//config: default y +//config: depends on LOADFONT || SETFONT +//config: help +//config: Support old (raw) console fonts. + +//applet:IF_LOADFONT(APPLET(loadfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) +//applet:IF_SETFONT(APPLET(setfont, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_LOADFONT) += loadfont.o +//kbuild:lib-$(CONFIG_SETFONT) += loadfont.o //usage:#define loadfont_trivial_usage //usage: "< font" @@ -319,8 +370,10 @@ int loadfont_main(int argc UNUSED_PARAM, char **argv) * We used to look at the length of the input file * with stat(); now that we accept compressed files, * just read the entire file. + * Len was 32k, but latarcyrheb-sun32.psfu is 34377 bytes + * (it has largish Unicode map). */ - len = 32*1024; // can't be larger + len = 128*1024; buffer = xmalloc_read(STDIN_FILENO, &len); // xmalloc_open_zipped_read_close(filename, &len); if (!buffer) @@ -405,7 +458,7 @@ int setfont_main(int argc UNUSED_PARAM, char **argv) } } // load font - len = 32*1024; // can't be larger + len = 128*1024; buffer = xmalloc_open_zipped_read_close(*argv, &len); if (!buffer) bb_simple_perror_msg_and_die(*argv); diff --git a/console-tools/loadkmap.c b/console-tools/loadkmap.c index 66ec3b0..70ab55a 100644 --- a/console-tools/loadkmap.c +++ b/console-tools/loadkmap.c @@ -6,12 +6,24 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config LOADKMAP +//config: bool "loadkmap" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program loads a keyboard translation table from +//config: standard input. + +//applet:IF_LOADKMAP(APPLET(loadkmap, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_LOADKMAP) += loadkmap.o //usage:#define loadkmap_trivial_usage //usage: "< keymap" //usage:#define loadkmap_full_usage "\n\n" -//usage: "Load a binary keyboard translation table from stdin\n" -/* //usage: "\n -C TTY Affect TTY instead of /dev/tty" */ +//usage: "Load a binary keyboard translation table from stdin" +////usage: "\n" +////usage: "\n -C TTY Affect TTY instead of /dev/tty" //usage: //usage:#define loadkmap_example_usage //usage: "$ loadkmap < /etc/i18n/lang-keymap\n" @@ -56,7 +68,7 @@ int loadkmap_main(int argc UNUSED_PARAM, char **argv) */ xread(STDIN_FILENO, flags, 7); - if (strncmp(flags, BINARY_KEYMAP_MAGIC, 7)) + if (!is_prefixed_with(flags, BINARY_KEYMAP_MAGIC)) bb_error_msg_and_die("not a valid binary keymap"); xread(STDIN_FILENO, flags, MAX_NR_KEYMAPS); diff --git a/console-tools/openvt.c b/console-tools/openvt.c index e523566..5cbc717 100644 --- a/console-tools/openvt.c +++ b/console-tools/openvt.c @@ -7,6 +7,17 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config OPENVT +//config: bool "openvt" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program is used to start a command on an unused +//config: virtual terminal. + +//applet:IF_OPENVT(APPLET(openvt, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_OPENVT) += openvt.o //usage:#define openvt_trivial_usage //usage: "[-c N] [-sw] [PROG ARGS]" diff --git a/console-tools/reset.c b/console-tools/reset.c index 65940bd..57cebb4 100644 --- a/console-tools/reset.c +++ b/console-tools/reset.c @@ -7,9 +7,18 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +/* "Standard" version of this tool is in ncurses package */ -/* BTW, which "standard" package has this utility? It doesn't seem - * to be ncurses, coreutils, console-tools... then what? */ +//config:config RESET +//config: bool "reset" +//config: default y +//config: help +//config: This program is used to reset the terminal screen, if it +//config: gets messed up. + +//applet:IF_RESET(APPLET(reset, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_RESET) += reset.o //usage:#define reset_trivial_usage //usage: "" diff --git a/console-tools/resize.c b/console-tools/resize.c index 4b0d63a..567086f 100644 --- a/console-tools/resize.c +++ b/console-tools/resize.c @@ -6,7 +6,26 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ -/* no options, no getopt */ +//config:config RESIZE +//config: bool "resize" +//config: default y +//config: help +//config: This program is used to (re)set the width and height of your current +//config: terminal. +//config: +//config:config FEATURE_RESIZE_PRINT +//config: bool "Print environment variables" +//config: default y +//config: depends on RESIZE +//config: help +//config: Prints the newly set size (number of columns and rows) of +//config: the terminal. +//config: E.g.: +//config: COLUMNS=80;LINES=44;export COLUMNS LINES; + +//applet:IF_RESIZE(APPLET(resize, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_RESIZE) += resize.o //usage:#define resize_trivial_usage //usage: "" @@ -14,10 +33,12 @@ //usage: "Resize the screen" #include "libbb.h" +#include "common_bufsiz.h" #define ESC "\033" -#define old_termios_p ((struct termios*)&bb_common_bufsiz1) +#define old_termios_p ((struct termios*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void onintr(int sig UNUSED_PARAM) @@ -33,6 +54,8 @@ int resize_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) struct winsize w = { 0, 0, 0, 0 }; int ret; + INIT_G(); + /* We use _stderr_ in order to make resize usable * in shell backticks (those redirect stdout away from tty). * NB: other versions of resize open "/dev/tty" diff --git a/console-tools/setconsole.c b/console-tools/setconsole.c index c0051dc..5805726 100644 --- a/console-tools/setconsole.c +++ b/console-tools/setconsole.c @@ -7,6 +7,24 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SETCONSOLE +//config: bool "setconsole" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program redirects the system console to another device, +//config: like the current tty while logged in via telnet. +//config: +//config:config FEATURE_SETCONSOLE_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on SETCONSOLE && LONG_OPTS +//config: help +//config: Support long options for the setconsole applet. + +//applet:IF_SETCONSOLE(APPLET(setconsole, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SETCONSOLE) += setconsole.o //usage:#define setconsole_trivial_usage //usage: "[-r" IF_FEATURE_SETCONSOLE_LONG_OPTIONS("|--reset") "] [DEVICE]" diff --git a/console-tools/setkeycodes.c b/console-tools/setkeycodes.c index a6a7c23..11fc37a 100644 --- a/console-tools/setkeycodes.c +++ b/console-tools/setkeycodes.c @@ -8,6 +8,17 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SETKEYCODES +//config: bool "setkeycodes" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program loads entries into the kernel's scancode-to-keycode +//config: map, allowing unusual keyboards to generate usable keycodes. + +//applet:IF_SETKEYCODES(APPLET(setkeycodes, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SETKEYCODES) += setkeycodes.o //usage:#define setkeycodes_trivial_usage //usage: "SCANCODE KEYCODE..." diff --git a/console-tools/setlogcons.c b/console-tools/setlogcons.c index c76a5a4..2ea36f0 100644 --- a/console-tools/setlogcons.c +++ b/console-tools/setlogcons.c @@ -8,11 +8,21 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SETLOGCONS +//config: bool "setlogcons" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: This program redirects the output console of kernel messages. + +//applet:IF_SETLOGCONS(APPLET(setlogcons, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SETLOGCONS) += setlogcons.o //usage:#define setlogcons_trivial_usage -//usage: "N" +//usage: "[N]" //usage:#define setlogcons_full_usage "\n\n" -//usage: "Redirect the kernel output to console N (0 for current)" +//usage: "Redirect the kernel output to console N. Default:0 (current console)" #include "libbb.h" diff --git a/console-tools/showkey.c b/console-tools/showkey.c index 69b785e..c2447b8 100644 --- a/console-tools/showkey.c +++ b/console-tools/showkey.c @@ -6,6 +6,16 @@ * * Licensed under GPLv2, see file LICENSE in this source tree. */ +//config:config SHOWKEY +//config: bool "showkey" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: Shows keys pressed. + +//applet:IF_SHOWKEY(APPLET(showkey, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SHOWKEY) += showkey.o //usage:#define showkey_trivial_usage //usage: "[-a | -k | -s]" @@ -83,7 +93,6 @@ int showkey_main(int argc UNUSED_PARAM, char **argv) if (04 /*CTRL-D*/ == c) break; } - } else { // we assume a PC keyboard xioctl(STDIN_FILENO, KDGKBMODE, &kbmode); diff --git a/coreutils/Config.src b/coreutils/Config.src index 0c44c4b..c056320 100644 --- a/coreutils/Config.src +++ b/coreutils/Config.src @@ -7,736 +7,15 @@ menu "Coreutils" INSERT -config CAL - bool "cal" - default y - help - cal is used to display a monthly calender. - -config CATV - bool "catv" - default y - help - Display nonprinting characters as escape sequences (like some - implementations' cat -v option). - -config CHGRP - bool "chgrp" - default y - help - chgrp is used to change the group ownership of files. - -config CHMOD - bool "chmod" - default y - help - chmod is used to change the access permission of files. - -config CHOWN - bool "chown" - default y - help - chown is used to change the user and/or group ownership - of files. - -config FEATURE_CHOWN_LONG_OPTIONS - bool "Enable long options" - default y - depends on CHOWN && LONG_OPTS - help - Enable use of long options - -config CHROOT - bool "chroot" - default y - help - chroot is used to change the root directory and run a command. - The default command is `/bin/sh'. - -config CKSUM - bool "cksum" - default y - help - cksum is used to calculate the CRC32 checksum of a file. - -config COMM - bool "comm" - default y - help - comm is used to compare two files line by line and return - a three-column output. - -config CP - bool "cp" - default y - help - cp is used to copy files and directories. - -config FEATURE_CP_LONG_OPTIONS - bool "Enable long options for cp" - default y - depends on CP && LONG_OPTS - help - Enable long options for cp. - Also add support for --parents option. - -config CUT - bool "cut" - default y - help - cut is used to print selected parts of lines from - each file to stdout. - -config DD - bool "dd" - default y - help - dd copies a file (from standard input to standard output, - by default) using specific input and output blocksizes, - while optionally performing conversions on it. - -config FEATURE_DD_SIGNAL_HANDLING - bool "Enable DD signal handling for status reporting" - default y - depends on DD - help - Sending a SIGUSR1 signal to a running `dd' process makes it - print to standard error the number of records read and written - so far, then to resume copying. - - $ dd if=/dev/zero of=/dev/null& - $ pid=$! kill -USR1 $pid; sleep 1; kill $pid - 10899206+0 records in - 10899206+0 records out - -config FEATURE_DD_THIRD_STATUS_LINE - bool "Enable the third status line upon signal" - default y - depends on DD && FEATURE_DD_SIGNAL_HANDLING - help - Displays a coreutils-like third status line with transferred bytes, - elapsed time and speed. - -config FEATURE_DD_IBS_OBS - bool "Enable ibs, obs and conv options" - default y - depends on DD - help - Enables support for writing a certain number of bytes in and out, - at a time, and performing conversions on the data stream. - -config DF - bool "df" - default y - help - df reports the amount of disk space used and available - on filesystems. - -config FEATURE_DF_FANCY - bool "Enable -a, -i, -B" - default y - depends on DF - help - This option enables -a, -i and -B. - - -a Show all filesystems - -i Inodes - -B Blocksize - -config DIRNAME - bool "dirname" - default y - help - dirname is used to strip a non-directory suffix from - a file name. - -config DOS2UNIX - bool "dos2unix/unix2dos" - default y - help - dos2unix is used to convert a text file from DOS format to - UNIX format, and vice versa. - -config UNIX2DOS - bool - default y - depends on DOS2UNIX - help - unix2dos is used to convert a text file from UNIX format to - DOS format, and vice versa. - -config DU - bool "du (default blocksize of 512 bytes)" - default y - help - du is used to report the amount of disk space used - for specified files. - -config FEATURE_DU_DEFAULT_BLOCKSIZE_1K - bool "Use a default blocksize of 1024 bytes (1K)" - default y - depends on DU - help - Use a blocksize of (1K) instead of the default 512b. - -config ECHO - bool "echo (basic SuSv3 version taking no options)" - default y - help - echo is used to print a specified string to stdout. - -# this entry also appears in shell/Config.in, next to the echo builtin -config FEATURE_FANCY_ECHO - bool "Enable echo options (-n and -e)" - default y - depends on ECHO || ASH_BUILTIN_ECHO || HUSH - help - This adds options (-n and -e) to echo. - -config ENV - bool "env" - default y - help - env is used to set an environment variable and run - a command; without options it displays the current - environment. - -config FEATURE_ENV_LONG_OPTIONS - bool "Enable long options" - default y - depends on ENV && LONG_OPTS - help - Support long options for the env applet. - -config EXPAND - bool "expand" - default y - help - By default, convert all tabs to spaces. - -config FEATURE_EXPAND_LONG_OPTIONS - bool "Enable long options" - default y - depends on EXPAND && LONG_OPTS - help - Support long options for the expand applet. - -config EXPR - bool "expr" - default y - help - expr is used to calculate numbers and print the result - to standard output. - -config EXPR_MATH_SUPPORT_64 - bool "Extend Posix numbers support to 64 bit" - default y - depends on EXPR - help - Enable 64-bit math support in the expr applet. This will make - the applet slightly larger, but will allow computation with very - large numbers. - -config FALSE - bool "false" - default y - help - false returns an exit code of FALSE (1). - -config FOLD - bool "fold" - default y - help - Wrap text to fit a specific width. - -config FSYNC - bool "fsync" - default y - help - fsync is used to flush file-related cached blocks to disk. - -config HEAD - bool "head" - default y - help - head is used to print the first specified number of lines - from files. - -config FEATURE_FANCY_HEAD - bool "Enable head options (-c, -q, and -v)" - default y - depends on HEAD - help - This enables the head options (-c, -q, and -v). - -config INSTALL - bool "install" - default y - help - Copy files and set attributes. - -config FEATURE_INSTALL_LONG_OPTIONS - bool "Enable long options" - default y - depends on INSTALL && LONG_OPTS - help - Support long options for the install applet. - -####config LENGTH -#### bool "length" -#### default y -#### help -#### length is used to print out the length of a specified string. - -config LN - bool "ln" - default y - help - ln is used to create hard or soft links between files. - -config LOGNAME - bool "logname" - default y - help - logname is used to print the current user's login name. - -config LS - bool "ls" - default y - help - ls is used to list the contents of directories. - -config FEATURE_LS_FILETYPES - bool "Enable filetyping options (-p and -F)" - default y - depends on LS - help - Enable the ls options (-p and -F). - -config FEATURE_LS_FOLLOWLINKS - bool "Enable symlinks dereferencing (-L)" - default y - depends on LS - help - Enable the ls option (-L). - -config FEATURE_LS_RECURSIVE - bool "Enable recursion (-R)" - default y - depends on LS - help - Enable the ls option (-R). - -config FEATURE_LS_SORTFILES - bool "Sort the file names" - default y - depends on LS - help - Allow ls to sort file names alphabetically. - -config FEATURE_LS_TIMESTAMPS - bool "Show file timestamps" - default y - depends on LS - help - Allow ls to display timestamps for files. - -config FEATURE_LS_USERNAME - bool "Show username/groupnames" - default y - depends on LS - help - Allow ls to display username/groupname for files. - -config FEATURE_LS_COLOR - bool "Allow use of color to identify file types" - default y - depends on LS && LONG_OPTS - help - This enables the --color option to ls. - -config FEATURE_LS_COLOR_IS_DEFAULT - bool "Produce colored ls output by default" - default y - depends on FEATURE_LS_COLOR - help - Saying yes here will turn coloring on by default, - even if no "--color" option is given to the ls command. - This is not recommended, since the colors are not - configurable, and the output may not be legible on - many output screens. - -config MD5SUM - bool "md5sum" - default y - help - md5sum is used to print or check MD5 checksums. - -config MKDIR - bool "mkdir" - default y - help - mkdir is used to create directories with the specified names. - -config FEATURE_MKDIR_LONG_OPTIONS - bool "Enable long options" - default y - depends on MKDIR && LONG_OPTS - help - Support long options for the mkdir applet. +comment "Common options" -config MKFIFO - bool "mkfifo" +config FEATURE_VERBOSE + bool "Support verbose options (usually -v) for various applets" default y help - mkfifo is used to create FIFOs (named pipes). - The `mknod' program can also create FIFOs. - -config MKNOD - bool "mknod" - default y - help - mknod is used to create FIFOs or block/character special - files with the specified names. - -config MV - bool "mv" - default y - help - mv is used to move or rename files or directories. - -config FEATURE_MV_LONG_OPTIONS - bool "Enable long options" - default y - depends on MV && LONG_OPTS - help - Support long options for the mv applet. - -config NICE - bool "nice" - default y - help - nice runs a program with modified scheduling priority. - -config NOHUP - bool "nohup" - default y - help - run a command immune to hangups, with output to a non-tty. - -config OD - bool "od" - default y - help - od is used to dump binary files in octal and other formats. - -config PRINTENV - bool "printenv" - default y - help - printenv is used to print all or part of environment. - -config PRINTF - bool "printf" - default y - help - printf is used to format and print specified strings. - It's similar to `echo' except it has more options. - -config PWD - bool "pwd" - default y - help - pwd is used to print the current directory. - -config READLINK - bool "readlink" - default y - help - This program reads a symbolic link and returns the name - of the file it points to - -config FEATURE_READLINK_FOLLOW - bool "Enable canonicalization by following all symlinks (-f)" - default y - depends on READLINK - help - Enable the readlink option (-f). - -config REALPATH - bool "realpath" - default y - help - Return the canonicalized absolute pathname. - This isn't provided by GNU shellutils, but where else does it belong. - -config RM - bool "rm" - default y - help - rm is used to remove files or directories. - -config RMDIR - bool "rmdir" - default y - help - rmdir is used to remove empty directories. - -config FEATURE_RMDIR_LONG_OPTIONS - bool "Enable long options" - default y - depends on RMDIR && LONG_OPTS - help - Support long options for the rmdir applet, including - --ignore-fail-on-non-empty for compatibility with GNU rmdir. - -config SEQ - bool "seq" - default y - help - print a sequence of numbers - -config SHA1SUM - bool "sha1sum" - default y - help - Compute and check SHA1 message digest - -config SHA256SUM - bool "sha256sum" - default y - help - Compute and check SHA256 message digest - -config SHA512SUM - bool "sha512sum" - default y - help - Compute and check SHA512 message digest - -config SHA3SUM - bool "sha3sum" - default y - help - Compute and check SHA3 (512-bit) message digest - -config SLEEP - bool "sleep" - default y - help - sleep is used to pause for a specified number of seconds. - It comes in 3 versions: - - small: takes one integer parameter - - fancy: takes multiple integer arguments with suffixes: - sleep 1d 2h 3m 15s - - fancy with fractional numbers: - sleep 2.3s 4.5h sleeps for 16202.3 seconds - Last one is "the most compatible" with coreutils sleep, - but it adds around 1k of code. - -config FEATURE_FANCY_SLEEP - bool "Enable multiple arguments and s/m/h/d suffixes" - default y - depends on SLEEP - help - Allow sleep to pause for specified minutes, hours, and days. - -config FEATURE_FLOAT_SLEEP - bool "Enable fractional arguments" - default y - depends on FEATURE_FANCY_SLEEP - help - Allow for fractional numeric parameters. - -config SORT - bool "sort" - default y - help - sort is used to sort lines of text in specified files. - -config FEATURE_SORT_BIG - bool "Full SuSv3 compliant sort (support -ktcsbdfiozgM)" - default y - depends on 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 SPLIT - bool "split" - default y - help - split a file into pieces. - -config FEATURE_SPLIT_FANCY - bool "Fancy extensions" - default y - depends on SPLIT - help - Add support for features not required by SUSv3. - Supports additional suffixes 'b' for 512 bytes, - 'g' for 1GiB for the -b option. - -config STAT - bool "stat" - default y - select PLATFORM_LINUX # statfs() - help - display file or filesystem status. - -config FEATURE_STAT_FORMAT - bool "Enable custom formats (-c)" - default y - depends on 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 STTY - bool "stty" - default y - help - stty is used to change and print terminal line settings. - -config SUM - bool "sum" - default y - help - checksum and count the blocks in a file - -config SYNC - bool "sync" - default y - help - sync is used to flush filesystem buffers. - -config TAC - bool "tac" - default y - help - tac is used to concatenate and print files in reverse. - -config TAIL - bool "tail" - default y - help - tail is used to print the last specified number of lines - from files. - -config FEATURE_FANCY_TAIL - bool "Enable extra tail options (-q, -s, -v, and -F)" - default y - depends on TAIL - help - The options (-q, -s, and -v) are provided by GNU tail, but - are not specific in the SUSv3 standard. - - -q Never output headers giving file names - -s SEC Wait SEC seconds between reads with -f - -v Always output headers giving file names - -config TEE - bool "tee" - default y - help - tee is used to read from standard input and write - to standard output and files. - -config FEATURE_TEE_USE_BLOCK_IO - bool "Enable block I/O (larger/faster) instead of byte I/O" - default y - depends on TEE - help - Enable this option for a faster tee, at expense of size. - -config TRUE - bool "true" - default y - help - true returns an exit code of TRUE (0). - -config TTY - bool "tty" - default y - help - tty is used to print the name of the current terminal to - standard output. - -config UNAME - bool "uname" - default y - help - uname is used to print system information. - -config UNEXPAND - bool "unexpand" - default y - help - By default, convert only leading sequences of blanks to tabs. - -config FEATURE_UNEXPAND_LONG_OPTIONS - bool "Enable long options" - default y - depends on UNEXPAND && LONG_OPTS - help - Support long options for the unexpand applet. - -config UNIQ - bool "uniq" - default y - help - uniq is used to remove duplicate lines from a sorted file. - -config USLEEP - bool "usleep" - default y - help - usleep is used to pause for a specified number of microseconds. - -config UUDECODE - bool "uudecode" - default y - help - uudecode is used to decode a uuencoded file. - -config UUENCODE - bool "uuencode" - default y - help - uuencode is used to uuencode a file. - -config WC - bool "wc" - default y - help - wc is used to print the number of bytes, words, and lines, - in specified files. - -config FEATURE_WC_LARGE - bool "Support very large files in wc" - default y - depends on WC - help - Use "unsigned long long" in wc for counter variables. - -config WHOAMI - bool "whoami" - default y - help - whoami is used to print the username of the current - user id (same as id -un). - -config YES - bool "yes" - default y - help - yes is used to repeatedly output a specific string, or - the default string `y'. + Enable cp -v, rm -v and similar messages. + Also enables long option (--verbose) if it exists. + Without this option, -v is accepted but ignored. comment "Common options for cp and mv" depends on CP || MV @@ -772,17 +51,4 @@ config FEATURE_HUMAN_READABLE help Allow df, du, and ls to have human readable output. -comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum" - depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM - -config FEATURE_MD5_SHA1_SUM_CHECK - bool "Enable -c, -s and -w options" - default y - depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM - help - Enabling the -c options allows files to be checked - against pre-calculated hash values. - - -s and -w are useful options when verifying checksums. - endmenu diff --git a/coreutils/Kbuild.src b/coreutils/Kbuild.src index 9970c8f..d9a4487 100644 --- a/coreutils/Kbuild.src +++ b/coreutils/Kbuild.src @@ -9,77 +9,17 @@ libs-y += libcoreutils/ lib-y:= INSERT -lib-$(CONFIG_CAL) += cal.o -lib-$(CONFIG_CATV) += catv.o -lib-$(CONFIG_CHGRP) += chgrp.o chown.o -lib-$(CONFIG_CHMOD) += chmod.o -lib-$(CONFIG_CHOWN) += chown.o -lib-$(CONFIG_ADDUSER) += chown.o # used by adduser -lib-$(CONFIG_ADDGROUP) += chown.o # used by adduser -lib-$(CONFIG_CHROOT) += chroot.o -lib-$(CONFIG_CKSUM) += cksum.o -lib-$(CONFIG_COMM) += comm.o -lib-$(CONFIG_CP) += cp.o -lib-$(CONFIG_CUT) += cut.o -lib-$(CONFIG_DD) += dd.o -lib-$(CONFIG_DF) += df.o -lib-$(CONFIG_DIRNAME) += dirname.o -lib-$(CONFIG_DOS2UNIX) += dos2unix.o -lib-$(CONFIG_DU) += du.o -lib-$(CONFIG_ECHO) += echo.o -lib-$(CONFIG_ASH) += echo.o # used by ash -lib-$(CONFIG_HUSH) += echo.o # used by hush -lib-$(CONFIG_ENV) += env.o -lib-$(CONFIG_EXPR) += expr.o -lib-$(CONFIG_EXPAND) += expand.o -lib-$(CONFIG_FALSE) += false.o -lib-$(CONFIG_FOLD) += fold.o -lib-$(CONFIG_FSYNC) += fsync.o -lib-$(CONFIG_INSTALL) += install.o -#lib-$(CONFIG_LENGTH) += length.o -lib-$(CONFIG_LN) += ln.o -lib-$(CONFIG_LOGNAME) += logname.o -lib-$(CONFIG_LS) += ls.o -lib-$(CONFIG_FTPD) += ls.o -lib-$(CONFIG_GROUPS) += id.o -lib-$(CONFIG_MD5SUM) += md5_sha1_sum.o -lib-$(CONFIG_MKDIR) += mkdir.o -lib-$(CONFIG_MKFIFO) += mkfifo.o -lib-$(CONFIG_MKNOD) += mknod.o -lib-$(CONFIG_MV) += mv.o -lib-$(CONFIG_NICE) += nice.o -lib-$(CONFIG_NOHUP) += nohup.o -lib-$(CONFIG_OD) += od.o -lib-$(CONFIG_PRINTENV) += printenv.o -lib-$(CONFIG_PRINTF) += printf.o + +lib-$(CONFIG_MORE) += cat.o # more uses it if stdout isn't a tty +lib-$(CONFIG_LESS) += cat.o # less too +lib-$(CONFIG_CRONTAB) += cat.o # crontab -l +lib-$(CONFIG_ADDUSER) += chown.o # used by adduser +lib-$(CONFIG_ADDGROUP) += chown.o # used by adduser +lib-$(CONFIG_ASH) += echo.o # used by ash +lib-$(CONFIG_SH_IS_ASH) += echo.o # used by ash +lib-$(CONFIG_BASH_IS_ASH) += echo.o # used by ash +lib-$(CONFIG_HUSH) += echo.o # used by hush +lib-$(CONFIG_SH_IS_HUSH) += echo.o # used by hush +lib-$(CONFIG_BASH_IS_HUSH) += echo.o # used by hush +lib-$(CONFIG_FTPD) += ls.o # used by ftpd lib-$(CONFIG_ASH_BUILTIN_PRINTF) += printf.o -lib-$(CONFIG_PWD) += pwd.o -lib-$(CONFIG_READLINK) += readlink.o -lib-$(CONFIG_REALPATH) += realpath.o -lib-$(CONFIG_RM) += rm.o -lib-$(CONFIG_RMDIR) += rmdir.o -lib-$(CONFIG_SEQ) += seq.o -lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o -lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o -lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o -lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o -lib-$(CONFIG_SLEEP) += sleep.o -lib-$(CONFIG_SPLIT) += split.o -lib-$(CONFIG_SORT) += sort.o -lib-$(CONFIG_STAT) += stat.o -lib-$(CONFIG_STTY) += stty.o -lib-$(CONFIG_SUM) += sum.o -lib-$(CONFIG_SYNC) += sync.o -lib-$(CONFIG_TAC) += tac.o -lib-$(CONFIG_TEE) += tee.o -lib-$(CONFIG_TRUE) += true.o -lib-$(CONFIG_TTY) += tty.o -lib-$(CONFIG_UNAME) += uname.o -lib-$(CONFIG_UNEXPAND) += expand.o -lib-$(CONFIG_UNIQ) += uniq.o -lib-$(CONFIG_USLEEP) += usleep.o -lib-$(CONFIG_UUDECODE) += uudecode.o -lib-$(CONFIG_UUENCODE) += uuencode.o -lib-$(CONFIG_WC) += wc.o -lib-$(CONFIG_WHOAMI) += whoami.o -lib-$(CONFIG_YES) += yes.o diff --git a/coreutils/basename.c b/coreutils/basename.c index 1f7a137..ace0148 100644 --- a/coreutils/basename.c +++ b/coreutils/basename.c @@ -14,12 +14,6 @@ * 2) Don't check for options, as per SUSv3. * 3) Save some space by using strcmp(). Calling strncmp() here was silly. */ - -/* BB_AUDIT SUSv3 compliant */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/basename.html */ - -//kbuild:lib-$(CONFIG_BASENAME) += basename.o - //config:config BASENAME //config: bool "basename" //config: default y @@ -28,10 +22,17 @@ //config: leaving just the filename itself. Enable this option if you wish //config: to enable the 'basename' utility. +//applet:IF_BASENAME(APPLET_NOFORK(basename, basename, BB_DIR_USR_BIN, BB_SUID_DROP, basename)) + +//kbuild:lib-$(CONFIG_BASENAME) += basename.o + +/* BB_AUDIT SUSv3 compliant */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/basename.html */ + //usage:#define basename_trivial_usage //usage: "FILE [SUFFIX]" //usage:#define basename_full_usage "\n\n" -//usage: "Strip directory path and .SUFFIX from FILE\n" +//usage: "Strip directory path and .SUFFIX from FILE" //usage: //usage:#define basename_example_usage //usage: "$ basename /usr/local/bin/foo\n" diff --git a/coreutils/cal.c b/coreutils/cal.c index 5d97d61..4f5bbf7 100644 --- a/coreutils/cal.c +++ b/coreutils/cal.c @@ -6,17 +6,25 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) + * + * Major size reduction... over 50% (>1.5k) on i386. + */ +//config:config CAL +//config: bool "cal" +//config: default y +//config: help +//config: cal is used to display a monthly calendar. + +//applet:IF_CAL(APPLET(cal, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_CAL) += cal.o /* BB_AUDIT SUSv3 compliant with -j and -y extensions (from util-linux). */ /* BB_AUDIT BUG: The output of 'cal -j 1752' is incorrect. The upstream * BB_AUDIT BUG: version in util-linux seems to be broken as well. */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/cal.html */ -/* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) - * - * Major size reduction... over 50% (>1.5k) on i386. - */ - //usage:#define cal_trivial_usage //usage: "[-jy] [[MONTH] YEAR]" //usage:#define cal_full_usage "\n\n" diff --git a/coreutils/cat.c b/coreutils/cat.c index 00c38d4..6597888 100644 --- a/coreutils/cat.c +++ b/coreutils/cat.c @@ -6,15 +6,6 @@ * * Licensed under GPLv2, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 compliant */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */ - -//kbuild:lib-$(CONFIG_CAT) += cat.o -//kbuild:lib-$(CONFIG_MORE) += cat.o # more uses it if stdout isn't a tty -//kbuild:lib-$(CONFIG_LESS) += cat.o # less too -//kbuild:lib-$(CONFIG_CRONTAB) += cat.o # crontab -l - //config:config CAT //config: bool "cat" //config: default y @@ -22,6 +13,13 @@ //config: cat is used to concatenate files and print them to the standard //config: output. Enable this option if you wish to enable the 'cat' utility. +//applet:IF_CAT(APPLET_NOFORK(cat, cat, BB_DIR_BIN, BB_SUID_DROP, cat)) + +//kbuild:lib-$(CONFIG_CAT) += cat.o + +/* BB_AUDIT SUSv3 compliant */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/cat.html */ + //usage:#define cat_trivial_usage //usage: "[FILE]..." //usage:#define cat_full_usage "\n\n" diff --git a/coreutils/catv.c b/coreutils/catv.c index e3499c5..1aeebe1 100644 --- a/coreutils/catv.c +++ b/coreutils/catv.c @@ -10,6 +10,17 @@ /* See "Cat -v considered harmful" at * http://cm.bell-labs.com/cm/cs/doc/84/kp.ps.gz */ +//config:config CATV +//config: bool "catv" +//config: default y +//config: help +//config: Display nonprinting characters as escape sequences (like some +//config: implementations' cat -v option). + +//applet:IF_CATV(APPLET(catv, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_CATV) += catv.o + //usage:#define catv_trivial_usage //usage: "[-etv] [FILE]..." //usage:#define catv_full_usage "\n\n" @@ -19,21 +30,24 @@ //usage: "\n -v Don't use ^x or M-x escapes" #include "libbb.h" +#include "common_bufsiz.h" -int catv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int catv_main(int argc UNUSED_PARAM, char **argv) -{ - int retval = EXIT_SUCCESS; - int fd; - unsigned opts; #define CATV_OPT_e (1<<0) #define CATV_OPT_t (1<<1) #define CATV_OPT_v (1<<2) - typedef char BUG_const_mismatch[ +struct BUG_const_mismatch { + char BUG_const_mismatch[ CATV_OPT_e == VISIBLE_ENDLINE && CATV_OPT_t == VISIBLE_SHOW_TABS ? 1 : -1 ]; +}; +int catv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int catv_main(int argc UNUSED_PARAM, char **argv) +{ + int retval = EXIT_SUCCESS; + int fd; + unsigned opts; opts = getopt32(argv, "etv"); argv += optind; #if 0 /* These consts match, we can just pass "opts" to visible() */ @@ -46,6 +60,9 @@ int catv_main(int argc UNUSED_PARAM, char **argv) /* Read from stdin if there's nothing else to do. */ if (!argv[0]) *--argv = (char*)"-"; + +#define read_buf bb_common_bufsiz1 + setup_common_bufsiz(); do { fd = open_or_warn_stdin(*argv); if (fd < 0) { @@ -55,7 +72,6 @@ int catv_main(int argc UNUSED_PARAM, char **argv) for (;;) { int i, res; -#define read_buf bb_common_bufsiz1 res = read(fd, read_buf, COMMON_BUFSIZE); if (res < 0) retval = EXIT_FAILURE; diff --git a/coreutils/chgrp.c b/coreutils/chgrp.c index 7076db6..8dca63c 100644 --- a/coreutils/chgrp.c +++ b/coreutils/chgrp.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config CHGRP +//config: bool "chgrp" +//config: default y +//config: help +//config: chgrp is used to change the group ownership of files. + +//applet:IF_CHGRP(APPLET_NOEXEC(chgrp, chgrp, BB_DIR_BIN, BB_SUID_DROP, chgrp)) + +//kbuild:lib-$(CONFIG_CHGRP) += chgrp.o chown.o /* BB_AUDIT SUSv3 defects - none? */ /* BB_AUDIT GNU defects - unsupported long options. */ diff --git a/coreutils/chmod.c b/coreutils/chmod.c index 5ee45b9..80913f5 100644 --- a/coreutils/chmod.c +++ b/coreutils/chmod.c @@ -9,6 +9,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config CHMOD +//config: bool "chmod" +//config: default y +//config: help +//config: chmod is used to change the access permission of files. + +//applet:IF_CHMOD(APPLET_NOEXEC(chmod, chmod, BB_DIR_BIN, BB_SUID_DROP, chmod)) + +//kbuild:lib-$(CONFIG_CHMOD) += chmod.o /* BB_AUDIT SUSv3 compliant */ /* BB_AUDIT GNU defects - unsupported long options. */ @@ -69,9 +78,9 @@ static int FAST_FUNC fileAction(const char *fileName, struct stat *statbuf, void if (S_ISLNK(statbuf->st_mode)) return TRUE; } - newmode = statbuf->st_mode; - if (!bb_parse_mode((char *)param, &newmode)) + newmode = bb_parse_mode((char *)param, statbuf->st_mode); + if (newmode == (mode_t)-1) bb_error_msg_and_die("invalid mode '%s'", (char *)param); if (chmod(fileName, newmode) == 0) { diff --git a/coreutils/chown.c b/coreutils/chown.c index 1a91276..50b06d7 100644 --- a/coreutils/chown.c +++ b/coreutils/chown.c @@ -6,20 +6,37 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config CHOWN +//config: bool "chown" +//config: default y +//config: help +//config: chown is used to change the user and/or group ownership +//config: of files. +//config: +//config:config FEATURE_CHOWN_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on CHOWN && LONG_OPTS +//config: help +//config: Enable use of long options + +//applet:IF_CHOWN(APPLET_NOEXEC(chown, chown, BB_DIR_BIN, BB_SUID_DROP, chown)) + +//kbuild:lib-$(CONFIG_CHOWN) += chown.o /* BB_AUDIT SUSv3 defects - none? */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/chown.html */ //usage:#define chown_trivial_usage -//usage: "[-RhLHP"IF_DESKTOP("cvf")"]... OWNER[<.|:>[GROUP]] FILE..." +//usage: "[-Rh"IF_DESKTOP("LHPcvf")"]... USER[:[GRP]] FILE..." //usage:#define chown_full_usage "\n\n" -//usage: "Change the owner and/or group of each FILE to OWNER and/or GROUP\n" +//usage: "Change the owner and/or group of each FILE to USER and/or GRP\n" //usage: "\n -R Recurse" //usage: "\n -h Affect symlinks instead of symlink targets" +//usage: IF_DESKTOP( //usage: "\n -L Traverse all symlinks to directories" //usage: "\n -H Traverse symlinks on command line only" //usage: "\n -P Don't traverse symlinks (default)" -//usage: IF_DESKTOP( //usage: "\n -c List changed files" //usage: "\n -v List all files" //usage: "\n -f Hide errors" @@ -112,10 +129,6 @@ int chown_main(int argc UNUSED_PARAM, char **argv) int opt, flags; struct param_t param; - /* Just -1 might not work: uid_t may be unsigned long */ - param.ugid.uid = -1L; - param.ugid.gid = -1L; - #if ENABLE_FEATURE_CHOWN_LONG_OPTIONS applet_long_options = chown_longopts; #endif diff --git a/coreutils/chroot.c b/coreutils/chroot.c index 633e66b..5c067c1 100644 --- a/coreutils/chroot.c +++ b/coreutils/chroot.c @@ -6,6 +6,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config CHROOT +//config: bool "chroot" +//config: default y +//config: help +//config: chroot is used to change the root directory and run a command. +//config: The default command is `/bin/sh'. + +//applet:IF_CHROOT(APPLET(chroot, BB_DIR_USR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_CHROOT) += chroot.o /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ diff --git a/coreutils/cksum.c b/coreutils/cksum.c index ac0b0c3..aeec018 100644 --- a/coreutils/cksum.c +++ b/coreutils/cksum.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config CKSUM +//config: bool "cksum" +//config: default y +//config: help +//config: cksum is used to calculate the CRC32 checksum of a file. + +//applet:IF_CKSUM(APPLET_NOEXEC(cksum, cksum, BB_DIR_USR_BIN, BB_SUID_DROP, cksum)) + +//kbuild:lib-$(CONFIG_CKSUM) += cksum.o //usage:#define cksum_trivial_usage //usage: "FILES..." @@ -13,6 +22,7 @@ //usage: "Calculate the CRC32 checksums of FILES" #include "libbb.h" +#include "common_bufsiz.h" /* This is a NOEXEC applet. Be very careful! */ @@ -32,6 +42,7 @@ int cksum_main(int argc UNUSED_PARAM, char **argv) argv++; #endif + setup_common_bufsiz(); do { int fd = open_or_warn_stdin(*argv ? *argv : bb_msg_standard_input); @@ -43,7 +54,7 @@ int cksum_main(int argc UNUSED_PARAM, char **argv) length = 0; #define read_buf bb_common_bufsiz1 - while ((bytes_read = safe_read(fd, read_buf, sizeof(read_buf))) > 0) { + while ((bytes_read = safe_read(fd, read_buf, COMMON_BUFSIZE)) > 0) { length += bytes_read; crc = crc32_block_endian1(crc, read_buf, bytes_read, crc32_table); } diff --git a/coreutils/comm.c b/coreutils/comm.c index cd45095..b6a1278 100644 --- a/coreutils/comm.c +++ b/coreutils/comm.c @@ -6,6 +6,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config COMM +//config: bool "comm" +//config: default y +//config: help +//config: comm is used to compare two files line by line and return +//config: a three-column output. + +//applet:IF_COMM(APPLET(comm, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_COMM) += comm.o //usage:#define comm_trivial_usage //usage: "[-123] FILE1 FILE2" diff --git a/coreutils/cp.c b/coreutils/cp.c index de2e512..4ecdaaf 100644 --- a/coreutils/cp.c +++ b/coreutils/cp.c @@ -7,13 +7,29 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Size reduction. */ +//config:config CP +//config: bool "cp" +//config: default y +//config: help +//config: cp is used to copy files and directories. +//config: +//config:config FEATURE_CP_LONG_OPTIONS +//config: bool "Enable long options for cp" +//config: default y +//config: depends on CP && LONG_OPTS +//config: help +//config: Enable long options for cp. +//config: Also add support for --parents option. + +//applet:IF_CP(APPLET_NOEXEC(cp, cp, BB_DIR_BIN, BB_SUID_DROP, cp)) + +//kbuild:lib-$(CONFIG_CP) += cp.o + +/* http://www.opengroup.org/onlinepubs/007904975/utilities/cp.html */ //usage:#define cp_trivial_usage //usage: "[OPTIONS] SOURCE... DEST" @@ -31,6 +47,7 @@ //usage: "\n -f Overwrite" //usage: "\n -i Prompt before overwrite" //usage: "\n -l,-s Create (sym)links" +//usage: "\n -u Copy only newer files" #include "libbb.h" #include "libcoreutils/coreutils.h" @@ -49,12 +66,10 @@ int cp_main(int argc, char **argv) int flags; int status; enum { - OPT_a = 1 << (sizeof(FILEUTILS_CP_OPTSTR)-1), - OPT_r = 1 << (sizeof(FILEUTILS_CP_OPTSTR)), - OPT_P = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+1), - OPT_v = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+2), + FILEUTILS_CP_OPTNUM = sizeof(FILEUTILS_CP_OPTSTR)-1, #if ENABLE_FEATURE_CP_LONG_OPTIONS - OPT_parents = 1 << (sizeof(FILEUTILS_CP_OPTSTR)+3), + /*OPT_rmdest = FILEUTILS_RMDEST = 1 << FILEUTILS_CP_OPTNUM */ + OPT_parents = 1 << (FILEUTILS_CP_OPTNUM+1), #endif }; @@ -76,11 +91,12 @@ int cp_main(int argc, char **argv) "recursive\0" No_argument "R" "symbolic-link\0" No_argument "s" "verbose\0" No_argument "v" - "parents\0" No_argument "\xff" + "update\0" No_argument "u" + "remove-destination\0" No_argument "\xff" + "parents\0" No_argument "\xfe" ; #endif - // -v (--verbose) is ignored - flags = getopt32(argv, FILEUTILS_CP_OPTSTR "arPv"); + flags = getopt32(argv, FILEUTILS_CP_OPTSTR); /* Options of cp from GNU coreutils 6.10: * -a, --archive * -f, --force @@ -95,6 +111,11 @@ int cp_main(int argc, char **argv) * -d same as --no-dereference --preserve=links * -p same as --preserve=mode,ownership,timestamps * -c same as --preserve=context + * -u, --update + * copy only when the SOURCE file is newer than the destination + * file or when the destination file is missing + * --remove-destination + * remove each existing destination file before attempting to open * --parents * use full source file name under DIRECTORY * NOT SUPPORTED IN BBOX: @@ -107,8 +128,6 @@ int cp_main(int argc, char **argv) * preserve attributes (default: mode,ownership,timestamps), * if possible additional attributes: security context,links,all * --no-preserve=ATTR_LIST - * --remove-destination - * remove each existing destination file before attempting to open * --sparse=WHEN * control creation of sparse files * --strip-trailing-slashes @@ -119,9 +138,6 @@ int cp_main(int argc, char **argv) * copy all SOURCE arguments into DIRECTORY * -T, --no-target-directory * treat DEST as a normal file - * -u, --update - * copy only when the SOURCE file is newer than the destination - * file or when the destination file is missing * -x, --one-file-system * stay on this file system * -Z, --context=CONTEXT @@ -157,11 +173,16 @@ int cp_main(int argc, char **argv) return EXIT_FAILURE; #if ENABLE_FEATURE_CP_LONG_OPTIONS + //bb_error_msg("flags:%x FILEUTILS_RMDEST:%x OPT_parents:%x", + // flags, FILEUTILS_RMDEST, OPT_parents); if (flags & OPT_parents) { if (!(d_flags & 2)) { bb_error_msg_and_die("with --parents, the destination must be a directory"); } } + if (flags & FILEUTILS_RMDEST) { + flags |= FILEUTILS_FORCE; + } #endif /* ...if neither is a directory... */ diff --git a/coreutils/cut.c b/coreutils/cut.c index 84449c7..a33a825 100644 --- a/coreutils/cut.c +++ b/coreutils/cut.c @@ -8,6 +8,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config CUT +//config: bool "cut" +//config: default y +//config: help +//config: cut is used to print selected parts of lines from +//config: each file to stdout. + +//applet:IF_CUT(APPLET_NOEXEC(cut, cut, BB_DIR_USR_BIN, BB_SUID_DROP, cut)) + +//kbuild:lib-$(CONFIG_CUT) += cut.o //usage:#define cut_trivial_usage //usage: "[OPTIONS] [FILE]..." diff --git a/coreutils/date.c b/coreutils/date.c index 767e0d4..31b53d2 100644 --- a/coreutils/date.c +++ b/coreutils/date.c @@ -8,8 +8,7 @@ * bugfixes and cleanup by Bernhard Reutner-Fischer * * Licensed under GPLv2 or later, see file LICENSE in this source tree. -*/ - + */ /* This 'date' command supports only 2 time setting formats, all the GNU strftime stuff (its in libc, lets use it), setting time using UTC and displaying it, as well as @@ -19,10 +18,6 @@ /* Input parsing code is always bulky - used heavy duty libc stuff as much as possible, missed out a lot of bounds checking */ -//applet:IF_DATE(APPLET(date, BB_DIR_BIN, BB_SUID_DROP)) - -//kbuild:lib-$(CONFIG_DATE) += date.o - //config:config DATE //config: bool "date" //config: default y @@ -63,6 +58,10 @@ //config: the same format. With it on, 'date DATE' additionally supports //config: MMDDhhmm[[YY]YY][.ss] format. +//applet:IF_DATE(APPLET(date, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_DATE) += date.o + /* GNU coreutils 6.9 man page: * date [OPTION]... [+FORMAT] * date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]] @@ -138,9 +137,11 @@ //usage: "Wed Apr 12 18:52:41 MDT 2000\n" #include "libbb.h" +#include "common_bufsiz.h" #if ENABLE_FEATURE_DATE_NANO # include #endif +#include enum { OPT_RFC2822 = (1 << 0), /* R */ @@ -368,16 +369,17 @@ int date_main(int argc UNUSED_PARAM, char **argv) #endif #define date_buf bb_common_bufsiz1 + setup_common_bufsiz(); if (*fmt_dt2str == '\0') { /* With no format string, just print a blank line */ date_buf[0] = '\0'; } else { /* Handle special conversions */ - if (strncmp(fmt_dt2str, "%f", 2) == 0) { + if (is_prefixed_with(fmt_dt2str, "%f")) { fmt_dt2str = (char*)"%Y.%m.%d-%H:%M:%S"; } /* Generate output string */ - strftime(date_buf, sizeof(date_buf), fmt_dt2str, &tm_time); + strftime(date_buf, COMMON_BUFSIZE, fmt_dt2str, &tm_time); } puts(date_buf); diff --git a/coreutils/dd.c b/coreutils/dd.c index 2838f63..3d1ba2e 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c @@ -2,15 +2,62 @@ /* * Mini dd implementation for busybox * - * * Copyright (C) 2000,2001 Matt Kraai * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config DD +//config: bool "dd" +//config: default y +//config: help +//config: dd copies a file (from standard input to standard output, +//config: by default) using specific input and output blocksizes, +//config: while optionally performing conversions on it. +//config: +//config:config FEATURE_DD_SIGNAL_HANDLING +//config: bool "Enable signal handling for status reporting" +//config: default y +//config: depends on DD +//config: help +//config: Sending a SIGUSR1 signal to a running `dd' process makes it +//config: print to standard error the number of records read and written +//config: so far, then to resume copying. +//config: +//config: $ dd if=/dev/zero of=/dev/null & +//config: $ pid=$!; kill -USR1 $pid; sleep 1; kill $pid +//config: 10899206+0 records in +//config: 10899206+0 records out +//config: +//config:config FEATURE_DD_THIRD_STATUS_LINE +//config: bool "Enable the third status line upon signal" +//config: default y +//config: depends on DD && FEATURE_DD_SIGNAL_HANDLING +//config: help +//config: Displays a coreutils-like third status line with transferred bytes, +//config: elapsed time and speed. +//config: +//config:config FEATURE_DD_IBS_OBS +//config: bool "Enable ibs, obs and conv options" +//config: default y +//config: depends on DD +//config: help +//config: Enables support for writing a certain number of bytes in and out, +//config: at a time, and performing conversions on the data stream. +//config: +//config:config FEATURE_DD_STATUS +//config: bool "Enable status display options" +//config: default y +//config: depends on DD +//config: help +//config: Enables support for status=noxfer/none option. + +//applet:IF_DD(APPLET_NOEXEC(dd, dd, BB_DIR_BIN, BB_SUID_DROP, dd)) + +//kbuild:lib-$(CONFIG_DD) += dd.o //usage:#define dd_trivial_usage //usage: "[if=FILE] [of=FILE] " IF_FEATURE_DD_IBS_OBS("[ibs=N] [obs=N] ") "[bs=N] [count=N] [skip=N]\n" -//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync]") +//usage: " [seek=N]" IF_FEATURE_DD_IBS_OBS(" [conv=notrunc|noerror|sync|fsync] [iflag=skip_bytes]") //usage:#define dd_full_usage "\n\n" //usage: "Copy a file with converting and formatting\n" //usage: "\n if=FILE Read from FILE instead of stdin" @@ -31,9 +78,14 @@ //usage: "\n conv=sync Pad blocks with zeros" //usage: "\n conv=fsync Physically write data out before finishing" //usage: "\n conv=swab Swap every pair of bytes" +//usage: "\n iflag=skip_bytes skip=N is in bytes" +//usage: ) +//usage: IF_FEATURE_DD_STATUS( +//usage: "\n status=noxfer Suppress rate output" +//usage: "\n status=none Suppress all output" //usage: ) //usage: "\n" -//usage: "\nN may be suffixed by c (1), w (2), b (512), kD (1000), k (1024), MD, M, GD, G" +//usage: "\nN may be suffixed by c (1), w (2), b (512), kB (1000), k (1024), MB, M, GB, G" //usage: //usage:#define dd_example_usage //usage: "$ dd if=/dev/zero of=/dev/ram1 bs=1M count=4\n" @@ -41,6 +93,7 @@ //usage: "4+0 records out\n" #include "libbb.h" +#include "common_bufsiz.h" /* This is a NOEXEC applet. Be very careful! */ @@ -50,33 +103,40 @@ enum { ofd = STDOUT_FILENO, }; -static const struct suffix_mult dd_suffixes[] = { - { "c", 1 }, - { "w", 2 }, - { "b", 512 }, - { "kD", 1000 }, - { "k", 1024 }, - { "K", 1024 }, /* compat with coreutils dd */ - { "MD", 1000000 }, - { "M", 1048576 }, - { "GD", 1000000000 }, - { "G", 1073741824 }, - { "", 0 } -}; - struct globals { off_t out_full, out_part, in_full, in_part; #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE unsigned long long total_bytes; unsigned long long begin_time_us; #endif + int flags; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ /* we have to zero it out because of NOEXEC */ \ memset(&G, 0, sizeof(G)); \ } while (0) +enum { + /* Must be in the same order as OP_conv_XXX! */ + /* (see "flags |= (1 << what)" below) */ + FLAG_NOTRUNC = (1 << 0) * ENABLE_FEATURE_DD_IBS_OBS, + FLAG_SYNC = (1 << 1) * ENABLE_FEATURE_DD_IBS_OBS, + FLAG_NOERROR = (1 << 2) * ENABLE_FEATURE_DD_IBS_OBS, + FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS, + FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS, + /* end of conv flags */ + /* start of input flags */ + FLAG_IFLAG_SHIFT = 5, + FLAG_SKIP_BYTES = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, + /* end of input flags */ + FLAG_TWOBUFS = (1 << 6) * ENABLE_FEATURE_DD_IBS_OBS, + FLAG_COUNT = 1 << 7, + FLAG_STATUS = 1 << 8, + FLAG_STATUS_NONE = 1 << 9, + FLAG_STATUS_NOXFER = 1 << 10, +}; static void dd_output_status(int UNUSED_PARAM cur_signal) { @@ -93,6 +153,13 @@ static void dd_output_status(int UNUSED_PARAM cur_signal) G.out_full, G.out_part); #if ENABLE_FEATURE_DD_THIRD_STATUS_LINE +# if ENABLE_FEATURE_DD_STATUS + if (G.flags & FLAG_STATUS_NOXFER) /* status=noxfer active? */ + return; + //TODO: should status=none make dd stop reacting to USR1 entirely? + //So far we react to it (we print the stats), + //status=none only suppresses final, non-USR1 generated status message. +# endif fprintf(stderr, "%llu bytes (%sB) copied, ", G.total_bytes, /* show fractional digit, use suffixes */ @@ -145,30 +212,51 @@ static bool write_and_stats(const void *buf, size_t len, size_t obs, # define XATOU_SFX xatoul_sfx #endif +#if ENABLE_FEATURE_DD_IBS_OBS +static int parse_comma_flags(char *val, const char *words, const char *error_in) +{ + int flags = 0; + while (1) { + int n; + char *arg; + /* find ',', replace them with NUL so we can use val for + * index_in_strings() without copying. + * We rely on val being non-null, else strchr would fault. + */ + arg = strchr(val, ','); + if (arg) + *arg = '\0'; + n = index_in_strings(words, val); + if (n < 0) + bb_error_msg_and_die(bb_msg_invalid_arg_to, val, error_in); + flags |= (1 << n); + if (!arg) /* no ',' left, so this was the last specifier */ + break; + *arg = ','; /* to preserve ps listing */ + val = arg + 1; /* skip this keyword and ',' */ + } + return flags; +} +#endif + int dd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int dd_main(int argc UNUSED_PARAM, char **argv) { - enum { - /* Must be in the same order as OP_conv_XXX! */ - /* (see "flags |= (1 << what)" below) */ - FLAG_NOTRUNC = (1 << 0) * ENABLE_FEATURE_DD_IBS_OBS, - FLAG_SYNC = (1 << 1) * ENABLE_FEATURE_DD_IBS_OBS, - FLAG_NOERROR = (1 << 2) * ENABLE_FEATURE_DD_IBS_OBS, - FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS, - FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS, - /* end of conv flags */ - FLAG_TWOBUFS = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, - FLAG_COUNT = 1 << 6, - }; static const char keywords[] ALIGN1 = - "bs\0""count\0""seek\0""skip\0""if\0""of\0" + "bs\0""count\0""seek\0""skip\0""if\0""of\0"IF_FEATURE_DD_STATUS("status\0") #if ENABLE_FEATURE_DD_IBS_OBS - "ibs\0""obs\0""conv\0" + "ibs\0""obs\0""conv\0""iflag\0" #endif ; #if ENABLE_FEATURE_DD_IBS_OBS static const char conv_words[] ALIGN1 = "notrunc\0""sync\0""noerror\0""fsync\0""swab\0"; + static const char iflag_words[] ALIGN1 = + "skip_bytes\0"; +#endif +#if ENABLE_FEATURE_DD_STATUS + static const char status_words[] ALIGN1 = + "none\0""noxfer\0"; #endif enum { OP_bs = 0, @@ -177,10 +265,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv) OP_skip, OP_if, OP_of, + IF_FEATURE_DD_STATUS(OP_status,) #if ENABLE_FEATURE_DD_IBS_OBS OP_ibs, OP_obs, OP_conv, + OP_iflag, /* Must be in the same order as FLAG_XXX! */ OP_conv_notrunc = 0, OP_conv_sync, @@ -200,6 +290,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) //ibm from ASCII to alternate EBCDIC /* Partially implemented: */ //swab swap every pair of input bytes: will abort on non-even reads + OP_iflag_skip_bytes, #endif }; smallint exitcode = EXIT_FAILURE; @@ -215,14 +306,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv) #endif /* These are all zeroed at once! */ struct { - int flags; size_t oc; ssize_t prev_read_size; /* for detecting swab failure */ off_t count; off_t seek, skip; const char *infile, *outfile; } Z; -#define flags (Z.flags ) #define oc (Z.oc ) #define prev_read_size (Z.prev_read_size) #define count (Z.count ) @@ -258,52 +347,39 @@ int dd_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_DD_IBS_OBS if (what == OP_ibs) { /* Must fit into positive ssize_t */ - ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes); + ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); /*continue;*/ } if (what == OP_obs) { - obs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes); + obs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); /*continue;*/ } if (what == OP_conv) { - while (1) { - int n; - /* find ',', replace them with NUL so we can use val for - * index_in_strings() without copying. - * We rely on val being non-null, else strchr would fault. - */ - arg = strchr(val, ','); - if (arg) - *arg = '\0'; - n = index_in_strings(conv_words, val); - if (n < 0) - bb_error_msg_and_die(bb_msg_invalid_arg, val, "conv"); - flags |= (1 << n); - if (!arg) /* no ',' left, so this was the last specifier */ - break; - /* *arg = ','; - to preserve ps listing? */ - val = arg + 1; /* skip this keyword and ',' */ - } + G.flags |= parse_comma_flags(val, conv_words, "conv"); + /*continue;*/ + } + if (what == OP_iflag) { + G.flags |= parse_comma_flags(val, iflag_words, "iflag") << FLAG_IFLAG_SHIFT; /*continue;*/ } #endif if (what == OP_bs) { - ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, dd_suffixes); + ibs = xatoul_range_sfx(val, 1, ((size_t)-1L)/2, cwbkMG_suffixes); obs = ibs; /*continue;*/ } /* These can be large: */ if (what == OP_count) { - flags |= FLAG_COUNT; - count = XATOU_SFX(val, dd_suffixes); + G.flags |= FLAG_COUNT; + count = XATOU_SFX(val, cwbkMG_suffixes); /*continue;*/ } if (what == OP_seek) { - seek = XATOU_SFX(val, dd_suffixes); + seek = XATOU_SFX(val, cwbkMG_suffixes); /*continue;*/ } if (what == OP_skip) { - skip = XATOU_SFX(val, dd_suffixes); + skip = XATOU_SFX(val, cwbkMG_suffixes); /*continue;*/ } if (what == OP_if) { @@ -314,6 +390,16 @@ int dd_main(int argc UNUSED_PARAM, char **argv) outfile = val; /*continue;*/ } +#if ENABLE_FEATURE_DD_STATUS + if (what == OP_status) { + int n; + n = index_in_strings(status_words, val); + if (n < 0) + bb_error_msg_and_die(bb_msg_invalid_arg_to, val, "status"); + G.flags |= FLAG_STATUS << n; + /*continue;*/ + } +#endif } /* end of "for (argv[i])" */ //XXX:FIXME for huge ibs or obs, malloc'ing them isn't the brightest idea ever @@ -321,7 +407,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) obuf = ibuf; #if ENABLE_FEATURE_DD_IBS_OBS if (ibs != obs) { - flags |= FLAG_TWOBUFS; + G.flags |= FLAG_TWOBUFS; obuf = xmalloc(obs); } #endif @@ -341,12 +427,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv) if (outfile) { int oflag = O_WRONLY | O_CREAT; - if (!seek && !(flags & FLAG_NOTRUNC)) + if (!seek && !(G.flags & FLAG_NOTRUNC)) oflag |= O_TRUNC; xmove_fd(xopen(outfile, oflag), ofd); - if (seek && !(flags & FLAG_NOTRUNC)) { + if (seek && !(G.flags & FLAG_NOTRUNC)) { if (ftruncate(ofd, seek * obs) < 0) { struct stat st; @@ -362,9 +448,10 @@ int dd_main(int argc UNUSED_PARAM, char **argv) outfile = bb_msg_standard_output; } if (skip) { - if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) { + size_t blocksz = (G.flags & FLAG_SKIP_BYTES) ? 1 : ibs; + if (lseek(ifd, skip * blocksz, SEEK_CUR) < 0) { do { - ssize_t n = safe_read(ifd, ibuf, ibs); + ssize_t n = safe_read(ifd, ibuf, blocksz); if (n < 0) goto die_infile; if (n == 0) @@ -377,7 +464,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) goto die_outfile; } - while (!(flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) { + while (!(G.flags & FLAG_COUNT) || (G.in_full + G.in_part != count)) { ssize_t n; n = safe_read(ifd, ibuf, ibs); @@ -385,7 +472,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) break; if (n < 0) { /* "Bad block" */ - if (!(flags & FLAG_NOERROR)) + if (!(G.flags & FLAG_NOERROR)) goto die_infile; bb_simple_perror_msg(infile); /* GNU dd with conv=noerror skips over bad blocks */ @@ -394,7 +481,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) * conv=noerror just ignores input bad blocks */ n = 0; } - if (flags & FLAG_SWAB) { + if (G.flags & FLAG_SWAB) { uint16_t *p16; ssize_t n2; @@ -419,12 +506,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv) G.in_full++; else { G.in_part++; - if (flags & FLAG_SYNC) { + if (G.flags & FLAG_SYNC) { memset(ibuf + n, 0, ibs - n); n = ibs; } } - if (flags & FLAG_TWOBUFS) { + if (G.flags & FLAG_TWOBUFS) { char *tmp = ibuf; while (n) { size_t d = obs - oc; @@ -446,7 +533,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) goto out_status; } - if (flags & FLAG_FSYNC) { + if (G.flags & FLAG_FSYNC) { if (fsync(ofd) < 0) goto die_outfile; } @@ -468,11 +555,12 @@ int dd_main(int argc UNUSED_PARAM, char **argv) exitcode = EXIT_SUCCESS; out_status: - dd_output_status(0); + if (!ENABLE_FEATURE_DD_STATUS || !(G.flags & FLAG_STATUS_NONE)) + dd_output_status(0); if (ENABLE_FEATURE_CLEAN_UP) { free(obuf); - if (flags & FLAG_TWOBUFS) + if (G.flags & FLAG_TWOBUFS) free(ibuf); } diff --git a/coreutils/df.c b/coreutils/df.c index 5e9a867..79e4c46 100644 --- a/coreutils/df.c +++ b/coreutils/df.c @@ -7,10 +7,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 _NOT_ compliant -- option -t missing. */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/df.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Size reduction. Removed floating point dependency. Added error checking @@ -21,10 +17,35 @@ * * Implement -P and -B; better coreutils compat; cleanup */ +//config:config DF +//config: bool "df" +//config: default y +//config: help +//config: df reports the amount of disk space used and available +//config: on filesystems. +//config: +//config:config FEATURE_DF_FANCY +//config: bool "Enable -a, -i, -B" +//config: default y +//config: depends on DF +//config: help +//config: This option enables -a, -i and -B. +//config: +//config: -a Show all filesystems +//config: -i Inodes +//config: -B Blocksize + +//applet:IF_DF(APPLET(df, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_DF) += df.o + +/* BB_AUDIT SUSv3 _NOT_ compliant -- option -t missing. */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/df.html */ //usage:#define df_trivial_usage //usage: "[-Pk" //usage: IF_FEATURE_HUMAN_READABLE("mh") +//usage: "T" //usage: IF_FEATURE_DF_FANCY("ai] [-B SIZE") //usage: "] [FILESYSTEM]..." //usage:#define df_full_usage "\n\n" @@ -35,6 +56,7 @@ //usage: "\n -m 1M-byte blocks" //usage: "\n -h Human readable (e.g. 1K 243M 2G)" //usage: ) +//usage: "\n -T Print filesystem type" //usage: IF_FEATURE_DF_FANCY( //usage: "\n -a Show all filesystems" //usage: "\n -i Inodes" @@ -83,11 +105,12 @@ int df_main(int argc UNUSED_PARAM, char **argv) enum { OPT_KILO = (1 << 0), OPT_POSIX = (1 << 1), - OPT_ALL = (1 << 2) * ENABLE_FEATURE_DF_FANCY, - OPT_INODE = (1 << 3) * ENABLE_FEATURE_DF_FANCY, - OPT_BSIZE = (1 << 4) * ENABLE_FEATURE_DF_FANCY, - OPT_HUMAN = (1 << (2 + 3*ENABLE_FEATURE_DF_FANCY)) * ENABLE_FEATURE_HUMAN_READABLE, - OPT_MEGA = (1 << (3 + 3*ENABLE_FEATURE_DF_FANCY)) * ENABLE_FEATURE_HUMAN_READABLE, + OPT_FSTYPE = (1 << 2), + OPT_ALL = (1 << 3) * ENABLE_FEATURE_DF_FANCY, + OPT_INODE = (1 << 4) * ENABLE_FEATURE_DF_FANCY, + OPT_BSIZE = (1 << 5) * ENABLE_FEATURE_DF_FANCY, + OPT_HUMAN = (1 << (3 + 3*ENABLE_FEATURE_DF_FANCY)) * ENABLE_FEATURE_HUMAN_READABLE, + OPT_MEGA = (1 << (4 + 3*ENABLE_FEATURE_DF_FANCY)) * ENABLE_FEATURE_HUMAN_READABLE, }; const char *disp_units_hdr = NULL; char *chp; @@ -99,15 +122,26 @@ int df_main(int argc UNUSED_PARAM, char **argv) #elif ENABLE_FEATURE_HUMAN_READABLE opt_complementary = "k-m:m-k"; #endif - opt = getopt32(argv, "kP" + opt = getopt32(argv, "kPT" IF_FEATURE_DF_FANCY("aiB:") IF_FEATURE_HUMAN_READABLE("hm") IF_FEATURE_DF_FANCY(, &chp)); if (opt & OPT_MEGA) df_disp_hr = 1024*1024; - if (opt & OPT_BSIZE) - df_disp_hr = xatoul_range(chp, 1, ULONG_MAX); /* disallow 0 */ + if (opt & OPT_BSIZE) { + /* GNU coreutils 8.25 accepts "-BMiB" form too */ + int i; + for (i = 0; kmg_i_suffixes[i].suffix[0]; i++) { + if (strcmp(kmg_i_suffixes[i].suffix, chp) == 0) { + df_disp_hr = kmg_i_suffixes[i].mult; + goto got_it; + } + } + /* Range used to disallow 0 */ + df_disp_hr = xatoul_range_sfx(chp, 1, ULONG_MAX, kmg_i_suffixes); + got_it: ; + } /* From the manpage of df from coreutils-6.10: * Disk space is shown in 1K blocks by default, unless the environment @@ -134,8 +168,11 @@ int df_main(int argc UNUSED_PARAM, char **argv) disp_units_hdr = xasprintf("%lu-blocks", df_disp_hr); #endif } - printf("Filesystem %-15sUsed Available %s Mounted on\n", - disp_units_hdr, (opt & OPT_POSIX) ? "Capacity" : "Use%"); + + printf("Filesystem %s%-15sUsed Available %s Mounted on\n", + (opt & OPT_FSTYPE) ? "Type " : "", + disp_units_hdr, + (opt & OPT_POSIX) ? "Capacity" : "Use%"); mount_table = NULL; argv += optind; @@ -148,6 +185,7 @@ int df_main(int argc UNUSED_PARAM, char **argv) while (1) { const char *device; const char *mount_point; + const char *fs_type; if (mount_table) { mount_entry = getmntent(mount_table); @@ -170,17 +208,23 @@ int df_main(int argc UNUSED_PARAM, char **argv) device = mount_entry->mnt_fsname; mount_point = mount_entry->mnt_dir; + fs_type = mount_entry->mnt_type; if (statfs(mount_point, &s) != 0) { bb_simple_perror_msg(mount_point); goto set_error; } + /* Some uclibc versions were seen to lose f_frsize + * (kernel does return it, but then uclibc does not copy it) + */ + if (s.f_frsize == 0) + s.f_frsize = s.f_bsize; if ((s.f_blocks > 0) || !mount_table || (opt & OPT_ALL)) { if (opt & OPT_INODE) { s.f_blocks = s.f_files; s.f_bavail = s.f_bfree = s.f_ffree; - s.f_bsize = 1; + s.f_frsize = 1; if (df_disp_hr) df_disp_hr = 1; @@ -218,34 +262,46 @@ int df_main(int argc UNUSED_PARAM, char **argv) printf("%s%*s", uni_dev, 20 - (int)uni_stat.unicode_width, ""); } free(uni_dev); + if (opt & OPT_FSTYPE) { + char *uni_type = unicode_conv_to_printable(&uni_stat, fs_type); + if (uni_stat.unicode_width > 10 && !(opt & OPT_POSIX)) + printf(" %s\n%31s", uni_type, ""); + else + printf(" %s%*s", uni_type, 10 - (int)uni_stat.unicode_width, ""); + free(uni_type); + } } #else if (printf("\n%-20s" + 1, device) > 20 && !(opt & OPT_POSIX)) printf("\n%-20s", ""); + if (opt & OPT_FSTYPE) { + if (printf(" %-10s", fs_type) > 11 && !(opt & OPT_POSIX)) + printf("\n%-30s", ""); + } #endif #if ENABLE_FEATURE_HUMAN_READABLE printf(" %9s ", - /* f_blocks x f_bsize / df_disp_hr, show one fractional, + /* f_blocks x f_frsize / df_disp_hr, show one fractional, * use suffixes if df_disp_hr == 0 */ - make_human_readable_str(s.f_blocks, s.f_bsize, df_disp_hr)); + make_human_readable_str(s.f_blocks, s.f_frsize, df_disp_hr)); printf(" %9s " + 1, - /* EXPR x f_bsize / df_disp_hr, show one fractional, + /* EXPR x f_frsize / df_disp_hr, show one fractional, * use suffixes if df_disp_hr == 0 */ make_human_readable_str((s.f_blocks - s.f_bfree), - s.f_bsize, df_disp_hr)); + s.f_frsize, df_disp_hr)); printf("%9s %3u%% %s\n", - /* f_bavail x f_bsize / df_disp_hr, show one fractional, + /* f_bavail x f_frsize / df_disp_hr, show one fractional, * use suffixes if df_disp_hr == 0 */ - make_human_readable_str(s.f_bavail, s.f_bsize, df_disp_hr), + make_human_readable_str(s.f_bavail, s.f_frsize, df_disp_hr), blocks_percent_used, mount_point); #else printf(" %9lu %9lu %9lu %3u%% %s\n", - kscale(s.f_blocks, s.f_bsize), - kscale(s.f_blocks - s.f_bfree, s.f_bsize), - kscale(s.f_bavail, s.f_bsize), + kscale(s.f_blocks, s.f_frsize), + kscale(s.f_blocks - s.f_bfree, s.f_frsize), + kscale(s.f_bavail, s.f_frsize), blocks_percent_used, mount_point); #endif } diff --git a/coreutils/dirname.c b/coreutils/dirname.c index 101067c..6593818 100644 --- a/coreutils/dirname.c +++ b/coreutils/dirname.c @@ -6,6 +6,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config DIRNAME +//config: bool "dirname" +//config: default y +//config: help +//config: dirname is used to strip a non-directory suffix from +//config: a file name. + +//applet:IF_DIRNAME(APPLET_NOFORK(dirname, dirname, BB_DIR_USR_BIN, BB_SUID_DROP, dirname)) + +//kbuild:lib-$(CONFIG_DIRNAME) += dirname.o /* BB_AUDIT SUSv3 compliant */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/dirname.html */ diff --git a/coreutils/dos2unix.c b/coreutils/dos2unix.c index c9ae76e..6d23471 100644 --- a/coreutils/dos2unix.c +++ b/coreutils/dos2unix.c @@ -10,7 +10,26 @@ * dos2unix filters reading input from stdin and writing output to stdout. * * Licensed under GPLv2 or later, see file LICENSE in this source tree. -*/ + */ +//config:config DOS2UNIX +//config: bool "dos2unix" +//config: default y +//config: help +//config: dos2unix is used to convert a text file from DOS format to +//config: UNIX format, and vice versa. +//config: +//config:config UNIX2DOS +//config: bool "unix2dos" +//config: default y +//config: help +//config: unix2dos is used to convert a text file from UNIX format to +//config: DOS format, and vice versa. + +//applet:IF_DOS2UNIX(APPLET_NOEXEC(dos2unix, dos2unix, BB_DIR_USR_BIN, BB_SUID_DROP, dos2unix)) +//applet:IF_UNIX2DOS(APPLET_NOEXEC(unix2dos, dos2unix, BB_DIR_USR_BIN, BB_SUID_DROP, unix2dos)) + +//kbuild:lib-$(CONFIG_DOS2UNIX) += dos2unix.o +//kbuild:lib-$(CONFIG_UNIX2DOS) += dos2unix.o //usage:#define dos2unix_trivial_usage //usage: "[-ud] [FILE]" @@ -41,36 +60,38 @@ enum { static void convert(char *fn, int conv_type) { FILE *in, *out; - int i; - char *temp_fn = NULL; - char *resolved_fn = NULL; + int ch; + char *temp_fn = temp_fn; /* for compiler */ + char *resolved_fn = resolved_fn; in = stdin; out = stdout; if (fn != NULL) { struct stat st; + int fd; resolved_fn = xmalloc_follow_symlinks(fn); if (resolved_fn == NULL) bb_simple_perror_msg_and_die(fn); in = xfopen_for_read(resolved_fn); - fstat(fileno(in), &st); + xfstat(fileno(in), &st, resolved_fn); temp_fn = xasprintf("%sXXXXXX", resolved_fn); - i = xmkstemp(temp_fn); - if (fchmod(i, st.st_mode) == -1) + fd = xmkstemp(temp_fn); + if (fchmod(fd, st.st_mode) == -1) bb_simple_perror_msg_and_die(temp_fn); + fchown(fd, st.st_uid, st.st_gid); - out = xfdopen_for_write(i); + out = xfdopen_for_write(fd); } - while ((i = fgetc(in)) != EOF) { - if (i == '\r') + while ((ch = fgetc(in)) != EOF) { + if (ch == '\r') continue; - if (i == '\n') + if (ch == '\n') if (conv_type == CT_UNIX2DOS) fputc('\r', out); - fputc(i, out); + fputc(ch, out); } if (fn != NULL) { @@ -90,9 +111,12 @@ int dos2unix_main(int argc UNUSED_PARAM, char **argv) int o, conv_type; /* See if we are supposed to be doing dos2unix or unix2dos */ - conv_type = CT_UNIX2DOS; - if (applet_name[0] == 'd') { + if (ENABLE_DOS2UNIX + && (!ENABLE_UNIX2DOS || applet_name[0] == 'd') + ) { conv_type = CT_DOS2UNIX; + } else { + conv_type = CT_UNIX2DOS; } /* -u convert to unix, -d convert to dos */ diff --git a/coreutils/du.c b/coreutils/du.c index 9c6ff88..03e31a0 100644 --- a/coreutils/du.c +++ b/coreutils/du.c @@ -8,10 +8,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 compliant (unless default blocksize set to 1k) */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/du.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Mostly rewritten for SUSv3 compliance and to fix bugs/defects. @@ -22,6 +18,26 @@ * 3) Added error checking of output. * 4) Fixed busybox bug #1284 involving long overflow with human_readable. */ +//config:config DU +//config: bool "du (default blocksize of 512 bytes)" +//config: default y +//config: help +//config: du is used to report the amount of disk space used +//config: for specified files. +//config: +//config:config FEATURE_DU_DEFAULT_BLOCKSIZE_1K +//config: bool "Use a default blocksize of 1024 bytes (1K)" +//config: default y +//config: depends on DU +//config: help +//config: Use a blocksize of (1K) instead of the default 512b. + +//applet:IF_DU(APPLET(du, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_DU) += du.o + +/* BB_AUDIT SUSv3 compliant (unless default blocksize set to 1k) */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/du.html */ //usage:#define du_trivial_usage //usage: "[-aHLdclsx" IF_FEATURE_HUMAN_READABLE("hm") "k] [FILE]..." @@ -58,6 +74,7 @@ //usage: "2417 .\n" #include "libbb.h" +#include "common_bufsiz.h" enum { OPT_a_files_too = (1 << 0), @@ -75,7 +92,7 @@ enum { struct globals { #if ENABLE_FEATURE_HUMAN_READABLE - unsigned long disp_hr; + unsigned long disp_unit; #else unsigned disp_k; #endif @@ -85,22 +102,31 @@ struct globals { int du_depth; dev_t dir_dev; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define G (*(struct globals*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) -/* FIXME? coreutils' du rounds sizes up: - * for example, 1025k file is shown as "2" by du -m. - * We round to nearest. - */ static void print(unsigned long long size, const char *filename) { /* TODO - May not want to defer error checking here. */ #if ENABLE_FEATURE_HUMAN_READABLE +# if ENABLE_DESKTOP + /* ~30 bytes of code for extra comtat: + * coreutils' du rounds sizes up: + * for example, 1025k file is shown as "2" by du -m. + * We round to nearest if human-readable [too hard to fix], + * else (fixed scale such as -m), we round up. To that end, + * add yet another half of the unit before displaying: + */ + if (G.disp_unit) + size += (G.disp_unit-1) / (unsigned)(512 * 2); +# endif printf("%s\t%s\n", - /* size x 512 / G.disp_hr, show one fractional, - * use suffixes if G.disp_hr == 0 */ - make_human_readable_str(size, 512, G.disp_hr), + /* size x 512 / G.disp_unit. + * If G.disp_unit == 0, show one fractional + * and use suffixes + */ + make_human_readable_str(size, 512, G.disp_unit), filename); #else if (G.disp_k) { @@ -199,10 +225,10 @@ int du_main(int argc UNUSED_PARAM, char **argv) INIT_G(); #if ENABLE_FEATURE_HUMAN_READABLE - IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 1024;) - IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_hr = 512;) + IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_unit = 1024;) + IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_unit = 512;) if (getenv("POSIXLY_CORRECT")) /* TODO - a new libbb function? */ - G.disp_hr = 512; + G.disp_unit = 512; #else IF_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 1;) /* IF_NOT_FEATURE_DU_DEFAULT_BLOCKSIZE_1K(G.disp_k = 0;) - G is pre-zeroed */ @@ -216,21 +242,21 @@ int du_main(int argc UNUSED_PARAM, char **argv) * ignore -a. This is consistent with -s being equivalent to -d 0. */ #if ENABLE_FEATURE_HUMAN_READABLE - opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s:d+"; - opt = getopt32(argv, "aHkLsx" "d:" "lc" "hm", &G.max_print_depth); + opt_complementary = "h-km:k-hm:m-hk:H-L:L-H:s-d:d-s"; + opt = getopt32(argv, "aHkLsx" "d:+" "lc" "hm", &G.max_print_depth); argv += optind; if (opt & OPT_h_for_humans) { - G.disp_hr = 0; + G.disp_unit = 0; } if (opt & OPT_m_mbytes) { - G.disp_hr = 1024*1024; + G.disp_unit = 1024*1024; } if (opt & OPT_k_kbytes) { - G.disp_hr = 1024; + G.disp_unit = 1024; } #else - opt_complementary = "H-L:L-H:s-d:d-s:d+"; - opt = getopt32(argv, "aHkLsx" "d:" "lc", &G.max_print_depth); + opt_complementary = "H-L:L-H:s-d:d-s"; + opt = getopt32(argv, "aHkLsx" "d:+" "lc", &G.max_print_depth); argv += optind; #if !ENABLE_FEATURE_DU_DEFAULT_BLOCKSIZE_1K if (opt & OPT_k_kbytes) { diff --git a/coreutils/echo.c b/coreutils/echo.c index 9663894..fd0d9b7 100644 --- a/coreutils/echo.c +++ b/coreutils/echo.c @@ -9,10 +9,6 @@ * * Original copyright notice is retained at the end of this file. */ - -/* BB_AUDIT SUSv3 compliant -- unless configured as fancy echo. */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/echo.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Because of behavioral differences, implemented configurable SUSv3 @@ -22,6 +18,26 @@ * 2) SUSv3 specifies that octal escapes are of the form \0{#{#{#}}}. * The previous version did not allow 4-digit octals. */ +//config:config ECHO +//config: bool "echo (basic SuSv3 version taking no options)" +//config: default y +//config: help +//config: echo is used to print a specified string to stdout. +//config: +//config:# this entry also appears in shell/Config.in, next to the echo builtin +//config:config FEATURE_FANCY_ECHO +//config: bool "Enable echo options (-n and -e)" +//config: default y +//config: depends on ECHO || ASH_BUILTIN_ECHO || HUSH +//config: help +//config: This adds options (-n and -e) to echo. + +//applet:IF_ECHO(APPLET_NOFORK(echo, echo, BB_DIR_BIN, BB_SUID_DROP, echo)) + +//kbuild:lib-$(CONFIG_ECHO) += echo.o + +/* BB_AUDIT SUSv3 compliant -- unless configured as fancy echo. */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/echo.html */ //usage:#define echo_trivial_usage //usage: IF_FEATURE_FANCY_ECHO("[-neE] ") "[ARG]..." @@ -72,7 +88,7 @@ int echo_main(int argc UNUSED_PARAM, char **argv) unsigned buflen; #if !ENABLE_FEATURE_FANCY_ECHO enum { - eflag = '\\', + eflag = 0, /* 0 -- disable escape sequences */ nflag = 1, /* 1 -- print '\n' */ }; diff --git a/coreutils/env.c b/coreutils/env.c index 807ef13..e91eddb 100644 --- a/coreutils/env.c +++ b/coreutils/env.c @@ -11,16 +11,11 @@ * * Modified for BusyBox by Erik Andersen */ - -/* BB_AUDIT SUSv3 compliant */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/env.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Fixed bug involving exit return codes if execvp fails. Also added * output error checking. */ - /* * Modified by Vladimir Oleynik (C) 2003 * - correct "-" option usage @@ -28,8 +23,27 @@ * - GNU long option support * - use xfunc_error_retval */ +//config:config ENV +//config: bool "env" +//config: default y +//config: help +//config: env is used to set an environment variable and run +//config: a command; without options it displays the current +//config: environment. +//config: +//config:config FEATURE_ENV_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on ENV && LONG_OPTS +//config: help +//config: Support long options for the env applet. -/* This is a NOEXEC applet. Be very careful! */ +//applet:IF_ENV(APPLET_NOEXEC(env, env, BB_DIR_USR_BIN, BB_SUID_DROP, env)) + +//kbuild:lib-$(CONFIG_ENV) += env.o + +/* BB_AUDIT SUSv3 compliant */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/env.html */ //usage:#define env_trivial_usage //usage: "[-iu] [-] [name=value]... [PROG ARGS]" @@ -54,11 +68,10 @@ int env_main(int argc UNUSED_PARAM, char **argv) unsigned opts; llist_t *unset_env = NULL; - opt_complementary = "u::"; #if ENABLE_FEATURE_ENV_LONG_OPTIONS applet_long_options = env_longopts; #endif - opts = getopt32(argv, "+iu:", &unset_env); + opts = getopt32(argv, "+iu:+", &unset_env); argv += optind; if (argv[0] && LONE_DASH(argv[0])) { opts |= 1; diff --git a/coreutils/expand.c b/coreutils/expand.c index 9a83fad..466c11a 100644 --- a/coreutils/expand.c +++ b/coreutils/expand.c @@ -20,6 +20,37 @@ * * Caveat: this versions of expand and unexpand don't accept tab lists. */ +//config:config EXPAND +//config: bool "expand" +//config: default y +//config: help +//config: By default, convert all tabs to spaces. +//config: +//config:config FEATURE_EXPAND_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on EXPAND && LONG_OPTS +//config: help +//config: Support long options for the expand applet. +//config: +//config:config UNEXPAND +//config: bool "unexpand" +//config: default y +//config: help +//config: By default, convert only leading sequences of blanks to tabs. +//config: +//config:config FEATURE_UNEXPAND_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on UNEXPAND && LONG_OPTS +//config: help +//config: Support long options for the unexpand applet. + +//applet:IF_EXPAND(APPLET(expand, BB_DIR_USR_BIN, BB_SUID_DROP)) +//applet:IF_UNEXPAND(APPLET_ODDNAME(unexpand, expand, BB_DIR_USR_BIN, BB_SUID_DROP, unexpand)) + +//kbuild:lib-$(CONFIG_EXPAND) += expand.o +//kbuild:lib-$(CONFIG_UNEXPAND) += expand.o //usage:#define expand_trivial_usage //usage: "[-i] [-t N] [FILE]..." diff --git a/coreutils/expr.c b/coreutils/expr.c index 128775b..55a19aa 100644 --- a/coreutils/expr.c +++ b/coreutils/expr.c @@ -13,7 +13,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - /* This program evaluates expressions. Each token (operator, operand, * parenthesis) of the expression must be a separate argument. The * parser used is a reasonably general one, though any incarnation of @@ -21,9 +20,27 @@ * * No parse tree is needed; a new node is evaluated immediately. * One function can handle multiple operators all of equal precedence, - * provided they all associate ((x op x) op x). */ - -/* no getopt needed */ + * provided they all associate ((x op x) op x). + */ +//config:config EXPR +//config: bool "expr" +//config: default y +//config: help +//config: expr is used to calculate numbers and print the result +//config: to standard output. +//config: +//config:config EXPR_MATH_SUPPORT_64 +//config: bool "Extend Posix numbers support to 64 bit" +//config: default y +//config: depends on EXPR +//config: help +//config: Enable 64-bit math support in the expr applet. This will make +//config: the applet slightly larger, but will allow computation with very +//config: large numbers. + +//applet:IF_EXPR(APPLET(expr, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_EXPR) += expr.o //usage:#define expr_trivial_usage //usage: "EXPRESSION" @@ -61,6 +78,7 @@ //usage: "of characters matched or 0." #include "libbb.h" +#include "common_bufsiz.h" #include "xregex.h" #if ENABLE_EXPR_MATH_SUPPORT_64 @@ -99,8 +117,8 @@ typedef struct valinfo VALUE; struct globals { char **args; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define G (*(struct globals*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) /* forward declarations */ static VALUE *eval(void); @@ -113,7 +131,7 @@ static VALUE *int_value(arith_t i) VALUE *v; v = xzalloc(sizeof(VALUE)); - if (INTEGER) /* otherwise xzaaloc did it already */ + if (INTEGER) /* otherwise xzalloc did it already */ v->type = INTEGER; v->u.i = i; return v; @@ -126,7 +144,7 @@ static VALUE *str_value(const char *s) VALUE *v; v = xzalloc(sizeof(VALUE)); - if (STRING) /* otherwise xzaaloc did it already */ + if (STRING) /* otherwise xzalloc did it already */ v->type = STRING; v->u.s = xstrdup(s); return v; diff --git a/coreutils/false.c b/coreutils/false.c index 59c2f32..b8f17c6 100644 --- a/coreutils/false.c +++ b/coreutils/false.c @@ -6,15 +6,22 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config FALSE +//config: bool "false" +//config: default y +//config: help +//config: false returns an exit code of FALSE (1). + +//applet:IF_FALSE(APPLET_NOFORK(false, false, BB_DIR_BIN, BB_SUID_DROP, false)) + +//kbuild:lib-$(CONFIG_FALSE) += false.o /* BB_AUDIT SUSv3 compliant */ /* http://www.opengroup.org/onlinepubs/000095399/utilities/false.html */ -//usage:#define false_trivial_usage -//usage: "" -//usage:#define false_full_usage "\n\n" -//usage: "Return an exit code of FALSE (1)" -//usage: +/* "false --help" is special-cased to ignore --help */ +//usage:#define false_trivial_usage NOUSAGE_STR +//usage:#define false_full_usage "" //usage:#define false_example_usage //usage: "$ false\n" //usage: "$ echo $?\n" diff --git a/coreutils/fold.c b/coreutils/fold.c index 0e73063..01f9bce 100644 --- a/coreutils/fold.c +++ b/coreutils/fold.c @@ -9,6 +9,15 @@ Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config FOLD +//config: bool "fold" +//config: default y +//config: help +//config: Wrap text to fit a specific width. + +//applet:IF_FOLD(APPLET_NOEXEC(fold, fold, BB_DIR_USR_BIN, BB_SUID_DROP, fold)) + +//kbuild:lib-$(CONFIG_FOLD) += fold.o //usage:#define fold_trivial_usage //usage: "[-bs] [-w WIDTH] [FILE]..." diff --git a/coreutils/fsync.c b/coreutils/fsync.c index 652a41c..596a2bc 100644 --- a/coreutils/fsync.c +++ b/coreutils/fsync.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config FSYNC +//config: bool "fsync" +//config: default y +//config: help +//config: fsync is used to flush file-related cached blocks to disk. + +//applet:IF_FSYNC(APPLET_NOFORK(fsync, fsync, BB_DIR_BIN, BB_SUID_DROP, fsync)) + +//kbuild:lib-$(CONFIG_FSYNC) += fsync.o //usage:#define fsync_trivial_usage //usage: "[-d] FILE..." diff --git a/coreutils/head.c b/coreutils/head.c index 9388b02..176e91e 100644 --- a/coreutils/head.c +++ b/coreutils/head.c @@ -6,13 +6,28 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config HEAD +//config: bool "head" +//config: default y +//config: help +//config: head is used to print the first specified number of lines +//config: from files. +//config: +//config:config FEATURE_FANCY_HEAD +//config: bool "Enable head options (-c, -q, and -v)" +//config: default y +//config: depends on HEAD +//config: help +//config: This enables the head options (-c, -q, and -v). + +//applet:IF_HEAD(APPLET_NOEXEC(head, head, BB_DIR_USR_BIN, BB_SUID_DROP, head)) + +//kbuild:lib-$(CONFIG_HEAD) += head.o /* BB_AUDIT SUSv3 compliant */ /* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/head.html */ -//kbuild:lib-$(CONFIG_HEAD) += head.o - //usage:#define head_trivial_usage //usage: "[OPTIONS] [FILE]..." //usage:#define head_full_usage "\n\n" diff --git a/coreutils/hostid.c b/coreutils/hostid.c index e5b1f51..5b47de1 100644 --- a/coreutils/hostid.c +++ b/coreutils/hostid.c @@ -6,9 +6,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ - //config:config HOSTID //config: bool "hostid" //config: default y @@ -20,6 +17,8 @@ //kbuild:lib-$(CONFIG_HOSTID) += hostid.o +/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ + //usage:#define hostid_trivial_usage //usage: "" //usage:#define hostid_full_usage "\n\n" diff --git a/coreutils/id.c b/coreutils/id.c index 1f3e1c4..ab7ac1e 100644 --- a/coreutils/id.c +++ b/coreutils/id.c @@ -7,31 +7,30 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 compliant. */ /* Hacked by Tito Ragusa (C) 2004 to handle usernames of whatever * length and to be more similar to GNU id. * -Z option support: by Yuichi Nakamura * Added -G option Tito Ragusa (C) 2008 for SUSv3. */ - //config:config ID //config: bool "id" //config: default y //config: help //config: id displays the current user and group ID names. - +//config: //config:config GROUPS //config: bool "groups" //config: default y //config: help //config: Print the group names associated with current user id. +//applet:IF_GROUPS(APPLET_NOEXEC(groups, id, BB_DIR_USR_BIN, BB_SUID_DROP, groups)) +//applet:IF_ID( APPLET_NOEXEC(id, id, BB_DIR_USR_BIN, BB_SUID_DROP, id )) + //kbuild:lib-$(CONFIG_GROUPS) += id.o //kbuild:lib-$(CONFIG_ID) += id.o -//applet:IF_GROUPS(APPLET_NOEXEC(groups, id, BB_DIR_USR_BIN, BB_SUID_DROP, groups)) -//applet:IF_ID( APPLET_NOEXEC(id, id, BB_DIR_USR_BIN, BB_SUID_DROP, id )) +/* BB_AUDIT SUSv3 compliant. */ //usage:#define id_trivial_usage //usage: "[OPTIONS] [USER]" diff --git a/coreutils/install.c b/coreutils/install.c index 445497f..831f9b8 100644 --- a/coreutils/install.c +++ b/coreutils/install.c @@ -5,10 +5,26 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config INSTALL +//config: bool "install" +//config: default y +//config: help +//config: Copy files and set attributes. +//config: +//config:config FEATURE_INSTALL_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on INSTALL && LONG_OPTS +//config: help +//config: Support long options for the install applet. + +//applet:IF_INSTALL(APPLET(install, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_INSTALL) += install.o /* -v, -b, -c are ignored */ //usage:#define install_trivial_usage -//usage: "[-cdDsp] [-o USER] [-g GRP] [-m MODE] [SOURCE]... DEST" +//usage: "[-cdDsp] [-o USER] [-g GRP] [-m MODE] [-t DIR] [SOURCE]... DEST" //usage:#define install_full_usage "\n\n" //usage: "Copy files and set attributes\n" //usage: "\n -c Just copy (default)" @@ -19,6 +35,7 @@ //usage: "\n -o USER Set ownership" //usage: "\n -g GRP Set group ownership" //usage: "\n -m MODE Set permissions" +//usage: "\n -t DIR Install to DIR" //usage: IF_SELINUX( //usage: "\n -Z Set security context" //usage: ) @@ -28,12 +45,16 @@ #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS static const char install_longopts[] ALIGN1 = + IF_FEATURE_VERBOSE( + "verbose\0" No_argument "v" + ) "directory\0" No_argument "d" "preserve-timestamps\0" No_argument "p" "strip\0" No_argument "s" "group\0" Required_argument "g" "mode\0" Required_argument "m" "owner\0" Required_argument "o" + "target-directory\0" Required_argument "t" /* autofs build insists of using -b --suffix=.orig */ /* TODO? (short option for --suffix is -S) */ #if ENABLE_SELINUX @@ -89,11 +110,11 @@ int install_main(int argc, char **argv) const char *gid_str; const char *uid_str; const char *mode_str; + int mkdir_flags = FILEUTILS_RECUR; int copy_flags = FILEUTILS_DEREFERENCE | FILEUTILS_FORCE; int opts; - int min_args = 1; int ret = EXIT_SUCCESS; - int isdir = 0; + int isdir; #if ENABLE_SELINUX security_context_t scontext; bool use_default_selinux_context = 1; @@ -109,21 +130,22 @@ int install_main(int argc, char **argv) OPT_GROUP = 1 << 7, OPT_MODE = 1 << 8, OPT_OWNER = 1 << 9, + OPT_TARGET = 1 << 10, #if ENABLE_SELINUX - OPT_SET_SECURITY_CONTEXT = 1 << 10, - OPT_PRESERVE_SECURITY_CONTEXT = 1 << 11, + OPT_SET_SECURITY_CONTEXT = 1 << 11, + OPT_PRESERVE_SECURITY_CONTEXT = 1 << 12, #endif }; #if ENABLE_FEATURE_INSTALL_LONG_OPTIONS applet_long_options = install_longopts; #endif - opt_complementary = "s--d:d--s" IF_FEATURE_INSTALL_LONG_OPTIONS(IF_SELINUX(":Z--\xff:\xff--Z")); + opt_complementary = "t--d:d--t:s--d:d--s" IF_FEATURE_INSTALL_LONG_OPTIONS(IF_SELINUX(":Z--\xff:\xff--Z")); /* -c exists for backwards compatibility, it's needed */ - /* -v is ignored ("print name of each created directory") */ /* -b is ignored ("make a backup of each existing destination file") */ - opts = getopt32(argv, "cvb" "Ddpsg:m:o:" IF_SELINUX("Z:"), - &gid_str, &mode_str, &uid_str IF_SELINUX(, &scontext)); + opts = getopt32(argv, "cvb" "Ddpsg:m:o:t:" IF_SELINUX("Z:"), + &gid_str, &mode_str, &uid_str, &last + IF_SELINUX(, &scontext)); argc -= optind; argv += optind; @@ -141,6 +163,11 @@ int install_main(int argc, char **argv) } #endif + if ((opts & OPT_v) && FILEUTILS_VERBOSE) { + mkdir_flags |= FILEUTILS_VERBOSE; + copy_flags |= FILEUTILS_VERBOSE; + } + /* preserve access and modification time, this is GNU behaviour, * BSD only preserves modification time */ if (opts & OPT_PRESERVE_TIME) { @@ -148,39 +175,44 @@ int install_main(int argc, char **argv) } mode = 0755; /* GNU coreutils 6.10 compat */ if (opts & OPT_MODE) - bb_parse_mode(mode_str, &mode); + mode = bb_parse_mode(mode_str, mode); uid = (opts & OPT_OWNER) ? get_ug_id(uid_str, xuname2uid) : getuid(); gid = (opts & OPT_GROUP) ? get_ug_id(gid_str, xgroup2gid) : getgid(); - last = argv[argc - 1]; - if (!(opts & OPT_DIRECTORY)) { - argv[argc - 1] = NULL; - min_args++; - + /* If -t DIR is in use, then isdir=true, last="DIR" */ + isdir = (opts & OPT_TARGET); + if (!(opts & (OPT_TARGET|OPT_DIRECTORY))) { + /* Neither -t DIR nor -d is in use */ + argc--; + last = argv[argc]; + argv[argc] = NULL; /* coreutils install resolves link in this case, don't use lstat */ isdir = stat(last, &statbuf) < 0 ? 0 : S_ISDIR(statbuf.st_mode); } - if (argc < min_args) + if (argc < 1) bb_show_usage(); while ((arg = *argv++) != NULL) { - char *dest = last; + char *dest; + if (opts & OPT_DIRECTORY) { dest = arg; /* GNU coreutils 6.9 does not set uid:gid * on intermediate created directories * (only on last one) */ - if (bb_make_directory(dest, 0755, FILEUTILS_RECUR)) { + if (bb_make_directory(dest, 0755, mkdir_flags)) { ret = EXIT_FAILURE; goto next; } } else { + dest = last; if (opts & OPT_MKDIR_LEADING) { char *ddir = xstrdup(dest); - bb_make_directory(dirname(ddir), 0755, FILEUTILS_RECUR); + bb_make_directory(dirname(ddir), 0755, mkdir_flags); /* errors are not checked. copy_file - * will fail if dir is not created. */ + * will fail if dir is not created. + */ free(ddir); } if (isdir) diff --git a/coreutils/length.c.disabled b/coreutils/length.c.disabled deleted file mode 100644 index aee898d..0000000 --- a/coreutils/length.c.disabled +++ b/dev/null @@ -1,31 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * Licensed under GPLv2, see file LICENSE in this source tree. - */ - -/* BB_AUDIT SUSv3 N/A -- Apparently a busybox (obsolete?) extension. */ - -//usage:#define length_trivial_usage -//usage: "STRING" -//usage:#define length_full_usage "\n\n" -//usage: "Print STRING's length" -//usage: -//usage:#define length_example_usage -//usage: "$ length Hello\n" -//usage: "5\n" - -#include "libbb.h" - -/* This is a NOFORK applet. Be very careful! */ - -int length_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int length_main(int argc, char **argv) -{ - if ((argc != 2) || (**(++argv) == '-')) { - bb_show_usage(); - } - - printf("%u\n", (unsigned)strlen(*argv)); - - return fflush_all(); -} diff --git a/coreutils/libcoreutils/getopt_mk_fifo_nod.c b/coreutils/libcoreutils/getopt_mk_fifo_nod.c index 2227171..47375ff 100644 --- a/coreutils/libcoreutils/getopt_mk_fifo_nod.c +++ b/coreutils/libcoreutils/getopt_mk_fifo_nod.c @@ -33,7 +33,9 @@ mode_t FAST_FUNC getopt_mk_fifo_nod(char **argv) int opt; opt = getopt32(argv, "m:" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); if (opt & 1) { - if (bb_parse_mode(smode, &mode)) + mode = bb_parse_mode(smode, mode); + if (mode != (mode_t)-1) /* if mode is valid */ + /* make future mknod/mkfifo set mode bits exactly */ umask(0); } diff --git a/coreutils/ln.c b/coreutils/ln.c index 3b822e8..0e2abac 100644 --- a/coreutils/ln.c +++ b/coreutils/ln.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config LN +//config: bool "ln" +//config: default y +//config: help +//config: ln is used to create hard or soft links between files. + +//applet:IF_LN(APPLET_NOEXEC(ln, ln, BB_DIR_BIN, BB_SUID_DROP, ln)) + +//kbuild:lib-$(CONFIG_LN) += ln.o /* BB_AUDIT SUSv3 compliant */ /* BB_AUDIT GNU options missing: -d, -F, -i, and -v. */ @@ -134,7 +143,6 @@ int ln_main(int argc, char **argv) } free(src_name); - } while ((++argv)[1]); return status; diff --git a/coreutils/logname.c b/coreutils/logname.c index 10b9615..a9b1c95 100644 --- a/coreutils/logname.c +++ b/coreutils/logname.c @@ -6,10 +6,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 compliant */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/logname.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * SUSv3 specifies the string used is that returned from getlogin(). @@ -19,6 +15,18 @@ * correct course of action wrt SUSv3 for a failing getlogin() is * a diagnostic message and an error return. */ +//config:config LOGNAME +//config: bool "logname" +//config: default y +//config: help +//config: logname is used to print the current user's login name. + +//applet:IF_LOGNAME(APPLET_NOFORK(logname, logname, BB_DIR_USR_BIN, BB_SUID_DROP, logname)) + +//kbuild:lib-$(CONFIG_LOGNAME) += logname.o + +/* BB_AUDIT SUSv3 compliant */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/logname.html */ //usage:#define logname_trivial_usage //usage: "" diff --git a/coreutils/ls.c b/coreutils/ls.c index 91552d7..e7490ac 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -4,7 +4,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - /* [date unknown. Perhaps before year 2000] * To achieve a small memory footprint, this version of 'ls' doesn't do any * file sorting, and only has the most essential command line switches @@ -28,6 +27,75 @@ * [2009-03] * ls sorts listing now, and supports almost all options. */ +//config:config LS +//config: bool "ls" +//config: default y +//config: help +//config: ls is used to list the contents of directories. +//config: +//config:config FEATURE_LS_FILETYPES +//config: bool "Enable filetyping options (-p and -F)" +//config: default y +//config: depends on LS +//config: help +//config: Enable the ls options (-p and -F). +//config: +//config:config FEATURE_LS_FOLLOWLINKS +//config: bool "Enable symlinks dereferencing (-L)" +//config: default y +//config: depends on LS +//config: help +//config: Enable the ls option (-L). +//config: +//config:config FEATURE_LS_RECURSIVE +//config: bool "Enable recursion (-R)" +//config: default y +//config: depends on LS +//config: help +//config: Enable the ls option (-R). +//config: +//config:config FEATURE_LS_SORTFILES +//config: bool "Sort the file names" +//config: default y +//config: depends on LS +//config: help +//config: Allow ls to sort file names alphabetically. +//config: +//config:config FEATURE_LS_TIMESTAMPS +//config: bool "Show file timestamps" +//config: default y +//config: depends on LS +//config: help +//config: Allow ls to display timestamps for files. +//config: +//config:config FEATURE_LS_USERNAME +//config: bool "Show username/groupnames" +//config: default y +//config: depends on LS +//config: help +//config: Allow ls to display username/groupname for files. +//config: +//config:config FEATURE_LS_COLOR +//config: bool "Allow use of color to identify file types" +//config: default y +//config: depends on LS && LONG_OPTS +//config: help +//config: This enables the --color option to ls. +//config: +//config:config FEATURE_LS_COLOR_IS_DEFAULT +//config: bool "Produce colored ls output by default" +//config: default y +//config: depends on FEATURE_LS_COLOR +//config: help +//config: Saying yes here will turn coloring on by default, +//config: even if no "--color" option is given to the ls command. +//config: This is not recommended, since the colors are not +//config: configurable, and the output may not be legible on +//config: many output screens. + +//applet:IF_LS(APPLET_NOEXEC(ls, ls, BB_DIR_BIN, BB_SUID_DROP, ls)) + +//kbuild:lib-$(CONFIG_LS) += ls.o //usage:#define ls_trivial_usage //usage: "[-1AaCxd" @@ -93,6 +161,7 @@ //usage: ) #include "libbb.h" +#include "common_bufsiz.h" #include "unicode.h" @@ -365,8 +434,9 @@ struct globals { time_t current_time_t; #endif } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ + setup_common_bufsiz(); \ /* we have to zero it out because of NOEXEC */ \ memset(&G, 0, sizeof(G)); \ IF_FEATURE_AUTOWIDTH(G_terminal_width = TERMINAL_WIDTH;) \ @@ -581,12 +651,12 @@ static NOINLINE unsigned display_single(const struct dnode *dn) #if ENABLE_FEATURE_LS_TIMESTAMPS if (G.all_fmt & (LIST_FULLTIME|LIST_DATE_TIME)) { char *filetime; - time_t ttime = dn->dn_mtime; + const time_t *ttime = &dn->dn_mtime; if (G.all_fmt & TIME_ACCESS) - ttime = dn->dn_atime; + ttime = &dn->dn_atime; if (G.all_fmt & TIME_CHANGE) - ttime = dn->dn_ctime; - filetime = ctime(&ttime); + ttime = &dn->dn_ctime; + filetime = ctime(ttime); /* filetime's format: "Wed Jun 30 21:49:08 1993\n" */ if (G.all_fmt & LIST_FULLTIME) { /* -e */ /* Note: coreutils 8.4 ls --full-time prints: @@ -595,13 +665,16 @@ static NOINLINE unsigned display_single(const struct dnode *dn) column += printf("%.24s ", filetime); } else { /* LIST_DATE_TIME */ /* G.current_time_t ~== time(NULL) */ - time_t age = G.current_time_t - ttime; - printf("%.6s ", filetime + 4); /* "Jun 30" */ + time_t age = G.current_time_t - *ttime; if (age < 3600L * 24 * 365 / 2 && age > -15 * 60) { - /* hh:mm if less than 6 months old */ - printf("%.5s ", filetime + 11); - } else { /* year. buggy if year > 9999 ;) */ - printf(" %.4s ", filetime + 20); + /* less than 6 months old */ + /* "mmm dd hh:mm " */ + printf("%.12s ", filetime + 4); + } else { + /* "mmm dd yyyy " */ + /* "mmm dd yyyyy " after year 9999 :) */ + strchr(filetime + 20, '\n')[0] = ' '; + printf("%.7s%6s", filetime + 4, filetime + 20); } column += 13; } @@ -680,7 +753,7 @@ static void display_files(struct dnode **dn, unsigned nfiles) if ((int)column_width < len) column_width = len; } - column_width += 1 + + column_width += 2 + IF_SELINUX( ((G.all_fmt & LIST_CONTEXT) ? 33 : 0) + ) ((G.all_fmt & LIST_INO) ? 8 : 0) + ((G.all_fmt & LIST_BLOCKS) ? 5 : 0); @@ -708,8 +781,8 @@ static void display_files(struct dnode **dn, unsigned nfiles) if (i < nfiles) { if (column > 0) { nexttab -= column; - printf("%*s ", nexttab, ""); - column += nexttab + 1; + printf("%*s", nexttab, ""); + column += nexttab; } nexttab = column + column_width; column += display_single(dn[i]); @@ -1047,7 +1120,7 @@ static void scan_and_display_dirs_recur(struct dnode **dn, int first) } subdnp = scan_one_dir((*dn)->fullname, &nfiles); #if ENABLE_DESKTOP - if ((G.all_fmt & STYLE_MASK) == STYLE_LONG) + if ((G.all_fmt & STYLE_MASK) == STYLE_LONG || (G.all_fmt & LIST_BLOCKS)) printf("total %"OFF_FMT"u\n", calculate_blocks(subdnp)); #endif if (nfiles > 0) { @@ -1117,7 +1190,7 @@ int ls_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_AUTOWIDTH /* obtain the terminal width */ - get_terminal_width_height(STDIN_FILENO, &G_terminal_width, NULL); + G_terminal_width = get_terminal_width(STDIN_FILENO); /* go one less... */ G_terminal_width--; #endif diff --git a/coreutils/md5_sha1_sum.c b/coreutils/md5_sha1_sum.c index 1a5342e..783f440 100644 --- a/coreutils/md5_sha1_sum.c +++ b/coreutils/md5_sha1_sum.c @@ -5,6 +5,60 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config MD5SUM +//config: bool "md5sum" +//config: default y +//config: help +//config: md5sum is used to print or check MD5 checksums. +//config: +//config:config SHA1SUM +//config: bool "sha1sum" +//config: default y +//config: help +//config: Compute and check SHA1 message digest +//config: +//config:config SHA256SUM +//config: bool "sha256sum" +//config: default y +//config: help +//config: Compute and check SHA256 message digest +//config: +//config:config SHA512SUM +//config: bool "sha512sum" +//config: default y +//config: help +//config: Compute and check SHA512 message digest +//config: +//config:config SHA3SUM +//config: bool "sha3sum" +//config: default y +//config: help +//config: Compute and check SHA3 message digest +//config: +//config:comment "Common options for md5sum, sha1sum, sha256sum, sha512sum, sha3sum" +//config: depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM +//config: +//config:config FEATURE_MD5_SHA1_SUM_CHECK +//config: bool "Enable -c, -s and -w options" +//config: default y +//config: depends on MD5SUM || SHA1SUM || SHA256SUM || SHA512SUM || SHA3SUM +//config: help +//config: Enabling the -c options allows files to be checked +//config: against pre-calculated hash values. +//config: +//config: -s and -w are useful options when verifying checksums. + +//applet:IF_MD5SUM(APPLET_NOEXEC(md5sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, md5sum)) +//applet:IF_SHA1SUM(APPLET_NOEXEC(sha1sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha1sum)) +//applet:IF_SHA3SUM(APPLET_NOEXEC(sha3sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha3sum)) +//applet:IF_SHA256SUM(APPLET_NOEXEC(sha256sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha256sum)) +//applet:IF_SHA512SUM(APPLET_NOEXEC(sha512sum, md5_sha1_sum, BB_DIR_USR_BIN, BB_SUID_DROP, sha512sum)) + +//kbuild:lib-$(CONFIG_MD5SUM) += md5_sha1_sum.o +//kbuild:lib-$(CONFIG_SHA1SUM) += md5_sha1_sum.o +//kbuild:lib-$(CONFIG_SHA256SUM) += md5_sha1_sum.o +//kbuild:lib-$(CONFIG_SHA512SUM) += md5_sha1_sum.o +//kbuild:lib-$(CONFIG_SHA3SUM) += md5_sha1_sum.o //usage:#define md5sum_trivial_usage //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..." @@ -57,15 +111,20 @@ //usage: ) //usage: //usage:#define sha3sum_trivial_usage -//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[FILE]..." +//usage: IF_FEATURE_MD5_SHA1_SUM_CHECK("[-c[sw]] ")"[-a BITS] [FILE]..." //usage:#define sha3sum_full_usage "\n\n" -//usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA3-512 checksums" +//usage: "Print" IF_FEATURE_MD5_SHA1_SUM_CHECK(" or check") " SHA3 checksums" //usage: IF_FEATURE_MD5_SHA1_SUM_CHECK( "\n" //usage: "\n -c Check sums against list in FILEs" //usage: "\n -s Don't output anything, status code shows success" //usage: "\n -w Warn about improperly formatted checksum lines" +//usage: "\n -a BITS 224 (default), 256, 384, 512" //usage: ) +//FIXME: GNU coreutils 8.25 has no -s option, it has only these two long opts: +// --quiet don't print OK for each successfully verified file +// --status don't output anything, status code shows success + #include "libbb.h" /* This is a NOEXEC applet. Be very careful! */ @@ -93,7 +152,10 @@ static unsigned char *hash_bin_to_hex(unsigned char *hash_value, return (unsigned char *)hex_value; } -static uint8_t *hash_file(const char *filename) +#if !ENABLE_SHA3SUM +# define hash_file(f,w) hash_file(f) +#endif +static uint8_t *hash_file(const char *filename, unsigned sha3_width) { int src_fd, hash_len, count; union _ctx_ { @@ -121,27 +183,47 @@ static uint8_t *hash_file(const char *filename) update = (void*)md5_hash; final = (void*)md5_end; hash_len = 16; - } else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) { + } + else if (ENABLE_SHA1SUM && hash_algo == HASH_SHA1) { sha1_begin(&context.sha1); update = (void*)sha1_hash; final = (void*)sha1_end; hash_len = 20; - } else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) { + } + else if (ENABLE_SHA256SUM && hash_algo == HASH_SHA256) { sha256_begin(&context.sha256); update = (void*)sha256_hash; final = (void*)sha256_end; hash_len = 32; - } else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) { + } + else if (ENABLE_SHA512SUM && hash_algo == HASH_SHA512) { sha512_begin(&context.sha512); update = (void*)sha512_hash; final = (void*)sha512_end; hash_len = 64; - } else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) { + } +#if ENABLE_SHA3SUM + else if (ENABLE_SHA3SUM && hash_algo == HASH_SHA3) { sha3_begin(&context.sha3); update = (void*)sha3_hash; final = (void*)sha3_end; - hash_len = 64; - } else { + /* + * Should support 224, 256, 384, 512. + * We allow any value which does not blow the algorithm up. + */ + if (sha3_width >= 1600/2 /* input block can't be <= 0 */ + || sha3_width == 0 /* hash len can't be 0 */ + || (sha3_width & 0x1f) /* should be multiple of 32 */ + /* (because input uses up to 8 byte wide word XORs. 32/4=8) */ + ) { + bb_error_msg_and_die("bad -a%u", sha3_width); + } + sha3_width /= 4; + context.sha3.input_block_bytes = 1600/8 - sha3_width; + hash_len = sha3_width/2; + } +#endif + else { xfunc_die(); /* can't reach this */ } @@ -172,28 +254,33 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) { int return_value = EXIT_SUCCESS; unsigned flags; +#if ENABLE_SHA3SUM + unsigned sha3_width = 224; +#endif if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK) { + /* -s and -w require -c */ + opt_complementary = "s?c:w?c"; /* -b "binary", -t "text" are ignored (shaNNNsum compat) */ - flags = getopt32(argv, "scwbt"); - argv += optind; - //argc -= optind; +#if ENABLE_SHA3SUM + if (applet_name[3] == HASH_SHA3) + flags = getopt32(argv, "scwbta:+", &sha3_width); + else +#endif + flags = getopt32(argv, "scwbt"); } else { - argv += 1; - //argc -= 1; +#if ENABLE_SHA3SUM + if (applet_name[3] == HASH_SHA3) + getopt32(argv, "a:+", &sha3_width); + else +#endif + getopt32(argv, ""); } + argv += optind; + //argc -= optind; if (!*argv) *--argv = (char*)"-"; - if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && !(flags & FLAG_CHECK)) { - if (flags & FLAG_SILENT) { - bb_error_msg_and_die("-%c is meaningful only with -c", 's'); - } - if (flags & FLAG_WARN) { - bb_error_msg_and_die("-%c is meaningful only with -c", 'w'); - } - } - do { if (ENABLE_FEATURE_MD5_SHA1_SUM_CHECK && (flags & FLAG_CHECK)) { FILE *pre_computed_stream; @@ -225,7 +312,7 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) *filename_ptr = '\0'; filename_ptr += 2; - hash_value = hash_file(filename_ptr); + hash_value = hash_file(filename_ptr, sha3_width); if (hash_value && (strcmp((char*)hash_value, line) == 0)) { if (!(flags & FLAG_SILENT)) @@ -244,9 +331,17 @@ int md5_sha1_sum_main(int argc UNUSED_PARAM, char **argv) bb_error_msg("WARNING: %d of %d computed checksums did NOT match", count_failed, count_total); } + if (count_total == 0) { + return_value = EXIT_FAILURE; + /* + * md5sum from GNU coreutils 8.25 says: + * md5sum: : no properly formatted MD5 checksum lines found + */ + bb_error_msg("%s: no checksum lines found", *argv); + } fclose_if_not_stdin(pre_computed_stream); } else { - uint8_t *hash_value = hash_file(*argv); + uint8_t *hash_value = hash_file(*argv, sha3_width); if (hash_value == NULL) { return_value = EXIT_FAILURE; } else { diff --git a/coreutils/mkdir.c b/coreutils/mkdir.c index 4a8e43e..3afe76c 100644 --- a/coreutils/mkdir.c +++ b/coreutils/mkdir.c @@ -6,18 +6,32 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 compliant */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/mkdir.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Fixed broken permission setting when -p was used; especially in * conjunction with -m. */ - /* Nov 28, 2006 Yoshinori Sato : Add SELinux Support. */ +//config:config MKDIR +//config: bool "mkdir" +//config: default y +//config: help +//config: mkdir is used to create directories with the specified names. +//config: +//config:config FEATURE_MKDIR_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on MKDIR && LONG_OPTS +//config: help +//config: Support long options for the mkdir applet. + +//applet:IF_MKDIR(APPLET_NOFORK(mkdir, mkdir, BB_DIR_BIN, BB_SUID_DROP, mkdir)) + +//kbuild:lib-$(CONFIG_MKDIR) += mkdir.o + +/* BB_AUDIT SUSv3 compliant */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/mkdir.html */ //usage:#define mkdir_trivial_usage //usage: "[OPTIONS] DIRECTORY..." @@ -48,7 +62,9 @@ static const char mkdir_longopts[] ALIGN1 = #if ENABLE_SELINUX "context\0" Required_argument "Z" #endif +#if ENABLE_FEATURE_VERBOSE "verbose\0" No_argument "v" +#endif ; #endif @@ -67,18 +83,20 @@ int mkdir_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_MKDIR_LONG_OPTIONS applet_long_options = mkdir_longopts; #endif - opt = getopt32(argv, "m:p" IF_SELINUX("Z:") "v", &smode IF_SELINUX(,&scontext)); + opt = getopt32(argv, "m:pv" IF_SELINUX("Z:"), &smode IF_SELINUX(,&scontext)); if (opt & 1) { - mode_t mmode = 0777; - if (!bb_parse_mode(smode, &mmode)) { + mode_t mmode = bb_parse_mode(smode, 0777); + if (mmode == (mode_t)-1) { bb_error_msg_and_die("invalid mode '%s'", smode); } mode = mmode; } if (opt & 2) flags |= FILEUTILS_RECUR; + if ((opt & 4) && FILEUTILS_VERBOSE) + flags |= FILEUTILS_VERBOSE; #if ENABLE_SELINUX - if (opt & 4) { + if (opt & 8) { selinux_or_die(); setfscreatecon_or_die(scontext); } diff --git a/coreutils/mkfifo.c b/coreutils/mkfifo.c index ef58325..66509a9 100644 --- a/coreutils/mkfifo.c +++ b/coreutils/mkfifo.c @@ -6,6 +6,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config MKFIFO +//config: bool "mkfifo" +//config: default y +//config: help +//config: mkfifo is used to create FIFOs (named pipes). +//config: The 'mknod' program can also create FIFOs. + +//applet:IF_MKFIFO(APPLET_NOEXEC(mkfifo, mkfifo, BB_DIR_USR_BIN, BB_SUID_DROP, mkfifo)) + +//kbuild:lib-$(CONFIG_MKFIFO) += mkfifo.o /* BB_AUDIT SUSv3 compliant */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/mkfifo.html */ diff --git a/coreutils/mknod.c b/coreutils/mknod.c index aa04504..466ef5c 100644 --- a/coreutils/mknod.c +++ b/coreutils/mknod.c @@ -6,6 +6,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config MKNOD +//config: bool "mknod" +//config: default y +//config: help +//config: mknod is used to create FIFOs or block/character special +//config: files with the specified names. + +//applet:IF_MKNOD(APPLET_NOEXEC(mknod, mknod, BB_DIR_BIN, BB_SUID_DROP, mknod)) + +//kbuild:lib-$(CONFIG_MKNOD) += mknod.o /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ diff --git a/coreutils/mv.c b/coreutils/mv.c index f127dfa..1cc318f 100644 --- a/coreutils/mv.c +++ b/coreutils/mv.c @@ -7,14 +7,26 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Size reduction and improved error checking. */ +//config:config MV +//config: bool "mv" +//config: default y +//config: help +//config: mv is used to move or rename files or directories. +//config: +//config:config FEATURE_MV_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on MV && LONG_OPTS +//config: help +//config: Support long options for the mv applet. -#include "libbb.h" -#include "libcoreutils/coreutils.h" +//applet:IF_MV(APPLET(mv, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_MV) += mv.o //usage:#define mv_trivial_usage //usage: "[-fin] SOURCE DEST\n" @@ -28,18 +40,25 @@ //usage:#define mv_example_usage //usage: "$ mv /tmp/foo /bin/bar\n" +#include "libbb.h" +#include "libcoreutils/coreutils.h" + #if ENABLE_FEATURE_MV_LONG_OPTIONS static const char mv_longopts[] ALIGN1 = "interactive\0" No_argument "i" "force\0" No_argument "f" "no-clobber\0" No_argument "n" + IF_FEATURE_VERBOSE( "verbose\0" No_argument "v" + ) ; #endif #define OPT_FORCE (1 << 0) #define OPT_INTERACTIVE (1 << 1) #define OPT_NOCLOBBER (1 << 2) +#define OPT_VERBOSE ((1 << 3) * ENABLE_FEATURE_VERBOSE) + int mv_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int mv_main(int argc, char **argv) @@ -58,7 +77,6 @@ int mv_main(int argc, char **argv) /* Need at least two arguments. * If more than one of -f, -i, -n is specified , only the final one * takes effect (it unsets previous options). - * -v is accepted but ignored. */ opt_complementary = "-2:f-in:i-fn:n-fi"; flags = getopt32(argv, "finv"); @@ -148,6 +166,9 @@ int mv_main(int argc, char **argv) status = 1; } RET_0: + if (flags & OPT_VERBOSE) { + printf("'%s' -> '%s'\n", *argv, dest); + } if (dest != last) { free((void *) dest); } diff --git a/coreutils/nice.c b/coreutils/nice.c index ce75991..3676ee6 100644 --- a/coreutils/nice.c +++ b/coreutils/nice.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config NICE +//config: bool "nice" +//config: default y +//config: help +//config: nice runs a program with modified scheduling priority. + +//applet:IF_NICE(APPLET(nice, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_NICE) += nice.o //usage:#define nice_trivial_usage //usage: "[-n ADJUST] [PROG ARGS]" diff --git a/coreutils/nohup.c b/coreutils/nohup.c index 63853fd..d848968 100644 --- a/coreutils/nohup.c +++ b/coreutils/nohup.c @@ -9,6 +9,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config NOHUP +//config: bool "nohup" +//config: default y +//config: help +//config: run a command immune to hangups, with output to a non-tty. + +//applet:IF_NOHUP(APPLET(nohup, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_NOHUP) += nohup.o //usage:#define nohup_trivial_usage //usage: "PROG ARGS" diff --git a/coreutils/od.c b/coreutils/od.c index fb11fcf..4b05ee7 100644 --- a/coreutils/od.c +++ b/coreutils/od.c @@ -10,6 +10,15 @@ * * Original copyright notice is retained at the end of this file. */ +//config:config OD +//config: bool "od" +//config: default y +//config: help +//config: od is used to dump binary files in octal and other formats. + +//applet:IF_OD(APPLET(od, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_OD) += od.o //usage:#if !ENABLE_DESKTOP //usage:#define od_trivial_usage diff --git a/coreutils/od_bloaty.c b/coreutils/od_bloaty.c index 6b00a43..475fb3f 100644 --- a/coreutils/od_bloaty.c +++ b/coreutils/od_bloaty.c @@ -20,6 +20,7 @@ /* #include "libbb.h" - done in od.c */ +#include "common_bufsiz.h" #define assert(a) ((void)0) @@ -61,12 +62,12 @@ enum { }; #define OD_GETOPT32() getopt32(argv, \ - "A:N:abcdfhij:lot:vxsS:w::", \ + "A:N:abcdfhij:lot:*vxsS:w:+:", \ /* -w with optional param */ \ /* -S was -s and also had optional parameter */ \ /* but in coreutils 6.3 it was renamed and now has */ \ /* _mandatory_ parameter */ \ - &str_A, &str_N, &str_j, &lst_t, &str_S, &bytes_per_block) + &str_A, &str_N, &str_j, &lst_t, &str_S, &G.bytes_per_block) /* Check for 0x7f is a coreutils 6.3 addition */ @@ -174,38 +175,53 @@ struct ERR_width_bytes_has_bad_size { char ERR_width_bytes_has_bad_size[ARRAY_SIZE(width_bytes) == N_SIZE_SPECS ? 1 : -1]; }; -static smallint exit_code; +struct globals { + smallint exit_code; -static unsigned string_min; + unsigned string_min; -/* An array of specs describing how to format each input block. */ -static size_t n_specs; -static struct tspec *spec; + /* An array of specs describing how to format each input block. */ + unsigned n_specs; + struct tspec *spec; -/* Function that accepts an address and an optional following char, - and prints the address and char to stdout. */ -static void (*format_address)(off_t, char); -/* The difference between the old-style pseudo starting address and - the number of bytes to skip. */ + /* Function that accepts an address and an optional following char, + and prints the address and char to stdout. */ + void (*format_address)(off_t, char); + + /* The difference between the old-style pseudo starting address and + the number of bytes to skip. */ #if ENABLE_LONG_OPTS -static off_t pseudo_offset; -#else -enum { pseudo_offset = 0 }; + off_t pseudo_offset; +# define G_pseudo_offset G.pseudo_offset #endif -/* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all - input is formatted. */ - -/* The number of input bytes formatted per output line. It must be - a multiple of the least common multiple of the sizes associated with - the specified output types. It should be as large as possible, but - no larger than 16 -- unless specified with the -w option. */ -static unsigned bytes_per_block = 32; /* have to use unsigned, not size_t */ - -/* A NULL-terminated list of the file-arguments from the command line. */ -static const char *const *file_list; + /* When zero, MAX_BYTES_TO_FORMAT and END_OFFSET are ignored, and all + input is formatted. */ + + /* The number of input bytes formatted per output line. It must be + a multiple of the least common multiple of the sizes associated with + the specified output types. It should be as large as possible, but + no larger than 16 -- unless specified with the -w option. */ + unsigned bytes_per_block; /* have to use unsigned, not size_t */ + + /* A NULL-terminated list of the file-arguments from the command line. */ + const char *const *file_list; + + /* The input stream associated with the current file. */ + FILE *in_stream; + + bool not_first; + bool prev_pair_equal; +} FIX_ALIASING; +#if !ENABLE_LONG_OPTS +enum { G_pseudo_offset = 0 }; +#endif +#define G (*(struct globals*)bb_common_bufsiz1) +#define INIT_G() do { \ + setup_common_bufsiz(); \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ + G.bytes_per_block = 32; \ +} while (0) -/* The input stream associated with the current file. */ -static FILE *in_stream; #define MAX_INTEGRAL_TYPE_SIZE sizeof(ulonglong_t) static const unsigned char integral_type_size[MAX_INTEGRAL_TYPE_SIZE + 1] ALIGN1 = { @@ -387,11 +403,11 @@ print_named_ascii(size_t n_bytes, const char *block, " sp" }; // buf[N] pos: 01234 56789 - char buf[12] = " x\0 0xx\0"; - // actually " x\0 xxx\0", but want to share string with print_ascii. + char buf[12] = " x\0 xxx\0"; // [12] because we take three 32bit stack slots anyway, and // gcc is too dumb to initialize with constant stores, // it copies initializer from rodata. Oh well. + // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65410 while (n_bytes--) { unsigned masked_c = *(unsigned char *) block++; @@ -419,7 +435,7 @@ print_ascii(size_t n_bytes, const char *block, const char *unused_fmt_string UNUSED_PARAM) { // buf[N] pos: 01234 56789 - char buf[12] = " x\0 0xx\0"; + char buf[12] = " x\0 xxx\0"; while (n_bytes--) { const char *s; @@ -455,11 +471,9 @@ print_ascii(size_t n_bytes, const char *block, case '\v': s = " \\v"; break; - case '\x7f': - s = " 177"; - break; - default: /* c is never larger than 040 */ - buf[7] = (c >> 3) + '0'; + default: + buf[6] = (c >> 6 & 3) + '0'; + buf[7] = (c >> 3 & 7) + '0'; buf[8] = (c & 7) + '0'; s = buf + 5; } @@ -478,17 +492,17 @@ static void open_next_file(void) { while (1) { - if (!*file_list) + if (!*G.file_list) return; - in_stream = fopen_or_warn_stdin(*file_list++); - if (in_stream) { + G.in_stream = fopen_or_warn_stdin(*G.file_list++); + if (G.in_stream) { break; } - exit_code = 1; + G.exit_code = 1; } if ((option_mask32 & (OPT_N|OPT_S)) == OPT_N) - setbuf(in_stream, NULL); + setbuf(G.in_stream, NULL); } /* Test whether there have been errors on in_stream, and close it if @@ -501,16 +515,16 @@ open_next_file(void) static void check_and_close(void) { - if (in_stream) { - if (ferror(in_stream)) { - bb_error_msg("%s: read error", (in_stream == stdin) + if (G.in_stream) { + if (ferror(G.in_stream)) { + bb_error_msg("%s: read error", (G.in_stream == stdin) ? bb_msg_standard_input - : file_list[-1] + : G.file_list[-1] ); - exit_code = 1; + G.exit_code = 1; } - fclose_if_not_stdin(in_stream); - in_stream = NULL; + fclose_if_not_stdin(G.in_stream); + G.in_stream = NULL; } if (ferror(stdout)) { @@ -746,9 +760,9 @@ decode_format_string(const char *s) assert(s != next); s = next; - spec = xrealloc_vector(spec, 4, n_specs); - memcpy(&spec[n_specs], &tspec, sizeof(spec[0])); - n_specs++; + G.spec = xrealloc_vector(G.spec, 4, G.n_specs); + memcpy(&G.spec[G.n_specs], &tspec, sizeof(G.spec[0])); + G.n_specs++; } } @@ -765,7 +779,7 @@ skip(off_t n_skip) if (n_skip == 0) return; - while (in_stream) { /* !EOF */ + while (G.in_stream) { /* !EOF */ struct stat file_stats; /* First try seeking. For large offsets, this extra work is @@ -783,15 +797,15 @@ skip(off_t n_skip) If the number of bytes left to skip is at least as large as the size of the current file, we can decrement n_skip and go on to the next file. */ - if (fstat(fileno(in_stream), &file_stats) == 0 + if (fstat(fileno(G.in_stream), &file_stats) == 0 && S_ISREG(file_stats.st_mode) && file_stats.st_size > 0 ) { if (file_stats.st_size < n_skip) { n_skip -= file_stats.st_size; /* take "check & close / open_next" route */ } else { - if (fseeko(in_stream, n_skip, SEEK_CUR) != 0) - exit_code = 1; + if (fseeko(G.in_stream, n_skip, SEEK_CUR) != 0) + G.exit_code = 1; return; } } else { @@ -804,7 +818,7 @@ skip(off_t n_skip) while (n_skip > 0) { if (n_skip < n_bytes_to_read) n_bytes_to_read = n_skip; - n_bytes_read = fread(buf, 1, n_bytes_to_read, in_stream); + n_bytes_read = fread(buf, 1, n_bytes_to_read, G.in_stream); n_skip -= n_bytes_read; if (n_bytes_read != n_bytes_to_read) break; /* EOF on this file or error */ @@ -857,7 +871,7 @@ static void format_address_label(off_t address, char c) { format_address_std(address, ' '); - format_address_paren(address + pseudo_offset, c); + format_address_paren(address + G_pseudo_offset, c); } #endif @@ -888,36 +902,34 @@ static void write_block(off_t current_offset, size_t n_bytes, const char *prev_block, const char *curr_block) { - static char first = 1; - static char prev_pair_equal = 0; - size_t i; + unsigned i; if (!(option_mask32 & OPT_v) - && !first - && n_bytes == bytes_per_block - && memcmp(prev_block, curr_block, bytes_per_block) == 0 + && G.not_first + && n_bytes == G.bytes_per_block + && memcmp(prev_block, curr_block, G.bytes_per_block) == 0 ) { - if (prev_pair_equal) { + if (G.prev_pair_equal) { /* The two preceding blocks were equal, and the current block is the same as the last one, so print nothing. */ } else { puts("*"); - prev_pair_equal = 1; + G.prev_pair_equal = 1; } } else { - first = 0; - prev_pair_equal = 0; - for (i = 0; i < n_specs; i++) { + G.not_first = 1; + G.prev_pair_equal = 0; + for (i = 0; i < G.n_specs; i++) { if (i == 0) - format_address(current_offset, '\0'); + G.format_address(current_offset, '\0'); else printf("%*s", address_pad_len_char - '0', ""); - (*spec[i].print_function) (n_bytes, curr_block, spec[i].fmt_string); - if (spec[i].hexl_mode_trailer) { + (*G.spec[i].print_function) (n_bytes, curr_block, G.spec[i].fmt_string); + if (G.spec[i].hexl_mode_trailer) { /* space-pad out to full line width, then dump the trailer */ - unsigned datum_width = width_bytes[spec[i].size]; - unsigned blank_fields = (bytes_per_block - n_bytes) / datum_width; - unsigned field_width = spec[i].field_width + 1; + unsigned datum_width = width_bytes[G.spec[i].size]; + unsigned blank_fields = (G.bytes_per_block - n_bytes) / datum_width; + unsigned field_width = G.spec[i].field_width + 1; printf("%*s", blank_fields * field_width, ""); dump_hexl_mode_trailer(n_bytes, curr_block); } @@ -929,19 +941,19 @@ write_block(off_t current_offset, size_t n_bytes, static void read_block(size_t n, char *block, size_t *n_bytes_in_buffer) { - assert(0 < n && n <= bytes_per_block); + assert(0 < n && n <= G.bytes_per_block); *n_bytes_in_buffer = 0; if (n == 0) return; - while (in_stream != NULL) { /* EOF. */ + while (G.in_stream != NULL) { /* EOF. */ size_t n_needed; size_t n_read; n_needed = n - *n_bytes_in_buffer; - n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, in_stream); + n_read = fread(block + *n_bytes_in_buffer, 1, n_needed, G.in_stream); *n_bytes_in_buffer += n_read; if (n_read == n_needed) break; @@ -960,8 +972,8 @@ get_lcm(void) size_t i; int l_c_m = 1; - for (i = 0; i < n_specs; i++) - l_c_m = lcm(l_c_m, width_bytes[(int) spec[i].size]); + for (i = 0; i < G.n_specs; i++) + l_c_m = lcm(l_c_m, width_bytes[(int) G.spec[i].size]); return l_c_m; } @@ -982,8 +994,8 @@ dump(off_t current_offset, off_t end_offset) int idx; size_t n_bytes_read; - block[0] = xmalloc(2 * bytes_per_block); - block[1] = block[0] + bytes_per_block; + block[0] = xmalloc(2 * G.bytes_per_block); + block[1] = block[0] + G.bytes_per_block; idx = 0; if (option_mask32 & OPT_N) { @@ -993,21 +1005,21 @@ dump(off_t current_offset, off_t end_offset) n_bytes_read = 0; break; } - n_needed = MIN(end_offset - current_offset, (off_t) bytes_per_block); + n_needed = MIN(end_offset - current_offset, (off_t) G.bytes_per_block); read_block(n_needed, block[idx], &n_bytes_read); - if (n_bytes_read < bytes_per_block) + if (n_bytes_read < G.bytes_per_block) break; - assert(n_bytes_read == bytes_per_block); + assert(n_bytes_read == G.bytes_per_block); write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]); current_offset += n_bytes_read; idx ^= 1; } } else { while (1) { - read_block(bytes_per_block, block[idx], &n_bytes_read); - if (n_bytes_read < bytes_per_block) + read_block(G.bytes_per_block, block[idx], &n_bytes_read); + if (n_bytes_read < G.bytes_per_block) break; - assert(n_bytes_read == bytes_per_block); + assert(n_bytes_read == G.bytes_per_block); write_block(current_offset, n_bytes_read, block[idx ^ 1], block[idx]); current_offset += n_bytes_read; idx ^= 1; @@ -1030,7 +1042,7 @@ dump(off_t current_offset, off_t end_offset) current_offset += n_bytes_read; } - format_address(current_offset, '\n'); + G.format_address(current_offset, '\n'); if ((option_mask32 & OPT_N) && current_offset >= end_offset) check_and_close(); @@ -1061,16 +1073,16 @@ dump(off_t current_offset, off_t end_offset) static void dump_strings(off_t address, off_t end_offset) { - unsigned bufsize = MAX(100, string_min); + unsigned bufsize = MAX(100, G.string_min); unsigned char *buf = xmalloc(bufsize); while (1) { size_t i; int c; - /* See if the next 'string_min' chars are all printing chars. */ + /* See if the next 'G.string_min' chars are all printing chars. */ tryline: - if ((option_mask32 & OPT_N) && (end_offset - string_min <= address)) + if ((option_mask32 & OPT_N) && (end_offset - G.string_min <= address)) break; i = 0; while (!(option_mask32 & OPT_N) || address < end_offset) { @@ -1079,8 +1091,8 @@ dump_strings(off_t address, off_t end_offset) buf = xrealloc(buf, bufsize); } - while (in_stream) { /* !EOF */ - c = fgetc(in_stream); + while (G.in_stream) { /* !EOF */ + c = fgetc(G.in_stream); if (c != EOF) goto got_char; check_and_close(); @@ -1097,12 +1109,12 @@ dump_strings(off_t address, off_t end_offset) buf[i++] = c; /* String continues; store it all. */ } - if (i < string_min) /* Too short! */ + if (i < G.string_min) /* Too short! */ goto tryline; /* If we get here, the string is all printable and NUL-terminated */ buf[i] = 0; - format_address(address - i - 1, ' '); + G.format_address(address - i - 1, ' '); for (i = 0; (c = buf[i]); i++) { switch (c) { @@ -1120,7 +1132,7 @@ dump_strings(off_t address, off_t end_offset) } /* We reach this point only if we search through - (max_bytes_to_format - string_min) bytes before reaching EOF. */ + (max_bytes_to_format - G.string_min) bytes before reaching EOF. */ check_and_close(); ret: free(buf); @@ -1192,13 +1204,14 @@ int od_main(int argc UNUSED_PARAM, char **argv) /* The maximum number of bytes that will be formatted. */ off_t max_bytes_to_format = 0; - spec = NULL; - format_address = format_address_std; + INIT_G(); + + /*G.spec = NULL; - already is */ + G.format_address = format_address_std; address_base_char = 'o'; address_pad_len_char = '7'; /* Parse command line */ - opt_complementary = "w+:t::"; /* -w N, -t is a list */ #if ENABLE_LONG_OPTS applet_long_options = od_longopts; #endif @@ -1219,7 +1232,7 @@ int od_main(int argc UNUSED_PARAM, char **argv) bb_error_msg_and_die("bad output address radix " "'%c' (must be [doxn])", str_A[0]); pos = p - doxn; - if (pos == 3) format_address = format_address_none; + if (pos == 3) G.format_address = format_address_none; address_base_char = doxn_address_base_char[pos]; address_pad_len_char = doxn_address_pad_len_char[pos]; } @@ -1242,11 +1255,11 @@ int od_main(int argc UNUSED_PARAM, char **argv) if (opt & OPT_x) decode_format_string("x2"); if (opt & OPT_s) decode_format_string("d2"); if (opt & OPT_S) { - string_min = xstrtou_sfx(str_S, 0, bkm_suffixes); + G.string_min = xstrtou_sfx(str_S, 0, bkm_suffixes); } // Bloat: - //if ((option_mask32 & OPT_S) && n_specs > 0) + //if ((option_mask32 & OPT_S) && G.n_specs > 0) // bb_error_msg_and_die("no type may be specified when dumping strings"); /* If the --traditional option is used, there may be from @@ -1302,14 +1315,14 @@ int od_main(int argc UNUSED_PARAM, char **argv) } if (pseudo_start >= 0) { - if (format_address == format_address_none) { + if (G.format_address == format_address_none) { address_base_char = 'o'; address_pad_len_char = '7'; - format_address = format_address_paren; + G.format_address = format_address_paren; } else { - format_address = format_address_label; + G.format_address = format_address_label; } - pseudo_offset = pseudo_start - n_bytes_to_skip; + G_pseudo_offset = pseudo_start - n_bytes_to_skip; } } /* else: od --traditional (without args) */ @@ -1322,45 +1335,45 @@ int od_main(int argc UNUSED_PARAM, char **argv) bb_error_msg_and_die("SKIP + SIZE is too large"); } - if (n_specs == 0) { + if (G.n_specs == 0) { decode_format_string("o2"); - /*n_specs = 1; - done by decode_format_string */ + /*G.n_specs = 1; - done by decode_format_string */ } /* If no files were listed on the command line, set the global pointer FILE_LIST so that it references the null-terminated list of one name: "-". */ - file_list = bb_argv_dash; + G.file_list = bb_argv_dash; if (argv[0]) { /* Set the global pointer FILE_LIST so that it references the first file-argument on the command-line. */ - file_list = (char const *const *) argv; + G.file_list = (char const *const *) argv; } /* Open the first input file */ open_next_file(); /* Skip over any unwanted header bytes */ skip(n_bytes_to_skip); - if (!in_stream) + if (!G.in_stream) return EXIT_FAILURE; /* Compute output block length */ l_c_m = get_lcm(); if (opt & OPT_w) { /* -w: width */ - if (!bytes_per_block || bytes_per_block % l_c_m != 0) { + if (!G.bytes_per_block || G.bytes_per_block % l_c_m != 0) { bb_error_msg("warning: invalid width %u; using %d instead", - (unsigned)bytes_per_block, l_c_m); - bytes_per_block = l_c_m; + (unsigned)G.bytes_per_block, l_c_m); + G.bytes_per_block = l_c_m; } } else { - bytes_per_block = l_c_m; + G.bytes_per_block = l_c_m; if (l_c_m < DEFAULT_BYTES_PER_BLOCK) - bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m; + G.bytes_per_block *= DEFAULT_BYTES_PER_BLOCK / l_c_m; } #ifdef DEBUG - for (i = 0; i < n_specs; i++) { + for (i = 0; i < G.n_specs; i++) { printf("%d: fmt=\"%s\" width=%d\n", i, spec[i].fmt_string, width_bytes[spec[i].size]); } @@ -1374,5 +1387,5 @@ int od_main(int argc UNUSED_PARAM, char **argv) if (fclose(stdin)) bb_perror_msg_and_die("%s", bb_msg_standard_input); - return exit_code; + return G.exit_code; } diff --git a/coreutils/printenv.c b/coreutils/printenv.c index bd5db70..fbd6494 100644 --- a/coreutils/printenv.c +++ b/coreutils/printenv.c @@ -7,6 +7,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config PRINTENV +//config: bool "printenv" +//config: default y +//config: help +//config: printenv is used to print all or part of environment. + +//applet:IF_PRINTENV(APPLET_NOFORK(printenv, printenv, BB_DIR_BIN, BB_SUID_DROP, printenv)) + +//kbuild:lib-$(CONFIG_PRINTENV) += printenv.o //usage:#define printenv_trivial_usage //usage: "[VARIABLE]..." diff --git a/coreutils/printf.c b/coreutils/printf.c index 3dd43a9..6c8e115 100644 --- a/coreutils/printf.c +++ b/coreutils/printf.c @@ -38,6 +38,17 @@ /* 19990508 Busy Boxed! Dave Cinege */ +//config:config PRINTF +//config: bool "printf" +//config: default y +//config: help +//config: printf is used to format and print specified strings. +//config: It's similar to `echo' except it has more options. + +//applet:IF_PRINTF(APPLET_NOFORK(printf, printf, BB_DIR_USR_BIN, BB_SUID_DROP, printf)) + +//kbuild:lib-$(CONFIG_PRINTF) += printf.o + //usage:#define printf_trivial_usage //usage: "FORMAT [ARG]..." //usage:#define printf_full_usage "\n\n" @@ -131,8 +142,8 @@ static double my_xstrtod(const char *arg) return result; } -/* Handles %b */ -static void print_esc_string(const char *str) +/* Handles %b; return 1 if output is to be short-circuited by \c */ +static int print_esc_string(const char *str) { char c; while ((c = *str) != '\0') { @@ -145,6 +156,9 @@ static void print_esc_string(const char *str) str++; } } + else if (*str == 'c') { + return 1; + } { /* optimization: don't force arg to be on-stack, * use another variable for that. */ @@ -155,6 +169,8 @@ static void print_esc_string(const char *str) } putchar(c); } + + return 0; } static void print_direc(char *format, unsigned fmt_length, @@ -280,7 +296,8 @@ static char **print_formatted(char *f, char **argv, int *conv_err) } if (*f == 'b') { if (*argv) { - print_esc_string(*argv); + if (print_esc_string(*argv)) + return saved_argv; /* causes main() to exit */ ++argv; } break; diff --git a/coreutils/pwd.c b/coreutils/pwd.c index bb3ad04..05dee49 100644 --- a/coreutils/pwd.c +++ b/coreutils/pwd.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config PWD +//config: bool "pwd" +//config: default y +//config: help +//config: pwd is used to print the current directory. + +//applet:IF_PWD(APPLET_NOFORK(pwd, pwd, BB_DIR_BIN, BB_SUID_DROP, pwd)) + +//kbuild:lib-$(CONFIG_PWD) += pwd.o //usage:#define pwd_trivial_usage //usage: "" @@ -18,8 +27,6 @@ #include "libbb.h" -/* This is a NOFORK applet. Be very careful! */ - static int logical_getcwd(void) { struct stat st1; diff --git a/coreutils/readlink.c b/coreutils/readlink.c index d73ef4d..1b223b3 100644 --- a/coreutils/readlink.c +++ b/coreutils/readlink.c @@ -6,6 +6,23 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config READLINK +//config: bool "readlink" +//config: default y +//config: help +//config: This program reads a symbolic link and returns the name +//config: of the file it points to +//config: +//config:config FEATURE_READLINK_FOLLOW +//config: bool "Enable canonicalization by following all symlinks (-f)" +//config: default y +//config: depends on READLINK +//config: help +//config: Enable the readlink option (-f). + +//applet:IF_READLINK(APPLET(readlink, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_READLINK) += readlink.o //usage:#define readlink_trivial_usage //usage: IF_FEATURE_READLINK_FOLLOW("[-fnv] ") "FILE" diff --git a/coreutils/realpath.c b/coreutils/realpath.c index c513b55..0c2d544 100644 --- a/coreutils/realpath.c +++ b/coreutils/realpath.c @@ -1,7 +1,4 @@ /* vi: set sw=4 ts=4: */ - -/* BB_AUDIT SUSv3 N/A -- Apparently a busybox extension. */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Now does proper error checking on output and returns a failure exit code @@ -9,6 +6,18 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config REALPATH +//config: bool "realpath" +//config: default y +//config: help +//config: Return the canonicalized absolute pathname. +//config: This isn't provided by GNU shellutils, but where else does it belong. + +//applet:IF_REALPATH(APPLET(realpath, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_REALPATH) += realpath.o + +/* BB_AUDIT SUSv3 N/A -- Apparently a busybox extension. */ //usage:#define realpath_trivial_usage //usage: "FILE..." diff --git a/coreutils/rm.c b/coreutils/rm.c index 042fba1..cec34cb 100644 --- a/coreutils/rm.c +++ b/coreutils/rm.c @@ -6,14 +6,22 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 compliant */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/rm.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Size reduction. */ +//config:config RM +//config: bool "rm" +//config: default y +//config: help +//config: rm is used to remove files or directories. + +//applet:IF_RM(APPLET_NOFORK(rm, rm, BB_DIR_BIN, BB_SUID_DROP, rm)) + +//kbuild:lib-$(CONFIG_RM) += rm.o + +/* BB_AUDIT SUSv3 compliant */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/rm.html */ //usage:#define rm_trivial_usage //usage: "[-irf] FILE..." @@ -38,7 +46,6 @@ int rm_main(int argc UNUSED_PARAM, char **argv) unsigned opt; opt_complementary = "f-i:i-f"; - /* -v (verbose) is ignored */ opt = getopt32(argv, "fiRrv"); argv += optind; if (opt & 1) @@ -47,6 +54,8 @@ int rm_main(int argc UNUSED_PARAM, char **argv) flags |= FILEUTILS_INTERACTIVE; if (opt & (8|4)) flags |= FILEUTILS_RECUR; + if ((opt & 16) && FILEUTILS_VERBOSE) + flags |= FILEUTILS_VERBOSE; if (*argv != NULL) { do { diff --git a/coreutils/rmdir.c b/coreutils/rmdir.c index cc2dea0..8979941 100644 --- a/coreutils/rmdir.c +++ b/coreutils/rmdir.c @@ -6,6 +6,23 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config RMDIR +//config: bool "rmdir" +//config: default y +//config: help +//config: rmdir is used to remove empty directories. +//config: +//config:config FEATURE_RMDIR_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on RMDIR && LONG_OPTS +//config: help +//config: Support long options for the rmdir applet, including +//config: --ignore-fail-on-non-empty for compatibility with GNU rmdir. + +//applet:IF_RMDIR(APPLET_NOFORK(rmdir, rmdir, BB_DIR_BIN, BB_SUID_DROP, rmdir)) + +//kbuild:lib-$(CONFIG_RMDIR) += rmdir.o /* BB_AUDIT SUSv3 compliant */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/rmdir.html */ @@ -31,7 +48,7 @@ #define PARENTS (1 << 0) -//efine VERBOSE (1 << 1) //accepted but ignored +#define VERBOSE ((1 << 1) * ENABLE_FEATURE_VERBOSE) #define IGNORE_NON_EMPTY (1 << 2) int rmdir_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; @@ -44,10 +61,12 @@ int rmdir_main(int argc UNUSED_PARAM, char **argv) #if ENABLE_FEATURE_RMDIR_LONG_OPTIONS static const char rmdir_longopts[] ALIGN1 = "parents\0" No_argument "p" - "verbose\0" No_argument "v" /* Debian etch: many packages fail to be purged or installed * because they desperately want this option: */ "ignore-fail-on-non-empty\0" No_argument "\xff" + IF_FEATURE_VERBOSE( + "verbose\0" No_argument "v" + ) ; applet_long_options = rmdir_longopts; #endif @@ -62,6 +81,10 @@ int rmdir_main(int argc UNUSED_PARAM, char **argv) path = *argv; while (1) { + if (flags & VERBOSE) { + printf("rmdir: removing directory, '%s'\n", path); + } + if (rmdir(path) < 0) { #if ENABLE_FEATURE_RMDIR_LONG_OPTIONS if ((flags & IGNORE_NON_EMPTY) && errno == ENOTEMPTY) diff --git a/coreutils/seq.c b/coreutils/seq.c index 10dabe9..7388f79 100644 --- a/coreutils/seq.c +++ b/coreutils/seq.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2, see file LICENSE in this source tree. */ +//config:config SEQ +//config: bool "seq" +//config: default y +//config: help +//config: print a sequence of numbers + +//applet:IF_SEQ(APPLET_NOFORK(seq, seq, BB_DIR_USR_BIN, BB_SUID_DROP, seq)) + +//kbuild:lib-$(CONFIG_SEQ) += seq.o //usage:#define seq_trivial_usage //usage: "[-w] [-s SEP] [FIRST [INC]] LAST" diff --git a/coreutils/shuf.c b/coreutils/shuf.c new file mode 100644 index 0000000..9f61f2f --- a/dev/null +++ b/coreutils/shuf.c @@ -0,0 +1,153 @@ +/* vi: set sw=4 ts=4: */ +/* + * shuf: Write a random permutation of the input lines to standard output. + * + * Copyright (C) 2014 by Bartosz Golaszewski + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +//config:config SHUF +//config: bool "shuf" +//config: default y +//config: help +//config: Generate random permutations + +//kbuild:lib-$(CONFIG_SHUF) += shuf.o +//applet:IF_SHUF(APPLET_NOEXEC(shuf, shuf, BB_DIR_USR_BIN, BB_SUID_DROP, shuf)) + +//usage:#define shuf_trivial_usage +//usage: "[-e|-i L-H] [-n NUM] [-o FILE] [-z] [FILE|ARG...]" +//usage:#define shuf_full_usage "\n\n" +//usage: "Randomly permute lines\n" +//usage: "\n -e Treat ARGs as lines" +//usage: "\n -i L-H Treat numbers L-H as lines" +//usage: "\n -n NUM Output at most NUM lines" +//usage: "\n -o FILE Write to FILE, not standard output" +//usage: "\n -z End lines with zero byte, not newline" + +#include "libbb.h" + +/* This is a NOEXEC applet. Be very careful! */ + +#define OPT_e (1 << 0) +#define OPT_i (1 << 1) +#define OPT_n (1 << 2) +#define OPT_o (1 << 3) +#define OPT_z (1 << 4) +#define OPT_STR "ei:n:o:z" + +/* + * Use the Fisher-Yates shuffle algorithm on an array of lines. + */ +static void shuffle_lines(char **lines, unsigned numlines) +{ + unsigned i; + unsigned r; + char *tmp; + + srand(monotonic_us()); + + for (i = numlines-1; i > 0; i--) { + r = rand(); + /* RAND_MAX can be as small as 32767 */ + if (i > RAND_MAX) + r ^= rand() << 15; + r %= i; + tmp = lines[i]; + lines[i] = lines[r]; + lines[r] = tmp; + } +} + +int shuf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int shuf_main(int argc, char **argv) +{ + unsigned opts; + char *opt_i_str, *opt_n_str, *opt_o_str; + unsigned i; + char **lines; + unsigned numlines; + char eol; + + opt_complementary = "e--i:i--e"; /* mutually exclusive */ + opts = getopt32(argv, OPT_STR, &opt_i_str, &opt_n_str, &opt_o_str); + + argc -= optind; + argv += optind; + + /* Prepare lines for shuffling - either: */ + if (opts & OPT_e) { + /* make lines from command-line arguments */ + numlines = argc; + lines = argv; + } else + if (opts & OPT_i) { + /* create a range of numbers */ + char *dash; + unsigned lo, hi; + + dash = strchr(opt_i_str, '-'); + if (!dash) { + bb_error_msg_and_die("bad range '%s'", opt_i_str); + } + *dash = '\0'; + lo = xatou(opt_i_str); + hi = xatou(dash + 1); + *dash = '-'; + if (hi < lo) { + bb_error_msg_and_die("bad range '%s'", opt_i_str); + } + + numlines = (hi+1) - lo; + lines = xmalloc(numlines * sizeof(lines[0])); + for (i = 0; i < numlines; i++) { + lines[i] = (char*)(uintptr_t)lo; + lo++; + } + } else { + /* default - read lines from stdin or the input file */ + FILE *fp; + + if (argc > 1) + bb_show_usage(); + + fp = xfopen_stdin(argv[0] ? argv[0] : "-"); + lines = NULL; + numlines = 0; + for (;;) { + char *line = xmalloc_fgetline(fp); + if (!line) + break; + lines = xrealloc_vector(lines, 6, numlines); + lines[numlines++] = line; + } + fclose_if_not_stdin(fp); + } + + if (numlines != 0) + shuffle_lines(lines, numlines); + + if (opts & OPT_o) + xmove_fd(xopen(opt_o_str, O_WRONLY|O_CREAT|O_TRUNC), STDOUT_FILENO); + + if (opts & OPT_n) { + unsigned maxlines; + maxlines = xatou(opt_n_str); + if (numlines > maxlines) + numlines = maxlines; + } + + eol = '\n'; + if (opts & OPT_z) + eol = '\0'; + + for (i = 0; i < numlines; i++) { + if (opts & OPT_i) + printf("%u%c", (unsigned)(uintptr_t)lines[i], eol); + else + printf("%s%c", lines[i], eol); + } + + fflush_stdout_and_exit(EXIT_SUCCESS); +} diff --git a/coreutils/sleep.c b/coreutils/sleep.c index 0ffbd16..ad2d6b5 100644 --- a/coreutils/sleep.c +++ b/coreutils/sleep.c @@ -6,17 +6,48 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 compliant */ -/* BB_AUDIT GNU issues -- fancy version matches except args must be ints. */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/sleep.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Rewritten to do proper arg and error checking. * Also, added a 'fancy' configuration to accept multiple args with * time suffixes for seconds, minutes, hours, and days. */ +//config:config SLEEP +//config: bool "sleep" +//config: default y +//config: help +//config: sleep is used to pause for a specified number of seconds. +//config: It comes in 3 versions: +//config: - small: takes one integer parameter +//config: - fancy: takes multiple integer arguments with suffixes: +//config: sleep 1d 2h 3m 15s +//config: - fancy with fractional numbers: +//config: sleep 2.3s 4.5h sleeps for 16202.3 seconds +//config: Last one is "the most compatible" with coreutils sleep, +//config: but it adds around 1k of code. +//config: +//config:config FEATURE_FANCY_SLEEP +//config: bool "Enable multiple arguments and s/m/h/d suffixes" +//config: default y +//config: depends on SLEEP +//config: help +//config: Allow sleep to pause for specified minutes, hours, and days. +//config: +//config:config FEATURE_FLOAT_SLEEP +//config: bool "Enable fractional arguments" +//config: default y +//config: depends on FEATURE_FANCY_SLEEP +//config: help +//config: Allow for fractional numeric parameters. + +/* Do not make this applet NOFORK. It breaks ^C-ing of pauses in shells */ +//applet:IF_SLEEP(APPLET(sleep, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SLEEP) += sleep.o + +/* BB_AUDIT SUSv3 compliant */ +/* BB_AUDIT GNU issues -- fancy version matches except args must be ints. */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/sleep.html */ //usage:#define sleep_trivial_usage //usage: IF_FEATURE_FANCY_SLEEP("[") "N" IF_FEATURE_FANCY_SLEEP("]...") @@ -35,9 +66,6 @@ #include "libbb.h" -/* Do not make this applet NOFORK. It breaks ^C-ing of pauses in shells */ - - #if ENABLE_FEATURE_FANCY_SLEEP || ENABLE_FEATURE_FLOAT_SLEEP static const struct suffix_mult sfx[] = { { "s", 1 }, diff --git a/coreutils/sort.c b/coreutils/sort.c index d78dba2..64b85e1 100644 --- a/coreutils/sort.c +++ b/coreutils/sort.c @@ -11,28 +11,49 @@ * See SuS3 sort standard at: * http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html */ +//config:config SORT +//config: bool "sort" +//config: default y +//config: help +//config: sort is used to sort lines of text in specified files. +//config: +//config:config FEATURE_SORT_BIG +//config: bool "Full SuSv3 compliant sort (support -ktcsbdfiozgM)" +//config: default y +//config: depends on SORT +//config: help +//config: Without this, sort only supports -r, -u, and an integer version +//config: of -n. Selecting this adds sort keys, floating point support, and +//config: more. This adds a little over 3k to a nonstatic build on x86. +//config: +//config: The SuSv3 sort standard is available at: +//config: http://www.opengroup.org/onlinepubs/007904975/utilities/sort.html + +//applet:IF_SORT(APPLET_NOEXEC(sort, sort, BB_DIR_USR_BIN, BB_SUID_DROP, sort)) + +//kbuild:lib-$(CONFIG_SORT) += sort.o //usage:#define sort_trivial_usage //usage: "[-nru" -//usage: IF_FEATURE_SORT_BIG("gMcszbdfimSTokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR") +//usage: IF_FEATURE_SORT_BIG("gMcszbdfiokt] [-o FILE] [-k start[.offset][opts][,end[.offset][opts]] [-t CHAR") //usage: "] [FILE]..." //usage:#define sort_full_usage "\n\n" //usage: "Sort lines of text\n" //usage: IF_FEATURE_SORT_BIG( -//usage: "\n -b Ignore leading blanks" +//usage: "\n -o FILE Output to FILE" //usage: "\n -c Check whether input is sorted" -//usage: "\n -d Dictionary order (blank or alphanumeric only)" +//usage: "\n -b Ignore leading blanks" //usage: "\n -f Ignore case" -//usage: "\n -g General numerical sort" //usage: "\n -i Ignore unprintable characters" -//usage: "\n -k Sort key" +//usage: "\n -d Dictionary order (blank or alphanumeric only)" +//usage: "\n -g General numerical sort" //usage: "\n -M Sort month" //usage: ) +//-h, --human-numeric-sort: compare human readable numbers (e.g., 2K 1G) //usage: "\n -n Sort numbers" //usage: IF_FEATURE_SORT_BIG( -//usage: "\n -o Output to file" -//usage: "\n -k Sort by key" -//usage: "\n -t CHAR Key separator" +//usage: "\n -t CHAR Field separator" +//usage: "\n -k N[,M] Sort by Nth field" //usage: ) //usage: "\n -r Reverse sort order" //usage: IF_FEATURE_SORT_BIG( @@ -41,7 +62,10 @@ //usage: "\n -u Suppress duplicate lines" //usage: IF_FEATURE_SORT_BIG( //usage: "\n -z Lines are terminated by NUL, not newline" -//usage: "\n -mST Ignored for GNU compatibility") +////usage: "\n -m Ignored for GNU compatibility" +////usage: "\n -S BUFSZ Ignored for GNU compatibility" +////usage: "\n -T TMPDIR Ignored for GNU compatibility" +//usage: ) //usage: //usage:#define sort_example_usage //usage: "$ echo -e \"e\\nf\\nb\\nd\\nc\\na\" | sort\n" @@ -70,7 +94,7 @@ */ /* These are sort types */ -static const char OPT_STR[] ALIGN1 = "ngMucszbrdfimS:T:o:k:t:"; +static const char OPT_STR[] ALIGN1 = "ngMucszbrdfimS:T:o:k:*t:"; enum { FLAG_n = 1, /* Numeric sort */ FLAG_g = 2, /* Sort using strtod() */ @@ -106,7 +130,9 @@ static struct sort_key { static char *get_key(char *str, struct sort_key *key, int flags) { - int start = 0, end = 0, len, j; + int start = start; /* for compiler */ + int end; + int len, j; unsigned i; /* Special case whole string, so we don't have to make a copy */ @@ -123,12 +149,15 @@ static char *get_key(char *str, struct sort_key *key, int flags) end = len; /* Loop through fields */ else { + unsigned char ch = 0; + end = 0; for (i = 1; i < key->range[2*j] + j; i++) { if (key_separator) { /* Skip body of key and separator */ - while (str[end]) { - if (str[end++] == key_separator) + while ((ch = str[end]) != '\0') { + end++; + if (ch == key_separator) break; } } else { @@ -136,34 +165,44 @@ static char *get_key(char *str, struct sort_key *key, int flags) while (isspace(str[end])) end++; /* Skip body of key */ - while (str[end]) { + while (str[end] != '\0') { if (isspace(str[end])) break; end++; } } } + /* Remove last delim: "abc:def:" => "abc:def" */ + if (j && ch) { + //if (str[end-1] != key_separator) + // bb_error_msg(_and_die("BUG! " + // "str[start:%d,end:%d]:'%.*s'", + // start, end, (int)(end-start), &str[start]); + end--; + } } if (!j) start = end; } /* Strip leading whitespace if necessary */ -//XXX: skip_whitespace() if (flags & FLAG_b) + /* not using skip_whitespace() for speed */ 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 */ + /* -kSTART,N.ENDCHAR: honor ENDCHAR (1-based) */ if (key->range[3]) { - end += key->range[3] - 1; + end = key->range[3]; if (end > len) end = len; } + /* -kN.STARTCHAR[,...]: honor STARTCHAR (1-based) */ if (key->range[1]) { start += key->range[1] - 1; if (start > len) start = len; } /* Make the copy */ - if (end < start) end = start; + if (end < start) + end = start; str = xstrndup(str+start, end-start); /* Handle -d */ if (flags & FLAG_d) { @@ -225,7 +264,7 @@ static int compare_keys(const void *xarg, const void *yarg) y = *(char **)yarg; #endif /* Perform actual comparison */ - switch (flags & 7) { + switch (flags & (FLAG_n | FLAG_M | FLAG_g)) { default: bb_error_msg_and_die("unknown sort type"); break; @@ -277,7 +316,7 @@ static int compare_keys(const void *xarg, const void *yarg) else if (!yy) retval = 1; else - retval = (dx == thyme.tm_mon) ? 0 : dx - thyme.tm_mon; + retval = dx - thyme.tm_mon; break; } /* Full floating point version of -n */ @@ -302,10 +341,14 @@ static int compare_keys(const void *xarg, const void *yarg) } /* for */ /* Perform fallback sort if necessary */ - if (!retval && !(option_mask32 & FLAG_s)) + if (!retval && !(option_mask32 & FLAG_s)) { + flags = option_mask32; retval = strcmp(*(char **)xarg, *(char **)yarg); + } + + if (flags & FLAG_r) + return -retval; - if (flags & FLAG_r) return -retval; return retval; } @@ -328,7 +371,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv) char *line, **lines; char *str_ignored, *str_o, *str_t; llist_t *lst_k = NULL; - int i, flag; + int i; int linecount; unsigned opts; @@ -336,8 +379,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv) /* Parse command line options */ /* -o and -t can be given at most once */ - opt_complementary = "o--o:t--t:" /* -t, -o: at most one of each */ - "k::"; /* -k takes list */ + opt_complementary = "o--o:t--t"; /* -t, -o: at most one of each */ opts = getopt32(argv, OPT_STR, &str_ignored, &str_ignored, &str_o, &lst_k, &str_t); /* global b strips leading and trailing spaces */ if (opts & FLAG_b) @@ -351,7 +393,7 @@ int sort_main(int argc UNUSED_PARAM, char **argv) /* note: below this point we use option_mask32, not opts, * since that reduces register pressure and makes code smaller */ - /* parse sort key */ + /* Parse sort key */ while (lst_k) { enum { FLAG_allowed_for_k = @@ -378,17 +420,18 @@ int sort_main(int argc UNUSED_PARAM, char **argv) key->range[2*i+1] = str2u(&str_k); } while (*str_k) { - const char *temp2; + int flag; + const char *idx; if (*str_k == ',' && !i++) { str_k++; break; } /* no else needed: fall through to syntax error because comma isn't in OPT_STR */ - temp2 = strchr(OPT_STR, *str_k); - if (!temp2) + idx = strchr(OPT_STR, *str_k); + if (!idx) bb_error_msg_and_die("unknown key option"); - flag = 1 << (temp2 - OPT_STR); + flag = 1 << (idx - OPT_STR); if (flag & ~FLAG_allowed_for_k) bb_error_msg_and_die("unknown sort type"); /* b after ',' means strip _trailing_ space */ @@ -422,10 +465,10 @@ int sort_main(int argc UNUSED_PARAM, char **argv) } while (*++argv); #if ENABLE_FEATURE_SORT_BIG - /* if no key, perform alphabetic sort */ + /* If no key, perform alphabetic sort */ if (!key_list) add_key()->range[0] = 1; - /* handle -c */ + /* Handle -c */ if (option_mask32 & FLAG_c) { int j = (option_mask32 & FLAG_u) ? -1 : 0; for (i = 1; i < linecount; i++) { @@ -439,20 +482,21 @@ int sort_main(int argc UNUSED_PARAM, char **argv) #endif /* Perform the actual sort */ qsort(lines, linecount, sizeof(lines[0]), compare_keys); - /* handle -u */ + + /* Handle -u */ if (option_mask32 & FLAG_u) { - flag = 0; + int j = 0; /* coreutils 6.3 drop lines for which only key is the same */ /* -- disabling last-resort compare... */ option_mask32 |= FLAG_s; for (i = 1; i < linecount; i++) { - if (compare_keys(&lines[flag], &lines[i]) == 0) + if (compare_keys(&lines[j], &lines[i]) == 0) free(lines[i]); else - lines[++flag] = lines[i]; + lines[++j] = lines[i]; } if (linecount) - linecount = flag+1; + linecount = j+1; } /* Print it */ @@ -461,9 +505,11 @@ int sort_main(int argc UNUSED_PARAM, char **argv) if (option_mask32 & FLAG_o) xmove_fd(xopen3(str_o, O_WRONLY|O_CREAT|O_TRUNC, 0666), STDOUT_FILENO); #endif - flag = (option_mask32 & FLAG_z) ? '\0' : '\n'; - for (i = 0; i < linecount; i++) - printf("%s%c", lines[i], flag); + { + int ch = (option_mask32 & FLAG_z) ? '\0' : '\n'; + for (i = 0; i < linecount; i++) + printf("%s%c", lines[i], ch); + } fflush_stdout_and_exit(EXIT_SUCCESS); } diff --git a/coreutils/split.c b/coreutils/split.c index 1e1673e..50918a1 100644 --- a/coreutils/split.c +++ b/coreutils/split.c @@ -5,6 +5,25 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SPLIT +//config: bool "split" +//config: default y +//config: help +//config: split a file into pieces. +//config: +//config:config FEATURE_SPLIT_FANCY +//config: bool "Fancy extensions" +//config: default y +//config: depends on SPLIT +//config: help +//config: Add support for features not required by SUSv3. +//config: Supports additional suffixes 'b' for 512 bytes, +//config: 'g' for 1GiB for the -b option. + +//applet:IF_SPLIT(APPLET(split, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SPLIT) += split.o + /* BB_AUDIT: SUSv3 compliant * SUSv3 requirements: * http://www.opengroup.org/onlinepubs/009695399/utilities/split.html @@ -22,6 +41,7 @@ //usage: "$ cat TODO | split -a 2 -l 2 TODO_\n" #include "libbb.h" +#include "common_bufsiz.h" #if ENABLE_FEATURE_SPLIT_FANCY static const struct suffix_mult split_suffixes[] = { @@ -78,8 +98,10 @@ int split_main(int argc UNUSED_PARAM, char **argv) ssize_t bytes_read, to_write; char *src; - opt_complementary = "?2:a+"; /* max 2 args; -a N */ - opt = getopt32(argv, "l:b:a:", &count_p, &count_p, &suffix_len); + setup_common_bufsiz(); + + opt_complementary = "?2"; /* max 2 args; -a N */ + opt = getopt32(argv, "l:b:a:+", &count_p, &count_p, &suffix_len); if (opt & SPLIT_OPT_l) cnt = XATOOFF(count_p); diff --git a/coreutils/stat.c b/coreutils/stat.c index 769fac0..b918ec6 100644 --- a/coreutils/stat.c +++ b/coreutils/stat.c @@ -12,54 +12,86 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config STAT +//config: bool "stat" +//config: default y +//config: help +//config: display file or filesystem status. +//config: +//config:config FEATURE_STAT_FORMAT +//config: bool "Enable custom formats (-c)" +//config: default y +//config: depends on STAT +//config: help +//config: Without this, stat will not support the '-c format' option where +//config: users can pass a custom format string for output. This adds about +//config: 7k to a nonstatic build on amd64. +//config: +//config:config FEATURE_STAT_FILESYSTEM +//config: bool "Enable display of filesystem status (-f)" +//config: default y +//config: depends on STAT +//config: select PLATFORM_LINUX # statfs() +//config: help +//config: Without this, stat will not support the '-f' option to display +//config: information about filesystem status. + +//applet:IF_STAT(APPLET(stat, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_STAT) += stat.o //usage:#define stat_trivial_usage //usage: "[OPTIONS] FILE..." //usage:#define stat_full_usage "\n\n" -//usage: "Display file (default) or filesystem status\n" +//usage: "Display file" +//usage: IF_FEATURE_STAT_FILESYSTEM(" (default) or filesystem") +//usage: " status\n" //usage: IF_FEATURE_STAT_FORMAT( -//usage: "\n -c fmt Use the specified format" +//usage: "\n -c FMT Use the specified format" //usage: ) +//usage: IF_FEATURE_STAT_FILESYSTEM( //usage: "\n -f Display filesystem status" +//usage: ) //usage: "\n -L Follow links" -//usage: "\n -t Display info in terse form" +//usage: "\n -t Terse display" //usage: IF_SELINUX( //usage: "\n -Z Print security context" //usage: ) //usage: IF_FEATURE_STAT_FORMAT( -//usage: "\n\nValid format sequences for files:\n" +//usage: "\n\nFMT sequences"IF_FEATURE_STAT_FILESYSTEM(" for files")":\n" //usage: " %a Access rights in octal\n" //usage: " %A Access rights in human readable form\n" //usage: " %b Number of blocks allocated (see %B)\n" -//usage: " %B The size in bytes of each block reported by %b\n" +//usage: " %B Size in bytes of each block reported by %b\n" //usage: " %d Device number in decimal\n" //usage: " %D Device number in hex\n" //usage: " %f Raw mode in hex\n" //usage: " %F File type\n" -//usage: " %g Group ID of owner\n" -//usage: " %G Group name of owner\n" +//usage: " %g Group ID\n" +//usage: " %G Group name\n" //usage: " %h Number of hard links\n" //usage: " %i Inode number\n" //usage: " %n File name\n" //usage: " %N File name, with -> TARGET if symlink\n" //usage: " %o I/O block size\n" -//usage: " %s Total size, in bytes\n" +//usage: " %s Total size in bytes\n" //usage: " %t Major device type in hex\n" //usage: " %T Minor device type in hex\n" -//usage: " %u User ID of owner\n" -//usage: " %U User name of owner\n" +//usage: " %u User ID\n" +//usage: " %U User name\n" //usage: " %x Time of last access\n" //usage: " %X Time of last access as seconds since Epoch\n" //usage: " %y Time of last modification\n" //usage: " %Y Time of last modification as seconds since Epoch\n" //usage: " %z Time of last change\n" //usage: " %Z Time of last change as seconds since Epoch\n" -//usage: "\nValid format sequences for file systems:\n" +//usage: IF_FEATURE_STAT_FILESYSTEM( +//usage: "\nFMT sequences for file systems:\n" //usage: " %a Free blocks available to non-superuser\n" -//usage: " %b Total data blocks in file system\n" -//usage: " %c Total file nodes in file system\n" -//usage: " %d Free file nodes in file system\n" -//usage: " %f Free blocks in file system\n" +//usage: " %b Total data blocks\n" +//usage: " %c Total file nodes\n" +//usage: " %d Free file nodes\n" +//usage: " %f Free blocks\n" //usage: IF_SELINUX( //usage: " %C Security context in selinux\n" //usage: ) @@ -71,13 +103,17 @@ //usage: " %t Type in hex\n" //usage: " %T Type in human readable form" //usage: ) +//usage: ) #include "libbb.h" +#include "common_bufsiz.h" -#define OPT_FILESYS (1 << 0) -#define OPT_TERSE (1 << 1) -#define OPT_DEREFERENCE (1 << 2) -#define OPT_SELINUX (1 << 3) +enum { + OPT_TERSE = (1 << 0), + OPT_DEREFERENCE = (1 << 1), + OPT_FILESYS = (1 << 2) * ENABLE_FEATURE_STAT_FILESYSTEM, + OPT_SELINUX = (1 << (2+ENABLE_FEATURE_STAT_FILESYSTEM)) * ENABLE_SELINUX, +}; #if ENABLE_FEATURE_STAT_FORMAT typedef bool (*statfunc_ptr)(const char *, const char *); @@ -126,12 +162,13 @@ static const char *human_time(time_t t) /*static char buf[sizeof("YYYY-MM-DD HH:MM:SS.000000000")] ALIGN1;*/ #define buf bb_common_bufsiz1 - - strcpy(strftime_YYYYMMDDHHMMSS(buf, sizeof(buf), &t), ".000000000"); + setup_common_bufsiz(); + strcpy(strftime_YYYYMMDDHHMMSS(buf, COMMON_BUFSIZE, &t), ".000000000"); return buf; #undef buf } +#if ENABLE_FEATURE_STAT_FILESYSTEM /* 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) @@ -202,6 +239,7 @@ static unsigned long long get_f_fsid(const struct statfs *statfsbuf) while (--sz > 0); return r; } +#endif /* FEATURE_STAT_FILESYSTEM */ #if ENABLE_FEATURE_STAT_FORMAT static void strcatc(char *str, char c) @@ -217,6 +255,7 @@ static void printfs(char *pformat, const char *msg) printf(pformat, msg); } +#if ENABLE_FEATURE_STAT_FILESYSTEM /* print statfs info */ static void FAST_FUNC print_statfs(char *pformat, const char m, const char *const filename, const void *data @@ -263,6 +302,7 @@ static void FAST_FUNC print_statfs(char *pformat, const char m, printf(pformat, m); } } +#endif /* print stat info */ static void FAST_FUNC print_stat(char *pformat, const char m, @@ -374,7 +414,7 @@ static void print_it(const char *masterformat, { /* Create a working copy of the format string */ char *format = xstrdup(masterformat); - /* Add 2 to accomodate our conversion of the stat '%s' format string + /* Add 2 to accommodate our conversion of the stat '%s' format string * to the printf '%llu' one. */ char *dest = xmalloc(strlen(format) + 2 + 1); char *b; @@ -423,6 +463,7 @@ static void print_it(const char *masterformat, } #endif /* FEATURE_STAT_FORMAT */ +#if ENABLE_FEATURE_STAT_FILESYSTEM /* Stat the file system and print what we find. */ #if !ENABLE_FEATURE_STAT_FORMAT #define do_statfs(filename, format) do_statfs(filename) @@ -538,6 +579,7 @@ static bool do_statfs(const char *filename, const char *format) #endif /* FEATURE_STAT_FORMAT */ return 1; } +#endif /* FEATURE_STAT_FILESYSTEM */ /* stat the file and print what we find */ #if !ENABLE_FEATURE_STAT_FORMAT @@ -721,12 +763,15 @@ int stat_main(int argc UNUSED_PARAM, char **argv) statfunc_ptr statfunc = do_stat; opt_complementary = "-1"; /* min one arg */ - opts = getopt32(argv, "ftL" + opts = getopt32(argv, "tL" + IF_FEATURE_STAT_FILESYSTEM("f") IF_SELINUX("Z") IF_FEATURE_STAT_FORMAT("c:", &format) ); +#if ENABLE_FEATURE_STAT_FILESYSTEM if (opts & OPT_FILESYS) /* -f */ statfunc = do_statfs; +#endif #if ENABLE_SELINUX if (opts & OPT_SELINUX) { selinux_or_die(); diff --git a/coreutils/stty.c b/coreutils/stty.c index 378a848..e818d57 100644 --- a/coreutils/stty.c +++ b/coreutils/stty.c @@ -18,8 +18,16 @@ David MacKenzie Special for busybox ported by Vladimir Oleynik 2001 +*/ +//config:config STTY +//config: bool "stty" +//config: default y +//config: help +//config: stty is used to change and print terminal line settings. + +//applet:IF_STTY(APPLET(stty, BB_DIR_BIN, BB_SUID_DROP)) - */ +//kbuild:lib-$(CONFIG_STTY) += stty.o //usage:#define stty_trivial_usage //usage: "[-a|g] [-F DEVICE] [SETTING]..." @@ -32,6 +40,7 @@ //usage: "\n [SETTING] See manpage" #include "libbb.h" +#include "common_bufsiz.h" #ifndef _POSIX_VDISABLE # define _POSIX_VDISABLE ((unsigned char) 0) @@ -317,7 +326,7 @@ enum { #define MI_ENTRY(N,T,F,B,M) N "\0" /* Mode names given on command line */ -static const char mode_name[] = +static const char mode_name[] ALIGN1 = MI_ENTRY("evenp", combination, REV | OMIT, 0, 0 ) MI_ENTRY("parity", combination, REV | OMIT, 0, 0 ) MI_ENTRY("oddp", combination, REV | OMIT, 0, 0 ) @@ -680,7 +689,7 @@ enum { #define CI_ENTRY(n,s,o) n "\0" /* Name given on command line */ -static const char control_name[] = +static const char control_name[] ALIGN1 = CI_ENTRY("intr", CINTR, VINTR ) CI_ENTRY("quit", CQUIT, VQUIT ) CI_ENTRY("erase", CERASE, VERASE ) @@ -722,7 +731,7 @@ static const char control_name[] = #undef CI_ENTRY #define CI_ENTRY(n,s,o) { s, o }, -static const struct control_info control_info[] = { +static const struct control_info control_info[] ALIGN2 = { /* This should be verbatim cut-n-paste copy of the above CI_ENTRYs */ CI_ENTRY("intr", CINTR, VINTR ) CI_ENTRY("quit", CQUIT, VQUIT ) @@ -775,7 +784,7 @@ struct globals { unsigned current_col; char buf[10]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define INIT_G() do { \ G.device_name = bb_msg_standard_input; \ G.max_col = 80; \ @@ -1403,7 +1412,7 @@ int stty_main(int argc UNUSED_PARAM, char **argv) perror_on_device_and_die("%s"); if (stty_state & (STTY_verbose_output | STTY_recoverable_output | STTY_noargs)) { - get_terminal_width_height(STDOUT_FILENO, &G.max_col, NULL); + G.max_col = get_terminal_width(STDOUT_FILENO); output_func(&mode, display_all); return EXIT_SUCCESS; } diff --git a/coreutils/sum.c b/coreutils/sum.c index deb068e..c55293d 100644 --- a/coreutils/sum.c +++ b/coreutils/sum.c @@ -12,6 +12,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SUM +//config: bool "sum" +//config: default y +//config: help +//config: checksum and count the blocks in a file + +//applet:IF_SUM(APPLET(sum, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_SUM) += sum.o //usage:#define sum_trivial_usage //usage: "[-rs] [FILE]..." @@ -21,6 +30,7 @@ //usage: "\n -s Use System V sum algorithm (512byte blocks)" #include "libbb.h" +#include "common_bufsiz.h" enum { SUM_BSD, PRINT_NAME, SUM_SYSV }; @@ -30,18 +40,20 @@ enum { SUM_BSD, PRINT_NAME, SUM_SYSV }; /* Return 1 if successful. */ static unsigned sum_file(const char *file, unsigned type) { -#define buf bb_common_bufsiz1 unsigned long long total_bytes = 0; int fd, r; /* The sum of all the input bytes, modulo (UINT_MAX + 1). */ unsigned s = 0; +#define buf bb_common_bufsiz1 + setup_common_bufsiz(); + fd = open_or_warn_stdin(file); if (fd == -1) return 0; while (1) { - size_t bytes_read = safe_read(fd, buf, BUFSIZ); + size_t bytes_read = safe_read(fd, buf, COMMON_BUFSIZE); if ((ssize_t)bytes_read <= 0) { r = (fd && close(fd) != 0); diff --git a/coreutils/sync.c b/coreutils/sync.c index 7d98a1e..1a5aae5 100644 --- a/coreutils/sync.c +++ b/coreutils/sync.c @@ -3,16 +3,40 @@ * Mini sync implementation for busybox * * Copyright (C) 1995, 1996 by Bruce Perens . + * Copyright (C) 2015 by Ari Sundholm * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config SYNC +//config: bool "sync" +//config: default y +//config: help +//config: sync is used to flush filesystem buffers. +//config:config FEATURE_SYNC_FANCY +//config: bool "Enable -d and -f flags (requires syncfs(2) in libc)" +//config: default y +//config: depends on SYNC +//config: help +//config: sync -d FILE... executes fdatasync() on each FILE. +//config: sync -f FILE... executes syncfs() on each FILE. + +//applet:IF_SYNC(APPLET_NOFORK(sync, sync, BB_DIR_BIN, BB_SUID_DROP, sync)) + +//kbuild:lib-$(CONFIG_SYNC) += sync.o /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ //usage:#define sync_trivial_usage -//usage: "" +//usage: ""IF_FEATURE_SYNC_FANCY("[-df] [FILE]...") //usage:#define sync_full_usage "\n\n" +//usage: IF_NOT_FEATURE_SYNC_FANCY( //usage: "Write all buffered blocks to disk" +//usage: ) +//usage: IF_FEATURE_SYNC_FANCY( +//usage: "Write all buffered blocks (in FILEs) to disk" +//usage: "\n -d Avoid syncing metadata" +//usage: "\n -f Sync filesystems underlying FILEs" +//usage: ) #include "libbb.h" diff --git a/coreutils/tac.c b/coreutils/tac.c index 94d669d..ca5617c 100644 --- a/coreutils/tac.c +++ b/coreutils/tac.c @@ -1,20 +1,26 @@ /* vi: set sw=4 ts=4: */ /* * tac implementation for busybox + * tac - concatenate and print files in reverse * * Copyright (C) 2003 Yang Xiaopeng * Copyright (C) 2007 Natanael Copa * Copyright (C) 2007 Tito Ragusa * * Licensed under GPLv2, see file LICENSE in this source tree. - * */ - -/* tac - concatenate and print files in reverse */ - /* Based on Yang Xiaopeng's (yxp at hanwang.com.cn) patch * http://www.uclibc.org/lists/busybox/2003-July/008813.html */ +//config:config TAC +//config: bool "tac" +//config: default y +//config: help +//config: tac is used to concatenate and print files in reverse. + +//applet:IF_TAC(APPLET_NOEXEC(tac, tac, BB_DIR_USR_BIN, BB_SUID_DROP, tac)) + +//kbuild:lib-$(CONFIG_TAC) += tac.o //usage:#define tac_trivial_usage //usage: "[FILE]..." diff --git a/coreutils/tail.c b/coreutils/tail.c index 0e12443..406edf8 100644 --- a/coreutils/tail.c +++ b/coreutils/tail.c @@ -6,11 +6,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 compliant (need fancy for -c) */ -/* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/tail.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Pretty much rewritten to fix numerous bugs and reduce realloc() calls. @@ -23,24 +18,48 @@ * 6) no check for lseek error * 7) lseek attempted when count==0 even if arg was +0 (from top) */ +//config:config TAIL +//config: bool "tail" +//config: default y +//config: help +//config: tail is used to print the last specified number of lines +//config: from files. +//config: +//config:config FEATURE_FANCY_TAIL +//config: bool "Enable extra tail options (-q, -s, -v, and -F)" +//config: default y +//config: depends on TAIL +//config: help +//config: The options (-q, -s, -v and -F) are provided by GNU tail, but +//config: are not specific in the SUSv3 standard. +//config: +//config: -q Never output headers giving file names +//config: -s SEC Wait SEC seconds between reads with -f +//config: -v Always output headers giving file names +//config: -F Same as -f, but keep retrying + +//applet:IF_TAIL(APPLET(tail, BB_DIR_USR_BIN, BB_SUID_DROP)) //kbuild:lib-$(CONFIG_TAIL) += tail.o +/* BB_AUDIT SUSv3 compliant (need fancy for -c) */ +/* BB_AUDIT GNU compatible -c, -q, and -v options in 'fancy' configuration. */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/tail.html */ + //usage:#define tail_trivial_usage //usage: "[OPTIONS] [FILE]..." //usage:#define tail_full_usage "\n\n" //usage: "Print last 10 lines of each FILE (or stdin) to stdout.\n" //usage: "With more than one FILE, precede each with a filename header.\n" //usage: "\n -f Print data as file grows" -//usage: IF_FEATURE_FANCY_TAIL( -//usage: "\n -s SECONDS Wait SECONDS between reads with -f" -//usage: ) +//usage: "\n -c [+]N[kbm] Print last N bytes" //usage: "\n -n N[kbm] Print last N lines" //usage: "\n -n +N[kbm] Start on Nth line and print the rest" //usage: IF_FEATURE_FANCY_TAIL( -//usage: "\n -c [+]N[kbm] Print last N bytes" //usage: "\n -q Never print headers" +//usage: "\n -s SECONDS Wait SECONDS between reads with -f" //usage: "\n -v Always print headers" +//usage: "\n -F Same as -f, but keep retrying" //usage: "\n" //usage: "\nN may be suffixed by k (x1024), b (x512), or m (x1024^2)." //usage: ) @@ -50,13 +69,14 @@ //usage: "nameserver 10.0.0.1\n" #include "libbb.h" +#include "common_bufsiz.h" struct globals { bool from_top; bool exitcode; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) -#define INIT_G() do { } while (0) +#define G (*(struct globals*)bb_common_bufsiz1) +#define INIT_G() do { setup_common_bufsiz(); } while (0) static void tail_xprint_header(const char *fmt, const char *filename) { @@ -121,8 +141,8 @@ int tail_main(int argc, char **argv) #endif /* -s NUM, -F imlies -f */ - IF_FEATURE_FANCY_TAIL(opt_complementary = "s+:Ff";) - opt = getopt32(argv, "fc:n:" IF_FEATURE_FANCY_TAIL("qs:vF"), + IF_FEATURE_FANCY_TAIL(opt_complementary = "Ff";) + opt = getopt32(argv, "fc:n:" IF_FEATURE_FANCY_TAIL("qs:+vF"), &str_c, &str_n IF_FEATURE_FANCY_TAIL(,&sleep_period)); #define FOLLOW (opt & 0x1) #define COUNT_BYTES (opt & 0x2) diff --git a/coreutils/tee.c b/coreutils/tee.c index 48cc050..602d067 100644 --- a/coreutils/tee.c +++ b/coreutils/tee.c @@ -6,6 +6,23 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config TEE +//config: bool "tee" +//config: default y +//config: help +//config: tee is used to read from standard input and write +//config: to standard output and files. +//config: +//config:config FEATURE_TEE_USE_BLOCK_IO +//config: bool "Enable block I/O (larger/faster) instead of byte I/O" +//config: default y +//config: depends on TEE +//config: help +//config: Enable this option for a faster tee, at expense of size. + +//applet:IF_TEE(APPLET(tee, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_TEE) += tee.o /* BB_AUDIT SUSv3 compliant */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/tee.html */ @@ -23,6 +40,7 @@ //usage: "Hello\n" #include "libbb.h" +#include "common_bufsiz.h" int tee_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int tee_main(int argc, char **argv) @@ -37,6 +55,7 @@ int tee_main(int argc, char **argv) #if ENABLE_FEATURE_TEE_USE_BLOCK_IO ssize_t c; # define buf bb_common_bufsiz1 + setup_common_bufsiz(); #else int c; #endif @@ -79,7 +98,7 @@ int tee_main(int argc, char **argv) /* names[0] will be filled later */ #if ENABLE_FEATURE_TEE_USE_BLOCK_IO - while ((c = safe_read(STDIN_FILENO, buf, sizeof(buf))) > 0) { + while ((c = safe_read(STDIN_FILENO, buf, COMMON_BUFSIZE)) > 0) { fp = files; do fwrite(buf, 1, c, *fp); diff --git a/coreutils/test.c b/coreutils/test.c index 92a210f..2c1e624 100644 --- a/coreutils/test.c +++ b/coreutils/test.c @@ -19,11 +19,6 @@ * Original copyright notice states: * "This program is in the Public Domain." */ - -//kbuild:lib-$(CONFIG_TEST) += test.o test_ptr_hack.o -//kbuild:lib-$(CONFIG_ASH) += test.o test_ptr_hack.o -//kbuild:lib-$(CONFIG_HUSH) += test.o test_ptr_hack.o - //config:config TEST //config: bool "test" //config: default y @@ -32,21 +27,40 @@ //config: returning an appropriate exit code. The bash shell //config: has test built in, ash can build it in optionally. //config: +//config:config TEST1 +//config: bool "test as [" +//config: default y +//config: help +//config: Provide test command in the "[ EXPR ]" form +//config: +//config:config TEST2 +//config: bool "test as [[" +//config: default y +//config: help +//config: Provide test command in the "[[ EXPR ]]" form +//config: //config:config FEATURE_TEST_64 //config: bool "Extend test to 64 bit" //config: default y -//config: depends on TEST || ASH_BUILTIN_TEST || HUSH +//config: depends on TEST || TEST1 || TEST2 || ASH_BUILTIN_TEST || HUSH //config: help //config: Enable 64-bit support in test. -/* "test --help" does not print help (POSIX compat), only "[ --help" does. - * We display " EXPRESSION ]" here (not " EXPRESSION") - * Unfortunately, it screws up generated BusyBox.html. TODO. */ -//usage:#define test_trivial_usage -//usage: "EXPRESSION ]" -//usage:#define test_full_usage "\n\n" -//usage: "Check file types, compare values etc. Return a 0/1 exit code\n" -//usage: "depending on logical value of EXPRESSION" +//applet:IF_TEST(APPLET_NOFORK(test, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) +//applet:IF_TEST1(APPLET_NOFORK([, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) +//applet:IF_TEST2(APPLET_NOFORK([[, test, BB_DIR_USR_BIN, BB_SUID_DROP, test)) + +//kbuild:lib-$(CONFIG_TEST) += test.o test_ptr_hack.o +//kbuild:lib-$(CONFIG_TEST1) += test.o test_ptr_hack.o +//kbuild:lib-$(CONFIG_TEST2) += test.o test_ptr_hack.o +//kbuild:lib-$(CONFIG_ASH_BUILTIN_TEST) += test.o test_ptr_hack.o +//kbuild:lib-$(CONFIG_HUSH) += test.o test_ptr_hack.o +//kbuild:lib-$(CONFIG_SH_IS_HUSH) += test.o test_ptr_hack.o +//kbuild:lib-$(CONFIG_BASH_IS_HUSH) += test.o test_ptr_hack.o + +/* "test --help" is special-cased to ignore --help */ +//usage:#define test_trivial_usage NOUSAGE_STR +//usage:#define test_full_usage "" //usage: //usage:#define test_example_usage //usage: "$ test 1 -eq 2\n" @@ -399,6 +413,7 @@ extern struct test_statics *const test_ptr_to_statics; barrier(); \ } while (0) #define DEINIT_S() do { \ + free(group_array); \ free(test_ptr_to_statics); \ } while (0) @@ -826,10 +841,11 @@ int test_main(int argc, char **argv) { int res; const char *arg0; -// bool negate = 0; arg0 = bb_basename(argv[0]); - if (arg0[0] == '[') { + if ((ENABLE_TEST1 || ENABLE_TEST2 || ENABLE_ASH_BUILTIN_TEST || ENABLE_HUSH) + && (arg0[0] == '[') + ) { --argc; if (!arg0[1]) { /* "[" ? */ if (NOT_LONE_CHAR(argv[argc], ']')) { @@ -844,6 +860,7 @@ int test_main(int argc, char **argv) } argv[argc] = NULL; } + /* argc is unused after this point */ /* We must do DEINIT_S() prior to returning */ INIT_S(); @@ -862,43 +879,45 @@ int test_main(int argc, char **argv) */ /*ngroups = 0; - done by INIT_S() */ - //argc--; argv++; + args = argv; - /* Implement special cases from POSIX.2, section 4.62.4 */ - if (!argv[0]) { /* "test" */ - res = 1; - goto ret; - } -#if 0 -// Now it's fixed in the parser and should not be needed - if (LONE_CHAR(argv[0], '!') && argv[1]) { - negate = 1; - //argc--; - argv++; - } - if (!argv[1]) { /* "test [!] arg" */ - res = (*argv[0] == '\0'); - goto ret; - } - if (argv[2] && !argv[3]) { - check_operator(argv[1]); - if (last_operator->op_type == BINOP) { - /* "test [!] arg1 arg2" */ - args = argv; - res = (binop() == 0); - goto ret; + /* Implement special cases from POSIX.2, section 4.62.4. + * Testcase: "test '(' = '('" + * The general parser would misinterpret '(' as group start. + */ + if (1) { + int negate = 0; + again: + if (!argv[0]) { + /* "test" */ + res = 1; + goto ret_special; + } + if (!argv[1]) { + /* "test [!] arg" */ + res = (argv[0][0] == '\0'); + goto ret_special; + } + if (argv[2] && !argv[3]) { + check_operator(argv[1]); + if (last_operator->op_type == BINOP) { + /* "test [!] arg1 arg2" */ + args = argv; + res = (binop() == 0); + ret_special: + /* If there was leading "!" op... */ + res ^= negate; + goto ret; + } + } + if (LONE_CHAR(argv[0], '!')) { + argv++; + negate ^= 1; + goto again; } } - /* Some complex expression. Undo '!' removal */ - if (negate) { - negate = 0; - //argc++; - argv--; - } -#endif - args = argv; res = !oexpr(check_operator(*args)); if (*args != NULL && *++args != NULL) { @@ -911,6 +930,5 @@ int test_main(int argc, char **argv) } ret: DEINIT_S(); -// return negate ? !res : res; return res; } diff --git a/coreutils/touch.c b/coreutils/touch.c index 293a968..7d58470 100644 --- a/coreutils/touch.c +++ b/coreutils/touch.c @@ -6,19 +6,12 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 _NOT_ compliant -- options -a, -m not supported. */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/touch.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Previous version called open() and then utime(). While this will be * be necessary to implement -r and -t, it currently only makes things bigger. * Also, exiting on a failure was a bug. All args should be processed. */ - -#include "libbb.h" - //config:config TOUCH //config: bool "touch" //config: default y @@ -45,6 +38,9 @@ //kbuild:lib-$(CONFIG_TOUCH) += touch.o +/* BB_AUDIT SUSv3 _NOT_ compliant -- options -a, -m not supported. */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/touch.html */ + //usage:#define touch_trivial_usage //usage: "[-c]" IF_FEATURE_TOUCH_SUSV3(" [-d DATE] [-t DATE] [-r FILE]") " FILE..." //usage:#define touch_full_usage "\n\n" @@ -66,8 +62,6 @@ //usage: "$ ls -l /tmp/foo\n" //usage: "-rw-rw-r-- 1 andersen andersen 0 Apr 15 01:11 /tmp/foo\n" -/* This is a NOFORK applet. Be very careful! */ - /* coreutils implements: * -a change only the access time * -c, --no-create @@ -85,6 +79,8 @@ * change the specified time: WORD is access, atime, or use */ +#include "libbb.h" + int touch_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int touch_main(int argc UNUSED_PARAM, char **argv) { @@ -168,7 +164,7 @@ int touch_main(int argc UNUSED_PARAM, char **argv) int result; result = ( #if ENABLE_FEATURE_TOUCH_NODEREF - (opts & OPT_h) ? lutimes : + (opts & OPT_h) ? utimes : #endif utimes)(*argv, (reference_file || date_str) ? timebuf : NULL); if (result != 0) { diff --git a/coreutils/tr.c b/coreutils/tr.c index e67948a..f552096 100644 --- a/coreutils/tr.c +++ b/coreutils/tr.c @@ -18,9 +18,6 @@ /* http://www.opengroup.org/onlinepubs/009695399/utilities/tr.html * TODO: graph, print */ - -//kbuild:lib-$(CONFIG_TR) += tr.o - //config:config TR //config: bool "tr" //config: default y @@ -47,6 +44,10 @@ //config: useful for cases when no other way of expressing a character //config: is possible. +//applet:IF_TR(APPLET(tr, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_TR) += tr.o + //usage:#define tr_trivial_usage //usage: "[-cds] STRING1 [STRING2]" //usage:#define tr_full_usage "\n\n" @@ -91,7 +92,6 @@ static void map(char *pvector, * Character classes, e.g. [:upper:] ==> A...Z * Equiv classess, e.g. [=A=] ==> A (hmmmmmmm?) * not supported: - * \ooo-\ooo - octal ranges * [x*N] - repeat char x N times * [x*] - repeat char x until it fills STRING2: * # echo qwe123 | /usr/bin/tr 123456789 '[d]' @@ -99,7 +99,7 @@ static void map(char *pvector, * # echo qwe123 | /usr/bin/tr 123456789 '[d*]' * qweddd */ -static unsigned expand(const char *arg, char **buffer_p) +static unsigned expand(char *arg, char **buffer_p) { char *buffer = *buffer_p; unsigned pos = 0; @@ -113,9 +113,17 @@ static unsigned expand(const char *arg, char **buffer_p) *buffer_p = buffer = xrealloc(buffer, size); } if (*arg == '\\') { + const char *z; arg++; - buffer[pos++] = bb_process_escape_sequence(&arg); - continue; + z = arg; + ac = bb_process_escape_sequence(&z); + arg = (char *)z; + arg--; + *arg = ac; + /* + * fall through, there may be a range. + * If not, current char will be treated anyway. + */ } if (arg[1] == '-') { /* "0-9..." */ ac = arg[2]; @@ -124,9 +132,15 @@ static unsigned expand(const char *arg, char **buffer_p) continue; /* next iter will copy '-' and stop */ } i = (unsigned char) *arg; + arg += 3; /* skip 0-9 or 0-\ */ + if (ac == '\\') { + const char *z; + z = arg; + ac = bb_process_escape_sequence(&z); + arg = (char *)z; + } while (i <= ac) /* ok: i is unsigned _int_ */ buffer[pos++] = i++; - arg += 3; /* skip 0-9 */ continue; } if ((ENABLE_FEATURE_TR_CLASSES || ENABLE_FEATURE_TR_EQUIV) diff --git a/coreutils/true.c b/coreutils/true.c index 382e476..6a9493f 100644 --- a/coreutils/true.c +++ b/coreutils/true.c @@ -6,15 +6,22 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config TRUE +//config: bool "true" +//config: default y +//config: help +//config: true returns an exit code of TRUE (0). + +//applet:IF_TRUE(APPLET_NOFORK(true, true, BB_DIR_BIN, BB_SUID_DROP, true)) + +//kbuild:lib-$(CONFIG_TRUE) += true.o /* BB_AUDIT SUSv3 compliant */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/true.html */ -//usage:#define true_trivial_usage -//usage: "" -//usage:#define true_full_usage "\n\n" -//usage: "Return an exit code of TRUE (0)" -//usage: +/* "true --help" is special-cased to ignore --help */ +//usage:#define true_trivial_usage NOUSAGE_STR +//usage:#define true_full_usage "" //usage:#define true_example_usage //usage: "$ true\n" //usage: "$ echo $?\n" diff --git a/coreutils/truncate.c b/coreutils/truncate.c new file mode 100644 index 0000000..253fe00 --- a/dev/null +++ b/coreutils/truncate.c @@ -0,0 +1,87 @@ +/* + * Mini truncate implementation for busybox + * + * Copyright (C) 2015 by Ari Sundholm + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ +//config:config TRUNCATE +//config: bool "truncate" +//config: default y +//config: help +//config: truncate truncates files to a given size. If a file does +//config: not exist, it is created unless told otherwise. + +//applet:IF_TRUNCATE(APPLET_NOFORK(truncate, truncate, BB_DIR_USR_BIN, BB_SUID_DROP, truncate)) + +//kbuild:lib-$(CONFIG_TRUNCATE) += truncate.o + +//usage:#define truncate_trivial_usage +//usage: "[-c] -s SIZE FILE..." +//usage:#define truncate_full_usage "\n\n" +//usage: "Truncate FILEs to the given size\n" +//usage: "\n -c Do not create files" +//usage: "\n -s SIZE Truncate to SIZE" +//usage: +//usage:#define truncate_example_usage +//usage: "$ truncate -s 1G foo" + +#include "libbb.h" + +#if ENABLE_LFS +# define XATOU_SFX xatoull_sfx +#else +# define XATOU_SFX xatoul_sfx +#endif + +/* This is a NOFORK applet. Be very careful! */ + +int truncate_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int truncate_main(int argc UNUSED_PARAM, char **argv) +{ + unsigned opts; + int flags = O_WRONLY | O_NONBLOCK; + int ret = EXIT_SUCCESS; + char *size_str; + off_t size; + + enum { + OPT_NOCREATE = (1 << 0), + OPT_SIZE = (1 << 1), + }; + + opt_complementary = "s:-1"; + opts = getopt32(argv, "cs:", &size_str); + + if (!(opts & OPT_NOCREATE)) + flags |= O_CREAT; + + // TODO: coreutils 8.17 also support "m" (lowercase) suffix + // with truncate, but not with dd! + // We share kMG_suffixes[], so we can't make both tools + // compatible at once... + size = XATOU_SFX(size_str, kMG_suffixes); + + argv += optind; + while (*argv) { + int fd = open(*argv, flags, 0666); + if (fd < 0) { + if (errno != ENOENT || !(opts & OPT_NOCREATE)) { + bb_perror_msg("%s: open", *argv); + ret = EXIT_FAILURE; + } + /* else: ENOENT && OPT_NOCREATE: + * do not report error, exitcode is also 0. + */ + } else { + if (ftruncate(fd, size) == -1) { + bb_perror_msg("%s: truncate", *argv); + ret = EXIT_FAILURE; + } + xclose(fd); + } + ++argv; + } + + return ret; +} diff --git a/coreutils/tty.c b/coreutils/tty.c index 4517505..359e5bc 100644 --- a/coreutils/tty.c +++ b/coreutils/tty.c @@ -6,6 +6,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config TTY +//config: bool "tty" +//config: default y +//config: help +//config: tty is used to print the name of the current terminal to +//config: standard output. + +//applet:IF_TTY(APPLET(tty, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_TTY) += tty.o /* BB_AUDIT SUSv4 compliant */ /* http://www.opengroup.org/onlinepubs/9699919799/utilities/tty.html */ diff --git a/coreutils/uname.c b/coreutils/uname.c index b96d76b..4d98fde 100644 --- a/coreutils/uname.c +++ b/coreutils/uname.c @@ -4,10 +4,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 compliant */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/uname.html */ - /* Option Example * -s, --sysname SunOS * -n, --nodename rocky8 @@ -37,7 +33,6 @@ * -a, --all: all of the above, in the order shown. * If -p or -i is not known, don't show them */ - /* Busyboxed by Erik Andersen * * Before 2003: Glenn McGrath and Manuel Novoa III @@ -47,18 +42,40 @@ * Jan 2009: * Fix handling of -a to not print "unknown", add -o and -i support. */ +//config:config UNAME +//config: bool "uname" +//config: default y +//config: help +//config: uname is used to print system information. +//config: +//config:config UNAME_OSNAME +//config: string "Operating system name" +//config: default "GNU/Linux" +//config: depends on UNAME +//config: help +//config: Sets the operating system name reported by uname -o. The +//config: default is "GNU/Linux". + +//applet:IF_UNAME(APPLET(uname, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_UNAME) += uname.o + +/* BB_AUDIT SUSv3 compliant */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/uname.html */ //usage:#define uname_trivial_usage -//usage: "[-amnrspv]" +//usage: "[-amnrspvio]" //usage:#define uname_full_usage "\n\n" //usage: "Print system information\n" //usage: "\n -a Print all" //usage: "\n -m The machine (hardware) type" //usage: "\n -n Hostname" -//usage: "\n -r OS release" -//usage: "\n -s OS name (default)" +//usage: "\n -r Kernel release" +//usage: "\n -s Kernel name (default)" //usage: "\n -p Processor type" -//usage: "\n -v OS version" +//usage: "\n -v Kernel version" +//usage: "\n -i The hardware platform" +//usage: "\n -o OS name" //usage: //usage:#define uname_example_usage //usage: "$ uname -a\n" @@ -72,7 +89,7 @@ typedef struct { struct utsname name; char processor[sizeof(((struct utsname*)NULL)->machine)]; char platform[sizeof(((struct utsname*)NULL)->machine)]; - char os[sizeof("GNU/Linux")]; + char os[sizeof(CONFIG_UNAME_OSNAME)]; } uname_info_t; static const char options[] ALIGN1 = "snrvmpioa"; @@ -139,7 +156,7 @@ int uname_main(int argc UNUSED_PARAM, char **argv) #endif strcpy(uname_info.processor, unknown_str); strcpy(uname_info.platform, unknown_str); - strcpy(uname_info.os, "GNU/Linux"); + strcpy(uname_info.os, CONFIG_UNAME_OSNAME); #if 0 /* Fedora does something like this */ strcpy(uname_info.processor, uname_info.name.machine); diff --git a/coreutils/uniq.c b/coreutils/uniq.c index 9208d34..be550b5 100644 --- a/coreutils/uniq.c +++ b/coreutils/uniq.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config UNIQ +//config: bool "uniq" +//config: default y +//config: help +//config: uniq is used to remove duplicate lines from a sorted file. + +//applet:IF_UNIQ(APPLET(uniq, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_UNIQ) += uniq.o /* BB_AUDIT SUSv3 compliant */ /* http://www.opengroup.org/onlinepubs/007904975/utilities/uniq.html */ @@ -50,8 +59,7 @@ int uniq_main(int argc UNUSED_PARAM, char **argv) skip_fields = skip_chars = 0; max_chars = INT_MAX; - opt_complementary = "f+:s+:w+"; - opt = getopt32(argv, "cduf:s:w:", &skip_fields, &skip_chars, &max_chars); + opt = getopt32(argv, "cduf:+s:+w:+", &skip_fields, &skip_chars, &max_chars); argv += optind; input_filename = argv[0]; @@ -112,7 +120,7 @@ int uniq_main(int argc UNUSED_PARAM, char **argv) /* %7lu matches GNU coreutils 6.9 */ printf("%7lu ", dups + 1); } - printf("%s\n", old_line); + puts(old_line); } free(old_line); } diff --git a/coreutils/unlink.c b/coreutils/unlink.c new file mode 100644 index 0000000..2879638 --- a/dev/null +++ b/coreutils/unlink.c @@ -0,0 +1,33 @@ +/* vi: set sw=4 ts=4: */ +/* unlink for busybox + * + * Copyright (C) 2014 Isaac Dunham + * + * Licensed under GPLv2, see LICENSE in this source tree + */ +//config:config UNLINK +//config: bool "unlink" +//config: default y +//config: help +//config: unlink deletes a file by calling unlink() + +//applet:IF_UNLINK(APPLET(unlink, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_UNLINK) += unlink.o + +//usage:#define unlink_trivial_usage +//usage: "FILE" +//usage:#define unlink_full_usage "\n\n" +//usage: "Delete FILE by calling unlink()" + +#include "libbb.h" + +int unlink_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; +int unlink_main(int argc UNUSED_PARAM, char **argv) +{ + opt_complementary = "=1"; /* must have exactly 1 param */ + getopt32(argv, ""); + argv += optind; + xunlink(argv[0]); + return 0; +} diff --git a/coreutils/usleep.c b/coreutils/usleep.c index 2e4eb57..7bc30c2 100644 --- a/coreutils/usleep.c +++ b/coreutils/usleep.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config USLEEP +//config: bool "usleep" +//config: default y +//config: help +//config: usleep is used to pause for a specified number of microseconds. + +//applet:IF_USLEEP(APPLET_NOFORK(usleep, usleep, BB_DIR_BIN, BB_SUID_DROP, usleep)) + +//kbuild:lib-$(CONFIG_USLEEP) += usleep.o /* BB_AUDIT SUSv3 N/A -- Apparently a busybox extension. */ diff --git a/coreutils/uudecode.c b/coreutils/uudecode.c index b298fcb..ddce254 100644 --- a/coreutils/uudecode.c +++ b/coreutils/uudecode.c @@ -10,6 +10,15 @@ * Bugs: the spec doesn't mention anything about "`\n`\n" prior to the * "end" line */ +//config:config UUDECODE +//config: bool "uudecode" +//config: default y +//config: help +//config: uudecode is used to decode a uuencoded file. + +//applet:IF_UUDECODE(APPLET(uudecode, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_UUDECODE) += uudecode.o //usage:#define uudecode_trivial_usage //usage: "[-o OUTFILE] [INFILE]" @@ -29,9 +38,19 @@ static void FAST_FUNC read_stduu(FILE *src_stream, FILE *dst_stream, int flags U { char *line; - while ((line = xmalloc_fgetline(src_stream)) != NULL) { + for (;;) { int encoded_len, str_len; char *line_ptr, *dst; + size_t line_len; + + line_len = 64 * 1024; + line = xmalloc_fgets_str_len(src_stream, "\n", &line_len); + if (!line) + break; + /* Handle both Unix and MSDOS text, and stray trailing spaces */ + str_len = line_len; + while (--str_len >= 0 && isspace(line[str_len])) + line[str_len] = '\0'; if (strcmp(line, "end") == 0) { return; /* the only non-error exit */ @@ -46,7 +65,7 @@ static void FAST_FUNC read_stduu(FILE *src_stream, FILE *dst_stream, int flags U encoded_len = line[0] * 4 / 3; /* Check that line is not too short. (we tolerate - * overly _long_ line to accomodate possible extra '`'). + * overly _long_ line to accommodate possible extra '`'). * Empty line case is also caught here. */ if (str_len <= encoded_len) { break; /* go to bb_error_msg_and_die("short file"); */ @@ -110,10 +129,10 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv) FILE *dst_stream; int mode; - if (strncmp(line, "begin-base64 ", 13) == 0) { + if (is_prefixed_with(line, "begin-base64 ")) { line_ptr = line + 13; decode_fn_ptr = read_base64; - } else if (strncmp(line, "begin ", 6) == 0) { + } else if (is_prefixed_with(line, "begin ")) { line_ptr = line + 6; decode_fn_ptr = read_stduu; } else { @@ -128,6 +147,7 @@ int uudecode_main(int argc UNUSED_PARAM, char **argv) if (!outname) break; outname++; + trim(outname); /* remove trailing space (and '\r' for DOS text) */ if (!outname[0]) break; } diff --git a/coreutils/uuencode.c b/coreutils/uuencode.c index 673ef36..917cdae 100644 --- a/coreutils/uuencode.c +++ b/coreutils/uuencode.c @@ -7,6 +7,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config UUENCODE +//config: bool "uuencode" +//config: default y +//config: help +//config: uuencode is used to uuencode a file. + +//applet:IF_UUENCODE(APPLET(uuencode, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_UUENCODE) += uuencode.o //usage:#define uuencode_trivial_usage //usage: "[-m] [FILE] STORED_FILENAME" diff --git a/coreutils/wc.c b/coreutils/wc.c index a410e40..7383714 100644 --- a/coreutils/wc.c +++ b/coreutils/wc.c @@ -6,10 +6,6 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 compliant. */ -/* http://www.opengroup.org/onlinepubs/007904975/utilities/wc.html */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Rewritten to fix a number of problems and do some size optimizations. @@ -36,6 +32,27 @@ * * for which 'wc -c' should output '0'. */ +//config:config WC +//config: bool "wc" +//config: default y +//config: help +//config: wc is used to print the number of bytes, words, and lines, +//config: in specified files. +//config: +//config:config FEATURE_WC_LARGE +//config: bool "Support very large files in wc" +//config: default y +//config: depends on WC +//config: help +//config: Use "unsigned long long" in wc for counter variables. + +//applet:IF_WC(APPLET(wc, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_WC) += wc.o + +/* BB_AUDIT SUSv3 compliant. */ +/* http://www.opengroup.org/onlinepubs/007904975/utilities/wc.html */ + #include "libbb.h" #include "unicode.h" diff --git a/coreutils/who.c b/coreutils/who.c index f955ce6..ac19dc7 100644 --- a/coreutils/who.c +++ b/coreutils/who.c @@ -16,15 +16,13 @@ * *---------------------------------------------------------------------- */ -/* BB_AUDIT SUSv3 _NOT_ compliant -- missing options -b, -d, -l, -m, -p, -q, -r, -s, -t, -T, -u; Missing argument 'file'. */ - //config:config WHO //config: bool "who" //config: default y //config: depends on FEATURE_UTMP //config: help //config: who is used to show who is logged on. - +//config: //config:config USERS //config: bool "users" //config: default y @@ -33,11 +31,13 @@ //config: Print users currently logged on. //applet:IF_USERS(APPLET_ODDNAME(users, who, BB_DIR_USR_BIN, BB_SUID_DROP, users)) -//applet:IF_WHO( APPLET( who, BB_DIR_USR_BIN, BB_SUID_DROP)) +//applet:IF_WHO(APPLET(who, BB_DIR_USR_BIN, BB_SUID_DROP)) //kbuild:lib-$(CONFIG_USERS) += who.o //kbuild:lib-$(CONFIG_WHO) += who.o +/* BB_AUDIT SUSv3 _NOT_ compliant -- missing options -b, -d, -l, -m, -p, -q, -r, -s, -t, -T, -u; Missing argument 'file'. */ + //usage:#define users_trivial_usage //usage: "" //usage:#define users_full_usage "\n\n" @@ -73,7 +73,7 @@ static void idle_string(char *str6, time_t t) int who_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int who_main(int argc UNUSED_PARAM, char **argv) { - struct utmp *ut; + struct utmpx *ut; unsigned opt; int do_users = (ENABLE_USERS && (!ENABLE_WHO || applet_name[0] == 'u')); const char *fmt = "%s"; @@ -81,10 +81,10 @@ int who_main(int argc UNUSED_PARAM, char **argv) opt_complementary = "=0"; opt = getopt32(argv, do_users ? "" : "aH"); if (opt & 2) // -H - printf("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST\n"); + puts("USER\t\tTTY\t\tIDLE\tTIME\t\t HOST"); - setutent(); - while ((ut = getutent()) != NULL) { + setutxent(); + while ((ut = getutxent()) != NULL) { if (ut->ut_user[0] && ((opt & 1) || ut->ut_type == USER_PROCESS) ) { @@ -126,6 +126,6 @@ int who_main(int argc UNUSED_PARAM, char **argv) if (do_users) bb_putchar('\n'); if (ENABLE_FEATURE_CLEAN_UP) - endutent(); + endutxent(); return EXIT_SUCCESS; } diff --git a/coreutils/whoami.c b/coreutils/whoami.c index 30b17ca..6357128 100644 --- a/coreutils/whoami.c +++ b/coreutils/whoami.c @@ -6,6 +6,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config WHOAMI +//config: bool "whoami" +//config: default y +//config: help +//config: whoami is used to print the username of the current +//config: user id (same as id -un). + +//applet:IF_WHOAMI(APPLET_NOFORK(whoami, whoami, BB_DIR_USR_BIN, BB_SUID_DROP, whoami)) + +//kbuild:lib-$(CONFIG_WHOAMI) += whoami.o /* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ @@ -16,8 +26,6 @@ #include "libbb.h" -/* This is a NOFORK applet. Be very careful! */ - int whoami_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int whoami_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) { diff --git a/coreutils/yes.c b/coreutils/yes.c index 5d799f0..81d8755 100644 --- a/coreutils/yes.c +++ b/coreutils/yes.c @@ -6,23 +6,30 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - -/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ - /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) * * Size reductions and removed redundant applet name prefix from error messages. */ +//config:config YES +//config: bool "yes" +//config: default y +//config: help +//config: yes is used to repeatedly output a specific string, or +//config: the default string `y'. -#include "libbb.h" +//applet:IF_YES(APPLET_NOFORK(yes, yes, BB_DIR_USR_BIN, BB_SUID_DROP, yes)) -/* This is a NOFORK applet. Be very careful! */ +//kbuild:lib-$(CONFIG_YES) += yes.o + +/* BB_AUDIT SUSv3 N/A -- Matches GNU behavior. */ //usage:#define yes_trivial_usage //usage: "[STRING]" //usage:#define yes_full_usage "\n\n" //usage: "Repeatedly output a line with STRING, or 'y'" +#include "libbb.h" + int yes_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int yes_main(int argc UNUSED_PARAM, char **argv) { diff --git a/debianutils/Config.src b/debianutils/Config.src index cbc09b5..61daeb0 100644 --- a/debianutils/Config.src +++ b/debianutils/Config.src @@ -7,79 +7,4 @@ menu "Debian Utilities" INSERT -config MKTEMP - bool "mktemp" - default y - help - mktemp is used to create unique temporary files - -config PIPE_PROGRESS - bool "pipe_progress" - default y - help - Display a dot to indicate pipe activity. - -config RUN_PARTS - bool "run-parts" - default y - help - run-parts is a utility designed to run all the scripts in a directory. - - It is useful to set up a directory like cron.daily, where you need to - execute all the scripts in that directory. - - In this implementation of run-parts some features (such as report - mode) are not implemented. - - Unless you know that run-parts is used in some of your scripts - you can safely say N here. - -config FEATURE_RUN_PARTS_LONG_OPTIONS - bool "Enable long options" - default y - depends on RUN_PARTS && LONG_OPTS - help - Support long options for the run-parts applet. - -config FEATURE_RUN_PARTS_FANCY - bool "Support additional arguments" - default y - depends on RUN_PARTS - help - Support additional options: - -l --list print the names of the all matching files (not - limited to executables), but don't actually run them. - -config START_STOP_DAEMON - bool "start-stop-daemon" - default y - help - start-stop-daemon is used to control the creation and - termination of system-level processes, usually the ones - started during the startup of the system. - -config FEATURE_START_STOP_DAEMON_FANCY - bool "Support additional arguments" - default y - depends on START_STOP_DAEMON - help - Support additional arguments. - -o|--oknodo ignored since we exit with 0 anyway - -v|--verbose - -N|--nicelevel N - -config FEATURE_START_STOP_DAEMON_LONG_OPTIONS - bool "Enable long options" - default y - depends on START_STOP_DAEMON && LONG_OPTS - help - Support long options for the start-stop-daemon applet. - -config WHICH - bool "which" - default y - help - which is used to find programs in your PATH and - print out their pathnames. - endmenu diff --git a/debianutils/Kbuild.src b/debianutils/Kbuild.src index d41b5c8..6b4fb74 100644 --- a/debianutils/Kbuild.src +++ b/debianutils/Kbuild.src @@ -7,8 +7,3 @@ lib-y:= INSERT -lib-$(CONFIG_MKTEMP) += mktemp.o -lib-$(CONFIG_PIPE_PROGRESS) += pipe_progress.o -lib-$(CONFIG_RUN_PARTS) += run_parts.o -lib-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o -lib-$(CONFIG_WHICH) += which.o diff --git a/debianutils/mktemp.c b/debianutils/mktemp.c index 10dd0de..8f9479f 100755..100644 --- a/debianutils/mktemp.c +++ b/debianutils/mktemp.c @@ -30,6 +30,15 @@ * a directory: $TMPDIR, if set; else the directory specified via * -p; else /tmp [deprecated] */ +//config:config MKTEMP +//config: bool "mktemp" +//config: default y +//config: help +//config: mktemp is used to create unique temporary files + +//applet:IF_MKTEMP(APPLET(mktemp, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_MKTEMP) += mktemp.o //usage:#define mktemp_trivial_usage //usage: "[-dt] [-p DIR] [TEMPLATE]" @@ -54,6 +63,7 @@ #include "libbb.h" #ifdef __BIONIC__ +#include #define mktemp(s) bb_mktemp(s) #endif diff --git a/debianutils/pipe_progress.c b/debianutils/pipe_progress.c index 2c7444f..21d330b 100644 --- a/debianutils/pipe_progress.c +++ b/debianutils/pipe_progress.c @@ -6,6 +6,15 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ +//config:config PIPE_PROGRESS +//config: bool "pipe_progress" +//config: default y +//config: help +//config: Display a dot to indicate pipe activity. + +//applet:IF_PIPE_PROGRESS(APPLET(pipe_progress, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_PIPE_PROGRESS) += pipe_progress.o //usage:#define pipe_progress_trivial_usage NOUSAGE_STR //usage:#define pipe_progress_full_usage "" diff --git a/debianutils/run_parts.c b/debianutils/run_parts.c index 527fae2..0bb666a 100644 --- a/debianutils/run_parts.c +++ b/debianutils/run_parts.c @@ -22,6 +22,40 @@ * report mode. As the original run-parts support only long options, I've * broken compatibility because the BusyBox policy doesn't allow them. */ +//config:config RUN_PARTS +//config: bool "run-parts" +//config: default y +//config: help +//config: run-parts is a utility designed to run all the scripts in a directory. +//config: +//config: It is useful to set up a directory like cron.daily, where you need to +//config: execute all the scripts in that directory. +//config: +//config: In this implementation of run-parts some features (such as report +//config: mode) are not implemented. +//config: +//config: Unless you know that run-parts is used in some of your scripts +//config: you can safely say N here. +//config: +//config:config FEATURE_RUN_PARTS_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on RUN_PARTS && LONG_OPTS +//config: help +//config: Support long options for the run-parts applet. +//config: +//config:config FEATURE_RUN_PARTS_FANCY +//config: bool "Support additional arguments" +//config: default y +//config: depends on RUN_PARTS +//config: help +//config: Support additional options: +//config: -l --list print the names of the all matching files (not +//config: limited to executables), but don't actually run them. + +//applet:IF_RUN_PARTS(APPLET_ODDNAME(run-parts, run_parts, BB_DIR_BIN, BB_SUID_DROP, run_parts)) + +//kbuild:lib-$(CONFIG_RUN_PARTS) += run_parts.o //usage:#define run_parts_trivial_usage //usage: "[-a ARG]... [-u UMASK] " @@ -55,17 +89,18 @@ //usage: "+ shutdown -h +4m" #include "libbb.h" +#include "common_bufsiz.h" struct globals { char **names; int cur; char *cmd[2 /* using 1 provokes compiler warning */]; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define names (G.names) #define cur (G.cur ) #define cmd (G.cmd ) -#define INIT_G() do { } while (0) +#define INIT_G() do { setup_common_bufsiz(); } while (0) enum { NUM_CMD = (COMMON_BUFSIZE - sizeof(G)) / sizeof(cmd[0]) - 1 }; @@ -146,8 +181,8 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv) applet_long_options = runparts_longopts; #endif /* We require exactly one argument: the directory name */ - opt_complementary = "=1:a::"; - getopt32(argv, "a:u:", &arg_list, &umask_p); + opt_complementary = "=1"; + getopt32(argv, "a:*u:", &arg_list, &umask_p); umask(xstrtou_range(umask_p, 8, 0, 07777)); @@ -189,7 +224,7 @@ int run_parts_main(int argc UNUSED_PARAM, char **argv) if (ret < 0) bb_perror_msg("can't execute '%s'", name); else /* ret > 0 */ - bb_error_msg("%s exited with code %d", name, ret & 0xff); + bb_error_msg("%s: exit status %u", name, ret & 0xff); if (option_mask32 & OPT_e) xfunc_die(); diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 7dadc3c..3625ffe 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c @@ -56,6 +56,34 @@ Misc options: -q,--quiet Quiet -v,--verbose Verbose */ +//config:config START_STOP_DAEMON +//config: bool "start-stop-daemon" +//config: default y +//config: help +//config: start-stop-daemon is used to control the creation and +//config: termination of system-level processes, usually the ones +//config: started during the startup of the system. +//config: +//config:config FEATURE_START_STOP_DAEMON_FANCY +//config: bool "Support additional arguments" +//config: default y +//config: depends on START_STOP_DAEMON +//config: help +//config: Support additional arguments. +//config: -o|--oknodo ignored since we exit with 0 anyway +//config: -v|--verbose +//config: -N|--nicelevel N +//config: +//config:config FEATURE_START_STOP_DAEMON_LONG_OPTIONS +//config: bool "Enable long options" +//config: default y +//config: depends on START_STOP_DAEMON && LONG_OPTS +//config: help +//config: Support long options for the start-stop-daemon applet. + +//applet:IF_START_STOP_DAEMON(APPLET_ODDNAME(start-stop-daemon, start_stop_daemon, BB_DIR_SBIN, BB_SUID_DROP, start_stop_daemon)) + +//kbuild:lib-$(CONFIG_START_STOP_DAEMON) += start_stop_daemon.o //usage:#define start_stop_daemon_trivial_usage //usage: "[OPTIONS] [-S|-K] ... [-- ARGS...]" @@ -125,6 +153,7 @@ Misc options: /* Override ENABLE_FEATURE_PIDFILE */ #define WANT_PIDFILE 1 #include "libbb.h" +#include "common_bufsiz.h" struct pid_list { struct pid_list *next; @@ -163,7 +192,7 @@ struct globals { int user_id; smallint signal_nr; } FIX_ALIASING; -#define G (*(struct globals*)&bb_common_bufsiz1) +#define G (*(struct globals*)bb_common_bufsiz1) #define userspec (G.userspec ) #define cmdname (G.cmdname ) #define execname (G.execname ) @@ -171,6 +200,7 @@ struct globals { #define user_id (G.user_id ) #define signal_nr (G.signal_nr ) #define INIT_G() do { \ + setup_common_bufsiz(); \ user_id = -1; \ signal_nr = 15; \ } while (0) @@ -511,15 +541,15 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) write_pidfile(pidfile); } if (opt & OPT_c) { - struct bb_uidgid_t ugid = { -1, -1 }; + struct bb_uidgid_t ugid; parse_chown_usergroup_or_die(&ugid, chuid); - if (ugid.uid != (uid_t) -1) { + if (ugid.uid != (uid_t) -1L) { struct passwd *pw = xgetpwuid(ugid.uid); - if (ugid.gid != (gid_t) -1) + if (ugid.gid != (gid_t) -1L) pw->pw_gid = ugid.gid; /* initgroups, setgid, setuid: */ change_identity(pw); - } else if (ugid.gid != (gid_t) -1) { + } else if (ugid.gid != (gid_t) -1L) { xsetgid(ugid.gid); setgroups(1, &ugid.gid); } diff --git a/debianutils/which.c b/debianutils/which.c index 15fd598..c0f8978 100644 --- a/debianutils/which.c +++ b/debianutils/which.c @@ -1,14 +1,20 @@ /* vi: set sw=4 ts=4: */ /* - * Which implementation for busybox - * * Copyright (C) 1999-2004 by Erik Andersen * Copyright (C) 2006 Gabriel Somlo * * Licensed under GPLv2 or later, see file LICENSE in this source tree. - * - * Based on which from debianutils */ +//config:config WHICH +//config: bool "which" +//config: default y +//config: help +//config: which is used to find programs in your PATH and +//config: print out their pathnames. + +//applet:IF_WHICH(APPLET(which, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_WHICH) += which.o //usage:#define which_trivial_usage //usage: "[COMMAND]..." @@ -24,76 +30,43 @@ int which_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int which_main(int argc UNUSED_PARAM, char **argv) { - IF_DESKTOP(int opt;) - int status = EXIT_SUCCESS; - char *path; - char *p; + const char *env_path; + int status = 0; + + env_path = getenv("PATH"); + if (!env_path) + env_path = bb_default_root_path; opt_complementary = "-1"; /* at least one argument */ - IF_DESKTOP(opt =) getopt32(argv, "a"); + getopt32(argv, "a"); argv += optind; - /* This matches what is seen on e.g. ubuntu. - * "which" there is a shell script. */ - path = getenv("PATH"); - if (!path) { - path = (char*)bb_PATH_root_path; - putenv(path); - path += 5; /* skip "PATH=" */ - } - do { -#if ENABLE_DESKTOP -/* Much bloat just to support -a */ - if (strchr(*argv, '/')) { - if (execable_file(*argv)) { - puts(*argv); - continue; - } - status = EXIT_FAILURE; - } else { - char *path2 = xstrdup(path); - char *tmp = path2; + int missing = 1; - p = find_execable(*argv, &tmp); - if (!p) - status = EXIT_FAILURE; - else { - print: - puts(p); - free(p); - if (opt) { - /* -a: show matches in all PATH components */ - if (tmp) { - p = find_execable(*argv, &tmp); - if (p) - goto print; - } - } - } - free(path2); - } -#else -/* Just ignoring -a */ + /* If file contains a slash don't use PATH */ if (strchr(*argv, '/')) { - if (execable_file(*argv)) { + if (file_is_executable(*argv)) { + missing = 0; puts(*argv); - continue; } } else { - char *path2 = xstrdup(path); - char *tmp = path2; - p = find_execable(*argv, &tmp); - free(path2); - if (p) { + char *path; + char *tmp; + char *p; + + path = tmp = xstrdup(env_path); + while ((p = find_executable(*argv, &tmp)) != NULL) { + missing = 0; puts(p); free(p); - continue; + if (!option_mask32) /* -a not set */ + break; } + free(path); } - status = EXIT_FAILURE; -#endif - } while (*(++argv) != NULL); + status |= missing; + } while (*++argv); - fflush_stdout_and_exit(status); + return status; } diff --git a/docs/busybox_footer.pod b/docs/busybox_footer.pod index c346c73..92748eb 100644 --- a/docs/busybox_footer.pod +++ b/docs/busybox_footer.pod @@ -1,5 +1,3 @@ -=back - =head1 LIBC NSS GNU Libc (glibc) uses the Name Service Switch (NSS) to configure the behavior diff --git a/docs/cgi/env.html b/docs/cgi/env.html index b83c750..66a548b 100644 --- a/docs/cgi/env.html +++ b/docs/cgi/env.html @@ -38,7 +38,7 @@ fulfilled by the gateway program:

  • SERVER_PROTOCOL

    - The name and revision of the information protcol this request came + The name and revision of the information protocol this request came in with. Format: protocol/revision

  • SERVER_PORT

    diff --git a/docs/ifupdown_design.txt b/docs/ifupdown_design.txt index 8ab4e51..39e28a9 100644 --- a/docs/ifupdown_design.txt +++ b/docs/ifupdown_design.txt @@ -21,7 +21,7 @@ static int dhcp_down(struct interface_defn_t *ifd, execfn *exec) #if ENABLE_FEATURE_IFUPDOWN_EXTERNAL_DHCP int i ; for (i = 0; i < ARRAY_SIZE(ext_dhcp_clients); i++) { - if (exists_execable(ext_dhcp_clients[i].name)) + if (executable_exists(ext_dhcp_clients[i].name)) return execute(ext_dhcp_clients[i].stopcmd, ifd, exec); } bb_error_msg("no dhcp clients found, using static interface shutdown"); diff --git a/docs/keep_data_small.txt b/docs/keep_data_small.txt index 9fc7996..218d4f2 100644 --- a/docs/keep_data_small.txt +++ b/docs/keep_data_small.txt @@ -59,7 +59,7 @@ wait Example 1 One example how to reduce global data usage is in -archival/libarchive/decompress_unzip.c: +archival/libarchive/decompress_gunzip.c: /* This is somewhat complex-looking arrangement, but it allows * to place decompressor state either in bss or in @@ -87,7 +87,7 @@ take a look at archival/gzip.c. Here all global data is replaced by single global pointer (ptr_to_globals) to allocated storage. In order to not duplicate ptr_to_globals in every applet, you can -reuse single common one. It is defined in libbb/messages.c +reuse single common one. It is defined in libbb/ptr_to_globals.c as struct globals *const ptr_to_globals, but the struct globals is NOT defined in libbb.h. You first define your own struct: @@ -103,7 +103,15 @@ smaller code. In order to assign it, use SET_PTR_TO_GLOBALS macro: SET_PTR_TO_GLOBALS(xzalloc(sizeof(G))); -Typically it is done in _main(). +Typically it is done in _main(). Another variation is +to use stack: + +int _main(...) +{ +#undef G + struct globals G; + memset(&G, 0, sizeof(G)); + SET_PTR_TO_GLOBALS(&G); Now you can reference "globals" by G.a, G.buf and so on, in any function. diff --git a/docs/logging_and_backgrounding.txt b/docs/logging_and_backgrounding.txt index 7e68855..c76cd36 100644 --- a/docs/logging_and_backgrounding.txt +++ b/docs/logging_and_backgrounding.txt @@ -45,6 +45,8 @@ udhcpc - auto-backgrounds unless -f after lease is obtained, udhcpd - auto-backgrounds and do not log to stderr unless -f, otherwise logs to stderr, but option -S makes it log *also* to syslog zcip - auto-backgrounds and logs *also* to syslog unless -f + behaviour can be overridden with experimental LOGGING env.var + (can be set to either "none" or "syslog") Total: 13 applets (+1 obsolete), 4 log to syslog by default (crond fakeidentd inetd zcip), diff --git a/docs/new-applet-HOWTO.txt b/docs/new-applet-HOWTO.txt index 6a8054d..078e77b 100644 --- a/docs/new-applet-HOWTO.txt +++ b/docs/new-applet-HOWTO.txt @@ -6,7 +6,7 @@ This document details the steps you must take to add a new applet to BusyBox. Credits: Matt Kraai - initial writeup Mark Whitley - the remix -Thomas Lundquist - Trying to keep it updated. +Thomas Lundquist - trying to keep it updated When doing this you should consider using the latest git HEAD. This is a good thing if you plan to getting it committed into mainline. @@ -16,14 +16,14 @@ Initial Write First, write your applet. Be sure to include copyright information at the top, such as who you stole the code from and so forth. Also include the mini-GPL -boilerplate. Be sure to name the main function _main instead of main. -And be sure to put it in .c. Usage does not have to be taken care of by -your applet. -Make sure to #include "libbb.h" as the first include file in your applet. +boilerplate and Config.in/Kbuild/usage/applet.h snippets (more on that below +in this document). Be sure to name the main function _main instead +of main. And be sure to put it in .c. Make sure to #include "libbb.h" +as the first include file in your applet. For a new applet mu, here is the code that would go in mu.c: -(busybox.h already includes most usual header files. You do not need +(libbb.h already includes most usual header files. You do not need #include etc...) @@ -41,6 +41,22 @@ For a new applet mu, here is the code that would go in mu.c: #include "libbb.h" #include "other.h" +//config:config MU +//config: bool "MU" +//config: default y +//config: help +//config: Returns an indeterminate value. + +//kbuild:lib-$(CONFIG_MU) += mu.o +//applet:IF_MU(APPLET(mu, BB_DIR_USR_BIN, BB_SUID_DROP)) + +//usage:#define mu_trivial_usage +//usage: "[-abcde] FILE..." +//usage:#define mu_full_usage +//usage: "Returns an indeterminate value\n" +//usage: "\n -a First function" +//usage: "\n -b Second function" + int mu_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; int mu_main(int argc, char **argv) { @@ -90,6 +106,8 @@ Make a new file named .c #include "libbb.h" #include "other.h" +//kbuild:lib-y += function.o + int function(char *a) { return *a; @@ -97,9 +115,7 @@ int function(char *a) ----end example code------ -Add .o in the right alphabetically sorted place -in libbb/Kbuild.src. You should look at the conditional part of -libbb/Kbuild.src as well. +Remember about the kbuild snippet. You should also try to find a suitable place in include/libbb.h for the function declaration. If not, add it somewhere anyway, with or without @@ -109,60 +125,68 @@ You can look at libbb/Config.src and try to find out if the function is tunable and add it there if it is. +Kbuild/Config.in/usage/applets.h snippets in .c files +----------------------------------------------------- + +The old way of adding new applets was to put all the information needed by the +configuration and build system into appropriate files (namely: Kbuild.src and +Config.src in new applet's directory) and to add the applet declaration and +usage info text to include/applets.src.h and include/usage.src.h respectively. + +Since the scripts/gen_build_files.sh script had been introduced, the preferred +way is to have all these declarations contained within the applet .c files. + +Every line intended to be processed by gen_build_files.sh should start as a +comment without any preceding whitespaces and be followed by an appropriate +keyword - kbuild, config, usage or applet - and a colon, just like shown in the +first example above. + + Placement / Directory --------------------- Find the appropriate directory for your new applet. -Make sure you find the appropriate places in the files, the applets are -sorted alphabetically. +Add the kbuild snippet to the .c file: -Add the applet to Kbuild.src in the chosen directory: +//kbuild:lib-$(CONFIG_MU) += mu.o -lib-$(CONFIG_MU) += mu.o +Add the config snippet to the .c file: -Add the applet to Config.src in the chosen directory: - -config MU - bool "MU" - default n - help - Returns an indeterminate value. +//config:config MU +//config: bool "MU" +//config: default y +//config: help +//config: Returns an indeterminate value. Usage String(s) --------------- -Next, add usage information for you applet to include/usage.src.h. +Next, add usage information for your applet to the .c file. This should look like the following: - #define mu_trivial_usage \ - "-[abcde] FILES" - #define mu_full_usage \ - "Returns an indeterminate value.\n\n" \ - "Options:\n" \ - "\t-a\t\tfirst function\n" \ - "\t-b\t\tsecond function\n" \ - ... +//usage:#define mu_trivial_usage +//usage: "[-abcde] FILE..." +//usage:#define mu_full_usage +//usage: "Returns an indeterminate value\n" +//usage: "\n -a First function" +//usage: "\n -b Second function" +//usage: ... If your program supports flags, the flags should be mentioned on the first -line (-[abcde]) and a detailed description of each flag should go in the -mu_full_usage section, one flag per line. (Numerous examples of this -currently exist in usage.src.h.) +line ([-abcde]) and a detailed description of each flag should go in the +mu_full_usage section, one flag per line. Header Files ------------ -Next, add an entry to include/applets.src.h. Be *sure* to keep the list -in alphabetical order, or else it will break the binary-search lookup -algorithm in busybox.c and the Gods of BusyBox smite you. Yea, verily: - -Be sure to read the top of applets.src.h before adding your applet. +Finally add the applet declaration snippet. Be sure to read the top of +applets.src.h before adding your applet - it contains important info +on applet macros and conventions. - /* all programs above here are alphabetically "less than" 'mu' */ - IF_MU(APPLET(mu, BB_DIR_USR_BIN, BB_SUID_DROP)) - /* all programs below here are alphabetically "greater than" 'mu' */ +//applet:IF_MU(APPLET(mu, BB_DIR_USR_BIN, BB_SUID_DROP)) The Grand Announcement diff --git a/docs/posix_conformance.txt b/docs/posix_conformance.txt index 5b616d7..c0582dc 100644 --- a/docs/posix_conformance.txt +++ b/docs/posix_conformance.txt @@ -178,6 +178,7 @@ dd POSIX options: conv=noerror | yes | | conv=notrunc | yes | | conv=sync | yes | | + iflag=skip_bytes| yes | | dd Busybox specific options: conv=fsync diff --git a/docs/unit-tests.txt b/docs/unit-tests.txt new file mode 100644 index 0000000..0fb5220 --- a/dev/null +++ b/docs/unit-tests.txt @@ -0,0 +1,50 @@ +Busybox unit test framework +=========================== + +This document describes what you need to do to write test cases using the +Busybox unit test framework. + + +Building unit tests +------------------- + +The framework and all tests are built as a regular Busybox applet if option +CONFIG_UNIT_TEST (found in General Configuration -> Debugging Options) is set. + + +Writing test cases +------------------ + +Unit testing interface can be found in include/bbunit.h. + +Tests can be placed in any .c file in Busybox tree - preferably right next to +the functions they test. Test cases should be enclosed within an #if, and +should start with BBUNIT_DEFINE_TEST macro and end with BBUNIT_ENDTEST within +the test curly brackets. If an assertion fails the test ends immediately, ie. +the following assertions will not be reached. Any code placed after +BBUNIT_ENDTEST is executed regardless of the test result. Here's an example: + +#if ENABLE_UNIT_TEST + +BBUNIT_DEFINE_TEST(test_name) +{ + int *i; + + i = malloc(sizeof(int)); + BBUNIT_ASSERT_NOTNULL(i); + *i = 2; + BBUNIT_ASSERT_EQ((*i)*(*i), 4); + + BBUNIT_ENDTEST; + + free(i); +} + +#endif /* ENABLE_UNIT_TEST */ + + +Running the unit test suite +--------------------------- + +To run the tests you can either directly run 'busybox unit' or use 'make test' +to run both the unit tests (if compiled) and regular test suite. diff --git a/e2fsprogs/Config.src b/e2fsprogs/Config.src index 743e1e1..a20d849 100644 --- a/e2fsprogs/Config.src +++ b/e2fsprogs/Config.src @@ -7,12 +7,6 @@ menu "Linux Ext2 FS Progs" INSERT -config CHATTR - bool "chattr" - default y - help - chattr changes the file attributes on a second extended file system. - ### config E2FSCK ### bool "e2fsck" ### default y @@ -22,21 +16,6 @@ config CHATTR ### The normal compat symlinks 'fsck.ext2' and 'fsck.ext3' are also ### provided. -config FSCK - bool "fsck" - default y - help - fsck is used to check and optionally repair one or more filesystems. - In actuality, fsck is simply a front-end for the various file system - checkers (fsck.fstype) available under Linux. - -config LSATTR - bool "lsattr" - default y - select PLATFORM_LINUX - help - lsattr lists the file attributes on a second extended file system. - ### config MKE2FS ### bool "mke2fs" ### default y @@ -44,13 +23,6 @@ config LSATTR ### mke2fs is used to create an ext2/ext3 filesystem. The normal compat ### symlinks 'mkfs.ext2' and 'mkfs.ext3' are also provided. -config TUNE2FS - bool "tune2fs" - default n # off: it is too limited compared to upstream version - help - tune2fs allows the system administrator to adjust various tunable - filesystem parameters on Linux ext2/ext3 filesystems. - ### config E2LABEL ### bool "e2label" ### default y diff --git a/e2fsprogs/Kbuild.src b/e2fsprogs/Kbuild.src index b7a14c3..6b4fb74 100644 --- a/e2fsprogs/Kbuild.src +++ b/e2fsprogs/Kbuild.src @@ -7,9 +7,3 @@ lib-y:= INSERT - -lib-$(CONFIG_CHATTR) += chattr.o e2fs_lib.o -lib-$(CONFIG_LSATTR) += lsattr.o e2fs_lib.o - -lib-$(CONFIG_FSCK) += fsck.o -lib-$(CONFIG_TUNE2FS) += tune2fs.o diff --git a/e2fsprogs/chattr.c b/e2fsprogs/chattr.c index f1cc838..043f395 100644 --- a/e2fsprogs/chattr.c +++ b/e2fsprogs/chattr.c @@ -9,24 +9,22 @@ * This file can be redistributed under the terms of the GNU General * Public License */ +//config:config CHATTR +//config: bool "chattr" +//config: default y +//config: help +//config: chattr changes the file attributes on a second extended file system. -/* - * 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) - */ +//applet:IF_CHATTR(APPLET(chattr, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_CHATTR) += chattr.o e2fs_lib.o //usage:#define chattr_trivial_usage //usage: "[-R] [-+=AacDdijsStTu] [-v VERSION] [FILE]..." //usage:#define chattr_full_usage "\n\n" -//usage: "Change file attributes on an ext2 fs\n" +//usage: "Change ext2 file attributes\n" //usage: "\nModifiers:" -//usage: "\n - Remove attributes" -//usage: "\n + Add attributes" -//usage: "\n = Set attributes" +//usage: "\n -,+,= Remove/add/set attributes" //usage: "\nAttributes:" //usage: "\n A Don't track atime" //usage: "\n a Append mode only" @@ -36,11 +34,11 @@ //usage: "\n i Cannot be modified (immutable)" //usage: "\n j Write all data to journal first" //usage: "\n s Zero disk storage when deleted" -//usage: "\n S Write file contents synchronously" +//usage: "\n S Write synchronously" //usage: "\n t Disable tail-merging of partial blocks with other files" //usage: "\n u Allow file to be undeleted" //usage: "\n -R Recurse" -//usage: "\n -v Set the file's version/generation number" +//usage: "\n -v VER Set version/generation number" #include "libbb.h" #include "e2fs_lib.h" diff --git a/e2fsprogs/e2fs_lib.c b/e2fsprogs/e2fs_lib.c index a6aec94..6ce655b 100644 --- a/e2fsprogs/e2fs_lib.c +++ b/e2fsprogs/e2fs_lib.c @@ -149,14 +149,14 @@ const uint32_t e2attr_flags_value[] = { EXT2_TOPDIR_FL }; -const char e2attr_flags_sname[] = +const char e2attr_flags_sname[] ALIGN1 = #ifdef ENABLE_COMPRESSION "BZXE" #endif "I" "suSDiadAcjtT"; -static const char e2attr_flags_lname[] = +static const char e2attr_flags_lname[] ALIGN1 = #ifdef ENABLE_COMPRESSION "Compressed_File" "\0" "Compressed_Dirty_File" "\0" diff --git a/e2fsprogs/fsck.c b/e2fsprogs/fsck.c index d32f396..6414988 100644 --- a/e2fsprogs/fsck.c +++ b/e2fsprogs/fsck.c @@ -33,9 +33,20 @@ * spawns actual fsck.something for each filesystem to check. * It doesn't guess filesystem types from on-disk format. */ +//config:config FSCK +//config: bool "fsck" +//config: default y +//config: help +//config: fsck is used to check and optionally repair one or more filesystems. +//config: In actuality, fsck is simply a front-end for the various file system +//config: checkers (fsck.fstype) available under Linux. + +//applet:IF_FSCK(APPLET(fsck, BB_DIR_SBIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_FSCK) += fsck.o //usage:#define fsck_trivial_usage -//usage: "[-ANPRTV] [-C FD] [-t FSTYPE] [FS_OPTS] [BLOCKDEV]..." +//usage: "[-ANPRTV] [-t FSTYPE] [FS_OPTS] [BLOCKDEV]..." //usage:#define fsck_full_usage "\n\n" //usage: "Check and repair filesystems\n" //usage: "\n -A Walk /etc/fstab and check all filesystems" @@ -44,10 +55,12 @@ //usage: "\n -R With -A, skip the root filesystem" //usage: "\n -T Don't show title on startup" //usage: "\n -V Verbose" -//usage: "\n -C n Write status information to specified filedescriptor" +//DO_PROGRESS_INDICATOR is off: +////usage: "\n -C FD Write status information to specified file descriptor" //usage: "\n -t TYPE List of filesystem types to check" #include "libbb.h" +#include "common_bufsiz.h" /* "progress indicator" code is somewhat buggy and ext[23] specific. * We should be filesystem agnostic. IOW: there should be a well-defined @@ -125,35 +138,43 @@ static const char really_wanted[] ALIGN1 = #define BASE_MD "/dev/md" -static char **args; -static int num_args; -static int verbose; +struct globals { + char **args; + int num_args; + int verbose; #define FS_TYPE_FLAG_NORMAL 0 #define FS_TYPE_FLAG_OPT 1 #define FS_TYPE_FLAG_NEGOPT 2 -static char **fs_type_list; -static uint8_t *fs_type_flag; -static smallint fs_type_negated; - -static smallint noexecute; -static smallint serialize; -static smallint skip_root; -/* static smallint like_mount; */ -static smallint parallel_root; -static smallint force_all_parallel; + char **fs_type_list; + uint8_t *fs_type_flag; + smallint fs_type_negated; + + smallint noexecute; + smallint serialize; + smallint skip_root; + /* smallint like_mount; */ + smallint parallel_root; + smallint force_all_parallel; + smallint kill_sent; #if DO_PROGRESS_INDICATOR -static smallint progress; -static int progress_fd; + smallint progress; + int progress_fd; #endif -static int num_running; -static int max_running; -static char *fstype; -static struct fs_info *filesys_info; -static struct fs_info *filesys_last; -static struct fsck_instance *instance_list; + int num_running; + int max_running; + char *fstype; + struct fs_info *filesys_info; + struct fs_info *filesys_last; + struct fsck_instance *instance_list; +} FIX_ALIASING; +#define G (*(struct globals*)bb_common_bufsiz1) +#define INIT_G() do { \ + setup_common_bufsiz(); \ + BUILD_BUG_ON(sizeof(G) > COMMON_BUFSIZE); \ +} while (0) /* * Return the "base device" given a particular device; this is used to @@ -199,7 +220,7 @@ static char *base_device(const char *device) } /* Handle DAC 960 devices */ - if (strncmp(cp, "rd/", 3) == 0) { + if (is_prefixed_with(cp, "rd/")) { cp += 3; if (cp[0] != 'c' || !isdigit(cp[1]) || cp[2] != 'd' || !isdigit(cp[3])) @@ -224,9 +245,9 @@ static char *base_device(const char *device) #if ENABLE_FEATURE_DEVFS /* Now let's handle devfs (ugh) names */ len = 0; - if (strncmp(cp, "ide/", 4) == 0) + if (is_prefixed_with(cp, "ide/")) len = 4; - if (strncmp(cp, "scsi/", 5) == 0) + if (is_prefixed_with(cp, "scsi/")) len = 5; if (len) { cp += len; @@ -237,38 +258,38 @@ static char *base_device(const char *device) * some number of digits at each level, abort. */ for (hier = devfs_hier; *hier; hier++) { - len = strlen(*hier); - if (strncmp(cp, *hier, len) != 0) + cp = is_prefixed_with(cp, *hier); + if (!cp) goto errout; - cp += len; - while (*cp != '/' && *cp != 0) { + while (*cp != '/' && *cp != '\0') { if (!isdigit(*cp)) goto errout; cp++; } +//FIXME: what if *cp = '\0' now? cp++ moves past it!!! cp++; } - cp[-1] = 0; + cp[-1] = '\0'; return str; } /* Now handle devfs /dev/disc or /dev/disk names */ - disk = 0; - if (strncmp(cp, "discs/", 6) == 0) + disk = NULL; + if (is_prefixed_with(cp, "discs/")) disk = "disc"; - else if (strncmp(cp, "disks/", 6) == 0) + else if (is_prefixed_with(cp, "disks/")) disk = "disk"; if (disk) { cp += 6; - if (strncmp(cp, disk, 4) != 0) + cp = is_prefixed_with(cp, disk); + if (!cp) goto errout; - cp += 4; - while (*cp != '/' && *cp != 0) { + while (*cp != '/' && *cp != '\0') { if (!isdigit(*cp)) goto errout; cp++; } - *cp = 0; + *cp = '\0'; return str; } #endif @@ -302,11 +323,11 @@ static struct fs_info *create_fs_device(const char *device, const char *mntpnt, /*fs->flags = 0; */ /*fs->next = NULL; */ - if (!filesys_info) - filesys_info = fs; + if (!G.filesys_info) + G.filesys_info = fs; else - filesys_last->next = fs; - filesys_last = fs; + G.filesys_last->next = fs; + G.filesys_last = fs; return fs; } @@ -316,6 +337,7 @@ static void load_fs_info(const char *filename) { FILE *fstab; struct mntent mte; + char buf[1024]; fstab = setmntent(filename, "r"); if (!fstab) { @@ -324,8 +346,8 @@ static void load_fs_info(const char *filename) } // Loop through entries - while (getmntent_r(fstab, &mte, bb_common_bufsiz1, COMMON_BUFSIZE)) { - //bb_info_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir, + while (getmntent_r(fstab, &mte, buf, sizeof(buf))) { + //bb_error_msg("CREATE[%s][%s][%s][%s][%d]", mte.mnt_fsname, mte.mnt_dir, // mte.mnt_type, mte.mnt_opts, // mte.mnt_passno); create_fs_device(mte.mnt_fsname, mte.mnt_dir, @@ -340,7 +362,7 @@ static struct fs_info *lookup(char *filesys) { struct fs_info *fs; - for (fs = filesys_info; fs; fs = fs->next) { + for (fs = G.filesys_info; fs; fs = fs->next) { if (strcmp(filesys, fs->device) == 0 || (fs->mountpt && strcmp(filesys, fs->mountpt) == 0) ) @@ -355,7 +377,7 @@ static int progress_active(void) { struct fsck_instance *inst; - for (inst = instance_list; inst; inst = inst->next) { + for (inst = G.instance_list; inst; inst = inst->next) { if (inst->flags & FLAG_DONE) continue; if (inst->flags & FLAG_PROGRESS) @@ -371,19 +393,17 @@ static int progress_active(void) */ static void kill_all_if_got_signal(void) { - static smallint kill_sent; - struct fsck_instance *inst; - if (!bb_got_signal || kill_sent) + if (!bb_got_signal || G.kill_sent) return; - for (inst = instance_list; inst; inst = inst->next) { + for (inst = G.instance_list; inst; inst = inst->next) { if (inst->flags & FLAG_DONE) continue; kill(inst->pid, SIGTERM); } - kill_sent = 1; + G.kill_sent = 1; } /* @@ -398,9 +418,9 @@ static int wait_one(int flags) struct fsck_instance *inst, *prev; pid_t pid; - if (!instance_list) + if (!G.instance_list) return -1; - /* if (noexecute) { already returned -1; } */ + /* if (G.noexecute) { already returned -1; } */ while (1) { pid = waitpid(-1, &status, flags); @@ -418,7 +438,7 @@ static int wait_one(int flags) continue; } prev = NULL; - inst = instance_list; + inst = G.instance_list; do { if (inst->pid == pid) goto child_died; @@ -428,9 +448,8 @@ static int wait_one(int flags) } child_died: - if (WIFEXITED(status)) - status = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) { + status = WEXITSTATUS(status); + if (WIFSIGNALED(status)) { sig = WTERMSIG(status); status = EXIT_UNCORRECTED; if (sig != SIGINT) { @@ -439,16 +458,12 @@ static int wait_one(int flags) inst->prog, inst->device, sig); status = EXIT_ERROR; } - } else { - printf("%s %s: status is %x, should never happen\n", - inst->prog, inst->device, status); - status = EXIT_ERROR; } #if DO_PROGRESS_INDICATOR if (progress && (inst->flags & FLAG_PROGRESS) && !progress_active()) { struct fsck_instance *inst2; - for (inst2 = instance_list; inst2; inst2 = inst2->next) { + for (inst2 = G.instance_list; inst2; inst2 = inst2->next) { if (inst2->flags & FLAG_DONE) continue; if (strcmp(inst2->type, "ext2") != 0 @@ -475,11 +490,11 @@ static int wait_one(int flags) if (prev) prev->next = inst->next; else - instance_list = inst->next; - if (verbose > 1) + G.instance_list = inst->next; + if (G.verbose > 1) printf("Finished with %s (exit status %d)\n", inst->device, status); - num_running--; + G.num_running--; free_instance(inst); return status; @@ -515,51 +530,51 @@ static void execute(const char *type, const char *device, struct fsck_instance *inst; pid_t pid; - args[0] = xasprintf("fsck.%s", type); + G.args[0] = xasprintf("fsck.%s", type); #if DO_PROGRESS_INDICATOR if (progress && !progress_active()) { if (strcmp(type, "ext2") == 0 || strcmp(type, "ext3") == 0 ) { - args[XXX] = xasprintf("-C%d", progress_fd); /* 1 */ + G.args[XXX] = xasprintf("-C%d", progress_fd); /* 1 */ inst->flags |= FLAG_PROGRESS; } } #endif - args[num_args - 2] = (char*)device; - /* args[num_args - 1] = NULL; - already is */ + G.args[G.num_args - 2] = (char*)device; + /* G.args[G.num_args - 1] = NULL; - already is */ - if (verbose || noexecute) { - printf("[%s (%d) -- %s]", args[0], num_running, + if (G.verbose || G.noexecute) { + printf("[%s (%d) -- %s]", G.args[0], G.num_running, mntpt ? mntpt : device); - for (i = 0; args[i]; i++) - printf(" %s", args[i]); + for (i = 0; G.args[i]; i++) + printf(" %s", G.args[i]); bb_putchar('\n'); } /* Fork and execute the correct program. */ pid = -1; - if (!noexecute) { - pid = spawn(args); + if (!G.noexecute) { + pid = spawn(G.args); if (pid < 0) - bb_simple_perror_msg(args[0]); + bb_simple_perror_msg(G.args[0]); } #if DO_PROGRESS_INDICATOR - free(args[XXX]); + free(G.args[XXX]); #endif /* No child, so don't record an instance */ if (pid <= 0) { - free(args[0]); + free(G.args[0]); return; } inst = xzalloc(sizeof(*inst)); inst->pid = pid; - inst->prog = args[0]; + inst->prog = G.args[0]; inst->device = xstrdup(device); inst->base_device = base_device(device); #if DO_PROGRESS_INDICATOR @@ -568,8 +583,8 @@ static void execute(const char *type, const char *device, /* Add to the list of running fsck's. * (was adding to the end, but adding to the front is simpler...) */ - inst->next = instance_list; - instance_list = inst; + inst->next = G.instance_list; + G.instance_list = inst; } /* @@ -588,27 +603,27 @@ static void fsck_device(struct fs_info *fs /*, int interactive */) if (strcmp(fs->type, "auto") != 0) { type = fs->type; - if (verbose > 2) - bb_info_msg("using filesystem type '%s' %s", + if (G.verbose > 2) + printf("using filesystem type '%s' %s\n", type, "from fstab"); - } else if (fstype - && (fstype[0] != 'n' || fstype[1] != 'o') /* != "no" */ - && strncmp(fstype, "opts=", 5) != 0 - && strncmp(fstype, "loop", 4) != 0 - && !strchr(fstype, ',') + } else if (G.fstype + && (G.fstype[0] != 'n' || G.fstype[1] != 'o') /* != "no" */ + && !is_prefixed_with(G.fstype, "opts=") + && !is_prefixed_with(G.fstype, "loop") + && !strchr(G.fstype, ',') ) { - type = fstype; - if (verbose > 2) - bb_info_msg("using filesystem type '%s' %s", + type = G.fstype; + if (G.verbose > 2) + printf("using filesystem type '%s' %s\n", type, "from -t"); } else { type = "auto"; - if (verbose > 2) - bb_info_msg("using filesystem type '%s' %s", + if (G.verbose > 2) + printf("using filesystem type '%s' %s\n", type, "(default)"); } - num_running++; + G.num_running++; execute(type, fs->device, fs->mountpt /*, interactive */); } @@ -621,14 +636,14 @@ static int device_already_active(char *device) struct fsck_instance *inst; char *base; - if (force_all_parallel) + if (G.force_all_parallel) return 0; #ifdef BASE_MD /* Don't check a soft raid disk with any other disk */ - if (instance_list - && (!strncmp(instance_list->device, BASE_MD, sizeof(BASE_MD)-1) - || !strncmp(device, BASE_MD, sizeof(BASE_MD)-1)) + if (G.instance_list + && (is_prefixed_with(G.instance_list->device, BASE_MD) + || is_prefixed_with(device, BASE_MD)) ) { return 1; } @@ -640,10 +655,10 @@ static int device_already_active(char *device) * already active if there are any fsck instances running. */ if (!base) - return (instance_list != NULL); + return (G.instance_list != NULL); - for (inst = instance_list; inst; inst = inst->next) { - if (!inst->base_device || !strcmp(base, inst->base_device)) { + for (inst = G.instance_list; inst; inst = inst->next) { + if (!inst->base_device || strcmp(base, inst->base_device) == 0) { free(base); return 1; } @@ -687,17 +702,17 @@ static int fs_match(struct fs_info *fs) int n, ret, checked_type; char *cp; - if (!fs_type_list) + if (!G.fs_type_list) return 1; ret = 0; checked_type = 0; n = 0; while (1) { - cp = fs_type_list[n]; + cp = G.fs_type_list[n]; if (!cp) break; - switch (fs_type_flag[n]) { + switch (G.fs_type_flag[n]) { case FS_TYPE_FLAG_NORMAL: checked_type++; if (strcmp(cp, fs->type) == 0) @@ -717,7 +732,7 @@ static int fs_match(struct fs_info *fs) if (checked_type == 0) return 1; - return (fs_type_negated ? !ret : ret); + return (G.fs_type_negated ? !ret : ret); } /* Check if we should ignore this filesystem. */ @@ -753,7 +768,7 @@ static int check_all(void) smallint pass_done; int passno; - if (verbose) + if (G.verbose) puts("Checking all filesystems"); /* @@ -761,17 +776,17 @@ static int check_all(void) * which should be ignored as done, and resolve any "auto" * filesystem types (done as a side-effect of calling ignore()). */ - for (fs = filesys_info; fs; fs = fs->next) + for (fs = G.filesys_info; fs; fs = fs->next) if (ignore(fs)) fs->flags |= FLAG_DONE; /* * Find and check the root filesystem. */ - if (!parallel_root) { - for (fs = filesys_info; fs; fs = fs->next) { + if (!G.parallel_root) { + for (fs = G.filesys_info; fs; fs = fs->next) { if (LONE_CHAR(fs->mountpt, '/')) { - if (!skip_root && !ignore(fs)) { + if (!G.skip_root && !ignore(fs)) { fsck_device(fs /*, 1*/); status |= wait_many(FLAG_WAIT_ALL); if (status > EXIT_NONDESTRUCT) @@ -787,8 +802,8 @@ static int check_all(void) * filesystem listed twice. * "Skip root" will skip _all_ root entries. */ - if (skip_root) - for (fs = filesys_info; fs; fs = fs->next) + if (G.skip_root) + for (fs = G.filesys_info; fs; fs = fs->next) if (LONE_CHAR(fs->mountpt, '/')) fs->flags |= FLAG_DONE; @@ -798,7 +813,7 @@ static int check_all(void) not_done_yet = 0; pass_done = 1; - for (fs = filesys_info; fs; fs = fs->next) { + for (fs = G.filesys_info; fs; fs = fs->next) { if (bb_got_signal) break; if (fs->flags & FLAG_DONE) @@ -824,7 +839,7 @@ static int check_all(void) /* * Spawn off the fsck process */ - fsck_device(fs /*, serialize*/); + fsck_device(fs /*, G.serialize*/); fs->flags |= FLAG_DONE; /* @@ -832,8 +847,8 @@ static int check_all(void) * have a limit on the number of fsck's extant * at one time, apply that limit. */ - if (serialize - || (max_running && (num_running >= max_running)) + if (G.serialize + || (G.num_running >= G.max_running) ) { pass_done = 0; break; @@ -841,12 +856,12 @@ static int check_all(void) } if (bb_got_signal) break; - if (verbose > 1) + if (G.verbose > 1) printf("--waiting-- (pass %d)\n", passno); status |= wait_many(pass_done ? FLAG_WAIT_ALL : FLAG_WAIT_ATLEAST_ONE); if (pass_done) { - if (verbose > 1) + if (G.verbose > 1) puts("----------------------------------"); passno++; } else @@ -874,9 +889,9 @@ static void compile_fs_type(char *fs_type) s++; } - fs_type_list = xzalloc(num * sizeof(fs_type_list[0])); - fs_type_flag = xzalloc(num * sizeof(fs_type_flag[0])); - fs_type_negated = -1; /* not yet known is it negated or not */ + G.fs_type_list = xzalloc(num * sizeof(G.fs_type_list[0])); + G.fs_type_flag = xzalloc(num * sizeof(G.fs_type_flag[0])); + G.fs_type_negated = -1; /* not yet known is it negated or not */ num = 0; s = fs_type; @@ -895,21 +910,21 @@ static void compile_fs_type(char *fs_type) if (strcmp(s, "loop") == 0) /* loop is really short-hand for opts=loop */ goto loop_special_case; - if (strncmp(s, "opts=", 5) == 0) { + if (is_prefixed_with(s, "opts=")) { s += 5; loop_special_case: - fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT; + G.fs_type_flag[num] = negate ? FS_TYPE_FLAG_NEGOPT : FS_TYPE_FLAG_OPT; } else { - if (fs_type_negated == -1) - fs_type_negated = negate; - if (fs_type_negated != negate) + if (G.fs_type_negated == -1) + G.fs_type_negated = negate; + if (G.fs_type_negated != negate) bb_error_msg_and_die( "either all or none of the filesystem types passed to -t must be prefixed " "with 'no' or '!'"); } - comma = strchr(s, ','); - fs_type_list[num++] = comma ? xstrndup(s, comma-s) : xstrdup(s); - if (!comma) + comma = strchrnul(s, ','); + G.fs_type_list[num++] = xstrndup(s, comma-s); + if (*comma == '\0') break; s = comma + 1; } @@ -917,8 +932,8 @@ static void compile_fs_type(char *fs_type) static char **new_args(void) { - args = xrealloc_vector(args, 2, num_args); - return &args[num_args++]; + G.args = xrealloc_vector(G.args, 2, G.num_args); + return &G.args[G.num_args++]; } int fsck_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; @@ -935,6 +950,8 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) smallint doall; smallint notitle; + INIT_G(); + /* we want wait() to be interruptible */ signal_no_SA_RESTART_empty_mask(SIGINT, record_signo); signal_no_SA_RESTART_empty_mask(SIGTERM, record_signo); @@ -944,8 +961,8 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) opts_for_fsck = doall = notitle = 0; devices = NULL; num_devices = 0; - new_args(); /* args[0] = NULL, will be replaced by fsck. */ - /* instance_list = NULL; - in bss, so already zeroed */ + new_args(); /* G.args[0] = NULL, will be replaced by fsck. */ + /* G.instance_list = NULL; - in bss, so already zeroed */ while (*++argv) { int j; @@ -994,13 +1011,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) goto next_arg; #endif case 'V': - verbose++; + G.verbose++; break; case 'N': - noexecute = 1; + G.noexecute = 1; break; case 'R': - skip_root = 1; + G.skip_root = 1; break; case 'T': notitle = 1; @@ -1009,13 +1026,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) like_mount = 1; break; */ case 'P': - parallel_root = 1; + G.parallel_root = 1; break; case 's': - serialize = 1; + G.serialize = 1; break; case 't': - if (fstype) + if (G.fstype) bb_show_usage(); if (arg[++j]) tmp = &arg[j]; @@ -1023,8 +1040,8 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) tmp = *argv; else bb_show_usage(); - fstype = xstrdup(tmp); - compile_fs_type(fstype); + G.fstype = xstrdup(tmp); + compile_fs_type(G.fstype); goto next_arg; case '?': bb_show_usage(); @@ -1045,12 +1062,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) } } if (getenv("FSCK_FORCE_ALL_PARALLEL")) - force_all_parallel = 1; + G.force_all_parallel = 1; tmp = getenv("FSCK_MAX_INST"); + G.max_running = INT_MAX; if (tmp) - max_running = xatoi(tmp); - new_args(); /* args[num_args - 2] will be replaced by */ - new_args(); /* args[num_args - 1] is the last, NULL element */ + G.max_running = xatoi(tmp); + new_args(); /* G.args[G.num_args - 2] will be replaced by */ + new_args(); /* G.args[G.num_args - 1] is the last, NULL element */ if (!notitle) puts("fsck (busybox "BB_VER", "BB_BT")"); @@ -1062,10 +1080,10 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) fstab = "/etc/fstab"; load_fs_info(fstab); - /*interactive = (num_devices == 1) | serialize;*/ + /*interactive = (num_devices == 1) | G.serialize;*/ if (num_devices == 0) - /*interactive =*/ serialize = doall = 1; + /*interactive =*/ G.serialize = doall = 1; if (doall) return check_all(); @@ -1081,13 +1099,13 @@ int fsck_main(int argc UNUSED_PARAM, char **argv) fs = create_fs_device(devices[i], "", "auto", NULL, -1); fsck_device(fs /*, interactive */); - if (serialize - || (max_running && (num_running >= max_running)) + if (G.serialize + || (G.num_running >= G.max_running) ) { int exit_status = wait_one(0); if (exit_status >= 0) status |= exit_status; - if (verbose > 1) + if (G.verbose > 1) puts("----------------------------------"); } } diff --git a/e2fsprogs/lsattr.c b/e2fsprogs/lsattr.c index 1312fe7..d2348b5 100644 --- a/e2fsprogs/lsattr.c +++ b/e2fsprogs/lsattr.c @@ -9,24 +9,26 @@ * This file can be redistributed under the terms of the GNU General * Public License */ +//config:config LSATTR +//config: bool "lsattr" +//config: default y +//config: select PLATFORM_LINUX +//config: help +//config: lsattr lists the file attributes on a second extended file system. -/* - * 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) - */ +//applet:IF_LSATTR(APPLET(lsattr, BB_DIR_BIN, BB_SUID_DROP)) + +//kbuild:lib-$(CONFIG_LSATTR) += lsattr.o e2fs_lib.o //usage:#define lsattr_trivial_usage //usage: "[-Radlv] [FILE]..." //usage:#define lsattr_full_usage "\n\n" -//usage: "List file attributes on an ext2 fs\n" +//usage: "List ext2 file attributes\n" //usage: "\n -R Recurse" //usage: "\n -a Don't hide entries starting with ." //usage: "\n -d List directory entries instead of contents" //usage: "\n -l List long flag names" -//usage: "\n -v List the file's version/generation number" +//usage: "\n -v List version/generation number" #include "libbb.h" #include "e2fs_lib.h" diff --git a/e2fsprogs/old_e2fsprogs/Config.src b/e2fsprogs/old_e2fsprogs/Config.src deleted file mode 100644 index bbec08e..0000000 --- a/e2fsprogs/old_e2fsprogs/Config.src +++ b/dev/null @@ -1,69 +0,0 @@ -# -# For a description of the syntax of this configuration file, -# see scripts/kbuild/config-language.txt. -# - -menu "Linux Ext2 FS Progs" - -INSERT - -config CHATTR - bool "chattr" - default n - help - chattr changes the file attributes on a second extended file system. - -config E2FSCK - bool "e2fsck" - default n - help - e2fsck is used to check Linux second extended file systems (ext2fs). - e2fsck also supports ext2 filesystems countaining a journal (ext3). - The normal compat symlinks 'fsck.ext2' and 'fsck.ext3' are also - provided. - -config FSCK - bool "fsck" - default n - help - fsck is used to check and optionally repair one or more filesystems. - In actuality, fsck is simply a front-end for the various file system - checkers (fsck.fstype) available under Linux. - -config LSATTR - bool "lsattr" - default n - help - lsattr lists the file attributes on a second extended file system. - -config MKE2FS - bool "mke2fs" - default n - help - mke2fs is used to create an ext2/ext3 filesystem. The normal compat - symlinks 'mkfs.ext2' and 'mkfs.ext3' are also provided. - -config TUNE2FS - bool "tune2fs" - default n - help - tune2fs allows the system administrator to adjust various tunable - filesystem parameters on Linux ext2/ext3 filesystems. - -config E2LABEL - bool "e2label" - default n - depends on TUNE2FS - help - e2label will display or change the filesystem label on the ext2 - filesystem located on device. - -config FINDFS - bool "findfs" - default n - depends on TUNE2FS - help - findfs will search the disks in the system looking for a filesystem - which has a label matching label or a UUID equal to uuid. - -endmenu diff --git a/e2fsprogs/old_e2fsprogs/Kbuild.src b/e2fsprogs/old_e2fsprogs/Kbuild.src deleted file mode 100644 index fff1a0d..0000000 --- a/e2fsprogs/old_e2fsprogs/Kbuild.src +++ b/dev/null @@ -1,18 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under GPLv2, see file LICENSE in this source tree. - -lib-y:= - -INSERT - -lib-$(CONFIG_CHATTR) += chattr.o -lib-$(CONFIG_E2FSCK) += e2fsck.o util.o -lib-$(CONFIG_FSCK) += fsck.o util.o -lib-$(CONFIG_LSATTR) += lsattr.o -lib-$(CONFIG_MKE2FS) += mke2fs.o util.o -lib-$(CONFIG_TUNE2FS) += tune2fs.o util.o - -CFLAGS += -include $(srctree)/e2fsprogs/e2fsbb.h diff --git a/e2fsprogs/old_e2fsprogs/README b/e2fsprogs/old_e2fsprogs/README deleted file mode 100644 index fac0901..0000000 --- a/e2fsprogs/old_e2fsprogs/README +++ b/dev/null @@ -1,3 +0,0 @@ -This is a pretty straight rip from the e2fsprogs pkg. - -See README's in subdirs for specific info. diff --git a/e2fsprogs/old_e2fsprogs/blkid/Kbuild.src b/e2fsprogs/old_e2fsprogs/blkid/Kbuild.src deleted file mode 100644 index 02b4d24..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/Kbuild.src +++ b/dev/null @@ -1,26 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under GPLv2, see file LICENSE in this source tree. - -NEEDED-$(CONFIG_E2FSCK) = y -NEEDED-$(CONFIG_FSCK) = y -NEEDED-$(CONFIG_MKE2FS) = y -NEEDED-$(CONFIG_TUNE2FS) = y - -lib-y:= - -INSERT - -lib-$(NEEDED-y) += cache.o dev.o devname.o devno.o blkid_getsize.o \ - probe.o read.o resolve.o save.o tag.o list.o - -CFLAGS_dev.o := -include $(srctree)/include/busybox.h -CFLAGS_devname.o := -include $(srctree)/include/busybox.h -CFLAGS_devno.o := -include $(srctree)/include/busybox.h -CFLAGS_blkid_getsize.o := -include $(srctree)/include/busybox.h -CFLAGS_probe.o := -include $(srctree)/include/busybox.h -CFLAGS_save.o := -include $(srctree)/include/busybox.h -CFLAGS_tag.o := -include $(srctree)/include/busybox.h -CFLAGS_list.o := -include $(srctree)/include/busybox.h diff --git a/e2fsprogs/old_e2fsprogs/blkid/blkid.h b/e2fsprogs/old_e2fsprogs/blkid/blkid.h deleted file mode 100644 index 9a3c2af..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/blkid.h +++ b/dev/null @@ -1,104 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 1 - -#include -#include - -#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_set_search(blkid_dev_iterate iter, - char *search_type, char *search_value); -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 int blkid_probe_all_new(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 int blkid_dev_has_tag(blkid_dev dev, const char *type, - const char *value); -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); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/e2fsprogs/old_e2fsprogs/blkid/blkidP.h b/e2fsprogs/old_e2fsprogs/blkid/blkidP.h deleted file mode 100644 index bbadc8e..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/blkidP.h +++ b/dev/null @@ -1,182 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 1 - -#include -#include - -#include "blkid.h" -#include "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 -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 -extern void blkid_debug_dump_dev(blkid_dev dev); -extern void blkid_debug_dump_tag(blkid_tag tag); -#endif - -/* lseek.c */ -/* extern blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence); */ -#ifdef CONFIG_LFS -# define blkid_llseek lseek64 -#else -# define blkid_llseek lseek -#endif - -/* 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); - -#endif diff --git a/e2fsprogs/old_e2fsprogs/blkid/blkid_getsize.c b/e2fsprogs/old_e2fsprogs/blkid/blkid_getsize.c deleted file mode 100644 index e1f6ba6..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/blkid_getsize.c +++ b/dev/null @@ -1,179 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#ifdef HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_LINUX_FD_H -#include -#endif -#ifdef HAVE_SYS_DISKLABEL_H -#include -#include -#endif -#ifdef HAVE_SYS_DISK_H -#ifdef HAVE_SYS_QUEUE_H -#include /* for LIST_HEAD */ -#endif -#include -#endif -#ifdef __linux__ -#include -#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__ - uname(&ut); - if ((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 %lld 1k blocks.\n", argv[1], bytes >> 10); - - return 0; -} -#endif diff --git a/e2fsprogs/old_e2fsprogs/blkid/cache.c b/e2fsprogs/old_e2fsprogs/blkid/cache.c deleted file mode 100644 index 251e499..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/cache.c +++ b/dev/null @@ -1,125 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include -#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")); - - cache = xzalloc(sizeof(struct blkid_struct_cache)); - - 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")); - - /* DBG(DEBUG_CACHE, blkid_debug_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); - } - 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, bb_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 --git a/e2fsprogs/old_e2fsprogs/blkid/dev.c b/e2fsprogs/old_e2fsprogs/blkid/dev.c deleted file mode 100644 index 260e49c..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/dev.c +++ b/dev/null @@ -1,213 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include - -#include "blkidP.h" - -blkid_dev blkid_new_dev(void) -{ - blkid_dev dev; - - dev = xzalloc(sizeof(struct blkid_struct_dev)); - - 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)); - DBG(DEBUG_DEV, blkid_debug_dump_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 - */ -const char *blkid_dev_devname(blkid_dev dev) -{ - return dev->bid_name; -} - -#ifdef CONFIG_BLKID_DEBUG -void blkid_debug_dump_dev(blkid_dev dev) -{ - struct list_head *p; - - if (!dev) { - printf(" dev: NULL\n"); - return; - } - - printf(" dev: name = %s\n", dev->bid_name); - printf(" dev: DEVNO=\"0x%0llx\"\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); - if (tag) - printf(" tag: %s=\"%s\"\n", tag->bit_name, - tag->bit_val); - else - printf(" tag: NULL\n"); - } - bb_putchar('\n'); -} -#endif - -/* - * 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; -}; - -blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache) -{ - blkid_dev_iterate iter; - - iter = xmalloc(sizeof(struct blkid_struct_dev_iterate)); - 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; -} - -void blkid_dev_iterate_end(blkid_dev_iterate iter) -{ - if (!iter || iter->magic != DEV_ITERATE_MAGIC) - return; - iter->magic = 0; - free(iter); -} - -#ifdef TEST_PROGRAM -#ifdef HAVE_GETOPT_H -#include -#else -extern char *optarg; -extern int optind; -#endif - -void usage(char *prog) -{ - fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask]\n", prog); - fprintf(stderr, "\tList all devices and exit\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - blkid_dev_iterate iter; - blkid_cache cache = NULL; - blkid_dev dev; - int c, ret; - char *tmp; - char *file = NULL; - char *search_type = NULL; - char *search_value = NULL; - - while ((c = getopt (argc, argv, "m:f:")) != EOF) - switch (c) { - case 'f': - file = optarg; - break; - case 'm': - blkid_debug_mask = strtoul (optarg, &tmp, 0); - if (*tmp) { - fprintf(stderr, "Invalid debug mask: %s\n", - optarg); - exit(1); - } - break; - case '?': - usage(argv[0]); - } - if (argc >= optind+2) { - search_type = argv[optind]; - search_value = argv[optind+1]; - optind += 2; - } - if (argc != optind) - usage(argv[0]); - - if ((ret = blkid_get_cache(&cache, file)) != 0) { - fprintf(stderr, "%s: error creating cache (%d)\n", - argv[0], ret); - exit(1); - } - - iter = blkid_dev_iterate_begin(cache); - if (search_type) - blkid_dev_set_search(iter, search_type, search_value); - while (blkid_dev_next(iter, &dev) == 0) { - printf("Device: %s\n", blkid_dev_devname(dev)); - } - blkid_dev_iterate_end(iter); - - - blkid_put_cache(cache); - return 0; -} -#endif diff --git a/e2fsprogs/old_e2fsprogs/blkid/devname.c b/e2fsprogs/old_e2fsprogs/blkid/devname.c deleted file mode 100644 index fad92cb..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/devname.c +++ b/dev/null @@ -1,367 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include -#include -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#include -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_SYS_MKDEV_H -#include -#endif -#include - -#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; -} - -#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 -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_for_read(lvm_device)) == 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 (LONE_CHAR(vg_name, '.') || !strcmp(vg_name, "..")) - continue; - vdirname = xmalloc(vg_len + strlen(vg_name) + 8); - 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 (LONE_CHAR(lv_name, '.') || !strcmp(lv_name, "..")) - continue; - - lvm_device = xmalloc(vg_len + strlen(vg_name) + - strlen(lv_name) + 8); - 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); - } - 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_for_read(PROC_EVMS_VOLUMES); - 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 = NULL; - 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(NULL) - 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_for_read(PROC_PARTITIONS); - 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(NULL); - 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, bb_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 --git a/e2fsprogs/old_e2fsprogs/blkid/devno.c b/e2fsprogs/old_e2fsprogs/blkid/devno.c deleted file mode 100644 index ae326f8..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/devno.c +++ b/dev/null @@ -1,222 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#include -#include -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_SYS_MKDEV_H -#include -#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 = xmalloc(length + 1); - 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 = xmalloc(sizeof(struct dir_list)); - dp->name = blkid_strdup(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 = 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%llx at %s (%p)\n", devno, - path, *devname)); - break; - } - } - closedir(dir); -} - -/* 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: cannot find devno 0x%04lx\n", - (unsigned long) devno)); - } else { - DBG(DEBUG_DEVNO, - printf("found devno 0x%04llx 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 = "Cannot 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); - free(devname); - return 0; -} -#endif diff --git a/e2fsprogs/old_e2fsprogs/blkid/list.c b/e2fsprogs/old_e2fsprogs/blkid/list.c deleted file mode 100644 index 04d61a1..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/list.c +++ b/dev/null @@ -1,110 +0,0 @@ -/* vi: set sw=4 ts=4: */ - -#include "list.h" - -/* - * Insert a new entry between two known consecutive entries. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -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. - */ -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. - */ -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! - */ -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. - */ -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. - */ -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. - */ -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. - */ -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; - } -} diff --git a/e2fsprogs/old_e2fsprogs/blkid/list.h b/e2fsprogs/old_e2fsprogs/blkid/list.h deleted file mode 100644 index a24baaa..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/list.h +++ b/dev/null @@ -1,73 +0,0 @@ -/* vi: set sw=4 ts=4: */ -#if !defined(_BLKID_LIST_H) && !defined(LIST_HEAD) -#define BLKID_LIST_H 1 - -#ifdef __cplusplus -extern "C" { -#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) - -void __list_add(struct list_head * add, struct list_head * prev, struct list_head * next); -void list_add(struct list_head *add, struct list_head *head); -void list_add_tail(struct list_head *add, struct list_head *head); -void __list_del(struct list_head * prev, struct list_head * next); -void list_del(struct list_head *entry); -void list_del_init(struct list_head *entry); -int list_empty(struct list_head *head); -void list_splice(struct list_head *list, struct list_head *head); - -/** - * 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) - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/e2fsprogs/old_e2fsprogs/blkid/probe.c b/e2fsprogs/old_e2fsprogs/blkid/probe.c deleted file mode 100644 index 651193b..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/probe.c +++ b/dev/null @@ -1,726 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_MKDEV_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#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 = NULL; - - 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, - const struct blkid_magic *id __BLKID_ATTR((unused)), - 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, - const struct blkid_magic *id __BLKID_ATTR((unused)), - 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; - - 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, - const 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, - const struct blkid_magic *id __BLKID_ATTR((unused)), - unsigned char *buf) -{ - struct vfat_super_block *vs; - char serno[10]; - const char *label = NULL; - 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, - const 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 = NULL; - 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, - const struct blkid_magic *id __BLKID_ATTR((unused)), - unsigned char *buf) -{ - struct xfs_super_block *xs; - const char *label = NULL; - - 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, - const struct blkid_magic *id, unsigned char *buf) -{ - struct reiserfs_super_block *rs = (struct reiserfs_super_block *) buf; - unsigned int blocksize; - const char *label = NULL; - - 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, - const struct blkid_magic *id __BLKID_ATTR((unused)), - unsigned char *buf) -{ - struct jfs_super_block *js; - const char *label = NULL; - - 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, - const struct blkid_magic *id __BLKID_ATTR((unused)), - unsigned char *buf) -{ - struct romfs_super_block *ros; - const char *label = NULL; - - 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_cramfs(int fd __BLKID_ATTR((unused)), - blkid_cache cache __BLKID_ATTR((unused)), - blkid_dev dev, - const struct blkid_magic *id __BLKID_ATTR((unused)), - unsigned char *buf) -{ - struct cramfs_super_block *csb; - const char *label = NULL; - - csb = (struct cramfs_super_block *)buf; - - if (strlen((char *) csb->name)) - label = (char *) csb->name; - 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, - const 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, - const struct blkid_magic *id __BLKID_ATTR((unused)), - unsigned char *buf __BLKID_ATTR((unused))) -{ - struct swap_id_block *sws; - - 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; - sws = xmalloc(1024); - 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", (const char*)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 -* const 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)), - const struct blkid_magic *id __BLKID_ATTR((unused)), - unsigned char *buf __BLKID_ATTR((unused))) -{ - int j, bs; - struct iso_volume_descriptor isosb; - const char *const *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, - const 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", (const char*)ovl.label, ocfslabellen(ovl)); - blkid_set_tag(dev, "MOUNT", (const char*)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, - const 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", (const char*)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, - const 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 const 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\050", probe_cramfs }, - { "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) -{ - const 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(NULL); - 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)); - - fd = open(dev->bid_name, O_RDONLY); - if (fd < 0 - || fstat(fd, &st) < 0 - ) { - if (fd >= 0) - close(fd); - 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; - - buf = xmalloc(1024); - - 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); - close(fd); - return NULL; - } - -found_type: - if (dev && type) { - dev->bid_devno = st.st_rdev; - dev->bid_time = time(NULL); - 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%04llx, type %s\n", - dev->bid_name, st.st_rdev, type)); - } - - close(fd); - - return dev; -} - -int blkid_known_fstype(const char *fstype) -{ - const 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, bb_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 --git a/e2fsprogs/old_e2fsprogs/blkid/probe.h b/e2fsprogs/old_e2fsprogs/blkid/probe.h deleted file mode 100644 index b6d8f8e..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/probe.h +++ b/dev/null @@ -1,374 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 1 - -#include - -struct blkid_magic; - -typedef int (*blkid_probe_t)(int fd, blkid_cache cache, blkid_dev dev, - const 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 cramfs_super_block { - __u8 magic[4]; - __u32 size; - __u32 flags; - __u32 future; - __u8 signature[16]; - struct cramfs_info { - __u32 crc; - __u32 edition; - __u32 blocks; - __u32 files; - } info; - __u8 name[16]; -}; - -struct swap_id_block { -/* unsigned char sws_boot[1024]; */ - __u32 sws_version; - __u32 sws_lastpage; - __u32 sws_nrbad; - unsigned char sws_uuid[16]; - 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]; - char mount[128]; - unsigned char mount_len[2]; -}; - -struct ocfs_volume_label { - unsigned char disk_lock[48]; - 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]; - 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((__u32)val)) << 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((__u32)val)) << 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 --git a/e2fsprogs/old_e2fsprogs/blkid/read.c b/e2fsprogs/old_e2fsprogs/blkid/read.c deleted file mode 100644 index feeda51..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/read.c +++ b/dev/null @@ -1,459 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include -#include -#include -#include -#include -#include -#include - -#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 - -#include - -#ifdef TEST_PROGRAM -#define blkid_debug_dump_dev(dev) (debug_dump_dev(dev)) -static void debug_dump_dev(blkid_dev dev); -#endif - -/* - * File format: - * - * ...]>device_name - * - * The following tags are required for each entry: - * unique (within this file) ID number of this device - * (ascii time_t) time this entry was last read from disk - * (detected) type of filesystem/data for this partition - * - * The following tags may be present, depending on the device contents - * (user supplied) label (volume name, etc) - * (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; -} - -/* - * Start parsing a new line from the cache. - * - * line starts with " continue parsing line - * line starts with " 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, "", 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: - * devname - * devnamebar - */ -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 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 value 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 /dev/foo - * - * 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); - } - - DBG(DEBUG_READ, blkid_debug_dump_dev(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 = xfdopen_for_read(fd); - - 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 (end < sizeof(buf) - 2 && buf[end] == '\\' && - 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); -} - -#ifdef TEST_PROGRAM -static void debug_dump_dev(blkid_dev dev) -{ - struct list_head *p; - - if (!dev) { - printf(" dev: NULL\n"); - return; - } - - printf(" dev: name = %s\n", dev->bid_name); - printf(" dev: DEVNO=\"0x%0llx\"\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); - if (tag) - printf(" tag: %s=\"%s\"\n", tag->bit_name, - tag->bit_val); - else - printf(" tag: NULL\n"); - } - bb_putchar('\n'); -} - -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 --git a/e2fsprogs/old_e2fsprogs/blkid/resolve.c b/e2fsprogs/old_e2fsprogs/blkid/resolve.c deleted file mode 100644 index 295ca61..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/resolve.c +++ b/dev/null @@ -1,139 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include -#include -#include -#include -#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 = NULL, *v = NULL; - 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: - free(t); - 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, bb_dev_null) < 0) { - fprintf(stderr, "Can'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 : ""); - } else { - value = blkid_get_devname(cache, argv[1], NULL); - printf("%s has tag %s\n", value ? value : "", argv[1]); - } - blkid_put_cache(cache); - return value ? 0 : 1; -} -#endif diff --git a/e2fsprogs/old_e2fsprogs/blkid/save.c b/e2fsprogs/old_e2fsprogs/blkid/save.c deleted file mode 100644 index e60cca4..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/save.c +++ b/dev/null @@ -1,189 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include -#include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_MKDEV_H -#include -#endif -#ifdef HAVE_ERRNO_H -#include -#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, - "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\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 = xmalloc(strlen(filename) + 8); - sprintf(tmp, "%s-XXXXXX", filename); - fd = mkstemp(tmp); - if (fd >= 0) { - file = xfdopen_for_write(fd); - opened = tmp; - } - fchmod(fd, 0644); - } - - if (!file) { - file = fopen_for_write(filename); - 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 = xmalloc(strlen(filename) + 5); - 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: - 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, bb_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 --git a/e2fsprogs/old_e2fsprogs/blkid/tag.c b/e2fsprogs/old_e2fsprogs/blkid/tag.c deleted file mode 100644 index 7424ede..0000000 --- a/e2fsprogs/old_e2fsprogs/blkid/tag.c +++ b/dev/null @@ -1,431 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include - -#include "blkidP.h" - -static blkid_tag blkid_new_tag(void) -{ - blkid_tag tag; - - tag = xzalloc(sizeof(struct blkid_struct_tag)); - - INIT_LIST_HEAD(&tag->bit_tags); - INIT_LIST_HEAD(&tag->bit_names); - - return tag; -} - -#ifdef CONFIG_BLKID_DEBUG -void blkid_debug_dump_tag(blkid_tag tag) -{ - if (!tag) { - printf(" tag: NULL\n"); - return; - } - - printf(" tag: %s=\"%s\"\n", tag->bit_name, tag->bit_val); -} -#endif - -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)")); - DBG(DEBUG_TAG, blkid_debug_dump_tag(tag)); - - list_del(&tag->bit_tags); /* list of tags for this device */ - list_del(&tag->bit_names); /* list of tags with this type */ - - free(tag->bit_name); - 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 = NULL; - - 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) { - 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: - blkid_free_tag(t); - if (!t) - free(val); - 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; -}; - -blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev) -{ - blkid_tag_iterate iter; - - iter = xmalloc(sizeof(struct blkid_struct_tag_iterate)); - 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; -} - -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; -} - -#ifdef TEST_PROGRAM -#ifdef HAVE_GETOPT_H -#include -#else -extern char *optarg; -extern int optind; -#endif - -void usage(char *prog) -{ - fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask] device " - "[type value]\n", - prog); - fprintf(stderr, "\tList all tags for a device and exit\n"); - exit(1); -} - -int main(int argc, char **argv) -{ - blkid_tag_iterate iter; - blkid_cache cache = NULL; - blkid_dev dev; - int c, ret, found; - int flags = BLKID_DEV_FIND; - char *tmp; - char *file = NULL; - char *devname = NULL; - char *search_type = NULL; - char *search_value = NULL; - const char *type, *value; - - while ((c = getopt (argc, argv, "m:f:")) != EOF) - switch (c) { - case 'f': - file = optarg; - break; - case 'm': - blkid_debug_mask = strtoul (optarg, &tmp, 0); - if (*tmp) { - fprintf(stderr, "Invalid debug mask: %s\n", - optarg); - exit(1); - } - break; - case '?': - usage(argv[0]); - } - if (argc > optind) - devname = argv[optind++]; - if (argc > optind) - search_type = argv[optind++]; - if (argc > optind) - search_value = argv[optind++]; - if (!devname || (argc != optind)) - usage(argv[0]); - - if ((ret = blkid_get_cache(&cache, file)) != 0) { - fprintf(stderr, "%s: error creating cache (%d)\n", - argv[0], ret); - exit(1); - } - - dev = blkid_get_dev(cache, devname, flags); - if (!dev) { - fprintf(stderr, "%s: cannot find device in blkid cache\n", devname); - exit(1); - } - if (search_type) { - found = blkid_dev_has_tag(dev, search_type, search_value); - printf("Device %s: (%s, %s) %s\n", blkid_dev_devname(dev), - search_type, search_value ? search_value : "NULL", - found ? "FOUND" : "NOT FOUND"); - return !found; - } - printf("Device %s...\n", blkid_dev_devname(dev)); - - iter = blkid_tag_iterate_begin(dev); - while (blkid_tag_next(iter, &type, &value) == 0) { - printf("\tTag %s has value %s\n", type, value); - } - blkid_tag_iterate_end(iter); - - blkid_put_cache(cache); - return 0; -} -#endif diff --git a/e2fsprogs/old_e2fsprogs/chattr.c b/e2fsprogs/old_e2fsprogs/chattr.c deleted file mode 100644 index ae39d92..0000000 --- a/e2fsprogs/old_e2fsprogs/chattr.c +++ b/dev/null @@ -1,220 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * chattr.c - Change file attributes on an ext2 file system - * - * Copyright (C) 1993, 1994 Remy Card - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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; - -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] || (de->d_name[1] == '.' && !de->d_name[2])) - ) { - 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) MAIN_EXTERNALLY_VISIBLE; -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 */ - 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 --git a/e2fsprogs/old_e2fsprogs/e2fsbb.h b/e2fsprogs/old_e2fsprogs/e2fsbb.h deleted file mode 100644 index d31c319..0000000 --- a/e2fsprogs/old_e2fsprogs/e2fsbb.h +++ b/dev/null @@ -1,43 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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.38" -#define E2FSPROGS_DATE "30-Jun-2005" - -typedef long errcode_t; -#define ERRCODE_RANGE 8 -#define error_message(code) strerror((int) (code & ((1< - * Free Software License: - * All rights are reserved by the author, with the following exceptions: - * Permission is granted to freely reproduce and distribute this software, - * possibly in exchange for a fee, provided that this copyright notice appears - * intact. Permission is also granted to adapt this software to produce - * derivative works, as long as the modified versions carry this copyright - * notice and additional notices stating that the work has been modified. - * This source code may be translated into executable form and incorporated - * into proprietary software; there is no requirement for such software to - * contain a copyright notice related to this source. - * - * linux/fs/recovery and linux/fs/revoke - * Written by Stephen C. Tweedie , 1999 - * - * Copyright 1999-2000 Red Hat Software --- All Rights Reserved - * - * Journal recovery routines for the generic filesystem journaling code; - * part of the ext2fs journaling system. - * - * Licensed under GPLv2 or later, see file LICENSE in this source tree. - */ - -/* -//usage:#define e2fsck_trivial_usage -//usage: "[-panyrcdfvstDFSV] [-b superblock] [-B blocksize] " -//usage: "[-I inode_buffer_blocks] [-P process_inode_size] " -//usage: "[-l|-L bad_blocks_file] [-C fd] [-j external_journal] " -//usage: "[-E extended-options] device" -//usage:#define e2fsck_full_usage "\n\n" -//usage: "Check ext2/ext3 file system\n" -//usage: "\n -p Automatic repair (no questions)" -//usage: "\n -n Make no changes to the filesystem" -//usage: "\n -y Assume 'yes' to all questions" -//usage: "\n -c Check for bad blocks and add them to the badblock list" -//usage: "\n -f Force checking even if filesystem is marked clean" -//usage: "\n -v Verbose" -//usage: "\n -b superblock Use alternative superblock" -//usage: "\n -B blocksize Force blocksize when looking for superblock" -//usage: "\n -j journal Set location of the external journal" -//usage: "\n -l file Add to badblocks list" -//usage: "\n -L file Set badblocks list" -*/ - -#include "e2fsck.h" /*Put all of our defines here to clean things up*/ - -#define _(x) x -#define N_(x) x - -/* - * Procedure declarations - */ - -static void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf); - -/* pass1.c */ -static void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool); - -/* pass2.c */ -static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, - ext2_ino_t ino, char *buf); - -/* pass3.c */ -static int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t inode); -static errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir, - int num, int gauranteed_size); -static ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix); -static errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, - int adj); - -/* rehash.c */ -static void e2fsck_rehash_directories(e2fsck_t ctx); - -/* util.c */ -static void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, - const char *description); -static int ask(e2fsck_t ctx, const char * string, int def); -static void e2fsck_read_bitmaps(e2fsck_t ctx); -static void preenhalt(e2fsck_t ctx); -static void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino, - struct ext2_inode * inode, const char * proc); -static void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino, - struct ext2_inode * inode, const char * proc); -static blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, - const char *name, io_manager manager); - -/* unix.c */ -static void e2fsck_clear_progbar(e2fsck_t ctx); -static int e2fsck_simple_progress(e2fsck_t ctx, const char *label, - float percent, unsigned int dpynum); - - -/* - * problem.h --- e2fsck problem error codes - */ - -typedef __u32 problem_t; - -struct problem_context { - errcode_t errcode; - ext2_ino_t ino, ino2, dir; - struct ext2_inode *inode; - struct ext2_dir_entry *dirent; - blk_t blk, blk2; - e2_blkcnt_t blkcount; - int group; - __u64 num; - const char *str; -}; - - -/* - * Function declarations - */ -static int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx); -static int end_problem_latch(e2fsck_t ctx, int mask); -static int set_latch_flags(int mask, int setflags, int clearflags); -static void clear_problem_context(struct problem_context *ctx); - -/* - * Dictionary Abstract Data Type - * Copyright (C) 1997 Kaz Kylheku - * - * dict.h v 1.22.2.6 2000/11/13 01:36:44 kaz - * kazlib_1_20 - */ - -#ifndef DICT_H -#define DICT_H - -/* - * Blurb for inclusion into C++ translation units - */ - -typedef unsigned long dictcount_t; -#define DICTCOUNT_T_MAX ULONG_MAX - -/* - * The dictionary is implemented as a red-black tree - */ - -typedef enum { dnode_red, dnode_black } dnode_color_t; - -typedef struct dnode_t { - struct dnode_t *dict_left; - struct dnode_t *dict_right; - struct dnode_t *dict_parent; - dnode_color_t dict_color; - const void *dict_key; - void *dict_data; -} dnode_t; - -typedef int (*dict_comp_t)(const void *, const void *); -typedef void (*dnode_free_t)(dnode_t *); - -typedef struct dict_t { - dnode_t dict_nilnode; - dictcount_t dict_nodecount; - dictcount_t dict_maxcount; - dict_comp_t dict_compare; - dnode_free_t dict_freenode; - int dict_dupes; -} dict_t; - -typedef void (*dnode_process_t)(dict_t *, dnode_t *, void *); - -typedef struct dict_load_t { - dict_t *dict_dictptr; - dnode_t dict_nilnode; -} dict_load_t; - -#define dict_count(D) ((D)->dict_nodecount) -#define dnode_get(N) ((N)->dict_data) -#define dnode_getkey(N) ((N)->dict_key) - -#endif - -/* - * Compatibility header file for e2fsck which should be included - * instead of linux/jfs.h - * - * Copyright (C) 2000 Stephen C. Tweedie - */ - -/* - * Pull in the definition of the e2fsck context structure - */ - -struct buffer_head { - char b_data[8192]; - e2fsck_t b_ctx; - io_channel b_io; - int b_size; - blk_t b_blocknr; - int b_dirty; - int b_uptodate; - int b_err; -}; - - -#define K_DEV_FS 1 -#define K_DEV_JOURNAL 2 - -#define lock_buffer(bh) do {} while (0) -#define unlock_buffer(bh) do {} while (0) -#define buffer_req(bh) 1 -#define do_readahead(journal, start) do {} while (0) - -static e2fsck_t e2fsck_global_ctx; /* Try your very best not to use this! */ - -typedef struct { - int object_length; -} kmem_cache_t; - -#define kmem_cache_alloc(cache,flags) malloc((cache)->object_length) - -/* - * We use the standard libext2fs portability tricks for inline - * functions. - */ - -static kmem_cache_t * do_cache_create(int len) -{ - kmem_cache_t *new_cache; - - new_cache = xmalloc(sizeof(*new_cache)); - new_cache->object_length = len; - return new_cache; -} - -static void do_cache_destroy(kmem_cache_t *cache) -{ - free(cache); -} - - -/* - * Dictionary Abstract Data Type - */ - - -/* - * These macros provide short convenient names for structure members, - * which are embellished with dict_ prefixes so that they are - * properly confined to the documented namespace. It's legal for a - * program which uses dict to define, for instance, a macro called ``parent''. - * Such a macro would interfere with the dnode_t struct definition. - * In general, highly portable and reusable C modules which expose their - * structures need to confine structure member names to well-defined spaces. - * The resulting identifiers aren't necessarily convenient to use, nor - * readable, in the implementation, however! - */ - -#define left dict_left -#define right dict_right -#define parent dict_parent -#define color dict_color -#define key dict_key -#define data dict_data - -#define nilnode dict_nilnode -#define maxcount dict_maxcount -#define compare dict_compare -#define dupes dict_dupes - -#define dict_root(D) ((D)->nilnode.left) -#define dict_nil(D) (&(D)->nilnode) - -static void dnode_free(dnode_t *node); - -/* - * Perform a ``left rotation'' adjustment on the tree. The given node P and - * its right child C are rearranged so that the P instead becomes the left - * child of C. The left subtree of C is inherited as the new right subtree - * for P. The ordering of the keys within the tree is thus preserved. - */ - -static void rotate_left(dnode_t *upper) -{ - dnode_t *lower, *lowleft, *upparent; - - lower = upper->right; - upper->right = lowleft = lower->left; - lowleft->parent = upper; - - lower->parent = upparent = upper->parent; - - /* don't need to check for root node here because root->parent is - the sentinel nil node, and root->parent->left points back to root */ - - if (upper == upparent->left) { - upparent->left = lower; - } else { - assert (upper == upparent->right); - upparent->right = lower; - } - - lower->left = upper; - upper->parent = lower; -} - -/* - * This operation is the ``mirror'' image of rotate_left. It is - * the same procedure, but with left and right interchanged. - */ - -static void rotate_right(dnode_t *upper) -{ - dnode_t *lower, *lowright, *upparent; - - lower = upper->left; - upper->left = lowright = lower->right; - lowright->parent = upper; - - lower->parent = upparent = upper->parent; - - if (upper == upparent->right) { - upparent->right = lower; - } else { - assert (upper == upparent->left); - upparent->left = lower; - } - - lower->right = upper; - upper->parent = lower; -} - -/* - * Do a postorder traversal of the tree rooted at the specified - * node and free everything under it. Used by dict_free(). - */ - -static void free_nodes(dict_t *dict, dnode_t *node, dnode_t *nil) -{ - if (node == nil) - return; - free_nodes(dict, node->left, nil); - free_nodes(dict, node->right, nil); - dict->dict_freenode(node); -} - -/* - * Verify that the tree contains the given node. This is done by - * traversing all of the nodes and comparing their pointers to the - * given pointer. Returns 1 if the node is found, otherwise - * returns zero. It is intended for debugging purposes. - */ - -static int verify_dict_has_node(dnode_t *nil, dnode_t *root, dnode_t *node) -{ - if (root != nil) { - return root == node - || verify_dict_has_node(nil, root->left, node) - || verify_dict_has_node(nil, root->right, node); - } - return 0; -} - - -/* - * Select a different set of node allocator routines. - */ - -static void dict_set_allocator(dict_t *dict, dnode_free_t fr) -{ - assert(dict_count(dict) == 0); - dict->dict_freenode = fr; -} - -/* - * Free all the nodes in the dictionary by using the dictionary's - * installed free routine. The dictionary is emptied. - */ - -static void dict_free_nodes(dict_t *dict) -{ - dnode_t *nil = dict_nil(dict), *root = dict_root(dict); - free_nodes(dict, root, nil); - dict->dict_nodecount = 0; - dict->nilnode.left = &dict->nilnode; - dict->nilnode.right = &dict->nilnode; -} - -/* - * Initialize a user-supplied dictionary object. - */ - -static dict_t *dict_init(dict_t *dict, dictcount_t maxcount, dict_comp_t comp) -{ - dict->compare = comp; - dict->dict_freenode = dnode_free; - dict->dict_nodecount = 0; - dict->maxcount = maxcount; - dict->nilnode.left = &dict->nilnode; - dict->nilnode.right = &dict->nilnode; - dict->nilnode.parent = &dict->nilnode; - dict->nilnode.color = dnode_black; - dict->dupes = 0; - return dict; -} - -/* - * Locate a node in the dictionary having the given key. - * If the node is not found, a null a pointer is returned (rather than - * a pointer that dictionary's nil sentinel node), otherwise a pointer to the - * located node is returned. - */ - -static dnode_t *dict_lookup(dict_t *dict, const void *key) -{ - dnode_t *root = dict_root(dict); - dnode_t *nil = dict_nil(dict); - dnode_t *saved; - int result; - - /* simple binary search adapted for trees that contain duplicate keys */ - - while (root != nil) { - result = dict->compare(key, root->key); - if (result < 0) - root = root->left; - else if (result > 0) - root = root->right; - else { - if (!dict->dupes) { /* no duplicates, return match */ - return root; - } else { /* could be dupes, find leftmost one */ - do { - saved = root; - root = root->left; - while (root != nil && dict->compare(key, root->key)) - root = root->right; - } while (root != nil); - return saved; - } - } - } - - return NULL; -} - -/* - * Insert a node into the dictionary. The node should have been - * initialized with a data field. All other fields are ignored. - * The behavior is undefined if the user attempts to insert into - * a dictionary that is already full (for which the dict_isfull() - * function returns true). - */ - -static void dict_insert(dict_t *dict, dnode_t *node, const void *key) -{ - dnode_t *where = dict_root(dict), *nil = dict_nil(dict); - dnode_t *parent = nil, *uncle, *grandpa; - int result = -1; - - node->key = key; - - /* basic binary tree insert */ - - while (where != nil) { - parent = where; - result = dict->compare(key, where->key); - /* trap attempts at duplicate key insertion unless it's explicitly allowed */ - assert(dict->dupes || result != 0); - if (result < 0) - where = where->left; - else - where = where->right; - } - - assert(where == nil); - - if (result < 0) - parent->left = node; - else - parent->right = node; - - node->parent = parent; - node->left = nil; - node->right = nil; - - dict->dict_nodecount++; - - /* red black adjustments */ - - node->color = dnode_red; - - while (parent->color == dnode_red) { - grandpa = parent->parent; - if (parent == grandpa->left) { - uncle = grandpa->right; - if (uncle->color == dnode_red) { /* red parent, red uncle */ - parent->color = dnode_black; - uncle->color = dnode_black; - grandpa->color = dnode_red; - node = grandpa; - parent = grandpa->parent; - } else { /* red parent, black uncle */ - if (node == parent->right) { - rotate_left(parent); - parent = node; - assert (grandpa == parent->parent); - /* rotation between parent and child preserves grandpa */ - } - parent->color = dnode_black; - grandpa->color = dnode_red; - rotate_right(grandpa); - break; - } - } else { /* symmetric cases: parent == parent->parent->right */ - uncle = grandpa->left; - if (uncle->color == dnode_red) { - parent->color = dnode_black; - uncle->color = dnode_black; - grandpa->color = dnode_red; - node = grandpa; - parent = grandpa->parent; - } else { - if (node == parent->left) { - rotate_right(parent); - parent = node; - assert (grandpa == parent->parent); - } - parent->color = dnode_black; - grandpa->color = dnode_red; - rotate_left(grandpa); - break; - } - } - } - - dict_root(dict)->color = dnode_black; -} - -/* - * Allocate a node using the dictionary's allocator routine, give it - * the data item. - */ - -static dnode_t *dnode_init(dnode_t *dnode, void *data) -{ - dnode->data = data; - dnode->parent = NULL; - dnode->left = NULL; - dnode->right = NULL; - return dnode; -} - -static int dict_alloc_insert(dict_t *dict, const void *key, void *data) -{ - dnode_t *node = xmalloc(sizeof(dnode_t)); - - dnode_init(node, data); - dict_insert(dict, node, key); - return 1; -} - -/* - * Return the node with the lowest (leftmost) key. If the dictionary is empty - * (that is, dict_isempty(dict) returns 1) a null pointer is returned. - */ - -static dnode_t *dict_first(dict_t *dict) -{ - dnode_t *nil = dict_nil(dict), *root = dict_root(dict), *left; - - if (root != nil) - while ((left = root->left) != nil) - root = left; - - return (root == nil) ? NULL : root; -} - -/* - * Return the given node's successor node---the node which has the - * next key in the left to right ordering. If the node has - * no successor, a null pointer is returned rather than a pointer to - * the nil node. - */ - -static dnode_t *dict_next(dict_t *dict, dnode_t *curr) -{ - dnode_t *nil = dict_nil(dict), *parent, *left; - - if (curr->right != nil) { - curr = curr->right; - while ((left = curr->left) != nil) - curr = left; - return curr; - } - - parent = curr->parent; - - while (parent != nil && curr == parent->right) { - curr = parent; - parent = curr->parent; - } - - return (parent == nil) ? NULL : parent; -} - - -static void dnode_free(dnode_t *node) -{ - free(node); -} - - -#undef left -#undef right -#undef parent -#undef color -#undef key -#undef data - -#undef nilnode -#undef maxcount -#undef compare -#undef dupes - - -/* - * dirinfo.c --- maintains the directory information table for e2fsck. - */ - -/* - * This subroutine is called during pass1 to create a directory info - * entry. During pass1, the passed-in parent is 0; it will get filled - * in during pass2. - */ -static void e2fsck_add_dir_info(e2fsck_t ctx, ext2_ino_t ino, ext2_ino_t parent) -{ - struct dir_info *dir; - int i, j; - ext2_ino_t num_dirs; - errcode_t retval; - unsigned long old_size; - - if (!ctx->dir_info) { - ctx->dir_info_count = 0; - retval = ext2fs_get_num_dirs(ctx->fs, &num_dirs); - if (retval) - num_dirs = 1024; /* Guess */ - ctx->dir_info_size = num_dirs + 10; - ctx->dir_info = (struct dir_info *) - e2fsck_allocate_memory(ctx, ctx->dir_info_size - * sizeof (struct dir_info), - "directory map"); - } - - if (ctx->dir_info_count >= ctx->dir_info_size) { - old_size = ctx->dir_info_size * sizeof(struct dir_info); - ctx->dir_info_size += 10; - retval = ext2fs_resize_mem(old_size, ctx->dir_info_size * - sizeof(struct dir_info), - &ctx->dir_info); - if (retval) { - ctx->dir_info_size -= 10; - return; - } - } - - /* - * Normally, add_dir_info is called with each inode in - * sequential order; but once in a while (like when pass 3 - * needs to recreate the root directory or lost+found - * directory) it is called out of order. In those cases, we - * need to move the dir_info entries down to make room, since - * the dir_info array needs to be sorted by inode number for - * get_dir_info()'s sake. - */ - if (ctx->dir_info_count && - ctx->dir_info[ctx->dir_info_count-1].ino >= ino) { - for (i = ctx->dir_info_count-1; i > 0; i--) - if (ctx->dir_info[i-1].ino < ino) - break; - dir = &ctx->dir_info[i]; - if (dir->ino != ino) - for (j = ctx->dir_info_count++; j > i; j--) - ctx->dir_info[j] = ctx->dir_info[j-1]; - } else - dir = &ctx->dir_info[ctx->dir_info_count++]; - - dir->ino = ino; - dir->dotdot = parent; - dir->parent = parent; -} - -/* - * get_dir_info() --- given an inode number, try to find the directory - * information entry for it. - */ -static struct dir_info *e2fsck_get_dir_info(e2fsck_t ctx, ext2_ino_t ino) -{ - int low, high, mid; - - low = 0; - high = ctx->dir_info_count-1; - if (!ctx->dir_info) - return 0; - if (ino == ctx->dir_info[low].ino) - return &ctx->dir_info[low]; - if (ino == ctx->dir_info[high].ino) - return &ctx->dir_info[high]; - - while (low < high) { - mid = (low+high)/2; - if (mid == low || mid == high) - break; - if (ino == ctx->dir_info[mid].ino) - return &ctx->dir_info[mid]; - if (ino < ctx->dir_info[mid].ino) - high = mid; - else - low = mid; - } - return 0; -} - -/* - * Free the dir_info structure when it isn't needed any more. - */ -static void e2fsck_free_dir_info(e2fsck_t ctx) -{ - ext2fs_free_mem(&ctx->dir_info); - ctx->dir_info_size = 0; - ctx->dir_info_count = 0; -} - -/* - * Return the count of number of directories in the dir_info structure - */ -static int e2fsck_get_num_dirinfo(e2fsck_t ctx) -{ - return ctx->dir_info_count; -} - -/* - * A simple interator function - */ -static struct dir_info *e2fsck_dir_info_iter(e2fsck_t ctx, int *control) -{ - if (*control >= ctx->dir_info_count) - return 0; - - return ctx->dir_info + (*control)++; -} - -/* - * dirinfo.c --- maintains the directory information table for e2fsck. - * - */ - -#ifdef ENABLE_HTREE - -/* - * This subroutine is called during pass1 to create a directory info - * entry. During pass1, the passed-in parent is 0; it will get filled - * in during pass2. - */ -static void e2fsck_add_dx_dir(e2fsck_t ctx, ext2_ino_t ino, int num_blocks) -{ - struct dx_dir_info *dir; - int i, j; - errcode_t retval; - unsigned long old_size; - - if (!ctx->dx_dir_info) { - ctx->dx_dir_info_count = 0; - ctx->dx_dir_info_size = 100; /* Guess */ - ctx->dx_dir_info = (struct dx_dir_info *) - e2fsck_allocate_memory(ctx, ctx->dx_dir_info_size - * sizeof (struct dx_dir_info), - "directory map"); - } - - if (ctx->dx_dir_info_count >= ctx->dx_dir_info_size) { - old_size = ctx->dx_dir_info_size * sizeof(struct dx_dir_info); - ctx->dx_dir_info_size += 10; - retval = ext2fs_resize_mem(old_size, ctx->dx_dir_info_size * - sizeof(struct dx_dir_info), - &ctx->dx_dir_info); - if (retval) { - ctx->dx_dir_info_size -= 10; - return; - } - } - - /* - * Normally, add_dx_dir_info is called with each inode in - * sequential order; but once in a while (like when pass 3 - * needs to recreate the root directory or lost+found - * directory) it is called out of order. In those cases, we - * need to move the dx_dir_info entries down to make room, since - * the dx_dir_info array needs to be sorted by inode number for - * get_dx_dir_info()'s sake. - */ - if (ctx->dx_dir_info_count && - ctx->dx_dir_info[ctx->dx_dir_info_count-1].ino >= ino) { - for (i = ctx->dx_dir_info_count-1; i > 0; i--) - if (ctx->dx_dir_info[i-1].ino < ino) - break; - dir = &ctx->dx_dir_info[i]; - if (dir->ino != ino) - for (j = ctx->dx_dir_info_count++; j > i; j--) - ctx->dx_dir_info[j] = ctx->dx_dir_info[j-1]; - } else - dir = &ctx->dx_dir_info[ctx->dx_dir_info_count++]; - - dir->ino = ino; - dir->numblocks = num_blocks; - dir->hashversion = 0; - dir->dx_block = e2fsck_allocate_memory(ctx, num_blocks - * sizeof (struct dx_dirblock_info), - "dx_block info array"); -} - -/* - * get_dx_dir_info() --- given an inode number, try to find the directory - * information entry for it. - */ -static struct dx_dir_info *e2fsck_get_dx_dir_info(e2fsck_t ctx, ext2_ino_t ino) -{ - int low, high, mid; - - low = 0; - high = ctx->dx_dir_info_count-1; - if (!ctx->dx_dir_info) - return 0; - if (ino == ctx->dx_dir_info[low].ino) - return &ctx->dx_dir_info[low]; - if (ino == ctx->dx_dir_info[high].ino) - return &ctx->dx_dir_info[high]; - - while (low < high) { - mid = (low+high)/2; - if (mid == low || mid == high) - break; - if (ino == ctx->dx_dir_info[mid].ino) - return &ctx->dx_dir_info[mid]; - if (ino < ctx->dx_dir_info[mid].ino) - high = mid; - else - low = mid; - } - return 0; -} - -/* - * Free the dx_dir_info structure when it isn't needed any more. - */ -static void e2fsck_free_dx_dir_info(e2fsck_t ctx) -{ - int i; - struct dx_dir_info *dir; - - if (ctx->dx_dir_info) { - dir = ctx->dx_dir_info; - for (i=0; i < ctx->dx_dir_info_count; i++) { - ext2fs_free_mem(&dir->dx_block); - } - ext2fs_free_mem(&ctx->dx_dir_info); - } - ctx->dx_dir_info_size = 0; - ctx->dx_dir_info_count = 0; -} - -/* - * A simple interator function - */ -static struct dx_dir_info *e2fsck_dx_dir_info_iter(e2fsck_t ctx, int *control) -{ - if (*control >= ctx->dx_dir_info_count) - return 0; - - return ctx->dx_dir_info + (*control)++; -} - -#endif /* ENABLE_HTREE */ -/* - * e2fsck.c - a consistency checker for the new extended file system. - * - */ - -/* - * This function allocates an e2fsck context - */ -static errcode_t e2fsck_allocate_context(e2fsck_t *ret) -{ - e2fsck_t context; - errcode_t retval; - - retval = ext2fs_get_mem(sizeof(struct e2fsck_struct), &context); - if (retval) - return retval; - - memset(context, 0, sizeof(struct e2fsck_struct)); - - context->process_inode_size = 256; - context->ext_attr_ver = 2; - - *ret = context; - return 0; -} - -struct ea_refcount_el { - blk_t ea_blk; - int ea_count; -}; - -struct ea_refcount { - blk_t count; - blk_t size; - blk_t cursor; - struct ea_refcount_el *list; -}; - -static void ea_refcount_free(ext2_refcount_t refcount) -{ - if (!refcount) - return; - - ext2fs_free_mem(&refcount->list); - ext2fs_free_mem(&refcount); -} - -/* - * This function resets an e2fsck context; it is called when e2fsck - * needs to be restarted. - */ -static errcode_t e2fsck_reset_context(e2fsck_t ctx) -{ - ctx->flags = 0; - ctx->lost_and_found = 0; - ctx->bad_lost_and_found = 0; - ext2fs_free_inode_bitmap(ctx->inode_used_map); - ctx->inode_used_map = 0; - ext2fs_free_inode_bitmap(ctx->inode_dir_map); - ctx->inode_dir_map = 0; - ext2fs_free_inode_bitmap(ctx->inode_reg_map); - ctx->inode_reg_map = 0; - ext2fs_free_block_bitmap(ctx->block_found_map); - ctx->block_found_map = 0; - ext2fs_free_icount(ctx->inode_link_info); - ctx->inode_link_info = 0; - if (ctx->journal_io) { - if (ctx->fs && ctx->fs->io != ctx->journal_io) - io_channel_close(ctx->journal_io); - ctx->journal_io = 0; - } - if (ctx->fs) { - ext2fs_free_dblist(ctx->fs->dblist); - ctx->fs->dblist = 0; - } - e2fsck_free_dir_info(ctx); -#ifdef ENABLE_HTREE - e2fsck_free_dx_dir_info(ctx); -#endif - ea_refcount_free(ctx->refcount); - ctx->refcount = 0; - ea_refcount_free(ctx->refcount_extra); - ctx->refcount_extra = 0; - ext2fs_free_block_bitmap(ctx->block_dup_map); - ctx->block_dup_map = 0; - ext2fs_free_block_bitmap(ctx->block_ea_map); - ctx->block_ea_map = 0; - ext2fs_free_inode_bitmap(ctx->inode_bad_map); - ctx->inode_bad_map = 0; - ext2fs_free_inode_bitmap(ctx->inode_imagic_map); - ctx->inode_imagic_map = 0; - ext2fs_u32_list_free(ctx->dirs_to_hash); - ctx->dirs_to_hash = 0; - - /* - * Clear the array of invalid meta-data flags - */ - ext2fs_free_mem(&ctx->invalid_inode_bitmap_flag); - ext2fs_free_mem(&ctx->invalid_block_bitmap_flag); - ext2fs_free_mem(&ctx->invalid_inode_table_flag); - - /* Clear statistic counters */ - ctx->fs_directory_count = 0; - ctx->fs_regular_count = 0; - ctx->fs_blockdev_count = 0; - ctx->fs_chardev_count = 0; - ctx->fs_links_count = 0; - ctx->fs_symlinks_count = 0; - ctx->fs_fast_symlinks_count = 0; - ctx->fs_fifo_count = 0; - ctx->fs_total_count = 0; - ctx->fs_sockets_count = 0; - ctx->fs_ind_count = 0; - ctx->fs_dind_count = 0; - ctx->fs_tind_count = 0; - ctx->fs_fragmented = 0; - ctx->large_files = 0; - - /* Reset the superblock to the user's requested value */ - ctx->superblock = ctx->use_superblock; - - return 0; -} - -static void e2fsck_free_context(e2fsck_t ctx) -{ - if (!ctx) - return; - - e2fsck_reset_context(ctx); - if (ctx->blkid) - blkid_put_cache(ctx->blkid); - - ext2fs_free_mem(&ctx); -} - -/* - * ea_refcount.c - */ - -/* - * The strategy we use for keeping track of EA refcounts is as - * follows. We keep a sorted array of first EA blocks and its - * reference counts. Once the refcount has dropped to zero, it is - * removed from the array to save memory space. Once the EA block is - * checked, its bit is set in the block_ea_map bitmap. - */ - - -static errcode_t ea_refcount_create(int size, ext2_refcount_t *ret) -{ - ext2_refcount_t refcount; - errcode_t retval; - size_t bytes; - - retval = ext2fs_get_mem(sizeof(struct ea_refcount), &refcount); - if (retval) - return retval; - memset(refcount, 0, sizeof(struct ea_refcount)); - - if (!size) - size = 500; - refcount->size = size; - bytes = (size_t) (size * sizeof(struct ea_refcount_el)); -#ifdef DEBUG - printf("Refcount allocated %d entries, %lu bytes.\n", - refcount->size, bytes); -#endif - retval = ext2fs_get_mem(bytes, &refcount->list); - if (retval) - goto errout; - memset(refcount->list, 0, bytes); - - refcount->count = 0; - refcount->cursor = 0; - - *ret = refcount; - return 0; - -errout: - ea_refcount_free(refcount); - return retval; -} - -/* - * collapse_refcount() --- go through the refcount array, and get rid - * of any count == zero entries - */ -static void refcount_collapse(ext2_refcount_t refcount) -{ - unsigned int i, j; - struct ea_refcount_el *list; - - list = refcount->list; - for (i = 0, j = 0; i < refcount->count; i++) { - if (list[i].ea_count) { - if (i != j) - list[j] = list[i]; - j++; - } - } -#if defined(DEBUG) || defined(TEST_PROGRAM) - printf("Refcount_collapse: size was %d, now %d\n", - refcount->count, j); -#endif - refcount->count = j; -} - - -/* - * insert_refcount_el() --- Insert a new entry into the sorted list at a - * specified position. - */ -static struct ea_refcount_el *insert_refcount_el(ext2_refcount_t refcount, - blk_t blk, int pos) -{ - struct ea_refcount_el *el; - errcode_t retval; - blk_t new_size = 0; - int num; - - if (refcount->count >= refcount->size) { - new_size = refcount->size + 100; -#ifdef DEBUG - printf("Reallocating refcount %d entries...\n", new_size); -#endif - retval = ext2fs_resize_mem((size_t) refcount->size * - sizeof(struct ea_refcount_el), - (size_t) new_size * - sizeof(struct ea_refcount_el), - &refcount->list); - if (retval) - return 0; - refcount->size = new_size; - } - num = (int) refcount->count - pos; - if (num < 0) - return 0; /* should never happen */ - if (num) { - memmove(&refcount->list[pos+1], &refcount->list[pos], - sizeof(struct ea_refcount_el) * num); - } - refcount->count++; - el = &refcount->list[pos]; - el->ea_count = 0; - el->ea_blk = blk; - return el; -} - - -/* - * get_refcount_el() --- given an block number, try to find refcount - * 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 ea_refcount_el *get_refcount_el(ext2_refcount_t refcount, - blk_t blk, int create) -{ - float range; - int low, high, mid; - blk_t lowval, highval; - - if (!refcount || !refcount->list) - return 0; -retry: - low = 0; - high = (int) refcount->count-1; - if (create && ((refcount->count == 0) || - (blk > refcount->list[high].ea_blk))) { - if (refcount->count >= refcount->size) - refcount_collapse(refcount); - - return insert_refcount_el(refcount, blk, - (unsigned) refcount->count); - } - if (refcount->count == 0) - return 0; - - if (refcount->cursor >= refcount->count) - refcount->cursor = 0; - if (blk == refcount->list[refcount->cursor].ea_blk) - return &refcount->list[refcount->cursor++]; -#ifdef DEBUG - printf("Non-cursor get_refcount_el: %u\n", blk); -#endif - while (low <= high) { - if (low == high) - mid = low; - else { - /* Interpolate for efficiency */ - lowval = refcount->list[low].ea_blk; - highval = refcount->list[high].ea_blk; - - if (blk < lowval) - range = 0; - else if (blk > highval) - range = 1; - else - range = ((float) (blk - lowval)) / - (highval - lowval); - mid = low + ((int) (range * (high-low))); - } - - if (blk == refcount->list[mid].ea_blk) { - refcount->cursor = mid+1; - return &refcount->list[mid]; - } - if (blk < refcount->list[mid].ea_blk) - 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) { - if (refcount->count >= refcount->size) { - refcount_collapse(refcount); - if (refcount->count < refcount->size) - goto retry; - } - return insert_refcount_el(refcount, blk, low); - } - return 0; -} - -static errcode_t -ea_refcount_increment(ext2_refcount_t refcount, blk_t blk, int *ret) -{ - struct ea_refcount_el *el; - - el = get_refcount_el(refcount, blk, 1); - if (!el) - return EXT2_ET_NO_MEMORY; - el->ea_count++; - - if (ret) - *ret = el->ea_count; - return 0; -} - -static errcode_t -ea_refcount_decrement(ext2_refcount_t refcount, blk_t blk, int *ret) -{ - struct ea_refcount_el *el; - - el = get_refcount_el(refcount, blk, 0); - if (!el || el->ea_count == 0) - return EXT2_ET_INVALID_ARGUMENT; - - el->ea_count--; - - if (ret) - *ret = el->ea_count; - return 0; -} - -static errcode_t -ea_refcount_store(ext2_refcount_t refcount, blk_t blk, int count) -{ - struct ea_refcount_el *el; - - /* - * Get the refcount element - */ - el = get_refcount_el(refcount, blk, count ? 1 : 0); - if (!el) - return count ? EXT2_ET_NO_MEMORY : 0; - el->ea_count = count; - return 0; -} - -static inline void ea_refcount_intr_begin(ext2_refcount_t refcount) -{ - refcount->cursor = 0; -} - - -static blk_t ea_refcount_intr_next(ext2_refcount_t refcount, int *ret) -{ - struct ea_refcount_el *list; - - while (1) { - if (refcount->cursor >= refcount->count) - return 0; - list = refcount->list; - if (list[refcount->cursor].ea_count) { - if (ret) - *ret = list[refcount->cursor].ea_count; - return list[refcount->cursor++].ea_blk; - } - refcount->cursor++; - } -} - - -/* - * ehandler.c --- handle bad block errors which come up during the - * course of an e2fsck session. - */ - - -static const char *operation; - -static errcode_t -e2fsck_handle_read_error(io_channel channel, unsigned long block, int count, - void *data, size_t size FSCK_ATTR((unused)), - int actual FSCK_ATTR((unused)), errcode_t error) -{ - int i; - char *p; - ext2_filsys fs = (ext2_filsys) channel->app_data; - e2fsck_t ctx; - - ctx = (e2fsck_t) fs->priv_data; - - /* - * If more than one block was read, try reading each block - * separately. We could use the actual bytes read to figure - * out where to start, but we don't bother. - */ - if (count > 1) { - p = (char *) data; - for (i=0; i < count; i++, p += channel->block_size, block++) { - error = io_channel_read_blk(channel, block, - 1, p); - if (error) - return error; - } - return 0; - } - if (operation) - printf(_("Error reading block %lu (%s) while %s. "), block, - error_message(error), operation); - else - printf(_("Error reading block %lu (%s). "), block, - error_message(error)); - preenhalt(ctx); - if (ask(ctx, _("Ignore error"), 1)) { - if (ask(ctx, _("Force rewrite"), 1)) - io_channel_write_blk(channel, block, 1, data); - return 0; - } - - return error; -} - -static errcode_t -e2fsck_handle_write_error(io_channel channel, unsigned long block, int count, - const void *data, size_t size FSCK_ATTR((unused)), - int actual FSCK_ATTR((unused)), errcode_t error) -{ - int i; - const char *p; - ext2_filsys fs = (ext2_filsys) channel->app_data; - e2fsck_t ctx; - - ctx = (e2fsck_t) fs->priv_data; - - /* - * If more than one block was written, try writing each block - * separately. We could use the actual bytes read to figure - * out where to start, but we don't bother. - */ - if (count > 1) { - p = (const char *) data; - for (i=0; i < count; i++, p += channel->block_size, block++) { - error = io_channel_write_blk(channel, block, - 1, p); - if (error) - return error; - } - return 0; - } - - if (operation) - printf(_("Error writing block %lu (%s) while %s. "), block, - error_message(error), operation); - else - printf(_("Error writing block %lu (%s). "), block, - error_message(error)); - preenhalt(ctx); - if (ask(ctx, _("Ignore error"), 1)) - return 0; - - return error; -} - -static const char *ehandler_operation(const char *op) -{ - const char *ret = operation; - - operation = op; - return ret; -} - -static void ehandler_init(io_channel channel) -{ - channel->read_error = e2fsck_handle_read_error; - channel->write_error = e2fsck_handle_write_error; -} - -/* - * journal.c --- code for handling the "ext3" journal - * - * Copyright (C) 2000 Andreas Dilger - * Copyright (C) 2000 Theodore Ts'o - * - * Parts of the code are based on fs/jfs/journal.c by Stephen C. Tweedie - * Copyright (C) 1999 Red Hat Software - * - * This file may be redistributed under the terms of the - * GNU General Public License version 2 or at your discretion - * any later version. - */ - -/* - * Define USE_INODE_IO to use the inode_io.c / fileio.c codepaths. - * This creates a larger static binary, and a smaller binary using - * shared libraries. It's also probably slightly less CPU-efficient, - * which is why it's not on by default. But, it's a good way of - * testing the functions in inode_io.c and fileio.c. - */ -#undef USE_INODE_IO - -/* Kernel compatibility functions for handling the journal. These allow us - * to use the recovery.c file virtually unchanged from the kernel, so we - * don't have to do much to keep kernel and user recovery in sync. - */ -static int journal_bmap(journal_t *journal, blk_t block, unsigned long *phys) -{ -#ifdef USE_INODE_IO - *phys = block; - return 0; -#else - struct inode *inode = journal->j_inode; - errcode_t retval; - blk_t pblk; - - if (!inode) { - *phys = block; - return 0; - } - - retval= ext2fs_bmap(inode->i_ctx->fs, inode->i_ino, - &inode->i_ext2, NULL, 0, block, &pblk); - *phys = pblk; - return retval; -#endif -} - -static struct buffer_head *getblk(kdev_t kdev, blk_t blocknr, int blocksize) -{ - struct buffer_head *bh; - - bh = e2fsck_allocate_memory(kdev->k_ctx, sizeof(*bh), "block buffer"); - if (!bh) - return NULL; - - bh->b_ctx = kdev->k_ctx; - if (kdev->k_dev == K_DEV_FS) - bh->b_io = kdev->k_ctx->fs->io; - else - bh->b_io = kdev->k_ctx->journal_io; - bh->b_size = blocksize; - bh->b_blocknr = blocknr; - - return bh; -} - -static void sync_blockdev(kdev_t kdev) -{ - io_channel io; - - if (kdev->k_dev == K_DEV_FS) - io = kdev->k_ctx->fs->io; - else - io = kdev->k_ctx->journal_io; - - io_channel_flush(io); -} - -static void ll_rw_block(int rw, int nr, struct buffer_head *bhp[]) -{ - int retval; - struct buffer_head *bh; - - for (; nr > 0; --nr) { - bh = *bhp++; - if (rw == READ && !bh->b_uptodate) { - retval = io_channel_read_blk(bh->b_io, - bh->b_blocknr, - 1, bh->b_data); - if (retval) { - bb_error_msg("while reading block %lu", - (unsigned long) bh->b_blocknr); - bh->b_err = retval; - continue; - } - bh->b_uptodate = 1; - } else if (rw == WRITE && bh->b_dirty) { - retval = io_channel_write_blk(bh->b_io, - bh->b_blocknr, - 1, bh->b_data); - if (retval) { - bb_error_msg("while writing block %lu", - (unsigned long) bh->b_blocknr); - bh->b_err = retval; - continue; - } - bh->b_dirty = 0; - bh->b_uptodate = 1; - } - } -} - -static void mark_buffer_dirty(struct buffer_head *bh) -{ - bh->b_dirty = 1; -} - -static inline void mark_buffer_clean(struct buffer_head * bh) -{ - bh->b_dirty = 0; -} - -static void brelse(struct buffer_head *bh) -{ - if (bh->b_dirty) - ll_rw_block(WRITE, 1, &bh); - ext2fs_free_mem(&bh); -} - -static int buffer_uptodate(struct buffer_head *bh) -{ - return bh->b_uptodate; -} - -static inline void mark_buffer_uptodate(struct buffer_head *bh, int val) -{ - bh->b_uptodate = val; -} - -static void wait_on_buffer(struct buffer_head *bh) -{ - if (!bh->b_uptodate) - ll_rw_block(READ, 1, &bh); -} - - -static void e2fsck_clear_recover(e2fsck_t ctx, int error) -{ - ctx->fs->super->s_feature_incompat &= ~EXT3_FEATURE_INCOMPAT_RECOVER; - - /* if we had an error doing journal recovery, we need a full fsck */ - if (error) - ctx->fs->super->s_state &= ~EXT2_VALID_FS; - ext2fs_mark_super_dirty(ctx->fs); -} - -static errcode_t e2fsck_get_journal(e2fsck_t ctx, journal_t **ret_journal) -{ - struct ext2_super_block *sb = ctx->fs->super; - struct ext2_super_block jsuper; - struct problem_context pctx; - struct buffer_head *bh; - struct inode *j_inode = NULL; - struct kdev_s *dev_fs = NULL, *dev_journal; - const char *journal_name = NULL; - journal_t *journal = NULL; - errcode_t retval = 0; - io_manager io_ptr = 0; - unsigned long start = 0; - blk_t blk; - int ext_journal = 0; - int tried_backup_jnl = 0; - int i; - - clear_problem_context(&pctx); - - journal = e2fsck_allocate_memory(ctx, sizeof(journal_t), "journal"); - if (!journal) { - return EXT2_ET_NO_MEMORY; - } - - dev_fs = e2fsck_allocate_memory(ctx, 2*sizeof(struct kdev_s), "kdev"); - if (!dev_fs) { - retval = EXT2_ET_NO_MEMORY; - goto errout; - } - dev_journal = dev_fs+1; - - dev_fs->k_ctx = dev_journal->k_ctx = ctx; - dev_fs->k_dev = K_DEV_FS; - dev_journal->k_dev = K_DEV_JOURNAL; - - journal->j_dev = dev_journal; - journal->j_fs_dev = dev_fs; - journal->j_inode = NULL; - journal->j_blocksize = ctx->fs->blocksize; - - if (uuid_is_null(sb->s_journal_uuid)) { - if (!sb->s_journal_inum) - return EXT2_ET_BAD_INODE_NUM; - j_inode = e2fsck_allocate_memory(ctx, sizeof(*j_inode), - "journal inode"); - if (!j_inode) { - retval = EXT2_ET_NO_MEMORY; - goto errout; - } - - j_inode->i_ctx = ctx; - j_inode->i_ino = sb->s_journal_inum; - - if ((retval = ext2fs_read_inode(ctx->fs, - sb->s_journal_inum, - &j_inode->i_ext2))) { - try_backup_journal: - if (sb->s_jnl_backup_type != EXT3_JNL_BACKUP_BLOCKS || - tried_backup_jnl) - goto errout; - memset(&j_inode->i_ext2, 0, sizeof(struct ext2_inode)); - memcpy(&j_inode->i_ext2.i_block[0], sb->s_jnl_blocks, - EXT2_N_BLOCKS*4); - j_inode->i_ext2.i_size = sb->s_jnl_blocks[16]; - j_inode->i_ext2.i_links_count = 1; - j_inode->i_ext2.i_mode = LINUX_S_IFREG | 0600; - tried_backup_jnl++; - } - if (!j_inode->i_ext2.i_links_count || - !LINUX_S_ISREG(j_inode->i_ext2.i_mode)) { - retval = EXT2_ET_NO_JOURNAL; - goto try_backup_journal; - } - if (j_inode->i_ext2.i_size / journal->j_blocksize < - JFS_MIN_JOURNAL_BLOCKS) { - retval = EXT2_ET_JOURNAL_TOO_SMALL; - goto try_backup_journal; - } - for (i=0; i < EXT2_N_BLOCKS; i++) { - blk = j_inode->i_ext2.i_block[i]; - if (!blk) { - if (i < EXT2_NDIR_BLOCKS) { - retval = EXT2_ET_JOURNAL_TOO_SMALL; - goto try_backup_journal; - } - continue; - } - if (blk < sb->s_first_data_block || - blk >= sb->s_blocks_count) { - retval = EXT2_ET_BAD_BLOCK_NUM; - goto try_backup_journal; - } - } - journal->j_maxlen = j_inode->i_ext2.i_size / journal->j_blocksize; - -#ifdef USE_INODE_IO - retval = ext2fs_inode_io_intern2(ctx->fs, sb->s_journal_inum, - &j_inode->i_ext2, - &journal_name); - if (retval) - goto errout; - - io_ptr = inode_io_manager; -#else - journal->j_inode = j_inode; - ctx->journal_io = ctx->fs->io; - if ((retval = journal_bmap(journal, 0, &start)) != 0) - goto errout; -#endif - } else { - ext_journal = 1; - if (!ctx->journal_name) { - char uuid[37]; - - uuid_unparse(sb->s_journal_uuid, uuid); - ctx->journal_name = blkid_get_devname(ctx->blkid, - "UUID", uuid); - if (!ctx->journal_name) - ctx->journal_name = blkid_devno_to_devname(sb->s_journal_dev); - } - journal_name = ctx->journal_name; - - if (!journal_name) { - fix_problem(ctx, PR_0_CANT_FIND_JOURNAL, &pctx); - return EXT2_ET_LOAD_EXT_JOURNAL; - } - - io_ptr = unix_io_manager; - } - -#ifndef USE_INODE_IO - if (ext_journal) -#endif - retval = io_ptr->open(journal_name, IO_FLAG_RW, - &ctx->journal_io); - if (retval) - goto errout; - - io_channel_set_blksize(ctx->journal_io, ctx->fs->blocksize); - - if (ext_journal) { - if (ctx->fs->blocksize == 1024) - start = 1; - bh = getblk(dev_journal, start, ctx->fs->blocksize); - if (!bh) { - retval = EXT2_ET_NO_MEMORY; - goto errout; - } - ll_rw_block(READ, 1, &bh); - if ((retval = bh->b_err) != 0) - goto errout; - memcpy(&jsuper, start ? bh->b_data : bh->b_data + 1024, - sizeof(jsuper)); - brelse(bh); -#if BB_BIG_ENDIAN - if (jsuper.s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) - ext2fs_swap_super(&jsuper); -#endif - if (jsuper.s_magic != EXT2_SUPER_MAGIC || - !(jsuper.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) { - fix_problem(ctx, PR_0_EXT_JOURNAL_BAD_SUPER, &pctx); - retval = EXT2_ET_LOAD_EXT_JOURNAL; - goto errout; - } - /* Make sure the journal UUID is correct */ - if (memcmp(jsuper.s_uuid, ctx->fs->super->s_journal_uuid, - sizeof(jsuper.s_uuid))) { - fix_problem(ctx, PR_0_JOURNAL_BAD_UUID, &pctx); - retval = EXT2_ET_LOAD_EXT_JOURNAL; - goto errout; - } - - journal->j_maxlen = jsuper.s_blocks_count; - start++; - } - - if (!(bh = getblk(dev_journal, start, journal->j_blocksize))) { - retval = EXT2_ET_NO_MEMORY; - goto errout; - } - - journal->j_sb_buffer = bh; - journal->j_superblock = (journal_superblock_t *)bh->b_data; - -#ifdef USE_INODE_IO - ext2fs_free_mem(&j_inode); -#endif - - *ret_journal = journal; - return 0; - -errout: - ext2fs_free_mem(&dev_fs); - ext2fs_free_mem(&j_inode); - ext2fs_free_mem(&journal); - return retval; -} - -static errcode_t e2fsck_journal_fix_bad_inode(e2fsck_t ctx, - struct problem_context *pctx) -{ - struct ext2_super_block *sb = ctx->fs->super; - int recover = ctx->fs->super->s_feature_incompat & - EXT3_FEATURE_INCOMPAT_RECOVER; - int has_journal = ctx->fs->super->s_feature_compat & - EXT3_FEATURE_COMPAT_HAS_JOURNAL; - - if (has_journal || sb->s_journal_inum) { - /* The journal inode is bogus, remove and force full fsck */ - pctx->ino = sb->s_journal_inum; - if (fix_problem(ctx, PR_0_JOURNAL_BAD_INODE, pctx)) { - if (has_journal && sb->s_journal_inum) - printf("*** ext3 journal has been deleted - " - "filesystem is now ext2 only ***\n\n"); - sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL; - sb->s_journal_inum = 0; - ctx->flags |= E2F_FLAG_JOURNAL_INODE; /* FIXME: todo */ - e2fsck_clear_recover(ctx, 1); - return 0; - } - return EXT2_ET_BAD_INODE_NUM; - } else if (recover) { - if (fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, pctx)) { - e2fsck_clear_recover(ctx, 1); - return 0; - } - return EXT2_ET_UNSUPP_FEATURE; - } - return 0; -} - -#define V1_SB_SIZE 0x0024 -static void clear_v2_journal_fields(journal_t *journal) -{ - e2fsck_t ctx = journal->j_dev->k_ctx; - struct problem_context pctx; - - clear_problem_context(&pctx); - - if (!fix_problem(ctx, PR_0_CLEAR_V2_JOURNAL, &pctx)) - return; - - memset(((char *) journal->j_superblock) + V1_SB_SIZE, 0, - ctx->fs->blocksize-V1_SB_SIZE); - mark_buffer_dirty(journal->j_sb_buffer); -} - - -static errcode_t e2fsck_journal_load(journal_t *journal) -{ - e2fsck_t ctx = journal->j_dev->k_ctx; - journal_superblock_t *jsb; - struct buffer_head *jbh = journal->j_sb_buffer; - struct problem_context pctx; - - clear_problem_context(&pctx); - - ll_rw_block(READ, 1, &jbh); - if (jbh->b_err) { - bb_error_msg(_("reading journal superblock")); - return jbh->b_err; - } - - jsb = journal->j_superblock; - /* If we don't even have JFS_MAGIC, we probably have a wrong inode */ - if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER)) - return e2fsck_journal_fix_bad_inode(ctx, &pctx); - - switch (ntohl(jsb->s_header.h_blocktype)) { - case JFS_SUPERBLOCK_V1: - journal->j_format_version = 1; - if (jsb->s_feature_compat || - jsb->s_feature_incompat || - jsb->s_feature_ro_compat || - jsb->s_nr_users) - clear_v2_journal_fields(journal); - break; - - case JFS_SUPERBLOCK_V2: - journal->j_format_version = 2; - if (ntohl(jsb->s_nr_users) > 1 && - uuid_is_null(ctx->fs->super->s_journal_uuid)) - clear_v2_journal_fields(journal); - if (ntohl(jsb->s_nr_users) > 1) { - fix_problem(ctx, PR_0_JOURNAL_UNSUPP_MULTIFS, &pctx); - return EXT2_ET_JOURNAL_UNSUPP_VERSION; - } - break; - - /* - * These should never appear in a journal super block, so if - * they do, the journal is badly corrupted. - */ - case JFS_DESCRIPTOR_BLOCK: - case JFS_COMMIT_BLOCK: - case JFS_REVOKE_BLOCK: - return EXT2_ET_CORRUPT_SUPERBLOCK; - - /* If we don't understand the superblock major type, but there - * is a magic number, then it is likely to be a new format we - * just don't understand, so leave it alone. */ - default: - return EXT2_ET_JOURNAL_UNSUPP_VERSION; - } - - if (JFS_HAS_INCOMPAT_FEATURE(journal, ~JFS_KNOWN_INCOMPAT_FEATURES)) - return EXT2_ET_UNSUPP_FEATURE; - - if (JFS_HAS_RO_COMPAT_FEATURE(journal, ~JFS_KNOWN_ROCOMPAT_FEATURES)) - return EXT2_ET_RO_UNSUPP_FEATURE; - - /* We have now checked whether we know enough about the journal - * format to be able to proceed safely, so any other checks that - * fail we should attempt to recover from. */ - if (jsb->s_blocksize != htonl(journal->j_blocksize)) { - bb_error_msg(_("%s: no valid journal superblock found"), - ctx->device_name); - return EXT2_ET_CORRUPT_SUPERBLOCK; - } - - if (ntohl(jsb->s_maxlen) < journal->j_maxlen) - journal->j_maxlen = ntohl(jsb->s_maxlen); - else if (ntohl(jsb->s_maxlen) > journal->j_maxlen) { - bb_error_msg(_("%s: journal too short"), - ctx->device_name); - return EXT2_ET_CORRUPT_SUPERBLOCK; - } - - journal->j_tail_sequence = ntohl(jsb->s_sequence); - journal->j_transaction_sequence = journal->j_tail_sequence; - journal->j_tail = ntohl(jsb->s_start); - journal->j_first = ntohl(jsb->s_first); - journal->j_last = ntohl(jsb->s_maxlen); - - return 0; -} - -static void e2fsck_journal_reset_super(e2fsck_t ctx, journal_superblock_t *jsb, - journal_t *journal) -{ - char *p; - union { - uuid_t uuid; - __u32 val[4]; - } u; - __u32 new_seq = 0; - int i; - - /* Leave a valid existing V1 superblock signature alone. - * Anything unrecognizable we overwrite with a new V2 - * signature. */ - - if (jsb->s_header.h_magic != htonl(JFS_MAGIC_NUMBER) || - jsb->s_header.h_blocktype != htonl(JFS_SUPERBLOCK_V1)) { - jsb->s_header.h_magic = htonl(JFS_MAGIC_NUMBER); - jsb->s_header.h_blocktype = htonl(JFS_SUPERBLOCK_V2); - } - - /* Zero out everything else beyond the superblock header */ - - p = ((char *) jsb) + sizeof(journal_header_t); - memset (p, 0, ctx->fs->blocksize-sizeof(journal_header_t)); - - jsb->s_blocksize = htonl(ctx->fs->blocksize); - jsb->s_maxlen = htonl(journal->j_maxlen); - jsb->s_first = htonl(1); - - /* Initialize the journal sequence number so that there is "no" - * chance we will find old "valid" transactions in the journal. - * This avoids the need to zero the whole journal (slow to do, - * and risky when we are just recovering the filesystem). - */ - uuid_generate(u.uuid); - for (i = 0; i < 4; i ++) - new_seq ^= u.val[i]; - jsb->s_sequence = htonl(new_seq); - - mark_buffer_dirty(journal->j_sb_buffer); - ll_rw_block(WRITE, 1, &journal->j_sb_buffer); -} - -static errcode_t e2fsck_journal_fix_corrupt_super(e2fsck_t ctx, - journal_t *journal, - struct problem_context *pctx) -{ - struct ext2_super_block *sb = ctx->fs->super; - int recover = ctx->fs->super->s_feature_incompat & - EXT3_FEATURE_INCOMPAT_RECOVER; - - if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) { - if (fix_problem(ctx, PR_0_JOURNAL_BAD_SUPER, pctx)) { - e2fsck_journal_reset_super(ctx, journal->j_superblock, - journal); - journal->j_transaction_sequence = 1; - e2fsck_clear_recover(ctx, recover); - return 0; - } - return EXT2_ET_CORRUPT_SUPERBLOCK; - } else if (e2fsck_journal_fix_bad_inode(ctx, pctx)) - return EXT2_ET_CORRUPT_SUPERBLOCK; - - return 0; -} - -static void e2fsck_journal_release(e2fsck_t ctx, journal_t *journal, - int reset, int drop) -{ - journal_superblock_t *jsb; - - if (drop) - mark_buffer_clean(journal->j_sb_buffer); - else if (!(ctx->options & E2F_OPT_READONLY)) { - jsb = journal->j_superblock; - jsb->s_sequence = htonl(journal->j_transaction_sequence); - if (reset) - jsb->s_start = 0; /* this marks the journal as empty */ - mark_buffer_dirty(journal->j_sb_buffer); - } - brelse(journal->j_sb_buffer); - - if (ctx->journal_io) { - if (ctx->fs && ctx->fs->io != ctx->journal_io) - io_channel_close(ctx->journal_io); - ctx->journal_io = 0; - } - -#ifndef USE_INODE_IO - ext2fs_free_mem(&journal->j_inode); -#endif - ext2fs_free_mem(&journal->j_fs_dev); - ext2fs_free_mem(&journal); -} - -/* - * This function makes sure that the superblock fields regarding the - * journal are consistent. - */ -static int e2fsck_check_ext3_journal(e2fsck_t ctx) -{ - struct ext2_super_block *sb = ctx->fs->super; - journal_t *journal; - int recover = ctx->fs->super->s_feature_incompat & - EXT3_FEATURE_INCOMPAT_RECOVER; - struct problem_context pctx; - problem_t problem; - int reset = 0, force_fsck = 0; - int retval; - - /* If we don't have any journal features, don't do anything more */ - if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && - !recover && sb->s_journal_inum == 0 && sb->s_journal_dev == 0 && - uuid_is_null(sb->s_journal_uuid)) - return 0; - - clear_problem_context(&pctx); - pctx.num = sb->s_journal_inum; - - retval = e2fsck_get_journal(ctx, &journal); - if (retval) { - if ((retval == EXT2_ET_BAD_INODE_NUM) || - (retval == EXT2_ET_BAD_BLOCK_NUM) || - (retval == EXT2_ET_JOURNAL_TOO_SMALL) || - (retval == EXT2_ET_NO_JOURNAL)) - return e2fsck_journal_fix_bad_inode(ctx, &pctx); - return retval; - } - - retval = e2fsck_journal_load(journal); - if (retval) { - if ((retval == EXT2_ET_CORRUPT_SUPERBLOCK) || - ((retval == EXT2_ET_UNSUPP_FEATURE) && - (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_INCOMPAT, - &pctx))) || - ((retval == EXT2_ET_RO_UNSUPP_FEATURE) && - (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_ROCOMPAT, - &pctx))) || - ((retval == EXT2_ET_JOURNAL_UNSUPP_VERSION) && - (!fix_problem(ctx, PR_0_JOURNAL_UNSUPP_VERSION, &pctx)))) - retval = e2fsck_journal_fix_corrupt_super(ctx, journal, - &pctx); - e2fsck_journal_release(ctx, journal, 0, 1); - return retval; - } - - /* - * We want to make the flags consistent here. We will not leave with - * needs_recovery set but has_journal clear. We can't get in a loop - * with -y, -n, or -p, only if a user isn't making up their mind. - */ -no_has_journal: - if (!(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) { - recover = sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER; - pctx.str = "inode"; - if (fix_problem(ctx, PR_0_JOURNAL_HAS_JOURNAL, &pctx)) { - if (recover && - !fix_problem(ctx, PR_0_JOURNAL_RECOVER_SET, &pctx)) - goto no_has_journal; - /* - * Need a full fsck if we are releasing a - * journal stored on a reserved inode. - */ - force_fsck = recover || - (sb->s_journal_inum < EXT2_FIRST_INODE(sb)); - /* Clear all of the journal fields */ - sb->s_journal_inum = 0; - sb->s_journal_dev = 0; - memset(sb->s_journal_uuid, 0, - sizeof(sb->s_journal_uuid)); - e2fsck_clear_recover(ctx, force_fsck); - } else if (!(ctx->options & E2F_OPT_READONLY)) { - sb->s_feature_compat |= EXT3_FEATURE_COMPAT_HAS_JOURNAL; - ext2fs_mark_super_dirty(ctx->fs); - } - } - - if (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL && - !(sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) && - journal->j_superblock->s_start != 0) { - /* Print status information */ - fix_problem(ctx, PR_0_JOURNAL_RECOVERY_CLEAR, &pctx); - if (ctx->superblock) - problem = PR_0_JOURNAL_RUN_DEFAULT; - else - problem = PR_0_JOURNAL_RUN; - if (fix_problem(ctx, problem, &pctx)) { - ctx->options |= E2F_OPT_FORCE; - sb->s_feature_incompat |= - EXT3_FEATURE_INCOMPAT_RECOVER; - ext2fs_mark_super_dirty(ctx->fs); - } else if (fix_problem(ctx, - PR_0_JOURNAL_RESET_JOURNAL, &pctx)) { - reset = 1; - sb->s_state &= ~EXT2_VALID_FS; - ext2fs_mark_super_dirty(ctx->fs); - } - /* - * If the user answers no to the above question, we - * ignore the fact that journal apparently has data; - * accidentally replaying over valid data would be far - * worse than skipping a questionable recovery. - * - * XXX should we abort with a fatal error here? What - * will the ext3 kernel code do if a filesystem with - * !NEEDS_RECOVERY but with a non-zero - * journal->j_superblock->s_start is mounted? - */ - } - - e2fsck_journal_release(ctx, journal, reset, 0); - return retval; -} - -static errcode_t recover_ext3_journal(e2fsck_t ctx) -{ - journal_t *journal; - int retval; - - journal_init_revoke_caches(); - retval = e2fsck_get_journal(ctx, &journal); - if (retval) - return retval; - - retval = e2fsck_journal_load(journal); - if (retval) - goto errout; - - retval = journal_init_revoke(journal, 1024); - if (retval) - goto errout; - - retval = -journal_recover(journal); - if (retval) - goto errout; - - if (journal->j_superblock->s_errno) { - ctx->fs->super->s_state |= EXT2_ERROR_FS; - ext2fs_mark_super_dirty(ctx->fs); - journal->j_superblock->s_errno = 0; - mark_buffer_dirty(journal->j_sb_buffer); - } - -errout: - journal_destroy_revoke(journal); - journal_destroy_revoke_caches(); - e2fsck_journal_release(ctx, journal, 1, 0); - return retval; -} - -static int e2fsck_run_ext3_journal(e2fsck_t ctx) -{ - io_manager io_ptr = ctx->fs->io->manager; - int blocksize = ctx->fs->blocksize; - errcode_t retval, recover_retval; - - printf(_("%s: recovering journal\n"), ctx->device_name); - if (ctx->options & E2F_OPT_READONLY) { - printf(_("%s: won't do journal recovery while read-only\n"), - ctx->device_name); - return EXT2_ET_FILE_RO; - } - - if (ctx->fs->flags & EXT2_FLAG_DIRTY) - ext2fs_flush(ctx->fs); /* Force out any modifications */ - - recover_retval = recover_ext3_journal(ctx); - - /* - * Reload the filesystem context to get up-to-date data from disk - * because journal recovery will change the filesystem under us. - */ - ext2fs_close(ctx->fs); - retval = ext2fs_open(ctx->filesystem_name, EXT2_FLAG_RW, - ctx->superblock, blocksize, io_ptr, - &ctx->fs); - - if (retval) { - bb_error_msg(_("while trying to re-open %s"), - ctx->device_name); - bb_error_msg_and_die(0); - } - ctx->fs->priv_data = ctx; - - /* Set the superblock flags */ - e2fsck_clear_recover(ctx, recover_retval); - return recover_retval; -} - -/* - * This function will move the journal inode from a visible file in - * the filesystem directory hierarchy to the reserved inode if necessary. - */ -static const char *const journal_names[] = { - ".journal", "journal", ".journal.dat", "journal.dat", 0 }; - -static void e2fsck_move_ext3_journal(e2fsck_t ctx) -{ - struct ext2_super_block *sb = ctx->fs->super; - struct problem_context pctx; - struct ext2_inode inode; - ext2_filsys fs = ctx->fs; - ext2_ino_t ino; - errcode_t retval; - const char *const * cpp; - int group, mount_flags; - - clear_problem_context(&pctx); - - /* - * If the filesystem is opened read-only, or there is no - * journal, then do nothing. - */ - if ((ctx->options & E2F_OPT_READONLY) || - (sb->s_journal_inum == 0) || - !(sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)) - return; - - /* - * Read in the journal inode - */ - if (ext2fs_read_inode(fs, sb->s_journal_inum, &inode) != 0) - return; - - /* - * If it's necessary to backup the journal inode, do so. - */ - if ((sb->s_jnl_backup_type == 0) || - ((sb->s_jnl_backup_type == EXT3_JNL_BACKUP_BLOCKS) && - memcmp(inode.i_block, sb->s_jnl_blocks, EXT2_N_BLOCKS*4))) { - if (fix_problem(ctx, PR_0_BACKUP_JNL, &pctx)) { - memcpy(sb->s_jnl_blocks, inode.i_block, - EXT2_N_BLOCKS*4); - sb->s_jnl_blocks[16] = inode.i_size; - sb->s_jnl_backup_type = EXT3_JNL_BACKUP_BLOCKS; - ext2fs_mark_super_dirty(fs); - fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; - } - } - - /* - * If the journal is already the hidden inode, then do nothing - */ - if (sb->s_journal_inum == EXT2_JOURNAL_INO) - return; - - /* - * The journal inode had better have only one link and not be readable. - */ - if (inode.i_links_count != 1) - return; - - /* - * If the filesystem is mounted, or we can't tell whether - * or not it's mounted, do nothing. - */ - retval = ext2fs_check_if_mounted(ctx->filesystem_name, &mount_flags); - if (retval || (mount_flags & EXT2_MF_MOUNTED)) - return; - - /* - * If we can't find the name of the journal inode, then do - * nothing. - */ - for (cpp = journal_names; *cpp; cpp++) { - retval = ext2fs_lookup(fs, EXT2_ROOT_INO, *cpp, - strlen(*cpp), 0, &ino); - if ((retval == 0) && (ino == sb->s_journal_inum)) - break; - } - if (*cpp == 0) - return; - - /* We need the inode bitmap to be loaded */ - retval = ext2fs_read_bitmaps(fs); - if (retval) - return; - - pctx.str = *cpp; - if (!fix_problem(ctx, PR_0_MOVE_JOURNAL, &pctx)) - return; - - /* - * OK, we've done all the checks, let's actually move the - * journal inode. Errors at this point mean we need to force - * an ext2 filesystem check. - */ - if ((retval = ext2fs_unlink(fs, EXT2_ROOT_INO, *cpp, ino, 0)) != 0) - goto err_out; - if ((retval = ext2fs_write_inode(fs, EXT2_JOURNAL_INO, &inode)) != 0) - goto err_out; - sb->s_journal_inum = EXT2_JOURNAL_INO; - ext2fs_mark_super_dirty(fs); - fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; - inode.i_links_count = 0; - inode.i_dtime = time(NULL); - if ((retval = ext2fs_write_inode(fs, ino, &inode)) != 0) - goto err_out; - - group = ext2fs_group_of_ino(fs, ino); - ext2fs_unmark_inode_bitmap(fs->inode_map, ino); - ext2fs_mark_ib_dirty(fs); - fs->group_desc[group].bg_free_inodes_count++; - fs->super->s_free_inodes_count++; - return; - -err_out: - pctx.errcode = retval; - fix_problem(ctx, PR_0_ERR_MOVE_JOURNAL, &pctx); - fs->super->s_state &= ~EXT2_VALID_FS; - ext2fs_mark_super_dirty(fs); -} - -/* - * message.c --- print e2fsck messages (with compression) - * - * print_e2fsck_message() prints a message to the user, using - * compression techniques and expansions of abbreviations. - * - * The following % expansions are supported: - * - * %b block number - * %B integer - * %c block number - * %Di ->ino inode number - * %Dn ->name string - * %Dr ->rec_len - * %Dl ->name_len - * %Dt ->filetype - * %d inode number - * %g integer - * %i inode number - * %Is -> i_size - * %IS -> i_extra_isize - * %Ib -> i_blocks - * %Il -> i_links_count - * %Im -> i_mode - * %IM -> i_mtime - * %IF -> i_faddr - * %If -> i_file_acl - * %Id -> i_dir_acl - * %Iu -> i_uid - * %Ig -> i_gid - * %j inode number - * %m - * %N - * %p ext2fs_get_pathname of directory - * %P ext2fs_get_pathname of ->ino with as - * the containing directory. (If dirent is NULL - * then return the pathname of directory ) - * %q ext2fs_get_pathname of directory - * %Q ext2fs_get_pathname of directory with as - * the containing directory. - * %s miscellaneous string - * %S backup superblock - * %X hexadecimal format - * - * The following '@' expansions are supported: - * - * @a extended attribute - * @A error allocating - * @b block - * @B bitmap - * @c compress - * @C conflicts with some other fs block - * @D deleted - * @d directory - * @e entry - * @E Entry '%Dn' in %p (%i) - * @f filesystem - * @F for @i %i (%Q) is - * @g group - * @h HTREE directory inode - * @i inode - * @I illegal - * @j journal - * @l lost+found - * @L is a link - * @m multiply-claimed - * @n invalid - * @o orphaned - * @p problem in - * @r root inode - * @s should be - * @S superblock - * @u unattached - * @v device - * @z zero-length - */ - - -/* - * This structure defines the abbreviations used by the text strings - * below. The first character in the string is the index letter. An - * abbreviation of the form '@' is expanded by looking up the index - * letter in the table below. - */ -static const char *const abbrevs[] = { - N_("aextended attribute"), - N_("Aerror allocating"), - N_("bblock"), - N_("Bbitmap"), - N_("ccompress"), - N_("Cconflicts with some other fs @b"), - N_("iinode"), - N_("Iillegal"), - N_("jjournal"), - N_("Ddeleted"), - N_("ddirectory"), - N_("eentry"), - N_("E@e '%Dn' in %p (%i)"), - N_("ffilesystem"), - N_("Ffor @i %i (%Q) is"), - N_("ggroup"), - N_("hHTREE @d @i"), - N_("llost+found"), - N_("Lis a link"), - N_("mmultiply-claimed"), - N_("ninvalid"), - N_("oorphaned"), - N_("pproblem in"), - N_("rroot @i"), - N_("sshould be"), - N_("Ssuper@b"), - N_("uunattached"), - N_("vdevice"), - N_("zzero-length"), - "@@", - 0 - }; - -/* - * Give more user friendly names to the "special" inodes. - */ -#define num_special_inodes 11 -static const char *const special_inode_name[] = -{ - N_(""), /* 0 */ - N_(""), /* 1 */ - "/", /* 2 */ - N_(""), /* 3 */ - N_(""), /* 4 */ - N_(""), /* 5 */ - N_(""), /* 6 */ - N_(""), /* 7 */ - N_(""), /* 8 */ - N_(""), /* 9 */ - N_(""), /* 10 */ -}; - -/* - * This function does "safe" printing. It will convert non-printable - * ASCII characters using '^' and M- notation. - */ -static void safe_print(const char *cp, int len) -{ - unsigned char ch; - - if (len < 0) - len = strlen(cp); - - while (len--) { - ch = *cp++; - if (ch > 128) { - fputs("M-", stdout); - ch -= 128; - } - if ((ch < 32) || (ch == 0x7f)) { - bb_putchar('^'); - ch ^= 0x40; /* ^@, ^A, ^B; ^? for DEL */ - } - bb_putchar(ch); - } -} - - -/* - * This function prints a pathname, using the ext2fs_get_pathname - * function - */ -static void print_pathname(ext2_filsys fs, ext2_ino_t dir, ext2_ino_t ino) -{ - errcode_t retval; - char *path; - - if (!dir && (ino < num_special_inodes)) { - fputs(_(special_inode_name[ino]), stdout); - return; - } - - retval = ext2fs_get_pathname(fs, dir, ino, &path); - if (retval) - fputs("???", stdout); - else { - safe_print(path, -1); - ext2fs_free_mem(&path); - } -} - -static void print_e2fsck_message(e2fsck_t ctx, const char *msg, - struct problem_context *pctx, int first); -/* - * This function handles the '@' expansion. We allow recursive - * expansion; an @ expression can contain further '@' and '%' - * expressions. - */ -static void expand_at_expression(e2fsck_t ctx, char ch, - struct problem_context *pctx, - int *first) -{ - const char *const *cpp; - const char *str; - - /* Search for the abbreviation */ - for (cpp = abbrevs; *cpp; cpp++) { - if (ch == *cpp[0]) - break; - } - if (*cpp) { - str = _(*cpp) + 1; - if (*first && islower(*str)) { - *first = 0; - bb_putchar(toupper(*str++)); - } - print_e2fsck_message(ctx, str, pctx, *first); - } else - printf("@%c", ch); -} - -/* - * This function expands '%IX' expressions - */ -static void expand_inode_expression(char ch, - struct problem_context *ctx) -{ - struct ext2_inode *inode; - struct ext2_inode_large *large_inode; - char * time_str; - time_t t; - int do_gmt = -1; - - if (!ctx || !ctx->inode) - goto no_inode; - - inode = ctx->inode; - large_inode = (struct ext2_inode_large *) inode; - - switch (ch) { - case 's': - if (LINUX_S_ISDIR(inode->i_mode)) - printf("%u", inode->i_size); - else { - printf("%"PRIu64, (inode->i_size | - ((uint64_t) inode->i_size_high << 32))); - } - break; - case 'S': - printf("%u", large_inode->i_extra_isize); - break; - case 'b': - printf("%u", inode->i_blocks); - break; - case 'l': - printf("%d", inode->i_links_count); - break; - case 'm': - printf("0%o", inode->i_mode); - break; - case 'M': - /* The diet libc doesn't respect the TZ environemnt variable */ - if (do_gmt == -1) { - time_str = getenv("TZ"); - if (!time_str) - time_str = ""; - do_gmt = !strcmp(time_str, "GMT"); - } - t = inode->i_mtime; - time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t)); - printf("%.24s", time_str); - break; - case 'F': - printf("%u", inode->i_faddr); - break; - case 'f': - printf("%u", inode->i_file_acl); - break; - case 'd': - printf("%u", (LINUX_S_ISDIR(inode->i_mode) ? - inode->i_dir_acl : 0)); - break; - case 'u': - printf("%d", (inode->i_uid | - (inode->osd2.linux2.l_i_uid_high << 16))); - break; - case 'g': - printf("%d", (inode->i_gid | - (inode->osd2.linux2.l_i_gid_high << 16))); - break; - default: - no_inode: - printf("%%I%c", ch); - break; - } -} - -/* - * This function expands '%dX' expressions - */ -static void expand_dirent_expression(char ch, - struct problem_context *ctx) -{ - struct ext2_dir_entry *dirent; - int len; - - if (!ctx || !ctx->dirent) - goto no_dirent; - - dirent = ctx->dirent; - - switch (ch) { - case 'i': - printf("%u", dirent->inode); - break; - case 'n': - len = dirent->name_len & 0xFF; - if (len > EXT2_NAME_LEN) - len = EXT2_NAME_LEN; - if (len > dirent->rec_len) - len = dirent->rec_len; - safe_print(dirent->name, len); - break; - case 'r': - printf("%u", dirent->rec_len); - break; - case 'l': - printf("%u", dirent->name_len & 0xFF); - break; - case 't': - printf("%u", dirent->name_len >> 8); - break; - default: - no_dirent: - printf("%%D%c", ch); - break; - } -} - -static void expand_percent_expression(ext2_filsys fs, char ch, - struct problem_context *ctx) -{ - if (!ctx) - goto no_context; - - switch (ch) { - case '%': - bb_putchar('%'); - break; - case 'b': - printf("%u", ctx->blk); - break; - case 'B': - printf("%"PRIi64, ctx->blkcount); - break; - case 'c': - printf("%u", ctx->blk2); - break; - case 'd': - printf("%u", ctx->dir); - break; - case 'g': - printf("%d", ctx->group); - break; - case 'i': - printf("%u", ctx->ino); - break; - case 'j': - printf("%u", ctx->ino2); - break; - case 'm': - fputs(error_message(ctx->errcode), stdout); - break; - case 'N': - printf("%"PRIi64, ctx->num); - break; - case 'p': - print_pathname(fs, ctx->ino, 0); - break; - case 'P': - print_pathname(fs, ctx->ino2, - ctx->dirent ? ctx->dirent->inode : 0); - break; - case 'q': - print_pathname(fs, ctx->dir, 0); - break; - case 'Q': - print_pathname(fs, ctx->dir, ctx->ino); - break; - case 'S': - printf("%d", get_backup_sb(NULL, fs, NULL, NULL)); - break; - case 's': - fputs((ctx->str ? ctx->str : "NULL"), stdout); - break; - case 'X': - printf("0x%"PRIi64, ctx->num); - break; - default: - no_context: - printf("%%%c", ch); - break; - } -} - - -static void print_e2fsck_message(e2fsck_t ctx, const char *msg, - struct problem_context *pctx, int first) -{ - ext2_filsys fs = ctx->fs; - const char * cp; - int i; - - e2fsck_clear_progbar(ctx); - for (cp = msg; *cp; cp++) { - if (cp[0] == '@') { - cp++; - expand_at_expression(ctx, *cp, pctx, &first); - } else if (cp[0] == '%' && cp[1] == 'I') { - cp += 2; - expand_inode_expression(*cp, pctx); - } else if (cp[0] == '%' && cp[1] == 'D') { - cp += 2; - expand_dirent_expression(*cp, pctx); - } else if ((cp[0] == '%')) { - cp++; - expand_percent_expression(fs, *cp, pctx); - } else { - for (i=0; cp[i]; i++) - if ((cp[i] == '@') || cp[i] == '%') - break; - printf("%.*s", i, cp); - cp += i-1; - } - first = 0; - } -} - - -/* - * region.c --- code which manages allocations within a region. - */ - -struct region_el { - region_addr_t start; - region_addr_t end; - struct region_el *next; -}; - -struct region_struct { - region_addr_t min; - region_addr_t max; - struct region_el *allocated; -}; - -static region_t region_create(region_addr_t min, region_addr_t max) -{ - region_t region; - - region = xzalloc(sizeof(struct region_struct)); - region->min = min; - region->max = max; - return region; -} - -static void region_free(region_t region) -{ - struct region_el *r, *next; - - for (r = region->allocated; r; r = next) { - next = r->next; - free(r); - } - memset(region, 0, sizeof(struct region_struct)); - free(region); -} - -static int region_allocate(region_t region, region_addr_t start, int n) -{ - struct region_el *r, *new_region, *prev, *next; - region_addr_t end; - - end = start+n; - if ((start < region->min) || (end > region->max)) - return -1; - if (n == 0) - return 1; - - /* - * Search through the linked list. If we find that it - * conflicts witih something that's already allocated, return - * 1; if we can find an existing region which we can grow, do - * so. Otherwise, stop when we find the appropriate place - * insert a new region element into the linked list. - */ - for (r = region->allocated, prev=NULL; r; prev = r, r = r->next) { - if (((start >= r->start) && (start < r->end)) || - ((end > r->start) && (end <= r->end)) || - ((start <= r->start) && (end >= r->end))) - return 1; - if (end == r->start) { - r->start = start; - return 0; - } - if (start == r->end) { - if ((next = r->next)) { - if (end > next->start) - return 1; - if (end == next->start) { - r->end = next->end; - r->next = next->next; - free(next); - return 0; - } - } - r->end = end; - return 0; - } - if (start < r->start) - break; - } - /* - * Insert a new region element structure into the linked list - */ - new_region = xmalloc(sizeof(struct region_el)); - new_region->start = start; - new_region->end = start + n; - new_region->next = r; - if (prev) - prev->next = new_region; - else - region->allocated = new_region; - return 0; -} - -/* - * pass1.c -- pass #1 of e2fsck: sequential scan of the inode table - * - * Pass 1 of e2fsck iterates over all the inodes in the filesystems, - * and applies the following tests to each inode: - * - * - The mode field of the inode must be legal. - * - The size and block count fields of the inode are correct. - * - A data block must not be used by another inode - * - * Pass 1 also gathers the collects the following information: - * - * - A bitmap of which inodes are in use. (inode_used_map) - * - A bitmap of which inodes are directories. (inode_dir_map) - * - A bitmap of which inodes are regular files. (inode_reg_map) - * - A bitmap of which inodes have bad fields. (inode_bad_map) - * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) - * - A bitmap of which blocks are in use. (block_found_map) - * - A bitmap of which blocks are in use by two inodes (block_dup_map) - * - The data blocks of the directory inodes. (dir_map) - * - * Pass 1 is designed to stash away enough information so that the - * other passes should not need to read in the inode information - * during the normal course of a filesystem check. (Althogh if an - * inconsistency is detected, other passes may need to read in an - * inode to fix it.) - * - * Note that pass 1B will be invoked if there are any duplicate blocks - * found. - */ - - -static int process_block(ext2_filsys fs, blk_t *blocknr, - e2_blkcnt_t blockcnt, blk_t ref_blk, - int ref_offset, void *priv_data); -static int process_bad_block(ext2_filsys fs, blk_t *block_nr, - e2_blkcnt_t blockcnt, blk_t ref_blk, - int ref_offset, void *priv_data); -static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, - char *block_buf); -static void mark_table_blocks(e2fsck_t ctx); -static void alloc_imagic_map(e2fsck_t ctx); -static void mark_inode_bad(e2fsck_t ctx, ino_t ino); -static void handle_fs_bad_blocks(e2fsck_t ctx); -static void process_inodes(e2fsck_t ctx, char *block_buf); -static int process_inode_cmp(const void *a, const void *b); -static errcode_t scan_callback(ext2_filsys fs, - dgrp_t group, void * priv_data); -static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount, - char *block_buf, int adjust_sign); -/* static char *describe_illegal_block(ext2_filsys fs, blk_t block); */ - -static void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino, - struct ext2_inode * inode, int bufsize, - const char *proc); - -struct process_block_struct_1 { - ext2_ino_t ino; - unsigned is_dir:1, is_reg:1, clear:1, suppress:1, - fragmented:1, compressed:1, bbcheck:1; - blk_t num_blocks; - blk_t max_blocks; - e2_blkcnt_t last_block; - int num_illegal_blocks; - blk_t previous_block; - struct ext2_inode *inode; - struct problem_context *pctx; - ext2fs_block_bitmap fs_meta_blocks; - e2fsck_t ctx; -}; - -struct process_inode_block { - ext2_ino_t ino; - struct ext2_inode inode; -}; - -struct scan_callback_struct { - e2fsck_t ctx; - char *block_buf; -}; - -/* - * For the inodes to process list. - */ -static struct process_inode_block *inodes_to_process; -static int process_inode_count; - -static __u64 ext2_max_sizes[EXT2_MAX_BLOCK_LOG_SIZE - - EXT2_MIN_BLOCK_LOG_SIZE + 1]; - -/* - * Free all memory allocated by pass1 in preparation for restarting - * things. - */ -static void unwind_pass1(void) -{ - ext2fs_free_mem(&inodes_to_process); -} - -/* - * Check to make sure a device inode is real. Returns 1 if the device - * checks out, 0 if not. - * - * Note: this routine is now also used to check FIFO's and Sockets, - * since they have the same requirement; the i_block fields should be - * zero. - */ -static int -e2fsck_pass1_check_device_inode(ext2_filsys fs, struct ext2_inode *inode) -{ - int i; - - /* - * If i_blocks is non-zero, or the index flag is set, then - * this is a bogus device/fifo/socket - */ - if ((ext2fs_inode_data_blocks(fs, inode) != 0) || - (inode->i_flags & EXT2_INDEX_FL)) - return 0; - - /* - * We should be able to do the test below all the time, but - * because the kernel doesn't forcibly clear the device - * inode's additional i_block fields, there are some rare - * occasions when a legitimate device inode will have non-zero - * additional i_block fields. So for now, we only complain - * when the immutable flag is set, which should never happen - * for devices. (And that's when the problem is caused, since - * you can't set or clear immutable flags for devices.) Once - * the kernel has been fixed we can change this... - */ - if (inode->i_flags & (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL)) { - for (i=4; i < EXT2_N_BLOCKS; i++) - if (inode->i_block[i]) - return 0; - } - return 1; -} - -/* - * Check to make sure a symlink inode is real. Returns 1 if the symlink - * checks out, 0 if not. - */ -static int -e2fsck_pass1_check_symlink(ext2_filsys fs, struct ext2_inode *inode, char *buf) -{ - unsigned int len; - int i; - blk_t blocks; - - if ((inode->i_size_high || inode->i_size == 0) || - (inode->i_flags & EXT2_INDEX_FL)) - return 0; - - blocks = ext2fs_inode_data_blocks(fs, inode); - if (blocks) { - if ((inode->i_size >= fs->blocksize) || - (blocks != fs->blocksize >> 9) || - (inode->i_block[0] < fs->super->s_first_data_block) || - (inode->i_block[0] >= fs->super->s_blocks_count)) - return 0; - - for (i = 1; i < EXT2_N_BLOCKS; i++) - if (inode->i_block[i]) - return 0; - - if (io_channel_read_blk(fs->io, inode->i_block[0], 1, buf)) - return 0; - - len = strnlen(buf, fs->blocksize); - if (len == fs->blocksize) - return 0; - } else { - if (inode->i_size >= sizeof(inode->i_block)) - return 0; - - len = strnlen((char *)inode->i_block, sizeof(inode->i_block)); - if (len == sizeof(inode->i_block)) - return 0; - } - if (len != inode->i_size) - return 0; - return 1; -} - -/* - * If the immutable (or append-only) flag is set on the inode, offer - * to clear it. - */ -#define BAD_SPECIAL_FLAGS (EXT2_IMMUTABLE_FL | EXT2_APPEND_FL) -static void check_immutable(e2fsck_t ctx, struct problem_context *pctx) -{ - if (!(pctx->inode->i_flags & BAD_SPECIAL_FLAGS)) - return; - - if (!fix_problem(ctx, PR_1_SET_IMMUTABLE, pctx)) - return; - - pctx->inode->i_flags &= ~BAD_SPECIAL_FLAGS; - e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1"); -} - -/* - * If device, fifo or socket, check size is zero -- if not offer to - * clear it - */ -static void check_size(e2fsck_t ctx, struct problem_context *pctx) -{ - struct ext2_inode *inode = pctx->inode; - - if ((inode->i_size == 0) && (inode->i_size_high == 0)) - return; - - if (!fix_problem(ctx, PR_1_SET_NONZSIZE, pctx)) - return; - - inode->i_size = 0; - inode->i_size_high = 0; - e2fsck_write_inode(ctx, pctx->ino, pctx->inode, "pass1"); -} - -static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx) -{ - struct ext2_super_block *sb = ctx->fs->super; - struct ext2_inode_large *inode; - struct ext2_ext_attr_entry *entry; - char *start, *end; - int storage_size, remain, offs; - int problem = 0; - - inode = (struct ext2_inode_large *) pctx->inode; - storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE - - inode->i_extra_isize; - start = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE + - inode->i_extra_isize + sizeof(__u32); - end = (char *) inode + EXT2_INODE_SIZE(ctx->fs->super); - entry = (struct ext2_ext_attr_entry *) start; - - /* scan all entry's headers first */ - - /* take finish entry 0UL into account */ - remain = storage_size - sizeof(__u32); - offs = end - start; - - while (!EXT2_EXT_IS_LAST_ENTRY(entry)) { - - /* header eats this space */ - remain -= sizeof(struct ext2_ext_attr_entry); - - /* is attribute name valid? */ - if (EXT2_EXT_ATTR_SIZE(entry->e_name_len) > remain) { - pctx->num = entry->e_name_len; - problem = PR_1_ATTR_NAME_LEN; - goto fix; - } - - /* attribute len eats this space */ - remain -= EXT2_EXT_ATTR_SIZE(entry->e_name_len); - - /* check value size */ - if (entry->e_value_size == 0 || entry->e_value_size > remain) { - pctx->num = entry->e_value_size; - problem = PR_1_ATTR_VALUE_SIZE; - goto fix; - } - - /* check value placement */ - if (entry->e_value_offs + - EXT2_XATTR_SIZE(entry->e_value_size) != offs) { - printf("(entry->e_value_offs + entry->e_value_size: %d, offs: %d)\n", entry->e_value_offs + entry->e_value_size, offs); - pctx->num = entry->e_value_offs; - problem = PR_1_ATTR_VALUE_OFFSET; - goto fix; - } - - /* e_value_block must be 0 in inode's ea */ - if (entry->e_value_block != 0) { - pctx->num = entry->e_value_block; - problem = PR_1_ATTR_VALUE_BLOCK; - goto fix; - } - - /* e_hash must be 0 in inode's ea */ - if (entry->e_hash != 0) { - pctx->num = entry->e_hash; - problem = PR_1_ATTR_HASH; - goto fix; - } - - remain -= entry->e_value_size; - offs -= EXT2_XATTR_SIZE(entry->e_value_size); - - entry = EXT2_EXT_ATTR_NEXT(entry); - } -fix: - /* - * it seems like a corruption. it's very unlikely we could repair - * EA(s) in automatic fashion -bzzz - */ - if (problem == 0 || !fix_problem(ctx, problem, pctx)) - return; - - /* simple remove all possible EA(s) */ - *((__u32 *)start) = 0UL; - e2fsck_write_inode_full(ctx, pctx->ino, (struct ext2_inode *)inode, - EXT2_INODE_SIZE(sb), "pass1"); -} - -static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx) -{ - struct ext2_super_block *sb = ctx->fs->super; - struct ext2_inode_large *inode; - __u32 *eamagic; - int min, max; - - inode = (struct ext2_inode_large *) pctx->inode; - if (EXT2_INODE_SIZE(sb) == EXT2_GOOD_OLD_INODE_SIZE) { - /* this isn't large inode. so, nothing to check */ - return; - } - - /* i_extra_isize must cover i_extra_isize + i_pad1 at least */ - min = sizeof(inode->i_extra_isize) + sizeof(inode->i_pad1); - max = EXT2_INODE_SIZE(sb) - EXT2_GOOD_OLD_INODE_SIZE; - /* - * For now we will allow i_extra_isize to be 0, but really - * implementations should never allow i_extra_isize to be 0 - */ - if (inode->i_extra_isize && - (inode->i_extra_isize < min || inode->i_extra_isize > max)) { - if (!fix_problem(ctx, PR_1_EXTRA_ISIZE, pctx)) - return; - inode->i_extra_isize = min; - e2fsck_write_inode_full(ctx, pctx->ino, pctx->inode, - EXT2_INODE_SIZE(sb), "pass1"); - return; - } - - eamagic = (__u32 *) (((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE + - inode->i_extra_isize); - if (*eamagic == EXT2_EXT_ATTR_MAGIC) { - /* it seems inode has an extended attribute(s) in body */ - check_ea_in_inode(ctx, pctx); - } -} - -static void e2fsck_pass1(e2fsck_t ctx) -{ - int i; - __u64 max_sizes; - ext2_filsys fs = ctx->fs; - ext2_ino_t ino; - struct ext2_inode *inode; - ext2_inode_scan scan; - char *block_buf; - unsigned char frag, fsize; - struct problem_context pctx; - struct scan_callback_struct scan_struct; - struct ext2_super_block *sb = ctx->fs->super; - int imagic_fs; - int busted_fs_time = 0; - int inode_size; - - clear_problem_context(&pctx); - - if (!(ctx->options & E2F_OPT_PREEN)) - fix_problem(ctx, PR_1_PASS_HEADER, &pctx); - - if ((fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) && - !(ctx->options & E2F_OPT_NO)) { - if (ext2fs_u32_list_create(&ctx->dirs_to_hash, 50)) - ctx->dirs_to_hash = 0; - } - - /* Pass 1 */ - -#define EXT2_BPP(bits) (1ULL << ((bits) - 2)) - - for (i = EXT2_MIN_BLOCK_LOG_SIZE; i <= EXT2_MAX_BLOCK_LOG_SIZE; i++) { - max_sizes = EXT2_NDIR_BLOCKS + EXT2_BPP(i); - max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i); - max_sizes = max_sizes + EXT2_BPP(i) * EXT2_BPP(i) * EXT2_BPP(i); - max_sizes = (max_sizes * (1UL << i)) - 1; - ext2_max_sizes[i - EXT2_MIN_BLOCK_LOG_SIZE] = max_sizes; - } -#undef EXT2_BPP - - imagic_fs = (sb->s_feature_compat & EXT2_FEATURE_COMPAT_IMAGIC_INODES); - - /* - * Allocate bitmaps structures - */ - pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("in-use inode map"), - &ctx->inode_used_map); - if (pctx.errcode) { - pctx.num = 1; - fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - pctx.errcode = ext2fs_allocate_inode_bitmap(fs, - _("directory inode map"), &ctx->inode_dir_map); - if (pctx.errcode) { - pctx.num = 2; - fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - pctx.errcode = ext2fs_allocate_inode_bitmap(fs, - _("regular file inode map"), &ctx->inode_reg_map); - if (pctx.errcode) { - pctx.num = 6; - fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - pctx.errcode = ext2fs_allocate_block_bitmap(fs, _("in-use block map"), - &ctx->block_found_map); - if (pctx.errcode) { - pctx.num = 1; - fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - pctx.errcode = ext2fs_create_icount2(fs, 0, 0, 0, - &ctx->inode_link_info); - if (pctx.errcode) { - fix_problem(ctx, PR_1_ALLOCATE_ICOUNT, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - inode_size = EXT2_INODE_SIZE(fs->super); - inode = (struct ext2_inode *) - e2fsck_allocate_memory(ctx, inode_size, "scratch inode"); - - inodes_to_process = (struct process_inode_block *) - e2fsck_allocate_memory(ctx, - (ctx->process_inode_size * - sizeof(struct process_inode_block)), - "array of inodes to process"); - process_inode_count = 0; - - pctx.errcode = ext2fs_init_dblist(fs, 0); - if (pctx.errcode) { - fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - - /* - * If the last orphan field is set, clear it, since the pass1 - * processing will automatically find and clear the orphans. - * In the future, we may want to try using the last_orphan - * linked list ourselves, but for now, we clear it so that the - * ext3 mount code won't get confused. - */ - if (!(ctx->options & E2F_OPT_READONLY)) { - if (fs->super->s_last_orphan) { - fs->super->s_last_orphan = 0; - ext2fs_mark_super_dirty(fs); - } - } - - mark_table_blocks(ctx); - block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3, - "block interate buffer"); - e2fsck_use_inode_shortcuts(ctx, 1); - ehandler_operation(_("doing inode scan")); - pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks, - &scan); - if (pctx.errcode) { - fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0); - ctx->stashed_inode = inode; - scan_struct.ctx = ctx; - scan_struct.block_buf = block_buf; - ext2fs_set_inode_callback(scan, scan_callback, &scan_struct); - if (ctx->progress) - if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count)) - return; - if ((fs->super->s_wtime < fs->super->s_inodes_count) || - (fs->super->s_mtime < fs->super->s_inodes_count)) - busted_fs_time = 1; - - while (1) { - pctx.errcode = ext2fs_get_next_inode_full(scan, &ino, - inode, inode_size); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) { - continue; - } - if (pctx.errcode) { - fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - if (!ino) - break; - pctx.ino = ino; - pctx.inode = inode; - ctx->stashed_ino = ino; - if (inode->i_links_count) { - pctx.errcode = ext2fs_icount_store(ctx->inode_link_info, - ino, inode->i_links_count); - if (pctx.errcode) { - pctx.num = inode->i_links_count; - fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - } - if (ino == EXT2_BAD_INO) { - struct process_block_struct_1 pb; - - pctx.errcode = ext2fs_copy_bitmap(ctx->block_found_map, - &pb.fs_meta_blocks); - if (pctx.errcode) { - pctx.num = 4; - fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - pb.ino = EXT2_BAD_INO; - pb.num_blocks = pb.last_block = 0; - pb.num_illegal_blocks = 0; - pb.suppress = 0; pb.clear = 0; pb.is_dir = 0; - pb.is_reg = 0; pb.fragmented = 0; pb.bbcheck = 0; - pb.inode = inode; - pb.pctx = &pctx; - pb.ctx = ctx; - pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, - block_buf, process_bad_block, &pb); - ext2fs_free_block_bitmap(pb.fs_meta_blocks); - if (pctx.errcode) { - fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - if (pb.bbcheck) - if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) { - ctx->flags |= E2F_FLAG_ABORT; - return; - } - ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); - clear_problem_context(&pctx); - continue; - } else if (ino == EXT2_ROOT_INO) { - /* - * Make sure the root inode is a directory; if - * not, offer to clear it. It will be - * regnerated in pass #3. - */ - if (!LINUX_S_ISDIR(inode->i_mode)) { - if (fix_problem(ctx, PR_1_ROOT_NO_DIR, &pctx)) { - inode->i_dtime = time(NULL); - inode->i_links_count = 0; - ext2fs_icount_store(ctx->inode_link_info, - ino, 0); - e2fsck_write_inode(ctx, ino, inode, - "pass1"); - } - } - /* - * If dtime is set, offer to clear it. mke2fs - * version 0.2b created filesystems with the - * dtime field set for the root and lost+found - * directories. We won't worry about - * /lost+found, since that can be regenerated - * easily. But we will fix the root directory - * as a special case. - */ - if (inode->i_dtime && inode->i_links_count) { - if (fix_problem(ctx, PR_1_ROOT_DTIME, &pctx)) { - inode->i_dtime = 0; - e2fsck_write_inode(ctx, ino, inode, - "pass1"); - } - } - } else if (ino == EXT2_JOURNAL_INO) { - ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); - if (fs->super->s_journal_inum == EXT2_JOURNAL_INO) { - if (!LINUX_S_ISREG(inode->i_mode) && - fix_problem(ctx, PR_1_JOURNAL_BAD_MODE, - &pctx)) { - inode->i_mode = LINUX_S_IFREG; - e2fsck_write_inode(ctx, ino, inode, - "pass1"); - } - check_blocks(ctx, &pctx, block_buf); - continue; - } - if ((inode->i_links_count || inode->i_blocks || - inode->i_block[0]) && - fix_problem(ctx, PR_1_JOURNAL_INODE_NOT_CLEAR, - &pctx)) { - memset(inode, 0, inode_size); - ext2fs_icount_store(ctx->inode_link_info, - ino, 0); - e2fsck_write_inode_full(ctx, ino, inode, - inode_size, "pass1"); - } - } else if (ino < EXT2_FIRST_INODE(fs->super)) { - int problem = 0; - - ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); - if (ino == EXT2_BOOT_LOADER_INO) { - if (LINUX_S_ISDIR(inode->i_mode)) - problem = PR_1_RESERVED_BAD_MODE; - } else if (ino == EXT2_RESIZE_INO) { - if (inode->i_mode && - !LINUX_S_ISREG(inode->i_mode)) - problem = PR_1_RESERVED_BAD_MODE; - } else { - if (inode->i_mode != 0) - problem = PR_1_RESERVED_BAD_MODE; - } - if (problem) { - if (fix_problem(ctx, problem, &pctx)) { - inode->i_mode = 0; - e2fsck_write_inode(ctx, ino, inode, - "pass1"); - } - } - check_blocks(ctx, &pctx, block_buf); - continue; - } - /* - * Check for inodes who might have been part of the - * orphaned list linked list. They should have gotten - * dealt with by now, unless the list had somehow been - * corrupted. - * - * FIXME: In the future, inodes which are still in use - * (and which are therefore) pending truncation should - * be handled specially. Right now we just clear the - * dtime field, and the normal e2fsck handling of - * inodes where i_size and the inode blocks are - * inconsistent is to fix i_size, instead of releasing - * the extra blocks. This won't catch the inodes that - * was at the end of the orphan list, but it's better - * than nothing. The right answer is that there - * shouldn't be any bugs in the orphan list handling. :-) - */ - if (inode->i_dtime && !busted_fs_time && - inode->i_dtime < ctx->fs->super->s_inodes_count) { - if (fix_problem(ctx, PR_1_LOW_DTIME, &pctx)) { - inode->i_dtime = inode->i_links_count ? - 0 : time(NULL); - e2fsck_write_inode(ctx, ino, inode, - "pass1"); - } - } - - /* - * This code assumes that deleted inodes have - * i_links_count set to 0. - */ - if (!inode->i_links_count) { - if (!inode->i_dtime && inode->i_mode) { - if (fix_problem(ctx, - PR_1_ZERO_DTIME, &pctx)) { - inode->i_dtime = time(NULL); - e2fsck_write_inode(ctx, ino, inode, - "pass1"); - } - } - continue; - } - /* - * n.b. 0.3c ext2fs code didn't clear i_links_count for - * deleted files. Oops. - * - * Since all new ext2 implementations get this right, - * we now assume that the case of non-zero - * i_links_count and non-zero dtime means that we - * should keep the file, not delete it. - * - */ - if (inode->i_dtime) { - if (fix_problem(ctx, PR_1_SET_DTIME, &pctx)) { - inode->i_dtime = 0; - e2fsck_write_inode(ctx, ino, inode, "pass1"); - } - } - - ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); - switch (fs->super->s_creator_os) { - case EXT2_OS_LINUX: - frag = inode->osd2.linux2.l_i_frag; - fsize = inode->osd2.linux2.l_i_fsize; - break; - case EXT2_OS_HURD: - frag = inode->osd2.hurd2.h_i_frag; - fsize = inode->osd2.hurd2.h_i_fsize; - break; - case EXT2_OS_MASIX: - frag = inode->osd2.masix2.m_i_frag; - fsize = inode->osd2.masix2.m_i_fsize; - break; - default: - frag = fsize = 0; - } - - if (inode->i_faddr || frag || fsize || - (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl)) - mark_inode_bad(ctx, ino); - if (inode->i_flags & EXT2_IMAGIC_FL) { - if (imagic_fs) { - if (!ctx->inode_imagic_map) - alloc_imagic_map(ctx); - ext2fs_mark_inode_bitmap(ctx->inode_imagic_map, - ino); - } else { - if (fix_problem(ctx, PR_1_SET_IMAGIC, &pctx)) { - inode->i_flags &= ~EXT2_IMAGIC_FL; - e2fsck_write_inode(ctx, ino, - inode, "pass1"); - } - } - } - - check_inode_extra_space(ctx, &pctx); - - if (LINUX_S_ISDIR(inode->i_mode)) { - ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino); - e2fsck_add_dir_info(ctx, ino, 0); - ctx->fs_directory_count++; - } else if (LINUX_S_ISREG (inode->i_mode)) { - ext2fs_mark_inode_bitmap(ctx->inode_reg_map, ino); - ctx->fs_regular_count++; - } else if (LINUX_S_ISCHR (inode->i_mode) && - e2fsck_pass1_check_device_inode(fs, inode)) { - check_immutable(ctx, &pctx); - check_size(ctx, &pctx); - ctx->fs_chardev_count++; - } else if (LINUX_S_ISBLK (inode->i_mode) && - e2fsck_pass1_check_device_inode(fs, inode)) { - check_immutable(ctx, &pctx); - check_size(ctx, &pctx); - ctx->fs_blockdev_count++; - } else if (LINUX_S_ISLNK (inode->i_mode) && - e2fsck_pass1_check_symlink(fs, inode, block_buf)) { - check_immutable(ctx, &pctx); - ctx->fs_symlinks_count++; - if (ext2fs_inode_data_blocks(fs, inode) == 0) { - ctx->fs_fast_symlinks_count++; - check_blocks(ctx, &pctx, block_buf); - continue; - } - } - else if (LINUX_S_ISFIFO (inode->i_mode) && - e2fsck_pass1_check_device_inode(fs, inode)) { - check_immutable(ctx, &pctx); - check_size(ctx, &pctx); - ctx->fs_fifo_count++; - } else if ((LINUX_S_ISSOCK (inode->i_mode)) && - e2fsck_pass1_check_device_inode(fs, inode)) { - check_immutable(ctx, &pctx); - check_size(ctx, &pctx); - ctx->fs_sockets_count++; - } else - mark_inode_bad(ctx, ino); - if (inode->i_block[EXT2_IND_BLOCK]) - ctx->fs_ind_count++; - if (inode->i_block[EXT2_DIND_BLOCK]) - ctx->fs_dind_count++; - if (inode->i_block[EXT2_TIND_BLOCK]) - ctx->fs_tind_count++; - if (inode->i_block[EXT2_IND_BLOCK] || - inode->i_block[EXT2_DIND_BLOCK] || - inode->i_block[EXT2_TIND_BLOCK] || - inode->i_file_acl) { - inodes_to_process[process_inode_count].ino = ino; - inodes_to_process[process_inode_count].inode = *inode; - process_inode_count++; - } else - check_blocks(ctx, &pctx, block_buf); - - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - - if (process_inode_count >= ctx->process_inode_size) { - process_inodes(ctx, block_buf); - - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - } - } - process_inodes(ctx, block_buf); - ext2fs_close_inode_scan(scan); - ehandler_operation(0); - - /* - * If any extended attribute blocks' reference counts need to - * be adjusted, either up (ctx->refcount_extra), or down - * (ctx->refcount), then fix them. - */ - if (ctx->refcount) { - adjust_extattr_refcount(ctx, ctx->refcount, block_buf, -1); - ea_refcount_free(ctx->refcount); - ctx->refcount = 0; - } - if (ctx->refcount_extra) { - adjust_extattr_refcount(ctx, ctx->refcount_extra, - block_buf, +1); - ea_refcount_free(ctx->refcount_extra); - ctx->refcount_extra = 0; - } - - if (ctx->invalid_bitmaps) - handle_fs_bad_blocks(ctx); - - /* We don't need the block_ea_map any more */ - ext2fs_free_block_bitmap(ctx->block_ea_map); - ctx->block_ea_map = 0; - - if (ctx->flags & E2F_FLAG_RESIZE_INODE) { - ext2fs_block_bitmap save_bmap; - - save_bmap = fs->block_map; - fs->block_map = ctx->block_found_map; - clear_problem_context(&pctx); - pctx.errcode = ext2fs_create_resize_inode(fs); - if (pctx.errcode) { - fix_problem(ctx, PR_1_RESIZE_INODE_CREATE, &pctx); - /* Should never get here */ - ctx->flags |= E2F_FLAG_ABORT; - return; - } - e2fsck_read_inode(ctx, EXT2_RESIZE_INO, inode, - "recreate inode"); - inode->i_mtime = time(NULL); - e2fsck_write_inode(ctx, EXT2_RESIZE_INO, inode, - "recreate inode"); - fs->block_map = save_bmap; - ctx->flags &= ~E2F_FLAG_RESIZE_INODE; - } - - if (ctx->flags & E2F_FLAG_RESTART) { - /* - * Only the master copy of the superblock and block - * group descriptors are going to be written during a - * restart, so set the superblock to be used to be the - * master superblock. - */ - ctx->use_superblock = 0; - unwind_pass1(); - goto endit; - } - - if (ctx->block_dup_map) { - if (ctx->options & E2F_OPT_PREEN) { - clear_problem_context(&pctx); - fix_problem(ctx, PR_1_DUP_BLOCKS_PREENSTOP, &pctx); - } - e2fsck_pass1_dupblocks(ctx, block_buf); - } - ext2fs_free_mem(&inodes_to_process); -endit: - e2fsck_use_inode_shortcuts(ctx, 0); - - ext2fs_free_mem(&block_buf); - ext2fs_free_mem(&inode); -} - -/* - * When the inode_scan routines call this callback at the end of the - * glock group, call process_inodes. - */ -static errcode_t scan_callback(ext2_filsys fs, - dgrp_t group, void * priv_data) -{ - struct scan_callback_struct *scan_struct; - e2fsck_t ctx; - - scan_struct = (struct scan_callback_struct *) priv_data; - ctx = scan_struct->ctx; - - process_inodes((e2fsck_t) fs->priv_data, scan_struct->block_buf); - - if (ctx->progress) - if ((ctx->progress)(ctx, 1, group+1, - ctx->fs->group_desc_count)) - return EXT2_ET_CANCEL_REQUESTED; - - return 0; -} - -/* - * Process the inodes in the "inodes to process" list. - */ -static void process_inodes(e2fsck_t ctx, char *block_buf) -{ - int i; - struct ext2_inode *old_stashed_inode; - ext2_ino_t old_stashed_ino; - const char *old_operation; - char buf[80]; - struct problem_context pctx; - - /* begin process_inodes */ - if (process_inode_count == 0) - return; - old_operation = ehandler_operation(0); - old_stashed_inode = ctx->stashed_inode; - old_stashed_ino = ctx->stashed_ino; - qsort(inodes_to_process, process_inode_count, - sizeof(struct process_inode_block), process_inode_cmp); - clear_problem_context(&pctx); - for (i=0; i < process_inode_count; i++) { - pctx.inode = ctx->stashed_inode = &inodes_to_process[i].inode; - pctx.ino = ctx->stashed_ino = inodes_to_process[i].ino; - sprintf(buf, _("reading indirect blocks of inode %u"), - pctx.ino); - ehandler_operation(buf); - check_blocks(ctx, &pctx, block_buf); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - break; - } - ctx->stashed_inode = old_stashed_inode; - ctx->stashed_ino = old_stashed_ino; - process_inode_count = 0; - /* end process inodes */ - - ehandler_operation(old_operation); -} - -static int process_inode_cmp(const void *a, const void *b) -{ - const struct process_inode_block *ib_a = - (const struct process_inode_block *) a; - const struct process_inode_block *ib_b = - (const struct process_inode_block *) b; - int ret; - - ret = (ib_a->inode.i_block[EXT2_IND_BLOCK] - - ib_b->inode.i_block[EXT2_IND_BLOCK]); - if (ret == 0) - ret = ib_a->inode.i_file_acl - ib_b->inode.i_file_acl; - return ret; -} - -/* - * Mark an inode as being bad in some what - */ -static void mark_inode_bad(e2fsck_t ctx, ino_t ino) -{ - struct problem_context pctx; - - if (!ctx->inode_bad_map) { - clear_problem_context(&pctx); - - pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs, - _("bad inode map"), &ctx->inode_bad_map); - if (pctx.errcode) { - pctx.num = 3; - fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); - /* Should never get here */ - ctx->flags |= E2F_FLAG_ABORT; - return; - } - } - ext2fs_mark_inode_bitmap(ctx->inode_bad_map, ino); -} - - -/* - * This procedure will allocate the inode imagic table - */ -static void alloc_imagic_map(e2fsck_t ctx) -{ - struct problem_context pctx; - - clear_problem_context(&pctx); - pctx.errcode = ext2fs_allocate_inode_bitmap(ctx->fs, - _("imagic inode map"), - &ctx->inode_imagic_map); - if (pctx.errcode) { - pctx.num = 5; - fix_problem(ctx, PR_1_ALLOCATE_IBITMAP_ERROR, &pctx); - /* Should never get here */ - ctx->flags |= E2F_FLAG_ABORT; - return; - } -} - -/* - * Marks a block as in use, setting the dup_map if it's been set - * already. Called by process_block and process_bad_block. - * - * WARNING: Assumes checks have already been done to make sure block - * is valid. This is true in both process_block and process_bad_block. - */ -static void mark_block_used(e2fsck_t ctx, blk_t block) -{ - struct problem_context pctx; - - clear_problem_context(&pctx); - - if (ext2fs_fast_test_block_bitmap(ctx->block_found_map, block)) { - if (!ctx->block_dup_map) { - pctx.errcode = ext2fs_allocate_block_bitmap(ctx->fs, - _("multiply claimed block map"), - &ctx->block_dup_map); - if (pctx.errcode) { - pctx.num = 3; - fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, - &pctx); - /* Should never get here */ - ctx->flags |= E2F_FLAG_ABORT; - return; - } - } - ext2fs_fast_mark_block_bitmap(ctx->block_dup_map, block); - } else { - ext2fs_fast_mark_block_bitmap(ctx->block_found_map, block); - } -} - -/* - * Adjust the extended attribute block's reference counts at the end - * of pass 1, either by subtracting out references for EA blocks that - * are still referenced in ctx->refcount, or by adding references for - * EA blocks that had extra references as accounted for in - * ctx->refcount_extra. - */ -static void adjust_extattr_refcount(e2fsck_t ctx, ext2_refcount_t refcount, - char *block_buf, int adjust_sign) -{ - struct ext2_ext_attr_header *header; - struct problem_context pctx; - ext2_filsys fs = ctx->fs; - blk_t blk; - __u32 should_be; - int count; - - clear_problem_context(&pctx); - - ea_refcount_intr_begin(refcount); - while (1) { - if ((blk = ea_refcount_intr_next(refcount, &count)) == 0) - break; - pctx.blk = blk; - pctx.errcode = ext2fs_read_ext_attr(fs, blk, block_buf); - if (pctx.errcode) { - fix_problem(ctx, PR_1_EXTATTR_READ_ABORT, &pctx); - return; - } - header = (struct ext2_ext_attr_header *) block_buf; - pctx.blkcount = header->h_refcount; - should_be = header->h_refcount + adjust_sign * count; - pctx.num = should_be; - if (fix_problem(ctx, PR_1_EXTATTR_REFCOUNT, &pctx)) { - header->h_refcount = should_be; - pctx.errcode = ext2fs_write_ext_attr(fs, blk, - block_buf); - if (pctx.errcode) { - fix_problem(ctx, PR_1_EXTATTR_WRITE, &pctx); - continue; - } - } - } -} - -/* - * Handle processing the extended attribute blocks - */ -static int check_ext_attr(e2fsck_t ctx, struct problem_context *pctx, - char *block_buf) -{ - ext2_filsys fs = ctx->fs; - ext2_ino_t ino = pctx->ino; - struct ext2_inode *inode = pctx->inode; - blk_t blk; - char * end; - struct ext2_ext_attr_header *header; - struct ext2_ext_attr_entry *entry; - int count; - region_t region; - - blk = inode->i_file_acl; - if (blk == 0) - return 0; - - /* - * If the Extended attribute flag isn't set, then a non-zero - * file acl means that the inode is corrupted. - * - * Or if the extended attribute block is an invalid block, - * then the inode is also corrupted. - */ - if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) || - (blk < fs->super->s_first_data_block) || - (blk >= fs->super->s_blocks_count)) { - mark_inode_bad(ctx, ino); - return 0; - } - - /* If ea bitmap hasn't been allocated, create it */ - if (!ctx->block_ea_map) { - pctx->errcode = ext2fs_allocate_block_bitmap(fs, - _("ext attr block map"), - &ctx->block_ea_map); - if (pctx->errcode) { - pctx->num = 2; - fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, pctx); - ctx->flags |= E2F_FLAG_ABORT; - return 0; - } - } - - /* Create the EA refcount structure if necessary */ - if (!ctx->refcount) { - pctx->errcode = ea_refcount_create(0, &ctx->refcount); - if (pctx->errcode) { - pctx->num = 1; - fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx); - ctx->flags |= E2F_FLAG_ABORT; - return 0; - } - } - - /* Have we seen this EA block before? */ - if (ext2fs_fast_test_block_bitmap(ctx->block_ea_map, blk)) { - if (ea_refcount_decrement(ctx->refcount, blk, 0) == 0) - return 1; - /* Ooops, this EA was referenced more than it stated */ - if (!ctx->refcount_extra) { - pctx->errcode = ea_refcount_create(0, - &ctx->refcount_extra); - if (pctx->errcode) { - pctx->num = 2; - fix_problem(ctx, PR_1_ALLOCATE_REFCOUNT, pctx); - ctx->flags |= E2F_FLAG_ABORT; - return 0; - } - } - ea_refcount_increment(ctx->refcount_extra, blk, 0); - return 1; - } - - /* - * OK, we haven't seen this EA block yet. So we need to - * validate it - */ - pctx->blk = blk; - pctx->errcode = ext2fs_read_ext_attr(fs, blk, block_buf); - if (pctx->errcode && fix_problem(ctx, PR_1_READ_EA_BLOCK, pctx)) - goto clear_extattr; - header = (struct ext2_ext_attr_header *) block_buf; - pctx->blk = inode->i_file_acl; - if (((ctx->ext_attr_ver == 1) && - (header->h_magic != EXT2_EXT_ATTR_MAGIC_v1)) || - ((ctx->ext_attr_ver == 2) && - (header->h_magic != EXT2_EXT_ATTR_MAGIC))) { - if (fix_problem(ctx, PR_1_BAD_EA_BLOCK, pctx)) - goto clear_extattr; - } - - if (header->h_blocks != 1) { - if (fix_problem(ctx, PR_1_EA_MULTI_BLOCK, pctx)) - goto clear_extattr; - } - - region = region_create(0, fs->blocksize); - if (!region) { - fix_problem(ctx, PR_1_EA_ALLOC_REGION, pctx); - ctx->flags |= E2F_FLAG_ABORT; - return 0; - } - if (region_allocate(region, 0, sizeof(struct ext2_ext_attr_header))) { - if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx)) - goto clear_extattr; - } - - entry = (struct ext2_ext_attr_entry *)(header+1); - end = block_buf + fs->blocksize; - while ((char *)entry < end && *(__u32 *)entry) { - if (region_allocate(region, (char *)entry - (char *)header, - EXT2_EXT_ATTR_LEN(entry->e_name_len))) { - if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx)) - goto clear_extattr; - } - if ((ctx->ext_attr_ver == 1 && - (entry->e_name_len == 0 || entry->e_name_index != 0)) || - (ctx->ext_attr_ver == 2 && - entry->e_name_index == 0)) { - if (fix_problem(ctx, PR_1_EA_BAD_NAME, pctx)) - goto clear_extattr; - } - if (entry->e_value_block != 0) { - if (fix_problem(ctx, PR_1_EA_BAD_VALUE, pctx)) - goto clear_extattr; - } - if (entry->e_value_size && - region_allocate(region, entry->e_value_offs, - EXT2_EXT_ATTR_SIZE(entry->e_value_size))) { - if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx)) - goto clear_extattr; - } - entry = EXT2_EXT_ATTR_NEXT(entry); - } - if (region_allocate(region, (char *)entry - (char *)header, 4)) { - if (fix_problem(ctx, PR_1_EA_ALLOC_COLLISION, pctx)) - goto clear_extattr; - } - region_free(region); - - count = header->h_refcount - 1; - if (count) - ea_refcount_store(ctx->refcount, blk, count); - mark_block_used(ctx, blk); - ext2fs_fast_mark_block_bitmap(ctx->block_ea_map, blk); - - return 1; - -clear_extattr: - inode->i_file_acl = 0; - e2fsck_write_inode(ctx, ino, inode, "check_ext_attr"); - return 0; -} - -/* Returns 1 if bad htree, 0 if OK */ -static int handle_htree(e2fsck_t ctx, struct problem_context *pctx, - ext2_ino_t ino FSCK_ATTR((unused)), - struct ext2_inode *inode, - char *block_buf) -{ - struct ext2_dx_root_info *root; - ext2_filsys fs = ctx->fs; - errcode_t retval; - blk_t blk; - - if ((!LINUX_S_ISDIR(inode->i_mode) && - fix_problem(ctx, PR_1_HTREE_NODIR, pctx)) || - (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) && - fix_problem(ctx, PR_1_HTREE_SET, pctx))) - return 1; - - blk = inode->i_block[0]; - if (((blk == 0) || - (blk < fs->super->s_first_data_block) || - (blk >= fs->super->s_blocks_count)) && - fix_problem(ctx, PR_1_HTREE_BADROOT, pctx)) - return 1; - - retval = io_channel_read_blk(fs->io, blk, 1, block_buf); - if (retval && fix_problem(ctx, PR_1_HTREE_BADROOT, pctx)) - return 1; - - /* XXX should check that beginning matches a directory */ - root = (struct ext2_dx_root_info *) (block_buf + 24); - - if ((root->reserved_zero || root->info_length < 8) && - fix_problem(ctx, PR_1_HTREE_BADROOT, pctx)) - return 1; - - pctx->num = root->hash_version; - if ((root->hash_version != EXT2_HASH_LEGACY) && - (root->hash_version != EXT2_HASH_HALF_MD4) && - (root->hash_version != EXT2_HASH_TEA) && - fix_problem(ctx, PR_1_HTREE_HASHV, pctx)) - return 1; - - if ((root->unused_flags & EXT2_HASH_FLAG_INCOMPAT) && - fix_problem(ctx, PR_1_HTREE_INCOMPAT, pctx)) - return 1; - - pctx->num = root->indirect_levels; - if ((root->indirect_levels > 1) && - fix_problem(ctx, PR_1_HTREE_DEPTH, pctx)) - return 1; - - return 0; -} - -/* - * This subroutine is called on each inode to account for all of the - * blocks used by that inode. - */ -static void check_blocks(e2fsck_t ctx, struct problem_context *pctx, - char *block_buf) -{ - ext2_filsys fs = ctx->fs; - struct process_block_struct_1 pb; - ext2_ino_t ino = pctx->ino; - struct ext2_inode *inode = pctx->inode; - int bad_size = 0; - int dirty_inode = 0; - __u64 size; - - pb.ino = ino; - pb.num_blocks = 0; - pb.last_block = -1; - pb.num_illegal_blocks = 0; - pb.suppress = 0; pb.clear = 0; - pb.fragmented = 0; - pb.compressed = 0; - pb.previous_block = 0; - pb.is_dir = LINUX_S_ISDIR(inode->i_mode); - pb.is_reg = LINUX_S_ISREG(inode->i_mode); - pb.max_blocks = 1 << (31 - fs->super->s_log_block_size); - pb.inode = inode; - pb.pctx = pctx; - pb.ctx = ctx; - pctx->ino = ino; - pctx->errcode = 0; - - if (inode->i_flags & EXT2_COMPRBLK_FL) { - if (fs->super->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_COMPRESSION) - pb.compressed = 1; - else { - if (fix_problem(ctx, PR_1_COMPR_SET, pctx)) { - inode->i_flags &= ~EXT2_COMPRBLK_FL; - dirty_inode++; - } - } - } - - if (inode->i_file_acl && check_ext_attr(ctx, pctx, block_buf)) - pb.num_blocks++; - - if (ext2fs_inode_has_valid_blocks(inode)) - pctx->errcode = ext2fs_block_iterate2(fs, ino, - pb.is_dir ? BLOCK_FLAG_HOLE : 0, - block_buf, process_block, &pb); - end_problem_latch(ctx, PR_LATCH_BLOCK); - end_problem_latch(ctx, PR_LATCH_TOOBIG); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - goto out; - if (pctx->errcode) - fix_problem(ctx, PR_1_BLOCK_ITERATE, pctx); - - if (pb.fragmented && pb.num_blocks < fs->super->s_blocks_per_group) - ctx->fs_fragmented++; - - if (pb.clear) { - inode->i_links_count = 0; - ext2fs_icount_store(ctx->inode_link_info, ino, 0); - inode->i_dtime = time(NULL); - dirty_inode++; - ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); - ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino); - ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); - /* - * The inode was probably partially accounted for - * before processing was aborted, so we need to - * restart the pass 1 scan. - */ - ctx->flags |= E2F_FLAG_RESTART; - goto out; - } - - if (inode->i_flags & EXT2_INDEX_FL) { - if (handle_htree(ctx, pctx, ino, inode, block_buf)) { - inode->i_flags &= ~EXT2_INDEX_FL; - dirty_inode++; - } else { -#ifdef ENABLE_HTREE - e2fsck_add_dx_dir(ctx, ino, pb.last_block+1); -#endif - } - } - if (ctx->dirs_to_hash && pb.is_dir && - !(inode->i_flags & EXT2_INDEX_FL) && - ((inode->i_size / fs->blocksize) >= 3)) - ext2fs_u32_list_add(ctx->dirs_to_hash, ino); - - if (!pb.num_blocks && pb.is_dir) { - if (fix_problem(ctx, PR_1_ZERO_LENGTH_DIR, pctx)) { - inode->i_links_count = 0; - ext2fs_icount_store(ctx->inode_link_info, ino, 0); - inode->i_dtime = time(NULL); - dirty_inode++; - ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); - ext2fs_unmark_inode_bitmap(ctx->inode_reg_map, ino); - ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); - ctx->fs_directory_count--; - goto out; - } - } - - pb.num_blocks *= (fs->blocksize / 512); - - if (pb.is_dir) { - int nblock = inode->i_size >> EXT2_BLOCK_SIZE_BITS(fs->super); - if (nblock > (pb.last_block + 1)) - bad_size = 1; - else if (nblock < (pb.last_block + 1)) { - if (((pb.last_block + 1) - nblock) > - fs->super->s_prealloc_dir_blocks) - bad_size = 2; - } - } else { - size = EXT2_I_SIZE(inode); - if ((pb.last_block >= 0) && - (size < (__u64) pb.last_block * fs->blocksize)) - bad_size = 3; - else if (size > ext2_max_sizes[fs->super->s_log_block_size]) - bad_size = 4; - } - /* i_size for symlinks is checked elsewhere */ - if (bad_size && !LINUX_S_ISLNK(inode->i_mode)) { - pctx->num = (pb.last_block+1) * fs->blocksize; - if (fix_problem(ctx, PR_1_BAD_I_SIZE, pctx)) { - inode->i_size = pctx->num; - if (!LINUX_S_ISDIR(inode->i_mode)) - inode->i_size_high = pctx->num >> 32; - dirty_inode++; - } - pctx->num = 0; - } - if (LINUX_S_ISREG(inode->i_mode) && - (inode->i_size_high || inode->i_size & 0x80000000UL)) - ctx->large_files++; - if (pb.num_blocks != inode->i_blocks) { - pctx->num = pb.num_blocks; - if (fix_problem(ctx, PR_1_BAD_I_BLOCKS, pctx)) { - inode->i_blocks = pb.num_blocks; - dirty_inode++; - } - pctx->num = 0; - } -out: - if (dirty_inode) - e2fsck_write_inode(ctx, ino, inode, "check_blocks"); -} - - -/* - * This is a helper function for check_blocks(). - */ -static int process_block(ext2_filsys fs, - blk_t *block_nr, - e2_blkcnt_t blockcnt, - blk_t ref_block FSCK_ATTR((unused)), - int ref_offset FSCK_ATTR((unused)), - void *priv_data) -{ - struct process_block_struct_1 *p; - struct problem_context *pctx; - blk_t blk = *block_nr; - int ret_code = 0; - int problem = 0; - e2fsck_t ctx; - - p = (struct process_block_struct_1 *) priv_data; - pctx = p->pctx; - ctx = p->ctx; - - if (p->compressed && (blk == EXT2FS_COMPRESSED_BLKADDR)) { - /* todo: Check that the comprblk_fl is high, that the - blkaddr pattern looks right (all non-holes up to - first EXT2FS_COMPRESSED_BLKADDR, then all - EXT2FS_COMPRESSED_BLKADDR up to end of cluster), - that the feature_incompat bit is high, and that the - inode is a regular file. If we're doing a "full - check" (a concept introduced to e2fsck by e2compr, - meaning that we look at data blocks as well as - metadata) then call some library routine that - checks the compressed data. I'll have to think - about this, because one particularly important - problem to be able to fix is to recalculate the - cluster size if necessary. I think that perhaps - we'd better do most/all e2compr-specific checks - separately, after the non-e2compr checks. If not - doing a full check, it may be useful to test that - the personality is linux; e.g. if it isn't then - perhaps this really is just an illegal block. */ - return 0; - } - - if (blk == 0) { - if (p->is_dir == 0) { - /* - * Should never happen, since only directories - * get called with BLOCK_FLAG_HOLE - */ -#ifdef DEBUG_E2FSCK - printf("process_block() called with blk == 0, " - "blockcnt=%d, inode %lu???\n", - blockcnt, p->ino); -#endif - return 0; - } - if (blockcnt < 0) - return 0; - if (blockcnt * fs->blocksize < p->inode->i_size) { - goto mark_dir; - } - return 0; - } - - /* - * Simplistic fragmentation check. We merely require that the - * file be contiguous. (Which can never be true for really - * big files that are greater than a block group.) - */ - if (!HOLE_BLKADDR(p->previous_block)) { - if (p->previous_block+1 != blk) - p->fragmented = 1; - } - p->previous_block = blk; - - if (p->is_dir && blockcnt > (1 << (21 - fs->super->s_log_block_size))) - problem = PR_1_TOOBIG_DIR; - if (p->is_reg && p->num_blocks+1 >= p->max_blocks) - problem = PR_1_TOOBIG_REG; - if (!p->is_dir && !p->is_reg && blockcnt > 0) - problem = PR_1_TOOBIG_SYMLINK; - - if (blk < fs->super->s_first_data_block || - blk >= fs->super->s_blocks_count) - problem = PR_1_ILLEGAL_BLOCK_NUM; - - if (problem) { - p->num_illegal_blocks++; - if (!p->suppress && (p->num_illegal_blocks % 12) == 0) { - if (fix_problem(ctx, PR_1_TOO_MANY_BAD_BLOCKS, pctx)) { - p->clear = 1; - return BLOCK_ABORT; - } - if (fix_problem(ctx, PR_1_SUPPRESS_MESSAGES, pctx)) { - p->suppress = 1; - set_latch_flags(PR_LATCH_BLOCK, - PRL_SUPPRESS, 0); - } - } - pctx->blk = blk; - pctx->blkcount = blockcnt; - if (fix_problem(ctx, problem, pctx)) { - blk = *block_nr = 0; - ret_code = BLOCK_CHANGED; - goto mark_dir; - } else - return 0; - } - - if (p->ino == EXT2_RESIZE_INO) { - /* - * The resize inode has already be sanity checked - * during pass #0 (the superblock checks). All we - * have to do is mark the double indirect block as - * being in use; all of the other blocks are handled - * by mark_table_blocks()). - */ - if (blockcnt == BLOCK_COUNT_DIND) - mark_block_used(ctx, blk); - } else - mark_block_used(ctx, blk); - p->num_blocks++; - if (blockcnt >= 0) - p->last_block = blockcnt; -mark_dir: - if (p->is_dir && (blockcnt >= 0)) { - pctx->errcode = ext2fs_add_dir_block(fs->dblist, p->ino, - blk, blockcnt); - if (pctx->errcode) { - pctx->blk = blk; - pctx->num = blockcnt; - fix_problem(ctx, PR_1_ADD_DBLOCK, pctx); - /* Should never get here */ - ctx->flags |= E2F_FLAG_ABORT; - return BLOCK_ABORT; - } - } - return ret_code; -} - -static int process_bad_block(ext2_filsys fs FSCK_ATTR((unused)), - blk_t *block_nr, - e2_blkcnt_t blockcnt, - blk_t ref_block FSCK_ATTR((unused)), - int ref_offset FSCK_ATTR((unused)), - void *priv_data EXT2FS_ATTR((unused))) -{ - /* - * Note: This function processes blocks for the bad blocks - * inode, which is never compressed. So we don't use HOLE_BLKADDR(). - */ - - printf("Unrecoverable Error: Found %"PRIi64" bad blocks starting at block number: %u\n", blockcnt, *block_nr); - return BLOCK_ERROR; -} - -/* - * This routine gets called at the end of pass 1 if bad blocks are - * detected in the superblock, group descriptors, inode_bitmaps, or - * block bitmaps. At this point, all of the blocks have been mapped - * out, so we can try to allocate new block(s) to replace the bad - * blocks. - */ -static void handle_fs_bad_blocks(e2fsck_t ctx) -{ - printf("Bad blocks detected on your filesystem\n" - "You should get your data off as the device will soon die\n"); -} - -/* - * This routine marks all blocks which are used by the superblock, - * group descriptors, inode bitmaps, and block bitmaps. - */ -static void mark_table_blocks(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - blk_t block, b; - dgrp_t i; - int j; - struct problem_context pctx; - - clear_problem_context(&pctx); - - block = fs->super->s_first_data_block; - for (i = 0; i < fs->group_desc_count; i++) { - pctx.group = i; - - ext2fs_reserve_super_and_bgd(fs, i, ctx->block_found_map); - - /* - * Mark the blocks used for the inode table - */ - if (fs->group_desc[i].bg_inode_table) { - for (j = 0, b = fs->group_desc[i].bg_inode_table; - j < fs->inode_blocks_per_group; - j++, b++) { - if (ext2fs_test_block_bitmap(ctx->block_found_map, - b)) { - pctx.blk = b; - if (fix_problem(ctx, - PR_1_ITABLE_CONFLICT, &pctx)) { - ctx->invalid_inode_table_flag[i]++; - ctx->invalid_bitmaps++; - } - } else { - ext2fs_mark_block_bitmap(ctx->block_found_map, b); - } - } - } - - /* - * Mark block used for the block bitmap - */ - if (fs->group_desc[i].bg_block_bitmap) { - if (ext2fs_test_block_bitmap(ctx->block_found_map, - fs->group_desc[i].bg_block_bitmap)) { - pctx.blk = fs->group_desc[i].bg_block_bitmap; - if (fix_problem(ctx, PR_1_BB_CONFLICT, &pctx)) { - ctx->invalid_block_bitmap_flag[i]++; - ctx->invalid_bitmaps++; - } - } else { - ext2fs_mark_block_bitmap(ctx->block_found_map, - fs->group_desc[i].bg_block_bitmap); - } - } - /* - * Mark block used for the inode bitmap - */ - if (fs->group_desc[i].bg_inode_bitmap) { - if (ext2fs_test_block_bitmap(ctx->block_found_map, - fs->group_desc[i].bg_inode_bitmap)) { - pctx.blk = fs->group_desc[i].bg_inode_bitmap; - if (fix_problem(ctx, PR_1_IB_CONFLICT, &pctx)) { - ctx->invalid_inode_bitmap_flag[i]++; - ctx->invalid_bitmaps++; - } - } else { - ext2fs_mark_block_bitmap(ctx->block_found_map, - fs->group_desc[i].bg_inode_bitmap); - } - } - block += fs->super->s_blocks_per_group; - } -} - -/* - * Thes subroutines short circuits ext2fs_get_blocks and - * ext2fs_check_directory; we use them since we already have the inode - * structure, so there's no point in letting the ext2fs library read - * the inode again. - */ -static errcode_t pass1_get_blocks(ext2_filsys fs, ext2_ino_t ino, - blk_t *blocks) -{ - e2fsck_t ctx = (e2fsck_t) fs->priv_data; - int i; - - if ((ino != ctx->stashed_ino) || !ctx->stashed_inode) - return EXT2_ET_CALLBACK_NOTHANDLED; - - for (i=0; i < EXT2_N_BLOCKS; i++) - blocks[i] = ctx->stashed_inode->i_block[i]; - return 0; -} - -static errcode_t pass1_read_inode(ext2_filsys fs, ext2_ino_t ino, - struct ext2_inode *inode) -{ - e2fsck_t ctx = (e2fsck_t) fs->priv_data; - - if ((ino != ctx->stashed_ino) || !ctx->stashed_inode) - return EXT2_ET_CALLBACK_NOTHANDLED; - *inode = *ctx->stashed_inode; - return 0; -} - -static errcode_t pass1_write_inode(ext2_filsys fs, ext2_ino_t ino, - struct ext2_inode *inode) -{ - e2fsck_t ctx = (e2fsck_t) fs->priv_data; - - if ((ino == ctx->stashed_ino) && ctx->stashed_inode) - *ctx->stashed_inode = *inode; - return EXT2_ET_CALLBACK_NOTHANDLED; -} - -static errcode_t pass1_check_directory(ext2_filsys fs, ext2_ino_t ino) -{ - e2fsck_t ctx = (e2fsck_t) fs->priv_data; - - if ((ino != ctx->stashed_ino) || !ctx->stashed_inode) - return EXT2_ET_CALLBACK_NOTHANDLED; - - if (!LINUX_S_ISDIR(ctx->stashed_inode->i_mode)) - return EXT2_ET_NO_DIRECTORY; - return 0; -} - -void e2fsck_use_inode_shortcuts(e2fsck_t ctx, int bool) -{ - ext2_filsys fs = ctx->fs; - - if (bool) { - fs->get_blocks = pass1_get_blocks; - fs->check_directory = pass1_check_directory; - fs->read_inode = pass1_read_inode; - fs->write_inode = pass1_write_inode; - ctx->stashed_ino = 0; - } else { - fs->get_blocks = 0; - fs->check_directory = 0; - fs->read_inode = 0; - fs->write_inode = 0; - } -} - -/* - * pass1b.c --- Pass #1b of e2fsck - * - * This file contains pass1B, pass1C, and pass1D of e2fsck. They are - * only invoked if pass 1 discovered blocks which are in use by more - * than one inode. - * - * Pass1B scans the data blocks of all the inodes again, generating a - * complete list of duplicate blocks and which inodes have claimed - * them. - * - * Pass1C does a tree-traversal of the filesystem, to determine the - * parent directories of these inodes. This step is necessary so that - * e2fsck can print out the pathnames of affected inodes. - * - * Pass1D is a reconciliation pass. For each inode with duplicate - * blocks, the user is prompted if s/he would like to clone the file - * (so that the file gets a fresh copy of the duplicated blocks) or - * simply to delete the file. - * - */ - - -/* Needed for architectures where sizeof(int) != sizeof(void *) */ -#define INT_TO_VOIDPTR(val) ((void *)(intptr_t)(val)) -#define VOIDPTR_TO_INT(ptr) ((int)(intptr_t)(ptr)) - -/* Define an extension to the ext2 library's block count information */ -#define BLOCK_COUNT_EXTATTR (-5) - -struct block_el { - blk_t block; - struct block_el *next; -}; - -struct inode_el { - ext2_ino_t inode; - struct inode_el *next; -}; - -struct dup_block { - int num_bad; - struct inode_el *inode_list; -}; - -/* - * This structure stores information about a particular inode which - * is sharing blocks with other inodes. This information is collected - * to display to the user, so that the user knows what files he or she - * is dealing with, when trying to decide how to resolve the conflict - * of multiply-claimed blocks. - */ -struct dup_inode { - ext2_ino_t dir; - int num_dupblocks; - struct ext2_inode inode; - struct block_el *block_list; -}; - -static int process_pass1b_block(ext2_filsys fs, blk_t *blocknr, - e2_blkcnt_t blockcnt, blk_t ref_blk, - int ref_offset, void *priv_data); -static void delete_file(e2fsck_t ctx, ext2_ino_t ino, - struct dup_inode *dp, char *block_buf); -static int clone_file(e2fsck_t ctx, ext2_ino_t ino, - struct dup_inode *dp, char* block_buf); -static int check_if_fs_block(e2fsck_t ctx, blk_t test_blk); - -static void pass1b(e2fsck_t ctx, char *block_buf); -static void pass1c(e2fsck_t ctx, char *block_buf); -static void pass1d(e2fsck_t ctx, char *block_buf); - -static int dup_inode_count = 0; - -static dict_t blk_dict, ino_dict; - -static ext2fs_inode_bitmap inode_dup_map; - -static int dict_int_cmp(const void *a, const void *b) -{ - intptr_t ia, ib; - - ia = (intptr_t)a; - ib = (intptr_t)b; - - return (ia-ib); -} - -/* - * Add a duplicate block record - */ -static void add_dupe(e2fsck_t ctx, ext2_ino_t ino, blk_t blk, - struct ext2_inode *inode) -{ - dnode_t *n; - struct dup_block *db; - struct dup_inode *di; - struct block_el *blk_el; - struct inode_el *ino_el; - - n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk)); - if (n) - db = (struct dup_block *) dnode_get(n); - else { - db = (struct dup_block *) e2fsck_allocate_memory(ctx, - sizeof(struct dup_block), "duplicate block header"); - db->num_bad = 0; - db->inode_list = 0; - dict_alloc_insert(&blk_dict, INT_TO_VOIDPTR(blk), db); - } - ino_el = (struct inode_el *) e2fsck_allocate_memory(ctx, - sizeof(struct inode_el), "inode element"); - ino_el->inode = ino; - ino_el->next = db->inode_list; - db->inode_list = ino_el; - db->num_bad++; - - n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino)); - if (n) - di = (struct dup_inode *) dnode_get(n); - else { - di = (struct dup_inode *) e2fsck_allocate_memory(ctx, - sizeof(struct dup_inode), "duplicate inode header"); - di->dir = (ino == EXT2_ROOT_INO) ? EXT2_ROOT_INO : 0; - di->num_dupblocks = 0; - di->block_list = 0; - di->inode = *inode; - dict_alloc_insert(&ino_dict, INT_TO_VOIDPTR(ino), di); - } - blk_el = (struct block_el *) e2fsck_allocate_memory(ctx, - sizeof(struct block_el), "block element"); - blk_el->block = blk; - blk_el->next = di->block_list; - di->block_list = blk_el; - di->num_dupblocks++; -} - -/* - * Free a duplicate inode record - */ -static void inode_dnode_free(dnode_t *node) -{ - struct dup_inode *di; - struct block_el *p, *next; - - di = (struct dup_inode *) dnode_get(node); - for (p = di->block_list; p; p = next) { - next = p->next; - free(p); - } - free(node); -} - -/* - * Free a duplicate block record - */ -static void block_dnode_free(dnode_t *node) -{ - struct dup_block *db; - struct inode_el *p, *next; - - db = (struct dup_block *) dnode_get(node); - for (p = db->inode_list; p; p = next) { - next = p->next; - free(p); - } - free(node); -} - - -/* - * Main procedure for handling duplicate blocks - */ -void e2fsck_pass1_dupblocks(e2fsck_t ctx, char *block_buf) -{ - ext2_filsys fs = ctx->fs; - struct problem_context pctx; - - clear_problem_context(&pctx); - - pctx.errcode = ext2fs_allocate_inode_bitmap(fs, - _("multiply claimed inode map"), &inode_dup_map); - if (pctx.errcode) { - fix_problem(ctx, PR_1B_ALLOCATE_IBITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - - dict_init(&ino_dict, DICTCOUNT_T_MAX, dict_int_cmp); - dict_init(&blk_dict, DICTCOUNT_T_MAX, dict_int_cmp); - dict_set_allocator(&ino_dict, inode_dnode_free); - dict_set_allocator(&blk_dict, block_dnode_free); - - pass1b(ctx, block_buf); - pass1c(ctx, block_buf); - pass1d(ctx, block_buf); - - /* - * Time to free all of the accumulated data structures that we - * don't need anymore. - */ - dict_free_nodes(&ino_dict); - dict_free_nodes(&blk_dict); -} - -/* - * Scan the inodes looking for inodes that contain duplicate blocks. - */ -struct process_block_struct_1b { - e2fsck_t ctx; - ext2_ino_t ino; - int dup_blocks; - struct ext2_inode *inode; - struct problem_context *pctx; -}; - -static void pass1b(e2fsck_t ctx, char *block_buf) -{ - ext2_filsys fs = ctx->fs; - ext2_ino_t ino; - struct ext2_inode inode; - ext2_inode_scan scan; - struct process_block_struct_1b pb; - struct problem_context pctx; - - clear_problem_context(&pctx); - - if (!(ctx->options & E2F_OPT_PREEN)) - fix_problem(ctx, PR_1B_PASS_HEADER, &pctx); - pctx.errcode = ext2fs_open_inode_scan(fs, ctx->inode_buffer_blocks, - &scan); - if (pctx.errcode) { - fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - ctx->stashed_inode = &inode; - pb.ctx = ctx; - pb.pctx = &pctx; - pctx.str = "pass1b"; - while (1) { - pctx.errcode = ext2fs_get_next_inode(scan, &ino, &inode); - if (pctx.errcode == EXT2_ET_BAD_BLOCK_IN_INODE_TABLE) - continue; - if (pctx.errcode) { - fix_problem(ctx, PR_1B_ISCAN_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - if (!ino) - break; - pctx.ino = ctx->stashed_ino = ino; - if ((ino != EXT2_BAD_INO) && - !ext2fs_test_inode_bitmap(ctx->inode_used_map, ino)) - continue; - - pb.ino = ino; - pb.dup_blocks = 0; - pb.inode = &inode; - - if (ext2fs_inode_has_valid_blocks(&inode) || - (ino == EXT2_BAD_INO)) - pctx.errcode = ext2fs_block_iterate2(fs, ino, - 0, block_buf, process_pass1b_block, &pb); - if (inode.i_file_acl) - process_pass1b_block(fs, &inode.i_file_acl, - BLOCK_COUNT_EXTATTR, 0, 0, &pb); - if (pb.dup_blocks) { - end_problem_latch(ctx, PR_LATCH_DBLOCK); - if (ino >= EXT2_FIRST_INODE(fs->super) || - ino == EXT2_ROOT_INO) - dup_inode_count++; - } - if (pctx.errcode) - fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); - } - ext2fs_close_inode_scan(scan); - e2fsck_use_inode_shortcuts(ctx, 0); -} - -static int process_pass1b_block(ext2_filsys fs FSCK_ATTR((unused)), - blk_t *block_nr, - e2_blkcnt_t blockcnt FSCK_ATTR((unused)), - blk_t ref_blk FSCK_ATTR((unused)), - int ref_offset FSCK_ATTR((unused)), - void *priv_data) -{ - struct process_block_struct_1b *p; - e2fsck_t ctx; - - if (HOLE_BLKADDR(*block_nr)) - return 0; - p = (struct process_block_struct_1b *) priv_data; - ctx = p->ctx; - - if (!ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) - return 0; - - /* OK, this is a duplicate block */ - if (p->ino != EXT2_BAD_INO) { - p->pctx->blk = *block_nr; - fix_problem(ctx, PR_1B_DUP_BLOCK, p->pctx); - } - p->dup_blocks++; - ext2fs_mark_inode_bitmap(inode_dup_map, p->ino); - - add_dupe(ctx, p->ino, *block_nr, p->inode); - - return 0; -} - -/* - * Pass 1c: Scan directories for inodes with duplicate blocks. This - * is used so that we can print pathnames when prompting the user for - * what to do. - */ -struct search_dir_struct { - int count; - ext2_ino_t first_inode; - ext2_ino_t max_inode; -}; - -static int search_dirent_proc(ext2_ino_t dir, int entry, - struct ext2_dir_entry *dirent, - int offset FSCK_ATTR((unused)), - int blocksize FSCK_ATTR((unused)), - char *buf FSCK_ATTR((unused)), - void *priv_data) -{ - struct search_dir_struct *sd; - struct dup_inode *p; - dnode_t *n; - - sd = (struct search_dir_struct *) priv_data; - - if (dirent->inode > sd->max_inode) - /* Should abort this inode, but not everything */ - return 0; - - if ((dirent->inode < sd->first_inode) || (entry < DIRENT_OTHER_FILE) || - !ext2fs_test_inode_bitmap(inode_dup_map, dirent->inode)) - return 0; - - n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(dirent->inode)); - if (!n) - return 0; - p = (struct dup_inode *) dnode_get(n); - p->dir = dir; - sd->count--; - - return sd->count ? 0 : DIRENT_ABORT; -} - - -static void pass1c(e2fsck_t ctx, char *block_buf) -{ - ext2_filsys fs = ctx->fs; - struct search_dir_struct sd; - struct problem_context pctx; - - clear_problem_context(&pctx); - - if (!(ctx->options & E2F_OPT_PREEN)) - fix_problem(ctx, PR_1C_PASS_HEADER, &pctx); - - /* - * Search through all directories to translate inodes to names - * (by searching for the containing directory for that inode.) - */ - sd.count = dup_inode_count; - sd.first_inode = EXT2_FIRST_INODE(fs->super); - sd.max_inode = fs->super->s_inodes_count; - ext2fs_dblist_dir_iterate(fs->dblist, 0, block_buf, - search_dirent_proc, &sd); -} - -static void pass1d(e2fsck_t ctx, char *block_buf) -{ - ext2_filsys fs = ctx->fs; - struct dup_inode *p, *t; - struct dup_block *q; - ext2_ino_t *shared, ino; - int shared_len; - int i; - int file_ok; - int meta_data = 0; - struct problem_context pctx; - dnode_t *n, *m; - struct block_el *s; - struct inode_el *r; - - clear_problem_context(&pctx); - - if (!(ctx->options & E2F_OPT_PREEN)) - fix_problem(ctx, PR_1D_PASS_HEADER, &pctx); - e2fsck_read_bitmaps(ctx); - - pctx.num = dup_inode_count; /* dict_count(&ino_dict); */ - fix_problem(ctx, PR_1D_NUM_DUP_INODES, &pctx); - shared = (ext2_ino_t *) e2fsck_allocate_memory(ctx, - sizeof(ext2_ino_t) * dict_count(&ino_dict), - "Shared inode list"); - for (n = dict_first(&ino_dict); n; n = dict_next(&ino_dict, n)) { - p = (struct dup_inode *) dnode_get(n); - shared_len = 0; - file_ok = 1; - ino = (ext2_ino_t)VOIDPTR_TO_INT(dnode_getkey(n)); - if (ino == EXT2_BAD_INO || ino == EXT2_RESIZE_INO) - continue; - - /* - * Find all of the inodes which share blocks with this - * one. First we find all of the duplicate blocks - * belonging to this inode, and then search each block - * get the list of inodes, and merge them together. - */ - for (s = p->block_list; s; s = s->next) { - m = dict_lookup(&blk_dict, INT_TO_VOIDPTR(s->block)); - if (!m) - continue; /* Should never happen... */ - q = (struct dup_block *) dnode_get(m); - if (q->num_bad > 1) - file_ok = 0; - if (check_if_fs_block(ctx, s->block)) { - file_ok = 0; - meta_data = 1; - } - - /* - * Add all inodes used by this block to the - * shared[] --- which is a unique list, so - * if an inode is already in shared[], don't - * add it again. - */ - for (r = q->inode_list; r; r = r->next) { - if (r->inode == ino) - continue; - for (i = 0; i < shared_len; i++) - if (shared[i] == r->inode) - break; - if (i == shared_len) { - shared[shared_len++] = r->inode; - } - } - } - - /* - * Report the inode that we are working on - */ - pctx.inode = &p->inode; - pctx.ino = ino; - pctx.dir = p->dir; - pctx.blkcount = p->num_dupblocks; - pctx.num = meta_data ? shared_len+1 : shared_len; - fix_problem(ctx, PR_1D_DUP_FILE, &pctx); - pctx.blkcount = 0; - pctx.num = 0; - - if (meta_data) - fix_problem(ctx, PR_1D_SHARE_METADATA, &pctx); - - for (i = 0; i < shared_len; i++) { - m = dict_lookup(&ino_dict, INT_TO_VOIDPTR(shared[i])); - if (!m) - continue; /* should never happen */ - t = (struct dup_inode *) dnode_get(m); - /* - * Report the inode that we are sharing with - */ - pctx.inode = &t->inode; - pctx.ino = shared[i]; - pctx.dir = t->dir; - fix_problem(ctx, PR_1D_DUP_FILE_LIST, &pctx); - } - if (file_ok) { - fix_problem(ctx, PR_1D_DUP_BLOCKS_DEALT, &pctx); - continue; - } - if (fix_problem(ctx, PR_1D_CLONE_QUESTION, &pctx)) { - pctx.errcode = clone_file(ctx, ino, p, block_buf); - if (pctx.errcode) - fix_problem(ctx, PR_1D_CLONE_ERROR, &pctx); - else - continue; - } - if (fix_problem(ctx, PR_1D_DELETE_QUESTION, &pctx)) - delete_file(ctx, ino, p, block_buf); - else - ext2fs_unmark_valid(fs); - } - ext2fs_free_mem(&shared); -} - -/* - * Drop the refcount on the dup_block structure, and clear the entry - * in the block_dup_map if appropriate. - */ -static void decrement_badcount(e2fsck_t ctx, blk_t block, struct dup_block *p) -{ - p->num_bad--; - if (p->num_bad <= 0 || - (p->num_bad == 1 && !check_if_fs_block(ctx, block))) - ext2fs_unmark_block_bitmap(ctx->block_dup_map, block); -} - -static int delete_file_block(ext2_filsys fs, - blk_t *block_nr, - e2_blkcnt_t blockcnt FSCK_ATTR((unused)), - blk_t ref_block FSCK_ATTR((unused)), - int ref_offset FSCK_ATTR((unused)), - void *priv_data) -{ - struct process_block_struct_1b *pb; - struct dup_block *p; - dnode_t *n; - e2fsck_t ctx; - - pb = (struct process_block_struct_1b *) priv_data; - ctx = pb->ctx; - - if (HOLE_BLKADDR(*block_nr)) - return 0; - - if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) { - n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr)); - if (n) { - p = (struct dup_block *) dnode_get(n); - decrement_badcount(ctx, *block_nr, p); - } else - bb_error_msg(_("internal error; can't find dup_blk for %d"), - *block_nr); - } else { - ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr); - ext2fs_block_alloc_stats(fs, *block_nr, -1); - } - - return 0; -} - -static void delete_file(e2fsck_t ctx, ext2_ino_t ino, - struct dup_inode *dp, char* block_buf) -{ - ext2_filsys fs = ctx->fs; - struct process_block_struct_1b pb; - struct ext2_inode inode; - struct problem_context pctx; - unsigned int count; - - clear_problem_context(&pctx); - pctx.ino = pb.ino = ino; - pb.dup_blocks = dp->num_dupblocks; - pb.ctx = ctx; - pctx.str = "delete_file"; - - e2fsck_read_inode(ctx, ino, &inode, "delete_file"); - if (ext2fs_inode_has_valid_blocks(&inode)) - pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, - delete_file_block, &pb); - if (pctx.errcode) - fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); - ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); - ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); - if (ctx->inode_bad_map) - ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); - ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode)); - - /* Inode may have changed by block_iterate, so reread it */ - e2fsck_read_inode(ctx, ino, &inode, "delete_file"); - inode.i_links_count = 0; - inode.i_dtime = time(NULL); - if (inode.i_file_acl && - (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) { - count = 1; - pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl, - block_buf, -1, &count); - if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) { - pctx.errcode = 0; - count = 1; - } - if (pctx.errcode) { - pctx.blk = inode.i_file_acl; - fix_problem(ctx, PR_1B_ADJ_EA_REFCOUNT, &pctx); - } - /* - * If the count is zero, then arrange to have the - * block deleted. If the block is in the block_dup_map, - * also call delete_file_block since it will take care - * of keeping the accounting straight. - */ - if ((count == 0) || - ext2fs_test_block_bitmap(ctx->block_dup_map, - inode.i_file_acl)) - delete_file_block(fs, &inode.i_file_acl, - BLOCK_COUNT_EXTATTR, 0, 0, &pb); - } - e2fsck_write_inode(ctx, ino, &inode, "delete_file"); -} - -struct clone_struct { - errcode_t errcode; - ext2_ino_t dir; - char *buf; - e2fsck_t ctx; -}; - -static int clone_file_block(ext2_filsys fs, - blk_t *block_nr, - e2_blkcnt_t blockcnt, - blk_t ref_block FSCK_ATTR((unused)), - int ref_offset FSCK_ATTR((unused)), - void *priv_data) -{ - struct dup_block *p; - blk_t new_block; - errcode_t retval; - struct clone_struct *cs = (struct clone_struct *) priv_data; - dnode_t *n; - e2fsck_t ctx; - - ctx = cs->ctx; - - if (HOLE_BLKADDR(*block_nr)) - return 0; - - if (ext2fs_test_block_bitmap(ctx->block_dup_map, *block_nr)) { - n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(*block_nr)); - if (n) { - p = (struct dup_block *) dnode_get(n); - retval = ext2fs_new_block(fs, 0, ctx->block_found_map, - &new_block); - if (retval) { - cs->errcode = retval; - return BLOCK_ABORT; - } - if (cs->dir && (blockcnt >= 0)) { - retval = ext2fs_set_dir_block(fs->dblist, - cs->dir, new_block, blockcnt); - if (retval) { - cs->errcode = retval; - return BLOCK_ABORT; - } - } - - retval = io_channel_read_blk(fs->io, *block_nr, 1, - cs->buf); - if (retval) { - cs->errcode = retval; - return BLOCK_ABORT; - } - retval = io_channel_write_blk(fs->io, new_block, 1, - cs->buf); - if (retval) { - cs->errcode = retval; - return BLOCK_ABORT; - } - decrement_badcount(ctx, *block_nr, p); - *block_nr = new_block; - ext2fs_mark_block_bitmap(ctx->block_found_map, - new_block); - ext2fs_mark_block_bitmap(fs->block_map, new_block); - return BLOCK_CHANGED; - } else - bb_error_msg(_("internal error; can't find dup_blk for %d"), - *block_nr); - } - return 0; -} - -static int clone_file(e2fsck_t ctx, ext2_ino_t ino, - struct dup_inode *dp, char* block_buf) -{ - ext2_filsys fs = ctx->fs; - errcode_t retval; - struct clone_struct cs; - struct problem_context pctx; - blk_t blk; - dnode_t *n; - struct inode_el *ino_el; - struct dup_block *db; - struct dup_inode *di; - - clear_problem_context(&pctx); - cs.errcode = 0; - cs.dir = 0; - cs.ctx = ctx; - retval = ext2fs_get_mem(fs->blocksize, &cs.buf); - if (retval) - return retval; - - if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) - cs.dir = ino; - - pctx.ino = ino; - pctx.str = "clone_file"; - if (ext2fs_inode_has_valid_blocks(&dp->inode)) - pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, - clone_file_block, &cs); - ext2fs_mark_bb_dirty(fs); - if (pctx.errcode) { - fix_problem(ctx, PR_1B_BLOCK_ITERATE, &pctx); - retval = pctx.errcode; - goto errout; - } - if (cs.errcode) { - bb_error_msg(_("returned from clone_file_block")); - retval = cs.errcode; - goto errout; - } - /* The inode may have changed on disk, so we have to re-read it */ - e2fsck_read_inode(ctx, ino, &dp->inode, "clone file EA"); - blk = dp->inode.i_file_acl; - if (blk && (clone_file_block(fs, &dp->inode.i_file_acl, - BLOCK_COUNT_EXTATTR, 0, 0, &cs) == - BLOCK_CHANGED)) { - e2fsck_write_inode(ctx, ino, &dp->inode, "clone file EA"); - /* - * If we cloned the EA block, find all other inodes - * which refered to that EA block, and modify - * them to point to the new EA block. - */ - n = dict_lookup(&blk_dict, INT_TO_VOIDPTR(blk)); - db = (struct dup_block *) dnode_get(n); - for (ino_el = db->inode_list; ino_el; ino_el = ino_el->next) { - if (ino_el->inode == ino) - continue; - n = dict_lookup(&ino_dict, INT_TO_VOIDPTR(ino_el->inode)); - di = (struct dup_inode *) dnode_get(n); - if (di->inode.i_file_acl == blk) { - di->inode.i_file_acl = dp->inode.i_file_acl; - e2fsck_write_inode(ctx, ino_el->inode, - &di->inode, "clone file EA"); - decrement_badcount(ctx, blk, db); - } - } - } - retval = 0; -errout: - ext2fs_free_mem(&cs.buf); - return retval; -} - -/* - * This routine returns 1 if a block overlaps with one of the superblocks, - * group descriptors, inode bitmaps, or block bitmaps. - */ -static int check_if_fs_block(e2fsck_t ctx, blk_t test_block) -{ - ext2_filsys fs = ctx->fs; - blk_t block; - dgrp_t i; - - block = fs->super->s_first_data_block; - for (i = 0; i < fs->group_desc_count; i++) { - - /* Check superblocks/block group descriptros */ - if (ext2fs_bg_has_super(fs, i)) { - if (test_block >= block && - (test_block <= block + fs->desc_blocks)) - return 1; - } - - /* Check the inode table */ - if ((fs->group_desc[i].bg_inode_table) && - (test_block >= fs->group_desc[i].bg_inode_table) && - (test_block < (fs->group_desc[i].bg_inode_table + - fs->inode_blocks_per_group))) - return 1; - - /* Check the bitmap blocks */ - if ((test_block == fs->group_desc[i].bg_block_bitmap) || - (test_block == fs->group_desc[i].bg_inode_bitmap)) - return 1; - - block += fs->super->s_blocks_per_group; - } - return 0; -} -/* - * pass2.c --- check directory structure - * - * Pass 2 of e2fsck iterates through all active directory inodes, and - * applies to following tests to each directory entry in the directory - * blocks in the inodes: - * - * - The length of the directory entry (rec_len) should be at - * least 8 bytes, and no more than the remaining space - * left in the directory block. - * - The length of the name in the directory entry (name_len) - * should be less than (rec_len - 8). - * - The inode number in the directory entry should be within - * legal bounds. - * - The inode number should refer to a in-use inode. - * - The first entry should be '.', and its inode should be - * the inode of the directory. - * - The second entry should be '..'. - * - * To minimize disk seek time, the directory blocks are processed in - * sorted order of block numbers. - * - * Pass 2 also collects the following information: - * - The inode numbers of the subdirectories for each directory. - * - * Pass 2 relies on the following information from previous passes: - * - The directory information collected in pass 1. - * - The inode_used_map bitmap - * - The inode_bad_map bitmap - * - The inode_dir_map bitmap - * - * Pass 2 frees the following data structures - * - The inode_bad_map bitmap - * - The inode_reg_map bitmap - */ - -/* - * Keeps track of how many times an inode is referenced. - */ -static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf); -static int check_dir_block(ext2_filsys fs, - struct ext2_db_entry *dir_blocks_info, - void *priv_data); -static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *dir_blocks_info, - struct problem_context *pctx); -static int update_dir_block(ext2_filsys fs, - blk_t *block_nr, - e2_blkcnt_t blockcnt, - blk_t ref_block, - int ref_offset, - void *priv_data); -static void clear_htree(e2fsck_t ctx, ext2_ino_t ino); -static int htree_depth(struct dx_dir_info *dx_dir, - struct dx_dirblock_info *dx_db); -static int special_dir_block_cmp(const void *a, const void *b); - -struct check_dir_struct { - char *buf; - struct problem_context pctx; - int count, max; - e2fsck_t ctx; -}; - -static void e2fsck_pass2(e2fsck_t ctx) -{ - struct ext2_super_block *sb = ctx->fs->super; - struct problem_context pctx; - ext2_filsys fs = ctx->fs; - char *buf; - struct dir_info *dir; - struct check_dir_struct cd; - struct dx_dir_info *dx_dir; - struct dx_dirblock_info *dx_db, *dx_parent; - int b; - int i, depth; - problem_t code; - int bad_dir; - - clear_problem_context(&cd.pctx); - - /* Pass 2 */ - - if (!(ctx->options & E2F_OPT_PREEN)) - fix_problem(ctx, PR_2_PASS_HEADER, &cd.pctx); - - cd.pctx.errcode = ext2fs_create_icount2(fs, EXT2_ICOUNT_OPT_INCREMENT, - 0, ctx->inode_link_info, - &ctx->inode_count); - if (cd.pctx.errcode) { - fix_problem(ctx, PR_2_ALLOCATE_ICOUNT, &cd.pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - buf = (char *) e2fsck_allocate_memory(ctx, 2*fs->blocksize, - "directory scan buffer"); - - /* - * Set up the parent pointer for the root directory, if - * present. (If the root directory is not present, we will - * create it in pass 3.) - */ - dir = e2fsck_get_dir_info(ctx, EXT2_ROOT_INO); - if (dir) - dir->parent = EXT2_ROOT_INO; - - cd.buf = buf; - cd.ctx = ctx; - cd.count = 1; - cd.max = ext2fs_dblist_count(fs->dblist); - - if (ctx->progress) - (void) (ctx->progress)(ctx, 2, 0, cd.max); - - if (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) - ext2fs_dblist_sort(fs->dblist, special_dir_block_cmp); - - cd.pctx.errcode = ext2fs_dblist_iterate(fs->dblist, check_dir_block, - &cd); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - if (cd.pctx.errcode) { - fix_problem(ctx, PR_2_DBLIST_ITERATE, &cd.pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - -#ifdef ENABLE_HTREE - for (i=0; (dx_dir = e2fsck_dx_dir_info_iter(ctx, &i)) != 0;) { - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - if (dx_dir->numblocks == 0) - continue; - clear_problem_context(&pctx); - bad_dir = 0; - pctx.dir = dx_dir->ino; - dx_db = dx_dir->dx_block; - if (dx_db->flags & DX_FLAG_REFERENCED) - dx_db->flags |= DX_FLAG_DUP_REF; - else - dx_db->flags |= DX_FLAG_REFERENCED; - /* - * Find all of the first and last leaf blocks, and - * update their parent's min and max hash values - */ - for (b=0, dx_db = dx_dir->dx_block; - b < dx_dir->numblocks; - b++, dx_db++) { - if ((dx_db->type != DX_DIRBLOCK_LEAF) || - !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST))) - continue; - dx_parent = &dx_dir->dx_block[dx_db->parent]; - /* - * XXX Make sure dx_parent->min_hash > dx_db->min_hash - */ - if (dx_db->flags & DX_FLAG_FIRST) - dx_parent->min_hash = dx_db->min_hash; - /* - * XXX Make sure dx_parent->max_hash < dx_db->max_hash - */ - if (dx_db->flags & DX_FLAG_LAST) - dx_parent->max_hash = dx_db->max_hash; - } - - for (b=0, dx_db = dx_dir->dx_block; - b < dx_dir->numblocks; - b++, dx_db++) { - pctx.blkcount = b; - pctx.group = dx_db->parent; - code = 0; - if (!(dx_db->flags & DX_FLAG_FIRST) && - (dx_db->min_hash < dx_db->node_min_hash)) { - pctx.blk = dx_db->min_hash; - pctx.blk2 = dx_db->node_min_hash; - code = PR_2_HTREE_MIN_HASH; - fix_problem(ctx, code, &pctx); - bad_dir++; - } - if (dx_db->type == DX_DIRBLOCK_LEAF) { - depth = htree_depth(dx_dir, dx_db); - if (depth != dx_dir->depth) { - code = PR_2_HTREE_BAD_DEPTH; - fix_problem(ctx, code, &pctx); - bad_dir++; - } - } - /* - * This test doesn't apply for the root block - * at block #0 - */ - if (b && - (dx_db->max_hash > dx_db->node_max_hash)) { - pctx.blk = dx_db->max_hash; - pctx.blk2 = dx_db->node_max_hash; - code = PR_2_HTREE_MAX_HASH; - fix_problem(ctx, code, &pctx); - bad_dir++; - } - if (!(dx_db->flags & DX_FLAG_REFERENCED)) { - code = PR_2_HTREE_NOTREF; - fix_problem(ctx, code, &pctx); - bad_dir++; - } else if (dx_db->flags & DX_FLAG_DUP_REF) { - code = PR_2_HTREE_DUPREF; - fix_problem(ctx, code, &pctx); - bad_dir++; - } - if (code == 0) - continue; - } - if (bad_dir && fix_problem(ctx, PR_2_HTREE_CLEAR, &pctx)) { - clear_htree(ctx, dx_dir->ino); - dx_dir->numblocks = 0; - } - } -#endif - ext2fs_free_mem(&buf); - ext2fs_free_dblist(fs->dblist); - - ext2fs_free_inode_bitmap(ctx->inode_bad_map); - ctx->inode_bad_map = 0; - ext2fs_free_inode_bitmap(ctx->inode_reg_map); - ctx->inode_reg_map = 0; - - clear_problem_context(&pctx); - if (ctx->large_files) { - if (!(sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_LARGE_FILE) && - fix_problem(ctx, PR_2_FEATURE_LARGE_FILES, &pctx)) { - sb->s_feature_ro_compat |= - EXT2_FEATURE_RO_COMPAT_LARGE_FILE; - ext2fs_mark_super_dirty(fs); - } - if (sb->s_rev_level == EXT2_GOOD_OLD_REV && - fix_problem(ctx, PR_1_FS_REV_LEVEL, &pctx)) { - ext2fs_update_dynamic_rev(fs); - ext2fs_mark_super_dirty(fs); - } - } else if (!ctx->large_files && - (sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_LARGE_FILE)) { - if (fs->flags & EXT2_FLAG_RW) { - sb->s_feature_ro_compat &= - ~EXT2_FEATURE_RO_COMPAT_LARGE_FILE; - ext2fs_mark_super_dirty(fs); - } - } -} - -#define MAX_DEPTH 32000 -static int htree_depth(struct dx_dir_info *dx_dir, - struct dx_dirblock_info *dx_db) -{ - int depth = 0; - - while (dx_db->type != DX_DIRBLOCK_ROOT && depth < MAX_DEPTH) { - dx_db = &dx_dir->dx_block[dx_db->parent]; - depth++; - } - return depth; -} - -static int dict_de_cmp(const void *a, const void *b) -{ - const struct ext2_dir_entry *de_a, *de_b; - int a_len, b_len; - - de_a = (const struct ext2_dir_entry *) a; - a_len = de_a->name_len & 0xFF; - de_b = (const struct ext2_dir_entry *) b; - b_len = de_b->name_len & 0xFF; - - if (a_len != b_len) - return (a_len - b_len); - - return strncmp(de_a->name, de_b->name, a_len); -} - -/* - * This is special sort function that makes sure that directory blocks - * with a dirblock of zero are sorted to the beginning of the list. - * This guarantees that the root node of the htree directories are - * processed first, so we know what hash version to use. - */ -static int special_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->blockcnt && !db_b->blockcnt) - return 1; - - if (!db_a->blockcnt && db_b->blockcnt) - return -1; - - 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); -} - - -/* - * Make sure the first entry in the directory is '.', and that the - * directory entry is sane. - */ -static int check_dot(e2fsck_t ctx, - struct ext2_dir_entry *dirent, - ext2_ino_t ino, struct problem_context *pctx) -{ - struct ext2_dir_entry *nextdir; - int status = 0; - int created = 0; - int new_len; - int problem = 0; - - if (!dirent->inode) - problem = PR_2_MISSING_DOT; - else if (((dirent->name_len & 0xFF) != 1) || - (dirent->name[0] != '.')) - problem = PR_2_1ST_NOT_DOT; - else if (dirent->name[1] != '\0') - problem = PR_2_DOT_NULL_TERM; - - if (problem) { - if (fix_problem(ctx, problem, pctx)) { - if (dirent->rec_len < 12) - dirent->rec_len = 12; - dirent->inode = ino; - dirent->name_len = 1; - dirent->name[0] = '.'; - dirent->name[1] = '\0'; - status = 1; - created = 1; - } - } - if (dirent->inode != ino) { - if (fix_problem(ctx, PR_2_BAD_INODE_DOT, pctx)) { - dirent->inode = ino; - status = 1; - } - } - if (dirent->rec_len > 12) { - new_len = dirent->rec_len - 12; - if (new_len > 12) { - if (created || - fix_problem(ctx, PR_2_SPLIT_DOT, pctx)) { - nextdir = (struct ext2_dir_entry *) - ((char *) dirent + 12); - dirent->rec_len = 12; - nextdir->rec_len = new_len; - nextdir->inode = 0; - nextdir->name_len = 0; - status = 1; - } - } - } - return status; -} - -/* - * Make sure the second entry in the directory is '..', and that the - * directory entry is sane. We do not check the inode number of '..' - * here; this gets done in pass 3. - */ -static int check_dotdot(e2fsck_t ctx, - struct ext2_dir_entry *dirent, - struct dir_info *dir, struct problem_context *pctx) -{ - int problem = 0; - - if (!dirent->inode) - problem = PR_2_MISSING_DOT_DOT; - else if (((dirent->name_len & 0xFF) != 2) || - (dirent->name[0] != '.') || - (dirent->name[1] != '.')) - problem = PR_2_2ND_NOT_DOT_DOT; - else if (dirent->name[2] != '\0') - problem = PR_2_DOT_DOT_NULL_TERM; - - if (problem) { - if (fix_problem(ctx, problem, pctx)) { - if (dirent->rec_len < 12) - dirent->rec_len = 12; - /* - * Note: we don't have the parent inode just - * yet, so we will fill it in with the root - * inode. This will get fixed in pass 3. - */ - dirent->inode = EXT2_ROOT_INO; - dirent->name_len = 2; - dirent->name[0] = '.'; - dirent->name[1] = '.'; - dirent->name[2] = '\0'; - return 1; - } - return 0; - } - dir->dotdot = dirent->inode; - return 0; -} - -/* - * Check to make sure a directory entry doesn't contain any illegal - * characters. - */ -static int check_name(e2fsck_t ctx, - struct ext2_dir_entry *dirent, - struct problem_context *pctx) -{ - int i; - int fixup = -1; - int ret = 0; - - for ( i = 0; i < (dirent->name_len & 0xFF); i++) { - if (dirent->name[i] == '/' || dirent->name[i] == '\0') { - if (fixup < 0) { - fixup = fix_problem(ctx, PR_2_BAD_NAME, pctx); - } - if (fixup) { - dirent->name[i] = '.'; - ret = 1; - } - } - } - return ret; -} - -/* - * Check the directory filetype (if present) - */ - -/* - * Given a mode, return the ext2 file type - */ -static int ext2_file_type(unsigned int mode) -{ - if (LINUX_S_ISREG(mode)) - return EXT2_FT_REG_FILE; - - if (LINUX_S_ISDIR(mode)) - return EXT2_FT_DIR; - - if (LINUX_S_ISCHR(mode)) - return EXT2_FT_CHRDEV; - - if (LINUX_S_ISBLK(mode)) - return EXT2_FT_BLKDEV; - - if (LINUX_S_ISLNK(mode)) - return EXT2_FT_SYMLINK; - - if (LINUX_S_ISFIFO(mode)) - return EXT2_FT_FIFO; - - if (LINUX_S_ISSOCK(mode)) - return EXT2_FT_SOCK; - - return 0; -} - -static int check_filetype(e2fsck_t ctx, - struct ext2_dir_entry *dirent, - struct problem_context *pctx) -{ - int filetype = dirent->name_len >> 8; - int should_be = EXT2_FT_UNKNOWN; - struct ext2_inode inode; - - if (!(ctx->fs->super->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_FILETYPE)) { - if (filetype == 0 || - !fix_problem(ctx, PR_2_CLEAR_FILETYPE, pctx)) - return 0; - dirent->name_len = dirent->name_len & 0xFF; - return 1; - } - - if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dirent->inode)) { - should_be = EXT2_FT_DIR; - } else if (ext2fs_test_inode_bitmap(ctx->inode_reg_map, - dirent->inode)) { - should_be = EXT2_FT_REG_FILE; - } else if (ctx->inode_bad_map && - ext2fs_test_inode_bitmap(ctx->inode_bad_map, - dirent->inode)) - should_be = 0; - else { - e2fsck_read_inode(ctx, dirent->inode, &inode, - "check_filetype"); - should_be = ext2_file_type(inode.i_mode); - } - if (filetype == should_be) - return 0; - pctx->num = should_be; - - if (fix_problem(ctx, filetype ? PR_2_BAD_FILETYPE : PR_2_SET_FILETYPE, - pctx) == 0) - return 0; - - dirent->name_len = (dirent->name_len & 0xFF) | should_be << 8; - return 1; -} - -#ifdef ENABLE_HTREE -static void parse_int_node(ext2_filsys fs, - struct ext2_db_entry *db, - struct check_dir_struct *cd, - struct dx_dir_info *dx_dir, - char *block_buf) -{ - struct ext2_dx_root_info *root; - struct ext2_dx_entry *ent; - struct ext2_dx_countlimit *limit; - struct dx_dirblock_info *dx_db; - int i, expect_limit, count; - blk_t blk; - ext2_dirhash_t min_hash = 0xffffffff; - ext2_dirhash_t max_hash = 0; - ext2_dirhash_t hash = 0, prev_hash; - - if (db->blockcnt == 0) { - root = (struct ext2_dx_root_info *) (block_buf + 24); - ent = (struct ext2_dx_entry *) (block_buf + 24 + root->info_length); - } else { - ent = (struct ext2_dx_entry *) (block_buf+8); - } - limit = (struct ext2_dx_countlimit *) ent; - - count = ext2fs_le16_to_cpu(limit->count); - expect_limit = (fs->blocksize - ((char *) ent - block_buf)) / - sizeof(struct ext2_dx_entry); - if (ext2fs_le16_to_cpu(limit->limit) != expect_limit) { - cd->pctx.num = ext2fs_le16_to_cpu(limit->limit); - if (fix_problem(cd->ctx, PR_2_HTREE_BAD_LIMIT, &cd->pctx)) - goto clear_and_exit; - } - if (count > expect_limit) { - cd->pctx.num = count; - if (fix_problem(cd->ctx, PR_2_HTREE_BAD_COUNT, &cd->pctx)) - goto clear_and_exit; - count = expect_limit; - } - - for (i=0; i < count; i++) { - prev_hash = hash; - hash = i ? (ext2fs_le32_to_cpu(ent[i].hash) & ~1) : 0; - blk = ext2fs_le32_to_cpu(ent[i].block) & 0x0ffffff; - /* Check to make sure the block is valid */ - if (blk > (blk_t) dx_dir->numblocks) { - cd->pctx.blk = blk; - if (fix_problem(cd->ctx, PR_2_HTREE_BADBLK, - &cd->pctx)) - goto clear_and_exit; - } - if (hash < prev_hash && - fix_problem(cd->ctx, PR_2_HTREE_HASH_ORDER, &cd->pctx)) - goto clear_and_exit; - dx_db = &dx_dir->dx_block[blk]; - if (dx_db->flags & DX_FLAG_REFERENCED) { - dx_db->flags |= DX_FLAG_DUP_REF; - } else { - dx_db->flags |= DX_FLAG_REFERENCED; - dx_db->parent = db->blockcnt; - } - if (hash < min_hash) - min_hash = hash; - if (hash > max_hash) - max_hash = hash; - dx_db->node_min_hash = hash; - if ((i+1) < count) - dx_db->node_max_hash = - ext2fs_le32_to_cpu(ent[i+1].hash) & ~1; - else { - dx_db->node_max_hash = 0xfffffffe; - dx_db->flags |= DX_FLAG_LAST; - } - if (i == 0) - dx_db->flags |= DX_FLAG_FIRST; - } - dx_db = &dx_dir->dx_block[db->blockcnt]; - dx_db->min_hash = min_hash; - dx_db->max_hash = max_hash; - return; - -clear_and_exit: - clear_htree(cd->ctx, cd->pctx.ino); - dx_dir->numblocks = 0; -} -#endif /* ENABLE_HTREE */ - -/* - * Given a busted directory, try to salvage it somehow. - * - */ -static void salvage_directory(ext2_filsys fs, - struct ext2_dir_entry *dirent, - struct ext2_dir_entry *prev, - unsigned int *offset) -{ - char *cp = (char *) dirent; - int left = fs->blocksize - *offset - dirent->rec_len; - int name_len = dirent->name_len & 0xFF; - - /* - * Special case of directory entry of size 8: copy what's left - * of the directory block up to cover up the invalid hole. - */ - if ((left >= 12) && (dirent->rec_len == 8)) { - memmove(cp, cp+8, left); - memset(cp + left, 0, 8); - return; - } - /* - * If the directory entry overruns the end of the directory - * block, and the name is small enough to fit, then adjust the - * record length. - */ - if ((left < 0) && - (name_len + 8 <= dirent->rec_len + left) && - dirent->inode <= fs->super->s_inodes_count && - strnlen(dirent->name, name_len) == name_len) { - dirent->rec_len += left; - return; - } - /* - * If the directory entry is a multiple of four, so it is - * valid, let the previous directory entry absorb the invalid - * one. - */ - if (prev && dirent->rec_len && (dirent->rec_len % 4) == 0) { - prev->rec_len += dirent->rec_len; - *offset += dirent->rec_len; - return; - } - /* - * Default salvage method --- kill all of the directory - * entries for the rest of the block. We will either try to - * absorb it into the previous directory entry, or create a - * new empty directory entry the rest of the directory block. - */ - if (prev) { - prev->rec_len += fs->blocksize - *offset; - *offset = fs->blocksize; - } else { - dirent->rec_len = fs->blocksize - *offset; - dirent->name_len = 0; - dirent->inode = 0; - } -} - -static int check_dir_block(ext2_filsys fs, - struct ext2_db_entry *db, - void *priv_data) -{ - struct dir_info *subdir, *dir; - struct dx_dir_info *dx_dir; -#ifdef ENABLE_HTREE - struct dx_dirblock_info *dx_db = NULL; -#endif /* ENABLE_HTREE */ - struct ext2_dir_entry *dirent, *prev; - ext2_dirhash_t hash; - unsigned int offset = 0; - int dir_modified = 0; - int dot_state; - blk_t block_nr = db->blk; - ext2_ino_t ino = db->ino; - __u16 links; - struct check_dir_struct *cd; - char *buf; - e2fsck_t ctx; - int problem; - struct ext2_dx_root_info *root; - struct ext2_dx_countlimit *limit; - static dict_t de_dict; - struct problem_context pctx; - int dups_found = 0; - - cd = (struct check_dir_struct *) priv_data; - buf = cd->buf; - ctx = cd->ctx; - - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return DIRENT_ABORT; - - if (ctx->progress && (ctx->progress)(ctx, 2, cd->count++, cd->max)) - return DIRENT_ABORT; - - /* - * Make sure the inode is still in use (could have been - * deleted in the duplicate/bad blocks pass. - */ - if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, ino))) - return 0; - - cd->pctx.ino = ino; - cd->pctx.blk = block_nr; - cd->pctx.blkcount = db->blockcnt; - cd->pctx.ino2 = 0; - cd->pctx.dirent = 0; - cd->pctx.num = 0; - - if (db->blk == 0) { - if (allocate_dir_block(ctx, db, &cd->pctx)) - return 0; - block_nr = db->blk; - } - - if (db->blockcnt) - dot_state = 2; - else - dot_state = 0; - - if (ctx->dirs_to_hash && - ext2fs_u32_list_test(ctx->dirs_to_hash, ino)) - dups_found++; - - cd->pctx.errcode = ext2fs_read_dir_block(fs, block_nr, buf); - if (cd->pctx.errcode == EXT2_ET_DIR_CORRUPTED) - cd->pctx.errcode = 0; /* We'll handle this ourselves */ - if (cd->pctx.errcode) { - if (!fix_problem(ctx, PR_2_READ_DIRBLOCK, &cd->pctx)) { - ctx->flags |= E2F_FLAG_ABORT; - return DIRENT_ABORT; - } - memset(buf, 0, fs->blocksize); - } -#ifdef ENABLE_HTREE - dx_dir = e2fsck_get_dx_dir_info(ctx, ino); - if (dx_dir && dx_dir->numblocks) { - if (db->blockcnt >= dx_dir->numblocks) { - printf("XXX should never happen!!!\n"); - abort(); - } - dx_db = &dx_dir->dx_block[db->blockcnt]; - dx_db->type = DX_DIRBLOCK_LEAF; - dx_db->phys = block_nr; - dx_db->min_hash = ~0; - dx_db->max_hash = 0; - - dirent = (struct ext2_dir_entry *) buf; - limit = (struct ext2_dx_countlimit *) (buf+8); - if (db->blockcnt == 0) { - root = (struct ext2_dx_root_info *) (buf + 24); - dx_db->type = DX_DIRBLOCK_ROOT; - dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST; - if ((root->reserved_zero || - root->info_length < 8 || - root->indirect_levels > 1) && - fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) { - clear_htree(ctx, ino); - dx_dir->numblocks = 0; - dx_db = 0; - } - dx_dir->hashversion = root->hash_version; - dx_dir->depth = root->indirect_levels + 1; - } else if ((dirent->inode == 0) && - (dirent->rec_len == fs->blocksize) && - (dirent->name_len == 0) && - (ext2fs_le16_to_cpu(limit->limit) == - ((fs->blocksize-8) / - sizeof(struct ext2_dx_entry)))) - dx_db->type = DX_DIRBLOCK_NODE; - } -#endif /* ENABLE_HTREE */ - - dict_init(&de_dict, DICTCOUNT_T_MAX, dict_de_cmp); - prev = 0; - do { - problem = 0; - dirent = (struct ext2_dir_entry *) (buf + offset); - cd->pctx.dirent = dirent; - cd->pctx.num = offset; - if (((offset + dirent->rec_len) > fs->blocksize) || - (dirent->rec_len < 12) || - ((dirent->rec_len % 4) != 0) || - (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) { - if (fix_problem(ctx, PR_2_DIR_CORRUPTED, &cd->pctx)) { - salvage_directory(fs, dirent, prev, &offset); - dir_modified++; - continue; - } else - goto abort_free_dict; - } - if ((dirent->name_len & 0xFF) > EXT2_NAME_LEN) { - if (fix_problem(ctx, PR_2_FILENAME_LONG, &cd->pctx)) { - dirent->name_len = EXT2_NAME_LEN; - dir_modified++; - } - } - - if (dot_state == 0) { - if (check_dot(ctx, dirent, ino, &cd->pctx)) - dir_modified++; - } else if (dot_state == 1) { - dir = e2fsck_get_dir_info(ctx, ino); - if (!dir) { - fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx); - goto abort_free_dict; - } - if (check_dotdot(ctx, dirent, dir, &cd->pctx)) - dir_modified++; - } else if (dirent->inode == ino) { - problem = PR_2_LINK_DOT; - if (fix_problem(ctx, PR_2_LINK_DOT, &cd->pctx)) { - dirent->inode = 0; - dir_modified++; - goto next; - } - } - if (!dirent->inode) - goto next; - - /* - * Make sure the inode listed is a legal one. - */ - if (((dirent->inode != EXT2_ROOT_INO) && - (dirent->inode < EXT2_FIRST_INODE(fs->super))) || - (dirent->inode > fs->super->s_inodes_count)) { - problem = PR_2_BAD_INO; - } else if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, - dirent->inode))) { - /* - * If the inode is unused, offer to clear it. - */ - problem = PR_2_UNUSED_INODE; - } else if ((dot_state > 1) && - ((dirent->name_len & 0xFF) == 1) && - (dirent->name[0] == '.')) { - /* - * If there's a '.' entry in anything other - * than the first directory entry, it's a - * duplicate entry that should be removed. - */ - problem = PR_2_DUP_DOT; - } else if ((dot_state > 1) && - ((dirent->name_len & 0xFF) == 2) && - (dirent->name[0] == '.') && - (dirent->name[1] == '.')) { - /* - * If there's a '..' entry in anything other - * than the second directory entry, it's a - * duplicate entry that should be removed. - */ - problem = PR_2_DUP_DOT_DOT; - } else if ((dot_state > 1) && - (dirent->inode == EXT2_ROOT_INO)) { - /* - * Don't allow links to the root directory. - * We check this specially to make sure we - * catch this error case even if the root - * directory hasn't been created yet. - */ - problem = PR_2_LINK_ROOT; - } else if ((dot_state > 1) && - (dirent->name_len & 0xFF) == 0) { - /* - * Don't allow zero-length directory names. - */ - problem = PR_2_NULL_NAME; - } - - if (problem) { - if (fix_problem(ctx, problem, &cd->pctx)) { - dirent->inode = 0; - dir_modified++; - goto next; - } else { - ext2fs_unmark_valid(fs); - if (problem == PR_2_BAD_INO) - goto next; - } - } - - /* - * If the inode was marked as having bad fields in - * pass1, process it and offer to fix/clear it. - * (We wait until now so that we can display the - * pathname to the user.) - */ - if (ctx->inode_bad_map && - ext2fs_test_inode_bitmap(ctx->inode_bad_map, - dirent->inode)) { - if (e2fsck_process_bad_inode(ctx, ino, - dirent->inode, - buf + fs->blocksize)) { - dirent->inode = 0; - dir_modified++; - goto next; - } - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return DIRENT_ABORT; - } - - if (check_name(ctx, dirent, &cd->pctx)) - dir_modified++; - - if (check_filetype(ctx, dirent, &cd->pctx)) - dir_modified++; - -#ifdef ENABLE_HTREE - if (dx_db) { - ext2fs_dirhash(dx_dir->hashversion, dirent->name, - (dirent->name_len & 0xFF), - fs->super->s_hash_seed, &hash, 0); - if (hash < dx_db->min_hash) - dx_db->min_hash = hash; - if (hash > dx_db->max_hash) - dx_db->max_hash = hash; - } -#endif - - /* - * If this is a directory, then mark its parent in its - * dir_info structure. If the parent field is already - * filled in, then this directory has more than one - * hard link. We assume the first link is correct, - * and ask the user if he/she wants to clear this one. - */ - if ((dot_state > 1) && - (ext2fs_test_inode_bitmap(ctx->inode_dir_map, - dirent->inode))) { - subdir = e2fsck_get_dir_info(ctx, dirent->inode); - if (!subdir) { - cd->pctx.ino = dirent->inode; - fix_problem(ctx, PR_2_NO_DIRINFO, &cd->pctx); - goto abort_free_dict; - } - if (subdir->parent) { - cd->pctx.ino2 = subdir->parent; - if (fix_problem(ctx, PR_2_LINK_DIR, - &cd->pctx)) { - dirent->inode = 0; - dir_modified++; - goto next; - } - cd->pctx.ino2 = 0; - } else - subdir->parent = ino; - } - - if (dups_found) { - ; - } else if (dict_lookup(&de_dict, dirent)) { - clear_problem_context(&pctx); - pctx.ino = ino; - pctx.dirent = dirent; - fix_problem(ctx, PR_2_REPORT_DUP_DIRENT, &pctx); - if (!ctx->dirs_to_hash) - ext2fs_u32_list_create(&ctx->dirs_to_hash, 50); - if (ctx->dirs_to_hash) - ext2fs_u32_list_add(ctx->dirs_to_hash, ino); - dups_found++; - } else - dict_alloc_insert(&de_dict, dirent, dirent); - - ext2fs_icount_increment(ctx->inode_count, dirent->inode, - &links); - if (links > 1) - ctx->fs_links_count++; - ctx->fs_total_count++; - next: - prev = dirent; - offset += dirent->rec_len; - dot_state++; - } while (offset < fs->blocksize); -#ifdef ENABLE_HTREE - if (dx_db) { - cd->pctx.dir = cd->pctx.ino; - if ((dx_db->type == DX_DIRBLOCK_ROOT) || - (dx_db->type == DX_DIRBLOCK_NODE)) - parse_int_node(fs, db, cd, dx_dir, buf); - } -#endif /* ENABLE_HTREE */ - if (offset != fs->blocksize) { - cd->pctx.num = dirent->rec_len - fs->blocksize + offset; - if (fix_problem(ctx, PR_2_FINAL_RECLEN, &cd->pctx)) { - dirent->rec_len = cd->pctx.num; - dir_modified++; - } - } - if (dir_modified) { - cd->pctx.errcode = ext2fs_write_dir_block(fs, block_nr, buf); - if (cd->pctx.errcode) { - if (!fix_problem(ctx, PR_2_WRITE_DIRBLOCK, - &cd->pctx)) - goto abort_free_dict; - } - ext2fs_mark_changed(fs); - } - dict_free_nodes(&de_dict); - return 0; -abort_free_dict: - dict_free_nodes(&de_dict); - ctx->flags |= E2F_FLAG_ABORT; - return DIRENT_ABORT; -} - -/* - * This function is called to deallocate a block, and is an interator - * functioned called by deallocate inode via ext2fs_iterate_block(). - */ -static int deallocate_inode_block(ext2_filsys fs, blk_t *block_nr, - e2_blkcnt_t blockcnt FSCK_ATTR((unused)), - blk_t ref_block FSCK_ATTR((unused)), - int ref_offset FSCK_ATTR((unused)), - void *priv_data) -{ - e2fsck_t ctx = (e2fsck_t) priv_data; - - if (HOLE_BLKADDR(*block_nr)) - return 0; - if ((*block_nr < fs->super->s_first_data_block) || - (*block_nr >= fs->super->s_blocks_count)) - return 0; - ext2fs_unmark_block_bitmap(ctx->block_found_map, *block_nr); - ext2fs_block_alloc_stats(fs, *block_nr, -1); - return 0; -} - -/* - * This fuction deallocates an inode - */ -static void deallocate_inode(e2fsck_t ctx, ext2_ino_t ino, char* block_buf) -{ - ext2_filsys fs = ctx->fs; - struct ext2_inode inode; - struct problem_context pctx; - __u32 count; - - ext2fs_icount_store(ctx->inode_link_info, ino, 0); - e2fsck_read_inode(ctx, ino, &inode, "deallocate_inode"); - inode.i_links_count = 0; - inode.i_dtime = time(NULL); - e2fsck_write_inode(ctx, ino, &inode, "deallocate_inode"); - clear_problem_context(&pctx); - pctx.ino = ino; - - /* - * Fix up the bitmaps... - */ - e2fsck_read_bitmaps(ctx); - ext2fs_unmark_inode_bitmap(ctx->inode_used_map, ino); - ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, ino); - if (ctx->inode_bad_map) - ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); - ext2fs_inode_alloc_stats2(fs, ino, -1, LINUX_S_ISDIR(inode.i_mode)); - - if (inode.i_file_acl && - (fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) { - pctx.errcode = ext2fs_adjust_ea_refcount(fs, inode.i_file_acl, - block_buf, -1, &count); - if (pctx.errcode == EXT2_ET_BAD_EA_BLOCK_NUM) { - pctx.errcode = 0; - count = 1; - } - if (pctx.errcode) { - pctx.blk = inode.i_file_acl; - fix_problem(ctx, PR_2_ADJ_EA_REFCOUNT, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - if (count == 0) { - ext2fs_unmark_block_bitmap(ctx->block_found_map, - inode.i_file_acl); - ext2fs_block_alloc_stats(fs, inode.i_file_acl, -1); - } - inode.i_file_acl = 0; - } - - if (!ext2fs_inode_has_valid_blocks(&inode)) - return; - - if (LINUX_S_ISREG(inode.i_mode) && - (inode.i_size_high || inode.i_size & 0x80000000UL)) - ctx->large_files--; - - pctx.errcode = ext2fs_block_iterate2(fs, ino, 0, block_buf, - deallocate_inode_block, ctx); - if (pctx.errcode) { - fix_problem(ctx, PR_2_DEALLOC_INODE, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } -} - -/* - * This fuction clears the htree flag on an inode - */ -static void clear_htree(e2fsck_t ctx, ext2_ino_t ino) -{ - struct ext2_inode inode; - - e2fsck_read_inode(ctx, ino, &inode, "clear_htree"); - inode.i_flags = inode.i_flags & ~EXT2_INDEX_FL; - e2fsck_write_inode(ctx, ino, &inode, "clear_htree"); - if (ctx->dirs_to_hash) - ext2fs_u32_list_add(ctx->dirs_to_hash, ino); -} - - -static int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir, - ext2_ino_t ino, char *buf) -{ - ext2_filsys fs = ctx->fs; - struct ext2_inode inode; - int inode_modified = 0; - int not_fixed = 0; - unsigned char *frag, *fsize; - struct problem_context pctx; - int problem = 0; - - e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode"); - - clear_problem_context(&pctx); - pctx.ino = ino; - pctx.dir = dir; - pctx.inode = &inode; - - if (inode.i_file_acl && - !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) && - fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) { - inode.i_file_acl = 0; -#if BB_BIG_ENDIAN - /* - * This is a special kludge to deal with long symlinks - * on big endian systems. i_blocks had already been - * decremented earlier in pass 1, but since i_file_acl - * hadn't yet been cleared, ext2fs_read_inode() - * assumed that the file was short symlink and would - * not have byte swapped i_block[0]. Hence, we have - * to byte-swap it here. - */ - if (LINUX_S_ISLNK(inode.i_mode) && - (fs->flags & EXT2_FLAG_SWAP_BYTES) && - (inode.i_blocks == fs->blocksize >> 9)) - inode.i_block[0] = ext2fs_swab32(inode.i_block[0]); -#endif - inode_modified++; - } else - not_fixed++; - - if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) && - !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) && - !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) && - !(LINUX_S_ISSOCK(inode.i_mode))) - problem = PR_2_BAD_MODE; - else if (LINUX_S_ISCHR(inode.i_mode) - && !e2fsck_pass1_check_device_inode(fs, &inode)) - problem = PR_2_BAD_CHAR_DEV; - else if (LINUX_S_ISBLK(inode.i_mode) - && !e2fsck_pass1_check_device_inode(fs, &inode)) - problem = PR_2_BAD_BLOCK_DEV; - else if (LINUX_S_ISFIFO(inode.i_mode) - && !e2fsck_pass1_check_device_inode(fs, &inode)) - problem = PR_2_BAD_FIFO; - else if (LINUX_S_ISSOCK(inode.i_mode) - && !e2fsck_pass1_check_device_inode(fs, &inode)) - problem = PR_2_BAD_SOCKET; - else if (LINUX_S_ISLNK(inode.i_mode) - && !e2fsck_pass1_check_symlink(fs, &inode, buf)) { - problem = PR_2_INVALID_SYMLINK; - } - - if (problem) { - if (fix_problem(ctx, problem, &pctx)) { - deallocate_inode(ctx, ino, 0); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return 0; - return 1; - } else - not_fixed++; - problem = 0; - } - - if (inode.i_faddr) { - if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) { - inode.i_faddr = 0; - inode_modified++; - } else - not_fixed++; - } - - switch (fs->super->s_creator_os) { - case EXT2_OS_LINUX: - frag = &inode.osd2.linux2.l_i_frag; - fsize = &inode.osd2.linux2.l_i_fsize; - break; - case EXT2_OS_HURD: - frag = &inode.osd2.hurd2.h_i_frag; - fsize = &inode.osd2.hurd2.h_i_fsize; - break; - case EXT2_OS_MASIX: - frag = &inode.osd2.masix2.m_i_frag; - fsize = &inode.osd2.masix2.m_i_fsize; - break; - default: - frag = fsize = 0; - } - if (frag && *frag) { - pctx.num = *frag; - if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) { - *frag = 0; - inode_modified++; - } else - not_fixed++; - pctx.num = 0; - } - if (fsize && *fsize) { - pctx.num = *fsize; - if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) { - *fsize = 0; - inode_modified++; - } else - not_fixed++; - pctx.num = 0; - } - - if (inode.i_file_acl && - ((inode.i_file_acl < fs->super->s_first_data_block) || - (inode.i_file_acl >= fs->super->s_blocks_count))) { - if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) { - inode.i_file_acl = 0; - inode_modified++; - } else - not_fixed++; - } - if (inode.i_dir_acl && - LINUX_S_ISDIR(inode.i_mode)) { - if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) { - inode.i_dir_acl = 0; - inode_modified++; - } else - not_fixed++; - } - - if (inode_modified) - e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode"); - if (!not_fixed) - ext2fs_unmark_inode_bitmap(ctx->inode_bad_map, ino); - return 0; -} - - -/* - * allocate_dir_block --- this function allocates a new directory - * block for a particular inode; this is done if a directory has - * a "hole" in it, or if a directory has a illegal block number - * that was zeroed out and now needs to be replaced. - */ -static int allocate_dir_block(e2fsck_t ctx, struct ext2_db_entry *db, - struct problem_context *pctx) -{ - ext2_filsys fs = ctx->fs; - blk_t blk; - char *block; - struct ext2_inode inode; - - if (fix_problem(ctx, PR_2_DIRECTORY_HOLE, pctx) == 0) - return 1; - - /* - * Read the inode and block bitmaps in; we'll be messing with - * them. - */ - e2fsck_read_bitmaps(ctx); - - /* - * First, find a free block - */ - pctx->errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk); - if (pctx->errcode) { - pctx->str = "ext2fs_new_block"; - fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); - return 1; - } - ext2fs_mark_block_bitmap(ctx->block_found_map, blk); - ext2fs_mark_block_bitmap(fs->block_map, blk); - ext2fs_mark_bb_dirty(fs); - - /* - * Now let's create the actual data block for the inode - */ - if (db->blockcnt) - pctx->errcode = ext2fs_new_dir_block(fs, 0, 0, &block); - else - pctx->errcode = ext2fs_new_dir_block(fs, db->ino, - EXT2_ROOT_INO, &block); - - if (pctx->errcode) { - pctx->str = "ext2fs_new_dir_block"; - fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); - return 1; - } - - pctx->errcode = ext2fs_write_dir_block(fs, blk, block); - ext2fs_free_mem(&block); - if (pctx->errcode) { - pctx->str = "ext2fs_write_dir_block"; - fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); - return 1; - } - - /* - * Update the inode block count - */ - e2fsck_read_inode(ctx, db->ino, &inode, "allocate_dir_block"); - inode.i_blocks += fs->blocksize / 512; - if (inode.i_size < (db->blockcnt+1) * fs->blocksize) - inode.i_size = (db->blockcnt+1) * fs->blocksize; - e2fsck_write_inode(ctx, db->ino, &inode, "allocate_dir_block"); - - /* - * Finally, update the block pointers for the inode - */ - db->blk = blk; - pctx->errcode = ext2fs_block_iterate2(fs, db->ino, BLOCK_FLAG_HOLE, - 0, update_dir_block, db); - if (pctx->errcode) { - pctx->str = "ext2fs_block_iterate"; - fix_problem(ctx, PR_2_ALLOC_DIRBOCK, pctx); - return 1; - } - - return 0; -} - -/* - * This is a helper function for allocate_dir_block(). - */ -static int update_dir_block(ext2_filsys fs FSCK_ATTR((unused)), - blk_t *block_nr, - e2_blkcnt_t blockcnt, - blk_t ref_block FSCK_ATTR((unused)), - int ref_offset FSCK_ATTR((unused)), - void *priv_data) -{ - struct ext2_db_entry *db; - - db = (struct ext2_db_entry *) priv_data; - if (db->blockcnt == (int) blockcnt) { - *block_nr = db->blk; - return BLOCK_CHANGED; - } - return 0; -} - -/* - * pass3.c -- pass #3 of e2fsck: Check for directory connectivity - * - * Pass #3 assures that all directories are connected to the - * filesystem tree, using the following algorithm: - * - * First, the root directory is checked to make sure it exists; if - * not, e2fsck will offer to create a new one. It is then marked as - * "done". - * - * Then, pass3 interates over all directory inodes; for each directory - * it attempts to trace up the filesystem tree, using dirinfo.parent - * until it reaches a directory which has been marked "done". If it - * cannot do so, then the directory must be disconnected, and e2fsck - * will offer to reconnect it to /lost+found. While it is chasing - * parent pointers up the filesystem tree, if pass3 sees a directory - * twice, then it has detected a filesystem loop, and it will again - * offer to reconnect the directory to /lost+found in to break the - * filesystem loop. - * - * Pass 3 also contains the subroutine, e2fsck_reconnect_file() to - * reconnect inodes to /lost+found; this subroutine is also used by - * pass 4. e2fsck_reconnect_file() calls get_lost_and_found(), which - * is responsible for creating /lost+found if it does not exist. - * - * Pass 3 frees the following data structures: - * - The dirinfo directory information cache. - */ - -static void check_root(e2fsck_t ctx); -static int check_directory(e2fsck_t ctx, struct dir_info *dir, - struct problem_context *pctx); -static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent); - -static ext2fs_inode_bitmap inode_loop_detect; -static ext2fs_inode_bitmap inode_done_map; - -static void e2fsck_pass3(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - int i; - struct problem_context pctx; - struct dir_info *dir; - unsigned long maxdirs, count; - - clear_problem_context(&pctx); - - /* Pass 3 */ - - if (!(ctx->options & E2F_OPT_PREEN)) - fix_problem(ctx, PR_3_PASS_HEADER, &pctx); - - /* - * Allocate some bitmaps to do loop detection. - */ - pctx.errcode = ext2fs_allocate_inode_bitmap(fs, _("inode done bitmap"), - &inode_done_map); - if (pctx.errcode) { - pctx.num = 2; - fix_problem(ctx, PR_3_ALLOCATE_IBITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - goto abort_exit; - } - check_root(ctx); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - goto abort_exit; - - ext2fs_mark_inode_bitmap(inode_done_map, EXT2_ROOT_INO); - - maxdirs = e2fsck_get_num_dirinfo(ctx); - count = 1; - - if (ctx->progress) - if ((ctx->progress)(ctx, 3, 0, maxdirs)) - goto abort_exit; - - for (i=0; (dir = e2fsck_dir_info_iter(ctx, &i)) != 0;) { - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - goto abort_exit; - if (ctx->progress && (ctx->progress)(ctx, 3, count++, maxdirs)) - goto abort_exit; - if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, dir->ino)) - if (check_directory(ctx, dir, &pctx)) - goto abort_exit; - } - - /* - * Force the creation of /lost+found if not present - */ - if ((ctx->flags & E2F_OPT_READONLY) == 0) - e2fsck_get_lost_and_found(ctx, 1); - - /* - * If there are any directories that need to be indexed or - * optimized, do it here. - */ - e2fsck_rehash_directories(ctx); - -abort_exit: - e2fsck_free_dir_info(ctx); - ext2fs_free_inode_bitmap(inode_loop_detect); - inode_loop_detect = 0; - ext2fs_free_inode_bitmap(inode_done_map); - inode_done_map = 0; -} - -/* - * This makes sure the root inode is present; if not, we ask if the - * user wants us to create it. Not creating it is a fatal error. - */ -static void check_root(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - blk_t blk; - struct ext2_inode inode; - char * block; - struct problem_context pctx; - - clear_problem_context(&pctx); - - if (ext2fs_test_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO)) { - /* - * If the root inode is not a directory, die here. The - * user must have answered 'no' in pass1 when we - * offered to clear it. - */ - if (!(ext2fs_test_inode_bitmap(ctx->inode_dir_map, - EXT2_ROOT_INO))) { - fix_problem(ctx, PR_3_ROOT_NOT_DIR_ABORT, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - } - return; - } - - if (!fix_problem(ctx, PR_3_NO_ROOT_INODE, &pctx)) { - fix_problem(ctx, PR_3_NO_ROOT_INODE_ABORT, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - - e2fsck_read_bitmaps(ctx); - - /* - * First, find a free block - */ - pctx.errcode = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk); - if (pctx.errcode) { - pctx.str = "ext2fs_new_block"; - fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - ext2fs_mark_block_bitmap(ctx->block_found_map, blk); - ext2fs_mark_block_bitmap(fs->block_map, blk); - ext2fs_mark_bb_dirty(fs); - - /* - * Now let's create the actual data block for the inode - */ - pctx.errcode = ext2fs_new_dir_block(fs, EXT2_ROOT_INO, EXT2_ROOT_INO, - &block); - if (pctx.errcode) { - pctx.str = "ext2fs_new_dir_block"; - fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - - pctx.errcode = ext2fs_write_dir_block(fs, blk, block); - if (pctx.errcode) { - pctx.str = "ext2fs_write_dir_block"; - fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - ext2fs_free_mem(&block); - - /* - * Set up the inode structure - */ - memset(&inode, 0, sizeof(inode)); - inode.i_mode = 040755; - inode.i_size = fs->blocksize; - inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL); - inode.i_links_count = 2; - inode.i_blocks = fs->blocksize / 512; - inode.i_block[0] = blk; - - /* - * Write out the inode. - */ - pctx.errcode = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode); - if (pctx.errcode) { - pctx.str = "ext2fs_write_inode"; - fix_problem(ctx, PR_3_CREATE_ROOT_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - - /* - * Miscellaneous bookkeeping... - */ - e2fsck_add_dir_info(ctx, EXT2_ROOT_INO, EXT2_ROOT_INO); - ext2fs_icount_store(ctx->inode_count, EXT2_ROOT_INO, 2); - ext2fs_icount_store(ctx->inode_link_info, EXT2_ROOT_INO, 2); - - ext2fs_mark_inode_bitmap(ctx->inode_used_map, EXT2_ROOT_INO); - ext2fs_mark_inode_bitmap(ctx->inode_dir_map, EXT2_ROOT_INO); - ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_ROOT_INO); - ext2fs_mark_ib_dirty(fs); -} - -/* - * This subroutine is responsible for making sure that a particular - * directory is connected to the root; if it isn't we trace it up as - * far as we can go, and then offer to connect the resulting parent to - * the lost+found. We have to do loop detection; if we ever discover - * a loop, we treat that as a disconnected directory and offer to - * reparent it to lost+found. - * - * However, loop detection is expensive, because for very large - * filesystems, the inode_loop_detect bitmap is huge, and clearing it - * is non-trivial. Loops in filesystems are also a rare error case, - * and we shouldn't optimize for error cases. So we try two passes of - * the algorithm. The first time, we ignore loop detection and merely - * increment a counter; if the counter exceeds some extreme threshold, - * then we try again with the loop detection bitmap enabled. - */ -static int check_directory(e2fsck_t ctx, struct dir_info *dir, - struct problem_context *pctx) -{ - ext2_filsys fs = ctx->fs; - struct dir_info *p = dir; - int loop_pass = 0, parent_count = 0; - - if (!p) - return 0; - - while (1) { - /* - * Mark this inode as being "done"; by the time we - * return from this function, the inode we either be - * verified as being connected to the directory tree, - * or we will have offered to reconnect this to - * lost+found. - * - * If it was marked done already, then we've reached a - * parent we've already checked. - */ - if (ext2fs_mark_inode_bitmap(inode_done_map, p->ino)) - break; - - /* - * If this directory doesn't have a parent, or we've - * seen the parent once already, then offer to - * reparent it to lost+found - */ - if (!p->parent || - (loop_pass && - (ext2fs_test_inode_bitmap(inode_loop_detect, - p->parent)))) { - pctx->ino = p->ino; - if (fix_problem(ctx, PR_3_UNCONNECTED_DIR, pctx)) { - if (e2fsck_reconnect_file(ctx, pctx->ino)) - ext2fs_unmark_valid(fs); - else { - p = e2fsck_get_dir_info(ctx, pctx->ino); - p->parent = ctx->lost_and_found; - fix_dotdot(ctx, p, ctx->lost_and_found); - } - } - break; - } - p = e2fsck_get_dir_info(ctx, p->parent); - if (!p) { - fix_problem(ctx, PR_3_NO_DIRINFO, pctx); - return 0; - } - if (loop_pass) { - ext2fs_mark_inode_bitmap(inode_loop_detect, - p->ino); - } else if (parent_count++ > 2048) { - /* - * If we've run into a path depth that's - * greater than 2048, try again with the inode - * loop bitmap turned on and start from the - * top. - */ - loop_pass = 1; - if (inode_loop_detect) - ext2fs_clear_inode_bitmap(inode_loop_detect); - else { - pctx->errcode = ext2fs_allocate_inode_bitmap(fs, _("inode loop detection bitmap"), &inode_loop_detect); - if (pctx->errcode) { - pctx->num = 1; - fix_problem(ctx, - PR_3_ALLOCATE_IBITMAP_ERROR, pctx); - ctx->flags |= E2F_FLAG_ABORT; - return -1; - } - } - p = dir; - } - } - - /* - * Make sure that .. and the parent directory are the same; - * offer to fix it if not. - */ - if (dir->parent != dir->dotdot) { - pctx->ino = dir->ino; - pctx->ino2 = dir->dotdot; - pctx->dir = dir->parent; - if (fix_problem(ctx, PR_3_BAD_DOT_DOT, pctx)) - fix_dotdot(ctx, dir, dir->parent); - } - return 0; -} - -/* - * This routine gets the lost_and_found inode, making it a directory - * if necessary - */ -ext2_ino_t e2fsck_get_lost_and_found(e2fsck_t ctx, int fix) -{ - ext2_filsys fs = ctx->fs; - ext2_ino_t ino; - blk_t blk; - errcode_t retval; - struct ext2_inode inode; - char * block; - static const char name[] = "lost+found"; - struct problem_context pctx; - struct dir_info *dirinfo; - - if (ctx->lost_and_found) - return ctx->lost_and_found; - - clear_problem_context(&pctx); - - retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name, - sizeof(name)-1, 0, &ino); - if (retval && !fix) - return 0; - if (!retval) { - if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, ino)) { - ctx->lost_and_found = ino; - return ino; - } - - /* Lost+found isn't a directory! */ - if (!fix) - return 0; - pctx.ino = ino; - if (!fix_problem(ctx, PR_3_LPF_NOTDIR, &pctx)) - return 0; - - /* OK, unlink the old /lost+found file. */ - pctx.errcode = ext2fs_unlink(fs, EXT2_ROOT_INO, name, ino, 0); - if (pctx.errcode) { - pctx.str = "ext2fs_unlink"; - fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx); - return 0; - } - dirinfo = e2fsck_get_dir_info(ctx, ino); - if (dirinfo) - dirinfo->parent = 0; - e2fsck_adjust_inode_count(ctx, ino, -1); - } else if (retval != EXT2_ET_FILE_NOT_FOUND) { - pctx.errcode = retval; - fix_problem(ctx, PR_3_ERR_FIND_LPF, &pctx); - } - if (!fix_problem(ctx, PR_3_NO_LF_DIR, 0)) - return 0; - - /* - * Read the inode and block bitmaps in; we'll be messing with - * them. - */ - e2fsck_read_bitmaps(ctx); - - /* - * First, find a free block - */ - retval = ext2fs_new_block(fs, 0, ctx->block_found_map, &blk); - if (retval) { - pctx.errcode = retval; - fix_problem(ctx, PR_3_ERR_LPF_NEW_BLOCK, &pctx); - return 0; - } - ext2fs_mark_block_bitmap(ctx->block_found_map, blk); - ext2fs_block_alloc_stats(fs, blk, +1); - - /* - * Next find a free inode. - */ - retval = ext2fs_new_inode(fs, EXT2_ROOT_INO, 040700, - ctx->inode_used_map, &ino); - if (retval) { - pctx.errcode = retval; - fix_problem(ctx, PR_3_ERR_LPF_NEW_INODE, &pctx); - return 0; - } - ext2fs_mark_inode_bitmap(ctx->inode_used_map, ino); - ext2fs_mark_inode_bitmap(ctx->inode_dir_map, ino); - ext2fs_inode_alloc_stats2(fs, ino, +1, 1); - - /* - * Now let's create the actual data block for the inode - */ - retval = ext2fs_new_dir_block(fs, ino, EXT2_ROOT_INO, &block); - if (retval) { - pctx.errcode = retval; - fix_problem(ctx, PR_3_ERR_LPF_NEW_DIR_BLOCK, &pctx); - return 0; - } - - retval = ext2fs_write_dir_block(fs, blk, block); - ext2fs_free_mem(&block); - if (retval) { - pctx.errcode = retval; - fix_problem(ctx, PR_3_ERR_LPF_WRITE_BLOCK, &pctx); - return 0; - } - - /* - * Set up the inode structure - */ - memset(&inode, 0, sizeof(inode)); - inode.i_mode = 040700; - inode.i_size = fs->blocksize; - inode.i_atime = inode.i_ctime = inode.i_mtime = time(NULL); - inode.i_links_count = 2; - inode.i_blocks = fs->blocksize / 512; - inode.i_block[0] = blk; - - /* - * Next, write out the inode. - */ - pctx.errcode = ext2fs_write_new_inode(fs, ino, &inode); - if (pctx.errcode) { - pctx.str = "ext2fs_write_inode"; - fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx); - return 0; - } - /* - * Finally, create the directory link - */ - pctx.errcode = ext2fs_link(fs, EXT2_ROOT_INO, name, ino, EXT2_FT_DIR); - if (pctx.errcode) { - pctx.str = "ext2fs_link"; - fix_problem(ctx, PR_3_CREATE_LPF_ERROR, &pctx); - return 0; - } - - /* - * Miscellaneous bookkeeping that needs to be kept straight. - */ - e2fsck_add_dir_info(ctx, ino, EXT2_ROOT_INO); - e2fsck_adjust_inode_count(ctx, EXT2_ROOT_INO, 1); - ext2fs_icount_store(ctx->inode_count, ino, 2); - ext2fs_icount_store(ctx->inode_link_info, ino, 2); - ctx->lost_and_found = ino; - return ino; -} - -/* - * This routine will connect a file to lost+found - */ -int e2fsck_reconnect_file(e2fsck_t ctx, ext2_ino_t ino) -{ - ext2_filsys fs = ctx->fs; - errcode_t retval; - char name[80]; - struct problem_context pctx; - struct ext2_inode inode; - int file_type = 0; - - clear_problem_context(&pctx); - pctx.ino = ino; - - if (!ctx->bad_lost_and_found && !ctx->lost_and_found) { - if (e2fsck_get_lost_and_found(ctx, 1) == 0) - ctx->bad_lost_and_found++; - } - if (ctx->bad_lost_and_found) { - fix_problem(ctx, PR_3_NO_LPF, &pctx); - return 1; - } - - sprintf(name, "#%u", ino); - if (ext2fs_read_inode(fs, ino, &inode) == 0) - file_type = ext2_file_type(inode.i_mode); - retval = ext2fs_link(fs, ctx->lost_and_found, name, ino, file_type); - if (retval == EXT2_ET_DIR_NO_SPACE) { - if (!fix_problem(ctx, PR_3_EXPAND_LF_DIR, &pctx)) - return 1; - retval = e2fsck_expand_directory(ctx, ctx->lost_and_found, - 1, 0); - if (retval) { - pctx.errcode = retval; - fix_problem(ctx, PR_3_CANT_EXPAND_LPF, &pctx); - return 1; - } - retval = ext2fs_link(fs, ctx->lost_and_found, name, - ino, file_type); - } - if (retval) { - pctx.errcode = retval; - fix_problem(ctx, PR_3_CANT_RECONNECT, &pctx); - return 1; - } - e2fsck_adjust_inode_count(ctx, ino, 1); - - return 0; -} - -/* - * Utility routine to adjust the inode counts on an inode. - */ -errcode_t e2fsck_adjust_inode_count(e2fsck_t ctx, ext2_ino_t ino, int adj) -{ - ext2_filsys fs = ctx->fs; - errcode_t retval; - struct ext2_inode inode; - - if (!ino) - return 0; - - retval = ext2fs_read_inode(fs, ino, &inode); - if (retval) - return retval; - - if (adj == 1) { - ext2fs_icount_increment(ctx->inode_count, ino, 0); - if (inode.i_links_count == (__u16) ~0) - return 0; - ext2fs_icount_increment(ctx->inode_link_info, ino, 0); - inode.i_links_count++; - } else if (adj == -1) { - ext2fs_icount_decrement(ctx->inode_count, ino, 0); - if (inode.i_links_count == 0) - return 0; - ext2fs_icount_decrement(ctx->inode_link_info, ino, 0); - inode.i_links_count--; - } - - retval = ext2fs_write_inode(fs, ino, &inode); - if (retval) - return retval; - - return 0; -} - -/* - * Fix parent --- this routine fixes up the parent of a directory. - */ -struct fix_dotdot_struct { - ext2_filsys fs; - ext2_ino_t parent; - int done; - e2fsck_t ctx; -}; - -static int fix_dotdot_proc(struct ext2_dir_entry *dirent, - int offset FSCK_ATTR((unused)), - int blocksize FSCK_ATTR((unused)), - char *buf FSCK_ATTR((unused)), - void *priv_data) -{ - struct fix_dotdot_struct *fp = (struct fix_dotdot_struct *) priv_data; - errcode_t retval; - struct problem_context pctx; - - if ((dirent->name_len & 0xFF) != 2) - return 0; - if (strncmp(dirent->name, "..", 2)) - return 0; - - clear_problem_context(&pctx); - - retval = e2fsck_adjust_inode_count(fp->ctx, dirent->inode, -1); - if (retval) { - pctx.errcode = retval; - fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx); - } - retval = e2fsck_adjust_inode_count(fp->ctx, fp->parent, 1); - if (retval) { - pctx.errcode = retval; - fix_problem(fp->ctx, PR_3_ADJUST_INODE, &pctx); - } - dirent->inode = fp->parent; - - fp->done++; - return DIRENT_ABORT | DIRENT_CHANGED; -} - -static void fix_dotdot(e2fsck_t ctx, struct dir_info *dir, ext2_ino_t parent) -{ - ext2_filsys fs = ctx->fs; - errcode_t retval; - struct fix_dotdot_struct fp; - struct problem_context pctx; - - fp.fs = fs; - fp.parent = parent; - fp.done = 0; - fp.ctx = ctx; - - retval = ext2fs_dir_iterate(fs, dir->ino, DIRENT_FLAG_INCLUDE_EMPTY, - 0, fix_dotdot_proc, &fp); - if (retval || !fp.done) { - clear_problem_context(&pctx); - pctx.ino = dir->ino; - pctx.errcode = retval; - fix_problem(ctx, retval ? PR_3_FIX_PARENT_ERR : - PR_3_FIX_PARENT_NOFIND, &pctx); - ext2fs_unmark_valid(fs); - } - dir->dotdot = parent; -} - -/* - * These routines are responsible for expanding a /lost+found if it is - * too small. - */ - -struct expand_dir_struct { - int num; - int guaranteed_size; - int newblocks; - int last_block; - errcode_t err; - e2fsck_t ctx; -}; - -static int expand_dir_proc(ext2_filsys fs, - blk_t *blocknr, - e2_blkcnt_t blockcnt, - blk_t ref_block FSCK_ATTR((unused)), - int ref_offset FSCK_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; - e2fsck_t ctx; - - ctx = es->ctx; - - if (es->guaranteed_size && blockcnt >= es->guaranteed_size) - return BLOCK_ABORT; - - if (blockcnt > 0) - es->last_block = blockcnt; - if (*blocknr) { - last_blk = *blocknr; - return 0; - } - retval = ext2fs_new_block(fs, last_blk, ctx->block_found_map, - &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->num--; - 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_mark_block_bitmap(ctx->block_found_map, new_blk); - ext2fs_block_alloc_stats(fs, new_blk, +1); - es->newblocks++; - - if (es->num == 0) - return (BLOCK_CHANGED | BLOCK_ABORT); - else - return BLOCK_CHANGED; -} - -errcode_t e2fsck_expand_directory(e2fsck_t ctx, ext2_ino_t dir, - int num, int guaranteed_size) -{ - ext2_filsys fs = ctx->fs; - errcode_t retval; - struct expand_dir_struct es; - struct ext2_inode inode; - - if (!(fs->flags & EXT2_FLAG_RW)) - return EXT2_ET_RO_FILSYS; - - /* - * Read the inode and block bitmaps in; we'll be messing with - * them. - */ - e2fsck_read_bitmaps(ctx); - - retval = ext2fs_check_directory(fs, dir); - if (retval) - return retval; - - es.num = num; - es.guaranteed_size = guaranteed_size; - es.last_block = 0; - es.err = 0; - es.newblocks = 0; - es.ctx = ctx; - - retval = ext2fs_block_iterate2(fs, dir, BLOCK_FLAG_APPEND, - 0, expand_dir_proc, &es); - - if (es.err) - return es.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 = (es.last_block + 1) * fs->blocksize; - inode.i_blocks += (fs->blocksize / 512) * es.newblocks; - - e2fsck_write_inode(ctx, dir, &inode, "expand_directory"); - - return 0; -} - -/* - * pass4.c -- pass #4 of e2fsck: Check reference counts - * - * Pass 4 frees the following data structures: - * - A bitmap of which inodes are imagic inodes. (inode_imagic_map) - */ - -/* - * This routine is called when an inode is not connected to the - * directory tree. - * - * This subroutine returns 1 then the caller shouldn't bother with the - * rest of the pass 4 tests. - */ -static int disconnect_inode(e2fsck_t ctx, ext2_ino_t i) -{ - ext2_filsys fs = ctx->fs; - struct ext2_inode inode; - struct problem_context pctx; - - e2fsck_read_inode(ctx, i, &inode, "pass4: disconnect_inode"); - clear_problem_context(&pctx); - pctx.ino = i; - pctx.inode = &inode; - - /* - * Offer to delete any zero-length files that does not have - * blocks. If there is an EA block, it might have useful - * information, so we won't prompt to delete it, but let it be - * reconnected to lost+found. - */ - if (!inode.i_blocks && (LINUX_S_ISREG(inode.i_mode) || - LINUX_S_ISDIR(inode.i_mode))) { - if (fix_problem(ctx, PR_4_ZERO_LEN_INODE, &pctx)) { - ext2fs_icount_store(ctx->inode_link_info, i, 0); - inode.i_links_count = 0; - inode.i_dtime = time(NULL); - e2fsck_write_inode(ctx, i, &inode, - "disconnect_inode"); - /* - * Fix up the bitmaps... - */ - e2fsck_read_bitmaps(ctx); - ext2fs_unmark_inode_bitmap(ctx->inode_used_map, i); - ext2fs_unmark_inode_bitmap(ctx->inode_dir_map, i); - ext2fs_inode_alloc_stats2(fs, i, -1, - LINUX_S_ISDIR(inode.i_mode)); - return 0; - } - } - - /* - * Prompt to reconnect. - */ - if (fix_problem(ctx, PR_4_UNATTACHED_INODE, &pctx)) { - if (e2fsck_reconnect_file(ctx, i)) - ext2fs_unmark_valid(fs); - } else { - /* - * If we don't attach the inode, then skip the - * i_links_test since there's no point in trying to - * force i_links_count to zero. - */ - ext2fs_unmark_valid(fs); - return 1; - } - return 0; -} - - -static void e2fsck_pass4(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - ext2_ino_t i; - struct ext2_inode inode; - struct problem_context pctx; - __u16 link_count, link_counted; - char *buf = NULL; - int group, maxgroup; - - /* Pass 4 */ - - clear_problem_context(&pctx); - - if (!(ctx->options & E2F_OPT_PREEN)) - fix_problem(ctx, PR_4_PASS_HEADER, &pctx); - - group = 0; - maxgroup = fs->group_desc_count; - if (ctx->progress) - if ((ctx->progress)(ctx, 4, 0, maxgroup)) - return; - - for (i=1; i <= fs->super->s_inodes_count; i++) { - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - if ((i % fs->super->s_inodes_per_group) == 0) { - group++; - if (ctx->progress) - if ((ctx->progress)(ctx, 4, group, maxgroup)) - return; - } - if (i == EXT2_BAD_INO || - (i > EXT2_ROOT_INO && i < EXT2_FIRST_INODE(fs->super))) - continue; - if (!(ext2fs_test_inode_bitmap(ctx->inode_used_map, i)) || - (ctx->inode_imagic_map && - ext2fs_test_inode_bitmap(ctx->inode_imagic_map, i))) - continue; - ext2fs_icount_fetch(ctx->inode_link_info, i, &link_count); - ext2fs_icount_fetch(ctx->inode_count, i, &link_counted); - if (link_counted == 0) { - if (!buf) - buf = e2fsck_allocate_memory(ctx, - fs->blocksize, "bad_inode buffer"); - if (e2fsck_process_bad_inode(ctx, 0, i, buf)) - continue; - if (disconnect_inode(ctx, i)) - continue; - ext2fs_icount_fetch(ctx->inode_link_info, i, - &link_count); - ext2fs_icount_fetch(ctx->inode_count, i, - &link_counted); - } - if (link_counted != link_count) { - e2fsck_read_inode(ctx, i, &inode, "pass4"); - pctx.ino = i; - pctx.inode = &inode; - if (link_count != inode.i_links_count) { - pctx.num = link_count; - fix_problem(ctx, - PR_4_INCONSISTENT_COUNT, &pctx); - } - pctx.num = link_counted; - if (fix_problem(ctx, PR_4_BAD_REF_COUNT, &pctx)) { - inode.i_links_count = link_counted; - e2fsck_write_inode(ctx, i, &inode, "pass4"); - } - } - } - ext2fs_free_icount(ctx->inode_link_info); ctx->inode_link_info = 0; - ext2fs_free_icount(ctx->inode_count); ctx->inode_count = 0; - ext2fs_free_inode_bitmap(ctx->inode_imagic_map); - ctx->inode_imagic_map = 0; - ext2fs_free_mem(&buf); -} - -/* - * pass5.c --- check block and inode bitmaps against on-disk bitmaps - */ - -#define NO_BLK ((blk_t) -1) - -static void print_bitmap_problem(e2fsck_t ctx, int problem, - struct problem_context *pctx) -{ - switch (problem) { - case PR_5_BLOCK_UNUSED: - if (pctx->blk == pctx->blk2) - pctx->blk2 = 0; - else - problem = PR_5_BLOCK_RANGE_UNUSED; - break; - case PR_5_BLOCK_USED: - if (pctx->blk == pctx->blk2) - pctx->blk2 = 0; - else - problem = PR_5_BLOCK_RANGE_USED; - break; - case PR_5_INODE_UNUSED: - if (pctx->ino == pctx->ino2) - pctx->ino2 = 0; - else - problem = PR_5_INODE_RANGE_UNUSED; - break; - case PR_5_INODE_USED: - if (pctx->ino == pctx->ino2) - pctx->ino2 = 0; - else - problem = PR_5_INODE_RANGE_USED; - break; - } - fix_problem(ctx, problem, pctx); - pctx->blk = pctx->blk2 = NO_BLK; - pctx->ino = pctx->ino2 = 0; -} - -static void check_block_bitmaps(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - blk_t i; - int *free_array; - int group = 0; - unsigned int blocks = 0; - unsigned int free_blocks = 0; - int group_free = 0; - int actual, bitmap; - struct problem_context pctx; - int problem, save_problem, fixit, had_problem; - errcode_t retval; - - clear_problem_context(&pctx); - free_array = (int *) e2fsck_allocate_memory(ctx, - fs->group_desc_count * sizeof(int), "free block count array"); - - if ((fs->super->s_first_data_block < - ext2fs_get_block_bitmap_start(ctx->block_found_map)) || - (fs->super->s_blocks_count-1 > - ext2fs_get_block_bitmap_end(ctx->block_found_map))) { - pctx.num = 1; - pctx.blk = fs->super->s_first_data_block; - pctx.blk2 = fs->super->s_blocks_count -1; - pctx.ino = ext2fs_get_block_bitmap_start(ctx->block_found_map); - pctx.ino2 = ext2fs_get_block_bitmap_end(ctx->block_found_map); - fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); - - ctx->flags |= E2F_FLAG_ABORT; /* fatal */ - return; - } - - if ((fs->super->s_first_data_block < - ext2fs_get_block_bitmap_start(fs->block_map)) || - (fs->super->s_blocks_count-1 > - ext2fs_get_block_bitmap_end(fs->block_map))) { - pctx.num = 2; - pctx.blk = fs->super->s_first_data_block; - pctx.blk2 = fs->super->s_blocks_count -1; - pctx.ino = ext2fs_get_block_bitmap_start(fs->block_map); - pctx.ino2 = ext2fs_get_block_bitmap_end(fs->block_map); - fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); - - ctx->flags |= E2F_FLAG_ABORT; /* fatal */ - return; - } - -redo_counts: - had_problem = 0; - save_problem = 0; - pctx.blk = pctx.blk2 = NO_BLK; - for (i = fs->super->s_first_data_block; - i < fs->super->s_blocks_count; - i++) { - actual = ext2fs_fast_test_block_bitmap(ctx->block_found_map, i); - bitmap = ext2fs_fast_test_block_bitmap(fs->block_map, i); - - if (actual == bitmap) - goto do_counts; - - if (!actual && bitmap) { - /* - * Block not used, but marked in use in the bitmap. - */ - problem = PR_5_BLOCK_UNUSED; - } else { - /* - * Block used, but not marked in use in the bitmap. - */ - problem = PR_5_BLOCK_USED; - } - if (pctx.blk == NO_BLK) { - pctx.blk = pctx.blk2 = i; - save_problem = problem; - } else { - if ((problem == save_problem) && - (pctx.blk2 == i-1)) - pctx.blk2++; - else { - print_bitmap_problem(ctx, save_problem, &pctx); - pctx.blk = pctx.blk2 = i; - save_problem = problem; - } - } - ctx->flags |= E2F_FLAG_PROG_SUPPRESS; - had_problem++; - - do_counts: - if (!bitmap) { - group_free++; - free_blocks++; - } - blocks ++; - if ((blocks == fs->super->s_blocks_per_group) || - (i == fs->super->s_blocks_count-1)) { - free_array[group] = group_free; - group ++; - blocks = 0; - group_free = 0; - if (ctx->progress) - if ((ctx->progress)(ctx, 5, group, - fs->group_desc_count*2)) - return; - } - } - if (pctx.blk != NO_BLK) - print_bitmap_problem(ctx, save_problem, &pctx); - if (had_problem) - fixit = end_problem_latch(ctx, PR_LATCH_BBITMAP); - else - fixit = -1; - ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS; - - if (fixit == 1) { - ext2fs_free_block_bitmap(fs->block_map); - retval = ext2fs_copy_bitmap(ctx->block_found_map, - &fs->block_map); - if (retval) { - clear_problem_context(&pctx); - fix_problem(ctx, PR_5_COPY_BBITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - ext2fs_set_bitmap_padding(fs->block_map); - ext2fs_mark_bb_dirty(fs); - - /* Redo the counts */ - blocks = 0; free_blocks = 0; group_free = 0; group = 0; - memset(free_array, 0, fs->group_desc_count * sizeof(int)); - goto redo_counts; - } else if (fixit == 0) - ext2fs_unmark_valid(fs); - - for (i = 0; i < fs->group_desc_count; i++) { - if (free_array[i] != fs->group_desc[i].bg_free_blocks_count) { - pctx.group = i; - pctx.blk = fs->group_desc[i].bg_free_blocks_count; - pctx.blk2 = free_array[i]; - - if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT_GROUP, - &pctx)) { - fs->group_desc[i].bg_free_blocks_count = - free_array[i]; - ext2fs_mark_super_dirty(fs); - } else - ext2fs_unmark_valid(fs); - } - } - if (free_blocks != fs->super->s_free_blocks_count) { - pctx.group = 0; - pctx.blk = fs->super->s_free_blocks_count; - pctx.blk2 = free_blocks; - - if (fix_problem(ctx, PR_5_FREE_BLOCK_COUNT, &pctx)) { - fs->super->s_free_blocks_count = free_blocks; - ext2fs_mark_super_dirty(fs); - } else - ext2fs_unmark_valid(fs); - } - ext2fs_free_mem(&free_array); -} - -static void check_inode_bitmaps(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - ext2_ino_t i; - unsigned int free_inodes = 0; - int group_free = 0; - int dirs_count = 0; - int group = 0; - unsigned int inodes = 0; - int *free_array; - int *dir_array; - int actual, bitmap; - errcode_t retval; - struct problem_context pctx; - int problem, save_problem, fixit, had_problem; - - clear_problem_context(&pctx); - free_array = (int *) e2fsck_allocate_memory(ctx, - fs->group_desc_count * sizeof(int), "free inode count array"); - - dir_array = (int *) e2fsck_allocate_memory(ctx, - fs->group_desc_count * sizeof(int), "directory count array"); - - if ((1 < ext2fs_get_inode_bitmap_start(ctx->inode_used_map)) || - (fs->super->s_inodes_count > - ext2fs_get_inode_bitmap_end(ctx->inode_used_map))) { - pctx.num = 3; - pctx.blk = 1; - pctx.blk2 = fs->super->s_inodes_count; - pctx.ino = ext2fs_get_inode_bitmap_start(ctx->inode_used_map); - pctx.ino2 = ext2fs_get_inode_bitmap_end(ctx->inode_used_map); - fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); - - ctx->flags |= E2F_FLAG_ABORT; /* fatal */ - return; - } - if ((1 < ext2fs_get_inode_bitmap_start(fs->inode_map)) || - (fs->super->s_inodes_count > - ext2fs_get_inode_bitmap_end(fs->inode_map))) { - pctx.num = 4; - pctx.blk = 1; - pctx.blk2 = fs->super->s_inodes_count; - pctx.ino = ext2fs_get_inode_bitmap_start(fs->inode_map); - pctx.ino2 = ext2fs_get_inode_bitmap_end(fs->inode_map); - fix_problem(ctx, PR_5_BMAP_ENDPOINTS, &pctx); - - ctx->flags |= E2F_FLAG_ABORT; /* fatal */ - return; - } - -redo_counts: - had_problem = 0; - save_problem = 0; - pctx.ino = pctx.ino2 = 0; - for (i = 1; i <= fs->super->s_inodes_count; i++) { - actual = ext2fs_fast_test_inode_bitmap(ctx->inode_used_map, i); - bitmap = ext2fs_fast_test_inode_bitmap(fs->inode_map, i); - - if (actual == bitmap) - goto do_counts; - - if (!actual && bitmap) { - /* - * Inode wasn't used, but marked in bitmap - */ - problem = PR_5_INODE_UNUSED; - } else /* if (actual && !bitmap) */ { - /* - * Inode used, but not in bitmap - */ - problem = PR_5_INODE_USED; - } - if (pctx.ino == 0) { - pctx.ino = pctx.ino2 = i; - save_problem = problem; - } else { - if ((problem == save_problem) && - (pctx.ino2 == i-1)) - pctx.ino2++; - else { - print_bitmap_problem(ctx, save_problem, &pctx); - pctx.ino = pctx.ino2 = i; - save_problem = problem; - } - } - ctx->flags |= E2F_FLAG_PROG_SUPPRESS; - had_problem++; - -do_counts: - if (!bitmap) { - group_free++; - free_inodes++; - } else { - if (ext2fs_test_inode_bitmap(ctx->inode_dir_map, i)) - dirs_count++; - } - inodes++; - if ((inodes == fs->super->s_inodes_per_group) || - (i == fs->super->s_inodes_count)) { - free_array[group] = group_free; - dir_array[group] = dirs_count; - group ++; - inodes = 0; - group_free = 0; - dirs_count = 0; - if (ctx->progress) - if ((ctx->progress)(ctx, 5, - group + fs->group_desc_count, - fs->group_desc_count*2)) - return; - } - } - if (pctx.ino) - print_bitmap_problem(ctx, save_problem, &pctx); - - if (had_problem) - fixit = end_problem_latch(ctx, PR_LATCH_IBITMAP); - else - fixit = -1; - ctx->flags &= ~E2F_FLAG_PROG_SUPPRESS; - - if (fixit == 1) { - ext2fs_free_inode_bitmap(fs->inode_map); - retval = ext2fs_copy_bitmap(ctx->inode_used_map, - &fs->inode_map); - if (retval) { - clear_problem_context(&pctx); - fix_problem(ctx, PR_5_COPY_IBITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - ext2fs_set_bitmap_padding(fs->inode_map); - ext2fs_mark_ib_dirty(fs); - - /* redo counts */ - inodes = 0; free_inodes = 0; group_free = 0; - dirs_count = 0; group = 0; - memset(free_array, 0, fs->group_desc_count * sizeof(int)); - memset(dir_array, 0, fs->group_desc_count * sizeof(int)); - goto redo_counts; - } else if (fixit == 0) - ext2fs_unmark_valid(fs); - - for (i = 0; i < fs->group_desc_count; i++) { - if (free_array[i] != fs->group_desc[i].bg_free_inodes_count) { - pctx.group = i; - pctx.ino = fs->group_desc[i].bg_free_inodes_count; - pctx.ino2 = free_array[i]; - if (fix_problem(ctx, PR_5_FREE_INODE_COUNT_GROUP, - &pctx)) { - fs->group_desc[i].bg_free_inodes_count = - free_array[i]; - ext2fs_mark_super_dirty(fs); - } else - ext2fs_unmark_valid(fs); - } - if (dir_array[i] != fs->group_desc[i].bg_used_dirs_count) { - pctx.group = i; - pctx.ino = fs->group_desc[i].bg_used_dirs_count; - pctx.ino2 = dir_array[i]; - - if (fix_problem(ctx, PR_5_FREE_DIR_COUNT_GROUP, - &pctx)) { - fs->group_desc[i].bg_used_dirs_count = - dir_array[i]; - ext2fs_mark_super_dirty(fs); - } else - ext2fs_unmark_valid(fs); - } - } - if (free_inodes != fs->super->s_free_inodes_count) { - pctx.group = -1; - pctx.ino = fs->super->s_free_inodes_count; - pctx.ino2 = free_inodes; - - if (fix_problem(ctx, PR_5_FREE_INODE_COUNT, &pctx)) { - fs->super->s_free_inodes_count = free_inodes; - ext2fs_mark_super_dirty(fs); - } else - ext2fs_unmark_valid(fs); - } - ext2fs_free_mem(&free_array); - ext2fs_free_mem(&dir_array); -} - -static void check_inode_end(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - ext2_ino_t end, save_inodes_count, i; - struct problem_context pctx; - - clear_problem_context(&pctx); - - end = EXT2_INODES_PER_GROUP(fs->super) * fs->group_desc_count; - pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, end, - &save_inodes_count); - if (pctx.errcode) { - pctx.num = 1; - fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; /* fatal */ - return; - } - if (save_inodes_count == end) - return; - - for (i = save_inodes_count + 1; i <= end; i++) { - if (!ext2fs_test_inode_bitmap(fs->inode_map, i)) { - if (fix_problem(ctx, PR_5_INODE_BMAP_PADDING, &pctx)) { - for (i = save_inodes_count + 1; i <= end; i++) - ext2fs_mark_inode_bitmap(fs->inode_map, - i); - ext2fs_mark_ib_dirty(fs); - } else - ext2fs_unmark_valid(fs); - break; - } - } - - pctx.errcode = ext2fs_fudge_inode_bitmap_end(fs->inode_map, - save_inodes_count, 0); - if (pctx.errcode) { - pctx.num = 2; - fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; /* fatal */ - return; - } -} - -static void check_block_end(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - blk_t end, save_blocks_count, i; - struct problem_context pctx; - - clear_problem_context(&pctx); - - end = fs->block_map->start + - (EXT2_BLOCKS_PER_GROUP(fs->super) * fs->group_desc_count) - 1; - pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, end, - &save_blocks_count); - if (pctx.errcode) { - pctx.num = 3; - fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; /* fatal */ - return; - } - if (save_blocks_count == end) - return; - - for (i = save_blocks_count + 1; i <= end; i++) { - if (!ext2fs_test_block_bitmap(fs->block_map, i)) { - if (fix_problem(ctx, PR_5_BLOCK_BMAP_PADDING, &pctx)) { - for (i = save_blocks_count + 1; i <= end; i++) - ext2fs_mark_block_bitmap(fs->block_map, - i); - ext2fs_mark_bb_dirty(fs); - } else - ext2fs_unmark_valid(fs); - break; - } - } - - pctx.errcode = ext2fs_fudge_block_bitmap_end(fs->block_map, - save_blocks_count, 0); - if (pctx.errcode) { - pctx.num = 4; - fix_problem(ctx, PR_5_FUDGE_BITMAP_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; /* fatal */ - return; - } -} - -static void e2fsck_pass5(e2fsck_t ctx) -{ - struct problem_context pctx; - - /* Pass 5 */ - - clear_problem_context(&pctx); - - if (!(ctx->options & E2F_OPT_PREEN)) - fix_problem(ctx, PR_5_PASS_HEADER, &pctx); - - if (ctx->progress) - if ((ctx->progress)(ctx, 5, 0, ctx->fs->group_desc_count*2)) - return; - - e2fsck_read_bitmaps(ctx); - - check_block_bitmaps(ctx); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - check_inode_bitmaps(ctx); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - check_inode_end(ctx); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - check_block_end(ctx); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - - ext2fs_free_inode_bitmap(ctx->inode_used_map); - ctx->inode_used_map = 0; - ext2fs_free_inode_bitmap(ctx->inode_dir_map); - ctx->inode_dir_map = 0; - ext2fs_free_block_bitmap(ctx->block_found_map); - ctx->block_found_map = 0; -} - -/* - * problem.c --- report filesystem problems to the user - */ - -#define PR_PREEN_OK 0x000001 /* Don't need to do preenhalt */ -#define PR_NO_OK 0x000002 /* If user answers no, don't make fs invalid */ -#define PR_NO_DEFAULT 0x000004 /* Default to no */ -#define PR_MSG_ONLY 0x000008 /* Print message only */ - -/* Bit positions 0x000ff0 are reserved for the PR_LATCH flags */ - -#define PR_FATAL 0x001000 /* Fatal error */ -#define PR_AFTER_CODE 0x002000 /* After asking the first question, */ - /* ask another */ -#define PR_PREEN_NOMSG 0x004000 /* Don't print a message if we're preening */ -#define PR_NOCOLLATE 0x008000 /* Don't collate answers for this latch */ -#define PR_NO_NOMSG 0x010000 /* Don't print a message if e2fsck -n */ -#define PR_PREEN_NO 0x020000 /* Use No as an answer if preening */ -#define PR_PREEN_NOHDR 0x040000 /* Don't print the preen header */ - - -#define PROMPT_NONE 0 -#define PROMPT_FIX 1 -#define PROMPT_CLEAR 2 -#define PROMPT_RELOCATE 3 -#define PROMPT_ALLOCATE 4 -#define PROMPT_EXPAND 5 -#define PROMPT_CONNECT 6 -#define PROMPT_CREATE 7 -#define PROMPT_SALVAGE 8 -#define PROMPT_TRUNCATE 9 -#define PROMPT_CLEAR_INODE 10 -#define PROMPT_ABORT 11 -#define PROMPT_SPLIT 12 -#define PROMPT_CONTINUE 13 -#define PROMPT_CLONE 14 -#define PROMPT_DELETE 15 -#define PROMPT_SUPPRESS 16 -#define PROMPT_UNLINK 17 -#define PROMPT_CLEAR_HTREE 18 -#define PROMPT_RECREATE 19 -#define PROMPT_NULL 20 - -struct e2fsck_problem { - problem_t e2p_code; - const char * e2p_description; - char prompt; - int flags; - problem_t second_code; -}; - -struct latch_descr { - int latch_code; - problem_t question; - problem_t end_message; - int flags; -}; - -/* - * These are the prompts which are used to ask the user if they want - * to fix a problem. - */ -static const char *const prompt[] = { - N_("(no prompt)"), /* 0 */ - N_("Fix"), /* 1 */ - N_("Clear"), /* 2 */ - N_("Relocate"), /* 3 */ - N_("Allocate"), /* 4 */ - N_("Expand"), /* 5 */ - N_("Connect to /lost+found"), /* 6 */ - N_("Create"), /* 7 */ - N_("Salvage"), /* 8 */ - N_("Truncate"), /* 9 */ - N_("Clear inode"), /* 10 */ - N_("Abort"), /* 11 */ - N_("Split"), /* 12 */ - N_("Continue"), /* 13 */ - N_("Clone multiply-claimed blocks"), /* 14 */ - N_("Delete file"), /* 15 */ - N_("Suppress messages"),/* 16 */ - N_("Unlink"), /* 17 */ - N_("Clear HTree index"),/* 18 */ - N_("Recreate"), /* 19 */ - "", /* 20 */ -}; - -/* - * These messages are printed when we are preen mode and we will be - * automatically fixing the problem. - */ -static const char *const preen_msg[] = { - N_("(NONE)"), /* 0 */ - N_("FIXED"), /* 1 */ - N_("CLEARED"), /* 2 */ - N_("RELOCATED"), /* 3 */ - N_("ALLOCATED"), /* 4 */ - N_("EXPANDED"), /* 5 */ - N_("RECONNECTED"), /* 6 */ - N_("CREATED"), /* 7 */ - N_("SALVAGED"), /* 8 */ - N_("TRUNCATED"), /* 9 */ - N_("INODE CLEARED"), /* 10 */ - N_("ABORTED"), /* 11 */ - N_("SPLIT"), /* 12 */ - N_("CONTINUING"), /* 13 */ - N_("MULTIPLY-CLAIMED BLOCKS CLONED"), /* 14 */ - N_("FILE DELETED"), /* 15 */ - N_("SUPPRESSED"), /* 16 */ - N_("UNLINKED"), /* 17 */ - N_("HTREE INDEX CLEARED"),/* 18 */ - N_("WILL RECREATE"), /* 19 */ - "", /* 20 */ -}; - -static const struct e2fsck_problem problem_table[] = { - - /* Pre-Pass 1 errors */ - - /* Block bitmap not in group */ - { PR_0_BB_NOT_GROUP, N_("@b @B for @g %g is not in @g. (@b %b)\n"), - PROMPT_RELOCATE, PR_LATCH_RELOC }, - - /* Inode bitmap not in group */ - { PR_0_IB_NOT_GROUP, N_("@i @B for @g %g is not in @g. (@b %b)\n"), - PROMPT_RELOCATE, PR_LATCH_RELOC }, - - /* Inode table not in group */ - { PR_0_ITABLE_NOT_GROUP, - N_("@i table for @g %g is not in @g. (@b %b)\n" - "WARNING: SEVERE DATA LOSS POSSIBLE.\n"), - PROMPT_RELOCATE, PR_LATCH_RELOC }, - - /* Superblock corrupt */ - { PR_0_SB_CORRUPT, - N_("\nThe @S could not be read or does not describe a correct ext2\n" - "@f. If the @v is valid and it really contains an ext2\n" - "@f (and not swap or ufs or something else), then the @S\n" - "is corrupt, and you might try running e2fsck with an alternate @S:\n" - " e2fsck -b %S <@v>\n\n"), - PROMPT_NONE, PR_FATAL }, - - /* Filesystem size is wrong */ - { PR_0_FS_SIZE_WRONG, - N_("The @f size (according to the @S) is %b @bs\n" - "The physical size of the @v is %c @bs\n" - "Either the @S or the partition table is likely to be corrupt!\n"), - PROMPT_ABORT, 0 }, - - /* Fragments not supported */ - { PR_0_NO_FRAGMENTS, - N_("@S @b_size = %b, fragsize = %c.\n" - "This version of e2fsck does not support fragment sizes different\n" - "from the @b size.\n"), - PROMPT_NONE, PR_FATAL }, - - /* Bad blocks_per_group */ - { PR_0_BLOCKS_PER_GROUP, - N_("@S @bs_per_group = %b, should have been %c\n"), - PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT }, - - /* Bad first_data_block */ - { PR_0_FIRST_DATA_BLOCK, - N_("@S first_data_@b = %b, should have been %c\n"), - PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT }, - - /* Adding UUID to filesystem */ - { PR_0_ADD_UUID, - N_("@f did not have a UUID; generating one.\n\n"), - PROMPT_NONE, 0 }, - - /* Relocate hint */ - { PR_0_RELOCATE_HINT, - N_("Note: if several inode or block bitmap blocks or part\n" - "of the inode table require relocation, you may wish to try\n" - "running e2fsck with the '-b %S' option first. The problem\n" - "may lie only with the primary block group descriptors, and\n" - "the backup block group descriptors may be OK.\n\n"), - PROMPT_NONE, PR_PREEN_OK | PR_NOCOLLATE }, - - /* Miscellaneous superblock corruption */ - { PR_0_MISC_CORRUPT_SUPER, - N_("Corruption found in @S. (%s = %N).\n"), - PROMPT_NONE, PR_AFTER_CODE, PR_0_SB_CORRUPT }, - - /* Error determing physical device size of filesystem */ - { PR_0_GETSIZE_ERROR, - N_("Error determining size of the physical @v: %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Inode count in superblock is incorrect */ - { PR_0_INODE_COUNT_WRONG, - N_("@i count in @S is %i, @s %j.\n"), - PROMPT_FIX, 0 }, - - { PR_0_HURD_CLEAR_FILETYPE, - N_("The Hurd does not support the filetype feature.\n"), - PROMPT_CLEAR, 0 }, - - /* Journal inode is invalid */ - { PR_0_JOURNAL_BAD_INODE, - N_("@S has an @n ext3 @j (@i %i).\n"), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* The external journal has (unsupported) multiple filesystems */ - { PR_0_JOURNAL_UNSUPP_MULTIFS, - N_("External @j has multiple @f users (unsupported).\n"), - PROMPT_NONE, PR_FATAL }, - - /* Can't find external journal */ - { PR_0_CANT_FIND_JOURNAL, - N_("Can't find external @j\n"), - PROMPT_NONE, PR_FATAL }, - - /* External journal has bad superblock */ - { PR_0_EXT_JOURNAL_BAD_SUPER, - N_("External @j has bad @S\n"), - PROMPT_NONE, PR_FATAL }, - - /* Superblock has a bad journal UUID */ - { PR_0_JOURNAL_BAD_UUID, - N_("External @j does not support this @f\n"), - PROMPT_NONE, PR_FATAL }, - - /* Journal has an unknown superblock type */ - { PR_0_JOURNAL_UNSUPP_SUPER, - N_("Ext3 @j @S is unknown type %N (unsupported).\n" - "It is likely that your copy of e2fsck is old and/or doesn't " - "support this @j format.\n" - "It is also possible the @j @S is corrupt.\n"), - PROMPT_ABORT, PR_NO_OK | PR_AFTER_CODE, PR_0_JOURNAL_BAD_SUPER }, - - /* Journal superblock is corrupt */ - { PR_0_JOURNAL_BAD_SUPER, - N_("Ext3 @j @S is corrupt.\n"), - PROMPT_FIX, PR_PREEN_OK }, - - /* Superblock flag should be cleared */ - { PR_0_JOURNAL_HAS_JOURNAL, - N_("@S doesn't have has_@j flag, but has ext3 @j %s.\n"), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* Superblock flag is incorrect */ - { PR_0_JOURNAL_RECOVER_SET, - N_("@S has ext3 needs_recovery flag set, but no @j.\n"), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* Journal has data, but recovery flag is clear */ - { PR_0_JOURNAL_RECOVERY_CLEAR, - N_("ext3 recovery flag is clear, but @j has data.\n"), - PROMPT_NONE, 0 }, - - /* Ask if we should clear the journal */ - { PR_0_JOURNAL_RESET_JOURNAL, - N_("Clear @j"), - PROMPT_NULL, PR_PREEN_NOMSG }, - - /* Ask if we should run the journal anyway */ - { PR_0_JOURNAL_RUN, - N_("Run @j anyway"), - PROMPT_NULL, 0 }, - - /* Run the journal by default */ - { PR_0_JOURNAL_RUN_DEFAULT, - N_("Recovery flag not set in backup @S, so running @j anyway.\n"), - PROMPT_NONE, 0 }, - - /* Clearing orphan inode */ - { PR_0_ORPHAN_CLEAR_INODE, - N_("%s @o @i %i (uid=%Iu, gid=%Ig, mode=%Im, size=%Is)\n"), - PROMPT_NONE, 0 }, - - /* Illegal block found in orphaned inode */ - { PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, - N_("@I @b #%B (%b) found in @o @i %i.\n"), - PROMPT_NONE, 0 }, - - /* Already cleared block found in orphaned inode */ - { PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, - N_("Already cleared @b #%B (%b) found in @o @i %i.\n"), - PROMPT_NONE, 0 }, - - /* Illegal orphan inode in superblock */ - { PR_0_ORPHAN_ILLEGAL_HEAD_INODE, - N_("@I @o @i %i in @S.\n"), - PROMPT_NONE, 0 }, - - /* Illegal inode in orphaned inode list */ - { PR_0_ORPHAN_ILLEGAL_INODE, - N_("@I @i %i in @o @i list.\n"), - PROMPT_NONE, 0 }, - - /* Filesystem revision is 0, but feature flags are set */ - { PR_0_FS_REV_LEVEL, - N_("@f has feature flag(s) set, but is a revision 0 @f. "), - PROMPT_FIX, PR_PREEN_OK | PR_NO_OK }, - - /* Journal superblock has an unknown read-only feature flag set */ - { PR_0_JOURNAL_UNSUPP_ROCOMPAT, - N_("Ext3 @j @S has an unknown read-only feature flag set.\n"), - PROMPT_ABORT, 0 }, - - /* Journal superblock has an unknown incompatible feature flag set */ - { PR_0_JOURNAL_UNSUPP_INCOMPAT, - N_("Ext3 @j @S has an unknown incompatible feature flag set.\n"), - PROMPT_ABORT, 0 }, - - /* Journal has unsupported version number */ - { PR_0_JOURNAL_UNSUPP_VERSION, - N_("@j version not supported by this e2fsck.\n"), - PROMPT_ABORT, 0 }, - - /* Moving journal to hidden file */ - { PR_0_MOVE_JOURNAL, - N_("Moving @j from /%s to hidden @i.\n\n"), - PROMPT_NONE, 0 }, - - /* Error moving journal to hidden file */ - { PR_0_ERR_MOVE_JOURNAL, - N_("Error moving @j: %m\n\n"), - PROMPT_NONE, 0 }, - - /* Clearing V2 journal superblock */ - { PR_0_CLEAR_V2_JOURNAL, - N_("Found @n V2 @j @S fields (from V1 @j).\n" - "Clearing fields beyond the V1 @j @S...\n\n"), - PROMPT_NONE, 0 }, - - /* Backup journal inode blocks */ - { PR_0_BACKUP_JNL, - N_("Backing up @j @i @b information.\n\n"), - PROMPT_NONE, 0 }, - - /* Reserved blocks w/o resize_inode */ - { PR_0_NONZERO_RESERVED_GDT_BLOCKS, - N_("@f does not have resize_@i enabled, but s_reserved_gdt_@bs\n" - "is %N; @s zero. "), - PROMPT_FIX, 0 }, - - /* Resize_inode not enabled, but resize inode is non-zero */ - { PR_0_CLEAR_RESIZE_INODE, - N_("Resize_@i not enabled, but the resize @i is non-zero. "), - PROMPT_CLEAR, 0 }, - - /* Resize inode invalid */ - { PR_0_RESIZE_INODE_INVALID, - N_("Resize @i not valid. "), - PROMPT_RECREATE, 0 }, - - /* Pass 1 errors */ - - /* Pass 1: Checking inodes, blocks, and sizes */ - { PR_1_PASS_HEADER, - N_("Pass 1: Checking @is, @bs, and sizes\n"), - PROMPT_NONE, 0 }, - - /* Root directory is not an inode */ - { PR_1_ROOT_NO_DIR, N_("@r is not a @d. "), - PROMPT_CLEAR, 0 }, - - /* Root directory has dtime set */ - { PR_1_ROOT_DTIME, - N_("@r has dtime set (probably due to old mke2fs). "), - PROMPT_FIX, PR_PREEN_OK }, - - /* Reserved inode has bad mode */ - { PR_1_RESERVED_BAD_MODE, - N_("Reserved @i %i (%Q) has @n mode. "), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* Deleted inode has zero dtime */ - { PR_1_ZERO_DTIME, - N_("@D @i %i has zero dtime. "), - PROMPT_FIX, PR_PREEN_OK }, - - /* Inode in use, but dtime set */ - { PR_1_SET_DTIME, - N_("@i %i is in use, but has dtime set. "), - PROMPT_FIX, PR_PREEN_OK }, - - /* Zero-length directory */ - { PR_1_ZERO_LENGTH_DIR, - N_("@i %i is a @z @d. "), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* Block bitmap conflicts with some other fs block */ - { PR_1_BB_CONFLICT, - N_("@g %g's @b @B at %b @C.\n"), - PROMPT_RELOCATE, 0 }, - - /* Inode bitmap conflicts with some other fs block */ - { PR_1_IB_CONFLICT, - N_("@g %g's @i @B at %b @C.\n"), - PROMPT_RELOCATE, 0 }, - - /* Inode table conflicts with some other fs block */ - { PR_1_ITABLE_CONFLICT, - N_("@g %g's @i table at %b @C.\n"), - PROMPT_RELOCATE, 0 }, - - /* Block bitmap is on a bad block */ - { PR_1_BB_BAD_BLOCK, - N_("@g %g's @b @B (%b) is bad. "), - PROMPT_RELOCATE, 0 }, - - /* Inode bitmap is on a bad block */ - { PR_1_IB_BAD_BLOCK, - N_("@g %g's @i @B (%b) is bad. "), - PROMPT_RELOCATE, 0 }, - - /* Inode has incorrect i_size */ - { PR_1_BAD_I_SIZE, - N_("@i %i, i_size is %Is, @s %N. "), - PROMPT_FIX, PR_PREEN_OK }, - - /* Inode has incorrect i_blocks */ - { PR_1_BAD_I_BLOCKS, - N_("@i %i, i_@bs is %Ib, @s %N. "), - PROMPT_FIX, PR_PREEN_OK }, - - /* Illegal blocknumber in inode */ - { PR_1_ILLEGAL_BLOCK_NUM, - N_("@I @b #%B (%b) in @i %i. "), - PROMPT_CLEAR, PR_LATCH_BLOCK }, - - /* Block number overlaps fs metadata */ - { PR_1_BLOCK_OVERLAPS_METADATA, - N_("@b #%B (%b) overlaps @f metadata in @i %i. "), - PROMPT_CLEAR, PR_LATCH_BLOCK }, - - /* Inode has illegal blocks (latch question) */ - { PR_1_INODE_BLOCK_LATCH, - N_("@i %i has illegal @b(s). "), - PROMPT_CLEAR, 0 }, - - /* Too many bad blocks in inode */ - { PR_1_TOO_MANY_BAD_BLOCKS, - N_("Too many illegal @bs in @i %i.\n"), - PROMPT_CLEAR_INODE, PR_NO_OK }, - - /* Illegal block number in bad block inode */ - { PR_1_BB_ILLEGAL_BLOCK_NUM, - N_("@I @b #%B (%b) in bad @b @i. "), - PROMPT_CLEAR, PR_LATCH_BBLOCK }, - - /* Bad block inode has illegal blocks (latch question) */ - { PR_1_INODE_BBLOCK_LATCH, - N_("Bad @b @i has illegal @b(s). "), - PROMPT_CLEAR, 0 }, - - /* Duplicate or bad blocks in use! */ - { PR_1_DUP_BLOCKS_PREENSTOP, - N_("Duplicate or bad @b in use!\n"), - PROMPT_NONE, 0 }, - - /* Bad block used as bad block indirect block */ - { PR_1_BBINODE_BAD_METABLOCK, - N_("Bad @b %b used as bad @b @i indirect @b. "), - PROMPT_CLEAR, PR_LATCH_BBLOCK }, - - /* Inconsistency can't be fixed prompt */ - { PR_1_BBINODE_BAD_METABLOCK_PROMPT, - N_("\nThe bad @b @i has probably been corrupted. You probably\n" - "should stop now and run ""e2fsck -c"" to scan for bad blocks\n" - "in the @f.\n"), - PROMPT_CONTINUE, PR_PREEN_NOMSG }, - - /* Bad primary block */ - { PR_1_BAD_PRIMARY_BLOCK, - N_("\nIf the @b is really bad, the @f cannot be fixed.\n"), - PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK_PROMPT }, - - /* Bad primary block prompt */ - { PR_1_BAD_PRIMARY_BLOCK_PROMPT, - N_("You can remove this @b from the bad @b list and hope\n" - "that the @b is really OK. But there are no guarantees.\n\n"), - PROMPT_CLEAR, PR_PREEN_NOMSG }, - - /* Bad primary superblock */ - { PR_1_BAD_PRIMARY_SUPERBLOCK, - N_("The primary @S (%b) is on the bad @b list.\n"), - PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK }, - - /* Bad primary block group descriptors */ - { PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR, - N_("Block %b in the primary @g descriptors " - "is on the bad @b list\n"), - PROMPT_NONE, PR_AFTER_CODE, PR_1_BAD_PRIMARY_BLOCK }, - - /* Bad superblock in group */ - { PR_1_BAD_SUPERBLOCK, - N_("Warning: Group %g's @S (%b) is bad.\n"), - PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Bad block group descriptors in group */ - { PR_1_BAD_GROUP_DESCRIPTORS, - N_("Warning: Group %g's copy of the @g descriptors has a bad " - "@b (%b).\n"), - PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Block claimed for no reason */ - { PR_1_PROGERR_CLAIMED_BLOCK, - N_("Programming error? @b #%b claimed for no reason in " - "process_bad_@b.\n"), - PROMPT_NONE, PR_PREEN_OK }, - - /* Error allocating blocks for relocating metadata */ - { PR_1_RELOC_BLOCK_ALLOCATE, - N_("@A %N contiguous @b(s) in @b @g %g for %s: %m\n"), - PROMPT_NONE, PR_PREEN_OK }, - - /* Error allocating block buffer during relocation process */ - { PR_1_RELOC_MEMORY_ALLOCATE, - N_("@A @b buffer for relocating %s\n"), - PROMPT_NONE, PR_PREEN_OK }, - - /* Relocating metadata group information from X to Y */ - { PR_1_RELOC_FROM_TO, - N_("Relocating @g %g's %s from %b to %c...\n"), - PROMPT_NONE, PR_PREEN_OK }, - - /* Relocating metatdata group information to X */ - { PR_1_RELOC_TO, - N_("Relocating @g %g's %s to %c...\n"), /* xgettext:no-c-format */ - PROMPT_NONE, PR_PREEN_OK }, - - /* Block read error during relocation process */ - { PR_1_RELOC_READ_ERR, - N_("Warning: could not read @b %b of %s: %m\n"), - PROMPT_NONE, PR_PREEN_OK }, - - /* Block write error during relocation process */ - { PR_1_RELOC_WRITE_ERR, - N_("Warning: could not write @b %b for %s: %m\n"), - PROMPT_NONE, PR_PREEN_OK }, - - /* Error allocating inode bitmap */ - { PR_1_ALLOCATE_IBITMAP_ERROR, - N_("@A @i @B (%N): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error allocating block bitmap */ - { PR_1_ALLOCATE_BBITMAP_ERROR, - N_("@A @b @B (%N): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error allocating icount structure */ - { PR_1_ALLOCATE_ICOUNT, - N_("@A icount link information: %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error allocating dbcount */ - { PR_1_ALLOCATE_DBCOUNT, - N_("@A @d @b array: %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error while scanning inodes */ - { PR_1_ISCAN_ERROR, - N_("Error while scanning @is (%i): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error while iterating over blocks */ - { PR_1_BLOCK_ITERATE, - N_("Error while iterating over @bs in @i %i: %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error while storing inode count information */ - { PR_1_ICOUNT_STORE, - N_("Error storing @i count information (@i=%i, count=%N): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error while storing directory block information */ - { PR_1_ADD_DBLOCK, - N_("Error storing @d @b information " - "(@i=%i, @b=%b, num=%N): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error while reading inode (for clearing) */ - { PR_1_READ_INODE, - N_("Error reading @i %i: %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Suppress messages prompt */ - { PR_1_SUPPRESS_MESSAGES, "", PROMPT_SUPPRESS, PR_NO_OK }, - - /* Imagic flag set on an inode when filesystem doesn't support it */ - { PR_1_SET_IMAGIC, - N_("@i %i has imagic flag set. "), - PROMPT_CLEAR, 0 }, - - /* Immutable flag set on a device or socket inode */ - { PR_1_SET_IMMUTABLE, - N_("Special (@v/socket/fifo/symlink) file (@i %i) has immutable\n" - "or append-only flag set. "), - PROMPT_CLEAR, PR_PREEN_OK | PR_PREEN_NO | PR_NO_OK }, - - /* Compression flag set on an inode when filesystem doesn't support it */ - { PR_1_COMPR_SET, - N_("@i %i has @cion flag set on @f without @cion support. "), - PROMPT_CLEAR, 0 }, - - /* Non-zero size for device, fifo or socket inode */ - { PR_1_SET_NONZSIZE, - N_("Special (@v/socket/fifo) @i %i has non-zero size. "), - PROMPT_FIX, PR_PREEN_OK }, - - /* Filesystem revision is 0, but feature flags are set */ - { PR_1_FS_REV_LEVEL, - N_("@f has feature flag(s) set, but is a revision 0 @f. "), - PROMPT_FIX, PR_PREEN_OK | PR_NO_OK }, - - /* Journal inode is not in use, but contains data */ - { PR_1_JOURNAL_INODE_NOT_CLEAR, - N_("@j @i is not in use, but contains data. "), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* Journal has bad mode */ - { PR_1_JOURNAL_BAD_MODE, - N_("@j is not regular file. "), - PROMPT_FIX, PR_PREEN_OK }, - - /* Deal with inodes that were part of orphan linked list */ - { PR_1_LOW_DTIME, - N_("@i %i was part of the @o @i list. "), - PROMPT_FIX, PR_LATCH_LOW_DTIME, 0 }, - - /* Deal with inodes that were part of corrupted orphan linked - list (latch question) */ - { PR_1_ORPHAN_LIST_REFUGEES, - N_("@is that were part of a corrupted orphan linked list found. "), - PROMPT_FIX, 0 }, - - /* Error allocating refcount structure */ - { PR_1_ALLOCATE_REFCOUNT, - N_("@A refcount structure (%N): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error reading extended attribute block */ - { PR_1_READ_EA_BLOCK, - N_("Error reading @a @b %b for @i %i. "), - PROMPT_CLEAR, 0 }, - - /* Invalid extended attribute block */ - { PR_1_BAD_EA_BLOCK, - N_("@i %i has a bad @a @b %b. "), - PROMPT_CLEAR, 0 }, - - /* Error reading Extended Attribute block while fixing refcount */ - { PR_1_EXTATTR_READ_ABORT, - N_("Error reading @a @b %b (%m). "), - PROMPT_ABORT, 0 }, - - /* Extended attribute reference count incorrect */ - { PR_1_EXTATTR_REFCOUNT, - N_("@a @b %b has reference count %B, @s %N. "), - PROMPT_FIX, 0 }, - - /* Error writing Extended Attribute block while fixing refcount */ - { PR_1_EXTATTR_WRITE, - N_("Error writing @a @b %b (%m). "), - PROMPT_ABORT, 0 }, - - /* Multiple EA blocks not supported */ - { PR_1_EA_MULTI_BLOCK, - N_("@a @b %b has h_@bs > 1. "), - PROMPT_CLEAR, 0}, - - /* Error allocating EA region allocation structure */ - { PR_1_EA_ALLOC_REGION, - N_("@A @a @b %b. "), - PROMPT_ABORT, 0}, - - /* Error EA allocation collision */ - { PR_1_EA_ALLOC_COLLISION, - N_("@a @b %b is corrupt (allocation collision). "), - PROMPT_CLEAR, 0}, - - /* Bad extended attribute name */ - { PR_1_EA_BAD_NAME, - N_("@a @b %b is corrupt (@n name). "), - PROMPT_CLEAR, 0}, - - /* Bad extended attribute value */ - { PR_1_EA_BAD_VALUE, - N_("@a @b %b is corrupt (@n value). "), - PROMPT_CLEAR, 0}, - - /* Inode too big (latch question) */ - { PR_1_INODE_TOOBIG, - N_("@i %i is too big. "), PROMPT_TRUNCATE, 0 }, - - /* Directory too big */ - { PR_1_TOOBIG_DIR, - N_("@b #%B (%b) causes @d to be too big. "), - PROMPT_CLEAR, PR_LATCH_TOOBIG }, - - /* Regular file too big */ - { PR_1_TOOBIG_REG, - N_("@b #%B (%b) causes file to be too big. "), - PROMPT_CLEAR, PR_LATCH_TOOBIG }, - - /* Symlink too big */ - { PR_1_TOOBIG_SYMLINK, - N_("@b #%B (%b) causes symlink to be too big. "), - PROMPT_CLEAR, PR_LATCH_TOOBIG }, - - /* INDEX_FL flag set on a non-HTREE filesystem */ - { PR_1_HTREE_SET, - N_("@i %i has INDEX_FL flag set on @f without htree support.\n"), - PROMPT_CLEAR_HTREE, PR_PREEN_OK }, - - /* INDEX_FL flag set on a non-directory */ - { PR_1_HTREE_NODIR, - N_("@i %i has INDEX_FL flag set but is not a @d.\n"), - PROMPT_CLEAR_HTREE, PR_PREEN_OK }, - - /* Invalid root node in HTREE directory */ - { PR_1_HTREE_BADROOT, - N_("@h %i has an @n root node.\n"), - PROMPT_CLEAR_HTREE, PR_PREEN_OK }, - - /* Unsupported hash version in HTREE directory */ - { PR_1_HTREE_HASHV, - N_("@h %i has an unsupported hash version (%N)\n"), - PROMPT_CLEAR_HTREE, PR_PREEN_OK }, - - /* Incompatible flag in HTREE root node */ - { PR_1_HTREE_INCOMPAT, - N_("@h %i uses an incompatible htree root node flag.\n"), - PROMPT_CLEAR_HTREE, PR_PREEN_OK }, - - /* HTREE too deep */ - { PR_1_HTREE_DEPTH, - N_("@h %i has a tree depth (%N) which is too big\n"), - PROMPT_CLEAR_HTREE, PR_PREEN_OK }, - - /* Bad block has indirect block that conflicts with filesystem block */ - { PR_1_BB_FS_BLOCK, - N_("Bad @b @i has an indirect @b (%b) that conflicts with\n" - "@f metadata. "), - PROMPT_CLEAR, PR_LATCH_BBLOCK }, - - /* Resize inode failed */ - { PR_1_RESIZE_INODE_CREATE, - N_("Resize @i (re)creation failed: %m."), - PROMPT_ABORT, 0 }, - - /* invalid inode->i_extra_isize */ - { PR_1_EXTRA_ISIZE, - N_("@i %i has a extra size (%IS) which is @n\n"), - PROMPT_FIX, PR_PREEN_OK }, - - /* invalid ea entry->e_name_len */ - { PR_1_ATTR_NAME_LEN, - N_("@a in @i %i has a namelen (%N) which is @n\n"), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* invalid ea entry->e_value_size */ - { PR_1_ATTR_VALUE_SIZE, - N_("@a in @i %i has a value size (%N) which is @n\n"), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* invalid ea entry->e_value_offs */ - { PR_1_ATTR_VALUE_OFFSET, - N_("@a in @i %i has a value offset (%N) which is @n\n"), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* invalid ea entry->e_value_block */ - { PR_1_ATTR_VALUE_BLOCK, - N_("@a in @i %i has a value @b (%N) which is @n (must be 0)\n"), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* invalid ea entry->e_hash */ - { PR_1_ATTR_HASH, - N_("@a in @i %i has a hash (%N) which is @n (must be 0)\n"), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* Pass 1b errors */ - - /* Pass 1B: Rescan for duplicate/bad blocks */ - { PR_1B_PASS_HEADER, - N_("\nRunning additional passes to resolve @bs claimed by more than one @i...\n" - "Pass 1B: Rescanning for @m @bs\n"), - PROMPT_NONE, 0 }, - - /* Duplicate/bad block(s) header */ - { PR_1B_DUP_BLOCK_HEADER, - N_("@m @b(s) in @i %i:"), - PROMPT_NONE, 0 }, - - /* Duplicate/bad block(s) in inode */ - { PR_1B_DUP_BLOCK, - " %b", - PROMPT_NONE, PR_LATCH_DBLOCK | PR_PREEN_NOHDR }, - - /* Duplicate/bad block(s) end */ - { PR_1B_DUP_BLOCK_END, - "\n", - PROMPT_NONE, PR_PREEN_NOHDR }, - - /* Error while scanning inodes */ - { PR_1B_ISCAN_ERROR, - N_("Error while scanning inodes (%i): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error allocating inode bitmap */ - { PR_1B_ALLOCATE_IBITMAP_ERROR, - N_("@A @i @B (@i_dup_map): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error while iterating over blocks */ - { PR_1B_BLOCK_ITERATE, - N_("Error while iterating over @bs in @i %i (%s): %m\n"), - PROMPT_NONE, 0 }, - - /* Error adjusting EA refcount */ - { PR_1B_ADJ_EA_REFCOUNT, - N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"), - PROMPT_NONE, 0 }, - - - /* Pass 1C: Scan directories for inodes with multiply-claimed blocks. */ - { PR_1C_PASS_HEADER, - N_("Pass 1C: Scanning directories for @is with @m @bs.\n"), - PROMPT_NONE, 0 }, - - - /* Pass 1D: Reconciling multiply-claimed blocks */ - { PR_1D_PASS_HEADER, - N_("Pass 1D: Reconciling @m @bs\n"), - PROMPT_NONE, 0 }, - - /* File has duplicate blocks */ - { PR_1D_DUP_FILE, - N_("File %Q (@i #%i, mod time %IM)\n" - " has %B @m @b(s), shared with %N file(s):\n"), - PROMPT_NONE, 0 }, - - /* List of files sharing duplicate blocks */ - { PR_1D_DUP_FILE_LIST, - N_("\t%Q (@i #%i, mod time %IM)\n"), - PROMPT_NONE, 0 }, - - /* File sharing blocks with filesystem metadata */ - { PR_1D_SHARE_METADATA, - N_("\t<@f metadata>\n"), - PROMPT_NONE, 0 }, - - /* Report of how many duplicate/bad inodes */ - { PR_1D_NUM_DUP_INODES, - N_("(There are %N @is containing @m @bs.)\n\n"), - PROMPT_NONE, 0 }, - - /* Duplicated blocks already reassigned or cloned. */ - { PR_1D_DUP_BLOCKS_DEALT, - N_("@m @bs already reassigned or cloned.\n\n"), - PROMPT_NONE, 0 }, - - /* Clone duplicate/bad blocks? */ - { PR_1D_CLONE_QUESTION, - "", PROMPT_CLONE, PR_NO_OK }, - - /* Delete file? */ - { PR_1D_DELETE_QUESTION, - "", PROMPT_DELETE, 0 }, - - /* Couldn't clone file (error) */ - { PR_1D_CLONE_ERROR, - N_("Couldn't clone file: %m\n"), PROMPT_NONE, 0 }, - - /* Pass 2 errors */ - - /* Pass 2: Checking directory structure */ - { PR_2_PASS_HEADER, - N_("Pass 2: Checking @d structure\n"), - PROMPT_NONE, 0 }, - - /* Bad inode number for '.' */ - { PR_2_BAD_INODE_DOT, - N_("@n @i number for '.' in @d @i %i.\n"), - PROMPT_FIX, 0 }, - - /* Directory entry has bad inode number */ - { PR_2_BAD_INO, - N_("@E has @n @i #: %Di.\n"), - PROMPT_CLEAR, 0 }, - - /* Directory entry has deleted or unused inode */ - { PR_2_UNUSED_INODE, - N_("@E has @D/unused @i %Di. "), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* Directry entry is link to '.' */ - { PR_2_LINK_DOT, - N_("@E @L to '.' "), - PROMPT_CLEAR, 0 }, - - /* Directory entry points to inode now located in a bad block */ - { PR_2_BB_INODE, - N_("@E points to @i (%Di) located in a bad @b.\n"), - PROMPT_CLEAR, 0 }, - - /* Directory entry contains a link to a directory */ - { PR_2_LINK_DIR, - N_("@E @L to @d %P (%Di).\n"), - PROMPT_CLEAR, 0 }, - - /* Directory entry contains a link to the root directry */ - { PR_2_LINK_ROOT, - N_("@E @L to the @r.\n"), - PROMPT_CLEAR, 0 }, - - /* Directory entry has illegal characters in its name */ - { PR_2_BAD_NAME, - N_("@E has illegal characters in its name.\n"), - PROMPT_FIX, 0 }, - - /* Missing '.' in directory inode */ - { PR_2_MISSING_DOT, - N_("Missing '.' in @d @i %i.\n"), - PROMPT_FIX, 0 }, - - /* Missing '..' in directory inode */ - { PR_2_MISSING_DOT_DOT, - N_("Missing '..' in @d @i %i.\n"), - PROMPT_FIX, 0 }, - - /* First entry in directory inode doesn't contain '.' */ - { PR_2_1ST_NOT_DOT, - N_("First @e '%Dn' (@i=%Di) in @d @i %i (%p) @s '.'\n"), - PROMPT_FIX, 0 }, - - /* Second entry in directory inode doesn't contain '..' */ - { PR_2_2ND_NOT_DOT_DOT, - N_("Second @e '%Dn' (@i=%Di) in @d @i %i @s '..'\n"), - PROMPT_FIX, 0 }, - - /* i_faddr should be zero */ - { PR_2_FADDR_ZERO, - N_("i_faddr @F %IF, @s zero.\n"), - PROMPT_CLEAR, 0 }, - - /* i_file_acl should be zero */ - { PR_2_FILE_ACL_ZERO, - N_("i_file_acl @F %If, @s zero.\n"), - PROMPT_CLEAR, 0 }, - - /* i_dir_acl should be zero */ - { PR_2_DIR_ACL_ZERO, - N_("i_dir_acl @F %Id, @s zero.\n"), - PROMPT_CLEAR, 0 }, - - /* i_frag should be zero */ - { PR_2_FRAG_ZERO, - N_("i_frag @F %N, @s zero.\n"), - PROMPT_CLEAR, 0 }, - - /* i_fsize should be zero */ - { PR_2_FSIZE_ZERO, - N_("i_fsize @F %N, @s zero.\n"), - PROMPT_CLEAR, 0 }, - - /* inode has bad mode */ - { PR_2_BAD_MODE, - N_("@i %i (%Q) has @n mode (%Im).\n"), - PROMPT_CLEAR, 0 }, - - /* directory corrupted */ - { PR_2_DIR_CORRUPTED, - N_("@d @i %i, @b %B, offset %N: @d corrupted\n"), - PROMPT_SALVAGE, 0 }, - - /* filename too long */ - { PR_2_FILENAME_LONG, - N_("@d @i %i, @b %B, offset %N: filename too long\n"), - PROMPT_TRUNCATE, 0 }, - - /* Directory inode has a missing block (hole) */ - { PR_2_DIRECTORY_HOLE, - N_("@d @i %i has an unallocated @b #%B. "), - PROMPT_ALLOCATE, 0 }, - - /* '.' is not NULL terminated */ - { PR_2_DOT_NULL_TERM, - N_("'.' @d @e in @d @i %i is not NULL terminated\n"), - PROMPT_FIX, 0 }, - - /* '..' is not NULL terminated */ - { PR_2_DOT_DOT_NULL_TERM, - N_("'..' @d @e in @d @i %i is not NULL terminated\n"), - PROMPT_FIX, 0 }, - - /* Illegal character device inode */ - { PR_2_BAD_CHAR_DEV, - N_("@i %i (%Q) is an @I character @v.\n"), - PROMPT_CLEAR, 0 }, - - /* Illegal block device inode */ - { PR_2_BAD_BLOCK_DEV, - N_("@i %i (%Q) is an @I @b @v.\n"), - PROMPT_CLEAR, 0 }, - - /* Duplicate '.' entry */ - { PR_2_DUP_DOT, - N_("@E is duplicate '.' @e.\n"), - PROMPT_FIX, 0 }, - - /* Duplicate '..' entry */ - { PR_2_DUP_DOT_DOT, - N_("@E is duplicate '..' @e.\n"), - PROMPT_FIX, 0 }, - - /* Internal error: couldn't find dir_info */ - { PR_2_NO_DIRINFO, - N_("Internal error: cannot find dir_info for %i.\n"), - PROMPT_NONE, PR_FATAL }, - - /* Final rec_len is wrong */ - { PR_2_FINAL_RECLEN, - N_("@E has rec_len of %Dr, @s %N.\n"), - PROMPT_FIX, 0 }, - - /* Error allocating icount structure */ - { PR_2_ALLOCATE_ICOUNT, - N_("@A icount structure: %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error iterating over directory blocks */ - { PR_2_DBLIST_ITERATE, - N_("Error iterating over @d @bs: %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error reading directory block */ - { PR_2_READ_DIRBLOCK, - N_("Error reading @d @b %b (@i %i): %m\n"), - PROMPT_CONTINUE, 0 }, - - /* Error writing directory block */ - { PR_2_WRITE_DIRBLOCK, - N_("Error writing @d @b %b (@i %i): %m\n"), - PROMPT_CONTINUE, 0 }, - - /* Error allocating new directory block */ - { PR_2_ALLOC_DIRBOCK, - N_("@A new @d @b for @i %i (%s): %m\n"), - PROMPT_NONE, 0 }, - - /* Error deallocating inode */ - { PR_2_DEALLOC_INODE, - N_("Error deallocating @i %i: %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Directory entry for '.' is big. Split? */ - { PR_2_SPLIT_DOT, - N_("@d @e for '.' is big. "), - PROMPT_SPLIT, PR_NO_OK }, - - /* Illegal FIFO inode */ - { PR_2_BAD_FIFO, - N_("@i %i (%Q) is an @I FIFO.\n"), - PROMPT_CLEAR, 0 }, - - /* Illegal socket inode */ - { PR_2_BAD_SOCKET, - N_("@i %i (%Q) is an @I socket.\n"), - PROMPT_CLEAR, 0 }, - - /* Directory filetype not set */ - { PR_2_SET_FILETYPE, - N_("Setting filetype for @E to %N.\n"), - PROMPT_NONE, PR_PREEN_OK | PR_NO_OK | PR_NO_NOMSG }, - - /* Directory filetype incorrect */ - { PR_2_BAD_FILETYPE, - N_("@E has an incorrect filetype (was %Dt, @s %N).\n"), - PROMPT_FIX, 0 }, - - /* Directory filetype set on filesystem */ - { PR_2_CLEAR_FILETYPE, - N_("@E has filetype set.\n"), - PROMPT_CLEAR, PR_PREEN_OK }, - - /* Directory filename is null */ - { PR_2_NULL_NAME, - N_("@E has a @z name.\n"), - PROMPT_CLEAR, 0 }, - - /* Invalid symlink */ - { PR_2_INVALID_SYMLINK, - N_("Symlink %Q (@i #%i) is @n.\n"), - PROMPT_CLEAR, 0 }, - - /* i_file_acl (extended attribute block) is bad */ - { PR_2_FILE_ACL_BAD, - N_("@a @b @F @n (%If).\n"), - PROMPT_CLEAR, 0 }, - - /* Filesystem contains large files, but has no such flag in sb */ - { PR_2_FEATURE_LARGE_FILES, - N_("@f contains large files, but lacks LARGE_FILE flag in @S.\n"), - PROMPT_FIX, 0 }, - - /* Node in HTREE directory not referenced */ - { PR_2_HTREE_NOTREF, - N_("@p @h %d: node (%B) not referenced\n"), - PROMPT_NONE, 0 }, - - /* Node in HTREE directory referenced twice */ - { PR_2_HTREE_DUPREF, - N_("@p @h %d: node (%B) referenced twice\n"), - PROMPT_NONE, 0 }, - - /* Node in HTREE directory has bad min hash */ - { PR_2_HTREE_MIN_HASH, - N_("@p @h %d: node (%B) has bad min hash\n"), - PROMPT_NONE, 0 }, - - /* Node in HTREE directory has bad max hash */ - { PR_2_HTREE_MAX_HASH, - N_("@p @h %d: node (%B) has bad max hash\n"), - PROMPT_NONE, 0 }, - - /* Clear invalid HTREE directory */ - { PR_2_HTREE_CLEAR, - N_("@n @h %d (%q). "), PROMPT_CLEAR, 0 }, - - /* Bad block in htree interior node */ - { PR_2_HTREE_BADBLK, - N_("@p @h %d (%q): bad @b number %b.\n"), - PROMPT_CLEAR_HTREE, 0 }, - - /* Error adjusting EA refcount */ - { PR_2_ADJ_EA_REFCOUNT, - N_("Error adjusting refcount for @a @b %b (@i %i): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Invalid HTREE root node */ - { PR_2_HTREE_BAD_ROOT, - N_("@p @h %d: root node is @n\n"), - PROMPT_CLEAR_HTREE, PR_PREEN_OK }, - - /* Invalid HTREE limit */ - { PR_2_HTREE_BAD_LIMIT, - N_("@p @h %d: node (%B) has @n limit (%N)\n"), - PROMPT_CLEAR_HTREE, PR_PREEN_OK }, - - /* Invalid HTREE count */ - { PR_2_HTREE_BAD_COUNT, - N_("@p @h %d: node (%B) has @n count (%N)\n"), - PROMPT_CLEAR_HTREE, PR_PREEN_OK }, - - /* HTREE interior node has out-of-order hashes in table */ - { PR_2_HTREE_HASH_ORDER, - N_("@p @h %d: node (%B) has an unordered hash table\n"), - PROMPT_CLEAR_HTREE, PR_PREEN_OK }, - - /* Node in HTREE directory has invalid depth */ - { PR_2_HTREE_BAD_DEPTH, - N_("@p @h %d: node (%B) has @n depth\n"), - PROMPT_NONE, 0 }, - - /* Duplicate directory entry found */ - { PR_2_DUPLICATE_DIRENT, - N_("Duplicate @E found. "), - PROMPT_CLEAR, 0 }, - - /* Non-unique filename found */ - { PR_2_NON_UNIQUE_FILE, /* xgettext: no-c-format */ - N_("@E has a non-unique filename.\nRename to %s"), - PROMPT_NULL, 0 }, - - /* Duplicate directory entry found */ - { PR_2_REPORT_DUP_DIRENT, - N_("Duplicate @e '%Dn' found.\n\tMarking %p (%i) to be rebuilt.\n\n"), - PROMPT_NONE, 0 }, - - /* Pass 3 errors */ - - /* Pass 3: Checking directory connectivity */ - { PR_3_PASS_HEADER, - N_("Pass 3: Checking @d connectivity\n"), - PROMPT_NONE, 0 }, - - /* Root inode not allocated */ - { PR_3_NO_ROOT_INODE, - N_("@r not allocated. "), - PROMPT_ALLOCATE, 0 }, - - /* No room in lost+found */ - { PR_3_EXPAND_LF_DIR, - N_("No room in @l @d. "), - PROMPT_EXPAND, 0 }, - - /* Unconnected directory inode */ - { PR_3_UNCONNECTED_DIR, - N_("Unconnected @d @i %i (%p)\n"), - PROMPT_CONNECT, 0 }, - - /* /lost+found not found */ - { PR_3_NO_LF_DIR, - N_("/@l not found. "), - PROMPT_CREATE, PR_PREEN_OK }, - - /* .. entry is incorrect */ - { PR_3_BAD_DOT_DOT, - N_("'..' in %Q (%i) is %P (%j), @s %q (%d).\n"), - PROMPT_FIX, 0 }, - - /* Bad or non-existent /lost+found. Cannot reconnect */ - { PR_3_NO_LPF, - N_("Bad or non-existent /@l. Cannot reconnect.\n"), - PROMPT_NONE, 0 }, - - /* Could not expand /lost+found */ - { PR_3_CANT_EXPAND_LPF, - N_("Could not expand /@l: %m\n"), - PROMPT_NONE, 0 }, - - /* Could not reconnect inode */ - { PR_3_CANT_RECONNECT, - N_("Could not reconnect %i: %m\n"), - PROMPT_NONE, 0 }, - - /* Error while trying to find /lost+found */ - { PR_3_ERR_FIND_LPF, - N_("Error while trying to find /@l: %m\n"), - PROMPT_NONE, 0 }, - - /* Error in ext2fs_new_block while creating /lost+found */ - { PR_3_ERR_LPF_NEW_BLOCK, - N_("ext2fs_new_@b: %m while trying to create /@l @d\n"), - PROMPT_NONE, 0 }, - - /* Error in ext2fs_new_inode while creating /lost+found */ - { PR_3_ERR_LPF_NEW_INODE, - N_("ext2fs_new_@i: %m while trying to create /@l @d\n"), - PROMPT_NONE, 0 }, - - /* Error in ext2fs_new_dir_block while creating /lost+found */ - { PR_3_ERR_LPF_NEW_DIR_BLOCK, - N_("ext2fs_new_dir_@b: %m while creating new @d @b\n"), - PROMPT_NONE, 0 }, - - /* Error while writing directory block for /lost+found */ - { PR_3_ERR_LPF_WRITE_BLOCK, - N_("ext2fs_write_dir_@b: %m while writing the @d @b for /@l\n"), - PROMPT_NONE, 0 }, - - /* Error while adjusting inode count */ - { PR_3_ADJUST_INODE, - N_("Error while adjusting @i count on @i %i\n"), - PROMPT_NONE, 0 }, - - /* Couldn't fix parent directory -- error */ - { PR_3_FIX_PARENT_ERR, - N_("Couldn't fix parent of @i %i: %m\n\n"), - PROMPT_NONE, 0 }, - - /* Couldn't fix parent directory -- couldn't find it */ - { PR_3_FIX_PARENT_NOFIND, - N_("Couldn't fix parent of @i %i: Couldn't find parent @d @e\n\n"), - PROMPT_NONE, 0 }, - - /* Error allocating inode bitmap */ - { PR_3_ALLOCATE_IBITMAP_ERROR, - N_("@A @i @B (%N): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error creating root directory */ - { PR_3_CREATE_ROOT_ERROR, - N_("Error creating root @d (%s): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error creating lost and found directory */ - { PR_3_CREATE_LPF_ERROR, - N_("Error creating /@l @d (%s): %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Root inode is not directory; aborting */ - { PR_3_ROOT_NOT_DIR_ABORT, - N_("@r is not a @d; aborting.\n"), - PROMPT_NONE, PR_FATAL }, - - /* Cannot proceed without a root inode. */ - { PR_3_NO_ROOT_INODE_ABORT, - N_("can't proceed without a @r.\n"), - PROMPT_NONE, PR_FATAL }, - - /* Internal error: couldn't find dir_info */ - { PR_3_NO_DIRINFO, - N_("Internal error: cannot find dir_info for %i.\n"), - PROMPT_NONE, PR_FATAL }, - - /* Lost+found not a directory */ - { PR_3_LPF_NOTDIR, - N_("/@l is not a @d (ino=%i)\n"), - PROMPT_UNLINK, 0 }, - - /* Pass 3A Directory Optimization */ - - /* Pass 3A: Optimizing directories */ - { PR_3A_PASS_HEADER, - N_("Pass 3A: Optimizing directories\n"), - PROMPT_NONE, PR_PREEN_NOMSG }, - - /* Error iterating over directories */ - { PR_3A_OPTIMIZE_ITER, - N_("Failed to create dirs_to_hash iterator: %m"), - PROMPT_NONE, 0 }, - - /* Error rehash directory */ - { PR_3A_OPTIMIZE_DIR_ERR, - N_("Failed to optimize directory %q (%d): %m"), - PROMPT_NONE, 0 }, - - /* Rehashing dir header */ - { PR_3A_OPTIMIZE_DIR_HEADER, - N_("Optimizing directories: "), - PROMPT_NONE, PR_MSG_ONLY }, - - /* Rehashing directory %d */ - { PR_3A_OPTIMIZE_DIR, - " %d", - PROMPT_NONE, PR_LATCH_OPTIMIZE_DIR | PR_PREEN_NOHDR}, - - /* Rehashing dir end */ - { PR_3A_OPTIMIZE_DIR_END, - "\n", - PROMPT_NONE, PR_PREEN_NOHDR }, - - /* Pass 4 errors */ - - /* Pass 4: Checking reference counts */ - { PR_4_PASS_HEADER, - N_("Pass 4: Checking reference counts\n"), - PROMPT_NONE, 0 }, - - /* Unattached zero-length inode */ - { PR_4_ZERO_LEN_INODE, - N_("@u @z @i %i. "), - PROMPT_CLEAR, PR_PREEN_OK|PR_NO_OK }, - - /* Unattached inode */ - { PR_4_UNATTACHED_INODE, - N_("@u @i %i\n"), - PROMPT_CONNECT, 0 }, - - /* Inode ref count wrong */ - { PR_4_BAD_REF_COUNT, - N_("@i %i ref count is %Il, @s %N. "), - PROMPT_FIX, PR_PREEN_OK }, - - { PR_4_INCONSISTENT_COUNT, - N_("WARNING: PROGRAMMING BUG IN E2FSCK!\n" - "\tOR SOME BONEHEAD (YOU) IS CHECKING A MOUNTED (LIVE) FILESYSTEM.\n" - "@i_link_info[%i] is %N, @i.i_links_count is %Il. " - "They @s the same!\n"), - PROMPT_NONE, 0 }, - - /* Pass 5 errors */ - - /* Pass 5: Checking group summary information */ - { PR_5_PASS_HEADER, - N_("Pass 5: Checking @g summary information\n"), - PROMPT_NONE, 0 }, - - /* Padding at end of inode bitmap is not set. */ - { PR_5_INODE_BMAP_PADDING, - N_("Padding at end of @i @B is not set. "), - PROMPT_FIX, PR_PREEN_OK }, - - /* Padding at end of block bitmap is not set. */ - { PR_5_BLOCK_BMAP_PADDING, - N_("Padding at end of @b @B is not set. "), - PROMPT_FIX, PR_PREEN_OK }, - - /* Block bitmap differences header */ - { PR_5_BLOCK_BITMAP_HEADER, - N_("@b @B differences: "), - PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG}, - - /* Block not used, but marked in bitmap */ - { PR_5_BLOCK_UNUSED, - " -%b", - PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Block used, but not marked used in bitmap */ - { PR_5_BLOCK_USED, - " +%b", - PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Block bitmap differences end */ - { PR_5_BLOCK_BITMAP_END, - "\n", - PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Inode bitmap differences header */ - { PR_5_INODE_BITMAP_HEADER, - N_("@i @B differences: "), - PROMPT_NONE, PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Inode not used, but marked in bitmap */ - { PR_5_INODE_UNUSED, - " -%i", - PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Inode used, but not marked used in bitmap */ - { PR_5_INODE_USED, - " +%i", - PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Inode bitmap differences end */ - { PR_5_INODE_BITMAP_END, - "\n", - PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Free inodes count for group wrong */ - { PR_5_FREE_INODE_COUNT_GROUP, - N_("Free @is count wrong for @g #%g (%i, counted=%j).\n"), - PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Directories count for group wrong */ - { PR_5_FREE_DIR_COUNT_GROUP, - N_("Directories count wrong for @g #%g (%i, counted=%j).\n"), - PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Free inodes count wrong */ - { PR_5_FREE_INODE_COUNT, - N_("Free @is count wrong (%i, counted=%j).\n"), - PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Free blocks count for group wrong */ - { PR_5_FREE_BLOCK_COUNT_GROUP, - N_("Free @bs count wrong for @g #%g (%b, counted=%c).\n"), - PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Free blocks count wrong */ - { PR_5_FREE_BLOCK_COUNT, - N_("Free @bs count wrong (%b, counted=%c).\n"), - PROMPT_FIX, PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Programming error: bitmap endpoints don't match */ - { PR_5_BMAP_ENDPOINTS, - N_("PROGRAMMING ERROR: @f (#%N) @B endpoints (%b, %c) don't " - "match calculated @B endpoints (%i, %j)\n"), - PROMPT_NONE, PR_FATAL }, - - /* Internal error: fudging end of bitmap */ - { PR_5_FUDGE_BITMAP_ERROR, - N_("Internal error: fudging end of bitmap (%N)\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error copying in replacement inode bitmap */ - { PR_5_COPY_IBITMAP_ERROR, - N_("Error copying in replacement @i @B: %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Error copying in replacement block bitmap */ - { PR_5_COPY_BBITMAP_ERROR, - N_("Error copying in replacement @b @B: %m\n"), - PROMPT_NONE, PR_FATAL }, - - /* Block range not used, but marked in bitmap */ - { PR_5_BLOCK_RANGE_UNUSED, - " -(%b--%c)", - PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Block range used, but not marked used in bitmap */ - { PR_5_BLOCK_RANGE_USED, - " +(%b--%c)", - PROMPT_NONE, PR_LATCH_BBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Inode range not used, but marked in bitmap */ - { PR_5_INODE_RANGE_UNUSED, - " -(%i--%j)", - PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, - - /* Inode range used, but not marked used in bitmap */ - { PR_5_INODE_RANGE_USED, - " +(%i--%j)", - PROMPT_NONE, PR_LATCH_IBITMAP | PR_PREEN_OK | PR_PREEN_NOMSG }, - - { 0 } -}; - -/* - * This is the latch flags register. It allows several problems to be - * "latched" together. This means that the user has to answer but one - * question for the set of problems, and all of the associated - * problems will be either fixed or not fixed. - */ -static struct latch_descr pr_latch_info[] = { - { PR_LATCH_BLOCK, PR_1_INODE_BLOCK_LATCH, 0 }, - { PR_LATCH_BBLOCK, PR_1_INODE_BBLOCK_LATCH, 0 }, - { PR_LATCH_IBITMAP, PR_5_INODE_BITMAP_HEADER, PR_5_INODE_BITMAP_END }, - { PR_LATCH_BBITMAP, PR_5_BLOCK_BITMAP_HEADER, PR_5_BLOCK_BITMAP_END }, - { PR_LATCH_RELOC, PR_0_RELOCATE_HINT, 0 }, - { PR_LATCH_DBLOCK, PR_1B_DUP_BLOCK_HEADER, PR_1B_DUP_BLOCK_END }, - { PR_LATCH_LOW_DTIME, PR_1_ORPHAN_LIST_REFUGEES, 0 }, - { PR_LATCH_TOOBIG, PR_1_INODE_TOOBIG, 0 }, - { PR_LATCH_OPTIMIZE_DIR, PR_3A_OPTIMIZE_DIR_HEADER, PR_3A_OPTIMIZE_DIR_END }, - { -1, 0, 0 }, -}; - -static const struct e2fsck_problem *find_problem(problem_t code) -{ - int i; - - for (i=0; problem_table[i].e2p_code; i++) { - if (problem_table[i].e2p_code == code) - return &problem_table[i]; - } - return 0; -} - -static struct latch_descr *find_latch(int code) -{ - int i; - - for (i=0; pr_latch_info[i].latch_code >= 0; i++) { - if (pr_latch_info[i].latch_code == code) - return &pr_latch_info[i]; - } - return 0; -} - -int end_problem_latch(e2fsck_t ctx, int mask) -{ - struct latch_descr *ldesc; - struct problem_context pctx; - int answer = -1; - - ldesc = find_latch(mask); - if (ldesc->end_message && (ldesc->flags & PRL_LATCHED)) { - clear_problem_context(&pctx); - answer = fix_problem(ctx, ldesc->end_message, &pctx); - } - ldesc->flags &= ~(PRL_VARIABLE); - return answer; -} - -int set_latch_flags(int mask, int setflags, int clearflags) -{ - struct latch_descr *ldesc; - - ldesc = find_latch(mask); - if (!ldesc) - return -1; - ldesc->flags |= setflags; - ldesc->flags &= ~clearflags; - return 0; -} - -void clear_problem_context(struct problem_context *ctx) -{ - memset(ctx, 0, sizeof(struct problem_context)); - ctx->blkcount = -1; - ctx->group = -1; -} - -int fix_problem(e2fsck_t ctx, problem_t code, struct problem_context *pctx) -{ - ext2_filsys fs = ctx->fs; - const struct e2fsck_problem *ptr; - struct latch_descr *ldesc = NULL; - const char *message; - int def_yn, answer, ans; - int print_answer = 0; - int suppress = 0; - - ptr = find_problem(code); - if (!ptr) { - printf(_("Unhandled error code (0x%x)!\n"), code); - return 0; - } - def_yn = 1; - if ((ptr->flags & PR_NO_DEFAULT) || - ((ptr->flags & PR_PREEN_NO) && (ctx->options & E2F_OPT_PREEN)) || - (ctx->options & E2F_OPT_NO)) - def_yn= 0; - - /* - * Do special latch processing. This is where we ask the - * latch question, if it exists - */ - if (ptr->flags & PR_LATCH_MASK) { - ldesc = find_latch(ptr->flags & PR_LATCH_MASK); - if (ldesc->question && !(ldesc->flags & PRL_LATCHED)) { - ans = fix_problem(ctx, ldesc->question, pctx); - if (ans == 1) - ldesc->flags |= PRL_YES; - if (ans == 0) - ldesc->flags |= PRL_NO; - ldesc->flags |= PRL_LATCHED; - } - if (ldesc->flags & PRL_SUPPRESS) - suppress++; - } - if ((ptr->flags & PR_PREEN_NOMSG) && - (ctx->options & E2F_OPT_PREEN)) - suppress++; - if ((ptr->flags & PR_NO_NOMSG) && - (ctx->options & E2F_OPT_NO)) - suppress++; - if (!suppress) { - message = ptr->e2p_description; - if ((ctx->options & E2F_OPT_PREEN) && - !(ptr->flags & PR_PREEN_NOHDR)) { - printf("%s: ", ctx->device_name ? - ctx->device_name : ctx->filesystem_name); - } - if (*message) - print_e2fsck_message(ctx, _(message), pctx, 1); - } - if (!(ptr->flags & PR_PREEN_OK) && (ptr->prompt != PROMPT_NONE)) - preenhalt(ctx); - - if (ptr->flags & PR_FATAL) - bb_error_msg_and_die(0); - - if (ptr->prompt == PROMPT_NONE) { - if (ptr->flags & PR_NOCOLLATE) - answer = -1; - else - answer = def_yn; - } else { - if (ctx->options & E2F_OPT_PREEN) { - answer = def_yn; - if (!(ptr->flags & PR_PREEN_NOMSG)) - print_answer = 1; - } else if ((ptr->flags & PR_LATCH_MASK) && - (ldesc->flags & (PRL_YES | PRL_NO))) { - if (!suppress) - print_answer = 1; - if (ldesc->flags & PRL_YES) - answer = 1; - else - answer = 0; - } else - answer = ask(ctx, _(prompt[(int) ptr->prompt]), def_yn); - if (!answer && !(ptr->flags & PR_NO_OK)) - ext2fs_unmark_valid(fs); - - if (print_answer) - printf("%s.\n", answer ? - _(preen_msg[(int) ptr->prompt]) : _("IGNORED")); - } - - if ((ptr->prompt == PROMPT_ABORT) && answer) - bb_error_msg_and_die(0); - - if (ptr->flags & PR_AFTER_CODE) - answer = fix_problem(ctx, ptr->second_code, pctx); - - return answer; -} - -/* - * linux/fs/recovery.c - * - * Written by Stephen C. Tweedie , 1999 - */ - -/* - * Maintain information about the progress of the recovery job, so that - * the different passes can carry information between them. - */ -struct recovery_info -{ - tid_t start_transaction; - tid_t end_transaction; - - int nr_replays; - int nr_revokes; - int nr_revoke_hits; -}; - -enum passtype {PASS_SCAN, PASS_REVOKE, PASS_REPLAY}; -static int do_one_pass(journal_t *journal, - struct recovery_info *info, enum passtype pass); -static int scan_revoke_records(journal_t *, struct buffer_head *, - tid_t, struct recovery_info *); - -/* - * Read a block from the journal - */ - -static int jread(struct buffer_head **bhp, journal_t *journal, - unsigned int offset) -{ - int err; - unsigned long blocknr; - struct buffer_head *bh; - - *bhp = NULL; - - err = journal_bmap(journal, offset, &blocknr); - - if (err) { - printf("JBD: bad block at offset %u\n", offset); - return err; - } - - bh = getblk(journal->j_dev, blocknr, journal->j_blocksize); - if (!bh) - return -ENOMEM; - - if (!buffer_uptodate(bh)) { - /* If this is a brand new buffer, start readahead. - Otherwise, we assume we are already reading it. */ - if (!buffer_req(bh)) - do_readahead(journal, offset); - wait_on_buffer(bh); - } - - if (!buffer_uptodate(bh)) { - printf("JBD: Failed to read block at offset %u\n", offset); - brelse(bh); - return -EIO; - } - - *bhp = bh; - return 0; -} - - -/* - * Count the number of in-use tags in a journal descriptor block. - */ - -static int count_tags(struct buffer_head *bh, int size) -{ - char * tagp; - journal_block_tag_t * tag; - int nr = 0; - - tagp = &bh->b_data[sizeof(journal_header_t)]; - - while ((tagp - bh->b_data + sizeof(journal_block_tag_t)) <= size) { - tag = (journal_block_tag_t *) tagp; - - nr++; - tagp += sizeof(journal_block_tag_t); - if (!(tag->t_flags & htonl(JFS_FLAG_SAME_UUID))) - tagp += 16; - - if (tag->t_flags & htonl(JFS_FLAG_LAST_TAG)) - break; - } - - return nr; -} - - -/* Make sure we wrap around the log correctly! */ -#define wrap(journal, var) \ -do { \ - if (var >= (journal)->j_last) \ - var -= ((journal)->j_last - (journal)->j_first); \ -} while (0) - -/** - * int journal_recover(journal_t *journal) - recovers a on-disk journal - * @journal: the journal to recover - * - * The primary function for recovering the log contents when mounting a - * journaled device. - * - * Recovery is done in three passes. In the first pass, we look for the - * end of the log. In the second, we assemble the list of revoke - * blocks. In the third and final pass, we replay any un-revoked blocks - * in the log. - */ -int journal_recover(journal_t *journal) -{ - int err; - journal_superblock_t * sb; - - struct recovery_info info; - - memset(&info, 0, sizeof(info)); - sb = journal->j_superblock; - - /* - * The journal superblock's s_start field (the current log head) - * is always zero if, and only if, the journal was cleanly - * unmounted. - */ - - if (!sb->s_start) { - journal->j_transaction_sequence = ntohl(sb->s_sequence) + 1; - return 0; - } - - err = do_one_pass(journal, &info, PASS_SCAN); - if (!err) - err = do_one_pass(journal, &info, PASS_REVOKE); - if (!err) - err = do_one_pass(journal, &info, PASS_REPLAY); - - /* Restart the log at the next transaction ID, thus invalidating - * any existing commit records in the log. */ - journal->j_transaction_sequence = ++info.end_transaction; - - journal_clear_revoke(journal); - sync_blockdev(journal->j_fs_dev); - return err; -} - -static int do_one_pass(journal_t *journal, - struct recovery_info *info, enum passtype pass) -{ - unsigned int first_commit_ID, next_commit_ID; - unsigned long next_log_block; - int err, success = 0; - journal_superblock_t * sb; - journal_header_t * tmp; - struct buffer_head * bh; - unsigned int sequence; - int blocktype; - - /* Precompute the maximum metadata descriptors in a descriptor block */ - int MAX_BLOCKS_PER_DESC; - MAX_BLOCKS_PER_DESC = ((journal->j_blocksize-sizeof(journal_header_t)) - / sizeof(journal_block_tag_t)); - - /* - * First thing is to establish what we expect to find in the log - * (in terms of transaction IDs), and where (in terms of log - * block offsets): query the superblock. - */ - - sb = journal->j_superblock; - next_commit_ID = ntohl(sb->s_sequence); - next_log_block = ntohl(sb->s_start); - - first_commit_ID = next_commit_ID; - if (pass == PASS_SCAN) - info->start_transaction = first_commit_ID; - - /* - * Now we walk through the log, transaction by transaction, - * making sure that each transaction has a commit block in the - * expected place. Each complete transaction gets replayed back - * into the main filesystem. - */ - - while (1) { - int flags; - char * tagp; - journal_block_tag_t * tag; - struct buffer_head * obh; - struct buffer_head * nbh; - - /* If we already know where to stop the log traversal, - * check right now that we haven't gone past the end of - * the log. */ - - if (pass != PASS_SCAN) - if (tid_geq(next_commit_ID, info->end_transaction)) - break; - - /* Skip over each chunk of the transaction looking - * either the next descriptor block or the final commit - * record. */ - - err = jread(&bh, journal, next_log_block); - if (err) - goto failed; - - next_log_block++; - wrap(journal, next_log_block); - - /* What kind of buffer is it? - * - * If it is a descriptor block, check that it has the - * expected sequence number. Otherwise, we're all done - * here. */ - - tmp = (journal_header_t *)bh->b_data; - - if (tmp->h_magic != htonl(JFS_MAGIC_NUMBER)) { - brelse(bh); - break; - } - - blocktype = ntohl(tmp->h_blocktype); - sequence = ntohl(tmp->h_sequence); - - if (sequence != next_commit_ID) { - brelse(bh); - break; - } - - /* OK, we have a valid descriptor block which matches - * all of the sequence number checks. What are we going - * to do with it? That depends on the pass... */ - - switch (blocktype) { - case JFS_DESCRIPTOR_BLOCK: - /* If it is a valid descriptor block, replay it - * in pass REPLAY; otherwise, just skip over the - * blocks it describes. */ - if (pass != PASS_REPLAY) { - next_log_block += - count_tags(bh, journal->j_blocksize); - wrap(journal, next_log_block); - brelse(bh); - continue; - } - - /* A descriptor block: we can now write all of - * the data blocks. Yay, useful work is finally - * getting done here! */ - - tagp = &bh->b_data[sizeof(journal_header_t)]; - while ((tagp - bh->b_data +sizeof(journal_block_tag_t)) - <= journal->j_blocksize) { - unsigned long io_block; - - tag = (journal_block_tag_t *) tagp; - flags = ntohl(tag->t_flags); - - io_block = next_log_block++; - wrap(journal, next_log_block); - err = jread(&obh, journal, io_block); - if (err) { - /* Recover what we can, but - * report failure at the end. */ - success = err; - printf("JBD: IO error %d recovering " - "block %ld in log\n", - err, io_block); - } else { - unsigned long blocknr; - - blocknr = ntohl(tag->t_blocknr); - - /* If the block has been - * revoked, then we're all done - * here. */ - if (journal_test_revoke - (journal, blocknr, - next_commit_ID)) { - brelse(obh); - ++info->nr_revoke_hits; - goto skip_write; - } - - /* Find a buffer for the new - * data being restored */ - nbh = getblk(journal->j_fs_dev, - blocknr, - journal->j_blocksize); - if (nbh == NULL) { - printf("JBD: Out of memory " - "during recovery.\n"); - err = -ENOMEM; - brelse(bh); - brelse(obh); - goto failed; - } - - lock_buffer(nbh); - memcpy(nbh->b_data, obh->b_data, - journal->j_blocksize); - if (flags & JFS_FLAG_ESCAPE) { - *((unsigned int *)bh->b_data) = - htonl(JFS_MAGIC_NUMBER); - } - - mark_buffer_uptodate(nbh, 1); - mark_buffer_dirty(nbh); - ++info->nr_replays; - /* ll_rw_block(WRITE, 1, &nbh); */ - unlock_buffer(nbh); - brelse(obh); - brelse(nbh); - } - - skip_write: - tagp += sizeof(journal_block_tag_t); - if (!(flags & JFS_FLAG_SAME_UUID)) - tagp += 16; - - if (flags & JFS_FLAG_LAST_TAG) - break; - } - - brelse(bh); - continue; - - case JFS_COMMIT_BLOCK: - /* Found an expected commit block: not much to - * do other than move on to the next sequence - * number. */ - brelse(bh); - next_commit_ID++; - continue; - - case JFS_REVOKE_BLOCK: - /* If we aren't in the REVOKE pass, then we can - * just skip over this block. */ - if (pass != PASS_REVOKE) { - brelse(bh); - continue; - } - - err = scan_revoke_records(journal, bh, - next_commit_ID, info); - brelse(bh); - if (err) - goto failed; - continue; - - default: - goto done; - } - } - - done: - /* - * We broke out of the log scan loop: either we came to the - * known end of the log or we found an unexpected block in the - * log. If the latter happened, then we know that the "current" - * transaction marks the end of the valid log. - */ - - if (pass == PASS_SCAN) - info->end_transaction = next_commit_ID; - else { - /* It's really bad news if different passes end up at - * different places (but possible due to IO errors). */ - if (info->end_transaction != next_commit_ID) { - printf("JBD: recovery pass %d ended at " - "transaction %u, expected %u\n", - pass, next_commit_ID, info->end_transaction); - if (!success) - success = -EIO; - } - } - - return success; - - failed: - return err; -} - - -/* Scan a revoke record, marking all blocks mentioned as revoked. */ - -static int scan_revoke_records(journal_t *journal, struct buffer_head *bh, - tid_t sequence, struct recovery_info *info) -{ - journal_revoke_header_t *header; - int offset, max; - - header = (journal_revoke_header_t *) bh->b_data; - offset = sizeof(journal_revoke_header_t); - max = ntohl(header->r_count); - - while (offset < max) { - unsigned long blocknr; - int err; - - blocknr = ntohl(* ((unsigned int *) (bh->b_data+offset))); - offset += 4; - err = journal_set_revoke(journal, blocknr, sequence); - if (err) - return err; - ++info->nr_revokes; - } - return 0; -} - - -/* - * rehash.c --- rebuild hash tree directories - * - * This algorithm is designed for simplicity of implementation and to - * pack the directory as much as possible. It however requires twice - * as much memory as the size of the directory. The maximum size - * directory supported using a 4k blocksize is roughly a gigabyte, and - * so there may very well be problems with machines that don't have - * virtual memory, and obscenely large directories. - * - * An alternate algorithm which is much more disk intensive could be - * written, and probably will need to be written in the future. The - * design goals of such an algorithm are: (a) use (roughly) constant - * amounts of memory, no matter how large the directory, (b) the - * directory must be safe at all times, even if e2fsck is interrupted - * in the middle, (c) we must use minimal amounts of extra disk - * blocks. This pretty much requires an incremental approach, where - * we are reading from one part of the directory, and inserting into - * the front half. So the algorithm will have to keep track of a - * moving block boundary between the new tree and the old tree, and - * files will need to be moved from the old directory and inserted - * into the new tree. If the new directory requires space which isn't - * yet available, blocks from the beginning part of the old directory - * may need to be moved to the end of the directory to make room for - * the new tree: - * - * -------------------------------------------------------- - * | new tree | | old tree | - * -------------------------------------------------------- - * ^ ptr ^ptr - * tail new head old - * - * This is going to be a pain in the tuckus to implement, and will - * require a lot more disk accesses. So I'm going to skip it for now; - * it's only really going to be an issue for really, really big - * filesystems (when we reach the level of tens of millions of files - * in a single directory). It will probably be easier to simply - * require that e2fsck use VM first. - */ - -struct fill_dir_struct { - char *buf; - struct ext2_inode *inode; - int err; - e2fsck_t ctx; - struct hash_entry *harray; - int max_array, num_array; - int dir_size; - int compress; - ino_t parent; -}; - -struct hash_entry { - ext2_dirhash_t hash; - ext2_dirhash_t minor_hash; - struct ext2_dir_entry *dir; -}; - -struct out_dir { - int num; - int max; - char *buf; - ext2_dirhash_t *hashes; -}; - -static int fill_dir_block(ext2_filsys fs, - blk_t *block_nr, - e2_blkcnt_t blockcnt, - blk_t ref_block FSCK_ATTR((unused)), - int ref_offset FSCK_ATTR((unused)), - void *priv_data) -{ - struct fill_dir_struct *fd = (struct fill_dir_struct *) priv_data; - struct hash_entry *new_array, *ent; - struct ext2_dir_entry *dirent; - char *dir; - unsigned int offset, dir_offset; - - if (blockcnt < 0) - return 0; - - offset = blockcnt * fs->blocksize; - if (offset + fs->blocksize > fd->inode->i_size) { - fd->err = EXT2_ET_DIR_CORRUPTED; - return BLOCK_ABORT; - } - dir = (fd->buf+offset); - if (HOLE_BLKADDR(*block_nr)) { - memset(dir, 0, fs->blocksize); - dirent = (struct ext2_dir_entry *) dir; - dirent->rec_len = fs->blocksize; - } else { - fd->err = ext2fs_read_dir_block(fs, *block_nr, dir); - if (fd->err) - return BLOCK_ABORT; - } - /* While the directory block is "hot", index it. */ - dir_offset = 0; - while (dir_offset < fs->blocksize) { - dirent = (struct ext2_dir_entry *) (dir + dir_offset); - if (((dir_offset + dirent->rec_len) > fs->blocksize) || - (dirent->rec_len < 8) || - ((dirent->rec_len % 4) != 0) || - (((dirent->name_len & 0xFF)+8) > dirent->rec_len)) { - fd->err = EXT2_ET_DIR_CORRUPTED; - return BLOCK_ABORT; - } - dir_offset += dirent->rec_len; - if (dirent->inode == 0) - continue; - if (!fd->compress && ((dirent->name_len&0xFF) == 1) && - (dirent->name[0] == '.')) - continue; - if (!fd->compress && ((dirent->name_len&0xFF) == 2) && - (dirent->name[0] == '.') && (dirent->name[1] == '.')) { - fd->parent = dirent->inode; - continue; - } - if (fd->num_array >= fd->max_array) { - new_array = xrealloc(fd->harray, - sizeof(struct hash_entry) * (fd->max_array+500)); - fd->harray = new_array; - fd->max_array += 500; - } - ent = fd->harray + fd->num_array++; - ent->dir = dirent; - fd->dir_size += EXT2_DIR_REC_LEN(dirent->name_len & 0xFF); - if (fd->compress) - ent->hash = ent->minor_hash = 0; - else { - fd->err = ext2fs_dirhash(fs->super->s_def_hash_version, - dirent->name, - dirent->name_len & 0xFF, - fs->super->s_hash_seed, - &ent->hash, &ent->minor_hash); - if (fd->err) - return BLOCK_ABORT; - } - } - - return 0; -} - -/* Used for sorting the hash entry */ -static int name_cmp(const void *a, const void *b) -{ - const struct hash_entry *he_a = (const struct hash_entry *) a; - const struct hash_entry *he_b = (const struct hash_entry *) b; - int ret; - int min_len; - - min_len = he_a->dir->name_len; - if (min_len > he_b->dir->name_len) - min_len = he_b->dir->name_len; - - ret = strncmp(he_a->dir->name, he_b->dir->name, min_len); - if (ret == 0) { - if (he_a->dir->name_len > he_b->dir->name_len) - ret = 1; - else if (he_a->dir->name_len < he_b->dir->name_len) - ret = -1; - else - ret = he_b->dir->inode - he_a->dir->inode; - } - return ret; -} - -/* Used for sorting the hash entry */ -static int hash_cmp(const void *a, const void *b) -{ - const struct hash_entry *he_a = (const struct hash_entry *) a; - const struct hash_entry *he_b = (const struct hash_entry *) b; - int ret; - - if (he_a->hash > he_b->hash) - ret = 1; - else if (he_a->hash < he_b->hash) - ret = -1; - else { - if (he_a->minor_hash > he_b->minor_hash) - ret = 1; - else if (he_a->minor_hash < he_b->minor_hash) - ret = -1; - else - ret = name_cmp(a, b); - } - return ret; -} - -static errcode_t alloc_size_dir(ext2_filsys fs, struct out_dir *outdir, - int blocks) -{ - void *new_mem; - - if (outdir->max) { - new_mem = xrealloc(outdir->buf, blocks * fs->blocksize); - outdir->buf = new_mem; - new_mem = xrealloc(outdir->hashes, - blocks * sizeof(ext2_dirhash_t)); - outdir->hashes = new_mem; - } else { - outdir->buf = xmalloc(blocks * fs->blocksize); - outdir->hashes = xmalloc(blocks * sizeof(ext2_dirhash_t)); - outdir->num = 0; - } - outdir->max = blocks; - return 0; -} - -static void free_out_dir(struct out_dir *outdir) -{ - free(outdir->buf); - free(outdir->hashes); - outdir->max = 0; - outdir->num =0; -} - -static errcode_t get_next_block(ext2_filsys fs, struct out_dir *outdir, - char ** ret) -{ - errcode_t retval; - - if (outdir->num >= outdir->max) { - retval = alloc_size_dir(fs, outdir, outdir->max + 50); - if (retval) - return retval; - } - *ret = outdir->buf + (outdir->num++ * fs->blocksize); - memset(*ret, 0, fs->blocksize); - return 0; -} - -/* - * This function is used to make a unique filename. We do this by - * appending ~0, and then incrementing the number. However, we cannot - * expand the length of the filename beyond the padding available in - * the directory entry. - */ -static void mutate_name(char *str, __u16 *len) -{ - int i; - __u16 l = *len & 0xFF, h = *len & 0xff00; - - /* - * First check to see if it looks the name has been mutated - * already - */ - for (i = l-1; i > 0; i--) { - if (!isdigit(str[i])) - break; - } - if ((i == l-1) || (str[i] != '~')) { - if (((l-1) & 3) < 2) - l += 2; - else - l = (l+3) & ~3; - str[l-2] = '~'; - str[l-1] = '0'; - *len = l | h; - return; - } - for (i = l-1; i >= 0; i--) { - if (isdigit(str[i])) { - if (str[i] == '9') - str[i] = '0'; - else { - str[i]++; - return; - } - continue; - } - if (i == 1) { - if (str[0] == 'z') - str[0] = 'A'; - else if (str[0] == 'Z') { - str[0] = '~'; - str[1] = '0'; - } else - str[0]++; - } else if (i > 0) { - str[i] = '1'; - str[i-1] = '~'; - } else { - if (str[0] == '~') - str[0] = 'a'; - else - str[0]++; - } - break; - } -} - -static int duplicate_search_and_fix(e2fsck_t ctx, ext2_filsys fs, - ext2_ino_t ino, - struct fill_dir_struct *fd) -{ - struct problem_context pctx; - struct hash_entry *ent, *prev; - int i, j; - int fixed = 0; - char new_name[256]; - __u16 new_len; - - clear_problem_context(&pctx); - pctx.ino = ino; - - for (i=1; i < fd->num_array; i++) { - ent = fd->harray + i; - prev = ent - 1; - if (!ent->dir->inode || - ((ent->dir->name_len & 0xFF) != - (prev->dir->name_len & 0xFF)) || - (strncmp(ent->dir->name, prev->dir->name, - ent->dir->name_len & 0xFF))) - continue; - pctx.dirent = ent->dir; - if ((ent->dir->inode == prev->dir->inode) && - fix_problem(ctx, PR_2_DUPLICATE_DIRENT, &pctx)) { - e2fsck_adjust_inode_count(ctx, ent->dir->inode, -1); - ent->dir->inode = 0; - fixed++; - continue; - } - memcpy(new_name, ent->dir->name, ent->dir->name_len & 0xFF); - new_len = ent->dir->name_len; - mutate_name(new_name, &new_len); - for (j=0; j < fd->num_array; j++) { - if ((i==j) || - ((ent->dir->name_len & 0xFF) != - (fd->harray[j].dir->name_len & 0xFF)) || - (strncmp(new_name, fd->harray[j].dir->name, - new_len & 0xFF))) - continue; - mutate_name(new_name, &new_len); - - j = -1; - } - new_name[new_len & 0xFF] = 0; - pctx.str = new_name; - if (fix_problem(ctx, PR_2_NON_UNIQUE_FILE, &pctx)) { - memcpy(ent->dir->name, new_name, new_len & 0xFF); - ent->dir->name_len = new_len; - ext2fs_dirhash(fs->super->s_def_hash_version, - ent->dir->name, - ent->dir->name_len & 0xFF, - fs->super->s_hash_seed, - &ent->hash, &ent->minor_hash); - fixed++; - } - } - return fixed; -} - - -static errcode_t copy_dir_entries(ext2_filsys fs, - struct fill_dir_struct *fd, - struct out_dir *outdir) -{ - errcode_t retval; - char *block_start; - struct hash_entry *ent; - struct ext2_dir_entry *dirent; - int i, rec_len, left; - ext2_dirhash_t prev_hash; - int offset; - - outdir->max = 0; - retval = alloc_size_dir(fs, outdir, - (fd->dir_size / fs->blocksize) + 2); - if (retval) - return retval; - outdir->num = fd->compress ? 0 : 1; - offset = 0; - outdir->hashes[0] = 0; - prev_hash = 1; - if ((retval = get_next_block(fs, outdir, &block_start))) - return retval; - dirent = (struct ext2_dir_entry *) block_start; - left = fs->blocksize; - for (i=0; i < fd->num_array; i++) { - ent = fd->harray + i; - if (ent->dir->inode == 0) - continue; - rec_len = EXT2_DIR_REC_LEN(ent->dir->name_len & 0xFF); - if (rec_len > left) { - if (left) - dirent->rec_len += left; - if ((retval = get_next_block(fs, outdir, - &block_start))) - return retval; - offset = 0; - } - left = fs->blocksize - offset; - dirent = (struct ext2_dir_entry *) (block_start + offset); - if (offset == 0) { - if (ent->hash == prev_hash) - outdir->hashes[outdir->num-1] = ent->hash | 1; - else - outdir->hashes[outdir->num-1] = ent->hash; - } - dirent->inode = ent->dir->inode; - dirent->name_len = ent->dir->name_len; - dirent->rec_len = rec_len; - memcpy(dirent->name, ent->dir->name, dirent->name_len & 0xFF); - offset += rec_len; - left -= rec_len; - if (left < 12) { - dirent->rec_len += left; - offset += left; - left = 0; - } - prev_hash = ent->hash; - } - if (left) - dirent->rec_len += left; - - return 0; -} - - -static struct ext2_dx_root_info *set_root_node(ext2_filsys fs, char *buf, - ext2_ino_t ino, ext2_ino_t parent) -{ - struct ext2_dir_entry *dir; - struct ext2_dx_root_info *root; - struct ext2_dx_countlimit *limits; - int filetype = 0; - - if (fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_FILETYPE) - filetype = EXT2_FT_DIR << 8; - - memset(buf, 0, fs->blocksize); - dir = (struct ext2_dir_entry *) buf; - dir->inode = ino; - dir->name[0] = '.'; - dir->name_len = 1 | filetype; - dir->rec_len = 12; - dir = (struct ext2_dir_entry *) (buf + 12); - dir->inode = parent; - dir->name[0] = '.'; - dir->name[1] = '.'; - dir->name_len = 2 | filetype; - dir->rec_len = fs->blocksize - 12; - - root = (struct ext2_dx_root_info *) (buf+24); - root->reserved_zero = 0; - root->hash_version = fs->super->s_def_hash_version; - root->info_length = 8; - root->indirect_levels = 0; - root->unused_flags = 0; - - limits = (struct ext2_dx_countlimit *) (buf+32); - limits->limit = (fs->blocksize - 32) / sizeof(struct ext2_dx_entry); - limits->count = 0; - - return root; -} - - -static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf) -{ - struct ext2_dir_entry *dir; - struct ext2_dx_countlimit *limits; - - memset(buf, 0, fs->blocksize); - dir = (struct ext2_dir_entry *) buf; - dir->inode = 0; - dir->rec_len = fs->blocksize; - - limits = (struct ext2_dx_countlimit *) (buf+8); - limits->limit = (fs->blocksize - 8) / sizeof(struct ext2_dx_entry); - limits->count = 0; - - return (struct ext2_dx_entry *) limits; -} - -/* - * This function takes the leaf nodes which have been written in - * outdir, and populates the root node and any necessary interior nodes. - */ -static errcode_t calculate_tree(ext2_filsys fs, - struct out_dir *outdir, - ext2_ino_t ino, - ext2_ino_t parent) -{ - struct ext2_dx_root_info *root_info; - struct ext2_dx_entry *root, *dx_ent = NULL; - struct ext2_dx_countlimit *root_limit, *limit; - errcode_t retval; - char * block_start; - int i, c1, c2, nblks; - int limit_offset, root_offset; - - root_info = set_root_node(fs, outdir->buf, ino, parent); - root_offset = limit_offset = ((char *) root_info - outdir->buf) + - root_info->info_length; - root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset); - c1 = root_limit->limit; - nblks = outdir->num; - - /* Write out the pointer blocks */ - if (nblks-1 <= c1) { - /* Just write out the root block, and we're done */ - root = (struct ext2_dx_entry *) (outdir->buf + root_offset); - for (i=1; i < nblks; i++) { - root->block = ext2fs_cpu_to_le32(i); - if (i != 1) - root->hash = - ext2fs_cpu_to_le32(outdir->hashes[i]); - root++; - c1--; - } - } else { - c2 = 0; - limit = 0; - root_info->indirect_levels = 1; - for (i=1; i < nblks; i++) { - if (c1 == 0) - return ENOSPC; - if (c2 == 0) { - if (limit) - limit->limit = limit->count = - ext2fs_cpu_to_le16(limit->limit); - root = (struct ext2_dx_entry *) - (outdir->buf + root_offset); - root->block = ext2fs_cpu_to_le32(outdir->num); - if (i != 1) - root->hash = - ext2fs_cpu_to_le32(outdir->hashes[i]); - if ((retval = get_next_block(fs, outdir, - &block_start))) - return retval; - dx_ent = set_int_node(fs, block_start); - limit = (struct ext2_dx_countlimit *) dx_ent; - c2 = limit->limit; - root_offset += sizeof(struct ext2_dx_entry); - c1--; - } - dx_ent->block = ext2fs_cpu_to_le32(i); - if (c2 != limit->limit) - dx_ent->hash = - ext2fs_cpu_to_le32(outdir->hashes[i]); - dx_ent++; - c2--; - } - limit->count = ext2fs_cpu_to_le16(limit->limit - c2); - limit->limit = ext2fs_cpu_to_le16(limit->limit); - } - root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset); - root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1); - root_limit->limit = ext2fs_cpu_to_le16(root_limit->limit); - - return 0; -} - -struct write_dir_struct { - struct out_dir *outdir; - errcode_t err; - e2fsck_t ctx; - int cleared; -}; - -/* - * Helper function which writes out a directory block. - */ -static int write_dir_block(ext2_filsys fs, - blk_t *block_nr, - e2_blkcnt_t blockcnt, - blk_t ref_block FSCK_ATTR((unused)), - int ref_offset FSCK_ATTR((unused)), - void *priv_data) -{ - struct write_dir_struct *wd = (struct write_dir_struct *) priv_data; - blk_t blk; - char *dir; - - if (*block_nr == 0) - return 0; - if (blockcnt >= wd->outdir->num) { - e2fsck_read_bitmaps(wd->ctx); - blk = *block_nr; - ext2fs_unmark_block_bitmap(wd->ctx->block_found_map, blk); - ext2fs_block_alloc_stats(fs, blk, -1); - *block_nr = 0; - wd->cleared++; - return BLOCK_CHANGED; - } - if (blockcnt < 0) - return 0; - - dir = wd->outdir->buf + (blockcnt * fs->blocksize); - wd->err = ext2fs_write_dir_block(fs, *block_nr, dir); - if (wd->err) - return BLOCK_ABORT; - return 0; -} - -static errcode_t write_directory(e2fsck_t ctx, ext2_filsys fs, - struct out_dir *outdir, - ext2_ino_t ino, int compress) -{ - struct write_dir_struct wd; - errcode_t retval; - struct ext2_inode inode; - - retval = e2fsck_expand_directory(ctx, ino, -1, outdir->num); - if (retval) - return retval; - - wd.outdir = outdir; - wd.err = 0; - wd.ctx = ctx; - wd.cleared = 0; - - retval = ext2fs_block_iterate2(fs, ino, 0, 0, - write_dir_block, &wd); - if (retval) - return retval; - if (wd.err) - return wd.err; - - e2fsck_read_inode(ctx, ino, &inode, "rehash_dir"); - if (compress) - inode.i_flags &= ~EXT2_INDEX_FL; - else - inode.i_flags |= EXT2_INDEX_FL; - inode.i_size = outdir->num * fs->blocksize; - inode.i_blocks -= (fs->blocksize / 512) * wd.cleared; - e2fsck_write_inode(ctx, ino, &inode, "rehash_dir"); - - return 0; -} - -static errcode_t e2fsck_rehash_dir(e2fsck_t ctx, ext2_ino_t ino) -{ - ext2_filsys fs = ctx->fs; - errcode_t retval; - struct ext2_inode inode; - char *dir_buf = NULL; - struct fill_dir_struct fd; - struct out_dir outdir; - - outdir.max = outdir.num = 0; - outdir.buf = 0; - outdir.hashes = 0; - e2fsck_read_inode(ctx, ino, &inode, "rehash_dir"); - - retval = ENOMEM; - fd.harray = 0; - dir_buf = xmalloc(inode.i_size); - - fd.max_array = inode.i_size / 32; - fd.num_array = 0; - fd.harray = xmalloc(fd.max_array * sizeof(struct hash_entry)); - - fd.ctx = ctx; - fd.buf = dir_buf; - fd.inode = &inode; - fd.err = 0; - fd.dir_size = 0; - fd.compress = 0; - if (!(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) || - (inode.i_size / fs->blocksize) < 2) - fd.compress = 1; - fd.parent = 0; - - /* Read in the entire directory into memory */ - retval = ext2fs_block_iterate2(fs, ino, 0, 0, - fill_dir_block, &fd); - if (fd.err) { - retval = fd.err; - goto errout; - } - - /* Sort the list */ -resort: - if (fd.compress) - qsort(fd.harray+2, fd.num_array-2, - sizeof(struct hash_entry), name_cmp); - else - qsort(fd.harray, fd.num_array, - sizeof(struct hash_entry), hash_cmp); - - /* - * Look for duplicates - */ - if (duplicate_search_and_fix(ctx, fs, ino, &fd)) - goto resort; - - if (ctx->options & E2F_OPT_NO) { - retval = 0; - goto errout; - } - - /* - * Copy the directory entries. In a htree directory these - * will become the leaf nodes. - */ - retval = copy_dir_entries(fs, &fd, &outdir); - if (retval) - goto errout; - - free(dir_buf); dir_buf = 0; - - if (!fd.compress) { - /* Calculate the interior nodes */ - retval = calculate_tree(fs, &outdir, ino, fd.parent); - if (retval) - goto errout; - } - - retval = write_directory(ctx, fs, &outdir, ino, fd.compress); - -errout: - free(dir_buf); - free(fd.harray); - - free_out_dir(&outdir); - return retval; -} - -void e2fsck_rehash_directories(e2fsck_t ctx) -{ - struct problem_context pctx; - struct dir_info *dir; - ext2_u32_iterate iter; - ext2_ino_t ino; - errcode_t retval; - int i, cur, max, all_dirs, dir_index, first = 1; - - all_dirs = ctx->options & E2F_OPT_COMPRESS_DIRS; - - if (!ctx->dirs_to_hash && !all_dirs) - return; - - e2fsck_get_lost_and_found(ctx, 0); - - clear_problem_context(&pctx); - - dir_index = ctx->fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX; - cur = 0; - if (all_dirs) { - i = 0; - max = e2fsck_get_num_dirinfo(ctx); - } else { - retval = ext2fs_u32_list_iterate_begin(ctx->dirs_to_hash, - &iter); - if (retval) { - pctx.errcode = retval; - fix_problem(ctx, PR_3A_OPTIMIZE_ITER, &pctx); - return; - } - max = ext2fs_u32_list_count(ctx->dirs_to_hash); - } - while (1) { - if (all_dirs) { - if ((dir = e2fsck_dir_info_iter(ctx, &i)) == 0) - break; - ino = dir->ino; - } else { - if (!ext2fs_u32_list_iterate(iter, &ino)) - break; - } - if (ino == ctx->lost_and_found) - continue; - pctx.dir = ino; - if (first) { - fix_problem(ctx, PR_3A_PASS_HEADER, &pctx); - first = 0; - } - pctx.errcode = e2fsck_rehash_dir(ctx, ino); - if (pctx.errcode) { - end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR); - fix_problem(ctx, PR_3A_OPTIMIZE_DIR_ERR, &pctx); - } - if (ctx->progress && !ctx->progress_fd) - e2fsck_simple_progress(ctx, "Rebuilding directory", - 100.0 * (float) (++cur) / (float) max, ino); - } - end_problem_latch(ctx, PR_LATCH_OPTIMIZE_DIR); - if (!all_dirs) - ext2fs_u32_list_iterate_end(iter); - - ext2fs_u32_list_free(ctx->dirs_to_hash); - ctx->dirs_to_hash = 0; -} - -/* - * linux/fs/revoke.c - * - * Journal revoke routines for the generic filesystem journaling code; - * part of the ext2fs journaling system. - * - * Revoke is the mechanism used to prevent old log records for deleted - * metadata from being replayed on top of newer data using the same - * blocks. The revoke mechanism is used in two separate places: - * - * + Commit: during commit we write the entire list of the current - * transaction's revoked blocks to the journal - * - * + Recovery: during recovery we record the transaction ID of all - * revoked blocks. If there are multiple revoke records in the log - * for a single block, only the last one counts, and if there is a log - * entry for a block beyond the last revoke, then that log entry still - * gets replayed. - * - * We can get interactions between revokes and new log data within a - * single transaction: - * - * Block is revoked and then journaled: - * The desired end result is the journaling of the new block, so we - * cancel the revoke before the transaction commits. - * - * Block is journaled and then revoked: - * The revoke must take precedence over the write of the block, so we - * need either to cancel the journal entry or to write the revoke - * later in the log than the log block. In this case, we choose the - * latter: journaling a block cancels any revoke record for that block - * in the current transaction, so any revoke for that block in the - * transaction must have happened after the block was journaled and so - * the revoke must take precedence. - * - * Block is revoked and then written as data: - * The data write is allowed to succeed, but the revoke is _not_ - * cancelled. We still need to prevent old log records from - * overwriting the new data. We don't even need to clear the revoke - * bit here. - * - * Revoke information on buffers is a tri-state value: - * - * RevokeValid clear: no cached revoke status, need to look it up - * RevokeValid set, Revoked clear: - * buffer has not been revoked, and cancel_revoke - * need do nothing. - * RevokeValid set, Revoked set: - * buffer has been revoked. - */ - -static kmem_cache_t *revoke_record_cache; -static kmem_cache_t *revoke_table_cache; - -/* Each revoke record represents one single revoked block. During - journal replay, this involves recording the transaction ID of the - last transaction to revoke this block. */ - -struct jbd_revoke_record_s -{ - struct list_head hash; - tid_t sequence; /* Used for recovery only */ - unsigned long blocknr; -}; - - -/* The revoke table is just a simple hash table of revoke records. */ -struct jbd_revoke_table_s -{ - /* It is conceivable that we might want a larger hash table - * for recovery. Must be a power of two. */ - int hash_size; - int hash_shift; - struct list_head *hash_table; -}; - - -/* Utility functions to maintain the revoke table */ - -/* Borrowed from buffer.c: this is a tried and tested block hash function */ -static int hash(journal_t *journal, unsigned long block) -{ - struct jbd_revoke_table_s *table = journal->j_revoke; - int hash_shift = table->hash_shift; - - return ((block << (hash_shift - 6)) ^ - (block >> 13) ^ - (block << (hash_shift - 12))) & (table->hash_size - 1); -} - -static int insert_revoke_hash(journal_t *journal, unsigned long blocknr, - tid_t seq) -{ - struct list_head *hash_list; - struct jbd_revoke_record_s *record; - - record = kmem_cache_alloc(revoke_record_cache, GFP_NOFS); - if (!record) - goto oom; - - record->sequence = seq; - record->blocknr = blocknr; - hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)]; - list_add(&record->hash, hash_list); - return 0; - -oom: - return -ENOMEM; -} - -/* Find a revoke record in the journal's hash table. */ - -static struct jbd_revoke_record_s *find_revoke_record(journal_t *journal, - unsigned long blocknr) -{ - struct list_head *hash_list; - struct jbd_revoke_record_s *record; - - hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)]; - - record = (struct jbd_revoke_record_s *) hash_list->next; - while (&(record->hash) != hash_list) { - if (record->blocknr == blocknr) - return record; - record = (struct jbd_revoke_record_s *) record->hash.next; - } - return NULL; -} - -int journal_init_revoke_caches(void) -{ - revoke_record_cache = do_cache_create(sizeof(struct jbd_revoke_record_s)); - if (revoke_record_cache == 0) - return -ENOMEM; - - revoke_table_cache = do_cache_create(sizeof(struct jbd_revoke_table_s)); - if (revoke_table_cache == 0) { - do_cache_destroy(revoke_record_cache); - revoke_record_cache = NULL; - return -ENOMEM; - } - return 0; -} - -void journal_destroy_revoke_caches(void) -{ - do_cache_destroy(revoke_record_cache); - revoke_record_cache = 0; - do_cache_destroy(revoke_table_cache); - revoke_table_cache = 0; -} - -/* Initialise the revoke table for a given journal to a given size. */ - -int journal_init_revoke(journal_t *journal, int hash_size) -{ - int shift, tmp; - - journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL); - if (!journal->j_revoke) - return -ENOMEM; - - /* Check that the hash_size is a power of two */ - journal->j_revoke->hash_size = hash_size; - - shift = 0; - tmp = hash_size; - while ((tmp >>= 1UL) != 0UL) - shift++; - journal->j_revoke->hash_shift = shift; - - journal->j_revoke->hash_table = xmalloc(hash_size * sizeof(struct list_head)); - - for (tmp = 0; tmp < hash_size; tmp++) - INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]); - - return 0; -} - -/* Destoy a journal's revoke table. The table must already be empty! */ - -void journal_destroy_revoke(journal_t *journal) -{ - struct jbd_revoke_table_s *table; - struct list_head *hash_list; - int i; - - table = journal->j_revoke; - if (!table) - return; - - for (i=0; ihash_size; i++) { - hash_list = &table->hash_table[i]; - } - - free(table->hash_table); - free(table); - journal->j_revoke = NULL; -} - -/* - * Revoke support for recovery. - * - * Recovery needs to be able to: - * - * record all revoke records, including the tid of the latest instance - * of each revoke in the journal - * - * check whether a given block in a given transaction should be replayed - * (ie. has not been revoked by a revoke record in that or a subsequent - * transaction) - * - * empty the revoke table after recovery. - */ - -/* - * First, setting revoke records. We create a new revoke record for - * every block ever revoked in the log as we scan it for recovery, and - * we update the existing records if we find multiple revokes for a - * single block. - */ - -int journal_set_revoke(journal_t *journal, unsigned long blocknr, - tid_t sequence) -{ - struct jbd_revoke_record_s *record; - - record = find_revoke_record(journal, blocknr); - if (record) { - /* If we have multiple occurences, only record the - * latest sequence number in the hashed record */ - if (tid_gt(sequence, record->sequence)) - record->sequence = sequence; - return 0; - } - return insert_revoke_hash(journal, blocknr, sequence); -} - -/* - * Test revoke records. For a given block referenced in the log, has - * that block been revoked? A revoke record with a given transaction - * sequence number revokes all blocks in that transaction and earlier - * ones, but later transactions still need replayed. - */ - -int journal_test_revoke(journal_t *journal, unsigned long blocknr, - tid_t sequence) -{ - struct jbd_revoke_record_s *record; - - record = find_revoke_record(journal, blocknr); - if (!record) - return 0; - if (tid_gt(sequence, record->sequence)) - return 0; - return 1; -} - -/* - * Finally, once recovery is over, we need to clear the revoke table so - * that it can be reused by the running filesystem. - */ - -void journal_clear_revoke(journal_t *journal) -{ - int i; - struct list_head *hash_list; - struct jbd_revoke_record_s *record; - struct jbd_revoke_table_s *revoke_var; - - revoke_var = journal->j_revoke; - - for (i = 0; i < revoke_var->hash_size; i++) { - hash_list = &revoke_var->hash_table[i]; - while (!list_empty(hash_list)) { - record = (struct jbd_revoke_record_s*) hash_list->next; - list_del(&record->hash); - free(record); - } - } -} - -/* - * e2fsck.c - superblock checks - */ - -#define MIN_CHECK 1 -#define MAX_CHECK 2 - -static void check_super_value(e2fsck_t ctx, const char *descr, - unsigned long value, int flags, - unsigned long min_val, unsigned long max_val) -{ - struct problem_context pctx; - - if (((flags & MIN_CHECK) && (value < min_val)) || - ((flags & MAX_CHECK) && (value > max_val))) { - clear_problem_context(&pctx); - pctx.num = value; - pctx.str = descr; - fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx); - ctx->flags |= E2F_FLAG_ABORT; /* never get here! */ - } -} - -/* - * This routine may get stubbed out in special compilations of the - * e2fsck code.. - */ -#ifndef EXT2_SPECIAL_DEVICE_SIZE -static errcode_t e2fsck_get_device_size(e2fsck_t ctx) -{ - return (ext2fs_get_device_size(ctx->filesystem_name, - EXT2_BLOCK_SIZE(ctx->fs->super), - &ctx->num_blocks)); -} -#endif - -/* - * helper function to release an inode - */ -struct process_block_struct { - e2fsck_t ctx; - char *buf; - struct problem_context *pctx; - int truncating; - int truncate_offset; - e2_blkcnt_t truncate_block; - int truncated_blocks; - int abort; - errcode_t errcode; -}; - -static int release_inode_block(ext2_filsys fs, blk_t *block_nr, - e2_blkcnt_t blockcnt, - blk_t ref_blk FSCK_ATTR((unused)), - int ref_offset FSCK_ATTR((unused)), - void *priv_data) -{ - struct process_block_struct *pb; - e2fsck_t ctx; - struct problem_context *pctx; - blk_t blk = *block_nr; - int retval = 0; - - pb = (struct process_block_struct *) priv_data; - ctx = pb->ctx; - pctx = pb->pctx; - - pctx->blk = blk; - pctx->blkcount = blockcnt; - - if (HOLE_BLKADDR(blk)) - return 0; - - if ((blk < fs->super->s_first_data_block) || - (blk >= fs->super->s_blocks_count)) { - fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_BLOCK_NUM, pctx); - return_abort: - pb->abort = 1; - return BLOCK_ABORT; - } - - if (!ext2fs_test_block_bitmap(fs->block_map, blk)) { - fix_problem(ctx, PR_0_ORPHAN_ALREADY_CLEARED_BLOCK, pctx); - goto return_abort; - } - - /* - * If we are deleting an orphan, then we leave the fields alone. - * If we are truncating an orphan, then update the inode fields - * and clean up any partial block data. - */ - if (pb->truncating) { - /* - * We only remove indirect blocks if they are - * completely empty. - */ - if (blockcnt < 0) { - int i, limit; - blk_t *bp; - - pb->errcode = io_channel_read_blk(fs->io, blk, 1, - pb->buf); - if (pb->errcode) - goto return_abort; - - limit = fs->blocksize >> 2; - for (i = 0, bp = (blk_t *) pb->buf; - i < limit; i++, bp++) - if (*bp) - return 0; - } - /* - * We don't remove direct blocks until we've reached - * the truncation block. - */ - if (blockcnt >= 0 && blockcnt < pb->truncate_block) - return 0; - /* - * If part of the last block needs truncating, we do - * it here. - */ - if ((blockcnt == pb->truncate_block) && pb->truncate_offset) { - pb->errcode = io_channel_read_blk(fs->io, blk, 1, - pb->buf); - if (pb->errcode) - goto return_abort; - memset(pb->buf + pb->truncate_offset, 0, - fs->blocksize - pb->truncate_offset); - pb->errcode = io_channel_write_blk(fs->io, blk, 1, - pb->buf); - if (pb->errcode) - goto return_abort; - } - pb->truncated_blocks++; - *block_nr = 0; - retval |= BLOCK_CHANGED; - } - - ext2fs_block_alloc_stats(fs, blk, -1); - return retval; -} - -/* - * This function releases an inode. Returns 1 if an inconsistency was - * found. If the inode has a link count, then it is being truncated and - * not deleted. - */ -static int release_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, - struct ext2_inode *inode, char *block_buf, - struct problem_context *pctx) -{ - struct process_block_struct pb; - ext2_filsys fs = ctx->fs; - errcode_t retval; - __u32 count; - - if (!ext2fs_inode_has_valid_blocks(inode)) - return 0; - - pb.buf = block_buf + 3 * ctx->fs->blocksize; - pb.ctx = ctx; - pb.abort = 0; - pb.errcode = 0; - pb.pctx = pctx; - if (inode->i_links_count) { - pb.truncating = 1; - pb.truncate_block = (e2_blkcnt_t) - ((((long long)inode->i_size_high << 32) + - inode->i_size + fs->blocksize - 1) / - fs->blocksize); - pb.truncate_offset = inode->i_size % fs->blocksize; - } else { - pb.truncating = 0; - pb.truncate_block = 0; - pb.truncate_offset = 0; - } - pb.truncated_blocks = 0; - retval = ext2fs_block_iterate2(fs, ino, BLOCK_FLAG_DEPTH_TRAVERSE, - block_buf, release_inode_block, &pb); - if (retval) { - bb_error_msg(_("while calling ext2fs_block_iterate for inode %d"), - ino); - return 1; - } - if (pb.abort) - return 1; - - /* Refresh the inode since ext2fs_block_iterate may have changed it */ - e2fsck_read_inode(ctx, ino, inode, "release_inode_blocks"); - - if (pb.truncated_blocks) - inode->i_blocks -= pb.truncated_blocks * - (fs->blocksize / 512); - - if (inode->i_file_acl) { - retval = ext2fs_adjust_ea_refcount(fs, inode->i_file_acl, - block_buf, -1, &count); - if (retval == EXT2_ET_BAD_EA_BLOCK_NUM) { - retval = 0; - count = 1; - } - if (retval) { - bb_error_msg(_("while calling ext2fs_adjust_ea_refocunt for inode %d"), - ino); - return 1; - } - if (count == 0) - ext2fs_block_alloc_stats(fs, inode->i_file_acl, -1); - inode->i_file_acl = 0; - } - return 0; -} - -/* - * This function releases all of the orphan inodes. It returns 1 if - * it hit some error, and 0 on success. - */ -static int release_orphan_inodes(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - ext2_ino_t ino, next_ino; - struct ext2_inode inode; - struct problem_context pctx; - char *block_buf; - - if ((ino = fs->super->s_last_orphan) == 0) - return 0; - - /* - * Win or lose, we won't be using the head of the orphan inode - * list again. - */ - fs->super->s_last_orphan = 0; - ext2fs_mark_super_dirty(fs); - - /* - * If the filesystem contains errors, don't run the orphan - * list, since the orphan list can't be trusted; and we're - * going to be running a full e2fsck run anyway... - */ - if (fs->super->s_state & EXT2_ERROR_FS) - return 0; - - if ((ino < EXT2_FIRST_INODE(fs->super)) || - (ino > fs->super->s_inodes_count)) { - clear_problem_context(&pctx); - pctx.ino = ino; - fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_HEAD_INODE, &pctx); - return 1; - } - - block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4, - "block iterate buffer"); - e2fsck_read_bitmaps(ctx); - - while (ino) { - e2fsck_read_inode(ctx, ino, &inode, "release_orphan_inodes"); - clear_problem_context(&pctx); - pctx.ino = ino; - pctx.inode = &inode; - pctx.str = inode.i_links_count ? _("Truncating") : - _("Clearing"); - - fix_problem(ctx, PR_0_ORPHAN_CLEAR_INODE, &pctx); - - next_ino = inode.i_dtime; - if (next_ino && - ((next_ino < EXT2_FIRST_INODE(fs->super)) || - (next_ino > fs->super->s_inodes_count))) { - pctx.ino = next_ino; - fix_problem(ctx, PR_0_ORPHAN_ILLEGAL_INODE, &pctx); - goto return_abort; - } - - if (release_inode_blocks(ctx, ino, &inode, block_buf, &pctx)) - goto return_abort; - - if (!inode.i_links_count) { - ext2fs_inode_alloc_stats2(fs, ino, -1, - LINUX_S_ISDIR(inode.i_mode)); - inode.i_dtime = time(NULL); - } else { - inode.i_dtime = 0; - } - e2fsck_write_inode(ctx, ino, &inode, "delete_file"); - ino = next_ino; - } - ext2fs_free_mem(&block_buf); - return 0; - return_abort: - ext2fs_free_mem(&block_buf); - return 1; -} - -/* - * Check the resize inode to make sure it is sane. We check both for - * the case where on-line resizing is not enabled (in which case the - * resize inode should be cleared) as well as the case where on-line - * resizing is enabled. - */ -static void check_resize_inode(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - struct ext2_inode inode; - struct problem_context pctx; - int i, j, gdt_off, ind_off; - blk_t blk, pblk, expect; - __u32 *dind_buf = NULL, *ind_buf; - errcode_t retval; - - clear_problem_context(&pctx); - - /* - * If the resize inode feature isn't set, then - * s_reserved_gdt_blocks must be zero. - */ - if (!(fs->super->s_feature_compat & - EXT2_FEATURE_COMPAT_RESIZE_INO)) { - if (fs->super->s_reserved_gdt_blocks) { - pctx.num = fs->super->s_reserved_gdt_blocks; - if (fix_problem(ctx, PR_0_NONZERO_RESERVED_GDT_BLOCKS, - &pctx)) { - fs->super->s_reserved_gdt_blocks = 0; - ext2fs_mark_super_dirty(fs); - } - } - } - - /* Read the resize inode */ - pctx.ino = EXT2_RESIZE_INO; - retval = ext2fs_read_inode(fs, EXT2_RESIZE_INO, &inode); - if (retval) { - if (fs->super->s_feature_compat & - EXT2_FEATURE_COMPAT_RESIZE_INO) - ctx->flags |= E2F_FLAG_RESIZE_INODE; - return; - } - - /* - * If the resize inode feature isn't set, check to make sure - * the resize inode is cleared; then we're done. - */ - if (!(fs->super->s_feature_compat & - EXT2_FEATURE_COMPAT_RESIZE_INO)) { - for (i=0; i < EXT2_N_BLOCKS; i++) { - if (inode.i_block[i]) - break; - } - if ((i < EXT2_N_BLOCKS) && - fix_problem(ctx, PR_0_CLEAR_RESIZE_INODE, &pctx)) { - memset(&inode, 0, sizeof(inode)); - e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode, - "clear_resize"); - } - return; - } - - /* - * The resize inode feature is enabled; check to make sure the - * only block in use is the double indirect block - */ - blk = inode.i_block[EXT2_DIND_BLOCK]; - for (i=0; i < EXT2_N_BLOCKS; i++) { - if (i != EXT2_DIND_BLOCK && inode.i_block[i]) - break; - } - if ((i < EXT2_N_BLOCKS) || !blk || !inode.i_links_count || - !(inode.i_mode & LINUX_S_IFREG) || - (blk < fs->super->s_first_data_block || - blk >= fs->super->s_blocks_count)) { - resize_inode_invalid: - if (fix_problem(ctx, PR_0_RESIZE_INODE_INVALID, &pctx)) { - memset(&inode, 0, sizeof(inode)); - e2fsck_write_inode(ctx, EXT2_RESIZE_INO, &inode, - "clear_resize"); - ctx->flags |= E2F_FLAG_RESIZE_INODE; - } - if (!(ctx->options & E2F_OPT_READONLY)) { - fs->super->s_state &= ~EXT2_VALID_FS; - ext2fs_mark_super_dirty(fs); - } - goto cleanup; - } - dind_buf = (__u32 *) e2fsck_allocate_memory(ctx, fs->blocksize * 2, - "resize dind buffer"); - ind_buf = (__u32 *) ((char *) dind_buf + fs->blocksize); - - retval = ext2fs_read_ind_block(fs, blk, dind_buf); - if (retval) - goto resize_inode_invalid; - - gdt_off = fs->desc_blocks; - pblk = fs->super->s_first_data_block + 1 + fs->desc_blocks; - for (i = 0; i < fs->super->s_reserved_gdt_blocks / 4; - i++, gdt_off++, pblk++) { - gdt_off %= fs->blocksize/4; - if (dind_buf[gdt_off] != pblk) - goto resize_inode_invalid; - retval = ext2fs_read_ind_block(fs, pblk, ind_buf); - if (retval) - goto resize_inode_invalid; - ind_off = 0; - for (j = 1; j < fs->group_desc_count; j++) { - if (!ext2fs_bg_has_super(fs, j)) - continue; - expect = pblk + (j * fs->super->s_blocks_per_group); - if (ind_buf[ind_off] != expect) - goto resize_inode_invalid; - ind_off++; - } - } - - cleanup: - ext2fs_free_mem(&dind_buf); -} - -static void check_super_block(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - blk_t first_block, last_block; - struct ext2_super_block *sb = fs->super; - struct ext2_group_desc *gd; - blk_t blocks_per_group = fs->super->s_blocks_per_group; - blk_t bpg_max; - int inodes_per_block; - int ipg_max; - int inode_size; - dgrp_t i; - blk_t should_be; - struct problem_context pctx; - __u32 free_blocks = 0, free_inodes = 0; - - inodes_per_block = EXT2_INODES_PER_BLOCK(fs->super); - ipg_max = inodes_per_block * (blocks_per_group - 4); - if (ipg_max > EXT2_MAX_INODES_PER_GROUP(sb)) - ipg_max = EXT2_MAX_INODES_PER_GROUP(sb); - bpg_max = 8 * EXT2_BLOCK_SIZE(sb); - if (bpg_max > EXT2_MAX_BLOCKS_PER_GROUP(sb)) - bpg_max = EXT2_MAX_BLOCKS_PER_GROUP(sb); - - ctx->invalid_inode_bitmap_flag = (int *) e2fsck_allocate_memory(ctx, - sizeof(int) * fs->group_desc_count, "invalid_inode_bitmap"); - ctx->invalid_block_bitmap_flag = (int *) e2fsck_allocate_memory(ctx, - sizeof(int) * fs->group_desc_count, "invalid_block_bitmap"); - ctx->invalid_inode_table_flag = (int *) e2fsck_allocate_memory(ctx, - sizeof(int) * fs->group_desc_count, "invalid_inode_table"); - - clear_problem_context(&pctx); - - /* - * Verify the super block constants... - */ - check_super_value(ctx, "inodes_count", sb->s_inodes_count, - MIN_CHECK, 1, 0); - check_super_value(ctx, "blocks_count", sb->s_blocks_count, - MIN_CHECK, 1, 0); - check_super_value(ctx, "first_data_block", sb->s_first_data_block, - MAX_CHECK, 0, sb->s_blocks_count); - check_super_value(ctx, "log_block_size", sb->s_log_block_size, - MIN_CHECK | MAX_CHECK, 0, - EXT2_MAX_BLOCK_LOG_SIZE - EXT2_MIN_BLOCK_LOG_SIZE); - check_super_value(ctx, "log_frag_size", sb->s_log_frag_size, - MIN_CHECK | MAX_CHECK, 0, sb->s_log_block_size); - check_super_value(ctx, "frags_per_group", sb->s_frags_per_group, - MIN_CHECK | MAX_CHECK, sb->s_blocks_per_group, - bpg_max); - check_super_value(ctx, "blocks_per_group", sb->s_blocks_per_group, - MIN_CHECK | MAX_CHECK, 8, bpg_max); - check_super_value(ctx, "inodes_per_group", sb->s_inodes_per_group, - MIN_CHECK | MAX_CHECK, inodes_per_block, ipg_max); - check_super_value(ctx, "r_blocks_count", sb->s_r_blocks_count, - MAX_CHECK, 0, sb->s_blocks_count / 2); - check_super_value(ctx, "reserved_gdt_blocks", - sb->s_reserved_gdt_blocks, MAX_CHECK, 0, - fs->blocksize/4); - inode_size = EXT2_INODE_SIZE(sb); - check_super_value(ctx, "inode_size", - inode_size, MIN_CHECK | MAX_CHECK, - EXT2_GOOD_OLD_INODE_SIZE, fs->blocksize); - if (inode_size & (inode_size - 1)) { - pctx.num = inode_size; - pctx.str = "inode_size"; - fix_problem(ctx, PR_0_MISC_CORRUPT_SUPER, &pctx); - ctx->flags |= E2F_FLAG_ABORT; /* never get here! */ - return; - } - - if (!ctx->num_blocks) { - pctx.errcode = e2fsck_get_device_size(ctx); - if (pctx.errcode && pctx.errcode != EXT2_ET_UNIMPLEMENTED) { - fix_problem(ctx, PR_0_GETSIZE_ERROR, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - if ((pctx.errcode != EXT2_ET_UNIMPLEMENTED) && - (ctx->num_blocks < sb->s_blocks_count)) { - pctx.blk = sb->s_blocks_count; - pctx.blk2 = ctx->num_blocks; - if (fix_problem(ctx, PR_0_FS_SIZE_WRONG, &pctx)) { - ctx->flags |= E2F_FLAG_ABORT; - return; - } - } - } - - if (sb->s_log_block_size != (__u32) sb->s_log_frag_size) { - pctx.blk = EXT2_BLOCK_SIZE(sb); - pctx.blk2 = EXT2_FRAG_SIZE(sb); - fix_problem(ctx, PR_0_NO_FRAGMENTS, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - - should_be = sb->s_frags_per_group >> - (sb->s_log_block_size - sb->s_log_frag_size); - if (sb->s_blocks_per_group != should_be) { - pctx.blk = sb->s_blocks_per_group; - pctx.blk2 = should_be; - fix_problem(ctx, PR_0_BLOCKS_PER_GROUP, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - - should_be = (sb->s_log_block_size == 0) ? 1 : 0; - if (sb->s_first_data_block != should_be) { - pctx.blk = sb->s_first_data_block; - pctx.blk2 = should_be; - fix_problem(ctx, PR_0_FIRST_DATA_BLOCK, &pctx); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - - should_be = sb->s_inodes_per_group * fs->group_desc_count; - if (sb->s_inodes_count != should_be) { - pctx.ino = sb->s_inodes_count; - pctx.ino2 = should_be; - if (fix_problem(ctx, PR_0_INODE_COUNT_WRONG, &pctx)) { - sb->s_inodes_count = should_be; - ext2fs_mark_super_dirty(fs); - } - } - - /* - * Verify the group descriptors.... - */ - first_block = sb->s_first_data_block; - last_block = first_block + blocks_per_group; - - for (i = 0, gd=fs->group_desc; i < fs->group_desc_count; i++, gd++) { - pctx.group = i; - - if (i == fs->group_desc_count - 1) - last_block = sb->s_blocks_count; - if ((gd->bg_block_bitmap < first_block) || - (gd->bg_block_bitmap >= last_block)) { - pctx.blk = gd->bg_block_bitmap; - if (fix_problem(ctx, PR_0_BB_NOT_GROUP, &pctx)) - gd->bg_block_bitmap = 0; - } - if (gd->bg_block_bitmap == 0) { - ctx->invalid_block_bitmap_flag[i]++; - ctx->invalid_bitmaps++; - } - if ((gd->bg_inode_bitmap < first_block) || - (gd->bg_inode_bitmap >= last_block)) { - pctx.blk = gd->bg_inode_bitmap; - if (fix_problem(ctx, PR_0_IB_NOT_GROUP, &pctx)) - gd->bg_inode_bitmap = 0; - } - if (gd->bg_inode_bitmap == 0) { - ctx->invalid_inode_bitmap_flag[i]++; - ctx->invalid_bitmaps++; - } - if ((gd->bg_inode_table < first_block) || - ((gd->bg_inode_table + - fs->inode_blocks_per_group - 1) >= last_block)) { - pctx.blk = gd->bg_inode_table; - if (fix_problem(ctx, PR_0_ITABLE_NOT_GROUP, &pctx)) - gd->bg_inode_table = 0; - } - if (gd->bg_inode_table == 0) { - ctx->invalid_inode_table_flag[i]++; - ctx->invalid_bitmaps++; - } - free_blocks += gd->bg_free_blocks_count; - free_inodes += gd->bg_free_inodes_count; - first_block += sb->s_blocks_per_group; - last_block += sb->s_blocks_per_group; - - if ((gd->bg_free_blocks_count > sb->s_blocks_per_group) || - (gd->bg_free_inodes_count > sb->s_inodes_per_group) || - (gd->bg_used_dirs_count > sb->s_inodes_per_group)) - ext2fs_unmark_valid(fs); - } - - /* - * Update the global counts from the block group counts. This - * is needed for an experimental patch which eliminates - * locking the entire filesystem when allocating blocks or - * inodes; if the filesystem is not unmounted cleanly, the - * global counts may not be accurate. - */ - if ((free_blocks != sb->s_free_blocks_count) || - (free_inodes != sb->s_free_inodes_count)) { - if (ctx->options & E2F_OPT_READONLY) - ext2fs_unmark_valid(fs); - else { - sb->s_free_blocks_count = free_blocks; - sb->s_free_inodes_count = free_inodes; - ext2fs_mark_super_dirty(fs); - } - } - - if ((sb->s_free_blocks_count > sb->s_blocks_count) || - (sb->s_free_inodes_count > sb->s_inodes_count)) - ext2fs_unmark_valid(fs); - - - /* - * If we have invalid bitmaps, set the error state of the - * filesystem. - */ - if (ctx->invalid_bitmaps && !(ctx->options & E2F_OPT_READONLY)) { - sb->s_state &= ~EXT2_VALID_FS; - ext2fs_mark_super_dirty(fs); - } - - clear_problem_context(&pctx); - - /* - * If the UUID field isn't assigned, assign it. - */ - if (!(ctx->options & E2F_OPT_READONLY) && uuid_is_null(sb->s_uuid)) { - if (fix_problem(ctx, PR_0_ADD_UUID, &pctx)) { - uuid_generate(sb->s_uuid); - ext2fs_mark_super_dirty(fs); - fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; - } - } - - /* FIXME - HURD support? - * For the Hurd, check to see if the filetype option is set, - * since it doesn't support it. - */ - if (!(ctx->options & E2F_OPT_READONLY) && - fs->super->s_creator_os == EXT2_OS_HURD && - (fs->super->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_FILETYPE)) { - if (fix_problem(ctx, PR_0_HURD_CLEAR_FILETYPE, &pctx)) { - fs->super->s_feature_incompat &= - ~EXT2_FEATURE_INCOMPAT_FILETYPE; - ext2fs_mark_super_dirty(fs); - } - } - - /* - * If we have any of the compatibility flags set, we need to have a - * revision 1 filesystem. Most kernels will not check the flags on - * a rev 0 filesystem and we may have corruption issues because of - * the incompatible changes to the filesystem. - */ - if (!(ctx->options & E2F_OPT_READONLY) && - fs->super->s_rev_level == EXT2_GOOD_OLD_REV && - (fs->super->s_feature_compat || - fs->super->s_feature_ro_compat || - fs->super->s_feature_incompat) && - fix_problem(ctx, PR_0_FS_REV_LEVEL, &pctx)) { - ext2fs_update_dynamic_rev(fs); - ext2fs_mark_super_dirty(fs); - } - - check_resize_inode(ctx); - - /* - * Clean up any orphan inodes, if present. - */ - if (!(ctx->options & E2F_OPT_READONLY) && release_orphan_inodes(ctx)) { - fs->super->s_state &= ~EXT2_VALID_FS; - ext2fs_mark_super_dirty(fs); - } - - /* - * Move the ext3 journal file, if necessary. - */ - e2fsck_move_ext3_journal(ctx); -} - -/* - * swapfs.c --- byte-swap an ext2 filesystem - */ - -#ifdef ENABLE_SWAPFS - -struct swap_block_struct { - ext2_ino_t ino; - int isdir; - errcode_t errcode; - char *dir_buf; - struct ext2_inode *inode; -}; - -/* - * This is a helper function for block_iterate. We mark all of the - * indirect and direct blocks as changed, so that block_iterate will - * write them out. - */ -static int swap_block(ext2_filsys fs, blk_t *block_nr, int blockcnt, - void *priv_data) -{ - errcode_t retval; - - struct swap_block_struct *sb = (struct swap_block_struct *) priv_data; - - if (sb->isdir && (blockcnt >= 0) && *block_nr) { - retval = ext2fs_read_dir_block(fs, *block_nr, sb->dir_buf); - if (retval) { - sb->errcode = retval; - return BLOCK_ABORT; - } - retval = ext2fs_write_dir_block(fs, *block_nr, sb->dir_buf); - if (retval) { - sb->errcode = retval; - return BLOCK_ABORT; - } - } - if (blockcnt >= 0) { - if (blockcnt < EXT2_NDIR_BLOCKS) - return 0; - return BLOCK_CHANGED; - } - if (blockcnt == BLOCK_COUNT_IND) { - if (*block_nr == sb->inode->i_block[EXT2_IND_BLOCK]) - return 0; - return BLOCK_CHANGED; - } - if (blockcnt == BLOCK_COUNT_DIND) { - if (*block_nr == sb->inode->i_block[EXT2_DIND_BLOCK]) - return 0; - return BLOCK_CHANGED; - } - if (blockcnt == BLOCK_COUNT_TIND) { - if (*block_nr == sb->inode->i_block[EXT2_TIND_BLOCK]) - return 0; - return BLOCK_CHANGED; - } - return BLOCK_CHANGED; -} - -/* - * This function is responsible for byte-swapping all of the indirect, - * block pointers. It is also responsible for byte-swapping directories. - */ -static void swap_inode_blocks(e2fsck_t ctx, ext2_ino_t ino, char *block_buf, - struct ext2_inode *inode) -{ - errcode_t retval; - struct swap_block_struct sb; - - sb.ino = ino; - sb.inode = inode; - sb.dir_buf = block_buf + ctx->fs->blocksize*3; - sb.errcode = 0; - sb.isdir = 0; - if (LINUX_S_ISDIR(inode->i_mode)) - sb.isdir = 1; - - retval = ext2fs_block_iterate(ctx->fs, ino, 0, block_buf, - swap_block, &sb); - if (retval) { - bb_error_msg(_("while calling ext2fs_block_iterate")); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - if (sb.errcode) { - bb_error_msg(_("while calling iterator function")); - ctx->flags |= E2F_FLAG_ABORT; - return; - } -} - -static void swap_inodes(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - dgrp_t group; - unsigned int i; - ext2_ino_t ino = 1; - char *buf, *block_buf; - errcode_t retval; - struct ext2_inode * inode; - - e2fsck_use_inode_shortcuts(ctx, 1); - - retval = ext2fs_get_mem(fs->blocksize * fs->inode_blocks_per_group, - &buf); - if (retval) { - bb_error_msg(_("while allocating inode buffer")); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 4, - "block interate buffer"); - for (group = 0; group < fs->group_desc_count; group++) { - retval = io_channel_read_blk(fs->io, - fs->group_desc[group].bg_inode_table, - fs->inode_blocks_per_group, buf); - if (retval) { - bb_error_msg(_("while reading inode table (group %d)"), - group); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - inode = (struct ext2_inode *) buf; - for (i=0; i < fs->super->s_inodes_per_group; - i++, ino++, inode++) { - ctx->stashed_ino = ino; - ctx->stashed_inode = inode; - - if (fs->flags & EXT2_FLAG_SWAP_BYTES_READ) - ext2fs_swap_inode(fs, inode, inode, 0); - - /* - * Skip deleted files. - */ - if (inode->i_links_count == 0) - continue; - - if (LINUX_S_ISDIR(inode->i_mode) || - ((inode->i_block[EXT2_IND_BLOCK] || - inode->i_block[EXT2_DIND_BLOCK] || - inode->i_block[EXT2_TIND_BLOCK]) && - ext2fs_inode_has_valid_blocks(inode))) - swap_inode_blocks(ctx, ino, block_buf, inode); - - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - - if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE) - ext2fs_swap_inode(fs, inode, inode, 1); - } - retval = io_channel_write_blk(fs->io, - fs->group_desc[group].bg_inode_table, - fs->inode_blocks_per_group, buf); - if (retval) { - bb_error_msg(_("while writing inode table (group %d)"), - group); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - } - ext2fs_free_mem(&buf); - ext2fs_free_mem(&block_buf); - e2fsck_use_inode_shortcuts(ctx, 0); - ext2fs_flush_icache(fs); -} - -#if defined(__powerpc__) && BB_BIG_ENDIAN -/* - * 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(ext2fs_generic_bitmap bmap) -{ - __u32 *p = (__u32 *) bmap->bitmap; - int n, nbytes = (bmap->end - bmap->start + 7) / 8; - - for (n = nbytes / sizeof(__u32); n > 0; --n, ++p) - *p = ext2fs_swab32(*p); -} -#endif - - -#ifdef ENABLE_SWAPFS -static void swap_filesys(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - if (!(ctx->options & E2F_OPT_PREEN)) - printf(_("Pass 0: Doing byte-swap of filesystem\n")); - - /* Byte swap */ - - if (fs->super->s_mnt_count) { - fprintf(stderr, _("%s: the filesystem must be freshly " - "checked using fsck\n" - "and not mounted before trying to " - "byte-swap it.\n"), ctx->device_name); - ctx->flags |= E2F_FLAG_ABORT; - return; - } - if (fs->flags & EXT2_FLAG_SWAP_BYTES) { - fs->flags &= ~(EXT2_FLAG_SWAP_BYTES| - EXT2_FLAG_SWAP_BYTES_WRITE); - fs->flags |= EXT2_FLAG_SWAP_BYTES_READ; - } else { - fs->flags &= ~EXT2_FLAG_SWAP_BYTES_READ; - fs->flags |= EXT2_FLAG_SWAP_BYTES_WRITE; - } - swap_inodes(ctx); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - return; - if (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE) - fs->flags |= EXT2_FLAG_SWAP_BYTES; - fs->flags &= ~(EXT2_FLAG_SWAP_BYTES_READ| - EXT2_FLAG_SWAP_BYTES_WRITE); - -#ifdef EXT2_BIG_ENDIAN_BITMAPS - e2fsck_read_bitmaps(ctx); - ext2fs_swap_bitmap(fs->inode_map); - ext2fs_swap_bitmap(fs->block_map); - fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_IB_DIRTY; -#endif - fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY; - ext2fs_flush(fs); - fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; -} -#endif /* ENABLE_SWAPFS */ - -#endif - -/* - * util.c --- miscellaneous utilities - */ - - -void *e2fsck_allocate_memory(e2fsck_t ctx, unsigned int size, - const char *description) -{ - return xzalloc(size); -} - -static char *string_copy(const char *str, int len) -{ - char *ret; - - if (!str) - return NULL; - if (!len) - len = strlen(str); - ret = xmalloc(len+1); - strncpy(ret, str, len); - ret[len] = 0; - return ret; -} - -#ifndef HAVE_CONIO_H -static int read_a_char(void) -{ - char c; - int r; - int fail = 0; - - while (1) { - if (e2fsck_global_ctx && - (e2fsck_global_ctx->flags & E2F_FLAG_CANCEL)) { - return 3; - } - r = read(0, &c, 1); - if (r == 1) - return c; - if (fail++ > 100) - break; - } - return EOF; -} -#endif - -static int ask_yn(const char * string, int def) -{ - int c; - const char *defstr; - static const char short_yes[] = "yY"; - static const char short_no[] = "nN"; - -#ifdef HAVE_TERMIOS_H - struct termios termios, tmp; - - tcgetattr (0, &termios); - tmp = termios; - tmp.c_lflag &= ~(ICANON | ECHO); - tmp.c_cc[VMIN] = 1; - tmp.c_cc[VTIME] = 0; - tcsetattr_stdin_TCSANOW(&tmp); -#endif - - if (def == 1) - defstr = ""; - else if (def == 0) - defstr = ""; - else - defstr = " (y/n)"; - printf("%s%s? ", string, defstr); - while (1) { - fflush (stdout); - if ((c = read_a_char()) == EOF) - break; - if (c == 3) { -#ifdef HAVE_TERMIOS_H - tcsetattr_stdin_TCSANOW(&termios); -#endif - if (e2fsck_global_ctx && - e2fsck_global_ctx->flags & E2F_FLAG_SETJMP_OK) { - puts("\n"); - longjmp(e2fsck_global_ctx->abort_loc, 1); - } - puts(_("cancelled!\n")); - return 0; - } - if (strchr(short_yes, (char) c)) { - def = 1; - break; - } - else if (strchr(short_no, (char) c)) { - def = 0; - break; - } - else if ((c == ' ' || c == '\n') && (def != -1)) - break; - } - if (def) - puts("yes\n"); - else - puts ("no\n"); -#ifdef HAVE_TERMIOS_H - tcsetattr_stdin_TCSANOW(&termios); -#endif - return def; -} - -int ask (e2fsck_t ctx, const char * string, int def) -{ - if (ctx->options & E2F_OPT_NO) { - printf(_("%s? no\n\n"), string); - return 0; - } - if (ctx->options & E2F_OPT_YES) { - printf(_("%s? yes\n\n"), string); - return 1; - } - if (ctx->options & E2F_OPT_PREEN) { - printf("%s? %s\n\n", string, def ? _("yes") : _("no")); - return def; - } - return ask_yn(string, def); -} - -void e2fsck_read_bitmaps(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - errcode_t retval; - - if (ctx->invalid_bitmaps) { - bb_error_msg(_("e2fsck_read_bitmaps: illegal bitmap block(s) for %s"), - ctx->device_name); - bb_error_msg_and_die(0); - } - - ehandler_operation(_("reading inode and block bitmaps")); - retval = ext2fs_read_bitmaps(fs); - ehandler_operation(0); - if (retval) { - bb_error_msg(_("while retrying to read bitmaps for %s"), - ctx->device_name); - bb_error_msg_and_die(0); - } -} - -static void e2fsck_write_bitmaps(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - errcode_t retval; - - if (ext2fs_test_bb_dirty(fs)) { - ehandler_operation(_("writing block bitmaps")); - retval = ext2fs_write_block_bitmap(fs); - ehandler_operation(0); - if (retval) { - bb_error_msg(_("while retrying to write block bitmaps for %s"), - ctx->device_name); - bb_error_msg_and_die(0); - } - } - - if (ext2fs_test_ib_dirty(fs)) { - ehandler_operation(_("writing inode bitmaps")); - retval = ext2fs_write_inode_bitmap(fs); - ehandler_operation(0); - if (retval) { - bb_error_msg(_("while retrying to write inode bitmaps for %s"), - ctx->device_name); - bb_error_msg_and_die(0); - } - } -} - -void preenhalt(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - - if (!(ctx->options & E2F_OPT_PREEN)) - return; - fprintf(stderr, _("\n\n%s: UNEXPECTED INCONSISTENCY; " - "RUN fsck MANUALLY.\n\t(i.e., without -a or -p options)\n"), - ctx->device_name); - if (fs != NULL) { - fs->super->s_state |= EXT2_ERROR_FS; - ext2fs_mark_super_dirty(fs); - ext2fs_close(fs); - } - exit(EXIT_UNCORRECTED); -} - -void e2fsck_read_inode(e2fsck_t ctx, unsigned long ino, - struct ext2_inode * inode, const char *proc) -{ - int retval; - - retval = ext2fs_read_inode(ctx->fs, ino, inode); - if (retval) { - bb_error_msg(_("while reading inode %ld in %s"), ino, proc); - bb_error_msg_and_die(0); - } -} - -extern void e2fsck_write_inode_full(e2fsck_t ctx, unsigned long ino, - struct ext2_inode * inode, int bufsize, - const char *proc) -{ - int retval; - - retval = ext2fs_write_inode_full(ctx->fs, ino, inode, bufsize); - if (retval) { - bb_error_msg(_("while writing inode %ld in %s"), ino, proc); - bb_error_msg_and_die(0); - } -} - -extern void e2fsck_write_inode(e2fsck_t ctx, unsigned long ino, - struct ext2_inode * inode, const char *proc) -{ - int retval; - - retval = ext2fs_write_inode(ctx->fs, ino, inode); - if (retval) { - bb_error_msg(_("while writing inode %ld in %s"), ino, proc); - bb_error_msg_and_die(0); - } -} - -blk_t get_backup_sb(e2fsck_t ctx, ext2_filsys fs, const char *name, - io_manager manager) -{ - struct ext2_super_block *sb; - io_channel io = NULL; - void *buf = NULL; - int blocksize; - blk_t superblock, ret_sb = 8193; - - if (fs && fs->super) { - ret_sb = (fs->super->s_blocks_per_group + - fs->super->s_first_data_block); - if (ctx) { - ctx->superblock = ret_sb; - ctx->blocksize = fs->blocksize; - } - return ret_sb; - } - - if (ctx) { - if (ctx->blocksize) { - ret_sb = ctx->blocksize * 8; - if (ctx->blocksize == 1024) - ret_sb++; - ctx->superblock = ret_sb; - return ret_sb; - } - ctx->superblock = ret_sb; - ctx->blocksize = 1024; - } - - if (!name || !manager) - goto cleanup; - - if (manager->open(name, 0, &io) != 0) - goto cleanup; - - if (ext2fs_get_mem(SUPERBLOCK_SIZE, &buf)) - goto cleanup; - sb = (struct ext2_super_block *) buf; - - for (blocksize = EXT2_MIN_BLOCK_SIZE; - blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) { - superblock = blocksize*8; - if (blocksize == 1024) - superblock++; - io_channel_set_blksize(io, blocksize); - if (io_channel_read_blk(io, superblock, - -SUPERBLOCK_SIZE, buf)) - continue; -#if BB_BIG_ENDIAN - if (sb->s_magic == ext2fs_swab16(EXT2_SUPER_MAGIC)) - ext2fs_swap_super(sb); -#endif - if (sb->s_magic == EXT2_SUPER_MAGIC) { - ret_sb = superblock; - if (ctx) { - ctx->superblock = superblock; - ctx->blocksize = blocksize; - } - break; - } - } - -cleanup: - if (io) - io_channel_close(io); - ext2fs_free_mem(&buf); - return ret_sb; -} - - -/* - * This function runs through the e2fsck passes and calls them all, - * returning restart, abort, or cancel as necessary... - */ -typedef void (*pass_t)(e2fsck_t ctx); - -static const pass_t e2fsck_passes[] = { - e2fsck_pass1, e2fsck_pass2, e2fsck_pass3, e2fsck_pass4, - e2fsck_pass5, 0 }; - -#define E2F_FLAG_RUN_RETURN (E2F_FLAG_SIGNAL_MASK|E2F_FLAG_RESTART) - -static int e2fsck_run(e2fsck_t ctx) -{ - int i; - pass_t e2fsck_pass; - - if (setjmp(ctx->abort_loc)) { - ctx->flags &= ~E2F_FLAG_SETJMP_OK; - return (ctx->flags & E2F_FLAG_RUN_RETURN); - } - ctx->flags |= E2F_FLAG_SETJMP_OK; - - for (i=0; (e2fsck_pass = e2fsck_passes[i]); i++) { - if (ctx->flags & E2F_FLAG_RUN_RETURN) - break; - e2fsck_pass(ctx); - if (ctx->progress) - (void) (ctx->progress)(ctx, 0, 0, 0); - } - ctx->flags &= ~E2F_FLAG_SETJMP_OK; - - if (ctx->flags & E2F_FLAG_RUN_RETURN) - return (ctx->flags & E2F_FLAG_RUN_RETURN); - return 0; -} - - -/* - * unix.c - The unix-specific code for e2fsck - */ - - -/* Command line options */ -static int swapfs; -#ifdef ENABLE_SWAPFS -static int normalize_swapfs; -#endif -static int cflag; /* check disk */ -static int show_version_only; -static int verbose; - -#define P_E2(singular, plural, n) n, ((n) == 1 ? singular : plural) - -static void show_stats(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - int inodes, inodes_used, blocks, blocks_used; - int dir_links; - int num_files, num_links; - int frag_percent; - - dir_links = 2 * ctx->fs_directory_count - 1; - num_files = ctx->fs_total_count - dir_links; - num_links = ctx->fs_links_count - dir_links; - inodes = fs->super->s_inodes_count; - inodes_used = (fs->super->s_inodes_count - - fs->super->s_free_inodes_count); - blocks = fs->super->s_blocks_count; - blocks_used = (fs->super->s_blocks_count - - fs->super->s_free_blocks_count); - - frag_percent = (10000 * ctx->fs_fragmented) / inodes_used; - frag_percent = (frag_percent + 5) / 10; - - if (!verbose) { - printf("%s: %d/%d files (%0d.%d%% non-contiguous), %d/%d blocks\n", - ctx->device_name, inodes_used, inodes, - frag_percent / 10, frag_percent % 10, - blocks_used, blocks); - return; - } - printf("\n%8d inode%s used (%d%%)\n", P_E2("", "s", inodes_used), - 100 * inodes_used / inodes); - printf("%8d non-contiguous inode%s (%0d.%d%%)\n", - P_E2("", "s", ctx->fs_fragmented), - frag_percent / 10, frag_percent % 10); - printf(_(" # of inodes with ind/dind/tind blocks: %d/%d/%d\n"), - ctx->fs_ind_count, ctx->fs_dind_count, ctx->fs_tind_count); - printf("%8d block%s used (%d%%)\n", P_E2("", "s", blocks_used), - (int) ((long long) 100 * blocks_used / blocks)); - printf("%8d large file%s\n", P_E2("", "s", ctx->large_files)); - printf("\n%8d regular file%s\n", P_E2("", "s", ctx->fs_regular_count)); - printf("%8d director%s\n", P_E2("y", "ies", ctx->fs_directory_count)); - printf("%8d character device file%s\n", P_E2("", "s", ctx->fs_chardev_count)); - printf("%8d block device file%s\n", P_E2("", "s", ctx->fs_blockdev_count)); - printf("%8d fifo%s\n", P_E2("", "s", ctx->fs_fifo_count)); - printf("%8d link%s\n", P_E2("", "s", ctx->fs_links_count - dir_links)); - printf("%8d symbolic link%s", P_E2("", "s", ctx->fs_symlinks_count)); - printf(" (%d fast symbolic link%s)\n", P_E2("", "s", ctx->fs_fast_symlinks_count)); - printf("%8d socket%s--------\n\n", P_E2("", "s", ctx->fs_sockets_count)); - printf("%8d file%s\n", P_E2("", "s", ctx->fs_total_count - dir_links)); -} - -static void check_mount(e2fsck_t ctx) -{ - errcode_t retval; - int cont; - - retval = ext2fs_check_if_mounted(ctx->filesystem_name, - &ctx->mount_flags); - if (retval) { - bb_error_msg(_("while determining whether %s is mounted"), - ctx->filesystem_name); - return; - } - - /* - * If the filesystem isn't mounted, or it's the root filesystem - * and it's mounted read-only, then everything's fine. - */ - if ((!(ctx->mount_flags & EXT2_MF_MOUNTED)) || - ((ctx->mount_flags & EXT2_MF_ISROOT) && - (ctx->mount_flags & EXT2_MF_READONLY))) - return; - - if (ctx->options & E2F_OPT_READONLY) { - printf(_("Warning! %s is mounted.\n"), ctx->filesystem_name); - return; - } - - printf(_("%s is mounted. "), ctx->filesystem_name); - if (!ctx->interactive) - bb_error_msg_and_die(_("can't continue, aborting")); - printf(_("\n\n\007\007\007\007WARNING!!! " - "Running e2fsck on a mounted filesystem may cause\n" - "SEVERE filesystem damage.\007\007\007\n\n")); - cont = ask_yn(_("Do you really want to continue"), -1); - if (!cont) { - printf(_("check aborted.\n")); - exit(0); - } -} - -static int is_on_batt(void) -{ - FILE *f; - DIR *d; - char tmp[80], tmp2[80], fname[80]; - unsigned int acflag; - struct dirent* de; - - f = fopen_for_read("/proc/apm"); - if (f) { - if (fscanf(f, "%s %s %s %x", tmp, tmp, tmp, &acflag) != 4) - acflag = 1; - fclose(f); - return (acflag != 1); - } - d = opendir("/proc/acpi/ac_adapter"); - if (d) { - while ((de=readdir(d)) != NULL) { - if (!strncmp(".", de->d_name, 1)) - continue; - snprintf(fname, 80, "/proc/acpi/ac_adapter/%s/state", - de->d_name); - f = fopen_for_read(fname); - if (!f) - continue; - if (fscanf(f, "%s %s", tmp2, tmp) != 2) - tmp[0] = 0; - fclose(f); - if (strncmp(tmp, "off-line", 8) == 0) { - closedir(d); - return 1; - } - } - closedir(d); - } - return 0; -} - -/* - * This routine checks to see if a filesystem can be skipped; if so, - * it will exit with EXIT_OK. Under some conditions it will print a - * message explaining why a check is being forced. - */ -static void check_if_skip(e2fsck_t ctx) -{ - ext2_filsys fs = ctx->fs; - const char *reason = NULL; - unsigned int reason_arg = 0; - long next_check; - int batt = is_on_batt(); - time_t now = time(NULL); - - if ((ctx->options & E2F_OPT_FORCE) || cflag || swapfs) - return; - - if ((fs->super->s_state & EXT2_ERROR_FS) || - !ext2fs_test_valid(fs)) - reason = _(" contains a file system with errors"); - else if ((fs->super->s_state & EXT2_VALID_FS) == 0) - reason = _(" was not cleanly unmounted"); - else if ((fs->super->s_max_mnt_count > 0) && - (fs->super->s_mnt_count >= - (unsigned) fs->super->s_max_mnt_count)) { - reason = _(" has been mounted %u times without being checked"); - reason_arg = fs->super->s_mnt_count; - if (batt && (fs->super->s_mnt_count < - (unsigned) fs->super->s_max_mnt_count*2)) - reason = 0; - } else if (fs->super->s_checkinterval && - ((now - fs->super->s_lastcheck) >= - fs->super->s_checkinterval)) { - reason = _(" has gone %u days without being checked"); - reason_arg = (now - fs->super->s_lastcheck)/(3600*24); - if (batt && ((now - fs->super->s_lastcheck) < - fs->super->s_checkinterval*2)) - reason = 0; - } - if (reason) { - fputs(ctx->device_name, stdout); - printf(reason, reason_arg); - fputs(_(", check forced.\n"), stdout); - return; - } - printf(_("%s: clean, %d/%d files, %d/%d blocks"), ctx->device_name, - fs->super->s_inodes_count - fs->super->s_free_inodes_count, - fs->super->s_inodes_count, - fs->super->s_blocks_count - fs->super->s_free_blocks_count, - fs->super->s_blocks_count); - next_check = 100000; - if (fs->super->s_max_mnt_count > 0) { - next_check = fs->super->s_max_mnt_count - fs->super->s_mnt_count; - if (next_check <= 0) - next_check = 1; - } - if (fs->super->s_checkinterval && - ((now - fs->super->s_lastcheck) >= fs->super->s_checkinterval)) - next_check = 1; - if (next_check <= 5) { - if (next_check == 1) - fputs(_(" (check after next mount)"), stdout); - else - printf(_(" (check in %ld mounts)"), next_check); - } - bb_putchar('\n'); - ext2fs_close(fs); - ctx->fs = NULL; - e2fsck_free_context(ctx); - exit(EXIT_OK); -} - -/* - * For completion notice - */ -struct percent_tbl { - int max_pass; - int table[32]; -}; -static const struct percent_tbl e2fsck_tbl = { - 5, { 0, 70, 90, 92, 95, 100 } -}; - -static char bar[128], spaces[128]; - -static float calc_percent(const struct percent_tbl *tbl, int pass, int curr, - int max) -{ - float percent; - - if (pass <= 0) - return 0.0; - if (pass > tbl->max_pass || max == 0) - return 100.0; - percent = ((float) curr) / ((float) max); - return ((percent * (tbl->table[pass] - tbl->table[pass-1])) - + tbl->table[pass-1]); -} - -void e2fsck_clear_progbar(e2fsck_t ctx) -{ - if (!(ctx->flags & E2F_FLAG_PROG_BAR)) - return; - - printf("%s%s\r%s", ctx->start_meta, spaces + (sizeof(spaces) - 80), - ctx->stop_meta); - fflush(stdout); - ctx->flags &= ~E2F_FLAG_PROG_BAR; -} - -int e2fsck_simple_progress(e2fsck_t ctx, const char *label, float percent, - unsigned int dpynum) -{ - static const char spinner[] = "\\|/-"; - int i; - unsigned int tick; - struct timeval tv; - int dpywidth; - int fixed_percent; - - if (ctx->flags & E2F_FLAG_PROG_SUPPRESS) - return 0; - - /* - * Calculate the new progress position. If the - * percentage hasn't changed, then we skip out right - * away. - */ - fixed_percent = (int) ((10 * percent) + 0.5); - if (ctx->progress_last_percent == fixed_percent) - return 0; - ctx->progress_last_percent = fixed_percent; - - /* - * If we've already updated the spinner once within - * the last 1/8th of a second, no point doing it - * again. - */ - gettimeofday(&tv, NULL); - tick = (tv.tv_sec << 3) + (tv.tv_usec / (1000000 / 8)); - if ((tick == ctx->progress_last_time) && - (fixed_percent != 0) && (fixed_percent != 1000)) - return 0; - ctx->progress_last_time = tick; - - /* - * Advance the spinner, and note that the progress bar - * will be on the screen - */ - ctx->progress_pos = (ctx->progress_pos+1) & 3; - ctx->flags |= E2F_FLAG_PROG_BAR; - - dpywidth = 66 - strlen(label); - dpywidth = 8 * (dpywidth / 8); - if (dpynum) - dpywidth -= 8; - - i = ((percent * dpywidth) + 50) / 100; - printf("%s%s: |%s%s", ctx->start_meta, label, - bar + (sizeof(bar) - (i+1)), - spaces + (sizeof(spaces) - (dpywidth - i + 1))); - if (fixed_percent == 1000) - bb_putchar('|'); - else - bb_putchar(spinner[ctx->progress_pos & 3]); - printf(" %4.1f%% ", percent); - if (dpynum) - printf("%u\r", dpynum); - else - fputs(" \r", stdout); - fputs(ctx->stop_meta, stdout); - - if (fixed_percent == 1000) - e2fsck_clear_progbar(ctx); - fflush(stdout); - - return 0; -} - -static int e2fsck_update_progress(e2fsck_t ctx, int pass, - unsigned long cur, unsigned long max) -{ - char buf[80]; - float percent; - - if (pass == 0) - return 0; - - if (ctx->progress_fd) { - sprintf(buf, "%d %lu %lu\n", pass, cur, max); - xwrite_str(ctx->progress_fd, buf); - } else { - percent = calc_percent(&e2fsck_tbl, pass, cur, max); - e2fsck_simple_progress(ctx, ctx->device_name, - percent, 0); - } - return 0; -} - -static void reserve_stdio_fds(void) -{ - int fd; - - while (1) { - fd = open(bb_dev_null, O_RDWR); - if (fd > 2) - break; - if (fd < 0) { - fprintf(stderr, _("ERROR: Cannot open " - "/dev/null (%s)\n"), - strerror(errno)); - break; - } - } - close(fd); -} - -static void signal_progress_on(int sig FSCK_ATTR((unused))) -{ - e2fsck_t ctx = e2fsck_global_ctx; - - if (!ctx) - return; - - ctx->progress = e2fsck_update_progress; - ctx->progress_fd = 0; -} - -static void signal_progress_off(int sig FSCK_ATTR((unused))) -{ - e2fsck_t ctx = e2fsck_global_ctx; - - if (!ctx) - return; - - e2fsck_clear_progbar(ctx); - ctx->progress = 0; -} - -static void signal_cancel(int sig FSCK_ATTR((unused))) -{ - e2fsck_t ctx = e2fsck_global_ctx; - - if (!ctx) - exit(FSCK_CANCELED); - - ctx->flags |= E2F_FLAG_CANCEL; -} - -static void parse_extended_opts(e2fsck_t ctx, const char *opts) -{ - char *buf, *token, *next, *p, *arg; - int ea_ver; - int extended_usage = 0; - - buf = string_copy(opts, 0); - 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, "ea_ver") == 0) { - if (!arg) { - extended_usage++; - continue; - } - ea_ver = strtoul(arg, &p, 0); - if (*p || - ((ea_ver != 1) && (ea_ver != 2))) { - fprintf(stderr, - _("Invalid EA version.\n")); - extended_usage++; - continue; - } - ctx->ext_attr_ver = ea_ver; - } else { - fprintf(stderr, _("Unknown extended option: %s\n"), - token); - extended_usage++; - } - } - if (extended_usage) { - bb_error_msg_and_die( - "Extended options are separated by commas, " - "and may take an argument which\n" - "is set off by an equals ('=') sign. " - "Valid extended options are:\n" - "\tea_ver=\n\n"); - } -} - - -static errcode_t PRS(int argc, char **argv, e2fsck_t *ret_ctx) -{ - int flush = 0; - int c, fd; - e2fsck_t ctx; - errcode_t retval; - struct sigaction sa; - char *extended_opts = NULL; - - retval = e2fsck_allocate_context(&ctx); - if (retval) - return retval; - - *ret_ctx = ctx; - - setvbuf(stdout, NULL, _IONBF, BUFSIZ); - setvbuf(stderr, NULL, _IONBF, BUFSIZ); - if (isatty(0) && isatty(1)) { - ctx->interactive = 1; - } else { - ctx->start_meta[0] = '\001'; - ctx->stop_meta[0] = '\002'; - } - memset(bar, '=', sizeof(bar)-1); - memset(spaces, ' ', sizeof(spaces)-1); - blkid_get_cache(&ctx->blkid, NULL); - - if (argc && *argv) - ctx->program_name = *argv; - else - ctx->program_name = "e2fsck"; - while ((c = getopt (argc, argv, "panyrcC:B:dE:fvtFVM:b:I:j:P:l:L:N:SsDk")) != EOF) - switch (c) { - case 'C': - ctx->progress = e2fsck_update_progress; - ctx->progress_fd = atoi(optarg); - if (!ctx->progress_fd) - break; - /* Validate the file descriptor to avoid disasters */ - fd = dup(ctx->progress_fd); - if (fd < 0) { - fprintf(stderr, - _("Error validating file descriptor %d: %s\n"), - ctx->progress_fd, - error_message(errno)); - bb_error_msg_and_die(_("Invalid completion information file descriptor")); - } else - close(fd); - break; - case 'D': - ctx->options |= E2F_OPT_COMPRESS_DIRS; - break; - case 'E': - extended_opts = optarg; - break; - case 'p': - case 'a': - if (ctx->options & (E2F_OPT_YES|E2F_OPT_NO)) { - conflict_opt: - bb_error_msg_and_die(_("only one the options -p/-a, -n or -y may be specified")); - } - ctx->options |= E2F_OPT_PREEN; - break; - case 'n': - if (ctx->options & (E2F_OPT_YES|E2F_OPT_PREEN)) - goto conflict_opt; - ctx->options |= E2F_OPT_NO; - break; - case 'y': - if (ctx->options & (E2F_OPT_PREEN|E2F_OPT_NO)) - goto conflict_opt; - ctx->options |= E2F_OPT_YES; - break; - case 't': - /* FIXME - This needs to go away in a future path - will change binary */ - fprintf(stderr, _("The -t option is not " - "supported on this version of e2fsck.\n")); - break; - case 'c': - if (cflag++) - ctx->options |= E2F_OPT_WRITECHECK; - ctx->options |= E2F_OPT_CHECKBLOCKS; - break; - case 'r': - /* What we do by default, anyway! */ - break; - case 'b': - ctx->use_superblock = atoi(optarg); - ctx->flags |= E2F_FLAG_SB_SPECIFIED; - break; - case 'B': - ctx->blocksize = atoi(optarg); - break; - case 'I': - ctx->inode_buffer_blocks = atoi(optarg); - break; - case 'j': - ctx->journal_name = string_copy(optarg, 0); - break; - case 'P': - ctx->process_inode_size = atoi(optarg); - break; - case 'd': - ctx->options |= E2F_OPT_DEBUG; - break; - case 'f': - ctx->options |= E2F_OPT_FORCE; - break; - case 'F': - flush = 1; - break; - case 'v': - verbose = 1; - break; - case 'V': - show_version_only = 1; - break; - case 'N': - ctx->device_name = optarg; - break; -#ifdef ENABLE_SWAPFS - case 's': - normalize_swapfs = 1; - case 'S': - swapfs = 1; - break; -#else - case 's': - case 'S': - fprintf(stderr, _("Byte-swapping filesystems " - "not compiled in this version " - "of e2fsck\n")); - exit(1); -#endif - default: - bb_show_usage(); - } - if (show_version_only) - return 0; - if (optind != argc - 1) - bb_show_usage(); - if ((ctx->options & E2F_OPT_NO) && - !cflag && !swapfs && !(ctx->options & E2F_OPT_COMPRESS_DIRS)) - ctx->options |= E2F_OPT_READONLY; - ctx->io_options = strchr(argv[optind], '?'); - if (ctx->io_options) - *ctx->io_options++ = 0; - ctx->filesystem_name = blkid_get_devname(ctx->blkid, argv[optind], 0); - if (!ctx->filesystem_name) { - bb_error_msg(_("Unable to resolve '%s'"), argv[optind]); - bb_error_msg_and_die(0); - } - if (extended_opts) - parse_extended_opts(ctx, extended_opts); - - if (flush) { - fd = open(ctx->filesystem_name, O_RDONLY, 0); - if (fd < 0) { - bb_error_msg(_("while opening %s for flushing"), - ctx->filesystem_name); - bb_error_msg_and_die(0); - } - if ((retval = ext2fs_sync_device(fd, 1))) { - bb_error_msg(_("while trying to flush %s"), - ctx->filesystem_name); - bb_error_msg_and_die(0); - } - close(fd); - } -#ifdef ENABLE_SWAPFS - if (swapfs && cflag) { - fprintf(stderr, _("Incompatible options not " - "allowed when byte-swapping.\n")); - exit(EXIT_USAGE); - } -#endif - /* - * Set up signal action - */ - memset(&sa, 0, sizeof(struct sigaction)); - sa.sa_handler = signal_cancel; - sigaction(SIGINT, &sa, 0); - sigaction(SIGTERM, &sa, 0); -#ifdef SA_RESTART - sa.sa_flags = SA_RESTART; -#endif - e2fsck_global_ctx = ctx; - sa.sa_handler = signal_progress_on; - sigaction(SIGUSR1, &sa, 0); - sa.sa_handler = signal_progress_off; - sigaction(SIGUSR2, &sa, 0); - - /* Update our PATH to include /sbin if we need to run badblocks */ - if (cflag) - e2fs_set_sbin_path(); - return 0; -} - -static const char my_ver_string[] = E2FSPROGS_VERSION; -static const char my_ver_date[] = E2FSPROGS_DATE; - -int e2fsck_main (int argc, char **argv); -int e2fsck_main (int argc, char **argv) -{ - errcode_t retval; - int exit_value = EXIT_OK; - ext2_filsys fs = 0; - io_manager io_ptr; - struct ext2_super_block *sb; - const char *lib_ver_date; - int my_ver, lib_ver; - e2fsck_t ctx; - struct problem_context pctx; - int flags, run_result; - - clear_problem_context(&pctx); - - my_ver = ext2fs_parse_version_string(my_ver_string); - lib_ver = ext2fs_get_library_version(0, &lib_ver_date); - if (my_ver > lib_ver) { - fprintf( stderr, _("Error: ext2fs library version " - "out of date!\n")); - show_version_only++; - } - - retval = PRS(argc, argv, &ctx); - if (retval) { - bb_error_msg(_("while trying to initialize program")); - exit(EXIT_ERROR); - } - reserve_stdio_fds(); - - if (!(ctx->options & E2F_OPT_PREEN) || show_version_only) - fprintf(stderr, "e2fsck %s (%s)\n", my_ver_string, - my_ver_date); - - if (show_version_only) { - fprintf(stderr, _("\tUsing %s, %s\n"), - error_message(EXT2_ET_BASE), lib_ver_date); - exit(EXIT_OK); - } - - check_mount(ctx); - - if (!(ctx->options & E2F_OPT_PREEN) && - !(ctx->options & E2F_OPT_NO) && - !(ctx->options & E2F_OPT_YES)) { - if (!ctx->interactive) - bb_error_msg_and_die(_("need terminal for interactive repairs")); - } - ctx->superblock = ctx->use_superblock; -restart: -#ifdef CONFIG_TESTIO_DEBUG - io_ptr = test_io_manager; - test_io_backing_manager = unix_io_manager; -#else - io_ptr = unix_io_manager; -#endif - flags = 0; - if ((ctx->options & E2F_OPT_READONLY) == 0) - flags |= EXT2_FLAG_RW; - - if (ctx->superblock && ctx->blocksize) { - retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options, - flags, ctx->superblock, ctx->blocksize, - io_ptr, &fs); - } else if (ctx->superblock) { - int blocksize; - for (blocksize = EXT2_MIN_BLOCK_SIZE; - blocksize <= EXT2_MAX_BLOCK_SIZE; blocksize *= 2) { - retval = ext2fs_open2(ctx->filesystem_name, - ctx->io_options, flags, - ctx->superblock, blocksize, - io_ptr, &fs); - if (!retval) - break; - } - } else - retval = ext2fs_open2(ctx->filesystem_name, ctx->io_options, - flags, 0, 0, io_ptr, &fs); - if (!ctx->superblock && !(ctx->options & E2F_OPT_PREEN) && - !(ctx->flags & E2F_FLAG_SB_SPECIFIED) && - ((retval == EXT2_ET_BAD_MAGIC) || - ((retval == 0) && ext2fs_check_desc(fs)))) { - if (!fs || (fs->group_desc_count > 1)) { - printf(_("%s trying backup blocks...\n"), - retval ? _("Couldn't find ext2 superblock,") : - _("Group descriptors look bad...")); - get_backup_sb(ctx, fs, ctx->filesystem_name, io_ptr); - if (fs) - ext2fs_close(fs); - goto restart; - } - } - if (retval) { - bb_error_msg(_("while trying to open %s"), - ctx->filesystem_name); - if (retval == EXT2_ET_REV_TOO_HIGH) { - printf(_("The filesystem revision is apparently " - "too high for this version of e2fsck.\n" - "(Or the filesystem superblock " - "is corrupt)\n\n")); - fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); - } else if (retval == EXT2_ET_SHORT_READ) - printf(_("Could this be a zero-length partition?\n")); - else if ((retval == EPERM) || (retval == EACCES)) - printf(_("You must have %s access to the " - "filesystem or be root\n"), - (ctx->options & E2F_OPT_READONLY) ? - "r/o" : "r/w"); - else if (retval == ENXIO) - printf(_("Possibly non-existent or swap device?\n")); -#ifdef EROFS - else if (retval == EROFS) - printf(_("Disk write-protected; use the -n option " - "to do a read-only\n" - "check of the device.\n")); -#endif - else - fix_problem(ctx, PR_0_SB_CORRUPT, &pctx); - bb_error_msg_and_die(0); - } - ctx->fs = fs; - fs->priv_data = ctx; - sb = fs->super; - if (sb->s_rev_level > E2FSCK_CURRENT_REV) { - bb_error_msg(_("while trying to open %s"), - ctx->filesystem_name); - get_newer: - bb_error_msg_and_die(_("Get a newer version of e2fsck!")); - } - - /* - * Set the device name, which is used whenever we print error - * or informational messages to the user. - */ - if (ctx->device_name == 0 && - (sb->s_volume_name[0] != 0)) { - ctx->device_name = string_copy(sb->s_volume_name, - sizeof(sb->s_volume_name)); - } - if (ctx->device_name == 0) - ctx->device_name = ctx->filesystem_name; - - /* - * Make sure the ext3 superblock fields are consistent. - */ - retval = e2fsck_check_ext3_journal(ctx); - if (retval) { - bb_error_msg(_("while checking ext3 journal for %s"), - ctx->device_name); - bb_error_msg_and_die(0); - } - - /* - * Check to see if we need to do ext3-style recovery. If so, - * do it, and then restart the fsck. - */ - if (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER) { - if (ctx->options & E2F_OPT_READONLY) { - printf(_("Warning: skipping journal recovery " - "because doing a read-only filesystem " - "check.\n")); - io_channel_flush(ctx->fs->io); - } else { - if (ctx->flags & E2F_FLAG_RESTARTED) { - /* - * Whoops, we attempted to run the - * journal twice. This should never - * happen, unless the hardware or - * device driver is being bogus. - */ - bb_error_msg(_("can't set superblock flags on %s"), ctx->device_name); - bb_error_msg_and_die(0); - } - retval = e2fsck_run_ext3_journal(ctx); - if (retval) { - bb_error_msg(_("while recovering ext3 journal of %s"), - ctx->device_name); - bb_error_msg_and_die(0); - } - ext2fs_close(ctx->fs); - ctx->fs = 0; - ctx->flags |= E2F_FLAG_RESTARTED; - goto restart; - } - } - - /* - * Check for compatibility with the feature sets. We need to - * be more stringent than ext2fs_open(). - */ - if ((sb->s_feature_compat & ~EXT2_LIB_FEATURE_COMPAT_SUPP) || - (sb->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP)) { - bb_error_msg("(%s)", ctx->device_name); - goto get_newer; - } - if (sb->s_feature_ro_compat & ~EXT2_LIB_FEATURE_RO_COMPAT_SUPP) { - bb_error_msg("(%s)", ctx->device_name); - goto get_newer; - } -#ifdef ENABLE_COMPRESSION - /* FIXME - do we support this at all? */ - if (sb->s_feature_incompat & EXT2_FEATURE_INCOMPAT_COMPRESSION) - bb_error_msg(_("warning: compression support is experimental")); -#endif -#ifndef ENABLE_HTREE - if (sb->s_feature_compat & EXT2_FEATURE_COMPAT_DIR_INDEX) { - bb_error_msg(_("E2fsck not compiled with HTREE support,\n\t" - "but filesystem %s has HTREE directories."), - ctx->device_name); - goto get_newer; - } -#endif - - /* - * If the user specified a specific superblock, presumably the - * master superblock has been trashed. So we mark the - * superblock as dirty, so it can be written out. - */ - if (ctx->superblock && - !(ctx->options & E2F_OPT_READONLY)) - ext2fs_mark_super_dirty(fs); - - /* - * We only update the master superblock because (a) paranoia; - * we don't want to corrupt the backup superblocks, and (b) we - * don't need to update the mount count and last checked - * fields in the backup superblock (the kernel doesn't - * update the backup superblocks anyway). - */ - fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; - - ehandler_init(fs->io); - - if (ctx->superblock) - set_latch_flags(PR_LATCH_RELOC, PRL_LATCHED, 0); - ext2fs_mark_valid(fs); - check_super_block(ctx); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - bb_error_msg_and_die(0); - check_if_skip(ctx); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - bb_error_msg_and_die(0); -#ifdef ENABLE_SWAPFS - -#ifdef WORDS_BIGENDIAN -#define NATIVE_FLAG EXT2_FLAG_SWAP_BYTES -#else -#define NATIVE_FLAG 0 -#endif - - - if (normalize_swapfs) { - if ((fs->flags & EXT2_FLAG_SWAP_BYTES) == NATIVE_FLAG) { - fprintf(stderr, _("%s: Filesystem byte order " - "already normalized.\n"), ctx->device_name); - bb_error_msg_and_die(0); - } - } - if (swapfs) { - swap_filesys(ctx); - if (ctx->flags & E2F_FLAG_SIGNAL_MASK) - bb_error_msg_and_die(0); - } -#endif - - /* - * Mark the system as valid, 'til proven otherwise - */ - ext2fs_mark_valid(fs); - - retval = ext2fs_read_bb_inode(fs, &fs->badblocks); - if (retval) { - bb_error_msg(_("while reading bad blocks inode")); - preenhalt(ctx); - printf(_("This doesn't bode well," - " but we'll try to go on...\n")); - } - - run_result = e2fsck_run(ctx); - e2fsck_clear_progbar(ctx); - if (run_result == E2F_FLAG_RESTART) { - printf(_("Restarting e2fsck from the beginning...\n")); - retval = e2fsck_reset_context(ctx); - if (retval) { - bb_error_msg(_("while resetting context")); - bb_error_msg_and_die(0); - } - ext2fs_close(fs); - goto restart; - } - if (run_result & E2F_FLAG_CANCEL) { - printf(_("%s: e2fsck canceled.\n"), ctx->device_name ? - ctx->device_name : ctx->filesystem_name); - exit_value |= FSCK_CANCELED; - } - if (run_result & E2F_FLAG_ABORT) - bb_error_msg_and_die(_("aborted")); - - /* Cleanup */ - if (ext2fs_test_changed(fs)) { - exit_value |= EXIT_NONDESTRUCT; - if (!(ctx->options & E2F_OPT_PREEN)) - printf(_("\n%s: ***** FILE SYSTEM WAS MODIFIED *****\n"), - ctx->device_name); - if (ctx->mount_flags & EXT2_MF_ISROOT) { - printf(_("%s: ***** REBOOT LINUX *****\n"), - ctx->device_name); - exit_value |= EXIT_DESTRUCT; - } - } - if (!ext2fs_test_valid(fs)) { - printf(_("\n%s: ********** WARNING: Filesystem still has " - "errors **********\n\n"), ctx->device_name); - exit_value |= EXIT_UNCORRECTED; - exit_value &= ~EXIT_NONDESTRUCT; - } - if (exit_value & FSCK_CANCELED) - exit_value &= ~EXIT_NONDESTRUCT; - else { - show_stats(ctx); - if (!(ctx->options & E2F_OPT_READONLY)) { - if (ext2fs_test_valid(fs)) { - if (!(sb->s_state & EXT2_VALID_FS)) - exit_value |= EXIT_NONDESTRUCT; - sb->s_state = EXT2_VALID_FS; - } else - sb->s_state &= ~EXT2_VALID_FS; - sb->s_mnt_count = 0; - sb->s_lastcheck = time(NULL); - ext2fs_mark_super_dirty(fs); - } - } - - e2fsck_write_bitmaps(ctx); - - ext2fs_close(fs); - ctx->fs = NULL; - free(ctx->filesystem_name); - free(ctx->journal_name); - e2fsck_free_context(ctx); - - return exit_value; -} diff --git a/e2fsprogs/old_e2fsprogs/e2fsck.h b/e2fsprogs/old_e2fsprogs/e2fsck.h deleted file mode 100644 index c159fab..0000000 --- a/e2fsprogs/old_e2fsprogs/e2fsck.h +++ b/dev/null @@ -1,638 +0,0 @@ -/* vi: set sw=4 ts=4: */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "ext2fs/kernel-list.h" -#include -#include - -/* - * Now pull in the real linux/jfs.h definitions. - */ -#include "ext2fs/kernel-jbd.h" - - - -#include "fsck.h" - -#include "ext2fs/ext2_fs.h" -#include "blkid/blkid.h" -#include "ext2fs/ext2_ext_attr.h" -#include "uuid/uuid.h" -#include "libbb.h" - -#ifdef HAVE_CONIO_H -#undef HAVE_TERMIOS_H -#include -#define read_a_char() getch() -#else -#ifdef HAVE_TERMIOS_H -#include -#endif -#endif - - -/* - * The last ext2fs revision level that this version of e2fsck is able to - * support - */ -#define E2FSCK_CURRENT_REV 1 - -/* Used by the region allocation code */ -typedef __u32 region_addr_t; -typedef struct region_struct *region_t; - -struct dx_dirblock_info { - int type; - blk_t phys; - int flags; - blk_t parent; - ext2_dirhash_t min_hash; - ext2_dirhash_t max_hash; - ext2_dirhash_t node_min_hash; - ext2_dirhash_t node_max_hash; -}; - -/* -These defines are used in the type field of dx_dirblock_info -*/ - -#define DX_DIRBLOCK_ROOT 1 -#define DX_DIRBLOCK_LEAF 2 -#define DX_DIRBLOCK_NODE 3 - - -/* -The following defines are used in the 'flags' field of a dx_dirblock_info -*/ -#define DX_FLAG_REFERENCED 1 -#define DX_FLAG_DUP_REF 2 -#define DX_FLAG_FIRST 4 -#define DX_FLAG_LAST 8 - -/* - * E2fsck options - */ -#define E2F_OPT_READONLY 0x0001 -#define E2F_OPT_PREEN 0x0002 -#define E2F_OPT_YES 0x0004 -#define E2F_OPT_NO 0x0008 -#define E2F_OPT_TIME 0x0010 -#define E2F_OPT_CHECKBLOCKS 0x0040 -#define E2F_OPT_DEBUG 0x0080 -#define E2F_OPT_FORCE 0x0100 -#define E2F_OPT_WRITECHECK 0x0200 -#define E2F_OPT_COMPRESS_DIRS 0x0400 - -/* - * E2fsck flags - */ -#define E2F_FLAG_ABORT 0x0001 /* Abort signaled */ -#define E2F_FLAG_CANCEL 0x0002 /* Cancel signaled */ -#define E2F_FLAG_SIGNAL_MASK 0x0003 -#define E2F_FLAG_RESTART 0x0004 /* Restart signaled */ - -#define E2F_FLAG_SETJMP_OK 0x0010 /* Setjmp valid for abort */ - -#define E2F_FLAG_PROG_BAR 0x0020 /* Progress bar on screen */ -#define E2F_FLAG_PROG_SUPPRESS 0x0040 /* Progress suspended */ -#define E2F_FLAG_JOURNAL_INODE 0x0080 /* Create a new ext3 journal inode */ -#define E2F_FLAG_SB_SPECIFIED 0x0100 /* The superblock was explicitly - * specified by the user */ -#define E2F_FLAG_RESTARTED 0x0200 /* E2fsck has been restarted */ -#define E2F_FLAG_RESIZE_INODE 0x0400 /* Request to recreate resize inode */ - - -/*Don't know where these come from*/ -#define READ 0 -#define WRITE 1 -#define cpu_to_be32(n) htonl(n) -#define be32_to_cpu(n) ntohl(n) - -/* - * We define a set of "latch groups"; these are problems which are - * handled as a set. The user answers once for a particular latch - * group. - */ -#define PR_LATCH_MASK 0x0ff0 /* Latch mask */ -#define PR_LATCH_BLOCK 0x0010 /* Latch for illegal blocks (pass 1) */ -#define PR_LATCH_BBLOCK 0x0020 /* Latch for bad block inode blocks (pass 1) */ -#define PR_LATCH_IBITMAP 0x0030 /* Latch for pass 5 inode bitmap proc. */ -#define PR_LATCH_BBITMAP 0x0040 /* Latch for pass 5 inode bitmap proc. */ -#define PR_LATCH_RELOC 0x0050 /* Latch for superblock relocate hint */ -#define PR_LATCH_DBLOCK 0x0060 /* Latch for pass 1b dup block headers */ -#define PR_LATCH_LOW_DTIME 0x0070 /* Latch for pass1 orphaned list refugees */ -#define PR_LATCH_TOOBIG 0x0080 /* Latch for file to big errors */ -#define PR_LATCH_OPTIMIZE_DIR 0x0090 /* Latch for optimize directories */ - -#define PR_LATCH(x) ((((x) & PR_LATCH_MASK) >> 4) - 1) - -/* - * Latch group descriptor flags - */ -#define PRL_YES 0x0001 /* Answer yes */ -#define PRL_NO 0x0002 /* Answer no */ -#define PRL_LATCHED 0x0004 /* The latch group is latched */ -#define PRL_SUPPRESS 0x0008 /* Suppress all latch group questions */ - -#define PRL_VARIABLE 0x000f /* All the flags that need to be reset */ - -/* - * Pre-Pass 1 errors - */ - -#define PR_0_BB_NOT_GROUP 0x000001 /* Block bitmap not in group */ -#define PR_0_IB_NOT_GROUP 0x000002 /* Inode bitmap not in group */ -#define PR_0_ITABLE_NOT_GROUP 0x000003 /* Inode table not in group */ -#define PR_0_SB_CORRUPT 0x000004 /* Superblock corrupt */ -#define PR_0_FS_SIZE_WRONG 0x000005 /* Filesystem size is wrong */ -#define PR_0_NO_FRAGMENTS 0x000006 /* Fragments not supported */ -#define PR_0_BLOCKS_PER_GROUP 0x000007 /* Bad blocks_per_group */ -#define PR_0_FIRST_DATA_BLOCK 0x000008 /* Bad first_data_block */ -#define PR_0_ADD_UUID 0x000009 /* Adding UUID to filesystem */ -#define PR_0_RELOCATE_HINT 0x00000A /* Relocate hint */ -#define PR_0_MISC_CORRUPT_SUPER 0x00000B /* Miscellaneous superblock corruption */ -#define PR_0_GETSIZE_ERROR 0x00000C /* Error determing physical device size of filesystem */ -#define PR_0_INODE_COUNT_WRONG 0x00000D /* Inode count in the superblock incorrect */ -#define PR_0_HURD_CLEAR_FILETYPE 0x00000E /* The Hurd does not support the filetype feature */ -#define PR_0_JOURNAL_BAD_INODE 0x00000F /* The Hurd does not support the filetype feature */ -#define PR_0_JOURNAL_UNSUPP_MULTIFS 0x000010 /* The external journal has multiple filesystems (which we can't handle yet) */ -#define PR_0_CANT_FIND_JOURNAL 0x000011 /* Can't find external journal */ -#define PR_0_EXT_JOURNAL_BAD_SUPER 0x000012/* External journal has bad superblock */ -#define PR_0_JOURNAL_BAD_UUID 0x000013 /* Superblock has a bad journal UUID */ -#define PR_0_JOURNAL_UNSUPP_SUPER 0x000014 /* Journal has an unknown superblock type */ -#define PR_0_JOURNAL_BAD_SUPER 0x000015 /* Journal superblock is corrupt */ -#define PR_0_JOURNAL_HAS_JOURNAL 0x000016 /* Journal superblock is corrupt */ -#define PR_0_JOURNAL_RECOVER_SET 0x000017 /* Superblock has recovery flag set but no journal */ -#define PR_0_JOURNAL_RECOVERY_CLEAR 0x000018 /* Journal has data, but recovery flag is clear */ -#define PR_0_JOURNAL_RESET_JOURNAL 0x000019 /* Ask if we should clear the journal */ -#define PR_0_FS_REV_LEVEL 0x00001A /* Filesystem revision is 0, but feature flags are set */ -#define PR_0_ORPHAN_CLEAR_INODE 0x000020 /* Clearing orphan inode */ -#define PR_0_ORPHAN_ILLEGAL_BLOCK_NUM 0x000021 /* Illegal block found in orphaned inode */ -#define PR_0_ORPHAN_ALREADY_CLEARED_BLOCK 0x000022 /* Already cleared block found in orphaned inode */ -#define PR_0_ORPHAN_ILLEGAL_HEAD_INODE 0x000023 /* Illegal orphan inode in superblock */ -#define PR_0_ORPHAN_ILLEGAL_INODE 0x000024 /* Illegal inode in orphaned inode list */ -#define PR_0_JOURNAL_UNSUPP_ROCOMPAT 0x000025 /* Journal has unsupported read-only feature - abort */ -#define PR_0_JOURNAL_UNSUPP_INCOMPAT 0x000026 /* Journal has unsupported incompatible feature - abort */ -#define PR_0_JOURNAL_UNSUPP_VERSION 0x000027 /* Journal has unsupported version number */ -#define PR_0_MOVE_JOURNAL 0x000028 /* Moving journal to hidden file */ -#define PR_0_ERR_MOVE_JOURNAL 0x000029 /* Error moving journal */ -#define PR_0_CLEAR_V2_JOURNAL 0x00002A /* Clearing V2 journal superblock */ -#define PR_0_JOURNAL_RUN 0x00002B /* Run journal anyway */ -#define PR_0_JOURNAL_RUN_DEFAULT 0x00002C /* Run journal anyway by default */ -#define PR_0_BACKUP_JNL 0x00002D /* Backup journal inode blocks */ -#define PR_0_NONZERO_RESERVED_GDT_BLOCKS 0x00002E /* Reserved blocks w/o resize_inode */ -#define PR_0_CLEAR_RESIZE_INODE 0x00002F /* Resize_inode not enabled, but resize inode is non-zero */ -#define PR_0_RESIZE_INODE_INVALID 0x000030 /* Resize inode invalid */ - -/* - * Pass 1 errors - */ - -#define PR_1_PASS_HEADER 0x010000 /* Pass 1: Checking inodes, blocks, and sizes */ -#define PR_1_ROOT_NO_DIR 0x010001 /* Root directory is not an inode */ -#define PR_1_ROOT_DTIME 0x010002 /* Root directory has dtime set */ -#define PR_1_RESERVED_BAD_MODE 0x010003 /* Reserved inode has bad mode */ -#define PR_1_ZERO_DTIME 0x010004 /* Deleted inode has zero dtime */ -#define PR_1_SET_DTIME 0x010005 /* Inode in use, but dtime set */ -#define PR_1_ZERO_LENGTH_DIR 0x010006 /* Zero-length directory */ -#define PR_1_BB_CONFLICT 0x010007 /* Block bitmap conflicts with some other fs block */ -#define PR_1_IB_CONFLICT 0x010008 /* Inode bitmap conflicts with some other fs block */ -#define PR_1_ITABLE_CONFLICT 0x010009 /* Inode table conflicts with some other fs block */ -#define PR_1_BB_BAD_BLOCK 0x01000A /* Block bitmap is on a bad block */ -#define PR_1_IB_BAD_BLOCK 0x01000B /* Inode bitmap is on a bad block */ -#define PR_1_BAD_I_SIZE 0x01000C /* Inode has incorrect i_size */ -#define PR_1_BAD_I_BLOCKS 0x01000D /* Inode has incorrect i_blocks */ -#define PR_1_ILLEGAL_BLOCK_NUM 0x01000E /* Illegal block number in inode */ -#define PR_1_BLOCK_OVERLAPS_METADATA 0x01000F /* Block number overlaps fs metadata */ -#define PR_1_INODE_BLOCK_LATCH 0x010010 /* Inode has illegal blocks (latch question) */ -#define PR_1_TOO_MANY_BAD_BLOCKS 0x010011 /* Too many bad blocks in inode */ -#define PR_1_BB_ILLEGAL_BLOCK_NUM 0x010012 /* Illegal block number in bad block inode */ -#define PR_1_INODE_BBLOCK_LATCH 0x010013 /* Bad block inode has illegal blocks (latch question) */ -#define PR_1_DUP_BLOCKS_PREENSTOP 0x010014 /* Duplicate or bad blocks in use! */ -#define PR_1_BBINODE_BAD_METABLOCK 0x010015 /* Bad block used as bad block indirect block */ -#define PR_1_BBINODE_BAD_METABLOCK_PROMPT 0x010016 /* Inconsistency can't be fixed prompt */ -#define PR_1_BAD_PRIMARY_BLOCK 0x010017 /* Bad primary block */ -#define PR_1_BAD_PRIMARY_BLOCK_PROMPT 0x010018 /* Bad primary block prompt */ -#define PR_1_BAD_PRIMARY_SUPERBLOCK 0x010019 /* Bad primary superblock */ -#define PR_1_BAD_PRIMARY_GROUP_DESCRIPTOR 0x01001A /* Bad primary block group descriptors */ -#define PR_1_BAD_SUPERBLOCK 0x01001B /* Bad superblock in group */ -#define PR_1_BAD_GROUP_DESCRIPTORS 0x01001C /* Bad block group descriptors in group */ -#define PR_1_PROGERR_CLAIMED_BLOCK 0x01001D /* Block claimed for no reason */ -#define PR_1_RELOC_BLOCK_ALLOCATE 0x01001E /* Error allocating blocks for relocating metadata */ -#define PR_1_RELOC_MEMORY_ALLOCATE 0x01001F /* Error allocating block buffer during relocation process */ -#define PR_1_RELOC_FROM_TO 0x010020 /* Relocating metadata group information from X to Y */ -#define PR_1_RELOC_TO 0x010021 /* Relocating metatdata group information to X */ -#define PR_1_RELOC_READ_ERR 0x010022 /* Block read error during relocation process */ -#define PR_1_RELOC_WRITE_ERR 0x010023 /* Block write error during relocation process */ -#define PR_1_ALLOCATE_IBITMAP_ERROR 0x010024 /* Error allocating inode bitmap */ -#define PR_1_ALLOCATE_BBITMAP_ERROR 0x010025 /* Error allocating block bitmap */ -#define PR_1_ALLOCATE_ICOUNT 0x010026 /* Error allocating icount structure */ -#define PR_1_ALLOCATE_DBCOUNT 0x010027 /* Error allocating dbcount */ -#define PR_1_ISCAN_ERROR 0x010028 /* Error while scanning inodes */ -#define PR_1_BLOCK_ITERATE 0x010029 /* Error while iterating over blocks */ -#define PR_1_ICOUNT_STORE 0x01002A /* Error while storing inode count information */ -#define PR_1_ADD_DBLOCK 0x01002B /* Error while storing directory block information */ -#define PR_1_READ_INODE 0x01002C /* Error while reading inode (for clearing) */ -#define PR_1_SUPPRESS_MESSAGES 0x01002D /* Suppress messages prompt */ -#define PR_1_SET_IMAGIC 0x01002F /* Imagic flag set on an inode when filesystem doesn't support it */ -#define PR_1_SET_IMMUTABLE 0x010030 /* Immutable flag set on a device or socket inode */ -#define PR_1_COMPR_SET 0x010031 /* Compression flag set on a non-compressed filesystem */ -#define PR_1_SET_NONZSIZE 0x010032 /* Non-zero size on device, fifo or socket inode */ -#define PR_1_FS_REV_LEVEL 0x010033 /* Filesystem revision is 0, but feature flags are set */ -#define PR_1_JOURNAL_INODE_NOT_CLEAR 0x010034 /* Journal inode not in use, needs clearing */ -#define PR_1_JOURNAL_BAD_MODE 0x010035 /* Journal inode has wrong mode */ -#define PR_1_LOW_DTIME 0x010036 /* Inode that was part of orphan linked list */ -#define PR_1_ORPHAN_LIST_REFUGEES 0x010037 /* Latch question which asks how to deal with low dtime inodes */ -#define PR_1_ALLOCATE_REFCOUNT 0x010038 /* Error allocating refcount structure */ -#define PR_1_READ_EA_BLOCK 0x010039 /* Error reading Extended Attribute block */ -#define PR_1_BAD_EA_BLOCK 0x01003A /* Invalid Extended Attribute block */ -#define PR_1_EXTATTR_READ_ABORT 0x01003B /* Error reading Extended Attribute block while fixing refcount -- abort */ -#define PR_1_EXTATTR_REFCOUNT 0x01003C /* Extended attribute reference count incorrect */ -#define PR_1_EXTATTR_WRITE 0x01003D /* Error writing Extended Attribute block while fixing refcount */ -#define PR_1_EA_MULTI_BLOCK 0x01003E /* Multiple EA blocks not supported */ -#define PR_1_EA_ALLOC_REGION 0x01003F /* Error allocating EA region allocation structure */ -#define PR_1_EA_ALLOC_COLLISION 0x010040 /* Error EA allocation collision */ -#define PR_1_EA_BAD_NAME 0x010041 /* Bad extended attribute name */ -#define PR_1_EA_BAD_VALUE 0x010042 /* Bad extended attribute value */ -#define PR_1_INODE_TOOBIG 0x010043 /* Inode too big (latch question) */ -#define PR_1_TOOBIG_DIR 0x010044 /* Directory too big */ -#define PR_1_TOOBIG_REG 0x010045 /* Regular file too big */ -#define PR_1_TOOBIG_SYMLINK 0x010046 /* Symlink too big */ -#define PR_1_HTREE_SET 0x010047 /* INDEX_FL flag set on a non-HTREE filesystem */ -#define PR_1_HTREE_NODIR 0x010048 /* INDEX_FL flag set on a non-directory */ -#define PR_1_HTREE_BADROOT 0x010049 /* Invalid root node in HTREE directory */ -#define PR_1_HTREE_HASHV 0x01004A /* Unsupported hash version in HTREE directory */ -#define PR_1_HTREE_INCOMPAT 0x01004B /* Incompatible flag in HTREE root node */ -#define PR_1_HTREE_DEPTH 0x01004C /* HTREE too deep */ -#define PR_1_BB_FS_BLOCK 0x01004D /* Bad block has indirect block that conflicts with filesystem block */ -#define PR_1_RESIZE_INODE_CREATE 0x01004E /* Resize inode failed */ -#define PR_1_EXTRA_ISIZE 0x01004F /* inode->i_size is too long */ -#define PR_1_ATTR_NAME_LEN 0x010050 /* attribute name is too long */ -#define PR_1_ATTR_VALUE_OFFSET 0x010051 /* wrong EA value offset */ -#define PR_1_ATTR_VALUE_BLOCK 0x010052 /* wrong EA blocknumber */ -#define PR_1_ATTR_VALUE_SIZE 0x010053 /* wrong EA value size */ -#define PR_1_ATTR_HASH 0x010054 /* wrong EA hash value */ - -/* - * Pass 1b errors - */ - -#define PR_1B_PASS_HEADER 0x011000 /* Pass 1B: Rescan for duplicate/bad blocks */ -#define PR_1B_DUP_BLOCK_HEADER 0x011001 /* Duplicate/bad block(s) header */ -#define PR_1B_DUP_BLOCK 0x011002 /* Duplicate/bad block(s) in inode */ -#define PR_1B_DUP_BLOCK_END 0x011003 /* Duplicate/bad block(s) end */ -#define PR_1B_ISCAN_ERROR 0x011004 /* Error while scanning inodes */ -#define PR_1B_ALLOCATE_IBITMAP_ERROR 0x011005 /* Error allocating inode bitmap */ -#define PR_1B_BLOCK_ITERATE 0x0110006 /* Error while iterating over blocks */ -#define PR_1B_ADJ_EA_REFCOUNT 0x0110007 /* Error adjusting EA refcount */ -#define PR_1C_PASS_HEADER 0x012000 /* Pass 1C: Scan directories for inodes with dup blocks. */ -#define PR_1D_PASS_HEADER 0x013000 /* Pass 1D: Reconciling duplicate blocks */ -#define PR_1D_DUP_FILE 0x013001 /* File has duplicate blocks */ -#define PR_1D_DUP_FILE_LIST 0x013002 /* List of files sharing duplicate blocks */ -#define PR_1D_SHARE_METADATA 0x013003 /* File sharing blocks with filesystem metadata */ -#define PR_1D_NUM_DUP_INODES 0x013004 /* Report of how many duplicate/bad inodes */ -#define PR_1D_DUP_BLOCKS_DEALT 0x013005 /* Duplicated blocks already reassigned or cloned. */ -#define PR_1D_CLONE_QUESTION 0x013006 /* Clone duplicate/bad blocks? */ -#define PR_1D_DELETE_QUESTION 0x013007 /* Delete file? */ -#define PR_1D_CLONE_ERROR 0x013008 /* Couldn't clone file (error) */ - -/* - * Pass 2 errors - */ - -#define PR_2_PASS_HEADER 0x020000 /* Pass 2: Checking directory structure */ -#define PR_2_BAD_INODE_DOT 0x020001 /* Bad inode number for '.' */ -#define PR_2_BAD_INO 0x020002 /* Directory entry has bad inode number */ -#define PR_2_UNUSED_INODE 0x020003 /* Directory entry has deleted or unused inode */ -#define PR_2_LINK_DOT 0x020004 /* Directry entry is link to '.' */ -#define PR_2_BB_INODE 0x020005 /* Directory entry points to inode now located in a bad block */ -#define PR_2_LINK_DIR 0x020006 /* Directory entry contains a link to a directory */ -#define PR_2_LINK_ROOT 0x020007 /* Directory entry contains a link to the root directry */ -#define PR_2_BAD_NAME 0x020008 /* Directory entry has illegal characters in its name */ -#define PR_2_MISSING_DOT 0x020009 /* Missing '.' in directory inode */ -#define PR_2_MISSING_DOT_DOT 0x02000A /* Missing '..' in directory inode */ -#define PR_2_1ST_NOT_DOT 0x02000B /* First entry in directory inode doesn't contain '.' */ -#define PR_2_2ND_NOT_DOT_DOT 0x02000C /* Second entry in directory inode doesn't contain '..' */ -#define PR_2_FADDR_ZERO 0x02000D /* i_faddr should be zero */ -#define PR_2_FILE_ACL_ZERO 0x02000E /* i_file_acl should be zero */ -#define PR_2_DIR_ACL_ZERO 0x02000F /* i_dir_acl should be zero */ -#define PR_2_FRAG_ZERO 0x020010 /* i_frag should be zero */ -#define PR_2_FSIZE_ZERO 0x020011 /* i_fsize should be zero */ -#define PR_2_BAD_MODE 0x020012 /* inode has bad mode */ -#define PR_2_DIR_CORRUPTED 0x020013 /* directory corrupted */ -#define PR_2_FILENAME_LONG 0x020014 /* filename too long */ -#define PR_2_DIRECTORY_HOLE 0x020015 /* Directory inode has a missing block (hole) */ -#define PR_2_DOT_NULL_TERM 0x020016 /* '.' is not NULL terminated */ -#define PR_2_DOT_DOT_NULL_TERM 0x020017 /* '..' is not NULL terminated */ -#define PR_2_BAD_CHAR_DEV 0x020018 /* Illegal character device in inode */ -#define PR_2_BAD_BLOCK_DEV 0x020019 /* Illegal block device in inode */ -#define PR_2_DUP_DOT 0x02001A /* Duplicate '.' entry */ -#define PR_2_DUP_DOT_DOT 0x02001B /* Duplicate '..' entry */ -#define PR_2_NO_DIRINFO 0x02001C /* Internal error: couldn't find dir_info */ -#define PR_2_FINAL_RECLEN 0x02001D /* Final rec_len is wrong */ -#define PR_2_ALLOCATE_ICOUNT 0x02001E /* Error allocating icount structure */ -#define PR_2_DBLIST_ITERATE 0x02001F /* Error iterating over directory blocks */ -#define PR_2_READ_DIRBLOCK 0x020020 /* Error reading directory block */ -#define PR_2_WRITE_DIRBLOCK 0x020021 /* Error writing directory block */ -#define PR_2_ALLOC_DIRBOCK 0x020022 /* Error allocating new directory block */ -#define PR_2_DEALLOC_INODE 0x020023 /* Error deallocating inode */ -#define PR_2_SPLIT_DOT 0x020024 /* Directory entry for '.' is big. Split? */ -#define PR_2_BAD_FIFO 0x020025 /* Illegal FIFO */ -#define PR_2_BAD_SOCKET 0x020026 /* Illegal socket */ -#define PR_2_SET_FILETYPE 0x020027 /* Directory filetype not set */ -#define PR_2_BAD_FILETYPE 0x020028 /* Directory filetype incorrect */ -#define PR_2_CLEAR_FILETYPE 0x020029 /* Directory filetype set when it shouldn't be */ -#define PR_2_NULL_NAME 0x020030 /* Directory filename can't be zero-length */ -#define PR_2_INVALID_SYMLINK 0x020031 /* Invalid symlink */ -#define PR_2_FILE_ACL_BAD 0x020032 /* i_file_acl (extended attribute) is bad */ -#define PR_2_FEATURE_LARGE_FILES 0x020033 /* Filesystem contains large files, but has no such flag in sb */ -#define PR_2_HTREE_NOTREF 0x020034 /* Node in HTREE directory not referenced */ -#define PR_2_HTREE_DUPREF 0x020035 /* Node in HTREE directory referenced twice */ -#define PR_2_HTREE_MIN_HASH 0x020036 /* Node in HTREE directory has bad min hash */ -#define PR_2_HTREE_MAX_HASH 0x020037 /* Node in HTREE directory has bad max hash */ -#define PR_2_HTREE_CLEAR 0x020038 /* Clear invalid HTREE directory */ -#define PR_2_HTREE_BADBLK 0x02003A /* Bad block in htree interior node */ -#define PR_2_ADJ_EA_REFCOUNT 0x02003B /* Error adjusting EA refcount */ -#define PR_2_HTREE_BAD_ROOT 0x02003C /* Invalid HTREE root node */ -#define PR_2_HTREE_BAD_LIMIT 0x02003D /* Invalid HTREE limit */ -#define PR_2_HTREE_BAD_COUNT 0x02003E /* Invalid HTREE count */ -#define PR_2_HTREE_HASH_ORDER 0x02003F /* HTREE interior node has out-of-order hashes in table */ -#define PR_2_HTREE_BAD_DEPTH 0x020040 /* Node in HTREE directory has bad depth */ -#define PR_2_DUPLICATE_DIRENT 0x020041 /* Duplicate directory entry found */ -#define PR_2_NON_UNIQUE_FILE 0x020042 /* Non-unique filename found */ -#define PR_2_REPORT_DUP_DIRENT 0x020043 /* Duplicate directory entry found */ - -/* - * Pass 3 errors - */ - -#define PR_3_PASS_HEADER 0x030000 /* Pass 3: Checking directory connectivity */ -#define PR_3_NO_ROOT_INODE 0x030001 /* Root inode not allocated */ -#define PR_3_EXPAND_LF_DIR 0x030002 /* No room in lost+found */ -#define PR_3_UNCONNECTED_DIR 0x030003 /* Unconnected directory inode */ -#define PR_3_NO_LF_DIR 0x030004 /* /lost+found not found */ -#define PR_3_BAD_DOT_DOT 0x030005 /* .. entry is incorrect */ -#define PR_3_NO_LPF 0x030006 /* Bad or non-existent /lost+found. Cannot reconnect */ -#define PR_3_CANT_EXPAND_LPF 0x030007 /* Could not expand /lost+found */ -#define PR_3_CANT_RECONNECT 0x030008 /* Could not reconnect inode */ -#define PR_3_ERR_FIND_LPF 0x030009 /* Error while trying to find /lost+found */ -#define PR_3_ERR_LPF_NEW_BLOCK 0x03000A /* Error in ext2fs_new_block while creating /lost+found */ -#define PR_3_ERR_LPF_NEW_INODE 0x03000B /* Error in ext2fs_new_inode while creating /lost+found */ -#define PR_3_ERR_LPF_NEW_DIR_BLOCK 0x03000C /* Error in ext2fs_new_dir_block while creating /lost+found */ -#define PR_3_ERR_LPF_WRITE_BLOCK 0x03000D /* Error while writing directory block for /lost+found */ -#define PR_3_ADJUST_INODE 0x03000E /* Error while adjusting inode count */ -#define PR_3_FIX_PARENT_ERR 0x03000F /* Couldn't fix parent directory -- error */ -#define PR_3_FIX_PARENT_NOFIND 0x030010 /* Couldn't fix parent directory -- couldn't find it */ -#define PR_3_ALLOCATE_IBITMAP_ERROR 0x030011 /* Error allocating inode bitmap */ -#define PR_3_CREATE_ROOT_ERROR 0x030012 /* Error creating root directory */ -#define PR_3_CREATE_LPF_ERROR 0x030013 /* Error creating lost and found directory */ -#define PR_3_ROOT_NOT_DIR_ABORT 0x030014 /* Root inode is not directory; aborting */ -#define PR_3_NO_ROOT_INODE_ABORT 0x030015 /* Cannot proceed without a root inode. */ -#define PR_3_NO_DIRINFO 0x030016 /* Internal error: couldn't find dir_info */ -#define PR_3_LPF_NOTDIR 0x030017 /* Lost+found is not a directory */ - -/* - * Pass 3a --- rehashing diretories - */ -#define PR_3A_PASS_HEADER 0x031000 /* Pass 3a: Reindexing directories */ -#define PR_3A_OPTIMIZE_ITER 0x031001 /* Error iterating over directories */ -#define PR_3A_OPTIMIZE_DIR_ERR 0x031002 /* Error rehash directory */ -#define PR_3A_OPTIMIZE_DIR_HEADER 0x031003 /* Rehashing dir header */ -#define PR_3A_OPTIMIZE_DIR 0x031004 /* Rehashing directory %d */ -#define PR_3A_OPTIMIZE_DIR_END 0x031005 /* Rehashing dir end */ - -/* - * Pass 4 errors - */ - -#define PR_4_PASS_HEADER 0x040000 /* Pass 4: Checking reference counts */ -#define PR_4_ZERO_LEN_INODE 0x040001 /* Unattached zero-length inode */ -#define PR_4_UNATTACHED_INODE 0x040002 /* Unattached inode */ -#define PR_4_BAD_REF_COUNT 0x040003 /* Inode ref count wrong */ -#define PR_4_INCONSISTENT_COUNT 0x040004 /* Inconsistent inode count information cached */ - -/* - * Pass 5 errors - */ - -#define PR_5_PASS_HEADER 0x050000 /* Pass 5: Checking group summary information */ -#define PR_5_INODE_BMAP_PADDING 0x050001 /* Padding at end of inode bitmap is not set. */ -#define PR_5_BLOCK_BMAP_PADDING 0x050002 /* Padding at end of block bitmap is not set. */ -#define PR_5_BLOCK_BITMAP_HEADER 0x050003 /* Block bitmap differences header */ -#define PR_5_BLOCK_UNUSED 0x050004 /* Block not used, but marked in bitmap */ -#define PR_5_BLOCK_USED 0x050005 /* Block used, but not marked used in bitmap */ -#define PR_5_BLOCK_BITMAP_END 0x050006 /* Block bitmap differences end */ -#define PR_5_INODE_BITMAP_HEADER 0x050007 /* Inode bitmap differences header */ -#define PR_5_INODE_UNUSED 0x050008 /* Inode not used, but marked in bitmap */ -#define PR_5_INODE_USED 0x050009 /* Inode used, but not marked used in bitmap */ -#define PR_5_INODE_BITMAP_END 0x05000A /* Inode bitmap differences end */ -#define PR_5_FREE_INODE_COUNT_GROUP 0x05000B /* Free inodes count for group wrong */ -#define PR_5_FREE_DIR_COUNT_GROUP 0x05000C /* Directories count for group wrong */ -#define PR_5_FREE_INODE_COUNT 0x05000D /* Free inodes count wrong */ -#define PR_5_FREE_BLOCK_COUNT_GROUP 0x05000E /* Free blocks count for group wrong */ -#define PR_5_FREE_BLOCK_COUNT 0x05000F /* Free blocks count wrong */ -#define PR_5_BMAP_ENDPOINTS 0x050010 /* Programming error: bitmap endpoints don't match */ -#define PR_5_FUDGE_BITMAP_ERROR 0x050011 /* Internal error: fudging end of bitmap */ -#define PR_5_COPY_IBITMAP_ERROR 0x050012 /* Error copying in replacement inode bitmap */ -#define PR_5_COPY_BBITMAP_ERROR 0x050013 /* Error copying in replacement block bitmap */ -#define PR_5_BLOCK_RANGE_UNUSED 0x050014 /* Block range not used, but marked in bitmap */ -#define PR_5_BLOCK_RANGE_USED 0x050015 /* Block range used, but not marked used in bitmap */ -#define PR_5_INODE_RANGE_UNUSED 0x050016 /* Inode range not used, but marked in bitmap */ -#define PR_5_INODE_RANGE_USED 0x050017 /* Inode rangeused, but not marked used in bitmap */ - - -/* - * The directory information structure; stores directory information - * collected in earlier passes, to avoid disk i/o in fetching the - * directory information. - */ -struct dir_info { - ext2_ino_t ino; /* Inode number */ - ext2_ino_t dotdot; /* Parent according to '..' */ - ext2_ino_t parent; /* Parent according to treewalk */ -}; - - - -/* - * The indexed directory information structure; stores information for - * directories which contain a hash tree index. - */ -struct dx_dir_info { - ext2_ino_t ino; /* Inode number */ - int numblocks; /* number of blocks */ - int hashversion; - short depth; /* depth of tree */ - struct dx_dirblock_info *dx_block; /* Array of size numblocks */ -}; - -/* - * Define the extended attribute refcount structure - */ -typedef struct ea_refcount *ext2_refcount_t; - -struct e2fsck_struct { - ext2_filsys fs; - const char *program_name; - char *filesystem_name; - char *device_name; - char *io_options; - int flags; /* E2fsck internal flags */ - int options; - blk_t use_superblock; /* sb requested by user */ - blk_t superblock; /* sb used to open fs */ - int blocksize; /* blocksize */ - blk_t num_blocks; /* Total number of blocks */ - int mount_flags; - blkid_cache blkid; /* blkid cache */ - - jmp_buf abort_loc; - - unsigned long abort_code; - - int (*progress)(e2fsck_t ctx, int pass, unsigned long cur, - unsigned long max); - - ext2fs_inode_bitmap inode_used_map; /* Inodes which are in use */ - ext2fs_inode_bitmap inode_bad_map; /* Inodes which are bad somehow */ - ext2fs_inode_bitmap inode_dir_map; /* Inodes which are directories */ - ext2fs_inode_bitmap inode_imagic_map; /* AFS inodes */ - ext2fs_inode_bitmap inode_reg_map; /* Inodes which are regular files*/ - - ext2fs_block_bitmap block_found_map; /* Blocks which are in use */ - ext2fs_block_bitmap block_dup_map; /* Blks referenced more than once */ - ext2fs_block_bitmap block_ea_map; /* Blocks which are used by EA's */ - - /* - * Inode count arrays - */ - ext2_icount_t inode_count; - ext2_icount_t inode_link_info; - - ext2_refcount_t refcount; - ext2_refcount_t refcount_extra; - - /* - * Array of flags indicating whether an inode bitmap, block - * bitmap, or inode table is invalid - */ - int *invalid_inode_bitmap_flag; - int *invalid_block_bitmap_flag; - int *invalid_inode_table_flag; - int invalid_bitmaps; /* There are invalid bitmaps/itable */ - - /* - * Block buffer - */ - char *block_buf; - - /* - * For pass1_check_directory and pass1_get_blocks - */ - ext2_ino_t stashed_ino; - struct ext2_inode *stashed_inode; - - /* - * Location of the lost and found directory - */ - ext2_ino_t lost_and_found; - int bad_lost_and_found; - - /* - * Directory information - */ - int dir_info_count; - int dir_info_size; - struct dir_info *dir_info; - - /* - * Indexed directory information - */ - int dx_dir_info_count; - int dx_dir_info_size; - struct dx_dir_info *dx_dir_info; - - /* - * Directories to hash - */ - ext2_u32_list dirs_to_hash; - - /* - * Tuning parameters - */ - int process_inode_size; - int inode_buffer_blocks; - - /* - * ext3 journal support - */ - io_channel journal_io; - char *journal_name; - - /* - * How we display the progress update (for unix) - */ - int progress_fd; - int progress_pos; - int progress_last_percent; - unsigned int progress_last_time; - int interactive; /* Are we connected directly to a tty? */ - char start_meta[2], stop_meta[2]; - - /* File counts */ - int fs_directory_count; - int fs_regular_count; - int fs_blockdev_count; - int fs_chardev_count; - int fs_links_count; - int fs_symlinks_count; - int fs_fast_symlinks_count; - int fs_fifo_count; - int fs_total_count; - int fs_sockets_count; - int fs_ind_count; - int fs_dind_count; - int fs_tind_count; - int fs_fragmented; - int large_files; - int fs_ext_attr_inodes; - int fs_ext_attr_blocks; - - int ext_attr_ver; - - /* - * For the use of callers of the e2fsck functions; not used by - * e2fsck functions themselves. - */ - void *priv_data; -}; - - -#define tid_gt(x, y) ((x - y) > 0) - -static inline int tid_geq(tid_t x, tid_t y) -{ - int difference = (x - y); - return (difference >= 0); -} diff --git a/e2fsprogs/old_e2fsprogs/e2p/Kbuild.src b/e2fsprogs/old_e2fsprogs/e2p/Kbuild.src deleted file mode 100644 index 482630c..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/Kbuild.src +++ b/dev/null @@ -1,18 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under GPLv2, see file LICENSE in this source tree. - -NEEDED-$(CONFIG_CHATTR) = y -NEEDED-$(CONFIG_LSATTR) = y -NEEDED-$(CONFIG_MKE2FS) = y -NEEDED-$(CONFIG_TUNE2FS) = y - -lib-y:= - -INSERT - -lib-$(NEEDED-y) += fgetsetflags.o fgetsetversion.o pf.o iod.o mntopts.o \ - feature.o ls.o uuid.o pe.o ostype.o ps.o hashstr.o \ - parse_num.o diff --git a/e2fsprogs/old_e2fsprogs/e2p/e2p.h b/e2fsprogs/old_e2fsprogs/e2p/e2p.h deleted file mode 100644 index bad2d6a..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/e2p.h +++ b/dev/null @@ -1,64 +0,0 @@ -/* vi: set sw=4 ts=4: */ -#include "libbb.h" -#include /* Needed by dirent.h on netbsd */ -#include -#include - -#include "../ext2fs/ext2_fs.h" - -#define E2P_FEATURE_COMPAT 0 -#define E2P_FEATURE_INCOMPAT 1 -#define E2P_FEATURE_RO_INCOMPAT 2 -#ifndef EXT3_FEATURE_INCOMPAT_EXTENTS -#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 -#endif - -/* `options' for print_e2flags() */ - -#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); -#define list_super(s) list_super2(s, stdout) -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 --git a/e2fsprogs/old_e2fsprogs/e2p/feature.c b/e2fsprogs/old_e2fsprogs/e2p/feature.c deleted file mode 100644 index 2102ed8..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/feature.c +++ b/dev/null @@ -1,187 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * feature.c --- convert between features and strings - * - * Copyright (C) 1999 Theodore Ts'o - * - * This file can be redistributed under the terms of the GNU Library General - * Public License - * - */ - -#include -#include -#include -#include -#include - -#include "e2p.h" - -struct feature { - int compat; - unsigned int mask; - const char *string; -}; - -static const 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_INO, - "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) -{ - const 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) -{ - const 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 inline char *skip_over_blanks(char *cp) -{ - while (*cp && isspace(*cp)) - cp++; - return cp; -} - -static inline 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 = xstrdup(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 --git a/e2fsprogs/old_e2fsprogs/e2p/fgetsetflags.c b/e2fsprogs/old_e2fsprogs/e2p/fgetsetflags.c deleted file mode 100644 index 008b798..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/fgetsetflags.c +++ b/dev/null @@ -1,70 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 - * 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 - */ - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include -#ifdef HAVE_EXT2_IOCTLS -#include -#include -#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) -{ -#ifdef 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; -notsupp: -#endif /* HAVE_EXT2_IOCTLS */ - errno = EOPNOTSUPP; - return -1; -} diff --git a/e2fsprogs/old_e2fsprogs/e2p/fgetsetversion.c b/e2fsprogs/old_e2fsprogs/e2p/fgetsetversion.c deleted file mode 100644 index 8d79054..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/fgetsetversion.c +++ b/dev/null @@ -1,70 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 - * 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 - */ - -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include - -#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) -{ -#ifdef 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 --git a/e2fsprogs/old_e2fsprogs/e2p/hashstr.c b/e2fsprogs/old_e2fsprogs/e2p/hashstr.c deleted file mode 100644 index 697ffad..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/hashstr.c +++ b/dev/null @@ -1,70 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * feature.c --- convert between features and strings - * - * Copyright (C) 1999 Theodore Ts'o - * - * This file can be redistributed under the terms of the GNU Library General - * Public License - * - */ - -#include -#include -#include -#include -#include - -#include "e2p.h" - -struct hash { - int num; - const char *string; -}; - -static const 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) -{ - const 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) -{ - const 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 --git a/e2fsprogs/old_e2fsprogs/e2p/iod.c b/e2fsprogs/old_e2fsprogs/e2p/iod.c deleted file mode 100644 index 23ab8d5..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/iod.c +++ b/dev/null @@ -1,52 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * iod.c - Iterate a function on each entry of a directory - * - * Copyright (C) 1993, 1994 Remy Card - * 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 -#include -#include - -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 = 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 --git a/e2fsprogs/old_e2fsprogs/e2p/ls.c b/e2fsprogs/old_e2fsprogs/e2p/ls.c deleted file mode 100644 index 9d29db6..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/ls.c +++ b/dev/null @@ -1,273 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * ls.c - List the contents of an ext2fs superblock - * - * Copyright (C) 1992, 1993, 1994 Remy Card - * Laboratoire MASI, Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * Copyright (C) 1995, 1996, 1997 Theodore Ts'o - * - * This file can be redistributed under the terms of the GNU Library General - * Public License - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "e2p.h" - -static void print_user(unsigned short uid, FILE *f) -{ - struct passwd *pw = getpwuid(uid); - fprintf(f, "%u (user %s)\n", uid, - (pw == NULL ? "unknown" : pw->pw_name)); -} - -static void print_group(unsigned short gid, FILE *f) -{ - struct group *gr = getgrgid(gid); - fprintf(f, "%u (group %s)\n", gid, - (gr == NULL ? "unknown" : 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 ""; - - 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, ""); - 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, ""); - fprintf(f, - "Last mounted on: %s\n" - "Filesystem UUID: %s\n" - "Filesystem magic number: 0x%04X\n" - "Filesystem revision #: %d", - buf, e2p_uuid2str(sb->s_uuid), sb->s_magic, 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, "\nErrors behavior: "); - print_fs_errors(f, sb->s_errors); - str = e2p_os2string(sb->s_creator_os); - fprintf(f, - "\n" - "Filesystem OS type: %s\n" - "Inode count: %u\n" - "Block count: %u\n" - "Reserved block count: %u\n" - "Free blocks: %u\n" - "Free inodes: %u\n" - "First block: %u\n" - "Block size: %u\n" - "Fragment size: %u\n", - str, sb->s_inodes_count, sb->s_blocks_count, sb->s_r_blocks_count, - sb->s_free_blocks_count, sb->s_free_inodes_count, - sb->s_first_data_block, EXT2_BLOCK_SIZE(sb), EXT2_FRAG_SIZE(sb)); - free(str); - 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" - "Fragments per group: %u\n" - "Inodes per group: %u\n" - "Inode blocks per group: %u\n", - sb->s_blocks_per_group, sb->s_frags_per_group, - sb->s_inodes_per_group, 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" - "Mount count: %u\n" - "Maximum mount count: %d\n", - ctime(&tm), sb->s_mnt_count, sb->s_max_mnt_count); - tm = sb->s_lastcheck; - fprintf(f, - "Last checked: %s" - "Check interval: %u (%s)\n", - ctime(&tm), - 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" - "Inode size: %d\n", - sb->s_first_ino, 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: "); - if (sb->s_jnl_backup_type == 1) - fprintf(f, "inode blocks\n"); - else - fprintf(f, "type %u\n", sb->s_jnl_backup_type); - } -} diff --git a/e2fsprogs/old_e2fsprogs/e2p/mntopts.c b/e2fsprogs/old_e2fsprogs/e2p/mntopts.c deleted file mode 100644 index 17c26c4..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/mntopts.c +++ b/dev/null @@ -1,134 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * mountopts.c --- convert between default mount options and strings - * - * Copyright (C) 2002 Theodore Ts'o - * - * This file can be redistributed under the terms of the GNU Library General - * Public License - * - */ - -#include -#include -#include -#include -#include - -#include "e2p.h" - -struct mntopt { - unsigned int mask; - const char *string; -}; - -static const 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) -{ - const 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) -{ - const 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 = xstrdup(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 --git a/e2fsprogs/old_e2fsprogs/e2p/ostype.c b/e2fsprogs/old_e2fsprogs/e2p/ostype.c deleted file mode 100644 index 6a2f178..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/ostype.c +++ b/dev/null @@ -1,72 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * getostype.c - Get the Filesystem OS type - * - * Copyright (C) 2004,2005 Theodore Ts'o - * - * This file can be redistributed under the terms of the GNU Library General - * Public License - */ - -#include "e2p.h" -#include -#include - -static const char *const 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 = xstrdup(os); - return ret; -} - -/* - * Convert an os_type to a string - */ -int e2p_string2os(char *str) -{ - const char *const *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 --git a/e2fsprogs/old_e2fsprogs/e2p/parse_num.c b/e2fsprogs/old_e2fsprogs/e2p/parse_num.c deleted file mode 100644 index 6db076f..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/parse_num.c +++ b/dev/null @@ -1,65 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * parse_num.c - Parse the number of blocks - * - * Copyright (C) 2004,2005 Theodore Ts'o - * - * This file can be redistributed under the terms of the GNU Library General - * Public License - */ - -#include "e2p.h" - -#include - -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 -#include - -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 --git a/e2fsprogs/old_e2fsprogs/e2p/pe.c b/e2fsprogs/old_e2fsprogs/e2p/pe.c deleted file mode 100644 index 835274b..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/pe.c +++ b/dev/null @@ -1,32 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * pe.c - Print a second extended filesystem errors behavior - * - * Copyright (C) 1992, 1993, 1994 Remy Card - * 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 - -#include "e2p.h" - -void print_fs_errors(FILE *f, unsigned short errors) -{ - char *disp = NULL; - switch (errors) { - case EXT2_ERRORS_CONTINUE: disp = "Continue"; break; - case EXT2_ERRORS_RO: disp = "Remount read-only"; break; - case EXT2_ERRORS_PANIC: disp = "Panic"; break; - default: disp = "Unknown (continue)"; - } - fprintf(f, disp); -} diff --git a/e2fsprogs/old_e2fsprogs/e2p/pf.c b/e2fsprogs/old_e2fsprogs/e2p/pf.c deleted file mode 100644 index 02cbec7..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/pf.c +++ b/dev/null @@ -1,74 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * pf.c - Print file attributes on an ext2 file system - * - * Copyright (C) 1993, 1994 Remy Card - * 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 - -#include "e2p.h" - -struct flags_name { - unsigned long flag; - const char *short_name; - const char *long_name; -}; - -static const 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); - const 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 --git a/e2fsprogs/old_e2fsprogs/e2p/ps.c b/e2fsprogs/old_e2fsprogs/e2p/ps.c deleted file mode 100644 index a6b4099..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/ps.c +++ b/dev/null @@ -1,27 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * ps.c - Print filesystem state - * - * Copyright (C) 1993, 1994 Remy Card - * 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 - -#include "e2p.h" - -void print_fs_state(FILE *f, unsigned short state) -{ - fprintf(f, (state & EXT2_VALID_FS ? " clean" : " not clean")); - if (state & EXT2_ERROR_FS) - fprintf(f, " with errors"); -} diff --git a/e2fsprogs/old_e2fsprogs/e2p/uuid.c b/e2fsprogs/old_e2fsprogs/e2p/uuid.c deleted file mode 100644 index 474d64a..0000000 --- a/e2fsprogs/old_e2fsprogs/e2p/uuid.c +++ b/dev/null @@ -1,78 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * uuid.c -- utility routines for manipulating UUID's. - */ - -#include -#include -#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 ""; - e2p_uuid_to_str(uu, buf); - return buf; -} diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/Kbuild.src b/e2fsprogs/old_e2fsprogs/ext2fs/Kbuild.src deleted file mode 100644 index 12adc6e..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/Kbuild.src +++ b/dev/null @@ -1,26 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under GPLv2, see file LICENSE in this source tree. - -NEEDED-$(CONFIG_E2FSCK) = y -NEEDED-$(CONFIG_FSCK) = y -NEEDED-$(CONFIG_MKE2FS) = y -NEEDED-$(CONFIG_TUNE2FS) = y - -lib-y:= - -INSERT - -lib-$(NEEDED-y) += gen_bitmap.o bitops.o ismounted.o mkjournal.o unix_io.o \ - rw_bitmaps.o initialize.o bitmaps.o block.o \ - ind_block.o inode.o freefs.o alloc_stats.o closefs.o \ - openfs.o io_manager.o finddev.o read_bb.o alloc.o badblocks.o \ - getsize.o getsectsize.o alloc_tables.o read_bb_file.o mkdir.o \ - bb_inode.o newdir.o alloc_sb.o lookup.o dirblock.o expanddir.o \ - dir_iterate.o link.o res_gdt.o icount.o get_pathname.o dblist.o \ - dirhash.o version.o flushb.o unlink.o check_desc.o valid_blk.o \ - ext_attr.o bmap.o dblist_dir.o ext2fs_inline.o swapfs.o - -CFLAGS += -include $(srctree)/e2fsprogs/e2fsbb.h diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/alloc.c b/e2fsprogs/old_e2fsprogs/ext2fs/alloc.c deleted file mode 100644 index cbb63e1..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/alloc.c +++ b/dev/null @@ -1,173 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 = NULL; - - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/alloc_sb.c b/e2fsprogs/old_e2fsprogs/ext2fs/alloc_sb.c deleted file mode 100644 index a7437c9..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/alloc_sb.c +++ b/dev/null @@ -1,58 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/alloc_stats.c b/e2fsprogs/old_e2fsprogs/ext2fs/alloc_stats.c deleted file mode 100644 index f3ab06a..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/alloc_stats.c +++ b/dev/null @@ -1,53 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 - -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/alloc_tables.c b/e2fsprogs/old_e2fsprogs/ext2fs/alloc_tables.c deleted file mode 100644 index 7c60e2b..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/alloc_tables.c +++ b/dev/null @@ -1,114 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/badblocks.c b/e2fsprogs/old_e2fsprogs/ext2fs/badblocks.c deleted file mode 100644 index 6e5cc10..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/badblocks.c +++ b/dev/null @@ -1,328 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/bb_compat.c b/e2fsprogs/old_e2fsprogs/ext2fs/bb_compat.c deleted file mode 100644 index 419ac77..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/bb_compat.c +++ b/dev/null @@ -1,64 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/bb_inode.c b/e2fsprogs/old_e2fsprogs/ext2fs/bb_inode.c deleted file mode 100644 index a967896..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/bb_inode.c +++ b/dev/null @@ -1,262 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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(NULL); - if (!inode.i_ctime) - inode.i_ctime = time(NULL); - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/bitmaps.c b/e2fsprogs/old_e2fsprogs/ext2fs/bitmaps.c deleted file mode 100644 index 637ed27..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/bitmaps.c +++ b/dev/null @@ -1,211 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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); -} - -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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/bitops.c b/e2fsprogs/old_e2fsprogs/ext2fs/bitops.c deleted file mode 100644 index 3d08394..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/bitops.c +++ b/dev/null @@ -1,90 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_SYS_TYPES_H -#include -#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(unsigned 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(unsigned 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(unsigned 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) - bb_error_msg("#%lu for %s", arg, description); - else - bb_error_msg("#%lu", arg); -#endif -} - -void ext2fs_warn_bitmap2(ext2fs_generic_bitmap bitmap, - int code, unsigned long arg) -{ -#ifndef OMIT_COM_ERR - if (bitmap->description) - bb_error_msg("#%lu for %s", arg, bitmap->description); - else - bb_error_msg("#%lu", arg); -#endif -} diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/bitops.h b/e2fsprogs/old_e2fsprogs/ext2fs/bitops.h deleted file mode 100644 index 7271a49..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/bitops.h +++ b/dev/null @@ -1,105 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 , Copyright 1992, - * Linus Torvalds. - */ -#include - -extern int ext2fs_set_bit(unsigned int nr,void * addr); -extern int ext2fs_clear_bit(unsigned int nr, void * addr); -extern int ext2fs_test_bit(unsigned 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); diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/block.c b/e2fsprogs/old_e2fsprogs/ext2fs/block.c deleted file mode 100644 index dbd04f8..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/block.c +++ b/dev/null @@ -1,437 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/bmap.c b/e2fsprogs/old_e2fsprogs/ext2fs/bmap.c deleted file mode 100644 index 796b0e4..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/bmap.c +++ b/dev/null @@ -1,261 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif - -#include "ext2_fs.h" -#include "ext2fs.h" - -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 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; -#if BB_BIG_ENDIAN - 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]; - -#if BB_BIG_ENDIAN - 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; - -#if BB_BIG_ENDIAN - 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 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 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 = NULL; - 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; -#if BB_BIG_ENDIAN - 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: - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/bmove.c b/e2fsprogs/old_e2fsprogs/ext2fs/bmove.c deleted file mode 100644 index ec9244d..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/bmove.c +++ b/dev/null @@ -1,155 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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) { - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/brel.h b/e2fsprogs/old_e2fsprogs/ext2fs/brel.h deleted file mode 100644 index 87bf72b..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/brel.h +++ b/dev/null @@ -1,86 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/brel_ma.c b/e2fsprogs/old_e2fsprogs/ext2fs/brel_ma.c deleted file mode 100644 index 652a350..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/brel_ma.c +++ b/dev/null @@ -1,196 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#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) { - ext2fs_free_mem(&ma->entries); - ext2fs_free_mem(&ma); - } - ext2fs_free_mem(&brel->name); - ext2fs_free_mem(&brel); - return 0; -} diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/check_desc.c b/e2fsprogs/old_e2fsprogs/ext2fs/check_desc.c deleted file mode 100644 index dd4b0e9..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/check_desc.c +++ b/dev/null @@ -1,69 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/closefs.c b/e2fsprogs/old_e2fsprogs/ext2fs/closefs.c deleted file mode 100644 index bfa15e2..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/closefs.c +++ b/dev/null @@ -1,380 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#endif -#include -#include - -#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); - 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; -#if BB_BIG_ENDIAN - 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; - blk_t group_block; - errcode_t retval; - unsigned long fs_state; - struct ext2_super_block *super_shadow = NULL; - struct ext2_group_desc *group_shadow = NULL; - char *group_ptr; - int old_desc_blocks; -#if BB_BIG_ENDIAN - dgrp_t j; - struct ext2_group_desc *s, *t; -#endif - - 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; -#if BB_BIG_ENDIAN - 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; -#if BB_BIG_ENDIAN - 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; -#if BB_BIG_ENDIAN - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/cmp_bitmaps.c b/e2fsprogs/old_e2fsprogs/ext2fs/cmp_bitmaps.c deleted file mode 100644 index 7f78ff8..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/cmp_bitmaps.c +++ b/dev/null @@ -1,72 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/dblist.c b/e2fsprogs/old_e2fsprogs/ext2fs/dblist.c deleted file mode 100644 index 06ff6d8..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/dblist.c +++ b/dev/null @@ -1,260 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#endif -#include -#include - -#include "ext2_fs.h" -#include "ext2fsP.h" - -static int 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: - 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, - int (*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 int 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/dblist_dir.c b/e2fsprogs/old_e2fsprogs/ext2fs/dblist_dir.c deleted file mode 100644 index b239204..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/dblist_dir.c +++ b/dev/null @@ -1,76 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#endif -#include -#include - -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/dir_iterate.c b/e2fsprogs/old_e2fsprogs/ext2fs/dir_iterate.c deleted file mode 100644 index eb5dae0..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/dir_iterate.c +++ b/dev/null @@ -1,219 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/dirblock.c b/e2fsprogs/old_e2fsprogs/ext2fs/dirblock.c deleted file mode 100644 index f9c5a10..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/dirblock.c +++ b/dev/null @@ -1,132 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#endif -#include -#include - -#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; -#if BB_BIG_ENDIAN - unsigned int do_swap; -#endif - - retval = io_channel_read_blk(fs->io, block, 1, buf); - if (retval) - return retval; -#if BB_BIG_ENDIAN - 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; -#if BB_BIG_ENDIAN - 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))) -{ -#if BB_BIG_ENDIAN - int do_swap = 0; - errcode_t retval; - char *p, *end; - char *buf = NULL; - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/dirhash.c b/e2fsprogs/old_e2fsprogs/ext2fs/dirhash.c deleted file mode 100644 index 09e34be..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/dirhash.c +++ b/dev/null @@ -1,234 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include - -#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 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/dupfs.c b/e2fsprogs/old_e2fsprogs/ext2fs/dupfs.c deleted file mode 100644 index d187937..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/dupfs.c +++ b/dev/null @@ -1,95 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#endif -#include -#include - -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/e2image.h b/e2fsprogs/old_e2fsprogs/ext2fs/e2image.h deleted file mode 100644 index a598d01..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/e2image.h +++ b/dev/null @@ -1,39 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/expanddir.c b/e2fsprogs/old_e2fsprogs/ext2fs/expanddir.c deleted file mode 100644 index 8a29ae5..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/expanddir.c +++ b/dev/null @@ -1,127 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_err.h b/e2fsprogs/old_e2fsprogs/ext2fs/ext2_err.h deleted file mode 100644 index ead3528..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_err.h +++ b/dev/null @@ -1,116 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * ext2_err.h: - * This file is automatically generated; please do not edit it. - */ - -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_ext_attr.h b/e2fsprogs/old_e2fsprogs/ext2fs/ext2_ext_attr.h deleted file mode 100644 index ca309c0..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_ext_attr.h +++ b/dev/null @@ -1,52 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - File: linux/ext2_ext_attr.h - - On-disk format of extended attributes for the ext2 filesystem. - - (C) 2000 Andreas Gruenbacher, -*/ - -/* 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 */ -}; - -#define EXT2_EXT_ATTR_PAD_BITS 2 -#define EXT2_EXT_ATTR_PAD (1<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) diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_fs.h b/e2fsprogs/old_e2fsprogs/ext2fs/ext2_fs.h deleted file mode 100644 index 80ea2cb..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_fs.h +++ b/dev/null @@ -1,569 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 1 - -#include "ext2_types.h" /* Changed from linux/types.h */ - -/* - * 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 - -/* 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) - -/* - * 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) -#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) -#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 -# 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)) - -/* - * 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)) -#define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) - -/* - * 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 - -/* - * 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_INO 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 diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_io.h b/e2fsprogs/old_e2fsprogs/ext2fs/ext2_io.h deleted file mode 100644 index 1900a76..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_io.h +++ b/dev/null @@ -1,112 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 1 - -/* - * 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); */ -#ifdef CONFIG_LFS -# define ext2fs_llseek lseek64 -#else -# define ext2fs_llseek lseek -#endif - -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 diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_types.h b/e2fsprogs/old_e2fsprogs/ext2fs/ext2_types.h deleted file mode 100644 index 2c1196b..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2_types.h +++ b/dev/null @@ -1,2 +0,0 @@ -/* vi: set sw=4 ts=4: */ -#include diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext2fs.h b/e2fsprogs/old_e2fsprogs/ext2fs/ext2fs.h deleted file mode 100644 index 39fb116..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2fs.h +++ b/dev/null @@ -1,922 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 1 - - -#define EXT2FS_ATTR(x) - -#ifdef __cplusplus -extern "C" { -#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 -#endif - -#include -#include - -#include "ext2_types.h" -#include "ext2_fs.h" - -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; - -#include "ext2_io.h" -#include "ext2_err.h" - -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; - -#define EXT2_FIRST_INODE(s) EXT2_FIRST_INO(s) - -/* - * 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; -}; - -#include "bitops.h" - -/* - * 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 -#define EXT2_MF_BUSY 16 - -/* - * 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_INO|\ - 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, - int (*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, - 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); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext2fsP.h b/e2fsprogs/old_e2fsprogs/ext2fs/ext2fsP.h deleted file mode 100644 index 7a02e9a..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2fsP.h +++ b/dev/null @@ -1,87 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext2fs_inline.c b/e2fsprogs/old_e2fsprogs/ext2fs/ext2fs_inline.c deleted file mode 100644 index 7d37d23..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ext2fs_inline.c +++ b/dev/null @@ -1,365 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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% - */ - -#include "ext2fs.h" -#include "bitops.h" -#include - -/* - * Allocate memory - */ -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 - */ -errcode_t ext2fs_free_mem(void *ptr) -{ - void **pp = (void **)ptr; - - free(*pp); - *pp = 0; - return 0; -} - -/* - * Resize memory - */ -errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_size, - unsigned long size, void *ptr) -{ - void *p; - - /* Use "memcpy" for pointer assignments here to avoid problems - * with C99 strict type aliasing rules. */ - memcpy(&p, ptr, sizeof (p)); - p = xrealloc(p, size); - memcpy(ptr, &p, sizeof (p)); - return 0; -} - -/* - * Mark a filesystem superblock as dirty - */ -void ext2fs_mark_super_dirty(ext2_filsys fs) -{ - fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED; -} - -/* - * Mark a filesystem as changed - */ -void ext2fs_mark_changed(ext2_filsys fs) -{ - fs->flags |= EXT2_FLAG_CHANGED; -} - -/* - * Check to see if a filesystem has changed - */ -int ext2fs_test_changed(ext2_filsys fs) -{ - return (fs->flags & EXT2_FLAG_CHANGED); -} - -/* - * Mark a filesystem as valid - */ -void ext2fs_mark_valid(ext2_filsys fs) -{ - fs->flags |= EXT2_FLAG_VALID; -} - -/* - * Mark a filesystem as NOT valid - */ -void ext2fs_unmark_valid(ext2_filsys fs) -{ - fs->flags &= ~EXT2_FLAG_VALID; -} - -/* - * Check to see if a filesystem is valid - */ -int ext2fs_test_valid(ext2_filsys fs) -{ - return (fs->flags & EXT2_FLAG_VALID); -} - -/* - * Mark the inode bitmap as dirty - */ -void ext2fs_mark_ib_dirty(ext2_filsys fs) -{ - fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED; -} - -/* - * Mark the block bitmap as dirty - */ -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 - */ -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 - */ -int ext2fs_test_bb_dirty(ext2_filsys fs) -{ - return (fs->flags & EXT2_FLAG_BB_DIRTY); -} - -/* - * Return the group # of a block - */ -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 - */ -int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino) -{ - return (ino - 1) / fs->super->s_inodes_per_group; -} - -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); -} - - - - - - - - - -__u16 ext2fs_swab16(__u16 val) -{ - return (val >> 8) | (val << 8); -} - -__u32 ext2fs_swab32(__u32 val) -{ - return ((val>>24) | ((val>>8)&0xFF00) | - ((val<<8)&0xFF0000) | (val<<24)); -} - -int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap, - blk_t bitno); - -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); -} - -int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, - blk_t block) -{ - return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) - bitmap, - block); -} - -int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap, - blk_t block) -{ - return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, - block); -} - -int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, - blk_t block) -{ - return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, - block); -} - -int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, - ext2_ino_t inode) -{ - return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, - inode); -} - -int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap, - ext2_ino_t inode) -{ - return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, - inode); -} - -int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, - ext2_ino_t inode) -{ - return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, - inode); -} - -void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap, - blk_t block) -{ - ext2fs_set_bit(block - bitmap->start, bitmap->bitmap); -} - -void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap, - blk_t block) -{ - ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap); -} - -int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap, - blk_t block) -{ - return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap); -} - -void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, - ext2_ino_t inode) -{ - ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap); -} - -void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap, - ext2_ino_t inode) -{ - ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap); -} - -int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap, - ext2_ino_t inode) -{ - return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap); -} - -blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap) -{ - return bitmap->start; -} - -ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap) -{ - return bitmap->start; -} - -blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap) -{ - return bitmap->end; -} - -ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap) -{ - return bitmap->end; -} - -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; -} - -int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap, - blk_t block, int num) -{ - int i; - - for (i=0; i < num; i++) { - if (ext2fs_fast_test_block_bitmap(bitmap, block+i)) - return 0; - } - return 1; -} - -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); -} - -void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap, - blk_t block, int num) -{ - int i; - - for (i=0; i < num; i++) - ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap); -} - -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); -} - -void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap, - blk_t block, int num) -{ - int i; - for (i=0; i < num; i++) - ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap); -} diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ext_attr.c b/e2fsprogs/old_e2fsprogs/ext2fs/ext_attr.c deleted file mode 100644 index a2ba12d..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ext_attr.c +++ b/dev/null @@ -1,101 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * ext_attr.c --- extended attribute blocks - * - * Copyright (C) 2001 Andreas Gruenbacher, - * - * Copyright (C) 2002 Theodore Ts'o. - * - * %Begin-Header% - * This file may be redistributed under the terms of the GNU Public - * License. - * %End-Header% - */ - -#include -#include -#include -#include - -#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; -#if BB_BIG_ENDIAN - 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; - - if (BB_BIG_ENDIAN && ((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 - 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 = NULL; - - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/fileio.c b/e2fsprogs/old_e2fsprogs/ext2fs/fileio.c deleted file mode 100644 index 5a5ad3e..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/fileio.c +++ b/dev/null @@ -1,377 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#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: - 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); - - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/finddev.c b/e2fsprogs/old_e2fsprogs/ext2fs/finddev.c deleted file mode 100644 index e9e83fd..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/finddev.c +++ b/dev/null @@ -1,199 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#ifdef HAVE_UNISTD_H -#include -#endif -#include -#include -#ifdef HAVE_SYS_TYPES_H -#include -#endif -#ifdef HAVE_SYS_STAT_H -#include -#endif -#include -#ifdef HAVE_ERRNO_H -#include -#endif -#ifdef HAVE_SYS_MKDEV_H -#include -#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 = xmalloc(sizeof(struct dir_list)); - dp->name = xmalloc(strlen(name)+1); - 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 = xmalloc(strlen(path)+1); - 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 = NULL, *new_list = NULL; - struct dir_list *current; - char *ret_path = NULL; - - /* - * 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 = "Cannot 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("Cannot find device.\n"); - } - return 0; -} - -#endif diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/flushb.c b/e2fsprogs/old_e2fsprogs/ext2fs/flushb.c deleted file mode 100644 index 45ed765..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/flushb.c +++ b/dev/null @@ -1,83 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_ERRNO_H -#include -#endif -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_SYS_IOCTL_H -#include -#endif -#if HAVE_SYS_MOUNT_H -#include -#include /* 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/freefs.c b/e2fsprogs/old_e2fsprogs/ext2fs/freefs.c deleted file mode 100644 index 0c5d48b..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/freefs.c +++ b/dev/null @@ -1,127 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#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); - } - ext2fs_free_mem(&fs->device_name); - ext2fs_free_mem(&fs->super); - ext2fs_free_mem(&fs->orig_super); - ext2fs_free_mem(&fs->group_desc); - ext2fs_free_block_bitmap(fs->block_map); - ext2fs_free_inode_bitmap(fs->inode_map); - - ext2fs_badblocks_list_free(fs->badblocks); - fs->badblocks = 0; - - 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; - ext2fs_free_mem(&bitmap->description); - ext2fs_free_mem(&bitmap->bitmap); - 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; - ext2fs_free_mem(&icache->buffer); - 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 || bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST) - return; - - ext2fs_free_mem(&bb->list); - 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; - - ext2fs_free_mem(&dblist->list); - if (dblist->fs && dblist->fs->dblist == dblist) - dblist->fs->dblist = 0; - dblist->magic = 0; - ext2fs_free_mem(&dblist); -} diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/gen_bitmap.c b/e2fsprogs/old_e2fsprogs/ext2fs/gen_bitmap.c deleted file mode 100644 index d0869c9..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/gen_bitmap.c +++ b/dev/null @@ -1,49 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/get_pathname.c b/e2fsprogs/old_e2fsprogs/ext2fs/get_pathname.c deleted file mode 100644 index 2bb1cc2..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/get_pathname.c +++ b/dev/null @@ -1,156 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 . is the containing - * directory inode, and is the inode number itself. If - * is zero, then ext2fs_get_pathname will return pathname - * of the directory . - * - */ - -#include -#include -#if HAVE_UNISTD_H -#include -#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: - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/getsectsize.c b/e2fsprogs/old_e2fsprogs/ext2fs/getsectsize.c deleted file mode 100644 index 163ec65..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/getsectsize.c +++ b/dev/null @@ -1,58 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_LINUX_FD_H -#include -#include -#endif - -#if defined(__linux__) && defined(_IO) && !defined(BLKSSZGET) -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/getsize.c b/e2fsprogs/old_e2fsprogs/ext2fs/getsize.c deleted file mode 100644 index ee4bbb7..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/getsize.c +++ b/dev/null @@ -1,291 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#ifdef HAVE_LINUX_FD_H -#include -#endif -#ifdef HAVE_SYS_DISKLABEL_H -#include -#endif -#ifdef HAVE_SYS_DISK_H -#ifdef HAVE_SYS_QUEUE_H -#include /* for LIST_HEAD */ -#endif -#include -#endif -#ifdef __linux__ -#include -#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 -#include - -#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__ - uname(&ut); - if ((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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/icount.c b/e2fsprogs/old_e2fsprogs/ext2fs/icount.c deleted file mode 100644 index 7ab5f51..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/icount.c +++ b/dev/null @@ -1,467 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#endif -#include -#include - -#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; - ext2fs_free_mem(&icount->list); - ext2fs_free_inode_bitmap(icount->single); - 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)); - 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; - 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++]; - low = 0; - high = (int) icount->count-1; - while (low <= high) { - 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))); - } - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/imager.c b/e2fsprogs/old_e2fsprogs/ext2fs/imager.c deleted file mode 100644 index 0f9cfcf..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/imager.c +++ b/dev/null @@ -1,377 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 = xmalloc(fs->blocksize * BUF_BLOCKS); - - 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 = xmalloc(fs->blocksize * BUF_BLOCKS); - - 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 = xmalloc(fs->blocksize); - - /* - * 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 = xmalloc(size); - - /* - * 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 = NULL; - 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 = xmalloc(size); - - 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: - free(buf); - return retval; -} diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ind_block.c b/e2fsprogs/old_e2fsprogs/ext2fs/ind_block.c deleted file mode 100644 index a103830..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ind_block.c +++ b/dev/null @@ -1,69 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#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; -#if BB_BIG_ENDIAN - blk_t *block_nr; - int i; - int limit = fs->blocksize >> 2; -#endif - - 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; - } -#if BB_BIG_ENDIAN - 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) -{ -#if BB_BIG_ENDIAN - blk_t *block_nr; - int i; - int limit = fs->blocksize >> 2; -#endif - - if (fs->flags & EXT2_FLAG_IMAGE_FILE) - return 0; - -#if BB_BIG_ENDIAN - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/initialize.c b/e2fsprogs/old_e2fsprogs/ext2fs/initialize.c deleted file mode 100644 index 240335b..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/initialize.c +++ b/dev/null @@ -1,388 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 = %u\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_INO) - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/inline.c b/e2fsprogs/old_e2fsprogs/ext2fs/inline.c deleted file mode 100644 index 7457b93..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/inline.c +++ b/dev/null @@ -1,32 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#endif - -#include "ext2_fs.h" -#define INCLUDE_INLINE_FUNCS -#include "ext2fs.h" diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/inode.c b/e2fsprogs/old_e2fsprogs/ext2fs/inode.c deleted file mode 100644 index 7a1d5c9..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/inode.c +++ b/dev/null @@ -1,766 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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, - 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) { - 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); -} - -void ext2fs_set_inode_callback(ext2_inode_scan scan, - errcode_t (*done_group)(ext2_filsys fs, - 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; -} - -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->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; - -#if BB_BIG_ENDIAN - 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 { -#if BB_BIG_ENDIAN - 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++; - } - -#if BB_BIG_ENDIAN - 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 = xmalloc(length); - } else - w_inode = &temp_inode; - memset(w_inode, 0, length); - -#if BB_BIG_ENDIAN - 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 = xmalloc(size); - - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/inode_io.c b/e2fsprogs/old_e2fsprogs/ext2fs/inode_io.c deleted file mode 100644 index b861d5f..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/inode_io.c +++ b/dev/null @@ -1,270 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#include - -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/io_manager.c b/e2fsprogs/old_e2fsprogs/ext2fs/io_manager.c deleted file mode 100644 index b470386..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/io_manager.c +++ b/dev/null @@ -1,70 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * io_manager.c --- the I/O manager abstraction - */ - -#include -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/irel.h b/e2fsprogs/old_e2fsprogs/ext2fs/irel.h deleted file mode 100644 index 91d1d89..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/irel.h +++ b/dev/null @@ -1,115 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/irel_ma.c b/e2fsprogs/old_e2fsprogs/ext2fs/irel_ma.c deleted file mode 100644 index c871b18..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/irel_ma.c +++ b/dev/null @@ -1,367 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#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]; - 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; - 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) { - ext2fs_free_mem(&ma->orig_map); - ext2fs_free_mem(&ma->entries); - if (ma->ref_entries) { - for (ino = 0; ino <= ma->max_inode; ino++) { - ext2fs_free_mem(&ma->ref_entries[(unsigned) ino].refs); - } - ext2fs_free_mem(&ma->ref_entries); - } - ext2fs_free_mem(&ma); - } - ext2fs_free_mem(&irel->name); - ext2fs_free_mem(&irel); - return 0; -} diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/ismounted.c b/e2fsprogs/old_e2fsprogs/ext2fs/ismounted.c deleted file mode 100644 index f5f6f31..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/ismounted.c +++ b/dev/null @@ -1,357 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#include -#ifdef HAVE_LINUX_FD_H -#include -#endif -#ifdef HAVE_MNTENT_H -#include -#endif -#ifdef HAVE_GETMNTINFO -#include -#include -#include -#endif /* HAVE_GETMNTINFO */ -#include -#include - -#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 (LONE_CHAR(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_for_read("/proc/swaps"))) - 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, "", 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_BUSY) - printf("\t%s is apparently in use.\n", argv[1]); - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/jfs_dat.h b/e2fsprogs/old_e2fsprogs/ext2fs/jfs_dat.h deleted file mode 100644 index 17c586a..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/jfs_dat.h +++ b/dev/null @@ -1,63 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/kernel-jbd.h b/e2fsprogs/old_e2fsprogs/ext2fs/kernel-jbd.h deleted file mode 100644 index 853d97a..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/kernel-jbd.h +++ b/dev/null @@ -1,235 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * linux/include/linux/jbd.h - * - * Written by Stephen C. Tweedie - * - * 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 1 - -#include -#include -#include "ext2fs.h" - -/* - * Standard header for all descriptor blocks: - */ - -typedef struct journal_header_s -{ - __u32 h_magic; - __u32 h_blocktype; - __u32 h_sequence; -} journal_header_t; - -/* - * This is the global e2fsck structure. - */ -typedef struct e2fsck_struct *e2fsck_t; - - -struct inode { - e2fsck_t i_ctx; - ext2_ino_t i_ino; - struct ext2_inode i_ext2; -}; - - -/* - * 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; - - -extern int journal_blocks_per_page(struct inode *inode); -extern int jbd_blocks_per_page(struct inode *inode); - -#define JFS_MIN_JOURNAL_BLOCKS 1024 - - -/* - * Internal structures used by the logging mechanism: - */ - -#define JFS_MAGIC_NUMBER 0xc03b3998U /* The first 4 bytes of /dev/random! */ - -/* - * 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 - -/* - * 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 */ - - - - -#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 - -/* Comparison functions for transaction IDs: perform comparisons using - * modulo arithmetic so that they work over sequence number wraps. */ - - -/* - * 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 - - -struct kdev_s { - e2fsck_t k_ctx; - int k_dev; -}; - -typedef struct kdev_s *kdev_t; -typedef unsigned int tid_t; - -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; -}; - -typedef struct journal_s journal_t; - -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 diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/kernel-list.h b/e2fsprogs/old_e2fsprogs/ext2fs/kernel-list.h deleted file mode 100644 index d80716a..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/kernel-list.h +++ b/dev/null @@ -1,113 +0,0 @@ -/* vi: set sw=4 ts=4: */ -#ifndef LINUX_LIST_H -#define LINUX_LIST_H 1 - -/* - * 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/link.c b/e2fsprogs/old_e2fsprogs/ext2fs/link.c deleted file mode 100644 index 08b2e96..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/link.c +++ b/dev/null @@ -1,135 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/lookup.c b/e2fsprogs/old_e2fsprogs/ext2fs/lookup.c deleted file mode 100644 index b2e8de8..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/lookup.c +++ b/dev/null @@ -1,68 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/mkdir.c b/e2fsprogs/old_e2fsprogs/ext2fs/mkdir.c deleted file mode 100644 index a86ac8e..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/mkdir.c +++ b/dev/null @@ -1,139 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 = NULL; - - 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: - ext2fs_free_mem(&block); - return retval; -} diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/mkjournal.c b/e2fsprogs/old_e2fsprogs/ext2fs/mkjournal.c deleted file mode 100644 index 748d9ab..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/mkjournal.c +++ b/dev/null @@ -1,426 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#endif -#if HAVE_SYS_IOCTL_H -#include -#endif -#if HAVE_NETINET_IN_H -#include -#endif - -#include "ext2_fs.h" -#include "../e2p/e2p.h" -#include "../e2fsck.h" -#include "ext2fs.h" -#include "kernel-jbd.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 = NULL; - 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(NULL); - 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; - - retval = ext2fs_check_mount_point(fs->device_name, &mount_flags, - jfile, sizeof(jfile)-10); - if (retval) - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/namei.c b/e2fsprogs/old_e2fsprogs/ext2fs/namei.c deleted file mode 100644 index 1824461..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/namei.c +++ b/dev/null @@ -1,204 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#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 = NULL; - 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); - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/newdir.c b/e2fsprogs/old_e2fsprogs/ext2fs/newdir.c deleted file mode 100644 index 9f15662..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/newdir.c +++ b/dev/null @@ -1,72 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/openfs.c b/e2fsprogs/old_e2fsprogs/ext2fs/openfs.c deleted file mode 100644 index 1b27119..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/openfs.c +++ b/dev/null @@ -1,330 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 groups_per_block, blocks_per_group; - blk_t group_block, blk; - char *dest, *cp; -#if BB_BIG_ENDIAN - int j; - struct ext2_group_desc *gdp; -#endif - - 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); - -#if BB_BIG_ENDIAN - 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; -#if BB_BIG_ENDIAN - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/read_bb.c b/e2fsprogs/old_e2fsprogs/ext2fs/read_bb.c deleted file mode 100644 index ce77bc9..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/read_bb.c +++ b/dev/null @@ -1,96 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/read_bb_file.c b/e2fsprogs/old_e2fsprogs/ext2fs/read_bb_file.c deleted file mode 100644 index bf1fc32..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/read_bb_file.c +++ b/dev/null @@ -1,96 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/res_gdt.c b/e2fsprogs/old_e2fsprogs/ext2fs/res_gdt.c deleted file mode 100644 index 403463a..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/res_gdt.c +++ b/dev/null @@ -1,220 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include -#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(NULL); - } - - 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(NULL); - retval2 = ext2fs_write_inode(fs, EXT2_RESIZE_INO, &inode); - if (!retval) - retval = retval2; - } -out_free: - ext2fs_free_mem((void *)&dindir_buf); - return retval; -} diff --git a/e2fsprogs/old_e2fsprogs/ext2fs/rs_bitmap.c b/e2fsprogs/old_e2fsprogs/ext2fs/rs_bitmap.c deleted file mode 100644 index 32e87b7..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/rs_bitmap.c +++ b/dev/null @@ -1,106 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/rw_bitmaps.c b/e2fsprogs/old_e2fsprogs/ext2fs/rw_bitmaps.c deleted file mode 100644 index bba4326..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/rw_bitmaps.c +++ b/dev/null @@ -1,294 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#ifdef HAVE_SYS_STAT_H -#include -#endif -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#include "ext2_fs.h" -#include "ext2fs.h" -#include "e2image.h" - -#if defined(__powerpc__) && BB_BIG_ENDIAN -/* - * 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 = NULL, *inode_bitmap = NULL; - 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) { - 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) { - 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); - } - if (do_inode) { - ext2fs_free_mem(&fs->inode_map); - } - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/sparse.c b/e2fsprogs/old_e2fsprogs/ext2fs/sparse.c deleted file mode 100644 index b3d3071..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/sparse.c +++ b/dev/null @@ -1,79 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 - -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/swapfs.c b/e2fsprogs/old_e2fsprogs/ext2fs/swapfs.c deleted file mode 100644 index 07b757a..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/swapfs.c +++ b/dev/null @@ -1,234 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include -#include - -#include "ext2_fs.h" -#include "ext2fs.h" -#include "ext2_ext_attr.h" - -#if BB_BIG_ENDIAN -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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/test_io.c b/e2fsprogs/old_e2fsprogs/ext2fs/test_io.c deleted file mode 100644 index 3d40d9a..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/test_io.c +++ b/dev/null @@ -1,380 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#include -#include -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#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_for_write(value); - 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: - ext2fs_free_mem(&io); - 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); - 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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/unix_io.c b/e2fsprogs/old_e2fsprogs/ext2fs/unix_io.c deleted file mode 100644 index 3c95829..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/unix_io.c +++ b/dev/null @@ -1,703 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#endif -#if HAVE_ERRNO_H -#include -#endif -#include -#include -#ifdef __linux__ -#include -#endif -#if HAVE_SYS_STAT_H -#include -#endif -#if HAVE_SYS_TYPES_H -#include -#endif -#include - -#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; - 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); - } - 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); - 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 %lu\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 %lu\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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/unlink.c b/e2fsprogs/old_e2fsprogs/ext2fs/unlink.c deleted file mode 100644 index 71a9ffc..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/unlink.c +++ b/dev/null @@ -1,99 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#if HAVE_UNISTD_H -#include -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/valid_blk.c b/e2fsprogs/old_e2fsprogs/ext2fs/valid_blk.c deleted file mode 100644 index 8ed77ae..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/valid_blk.c +++ b/dev/null @@ -1,57 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#if HAVE_UNISTD_H -#include -#endif -#include -#include - -#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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/version.c b/e2fsprogs/old_e2fsprogs/ext2fs/version.c deleted file mode 100644 index d2981e8..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/version.c +++ b/dev/null @@ -1,51 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#endif -#include -#include -#include - -#include "ext2_fs.h" -#include "ext2fs.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 --git a/e2fsprogs/old_e2fsprogs/ext2fs/write_bb_file.c b/e2fsprogs/old_e2fsprogs/ext2fs/write_bb_file.c deleted file mode 100644 index 5b19eef..0000000 --- a/e2fsprogs/old_e2fsprogs/ext2fs/write_bb_file.c +++ b/dev/null @@ -1,35 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 - -#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 --git a/e2fsprogs/old_e2fsprogs/fsck.c b/e2fsprogs/old_e2fsprogs/fsck.c deleted file mode 100644 index 91cce97..0000000 --- a/e2fsprogs/old_e2fsprogs/fsck.c +++ b/dev/null @@ -1,1375 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * pfsck --- A generic, parallelizing front-end for the fsck program. - * It will automatically try to run fsck programs in parallel if the - * devices are on separate spindles. It is based on the same ideas as - * the generic front end for fsck by David Engel and Fred van Kempen, - * but it has been completely rewritten from scratch to support - * parallel execution. - * - * Written by Theodore Ts'o, - * - * Miquel van Smoorenburg (miquels@drinkel.ow.org) 20-Oct-1994: - * o Changed -t fstype to behave like with mount when -A (all file - * systems) or -M (like mount) is specified. - * o fsck looks if it can find the fsck.type program to decide - * if it should ignore the fs type. This way more fsck programs - * can be added without changing this front-end. - * o -R flag skip root file system. - * - * Copyright (C) 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, - * 2001, 2002, 2003, 2004, 2005 by Theodore Ts'o. - * - * Licensed under GPLv2, see file LICENSE in this source tree. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "fsck.h" -#include "blkid/blkid.h" - -#include "e2fsbb.h" - -#include "libbb.h" - -#ifndef _PATH_MNTTAB -#define _PATH_MNTTAB "/etc/fstab" -#endif - -/* - * fsck.h - */ - -#ifndef DEFAULT_FSTYPE -#define DEFAULT_FSTYPE "ext2" -#endif - -#define MAX_DEVICES 32 -#define MAX_ARGS 32 - -/* - * Internal structure for mount tabel entries. - */ - -struct fs_info { - char *device; - char *mountpt; - char *type; - char *opts; - int freq; - int passno; - int flags; - struct fs_info *next; -}; - -#define FLAG_DONE 1 -#define FLAG_PROGRESS 2 - -/* - * Structure to allow exit codes to be stored - */ -struct fsck_instance { - int pid; - int flags; - int exit_status; - time_t start_time; - char * prog; - char * type; - char * device; - char * base_device; - struct fsck_instance *next; -}; - -/* - * 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 cannot be determined, return NULL. - * - * The base_device() function returns an allocated string which must - * be freed. - * - */ - - -#ifdef CONFIG_FEATURE_DEVFS -/* - * Required for the uber-silly devfs /dev/ide/host1/bus2/target3/lun3 - * pathames. - */ -static const char *const devfs_hier[] = { - "host", "bus", "target", "lun", 0 -}; -#endif - -static char *base_device(const char *device) -{ - char *str, *cp; -#ifdef CONFIG_FEATURE_DEVFS - const char *const *hier; - const char *disk; - int len; -#endif - - cp = str = xstrdup(device); - - /* Skip over /dev/; if it's not present, give up. */ - if (strncmp(cp, "/dev/", 5) != 0) - goto errout; - cp += 5; - - /* - * 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; -} - - -static const char *const ignored_types[] = { - "ignore", - "iso9660", - "nfs", - "proc", - "sw", - "swap", - "tmpfs", - "devpts", - NULL -}; - -static const char *const really_wanted[] = { - "minix", - "ext2", - "ext3", - "jfs", - "reiserfs", - "xiafs", - "xfs", - NULL -}; - -#define BASE_MD "/dev/md" - -/* - * Global variables for options - */ -static char *devices[MAX_DEVICES]; -static char *args[MAX_ARGS]; -static int num_devices, num_args; - -static int verbose; -static int doall; -static int noexecute; -static int serialize; -static int skip_root; -static int like_mount; -static int notitle; -static int parallel_root; -static int progress; -static int progress_fd; -static int force_all_parallel; -static int num_running; -static int max_running; -static volatile int cancel_requested; -static int kill_sent; -static char *fstype; -static struct fs_info *filesys_info, *filesys_last; -static struct fsck_instance *instance_list; -static char *fsck_path; -static blkid_cache cache; - -static char *string_copy(const char *s) -{ - char *ret; - - if (!s) - return 0; - ret = xstrdup(s); - return ret; -} - -static int string_to_int(const char *s) -{ - long l; - char *p; - - l = strtol(s, &p, 0); - if (*p || l == LONG_MIN || l == LONG_MAX || l < 0 || l > INT_MAX) - return -1; - else - return (int) l; -} - -static char *skip_over_blank(char *cp) -{ - while (*cp && isspace(*cp)) - cp++; - return cp; -} - -static char *skip_over_word(char *cp) -{ - while (*cp && !isspace(*cp)) - cp++; - return cp; -} - -static void strip_line(char *line) -{ - char *p; - - while (*line) { - p = line + strlen(line) - 1; - if ((*p == '\n') || (*p == '\r')) - *p = 0; - else - break; - } -} - -static char *parse_word(char **buf) -{ - char *word, *next; - - word = *buf; - if (*word == 0) - return 0; - - word = skip_over_blank(word); - next = skip_over_word(word); - if (*next) - *next++ = 0; - *buf = next; - return word; -} - -static void parse_escape(char *word) -{ - char *q, c; - const char *p; - - if (!word) - return; - - strcpy_and_process_escape_sequences(word, word); -} - -static void free_instance(struct fsck_instance *i) -{ - if (i->prog) - free(i->prog); - if (i->device) - free(i->device); - if (i->base_device) - free(i->base_device); - free(i); -} - -static struct fs_info *create_fs_device(const char *device, const char *mntpnt, - const char *type, const char *opts, - int freq, int passno) -{ - struct fs_info *fs; - - fs = xmalloc(sizeof(struct fs_info)); - - fs->device = string_copy(device); - fs->mountpt = string_copy(mntpnt); - fs->type = string_copy(type); - fs->opts = string_copy(opts ? opts : ""); - fs->freq = freq; - fs->passno = passno; - fs->flags = 0; - fs->next = NULL; - - if (!filesys_info) - filesys_info = fs; - else - filesys_last->next = fs; - filesys_last = fs; - - return fs; -} - - - -static int parse_fstab_line(char *line, struct fs_info **ret_fs) -{ - char *dev, *device, *mntpnt, *type, *opts, *freq, *passno, *cp; - struct fs_info *fs; - - *ret_fs = 0; - strip_line(line); - if ((cp = strchr(line, '#'))) - *cp = 0; /* Ignore everything after the comment char */ - cp = line; - - device = parse_word(&cp); - mntpnt = parse_word(&cp); - type = parse_word(&cp); - opts = parse_word(&cp); - freq = parse_word(&cp); - passno = parse_word(&cp); - - if (!device) - return 0; /* Allow blank lines */ - - if (!mntpnt || !type) - return -1; - - parse_escape(device); - parse_escape(mntpnt); - parse_escape(type); - parse_escape(opts); - parse_escape(freq); - parse_escape(passno); - - dev = blkid_get_devname(cache, device, NULL); - if (dev) - device = dev; - - if (strchr(type, ',')) - type = 0; - - fs = create_fs_device(device, mntpnt, type ? type : "auto", opts, - freq ? atoi(freq) : -1, - passno ? atoi(passno) : -1); - if (dev) - free(dev); - - if (!fs) - return -1; - *ret_fs = fs; - return 0; -} - -static void interpret_type(struct fs_info *fs) -{ - char *t; - - if (strcmp(fs->type, "auto") != 0) - return; - t = blkid_get_tag_value(cache, "TYPE", fs->device); - if (t) { - free(fs->type); - fs->type = t; - } -} - -/* - * Load the filesystem database from /etc/fstab - */ -static void load_fs_info(const char *filename) -{ - FILE *f; - char buf[1024]; - int lineno = 0; - int old_fstab = 1; - struct fs_info *fs; - - if ((f = fopen_or_warn(filename, "r")) == NULL) { - return; - } - while (!feof(f)) { - lineno++; - if (!fgets(buf, sizeof(buf), f)) - break; - buf[sizeof(buf)-1] = 0; - if (parse_fstab_line(buf, &fs) < 0) { - bb_error_msg("WARNING: bad format " - "on line %d of %s\n", lineno, filename); - continue; - } - if (!fs) - continue; - if (fs->passno < 0) - fs->passno = 0; - else - old_fstab = 0; - } - - fclose(f); - - if (old_fstab) { - fputs("\007\007\007" - "WARNING: Your /etc/fstab does not contain the fsck passno\n" - " field. I will kludge around things for you, but you\n" - " should fix your /etc/fstab file as soon as you can.\n\n", stderr); - - for (fs = filesys_info; fs; fs = fs->next) { - fs->passno = 1; - } - } -} - -/* Lookup filesys in /etc/fstab and return the corresponding entry. */ -static struct fs_info *lookup(char *filesys) -{ - struct fs_info *fs; - - /* No filesys name given. */ - if (filesys == NULL) - return NULL; - - for (fs = filesys_info; fs; fs = fs->next) { - if (!strcmp(filesys, fs->device) || - (fs->mountpt && !strcmp(filesys, fs->mountpt))) - break; - } - - return fs; -} - -/* Find fsck program for a given fs type. */ -static char *find_fsck(char *type) -{ - char *s; - const char *tpl; - char *p = string_copy(fsck_path); - struct stat st; - - /* Are we looking for a program or just a type? */ - tpl = (strncmp(type, "fsck.", 5) ? "%s/fsck.%s" : "%s/%s"); - - for (s = strtok(p, ":"); s; s = strtok(NULL, ":")) { - s = xasprintf(tpl, s, type); - if (stat(s, &st) == 0) break; - free(s); - } - free(p); - return s; -} - -static int progress_active(void) -{ - struct fsck_instance *inst; - - for (inst = instance_list; inst; inst = inst->next) { - if (inst->flags & FLAG_DONE) - continue; - if (inst->flags & FLAG_PROGRESS) - return 1; - } - return 0; -} - -/* - * Execute a particular fsck program, and link it into the list of - * child processes we are waiting for. - */ -static int execute(const char *type, const char *device, const char *mntpt, - int interactive) -{ - char *s, *argv[80]; - char *prog; - int argc, i; - struct fsck_instance *inst, *p; - pid_t pid; - - inst = xzalloc(sizeof(struct fsck_instance)); - - prog = xasprintf("fsck.%s", type); - argv[0] = prog; - argc = 1; - - for (i=0; i flags |= FLAG_PROGRESS; - } - } - - argv[argc++] = string_copy(device); - argv[argc] = 0; - - s = find_fsck(prog); - if (s == NULL) { - bb_error_msg("%s: not found", prog); - return ENOENT; - } - - if (verbose || noexecute) { - printf("[%s (%d) -- %s] ", s, num_running, - mntpt ? mntpt : device); - for (i=0; i < argc; i++) - printf("%s ", argv[i]); - bb_putchar('\n'); - } - - /* Fork and execute the correct program. */ - if (noexecute) - pid = -1; - else if ((pid = fork()) < 0) { - perror("vfork"+1); - return errno; - } else if (pid == 0) { - if (!interactive) - close(0); - (void) execv(s, argv); - bb_simple_perror_msg_and_die(argv[0]); - } - - for (i = 1; i < argc; i++) - free(argv[i]); - - free(s); - inst->pid = pid; - inst->prog = prog; - inst->type = string_copy(type); - inst->device = string_copy(device); - inst->base_device = base_device(device); - inst->start_time = time(0); - inst->next = NULL; - - /* - * Find the end of the list, so we add the instance on at the end. - */ - for (p = instance_list; p && p->next; p = p->next); - - if (p) - p->next = inst; - else - instance_list = inst; - - return 0; -} - -/* - * Send a signal to all outstanding fsck child processes - */ -static int kill_all(int signum) -{ - struct fsck_instance *inst; - int n = 0; - - for (inst = instance_list; inst; inst = inst->next) { - if (inst->flags & FLAG_DONE) - continue; - kill(inst->pid, signum); - n++; - } - return n; -} - -/* - * Wait for one child process to exit; when it does, unlink it from - * the list of executing child processes, and return it. - */ -static struct fsck_instance *wait_one(int flags) -{ - int status; - int sig; - struct fsck_instance *inst, *inst2, *prev; - pid_t pid; - - if (!instance_list) - return NULL; - - if (noexecute) { - inst = instance_list; - prev = 0; -#ifdef RANDOM_DEBUG - while (inst->next && (random() & 1)) { - prev = inst; - inst = inst->next; - } -#endif - inst->exit_status = 0; - goto ret_inst; - } - - /* - * gcc -Wall fails saving throw against stupidity - * (inst and prev are thought to be uninitialized variables) - */ - inst = prev = NULL; - - do { - pid = waitpid(-1, &status, flags); - if (cancel_requested && !kill_sent) { - kill_all(SIGTERM); - kill_sent++; - } - if ((pid == 0) && (flags & WNOHANG)) - return NULL; - if (pid < 0) { - if ((errno == EINTR) || (errno == EAGAIN)) - continue; - if (errno == ECHILD) { - bb_error_msg("wait: no more child process?!?"); - return NULL; - } - perror("wait"); - continue; - } - for (prev = 0, inst = instance_list; - inst; - prev = inst, inst = inst->next) { - if (inst->pid == pid) - break; - } - } while (!inst); - - if (WIFEXITED(status)) - status = WEXITSTATUS(status); - else if (WIFSIGNALED(status)) { - sig = WTERMSIG(status); - if (sig == SIGINT) { - status = EXIT_UNCORRECTED; - } else { - printf("Warning... %s for device %s exited " - "with signal %d.\n", - inst->prog, inst->device, sig); - status = EXIT_ERROR; - } - } else { - printf("%s %s: status is %x, should never happen.\n", - inst->prog, inst->device, status); - status = EXIT_ERROR; - } - inst->exit_status = status; - if (progress && (inst->flags & FLAG_PROGRESS) && - !progress_active()) { - for (inst2 = instance_list; inst2; inst2 = inst2->next) { - if (inst2->flags & FLAG_DONE) - continue; - if (strcmp(inst2->type, "ext2") && - strcmp(inst2->type, "ext3")) - continue; - /* - * If we've just started the fsck, wait a tiny - * bit before sending the kill, to give it - * time to set up the signal handler - */ - if (inst2->start_time < time(0)+2) { - if (fork() == 0) { - sleep(1); - kill(inst2->pid, SIGUSR1); - exit(0); - } - } else - kill(inst2->pid, SIGUSR1); - inst2->flags |= FLAG_PROGRESS; - break; - } - } -ret_inst: - if (prev) - prev->next = inst->next; - else - instance_list = inst->next; - if (verbose > 1) - printf("Finished with %s (exit status %d)\n", - inst->device, inst->exit_status); - num_running--; - return inst; -} - -#define FLAG_WAIT_ALL 0 -#define FLAG_WAIT_ATLEAST_ONE 1 -/* - * Wait until all executing child processes have exited; return the - * logical OR of all of their exit code values. - */ -static int wait_many(int flags) -{ - struct fsck_instance *inst; - int global_status = 0; - int wait_flags = 0; - - while ((inst = wait_one(wait_flags))) { - global_status |= inst->exit_status; - free_instance(inst); -#ifdef RANDOM_DEBUG - if (noexecute && (flags & WNOHANG) && !(random() % 3)) - break; -#endif - if (flags & FLAG_WAIT_ATLEAST_ONE) - wait_flags = WNOHANG; - } - return global_status; -} - -/* - * Run the fsck program on a particular device - * - * If the type is specified using -t, and it isn't prefixed with "no" - * (as in "noext2") and only one filesystem type is specified, then - * use that type regardless of what is specified in /etc/fstab. - * - * If the type isn't specified by the user, then use either the type - * specified in /etc/fstab, or DEFAULT_FSTYPE. - */ -static void fsck_device(struct fs_info *fs, int interactive) -{ - const char *type; - int retval; - - interpret_type(fs); - - if (strcmp(fs->type, "auto") != 0) - type = fs->type; - else if (fstype && strncmp(fstype, "no", 2) && - strncmp(fstype, "opts=", 5) && strncmp(fstype, "loop", 4) && - !strchr(fstype, ',')) - type = fstype; - else - type = DEFAULT_FSTYPE; - - num_running++; - retval = execute(type, fs->device, fs->mountpt, interactive); - if (retval) { - bb_error_msg("error %d while executing fsck.%s for %s", - retval, type, fs->device); - num_running--; - } -} - - -/* - * Deal with the fsck -t argument. - */ -struct fs_type_compile { - char **list; - int *type; - int negate; -} fs_type_compiled; - -#define FS_TYPE_NORMAL 0 -#define FS_TYPE_OPT 1 -#define FS_TYPE_NEGOPT 2 - -static const char fs_type_syntax_error[] = -"Either all or none of the filesystem types passed to -t must be prefixed\n" - "with 'no' or '!'."; - -static void compile_fs_type(char *fs_type, struct fs_type_compile *cmp) -{ - char *cp, *list, *s; - int num = 2; - int negate, first_negate = 1; - - if (fs_type) { - for (cp=fs_type; *cp; cp++) { - if (*cp == ',') - num++; - } - } - - cmp->list = xzalloc(num * sizeof(char *)); - cmp->type = xzalloc(num * sizeof(int)); - cmp->negate = 0; - - if (!fs_type) - return; - - list = string_copy(fs_type); - num = 0; - s = strtok(list, ","); - while (s) { - negate = 0; - if (strncmp(s, "no", 2) == 0) { - s += 2; - negate = 1; - } else if (*s == '!') { - s++; - negate = 1; - } - if (strcmp(s, "loop") == 0) - /* loop is really short-hand for opts=loop */ - goto loop_special_case; - else if (strncmp(s, "opts=", 5) == 0) { - s += 5; - loop_special_case: - cmp->type[num] = negate ? FS_TYPE_NEGOPT : FS_TYPE_OPT; - } else { - if (first_negate) { - cmp->negate = negate; - first_negate = 0; - } - if ((negate && !cmp->negate) || - (!negate && cmp->negate)) { - bb_error_msg_and_die("%s", fs_type_syntax_error); - } - } - cmp->list[num++] = string_copy(s); - s = strtok(NULL, ","); - } - free(list); -} - -/* - * This function returns true if a particular option appears in a - * comma-delimited options list - */ -static int opt_in_list(char *opt, char *optlist) -{ - char *list, *s; - - if (!optlist) - return 0; - list = string_copy(optlist); - - s = strtok(list, ","); - while (s) { - if (strcmp(s, opt) == 0) { - free(list); - return 1; - } - s = strtok(NULL, ","); - } - free(list); - return 0; -} - -/* See if the filesystem matches the criteria given by the -t option */ -static int fs_match(struct fs_info *fs, struct fs_type_compile *cmp) -{ - int n, ret = 0, checked_type = 0; - char *cp; - - if (cmp->list == 0 || cmp->list[0] == 0) - return 1; - - for (n=0; (cp = cmp->list[n]); n++) { - switch (cmp->type[n]) { - case FS_TYPE_NORMAL: - checked_type++; - if (strcmp(cp, fs->type) == 0) { - ret = 1; - } - break; - case FS_TYPE_NEGOPT: - if (opt_in_list(cp, fs->opts)) - return 0; - break; - case FS_TYPE_OPT: - if (!opt_in_list(cp, fs->opts)) - return 0; - break; - } - } - if (checked_type == 0) - return 1; - return (cmp->negate ? !ret : ret); -} - -/* Check if we should ignore this filesystem. */ -static int ignore(struct fs_info *fs) -{ - int wanted; - char *s; - - /* - * If the pass number is 0, ignore it. - */ - if (fs->passno == 0) - return 1; - - interpret_type(fs); - - /* - * If a specific fstype is specified, and it doesn't match, - * ignore it. - */ - if (!fs_match(fs, &fs_type_compiled)) return 1; - - /* Are we ignoring this type? */ - if (index_in_str_array(ignored_types, fs->type) >= 0) - return 1; - - /* Do we really really want to check this fs? */ - wanted = index_in_str_array(really_wanted, fs->type) >= 0; - - /* See if the program is available. */ - s = find_fsck(fs->type); - if (s == NULL) { - if (wanted) - bb_error_msg("can't check %s: fsck.%s not found", - fs->device, fs->type); - return 1; - } - free(s); - - /* We can and want to check this file system type. */ - return 0; -} - -/* - * Returns TRUE if a partition on the same disk is already being - * checked. - */ -static int device_already_active(char *device) -{ - struct fsck_instance *inst; - char *base; - - if (force_all_parallel) - return 0; - -#ifdef BASE_MD - /* Don't check a soft raid disk with any other disk */ - if (instance_list && - (!strncmp(instance_list->device, BASE_MD, sizeof(BASE_MD)-1) || - !strncmp(device, BASE_MD, sizeof(BASE_MD)-1))) - return 1; -#endif - - base = base_device(device); - /* - * If we don't know the base device, assume that the device is - * already active if there are any fsck instances running. - */ - if (!base) - return (instance_list != 0); - for (inst = instance_list; inst; inst = inst->next) { - if (!inst->base_device || !strcmp(base, inst->base_device)) { - free(base); - return 1; - } - } - free(base); - return 0; -} - -/* Check all file systems, using the /etc/fstab table. */ -static int check_all(void) -{ - struct fs_info *fs = NULL; - int status = EXIT_OK; - int not_done_yet = 1; - int passno = 1; - int pass_done; - - if (verbose) - fputs("Checking all file systems.\n", stdout); - - /* - * Do an initial scan over the filesystem; mark filesystems - * which should be ignored as done, and resolve any "auto" - * filesystem types (done as a side-effect of calling ignore()). - */ - for (fs = filesys_info; fs; fs = fs->next) { - if (ignore(fs)) - fs->flags |= FLAG_DONE; - } - - /* - * Find and check the root filesystem. - */ - if (!parallel_root) { - for (fs = filesys_info; fs; fs = fs->next) { - if (LONE_CHAR(fs->mountpt, '/')) - break; - } - if (fs) { - if (!skip_root && !ignore(fs)) { - fsck_device(fs, 1); - status |= wait_many(FLAG_WAIT_ALL); - if (status > EXIT_NONDESTRUCT) - return status; - } - fs->flags |= FLAG_DONE; - } - } - /* - * This is for the bone-headed user who enters the root - * filesystem twice. Skip root will skep all root entries. - */ - if (skip_root) - for (fs = filesys_info; fs; fs = fs->next) - if (LONE_CHAR(fs->mountpt, '/')) - fs->flags |= FLAG_DONE; - - while (not_done_yet) { - not_done_yet = 0; - pass_done = 1; - - for (fs = filesys_info; fs; fs = fs->next) { - if (cancel_requested) - break; - if (fs->flags & FLAG_DONE) - continue; - /* - * If the filesystem's pass number is higher - * than the current pass number, then we don't - * do it yet. - */ - if (fs->passno > passno) { - not_done_yet++; - continue; - } - /* - * If a filesystem on a particular device has - * already been spawned, then we need to defer - * this to another pass. - */ - if (device_already_active(fs->device)) { - pass_done = 0; - continue; - } - /* - * Spawn off the fsck process - */ - fsck_device(fs, serialize); - fs->flags |= FLAG_DONE; - - /* - * Only do one filesystem at a time, or if we - * have a limit on the number of fsck's extant - * at one time, apply that limit. - */ - if (serialize || - (max_running && (num_running >= max_running))) { - pass_done = 0; - break; - } - } - if (cancel_requested) - break; - if (verbose > 1) - printf("--waiting-- (pass %d)\n", passno); - status |= wait_many(pass_done ? FLAG_WAIT_ALL : - FLAG_WAIT_ATLEAST_ONE); - if (pass_done) { - if (verbose > 1) - printf("----------------------------------\n"); - passno++; - } else - not_done_yet++; - } - if (cancel_requested && !kill_sent) { - kill_all(SIGTERM); - kill_sent++; - } - status |= wait_many(FLAG_WAIT_ATLEAST_ONE); - return status; -} - -static void signal_cancel(int sig FSCK_ATTR((unused))) -{ - cancel_requested++; -} - -static void PRS(int argc, char **argv) -{ - int i, j; - char *arg, *dev, *tmp = NULL; - char options[128]; - int opt = 0; - int opts_for_fsck = 0; - struct sigaction sa; - - /* - * Set up signal action - */ - memset(&sa, 0, sizeof(struct sigaction)); - sa.sa_handler = signal_cancel; - sigaction(SIGINT, &sa, 0); - sigaction(SIGTERM, &sa, 0); - - num_devices = 0; - num_args = 0; - instance_list = 0; - - for (i=1; i < argc; i++) { - arg = argv[i]; - if (!arg) - continue; - if ((arg[0] == '/' && !opts_for_fsck) || strchr(arg, '=')) { - if (num_devices >= MAX_DEVICES) { - bb_error_msg_and_die("too many devices"); - } - dev = blkid_get_devname(cache, arg, NULL); - if (!dev && strchr(arg, '=')) { - /* - * Check to see if we failed because - * /proc/partitions isn't found. - */ - if (access("/proc/partitions", R_OK) < 0) { - bb_perror_msg_and_die("can't open /proc/partitions " - "(is /proc mounted?)"); - } - /* - * Check to see if this is because - * we're not running as root - */ - if (geteuid()) - bb_error_msg_and_die( - "must be root to scan for matching filesystems: %s\n", arg); - else - bb_error_msg_and_die( - "can't find matching filesystem: %s", arg); - } - devices[num_devices++] = dev ? dev : string_copy(arg); - continue; - } - if (arg[0] != '-' || opts_for_fsck) { - if (num_args >= MAX_ARGS) { - bb_error_msg_and_die("too many arguments"); - } - args[num_args++] = string_copy(arg); - continue; - } - for (j=1; arg[j]; j++) { - if (opts_for_fsck) { - options[++opt] = arg[j]; - continue; - } - switch (arg[j]) { - case 'A': - doall++; - break; - case 'C': - progress++; - if (arg[j+1]) { - progress_fd = string_to_int(arg+j+1); - if (progress_fd < 0) - progress_fd = 0; - else - goto next_arg; - } else if ((i+1) < argc - && argv[i+1][0] != '-') { - progress_fd = string_to_int(argv[i]); - if (progress_fd < 0) - progress_fd = 0; - else { - goto next_arg; - } - } - break; - case 'V': - verbose++; - break; - case 'N': - noexecute++; - break; - case 'R': - skip_root++; - break; - case 'T': - notitle++; - break; - case 'M': - like_mount++; - break; - case 'P': - parallel_root++; - break; - case 's': - serialize++; - break; - case 't': - tmp = 0; - if (fstype) - bb_show_usage(); - if (arg[j+1]) - tmp = arg+j+1; - else if ((i+1) < argc) - tmp = argv[++i]; - else - bb_show_usage(); - fstype = string_copy(tmp); - compile_fs_type(fstype, &fs_type_compiled); - goto next_arg; - case '-': - opts_for_fsck++; - break; - case '?': - bb_show_usage(); - break; - default: - options[++opt] = arg[j]; - break; - } - } - next_arg: - if (opt) { - options[0] = '-'; - options[++opt] = '\0'; - if (num_args >= MAX_ARGS) { - bb_error_msg("too many arguments"); - } - args[num_args++] = string_copy(options); - opt = 0; - } - } - if (getenv("FSCK_FORCE_ALL_PARALLEL")) - force_all_parallel++; - if ((tmp = getenv("FSCK_MAX_INST"))) - max_running = atoi(tmp); -} - -int fsck_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int fsck_main(int argc, char **argv) -{ - int i, status = 0; - int interactive = 0; - const char *fstab; - struct fs_info *fs; - - setvbuf(stdout, NULL, _IONBF, BUFSIZ); - setvbuf(stderr, NULL, _IONBF, BUFSIZ); - - blkid_get_cache(&cache, NULL); - PRS(argc, argv); - - if (!notitle) - printf("fsck %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); - - fstab = getenv("FSTAB_FILE"); - if (!fstab) - fstab = _PATH_MNTTAB; - load_fs_info(fstab); - - fsck_path = e2fs_set_sbin_path(); - - if ((num_devices == 1) || (serialize)) - interactive = 1; - - /* If -A was specified ("check all"), do that! */ - if (doall) - return check_all(); - - if (num_devices == 0) { - serialize++; - interactive++; - return check_all(); - } - for (i = 0; i < num_devices; i++) { - if (cancel_requested) { - if (!kill_sent) { - kill_all(SIGTERM); - kill_sent++; - } - break; - } - fs = lookup(devices[i]); - if (!fs) { - fs = create_fs_device(devices[i], 0, "auto", - 0, -1, -1); - if (!fs) - continue; - } - fsck_device(fs, interactive); - if (serialize || - (max_running && (num_running >= max_running))) { - struct fsck_instance *inst; - - inst = wait_one(0); - if (inst) { - status |= inst->exit_status; - free_instance(inst); - } - if (verbose > 1) - printf("----------------------------------\n"); - } - } - status |= wait_many(FLAG_WAIT_ALL); - blkid_put_cache(cache); - return status; -} diff --git a/e2fsprogs/old_e2fsprogs/fsck.h b/e2fsprogs/old_e2fsprogs/fsck.h deleted file mode 100644 index 2ca2af7..0000000 --- a/e2fsprogs/old_e2fsprogs/fsck.h +++ b/dev/null @@ -1,16 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * fsck.h - */ - -#define FSCK_ATTR(x) __attribute__(x) - -#define EXIT_OK 0 -#define EXIT_NONDESTRUCT 1 -#define EXIT_DESTRUCT 2 -#define EXIT_UNCORRECTED 4 -#define EXIT_ERROR 8 -#define EXIT_USAGE 16 -#define FSCK_CANCELED 32 /* Aborted with a signal or ^C */ - -extern char *e2fs_set_sbin_path(void); diff --git a/e2fsprogs/old_e2fsprogs/lsattr.c b/e2fsprogs/old_e2fsprogs/lsattr.c deleted file mode 100644 index 9eab68b..0000000 --- a/e2fsprogs/old_e2fsprogs/lsattr.c +++ b/dev/null @@ -1,129 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * lsattr.c - List file attributes on an ext2 file system - * - * Copyright (C) 1993, 1994 Remy Card - * 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ext2fs/ext2_fs.h" -#include "e2fsbb.h" -#include "e2p/e2p.h" - -#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; - -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_e2flags(stdout, fsflags, PFOPT_LONG); - bb_putchar('\n'); - } else { - print_e2flags(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) -{ - struct stat st; - char *path; - - path = concat_path_file(dir_name, de->d_name); - - if (lstat(path, &st) == -1) - bb_simple_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); - bb_putchar('\n'); - } - } - } - - free(path); - - return 0; -} - -int lsattr_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int lsattr_main(int argc, char **argv) -{ - int i; - - flags = getopt32(argv, "Radlv"); - - if (optind > argc - 1) - lsattr_args("."); - else - for (i = optind; i < argc; i++) - lsattr_args(argv[i]); - - return EXIT_SUCCESS; -} diff --git a/e2fsprogs/old_e2fsprogs/mke2fs.c b/e2fsprogs/old_e2fsprogs/mke2fs.c deleted file mode 100644 index ebcb46c..0000000 --- a/e2fsprogs/old_e2fsprogs/mke2fs.c +++ b/dev/null @@ -1,1333 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * mke2fs.c - Make a ext2fs filesystem. - * - * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, - * 2003, 2004, 2005 by Theodore Ts'o. - * - * Licensed under GPLv2, see file LICENSE in this source tree. - */ - -/* Usage: mke2fs [options] device - * - * The device may be a block device or a image of one, but this isn't - * enforced (but it's not much fun on a character device :-). - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "e2fsbb.h" -#include "ext2fs/ext2_fs.h" -#include "uuid/uuid.h" -#include "e2p/e2p.h" -#include "ext2fs/ext2fs.h" -#include "util.h" - -#define STRIDE_LENGTH 8 - -#ifndef __sparc__ -#define ZAP_BOOTBLOCK -#endif - -static const char * device_name; - -/* Command line options */ -static int cflag; -static int quiet; -static int super_only; -static int force; -static int noaction; -static int journal_size; -static int journal_flags; -static const char *bad_blocks_filename; -static __u32 fs_stride; - -static struct ext2_super_block param; -static char *creator_os; -static char *volume_label; -static char *mount_dir; -static char *journal_device = NULL; -static int sync_kludge; /* Set using the MKE2FS_SYNC env. option */ - -static int sys_page_size = 4096; -static int linux_version_code = 0; - -static int int_log2(int arg) -{ - int l = 0; - - arg >>= 1; - while (arg) { - l++; - arg >>= 1; - } - return l; -} - -static int int_log10(unsigned int arg) -{ - int l; - - for (l = 0; arg; l++) - arg = arg / 10; - return l; -} - -/* - * This function sets the default parameters for a filesystem - * - * The type is specified by the user. The size is the maximum size - * (in megabytes) for which a set of parameters applies, with a size - * of zero meaning that it is the default parameter for the type. - * Note that order is important in the table below. - */ -#define DEF_MAX_BLOCKSIZE -1 -static const char default_str[] = "default"; -struct mke2fs_defaults { - const char *type; - int size; - int blocksize; - int inode_ratio; -}; - -static const struct mke2fs_defaults settings[] = { - { default_str, 0, 4096, 8192 }, - { default_str, 512, 1024, 4096 }, - { default_str, 3, 1024, 8192 }, - { "journal", 0, 4096, 8192 }, - { "news", 0, 4096, 4096 }, - { "largefile", 0, 4096, 1024 * 1024 }, - { "largefile4", 0, 4096, 4096 * 1024 }, - { 0, 0, 0, 0}, -}; - -static void set_fs_defaults(const char *fs_type, - struct ext2_super_block *super, - int blocksize, int sector_size, - int *inode_ratio) -{ - int megs; - int ratio = 0; - const struct mke2fs_defaults *p; - int use_bsize = 1024; - - megs = super->s_blocks_count * (EXT2_BLOCK_SIZE(super) / 1024) / 1024; - if (inode_ratio) - ratio = *inode_ratio; - if (!fs_type) - fs_type = default_str; - for (p = settings; p->type; p++) { - if ((strcmp(p->type, fs_type) != 0) && - (strcmp(p->type, default_str) != 0)) - continue; - if ((p->size != 0) && (megs > p->size)) - continue; - if (ratio == 0) - *inode_ratio = p->inode_ratio < blocksize ? - blocksize : p->inode_ratio; - use_bsize = p->blocksize; - } - if (blocksize <= 0) { - if (use_bsize == DEF_MAX_BLOCKSIZE) { - use_bsize = sys_page_size; - if ((linux_version_code < (2*65536 + 6*256)) && - (use_bsize > 4096)) - use_bsize = 4096; - } - if (sector_size && use_bsize < sector_size) - use_bsize = sector_size; - if ((blocksize < 0) && (use_bsize < (-blocksize))) - use_bsize = -blocksize; - blocksize = use_bsize; - super->s_blocks_count /= blocksize / 1024; - } - super->s_log_frag_size = super->s_log_block_size = - int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); -} - - -/* - * Helper function for read_bb_file and test_disk - */ -static void invalid_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk_t blk) -{ - bb_error_msg("Bad block %u out of range; ignored", blk); -} - -/* - * Busybox stuff - */ -static void mke2fs_error_msg_and_die(int retval, const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); -static void mke2fs_error_msg_and_die(int retval, const char *fmt, ...) -{ - va_list ap; - - if (retval) { - va_start(ap, fmt); - fprintf(stderr, "\nCould not "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - exit(EXIT_FAILURE); - } -} - -static void mke2fs_verbose(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))); -static void mke2fs_verbose(const char *fmt, ...) -{ - va_list ap; - - if (!quiet) { - va_start(ap, fmt); - vfprintf(stdout, fmt, ap); - fflush(stdout); - va_end(ap); - } -} - -static void mke2fs_verbose_done(void) -{ - mke2fs_verbose("done\n"); -} - -static void mke2fs_warning_msg(int retval, char *fmt, ... ) __attribute__ ((format (printf, 2, 3))); -static void mke2fs_warning_msg(int retval, char *fmt, ... ) -{ - va_list ap; - - if (retval) { - va_start(ap, fmt); - fprintf(stderr, "\nWarning: "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); - } -} - -/* - * Reads the bad blocks list from a file - */ -static void read_bb_file(ext2_filsys fs, badblocks_list *bb_list, - const char *bad_blocks_file) -{ - FILE *f; - errcode_t retval; - - f = xfopen_for_read(bad_blocks_file); - retval = ext2fs_read_bb_FILE(fs, f, bb_list, invalid_block); - fclose (f); - mke2fs_error_msg_and_die(retval, "read bad blocks from list"); -} - -/* - * Runs the badblocks program to test the disk - */ -static void test_disk(ext2_filsys fs, badblocks_list *bb_list) -{ - FILE *f; - errcode_t retval; - char buf[1024]; - - sprintf(buf, "badblocks -b %u %s%s%s %d", fs->blocksize, - quiet ? "" : "-s ", (cflag > 1) ? "-w " : "", - fs->device_name, fs->super->s_blocks_count); - mke2fs_verbose("Running command: %s\n", buf); - f = popen(buf, "r"); - if (!f) { - bb_perror_msg_and_die("can't run '%s'", buf); - } - retval = ext2fs_read_bb_FILE(fs, f, bb_list, invalid_block); - pclose(f); - mke2fs_error_msg_and_die(retval, "read bad blocks from program"); -} - -static void handle_bad_blocks(ext2_filsys fs, badblocks_list bb_list) -{ - dgrp_t i; - blk_t j; - unsigned must_be_good; - blk_t blk; - badblocks_iterate bb_iter; - errcode_t retval; - blk_t group_block; - int group; - int group_bad; - - if (!bb_list) - return; - - /* - * The primary superblock and group descriptors *must* be - * good; if not, abort. - */ - must_be_good = fs->super->s_first_data_block + 1 + fs->desc_blocks; - for (i = fs->super->s_first_data_block; i <= must_be_good; i++) { - if (ext2fs_badblocks_list_test(bb_list, i)) { - bb_error_msg_and_die( - "Block %d in primary superblock/group descriptor area bad\n" - "Blocks %d through %d must be good in order to build a filesystem\n" - "Aborting ...", i, fs->super->s_first_data_block, must_be_good); - } - } - - /* - * See if any of the bad blocks are showing up in the backup - * superblocks and/or group descriptors. If so, issue a - * warning and adjust the block counts appropriately. - */ - group_block = fs->super->s_first_data_block + - fs->super->s_blocks_per_group; - - for (i = 1; i < fs->group_desc_count; i++) { - group_bad = 0; - for (j=0; j < fs->desc_blocks+1; j++) { - if (ext2fs_badblocks_list_test(bb_list, - group_block + j)) { - mke2fs_warning_msg(!group_bad, - "the backup superblock/group descriptors at block %d contain\n" - "bad blocks\n", group_block); - group_bad++; - group = ext2fs_group_of_blk(fs, group_block+j); - fs->group_desc[group].bg_free_blocks_count++; - fs->super->s_free_blocks_count++; - } - } - group_block += fs->super->s_blocks_per_group; - } - - /* - * Mark all the bad blocks as used... - */ - retval = ext2fs_badblocks_list_iterate_begin(bb_list, &bb_iter); - mke2fs_error_msg_and_die(retval, "mark bad blocks as used"); - - while (ext2fs_badblocks_list_iterate(bb_iter, &blk)) - ext2fs_mark_block_bitmap(fs->block_map, blk); - ext2fs_badblocks_list_iterate_end(bb_iter); -} - -/* - * These functions implement a generalized progress meter. - */ -struct progress_struct { - char format[20]; - char backup[80]; - __u32 max; - int skip_progress; -}; - -static void progress_init(struct progress_struct *progress, - const char *label,__u32 max) -{ - int i; - - memset(progress, 0, sizeof(struct progress_struct)); - if (quiet) - return; - - /* - * Figure out how many digits we need - */ - i = int_log10(max); - sprintf(progress->format, "%%%dd/%%%dld", i, i); - memset(progress->backup, '\b', sizeof(progress->backup)-1); - progress->backup[sizeof(progress->backup)-1] = 0; - if ((2*i)+1 < (int) sizeof(progress->backup)) - progress->backup[(2*i)+1] = 0; - progress->max = max; - - progress->skip_progress = 0; - if (getenv("MKE2FS_SKIP_PROGRESS")) - progress->skip_progress++; - - fputs(label, stdout); - fflush(stdout); -} - -static void progress_update(struct progress_struct *progress, __u32 val) -{ - if ((progress->format[0] == 0) || progress->skip_progress) - return; - printf(progress->format, val, progress->max); - fputs(progress->backup, stdout); -} - -static void progress_close(struct progress_struct *progress) -{ - if (progress->format[0] == 0) - return; - printf("%-28s\n", "done"); -} - - -/* - * Helper function which zeros out _num_ blocks starting at _blk_. In - * case of an error, the details of the error is returned via _ret_blk_ - * and _ret_count_ if they are non-NULL pointers. Returns 0 on - * success, and an error code on an error. - * - * As a special case, if the first argument is NULL, then it will - * attempt to free the static zeroizing buffer. (This is to keep - * programs that check for memory leaks happy.) - */ -static errcode_t zero_blocks(ext2_filsys fs, blk_t blk, int num, - struct progress_struct *progress, - blk_t *ret_blk, int *ret_count) -{ - int j, count, next_update; - static char *buf; - errcode_t retval; - - /* If fs is null, clean up the static buffer and return */ - if (!fs) { - if (buf) { - free(buf); - buf = 0; - } - return 0; - } - /* Allocate the zeroizing buffer if necessary */ - if (!buf) { - buf = xzalloc(fs->blocksize * STRIDE_LENGTH); - } - /* OK, do the write loop */ - next_update = 0; - - for (j=0; j < num; j += STRIDE_LENGTH, blk += STRIDE_LENGTH) { - count = num - j; - if (count > STRIDE_LENGTH) - count = STRIDE_LENGTH; - retval = io_channel_write_blk(fs->io, blk, count, buf); - if (retval) { - if (ret_count) - *ret_count = count; - if (ret_blk) - *ret_blk = blk; - return retval; - } - if (progress && j > next_update) { - next_update += num / 100; - progress_update(progress, blk); - } - } - return 0; -} - -static void write_inode_tables(ext2_filsys fs) -{ - errcode_t retval; - blk_t blk; - dgrp_t i; - int num; - struct progress_struct progress; - - if (quiet) - memset(&progress, 0, sizeof(progress)); - else - progress_init(&progress, "Writing inode tables: ", - fs->group_desc_count); - - for (i = 0; i < fs->group_desc_count; i++) { - progress_update(&progress, i); - - blk = fs->group_desc[i].bg_inode_table; - num = fs->inode_blocks_per_group; - - retval = zero_blocks(fs, blk, num, 0, &blk, &num); - mke2fs_error_msg_and_die(retval, - "write %d blocks in inode table starting at %d.", - num, blk); - if (sync_kludge) { - if (sync_kludge == 1) - sync(); - else if ((i % sync_kludge) == 0) - sync(); - } - } - zero_blocks(0, 0, 0, 0, 0, 0); - progress_close(&progress); -} - -static void create_root_dir(ext2_filsys fs) -{ - errcode_t retval; - struct ext2_inode inode; - - retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, EXT2_ROOT_INO, 0); - mke2fs_error_msg_and_die(retval, "create root dir"); - if (geteuid()) { - retval = ext2fs_read_inode(fs, EXT2_ROOT_INO, &inode); - mke2fs_error_msg_and_die(retval, "read root inode"); - inode.i_uid = getuid(); - if (inode.i_uid) - inode.i_gid = getgid(); - retval = ext2fs_write_new_inode(fs, EXT2_ROOT_INO, &inode); - mke2fs_error_msg_and_die(retval, "set root inode ownership"); - } -} - -static void create_lost_and_found(ext2_filsys fs) -{ - errcode_t retval; - ext2_ino_t ino; - const char *name = "lost+found"; - int i = 1; - char *msg = "create"; - int lpf_size = 0; - - fs->umask = 077; - retval = ext2fs_mkdir(fs, EXT2_ROOT_INO, 0, name); - if (retval) { - goto CREATE_LOST_AND_FOUND_ERROR; - } - - retval = ext2fs_lookup(fs, EXT2_ROOT_INO, name, strlen(name), 0, &ino); - if (retval) { - msg = "lookup"; - goto CREATE_LOST_AND_FOUND_ERROR; - } - - for (; i < EXT2_NDIR_BLOCKS; i++) { - if ((lpf_size += fs->blocksize) >= 16*1024) - break; - retval = ext2fs_expand_dir(fs, ino); - msg = "expand"; -CREATE_LOST_AND_FOUND_ERROR: - mke2fs_error_msg_and_die(retval, "%s %s", msg, name); - } -} - -static void create_bad_block_inode(ext2_filsys fs, badblocks_list bb_list) -{ - errcode_t retval; - - ext2fs_mark_inode_bitmap(fs->inode_map, EXT2_BAD_INO); - fs->group_desc[0].bg_free_inodes_count--; - fs->super->s_free_inodes_count--; - retval = ext2fs_update_bb_inode(fs, bb_list); - mke2fs_error_msg_and_die(retval, "set bad block inode"); -} - -static void reserve_inodes(ext2_filsys fs) -{ - ext2_ino_t i; - int group; - - for (i = EXT2_ROOT_INO + 1; i < EXT2_FIRST_INODE(fs->super); i++) { - ext2fs_mark_inode_bitmap(fs->inode_map, i); - group = ext2fs_group_of_ino(fs, i); - fs->group_desc[group].bg_free_inodes_count--; - fs->super->s_free_inodes_count--; - } - ext2fs_mark_ib_dirty(fs); -} - -#define BSD_DISKMAGIC (0x82564557UL) /* The disk magic number */ -#define BSD_MAGICDISK (0x57455682UL) /* The disk magic number reversed */ -#define BSD_LABEL_OFFSET 64 - -static void zap_sector(ext2_filsys fs, int sect, int nsect) -{ - char *buf; - char *fmt = "could not %s %d"; - int retval; - unsigned int *magic; - - buf = xmalloc(512*nsect); - - if (sect == 0) { - /* Check for a BSD disklabel, and don't erase it if so */ - retval = io_channel_read_blk(fs->io, 0, -512, buf); - if (retval) - mke2fs_warning_msg(retval, fmt, "read block", 0); - else { - magic = (unsigned int *) (buf + BSD_LABEL_OFFSET); - if ((*magic == BSD_DISKMAGIC) || - (*magic == BSD_MAGICDISK)) - return; - } - } - - memset(buf, 0, 512*nsect); - io_channel_set_blksize(fs->io, 512); - retval = io_channel_write_blk(fs->io, sect, -512*nsect, buf); - io_channel_set_blksize(fs->io, fs->blocksize); - free(buf); - mke2fs_warning_msg(retval, fmt, "erase sector", sect); -} - -static void create_journal_dev(ext2_filsys fs) -{ - struct progress_struct progress; - errcode_t retval; - char *buf; - char *fmt = "%s journal superblock"; - blk_t blk; - int count; - - retval = ext2fs_create_journal_superblock(fs, - fs->super->s_blocks_count, 0, &buf); - mke2fs_error_msg_and_die(retval, fmt, "init"); - if (quiet) - memset(&progress, 0, sizeof(progress)); - else - progress_init(&progress, "Zeroing journal device: ", - fs->super->s_blocks_count); - - retval = zero_blocks(fs, 0, fs->super->s_blocks_count, - &progress, &blk, &count); - mke2fs_error_msg_and_die(retval, "zero journal device (block %u, count %d)", - blk, count); - zero_blocks(0, 0, 0, 0, 0, 0); - - retval = io_channel_write_blk(fs->io, - fs->super->s_first_data_block+1, - 1, buf); - mke2fs_error_msg_and_die(retval, fmt, "write"); - progress_close(&progress); -} - -static void show_stats(ext2_filsys fs) -{ - struct ext2_super_block *s = fs->super; - char *os; - blk_t group_block; - dgrp_t i; - int need, col_left; - - mke2fs_warning_msg((param.s_blocks_count != s->s_blocks_count), - "%d blocks unused\n", param.s_blocks_count - s->s_blocks_count); - os = e2p_os2string(fs->super->s_creator_os); - printf( "Filesystem label=%.*s\n" - "OS type: %s\n" - "Block size=%u (log=%u)\n" - "Fragment size=%u (log=%u)\n" - "%u inodes, %u blocks\n" - "%u blocks (%2.2f%%) reserved for the super user\n" - "First data block=%u\n", - (int) sizeof(s->s_volume_name), - s->s_volume_name, - os, - fs->blocksize, s->s_log_block_size, - fs->fragsize, s->s_log_frag_size, - s->s_inodes_count, s->s_blocks_count, - s->s_r_blocks_count, 100.0 * s->s_r_blocks_count / s->s_blocks_count, - s->s_first_data_block); - free(os); - if (s->s_reserved_gdt_blocks) { - printf("Maximum filesystem blocks=%lu\n", - (s->s_reserved_gdt_blocks + fs->desc_blocks) * - (fs->blocksize / sizeof(struct ext2_group_desc)) * - s->s_blocks_per_group); - } - printf( "%u block group%s\n" - "%u blocks per group, %u fragments per group\n" - "%u inodes per group\n", - fs->group_desc_count, (fs->group_desc_count > 1) ? "s" : "", - s->s_blocks_per_group, s->s_frags_per_group, - s->s_inodes_per_group); - if (fs->group_desc_count == 1) { - bb_putchar('\n'); - return; - } - - printf("Superblock backups stored on blocks: "); - group_block = s->s_first_data_block; - col_left = 0; - for (i = 1; i < fs->group_desc_count; i++) { - group_block += s->s_blocks_per_group; - if (!ext2fs_bg_has_super(fs, i)) - continue; - if (i != 1) - printf(", "); - need = int_log10(group_block) + 2; - if (need > col_left) { - printf("\n\t"); - col_left = 72; - } - col_left -= need; - printf("%u", group_block); - } - puts("\n"); -} - -/* - * Set the S_CREATOR_OS field. Return true if OS is known, - * otherwise, 0. - */ -static int set_os(struct ext2_super_block *sb, char *os) -{ - if (isdigit (*os)) { - sb->s_creator_os = atoi(os); - return 1; - } - - if ((sb->s_creator_os = e2p_string2os(os)) >= 0) { - return 1; - } else if (!strcasecmp("GNU", os)) { - sb->s_creator_os = EXT2_OS_HURD; - return 1; - } - return 0; -} - -static void parse_extended_opts(struct ext2_super_block *sb_param, - const char *opts) -{ - char *buf, *token, *next, *p, *arg; - int r_usage = 0; - - buf = xstrdup(opts); - 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, "stride") == 0) { - if (!arg) { - r_usage++; - continue; - } - fs_stride = strtoul(arg, &p, 0); - if (*p || (fs_stride == 0)) { - bb_error_msg("Invalid stride parameter: %s", arg); - r_usage++; - continue; - } - } else if (!strcmp(token, "resize")) { - unsigned long resize, bpg, rsv_groups; - unsigned long group_desc_count, desc_blocks; - unsigned int gdpb, blocksize; - int rsv_gdb; - - if (!arg) { - r_usage++; - continue; - } - - resize = parse_num_blocks(arg, - sb_param->s_log_block_size); - - if (resize == 0) { - bb_error_msg("Invalid resize parameter: %s", arg); - r_usage++; - continue; - } - if (resize <= sb_param->s_blocks_count) { - bb_error_msg("The resize maximum must be greater " - "than the filesystem size"); - r_usage++; - continue; - } - - blocksize = EXT2_BLOCK_SIZE(sb_param); - bpg = sb_param->s_blocks_per_group; - if (!bpg) - bpg = blocksize * 8; - gdpb = blocksize / sizeof(struct ext2_group_desc); - group_desc_count = (sb_param->s_blocks_count + - bpg - 1) / bpg; - desc_blocks = (group_desc_count + - gdpb - 1) / gdpb; - rsv_groups = (resize + bpg - 1) / bpg; - rsv_gdb = (rsv_groups + gdpb - 1) / gdpb - - desc_blocks; - if (rsv_gdb > EXT2_ADDR_PER_BLOCK(sb_param)) - rsv_gdb = EXT2_ADDR_PER_BLOCK(sb_param); - - if (rsv_gdb > 0) { - sb_param->s_feature_compat |= - EXT2_FEATURE_COMPAT_RESIZE_INO; - - sb_param->s_reserved_gdt_blocks = rsv_gdb; - } - } else - r_usage++; - } - if (r_usage) { - bb_error_msg_and_die( - "\nBad options specified.\n\n" - "Extended options are separated by commas, " - "and may take an argument which\n" - "\tis set off by an equals ('=') sign.\n\n" - "Valid extended options are:\n" - "\tstride=\n" - "\tresize=\n"); - } -} - -static __u32 ok_features[3] = { - EXT3_FEATURE_COMPAT_HAS_JOURNAL | - EXT2_FEATURE_COMPAT_RESIZE_INO | - EXT2_FEATURE_COMPAT_DIR_INDEX, /* Compat */ - EXT2_FEATURE_INCOMPAT_FILETYPE| /* Incompat */ - EXT3_FEATURE_INCOMPAT_JOURNAL_DEV| - EXT2_FEATURE_INCOMPAT_META_BG, - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER /* R/O compat */ -}; - -static int PRS(int argc, char **argv) -{ - int c; - int size; - char * tmp; - int blocksize = 0; - int inode_ratio = 0; - int inode_size = 0; - int reserved_ratio = 5; - int sector_size = 0; - int show_version_only = 0; - ext2_ino_t num_inodes = 0; - errcode_t retval; - char * extended_opts = NULL; - const char * fs_type = NULL; - blk_t dev_size; - long sysval; - - /* Update our PATH to include /sbin */ - e2fs_set_sbin_path(); - - tmp = getenv("MKE2FS_SYNC"); - if (tmp) - sync_kludge = atoi(tmp); - - /* Determine the system page size if possible */ -#if (!defined(_SC_PAGESIZE) && defined(_SC_PAGE_SIZE)) -#define _SC_PAGESIZE _SC_PAGE_SIZE -#endif -#ifdef _SC_PAGESIZE - sysval = sysconf(_SC_PAGESIZE); - if (sysval > 0) - sys_page_size = sysval; -#endif /* _SC_PAGESIZE */ - - setbuf(stdout, NULL); - setbuf(stderr, NULL); - memset(¶m, 0, sizeof(struct ext2_super_block)); - param.s_rev_level = 1; /* Create revision 1 filesystems now */ - param.s_feature_incompat |= EXT2_FEATURE_INCOMPAT_FILETYPE; - param.s_feature_ro_compat |= EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - -#ifdef __linux__ - linux_version_code = get_linux_version_code(); - if (linux_version_code && linux_version_code < KERNEL_VERSION(2,2,0)) { - param.s_rev_level = 0; - param.s_feature_incompat = 0; - param.s_feature_compat = 0; - param.s_feature_ro_compat = 0; - } -#endif - - /* If called as mkfs.ext3, create a journal inode */ - if (last_char_is(applet_name, '3')) - journal_size = -1; - - while ((c = getopt (argc, argv, - "b:cE:f:g:i:jl:m:no:qr:R:s:tvI:J:ST:FL:M:N:O:V")) != EOF) { - switch (c) { - case 'b': - blocksize = xatou_range(optarg, EXT2_MIN_BLOCK_SIZE, EXT2_MAX_BLOCK_SIZE); - mke2fs_warning_msg((blocksize > 4096), - "blocksize %d not usable on most systems", - blocksize); - param.s_log_block_size = - int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); - break; - case 'c': /* Check for bad blocks */ - case 't': /* deprecated */ - cflag++; - break; - case 'f': - size = xatou_range(optarg, EXT2_MIN_BLOCK_SIZE, EXT2_MAX_BLOCK_SIZE); - param.s_log_frag_size = - int_log2(size >> EXT2_MIN_BLOCK_LOG_SIZE); - mke2fs_warning_msg(1, "fragments not supported. Ignoring -f option"); - break; - case 'g': - param.s_blocks_per_group = xatou32(optarg); - if ((param.s_blocks_per_group % 8) != 0) { - bb_error_msg_and_die("blocks per group must be multiple of 8"); - } - break; - case 'i': - /* Huh? is "* 1024" correct? */ - inode_ratio = xatou_range(optarg, EXT2_MIN_BLOCK_SIZE, EXT2_MAX_BLOCK_SIZE * 1024); - break; - case 'J': - parse_journal_opts(&journal_device, &journal_flags, &journal_size, optarg); - break; - case 'j': - param.s_feature_compat |= - EXT3_FEATURE_COMPAT_HAS_JOURNAL; - if (!journal_size) - journal_size = -1; - break; - case 'l': - bad_blocks_filename = optarg; - break; - case 'm': - reserved_ratio = xatou_range(optarg, 0, 50); - break; - case 'n': - noaction++; - break; - case 'o': - creator_os = optarg; - break; - case 'r': - param.s_rev_level = xatoi_positive(optarg); - if (param.s_rev_level == EXT2_GOOD_OLD_REV) { - param.s_feature_incompat = 0; - param.s_feature_compat = 0; - param.s_feature_ro_compat = 0; - } - break; - case 's': /* deprecated */ - if (xatou(optarg)) - param.s_feature_ro_compat |= - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - else - param.s_feature_ro_compat &= - ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - break; -#ifdef EXT2_DYNAMIC_REV - case 'I': - inode_size = xatoi_positive(optarg); - break; -#endif - case 'N': - num_inodes = xatoi_positive(optarg); - break; - case 'v': - quiet = 0; - break; - case 'q': - quiet = 1; - break; - case 'F': - force = 1; - break; - case 'L': - volume_label = optarg; - break; - case 'M': - mount_dir = optarg; - break; - case 'O': - if (!strcmp(optarg, "none")) { - param.s_feature_compat = 0; - param.s_feature_incompat = 0; - param.s_feature_ro_compat = 0; - break; - } - if (e2p_edit_feature(optarg, - ¶m.s_feature_compat, - ok_features)) { - bb_error_msg_and_die("Invalid filesystem option set: %s", optarg); - } - break; - case 'E': - case 'R': - extended_opts = optarg; - break; - case 'S': - super_only = 1; - break; - case 'T': - fs_type = optarg; - break; - case 'V': - /* Print version number and exit */ - show_version_only = 1; - quiet = 0; - break; - default: - bb_show_usage(); - } - } - if ((optind == argc) /*&& !show_version_only*/) - bb_show_usage(); - device_name = argv[optind++]; - - mke2fs_verbose("mke2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); - - if (show_version_only) { - return 0; - } - - /* - * If there's no blocksize specified and there is a journal - * device, use it to figure out the blocksize - */ - if (blocksize <= 0 && journal_device) { - ext2_filsys jfs; - io_manager io_ptr; - -#ifdef CONFIG_TESTIO_DEBUG - io_ptr = test_io_manager; - test_io_backing_manager = unix_io_manager; -#else - io_ptr = unix_io_manager; -#endif - retval = ext2fs_open(journal_device, - EXT2_FLAG_JOURNAL_DEV_OK, 0, - 0, io_ptr, &jfs); - mke2fs_error_msg_and_die(retval, "open journal device %s", journal_device); - if ((blocksize < 0) && (jfs->blocksize < (unsigned) (-blocksize))) { - bb_error_msg_and_die( - "Journal dev blocksize (%d) smaller than " - "minimum blocksize %d\n", jfs->blocksize, - -blocksize); - } - blocksize = jfs->blocksize; - param.s_log_block_size = - int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE); - ext2fs_close(jfs); - } - - if (blocksize > sys_page_size) { - mke2fs_warning_msg(1, "%d-byte blocks too big for system (max %d)", - blocksize, sys_page_size); - if (!force) { - proceed_question(); - } - bb_error_msg("Forced to continue"); - } - mke2fs_warning_msg(((blocksize > 4096) && - (param.s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL)), - "some 2.4 kernels do not support " - "blocksizes greater than 4096 using ext3.\n" - "Use -b 4096 if this is an issue for you\n"); - - if (optind < argc) { - param.s_blocks_count = parse_num_blocks(argv[optind++], - param.s_log_block_size); - mke2fs_error_msg_and_die(!param.s_blocks_count, "invalid blocks count - %s", argv[optind - 1]); - } - if (optind < argc) - bb_show_usage(); - - if (param.s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) { - if (!fs_type) - fs_type = "journal"; - reserved_ratio = 0; - param.s_feature_incompat = EXT3_FEATURE_INCOMPAT_JOURNAL_DEV; - param.s_feature_compat = 0; - param.s_feature_ro_compat = 0; - } - if (param.s_rev_level == EXT2_GOOD_OLD_REV && - (param.s_feature_compat || param.s_feature_ro_compat || - param.s_feature_incompat)) - param.s_rev_level = 1; /* Create a revision 1 filesystem */ - - check_plausibility(device_name , force); - check_mount(device_name, force, "filesystem"); - - param.s_log_frag_size = param.s_log_block_size; - - if (noaction && param.s_blocks_count) { - dev_size = param.s_blocks_count; - retval = 0; - } else { - retry: - retval = ext2fs_get_device_size(device_name, - EXT2_BLOCK_SIZE(¶m), - &dev_size); - if ((retval == EFBIG) && - (blocksize == 0) && - (param.s_log_block_size == 0)) { - param.s_log_block_size = 2; - blocksize = 4096; - goto retry; - } - } - - mke2fs_error_msg_and_die((retval && (retval != EXT2_ET_UNIMPLEMENTED)),"determine filesystem size"); - - if (!param.s_blocks_count) { - if (retval == EXT2_ET_UNIMPLEMENTED) { - mke2fs_error_msg_and_die(1, - "determine device size; you " - "must specify\nthe size of the " - "filesystem"); - } else { - if (dev_size == 0) { - bb_error_msg_and_die( - "Device size reported to be zero. " - "Invalid partition specified, or\n\t" - "partition table wasn't reread " - "after running fdisk, due to\n\t" - "a modified partition being busy " - "and in use. You may need to reboot\n\t" - "to re-read your partition table.\n" - ); - } - param.s_blocks_count = dev_size; - if (sys_page_size > EXT2_BLOCK_SIZE(¶m)) - param.s_blocks_count &= ~((sys_page_size / - EXT2_BLOCK_SIZE(¶m))-1); - } - - } else if (!force && (param.s_blocks_count > dev_size)) { - bb_error_msg("Filesystem larger than apparent device size"); - proceed_question(); - } - - /* - * If the user asked for HAS_JOURNAL, then make sure a journal - * gets created. - */ - if ((param.s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) && - !journal_size) - journal_size = -1; - - /* Set first meta blockgroup via an environment variable */ - /* (this is mostly for debugging purposes) */ - if ((param.s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) && - ((tmp = getenv("MKE2FS_FIRST_META_BG")))) - param.s_first_meta_bg = atoi(tmp); - - /* Get the hardware sector size, if available */ - retval = ext2fs_get_device_sectsize(device_name, §or_size); - mke2fs_error_msg_and_die(retval, "determine hardware sector size"); - - if ((tmp = getenv("MKE2FS_DEVICE_SECTSIZE")) != NULL) - sector_size = atoi(tmp); - - set_fs_defaults(fs_type, ¶m, blocksize, sector_size, &inode_ratio); - blocksize = EXT2_BLOCK_SIZE(¶m); - - if (extended_opts) - parse_extended_opts(¶m, extended_opts); - - /* Since sparse_super is the default, we would only have a problem - * here if it was explicitly disabled. - */ - if ((param.s_feature_compat & EXT2_FEATURE_COMPAT_RESIZE_INO) && - !(param.s_feature_ro_compat&EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) { - bb_error_msg_and_die("reserved online resize blocks not supported " - "on non-sparse filesystem"); - } - - if (param.s_blocks_per_group) { - if (param.s_blocks_per_group < 256 || - param.s_blocks_per_group > 8 * (unsigned) blocksize) { - bb_error_msg_and_die("blocks per group count out of range"); - } - } - - if (!force && param.s_blocks_count >= (1 << 31)) { - bb_error_msg_and_die("Filesystem too large. No more than 2**31-1 blocks\n" - "\t (8TB using a blocksize of 4k) are currently supported."); - } - - if (inode_size) { - if (inode_size < EXT2_GOOD_OLD_INODE_SIZE || - inode_size > EXT2_BLOCK_SIZE(¶m) || - inode_size & (inode_size - 1)) { - bb_error_msg_and_die("invalid inode size %d (min %d/max %d)", - inode_size, EXT2_GOOD_OLD_INODE_SIZE, - blocksize); - } - mke2fs_warning_msg((inode_size != EXT2_GOOD_OLD_INODE_SIZE), - "%d-byte inodes not usable on most systems", - inode_size); - param.s_inode_size = inode_size; - } - - /* - * Calculate number of inodes based on the inode ratio - */ - param.s_inodes_count = num_inodes ? num_inodes : - ((__u64) param.s_blocks_count * blocksize) - / inode_ratio; - - /* - * Calculate number of blocks to reserve - */ - param.s_r_blocks_count = (param.s_blocks_count * reserved_ratio) / 100; - return 1; -} - -static void mke2fs_clean_up(void) -{ - if (ENABLE_FEATURE_CLEAN_UP && journal_device) free(journal_device); -} - -int mke2fs_main (int argc, char **argv); -int mke2fs_main (int argc, char **argv) -{ - errcode_t retval; - ext2_filsys fs; - badblocks_list bb_list = 0; - unsigned int i; - int val; - io_manager io_ptr; - - if (ENABLE_FEATURE_CLEAN_UP) - atexit(mke2fs_clean_up); - if (!PRS(argc, argv)) - return 0; - -#ifdef CONFIG_TESTIO_DEBUG - io_ptr = test_io_manager; - test_io_backing_manager = unix_io_manager; -#else - io_ptr = unix_io_manager; -#endif - - /* - * Initialize the superblock.... - */ - retval = ext2fs_initialize(device_name, 0, ¶m, - io_ptr, &fs); - mke2fs_error_msg_and_die(retval, "set up superblock"); - - /* - * Wipe out the old on-disk superblock - */ - if (!noaction) - zap_sector(fs, 2, 6); - - /* - * Generate a UUID for it... - */ - uuid_generate(fs->super->s_uuid); - - /* - * Initialize the directory index variables - */ - fs->super->s_def_hash_version = EXT2_HASH_TEA; - uuid_generate((unsigned char *) fs->super->s_hash_seed); - - /* - * Add "jitter" to the superblock's check interval so that we - * don't check all the filesystems at the same time. We use a - * kludgy hack of using the UUID to derive a random jitter value. - */ - for (i = 0, val = 0; i < sizeof(fs->super->s_uuid); i++) - val += fs->super->s_uuid[i]; - fs->super->s_max_mnt_count += val % EXT2_DFL_MAX_MNT_COUNT; - - /* - * Override the creator OS, if applicable - */ - if (creator_os && !set_os(fs->super, creator_os)) { - bb_error_msg_and_die("unknown os - %s", creator_os); - } - - /* - * For the Hurd, we will turn off filetype since it doesn't - * support it. - */ - if (fs->super->s_creator_os == EXT2_OS_HURD) - fs->super->s_feature_incompat &= - ~EXT2_FEATURE_INCOMPAT_FILETYPE; - - /* - * Set the volume label... - */ - if (volume_label) { - snprintf(fs->super->s_volume_name, sizeof(fs->super->s_volume_name), "%s", volume_label); - } - - /* - * Set the last mount directory - */ - if (mount_dir) { - snprintf(fs->super->s_last_mounted, sizeof(fs->super->s_last_mounted), "%s", mount_dir); - } - - if (!quiet || noaction) - show_stats(fs); - - if (noaction) - return 0; - - if (fs->super->s_feature_incompat & - EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) { - create_journal_dev(fs); - return (ext2fs_close(fs) ? 1 : 0); - } - - if (bad_blocks_filename) - read_bb_file(fs, &bb_list, bad_blocks_filename); - if (cflag) - test_disk(fs, &bb_list); - - handle_bad_blocks(fs, bb_list); - fs->stride = fs_stride; - retval = ext2fs_allocate_tables(fs); - mke2fs_error_msg_and_die(retval, "allocate filesystem tables"); - if (super_only) { - fs->super->s_state |= EXT2_ERROR_FS; - fs->flags &= ~(EXT2_FLAG_IB_DIRTY|EXT2_FLAG_BB_DIRTY); - } else { - /* rsv must be a power of two (64kB is MD RAID sb alignment) */ - unsigned int rsv = 65536 / fs->blocksize; - unsigned long blocks = fs->super->s_blocks_count; - unsigned long start; - blk_t ret_blk; - -#ifdef ZAP_BOOTBLOCK - zap_sector(fs, 0, 2); -#endif - - /* - * Wipe out any old MD RAID (or other) metadata at the end - * of the device. This will also verify that the device is - * as large as we think. Be careful with very small devices. - */ - start = (blocks & ~(rsv - 1)); - if (start > rsv) - start -= rsv; - if (start > 0) - retval = zero_blocks(fs, start, blocks - start, - NULL, &ret_blk, NULL); - - mke2fs_warning_msg(retval, "can't zero block %u at end of filesystem", ret_blk); - write_inode_tables(fs); - create_root_dir(fs); - create_lost_and_found(fs); - reserve_inodes(fs); - create_bad_block_inode(fs, bb_list); - if (fs->super->s_feature_compat & - EXT2_FEATURE_COMPAT_RESIZE_INO) { - retval = ext2fs_create_resize_inode(fs); - mke2fs_error_msg_and_die(retval, "reserve blocks for online resize"); - } - } - - if (journal_device) { - make_journal_device(journal_device, fs, quiet, force); - } else if (journal_size) { - make_journal_blocks(fs, journal_size, journal_flags, quiet); - } - - mke2fs_verbose("Writing superblocks and filesystem accounting information: "); - retval = ext2fs_flush(fs); - mke2fs_warning_msg(retval, "had trouble writing out superblocks"); - mke2fs_verbose_done(); - if (!quiet && !getenv("MKE2FS_SKIP_CHECK_MSG")) - print_check_message(fs); - val = ext2fs_close(fs); - return (retval || val) ? 1 : 0; -} diff --git a/e2fsprogs/old_e2fsprogs/tune2fs.c b/e2fsprogs/old_e2fsprogs/tune2fs.c deleted file mode 100644 index bbe30e5..0000000 --- a/e2fsprogs/old_e2fsprogs/tune2fs.c +++ b/dev/null @@ -1,710 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * tune2fs.c - Change the file system parameters on an ext2 file system - * - * Copyright (C) 1992, 1993, 1994 Remy Card - * Laboratoire MASI, Institut Blaise Pascal - * Universite Pierre et Marie Curie (Paris VI) - * - * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o. - * - * Licensed under GPLv2, see file LICENSE in this source tree. - */ - -/* - * History: - * 93/06/01 - Creation - * 93/10/31 - Added the -c option to change the maximal mount counts - * 93/12/14 - Added -l flag to list contents of superblock - * M.J.E. Mol (marcel@duteca.et.tudelft.nl) - * F.W. ten Wolde (franky@duteca.et.tudelft.nl) - * 93/12/29 - Added the -e option to change errors behavior - * 94/02/27 - Ported to use the ext2fs library - * 94/03/06 - Added the checks interval from Uwe Ohse (uwe@tirka.gun.de) - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "e2fsbb.h" -#include "ext2fs/ext2_fs.h" -#include "ext2fs/ext2fs.h" -#include "uuid/uuid.h" -#include "e2p/e2p.h" -#include "ext2fs/kernel-jbd.h" -#include "util.h" -#include "blkid/blkid.h" - -#include "libbb.h" - -static char * device_name = NULL; -static char * new_label, *new_last_mounted, *new_UUID; -static char * io_options; -static int c_flag, C_flag, e_flag, f_flag, g_flag, i_flag, l_flag, L_flag; -static int m_flag, M_flag, r_flag, s_flag = -1, u_flag, U_flag, T_flag; -static time_t last_check_time; -static int print_label; -static int max_mount_count, mount_count, mount_flags; -static unsigned long interval, reserved_blocks; -static unsigned reserved_ratio; -static unsigned long resgid, resuid; -static unsigned short errors; -static int open_flag; -static char *features_cmd; -static char *mntopts_cmd; - -static int journal_size, journal_flags; -static char *journal_device = NULL; - -static const char *please_fsck = "Please run e2fsck on the filesystem\n"; - -static __u32 ok_features[3] = { - EXT3_FEATURE_COMPAT_HAS_JOURNAL | EXT2_FEATURE_COMPAT_DIR_INDEX, - EXT2_FEATURE_INCOMPAT_FILETYPE, - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER -}; - -/* - * Remove an external journal from the filesystem - */ -static void remove_journal_device(ext2_filsys fs) -{ - char *journal_path; - ext2_filsys jfs; - char buf[1024]; - journal_superblock_t *jsb; - int i, nr_users; - errcode_t retval; - int commit_remove_journal = 0; - io_manager io_ptr; - - if (f_flag) - commit_remove_journal = 1; /* force removal even if error */ - - uuid_unparse(fs->super->s_journal_uuid, buf); - journal_path = blkid_get_devname(NULL, "UUID", buf); - - if (!journal_path) { - journal_path = - ext2fs_find_block_device(fs->super->s_journal_dev); - if (!journal_path) - return; - } - - io_ptr = unix_io_manager; - retval = ext2fs_open(journal_path, EXT2_FLAG_RW| - EXT2_FLAG_JOURNAL_DEV_OK, 0, - fs->blocksize, io_ptr, &jfs); - if (retval) { - bb_error_msg("Failed to open external journal"); - goto no_valid_journal; - } - if (!(jfs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_JOURNAL_DEV)) { - bb_error_msg("%s is not a journal device", journal_path); - goto no_valid_journal; - } - - /* Get the journal superblock */ - if ((retval = io_channel_read_blk(jfs->io, 1, -1024, buf))) { - bb_error_msg("Failed to read journal superblock"); - goto no_valid_journal; - } - - 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))) { - bb_error_msg("Journal superblock not found!"); - goto no_valid_journal; - } - - /* Find the filesystem UUID */ - 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) { - bb_error_msg("Filesystem's UUID not found on journal device"); - commit_remove_journal = 1; - goto no_valid_journal; - } - nr_users--; - for (i=0; i < nr_users; i++) - memcpy(&jsb->s_users[i*16], &jsb->s_users[(i+1)*16], 16); - jsb->s_nr_users = htonl(nr_users); - - /* Write back the journal superblock */ - if ((retval = io_channel_write_blk(jfs->io, 1, -1024, buf))) { - bb_error_msg("Failed to write journal superblock"); - goto no_valid_journal; - } - - commit_remove_journal = 1; - -no_valid_journal: - if (commit_remove_journal == 0) - bb_error_msg_and_die("Journal NOT removed"); - fs->super->s_journal_dev = 0; - uuid_clear(fs->super->s_journal_uuid); - ext2fs_mark_super_dirty(fs); - puts("Journal removed"); - free(journal_path); -} - -/* Helper function for remove_journal_inode */ -static int release_blocks_proc(ext2_filsys fs, blk_t *blocknr, - int blockcnt EXT2FS_ATTR((unused)), - void *private EXT2FS_ATTR((unused))) -{ - blk_t block; - int group; - - block = *blocknr; - ext2fs_unmark_block_bitmap(fs->block_map,block); - group = ext2fs_group_of_blk(fs, block); - fs->group_desc[group].bg_free_blocks_count++; - fs->super->s_free_blocks_count++; - return 0; -} - -/* - * Remove the journal inode from the filesystem - */ -static void remove_journal_inode(ext2_filsys fs) -{ - struct ext2_inode inode; - errcode_t retval; - ino_t ino = fs->super->s_journal_inum; - char *msg = "to read"; - char *s = "journal inode"; - - retval = ext2fs_read_inode(fs, ino, &inode); - if (retval) - goto REMOVE_JOURNAL_INODE_ERROR; - if (ino == EXT2_JOURNAL_INO) { - retval = ext2fs_read_bitmaps(fs); - if (retval) { - msg = "to read bitmaps"; - s = ""; - goto REMOVE_JOURNAL_INODE_ERROR; - } - retval = ext2fs_block_iterate(fs, ino, 0, NULL, - release_blocks_proc, NULL); - if (retval) { - msg = "clearing"; - goto REMOVE_JOURNAL_INODE_ERROR; - } - memset(&inode, 0, sizeof(inode)); - ext2fs_mark_bb_dirty(fs); - fs->flags &= ~EXT2_FLAG_SUPER_ONLY; - } else - inode.i_flags &= ~EXT2_IMMUTABLE_FL; - retval = ext2fs_write_inode(fs, ino, &inode); - if (retval) { - msg = "writing"; -REMOVE_JOURNAL_INODE_ERROR: - bb_error_msg_and_die("Failed %s %s", msg, s); - } - fs->super->s_journal_inum = 0; - ext2fs_mark_super_dirty(fs); -} - -/* - * Update the default mount options - */ -static void update_mntopts(ext2_filsys fs, char *mntopts) -{ - struct ext2_super_block *sb= fs->super; - - if (e2p_edit_mntopts(mntopts, &sb->s_default_mount_opts, ~0)) - bb_error_msg_and_die("Invalid mount option set: %s", mntopts); - ext2fs_mark_super_dirty(fs); -} - -/* - * Update the feature set as provided by the user. - */ -static void update_feature_set(ext2_filsys fs, char *features) -{ - int sparse, old_sparse, filetype, old_filetype; - int journal, old_journal, dxdir, old_dxdir; - struct ext2_super_block *sb= fs->super; - __u32 old_compat, old_incompat, old_ro_compat; - - old_compat = sb->s_feature_compat; - old_ro_compat = sb->s_feature_ro_compat; - old_incompat = sb->s_feature_incompat; - - old_sparse = sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - old_filetype = sb->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_FILETYPE; - old_journal = sb->s_feature_compat & - EXT3_FEATURE_COMPAT_HAS_JOURNAL; - old_dxdir = sb->s_feature_compat & - EXT2_FEATURE_COMPAT_DIR_INDEX; - if (e2p_edit_feature(features, &sb->s_feature_compat, ok_features)) - bb_error_msg_and_die("Invalid filesystem option set: %s", features); - sparse = sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - filetype = sb->s_feature_incompat & - EXT2_FEATURE_INCOMPAT_FILETYPE; - journal = sb->s_feature_compat & - EXT3_FEATURE_COMPAT_HAS_JOURNAL; - dxdir = sb->s_feature_compat & - EXT2_FEATURE_COMPAT_DIR_INDEX; - if (old_journal && !journal) { - if ((mount_flags & EXT2_MF_MOUNTED) && - !(mount_flags & EXT2_MF_READONLY)) { - bb_error_msg_and_die( - "The has_journal flag may only be " - "cleared when the filesystem is\n" - "unmounted or mounted " - "read-only"); - } - if (sb->s_feature_incompat & - EXT3_FEATURE_INCOMPAT_RECOVER) { - bb_error_msg_and_die( - "The needs_recovery flag is set. " - "%s before clearing the has_journal flag.", - please_fsck); - } - if (sb->s_journal_inum) { - remove_journal_inode(fs); - } - if (sb->s_journal_dev) { - remove_journal_device(fs); - } - } - if (journal && !old_journal) { - /* - * If adding a journal flag, let the create journal - * code below handle creating setting the flag and - * creating the journal. We supply a default size if - * necessary. - */ - if (!journal_size) - journal_size = -1; - sb->s_feature_compat &= ~EXT3_FEATURE_COMPAT_HAS_JOURNAL; - } - if (dxdir && !old_dxdir) { - if (!sb->s_def_hash_version) - sb->s_def_hash_version = EXT2_HASH_TEA; - if (uuid_is_null((unsigned char *) sb->s_hash_seed)) - uuid_generate((unsigned char *) sb->s_hash_seed); - } - - if (sb->s_rev_level == EXT2_GOOD_OLD_REV && - (sb->s_feature_compat || sb->s_feature_ro_compat || - sb->s_feature_incompat)) - ext2fs_update_dynamic_rev(fs); - if ((sparse != old_sparse) || - (filetype != old_filetype)) { - sb->s_state &= ~EXT2_VALID_FS; - printf("\n%s\n", please_fsck); - } - if ((old_compat != sb->s_feature_compat) || - (old_ro_compat != sb->s_feature_ro_compat) || - (old_incompat != sb->s_feature_incompat)) - ext2fs_mark_super_dirty(fs); -} - -/* - * Add a journal to the filesystem. - */ -static void add_journal(ext2_filsys fs) -{ - if (fs->super->s_feature_compat & - EXT3_FEATURE_COMPAT_HAS_JOURNAL) { - bb_error_msg_and_die("The filesystem already has a journal"); - } - if (journal_device) { - make_journal_device(journal_device, fs, 0, 0); - } else if (journal_size) { - make_journal_blocks(fs, journal_size, journal_flags, 0); - /* - * If the filesystem wasn't mounted, we need to force - * the block group descriptors out. - */ - if ((mount_flags & EXT2_MF_MOUNTED) == 0) - fs->flags &= ~EXT2_FLAG_SUPER_ONLY; - } - print_check_message(fs); -} - -/* - * Busybox stuff - */ -static char * x_blkid_get_devname(const char *token) -{ - char * dev_name; - - if (!(dev_name = blkid_get_devname(NULL, token, NULL))) - bb_error_msg_and_die("Unable to resolve '%s'", token); - return dev_name; -} - -#ifdef CONFIG_E2LABEL -static void parse_e2label_options(int argc, char ** argv) -{ - if ((argc < 2) || (argc > 3)) - bb_show_usage(); - io_options = strchr(argv[1], '?'); - if (io_options) - *io_options++ = 0; - device_name = x_blkid_get_devname(argv[1]); - if (argc == 3) { - open_flag = EXT2_FLAG_RW | EXT2_FLAG_JOURNAL_DEV_OK; - L_flag = 1; - new_label = argv[2]; - } else - print_label++; -} -#else -#define parse_e2label_options(x,y) -#endif - -static time_t parse_time(char *str) -{ - struct tm ts; - - if (strcmp(str, "now") == 0) { - return time(0); - } - memset(&ts, 0, sizeof(ts)); -#ifdef HAVE_STRPTIME - strptime(str, "%Y%m%d%H%M%S", &ts); -#else - sscanf(str, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon, - &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec); - ts.tm_year -= 1900; - ts.tm_mon -= 1; - if (ts.tm_year < 0 || ts.tm_mon < 0 || ts.tm_mon > 11 || - ts.tm_mday < 0 || ts.tm_mday > 31 || ts.tm_hour > 23 || - ts.tm_min > 59 || ts.tm_sec > 61) - ts.tm_mday = 0; -#endif - if (ts.tm_mday == 0) { - bb_error_msg_and_die("can't parse date/time specifier: %s", str); - } - return mktime(&ts); -} - -static void parse_tune2fs_options(int argc, char **argv) -{ - int c; - char * tmp; - - printf("tune2fs %s (%s)\n", E2FSPROGS_VERSION, E2FSPROGS_DATE); - while ((c = getopt(argc, argv, "c:e:fg:i:jlm:o:r:s:u:C:J:L:M:O:T:U:")) != EOF) - switch (c) - { - case 'c': - max_mount_count = xatou_range(optarg, 0, 16000); - if (max_mount_count == 0) - max_mount_count = -1; - c_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'C': - mount_count = xatou_range(optarg, 0, 16000); - C_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'e': - if (strcmp (optarg, "continue") == 0) - errors = EXT2_ERRORS_CONTINUE; - else if (strcmp (optarg, "remount-ro") == 0) - errors = EXT2_ERRORS_RO; - else if (strcmp (optarg, "panic") == 0) - errors = EXT2_ERRORS_PANIC; - else { - bb_error_msg_and_die("bad error behavior - %s", optarg); - } - e_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'f': /* Force */ - f_flag = 1; - break; - case 'g': - resgid = bb_strtoul(optarg, NULL, 10); - if (errno) - resgid = xgroup2gid(optarg); - g_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'i': - interval = strtoul(optarg, &tmp, 0); - switch (*tmp) { - case 's': - tmp++; - break; - case '\0': - case 'd': - case 'D': /* days */ - interval *= 86400; - if (*tmp != '\0') - tmp++; - break; - case 'm': - case 'M': /* months! */ - interval *= 86400 * 30; - tmp++; - break; - case 'w': - case 'W': /* weeks */ - interval *= 86400 * 7; - tmp++; - break; - } - if (*tmp || interval > (365 * 86400)) { - bb_error_msg_and_die("bad interval - %s", optarg); - } - i_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'j': - if (!journal_size) - journal_size = -1; - open_flag = EXT2_FLAG_RW; - break; - case 'J': - parse_journal_opts(&journal_device, &journal_flags, &journal_size, optarg); - open_flag = EXT2_FLAG_RW; - break; - case 'l': - l_flag = 1; - break; - case 'L': - new_label = optarg; - L_flag = 1; - open_flag = EXT2_FLAG_RW | - EXT2_FLAG_JOURNAL_DEV_OK; - break; - case 'm': - reserved_ratio = xatou_range(optarg, 0, 50); - m_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'M': - new_last_mounted = optarg; - M_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'o': - if (mntopts_cmd) { - bb_error_msg_and_die("-o may only be specified once"); - } - mntopts_cmd = optarg; - open_flag = EXT2_FLAG_RW; - break; - - case 'O': - if (features_cmd) { - bb_error_msg_and_die("-O may only be specified once"); - } - features_cmd = optarg; - open_flag = EXT2_FLAG_RW; - break; - case 'r': - reserved_blocks = xatoul(optarg); - r_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 's': - s_flag = atoi(optarg); - open_flag = EXT2_FLAG_RW; - break; - case 'T': - T_flag = 1; - last_check_time = parse_time(optarg); - open_flag = EXT2_FLAG_RW; - break; - case 'u': - resuid = bb_strtoul(optarg, NULL, 10); - if (errno) - resuid = xuname2uid(optarg); - u_flag = 1; - open_flag = EXT2_FLAG_RW; - break; - case 'U': - new_UUID = optarg; - U_flag = 1; - open_flag = EXT2_FLAG_RW | - EXT2_FLAG_JOURNAL_DEV_OK; - break; - default: - bb_show_usage(); - } - if (optind < argc - 1 || optind == argc) - bb_show_usage(); - if (!open_flag && !l_flag) - bb_show_usage(); - io_options = strchr(argv[optind], '?'); - if (io_options) - *io_options++ = 0; - device_name = x_blkid_get_devname(argv[optind]); -} - -static void tune2fs_clean_up(void) -{ - if (ENABLE_FEATURE_CLEAN_UP && device_name) free(device_name); - if (ENABLE_FEATURE_CLEAN_UP && journal_device) free(journal_device); -} - -int tune2fs_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; -int tune2fs_main(int argc, char **argv) -{ - errcode_t retval; - ext2_filsys fs; - struct ext2_super_block *sb; - io_manager io_ptr; - - if (ENABLE_FEATURE_CLEAN_UP) - atexit(tune2fs_clean_up); - - if (ENABLE_E2LABEL && (applet_name[0] == 'e')) /* e2label */ - parse_e2label_options(argc, argv); - else - parse_tune2fs_options(argc, argv); /* tune2fs */ - - io_ptr = unix_io_manager; - retval = ext2fs_open2(device_name, io_options, open_flag, - 0, 0, io_ptr, &fs); - if (retval) - bb_error_msg_and_die("No valid superblock on %s", device_name); - sb = fs->super; - if (print_label) { - /* For e2label emulation */ - printf("%.*s\n", (int) sizeof(sb->s_volume_name), - sb->s_volume_name); - return 0; - } - retval = ext2fs_check_if_mounted(device_name, &mount_flags); - if (retval) - bb_error_msg_and_die("can't determine if %s is mounted", device_name); - /* Normally we only need to write out the superblock */ - fs->flags |= EXT2_FLAG_SUPER_ONLY; - - if (c_flag) { - sb->s_max_mnt_count = max_mount_count; - ext2fs_mark_super_dirty(fs); - printf("Setting maximal mount count to %d\n", max_mount_count); - } - if (C_flag) { - sb->s_mnt_count = mount_count; - ext2fs_mark_super_dirty(fs); - printf("Setting current mount count to %d\n", mount_count); - } - if (e_flag) { - sb->s_errors = errors; - ext2fs_mark_super_dirty(fs); - printf("Setting error behavior to %u\n", errors); - } - if (g_flag) { - sb->s_def_resgid = resgid; - ext2fs_mark_super_dirty(fs); - printf("Setting reserved blocks gid to %lu\n", resgid); - } - if (i_flag) { - sb->s_checkinterval = interval; - ext2fs_mark_super_dirty(fs); - printf("Setting interval between check %lu seconds\n", interval); - } - if (m_flag) { - sb->s_r_blocks_count = (sb->s_blocks_count / 100) - * reserved_ratio; - ext2fs_mark_super_dirty(fs); - printf("Setting reserved blocks percentage to %u (%u blocks)\n", - reserved_ratio, sb->s_r_blocks_count); - } - if (r_flag) { - if (reserved_blocks >= sb->s_blocks_count/2) - bb_error_msg_and_die("reserved blocks count is too big (%lu)", reserved_blocks); - sb->s_r_blocks_count = reserved_blocks; - ext2fs_mark_super_dirty(fs); - printf("Setting reserved blocks count to %lu\n", reserved_blocks); - } - if (s_flag == 1) { - if (sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) - bb_error_msg("\nThe filesystem already has sparse superblocks"); - else { - sb->s_feature_ro_compat |= - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - sb->s_state &= ~EXT2_VALID_FS; - ext2fs_mark_super_dirty(fs); - printf("\nSparse superblock flag set. %s", please_fsck); - } - } - if (s_flag == 0) { - if (!(sb->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) - bb_error_msg("\nThe filesystem already has sparse superblocks disabled"); - else { - sb->s_feature_ro_compat &= - ~EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER; - sb->s_state &= ~EXT2_VALID_FS; - fs->flags |= EXT2_FLAG_MASTER_SB_ONLY; - ext2fs_mark_super_dirty(fs); - printf("\nSparse superblock flag cleared. %s", please_fsck); - } - } - if (T_flag) { - sb->s_lastcheck = last_check_time; - ext2fs_mark_super_dirty(fs); - printf("Setting time filesystem last checked to %s\n", - ctime(&last_check_time)); - } - if (u_flag) { - sb->s_def_resuid = resuid; - ext2fs_mark_super_dirty(fs); - printf("Setting reserved blocks uid to %lu\n", resuid); - } - if (L_flag) { - if (strlen(new_label) > sizeof(sb->s_volume_name)) - bb_error_msg("Warning: label too long, truncating"); - memset(sb->s_volume_name, 0, sizeof(sb->s_volume_name)); - safe_strncpy(sb->s_volume_name, new_label, - sizeof(sb->s_volume_name)); - ext2fs_mark_super_dirty(fs); - } - if (M_flag) { - memset(sb->s_last_mounted, 0, sizeof(sb->s_last_mounted)); - safe_strncpy(sb->s_last_mounted, new_last_mounted, - sizeof(sb->s_last_mounted)); - ext2fs_mark_super_dirty(fs); - } - if (mntopts_cmd) - update_mntopts(fs, mntopts_cmd); - if (features_cmd) - update_feature_set(fs, features_cmd); - if (journal_size || journal_device) - add_journal(fs); - - if (U_flag) { - if ((strcasecmp(new_UUID, "null") == 0) || - (strcasecmp(new_UUID, "clear") == 0)) { - uuid_clear(sb->s_uuid); - } else if (strcasecmp(new_UUID, "time") == 0) { - uuid_generate_time(sb->s_uuid); - } else if (strcasecmp(new_UUID, "random") == 0) { - uuid_generate(sb->s_uuid); - } else if (uuid_parse(new_UUID, sb->s_uuid)) { - bb_error_msg_and_die("Invalid UUID format"); - } - ext2fs_mark_super_dirty(fs); - } - - if (l_flag) - list_super (sb); - return (ext2fs_close (fs) ? 1 : 0); -} diff --git a/e2fsprogs/old_e2fsprogs/util.c b/e2fsprogs/old_e2fsprogs/util.c deleted file mode 100644 index 3e7ee8e..0000000 --- a/e2fsprogs/old_e2fsprogs/util.c +++ b/dev/null @@ -1,263 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * util.c --- helper functions used by tune2fs and mke2fs - * - * Copyright 1995, 1996, 1997, 1998, 1999, 2000 by Theodore Ts'o. - * - * Licensed under GPLv2, see file LICENSE in this source tree. - */ - -#include -#include -#include -#include -#include - -#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 force) -{ - int val; - struct stat s; - val = stat(device, &s); - if (force) - return; - if (val == -1) - bb_perror_msg_and_die("can't 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("can't determine if %s is mounted", device); - return; - } - if (mount_flags & EXT2_MF_MOUNTED) { - bb_error_msg("%s is mounted !", device); -force_check: - if (force) - bb_error_msg("badblocks forced anyways"); - else - bb_error_msg_and_die("it's not safe to run badblocks!"); - } - - if (mount_flags & EXT2_MF_BUSY) { - bb_error_msg("%s is apparently in use by the system", device); - goto force_check; - } -} - -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; - buf = xstrdup(opts); - 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=\n" - "\tdevice=\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 < 256*1024) - j_blocks = 4096; - else if (fs->super->s_blocks_count < 512*1024) - j_blocks = 8192; - else if (fs->super->s_blocks_count < 1024*1024) - j_blocks = 16384; - else - j_blocks = 32768; - - 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)); -} - -void make_journal_device(char *journal_device, ext2_filsys fs, int quiet, int force) -{ - errcode_t retval; - ext2_filsys jfs; - io_manager io_ptr; - - check_plausibility(journal_device, force); - check_mount(journal_device, force, "journal"); - io_ptr = unix_io_manager; - retval = ext2fs_open(journal_device, EXT2_FLAG_RW| - EXT2_FLAG_JOURNAL_DEV_OK, 0, - fs->blocksize, io_ptr, &jfs); - if (retval) - bb_error_msg_and_die("can't journal device %s", journal_device); - if (!quiet) - printf("Adding journal to device %s: ", journal_device); - fflush(stdout); - retval = ext2fs_add_journal_device(fs, jfs); - if (retval) - bb_error_msg_and_die("\nFailed to add journal to device %s", journal_device); - if (!quiet) - puts("done"); - ext2fs_close(jfs); -} - -void make_journal_blocks(ext2_filsys fs, int journal_size, int journal_flags, int quiet) -{ - unsigned long journal_blocks; - errcode_t retval; - - journal_blocks = figure_journal_size(journal_size, fs); - if (!journal_blocks) { - fs->super->s_feature_compat &= - ~EXT3_FEATURE_COMPAT_HAS_JOURNAL; - return; - } - if (!quiet) - printf("Creating journal (%lu blocks): ", journal_blocks); - fflush(stdout); - retval = ext2fs_add_journal_inode(fs, journal_blocks, - journal_flags); - if (retval) - bb_error_msg_and_die("can't create journal"); - if (!quiet) - puts("done"); -} - -char *e2fs_set_sbin_path(void) -{ - char *oldpath = getenv("PATH"); - /* Update our PATH to include /sbin */ -#define PATH_SET "/sbin" - if (oldpath) - oldpath = xasprintf("%s:%s", PATH_SET, oldpath); - else - oldpath = PATH_SET; - putenv(oldpath); - return oldpath; -} diff --git a/e2fsprogs/old_e2fsprogs/util.h b/e2fsprogs/old_e2fsprogs/util.h deleted file mode 100644 index 80d2417..0000000 --- a/e2fsprogs/old_e2fsprogs/util.h +++ b/dev/null @@ -1,22 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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, int force); -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); -extern void make_journal_device(char *journal_device, ext2_filsys fs, int quiet, int force); -extern void make_journal_blocks(ext2_filsys fs, int journal_size, int journal_flags, int quiet); -extern char *e2fs_set_sbin_path(void); diff --git a/e2fsprogs/old_e2fsprogs/uuid/Kbuild.src b/e2fsprogs/old_e2fsprogs/uuid/Kbuild.src deleted file mode 100644 index b8c687d..0000000 --- a/e2fsprogs/old_e2fsprogs/uuid/Kbuild.src +++ b/dev/null @@ -1,16 +0,0 @@ -# Makefile for busybox -# -# Copyright (C) 1999-2005 by Erik Andersen -# -# Licensed under GPLv2, see file LICENSE in this source tree. - -NEEDED-$(CONFIG_E2FSCK) = y -NEEDED-$(CONFIG_FSCK) = y -NEEDED-$(CONFIG_MKE2FS) = y -NEEDED-$(CONFIG_TUNE2FS) = y - -lib-y:= - -INSERT -lib-$(NEEDED-y) += compare.o gen_uuid.o pack.o parse.o unpack.o unparse.o \ - uuid_time.o diff --git a/e2fsprogs/old_e2fsprogs/uuid/compare.c b/e2fsprogs/old_e2fsprogs/uuid/compare.c deleted file mode 100644 index 348ea7c..0000000 --- a/e2fsprogs/old_e2fsprogs/uuid/compare.c +++ b/dev/null @@ -1,55 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 - -#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 --git a/e2fsprogs/old_e2fsprogs/uuid/gen_uuid.c b/e2fsprogs/old_e2fsprogs/uuid/gen_uuid.c deleted file mode 100644 index 4310c17..0000000 --- a/e2fsprogs/old_e2fsprogs/uuid/gen_uuid.c +++ b/dev/null @@ -1,304 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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% - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef HAVE_SYS_IOCTL_H -#include -#endif -#include -#ifdef HAVE_SYS_SOCKIO_H -#include -#endif -#ifdef HAVE_NET_IF_H -#include -#endif -#ifdef HAVE_NETINET_IN_H -#include -#endif -#ifdef HAVE_NET_IF_DL_H -#include -#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; -} - -/* - * 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_IFNAMSIZ(ifr.ifr_name, ifrp->ifr_name); -#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 --git a/e2fsprogs/old_e2fsprogs/uuid/pack.c b/e2fsprogs/old_e2fsprogs/uuid/pack.c deleted file mode 100644 index 217cfce..0000000 --- a/e2fsprogs/old_e2fsprogs/uuid/pack.c +++ b/dev/null @@ -1,69 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#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 --git a/e2fsprogs/old_e2fsprogs/uuid/parse.c b/e2fsprogs/old_e2fsprogs/uuid/parse.c deleted file mode 100644 index 9a3f9cb..0000000 --- a/e2fsprogs/old_e2fsprogs/uuid/parse.c +++ b/dev/null @@ -1,80 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include -#include - -#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 --git a/e2fsprogs/old_e2fsprogs/uuid/unpack.c b/e2fsprogs/old_e2fsprogs/uuid/unpack.c deleted file mode 100644 index 95d3aab..0000000 --- a/e2fsprogs/old_e2fsprogs/uuid/unpack.c +++ b/dev/null @@ -1,63 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#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 --git a/e2fsprogs/old_e2fsprogs/uuid/unparse.c b/e2fsprogs/old_e2fsprogs/uuid/unparse.c deleted file mode 100644 index d2948fe..0000000 --- a/e2fsprogs/old_e2fsprogs/uuid/unparse.c +++ b/dev/null @@ -1,77 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 - -#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 --git a/e2fsprogs/old_e2fsprogs/uuid/uuid.h b/e2fsprogs/old_e2fsprogs/uuid/uuid.h deleted file mode 100644 index 7a97064..0000000 --- a/e2fsprogs/old_e2fsprogs/uuid/uuid.h +++ b/dev/null @@ -1,103 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 1 - -#include -#include - -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 UNUSED_PARAM = {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);*/ -#define uuid_clear(uu) memset(uu, 0, sizeof(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);*/ -#define uuid_copy(dst,src) memcpy(dst, src, sizeof(dst)) - -/* 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);*/ -#define uuid_is_null(uu) (!memcmp(uu, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", sizeof(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 --git a/e2fsprogs/old_e2fsprogs/uuid/uuidP.h b/e2fsprogs/old_e2fsprogs/uuid/uuidP.h deleted file mode 100644 index 87041ef..0000000 --- a/e2fsprogs/old_e2fsprogs/uuid/uuidP.h +++ b/dev/null @@ -1,60 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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% - */ - -#include -#include - -#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 --git a/e2fsprogs/old_e2fsprogs/uuid/uuid_time.c b/e2fsprogs/old_e2fsprogs/uuid/uuid_time.c deleted file mode 100644 index b6f73e6..0000000 --- a/e2fsprogs/old_e2fsprogs/uuid/uuid_time.c +++ b/dev/null @@ -1,161 +0,0 @@ -/* vi: set sw=4 ts=4: */ -/* - * 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 -#include -#include -#include -#include - -#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: - bb_putchar('\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 --git a/e2fsprogs/tune2fs.c b/e2fsprogs/tune2fs.c index 119460a..0485e82 100644 --- a/e2fsprogs/tune2fs.c +++ b/e2fsprogs/tune2fs.c @@ -6,6 +6,35 @@ * * Licensed under GPLv2, see file LICENSE in this source tree. */ +//config:config TUNE2FS +//config: bool "tune2fs" +//config: default n # off: it is too limited compared to upstream version +//config: help +//config: tune2fs allows the system administrator to adjust various tunable +//config: filesystem parameters on Linux ext2/ext3 filesystems. + +//applet:IF_TUNE2FS(APPLET(tune2fs, BB_DIR_SBIN, BB_SUID_DROP)) + +//TODO alias to "tune2fs -L LABEL": //applet:IF_E2LABEL(APPLET_ODDNAME(e2label, tune2fs, BB_DIR_SBIN, BB_SUID_DROP, e2label)) + +//kbuild:lib-$(CONFIG_TUNE2FS) += tune2fs.o + +//usage:#define tune2fs_trivial_usage +//usage: "[-c MAX_MOUNT_COUNT] " +////usage: "[-e errors-behavior] [-g group] " +//usage: "[-i DAYS] " +////usage: "[-j] [-J journal-options] [-l] [-s sparse-flag] " +////usage: "[-m reserved-blocks-percent] [-o [^]mount-options[,...]] " +////usage: "[-r reserved-blocks-count] [-u user] " +//usage: "[-C MOUNT_COUNT] " +//usage: "[-L LABEL] " +////usage: "[-M last-mounted-dir] [-O [^]feature[,...]] " +////usage: "[-T last-check-time] [-U UUID] " +//usage: "BLOCKDEV" +//usage: +//usage:#define tune2fs_full_usage "\n\n" +//usage: "Adjust filesystem options on ext[23] filesystems" + #include "libbb.h" #include #include "bb_e2fs_defs.h" @@ -27,22 +56,6 @@ do { \ #define FETCH_LE32(field) \ (sizeof(field) == 4 ? SWAP_LE32(field) : BUG_wrong_field_size()) -//usage:#define tune2fs_trivial_usage -//usage: "[-c MAX_MOUNT_COUNT] " -////usage: "[-e errors-behavior] [-g group] " -//usage: "[-i DAYS] " -////usage: "[-j] [-J journal-options] [-l] [-s sparse-flag] " -////usage: "[-m reserved-blocks-percent] [-o [^]mount-options[,...]] " -////usage: "[-r reserved-blocks-count] [-u user] " -//usage: "[-C MOUNT_COUNT] " -//usage: "[-L LABEL] " -////usage: "[-M last-mounted-dir] [-O [^]feature[,...]] " -////usage: "[-T last-check-time] [-U UUID] " -//usage: "BLOCKDEV" -//usage: -//usage:#define tune2fs_full_usage "\n\n" -//usage: "Adjust filesystem options on ext[23] filesystems" - enum { OPT_L = 1 << 0, // label OPT_c = 1 << 1, // max mount count diff --git a/editors/awk.c b/editors/awk.c index e2527ff..b1dfe9e 100644 --- a/editors/awk.c +++ b/editors/awk.c @@ -72,12 +72,9 @@ #define OPTSTR_AWK \ - "F:v:f:" \ - IF_FEATURE_AWK_GNU_EXTENSIONS("e:") \ + "F:v:*f:*" \ + IF_FEATURE_AWK_GNU_EXTENSIONS("e:*") \ "W:" -#define OPTCOMPLSTR_AWK \ - "v::f::" \ - IF_FEATURE_AWK_GNU_EXTENSIONS("e::") enum { OPTBIT_F, /* define field separator */ OPTBIT_v, /* define variable */ @@ -207,7 +204,7 @@ typedef struct tsplitter_s { /* simple token classes */ /* Order and hex values are very important!!! See next_token() */ -#define TC_SEQSTART 1 /* ( */ +#define TC_SEQSTART (1 << 0) /* ( */ #define TC_SEQTERM (1 << 1) /* ) */ #define TC_REGEXP (1 << 2) /* /.../ */ #define TC_OUTRDR (1 << 3) /* | > >> */ @@ -227,16 +224,22 @@ typedef struct tsplitter_s { #define TC_WHILE (1 << 17) #define TC_ELSE (1 << 18) #define TC_BUILTIN (1 << 19) -#define TC_GETLINE (1 << 20) -#define TC_FUNCDECL (1 << 21) /* `function' `func' */ -#define TC_BEGIN (1 << 22) -#define TC_END (1 << 23) -#define TC_EOF (1 << 24) -#define TC_VARIABLE (1 << 25) -#define TC_ARRAY (1 << 26) -#define TC_FUNCTION (1 << 27) -#define TC_STRING (1 << 28) -#define TC_NUMBER (1 << 29) +/* This costs ~50 bytes of code. + * A separate class to support deprecated "length" form. If we don't need that + * (i.e. if we demand that only "length()" with () is valid), then TC_LENGTH + * can be merged with TC_BUILTIN: + */ +#define TC_LENGTH (1 << 20) +#define TC_GETLINE (1 << 21) +#define TC_FUNCDECL (1 << 22) /* `function' `func' */ +#define TC_BEGIN (1 << 23) +#define TC_END (1 << 24) +#define TC_EOF (1 << 25) +#define TC_VARIABLE (1 << 26) +#define TC_ARRAY (1 << 27) +#define TC_FUNCTION (1 << 28) +#define TC_STRING (1 << 29) +#define TC_NUMBER (1 << 30) #define TC_UOPPRE (TC_UOPPRE1 | TC_UOPPRE2) @@ -244,14 +247,16 @@ typedef struct tsplitter_s { #define TC_BINOP (TC_BINOPX | TC_COMMA | TC_PIPE | TC_IN) //#define TC_UNARYOP (TC_UOPPRE | TC_UOPPOST) #define TC_OPERAND (TC_VARIABLE | TC_ARRAY | TC_FUNCTION \ - | TC_BUILTIN | TC_GETLINE | TC_SEQSTART | TC_STRING | TC_NUMBER) + | TC_BUILTIN | TC_LENGTH | TC_GETLINE \ + | TC_SEQSTART | TC_STRING | TC_NUMBER) #define TC_STATEMNT (TC_STATX | TC_WHILE) #define TC_OPTERM (TC_SEMICOL | TC_NEWLINE) /* word tokens, cannot mean something else if not expected */ -#define TC_WORD (TC_IN | TC_STATEMNT | TC_ELSE | TC_BUILTIN \ - | TC_GETLINE | TC_FUNCDECL | TC_BEGIN | TC_END) +#define TC_WORD (TC_IN | TC_STATEMNT | TC_ELSE \ + | TC_BUILTIN | TC_LENGTH | TC_GETLINE \ + | TC_FUNCDECL | TC_BEGIN | TC_END) /* discard newlines after these */ #define TC_NOTERM (TC_COMMA | TC_GRPSTART | TC_GRPTERM \ @@ -346,54 +351,54 @@ enum { #define NTC "\377" /* switch to next token class (tc<<1) */ #define NTCC '\377' -#define OC_B OC_BUILTIN - static const char tokenlist[] ALIGN1 = - "\1(" NTC - "\1)" NTC - "\1/" NTC /* REGEXP */ - "\2>>" "\1>" "\1|" NTC /* OUTRDR */ - "\2++" "\2--" NTC /* UOPPOST */ - "\2++" "\2--" "\1$" NTC /* UOPPRE1 */ - "\2==" "\1=" "\2+=" "\2-=" /* BINOPX */ + "\1(" NTC /* TC_SEQSTART */ + "\1)" NTC /* TC_SEQTERM */ + "\1/" NTC /* TC_REGEXP */ + "\2>>" "\1>" "\1|" NTC /* TC_OUTRDR */ + "\2++" "\2--" NTC /* TC_UOPPOST */ + "\2++" "\2--" "\1$" NTC /* TC_UOPPRE1 */ + "\2==" "\1=" "\2+=" "\2-=" /* TC_BINOPX */ "\2*=" "\2/=" "\2%=" "\2^=" "\1+" "\1-" "\3**=" "\2**" "\1/" "\1%" "\1^" "\1*" "\2!=" "\2>=" "\2<=" "\1>" "\1<" "\2!~" "\1~" "\2&&" "\2||" "\1?" "\1:" NTC - "\2in" NTC - "\1," NTC - "\1|" NTC - "\1+" "\1-" "\1!" NTC /* UOPPRE2 */ - "\1]" NTC - "\1{" NTC - "\1}" NTC - "\1;" NTC - "\1\n" NTC - "\2if" "\2do" "\3for" "\5break" /* STATX */ + "\2in" NTC /* TC_IN */ + "\1," NTC /* TC_COMMA */ + "\1|" NTC /* TC_PIPE */ + "\1+" "\1-" "\1!" NTC /* TC_UOPPRE2 */ + "\1]" NTC /* TC_ARRTERM */ + "\1{" NTC /* TC_GRPSTART */ + "\1}" NTC /* TC_GRPTERM */ + "\1;" NTC /* TC_SEMICOL */ + "\1\n" NTC /* TC_NEWLINE */ + "\2if" "\2do" "\3for" "\5break" /* TC_STATX */ "\10continue" "\6delete" "\5print" "\6printf" "\4next" "\10nextfile" "\6return" "\4exit" NTC - "\5while" NTC - "\4else" NTC - - "\3and" "\5compl" "\6lshift" "\2or" + "\5while" NTC /* TC_WHILE */ + "\4else" NTC /* TC_ELSE */ + "\3and" "\5compl" "\6lshift" "\2or" /* TC_BUILTIN */ "\6rshift" "\3xor" - "\5close" "\6system" "\6fflush" "\5atan2" /* BUILTIN */ + "\5close" "\6system" "\6fflush" "\5atan2" "\3cos" "\3exp" "\3int" "\3log" "\4rand" "\3sin" "\4sqrt" "\5srand" - "\6gensub" "\4gsub" "\5index" "\6length" + "\6gensub" "\4gsub" "\5index" /* "\6length" was here */ "\5match" "\5split" "\7sprintf" "\3sub" "\6substr" "\7systime" "\10strftime" "\6mktime" "\7tolower" "\7toupper" NTC - "\7getline" NTC - "\4func" "\10function" NTC - "\5BEGIN" NTC - "\3END" + "\6length" NTC /* TC_LENGTH */ + "\7getline" NTC /* TC_GETLINE */ + "\4func" "\10function" NTC /* TC_FUNCDECL */ + "\5BEGIN" NTC /* TC_BEGIN */ + "\3END" /* TC_END */ /* compiler adds trailing "\0" */ ; +#define OC_B OC_BUILTIN + static const uint32_t tokeninfo[] = { 0, 0, @@ -408,7 +413,7 @@ static const uint32_t tokeninfo[] = { OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1, OC_COMPARE|VV|P(39)|2, OC_MATCH|Sx|P(45)|'!', OC_MATCH|Sx|P(45)|'~', OC_LAND|Vx|P(55), OC_LOR|Vx|P(59), OC_TERNARY|Vx|P(64)|'?', OC_COLON|xx|P(67)|':', - OC_IN|SV|P(49), /* in */ + OC_IN|SV|P(49), /* TC_IN */ OC_COMMA|SS|P(80), OC_PGETLINE|SV|P(37), OC_UNARY|xV|P(19)|'+', OC_UNARY|xV|P(19)|'-', OC_UNARY|xV|P(19)|'!', @@ -423,20 +428,20 @@ static const uint32_t tokeninfo[] = { OC_RETURN|Vx, OC_EXIT|Nx, ST_WHILE, 0, /* else */ - OC_B|B_an|P(0x83), OC_B|B_co|P(0x41), OC_B|B_ls|P(0x83), OC_B|B_or|P(0x83), OC_B|B_rs|P(0x83), OC_B|B_xo|P(0x83), OC_FBLTIN|Sx|F_cl, OC_FBLTIN|Sx|F_sy, OC_FBLTIN|Sx|F_ff, OC_B|B_a2|P(0x83), OC_FBLTIN|Nx|F_co, OC_FBLTIN|Nx|F_ex, OC_FBLTIN|Nx|F_in, OC_FBLTIN|Nx|F_lg, OC_FBLTIN|F_rn, OC_FBLTIN|Nx|F_si, OC_FBLTIN|Nx|F_sq, OC_FBLTIN|Nx|F_sr, - OC_B|B_ge|P(0xd6), OC_B|B_gs|P(0xb6), OC_B|B_ix|P(0x9b), OC_FBLTIN|Sx|F_le, + OC_B|B_ge|P(0xd6), OC_B|B_gs|P(0xb6), OC_B|B_ix|P(0x9b), /* OC_FBLTIN|Sx|F_le, was here */ OC_B|B_ma|P(0x89), OC_B|B_sp|P(0x8b), OC_SPRINTF, OC_B|B_su|P(0xb6), OC_B|B_ss|P(0x8f), OC_FBLTIN|F_ti, OC_B|B_ti|P(0x0b), OC_B|B_mt|P(0x0b), OC_B|B_lo|P(0x49), OC_B|B_up|P(0x49), + OC_FBLTIN|Sx|F_le, /* TC_LENGTH */ OC_GETLINE|SV|P(0), 0, 0, 0, - 0 /* END */ + 0 /* TC_END */ }; /* internal variable names and their initial values */ @@ -1060,12 +1065,10 @@ static uint32_t next_token(uint32_t expected) if (t_rollback) { t_rollback = FALSE; - } else if (concat_inserted) { concat_inserted = FALSE; t_tclass = save_tclass; t_info = save_info; - } else { p = g_pos; readnext: @@ -1081,7 +1084,6 @@ static uint32_t next_token(uint32_t expected) if (*p == '\0') { tc = TC_EOF; debug_printf_parse("%s: token found: TC_EOF\n", __func__); - } else if (*p == '\"') { /* it's a string */ t_string = s = ++p; @@ -1097,7 +1099,6 @@ static uint32_t next_token(uint32_t expected) *s = '\0'; tc = TC_STRING; debug_printf_parse("%s: token found:'%s' TC_STRING\n", __func__, t_string); - } else if ((expected & TC_REGEXP) && *p == '/') { /* it's regexp */ t_string = s = ++p; @@ -1130,7 +1131,6 @@ static uint32_t next_token(uint32_t expected) syntax_error(EMSG_UNEXP_TOKEN); tc = TC_NUMBER; debug_printf_parse("%s: token found:%f TC_NUMBER\n", __func__, t_double); - } else { /* search for something known */ tl = tokenlist; @@ -1207,9 +1207,10 @@ static uint32_t next_token(uint32_t expected) ltclass = t_tclass; /* Are we ready for this? */ - if (!(ltclass & expected)) + if (!(ltclass & expected)) { syntax_error((ltclass & (TC_NEWLINE | TC_EOF)) ? EMSG_UNEXP_EOS : EMSG_UNEXP_TOKEN); + } return ltclass; #undef concat_inserted @@ -1376,6 +1377,16 @@ static node *parse_expr(uint32_t iexp) debug_printf_parse("%s: TC_BUILTIN\n", __func__); cn->l.n = condition(); break; + + case TC_LENGTH: + debug_printf_parse("%s: TC_LENGTH\n", __func__); + next_token(TC_SEQSTART | TC_OPTERM | TC_GRPTERM); + rollback_token(); + if (t_tclass & TC_SEQSTART) { + /* It was a "(" token. Handle just like TC_BUILTIN */ + cn->l.n = condition(); + } + break; } } } @@ -1503,7 +1514,7 @@ static void chain_group(void) next_token(TC_SEQSTART); n2 = parse_expr(TC_SEMICOL | TC_SEQTERM); if (t_tclass & TC_SEQTERM) { /* for-in */ - if ((n2->info & OPCLSMASK) != OC_IN) + if (!n2 || (n2->info & OPCLSMASK) != OC_IN) syntax_error(EMSG_UNEXP_TOKEN); n = chain_node(OC_WALKINIT | VV); n->l.n = n2->l.n; @@ -1540,12 +1551,14 @@ static void chain_group(void) debug_printf_parse("%s: OC_BREAK\n", __func__); n = chain_node(OC_EXEC); n->a.n = break_ptr; + chain_expr(t_info); break; case OC_CONTINUE: debug_printf_parse("%s: OC_CONTINUE\n", __func__); n = chain_node(OC_EXEC); n->a.n = continue_ptr; + chain_expr(t_info); break; /* delete, next, nextfile, return, exit */ @@ -1578,12 +1591,10 @@ static void parse_program(char *p) debug_printf_parse("%s: TC_BEGIN\n", __func__); seq = &beginseq; chain_group(); - } else if (tclass & TC_END) { debug_printf_parse("%s: TC_END\n", __func__); seq = &endseq; chain_group(); - } else if (tclass & TC_FUNCDECL) { debug_printf_parse("%s: TC_FUNCDECL\n", __func__); next_token(TC_FUNCTION); @@ -1601,7 +1612,6 @@ static void parse_program(char *p) seq = &f->body; chain_group(); clear_array(ahash); - } else if (tclass & TC_OPSEQ) { debug_printf_parse("%s: TC_OPSEQ\n", __func__); rollback_token(); @@ -1616,7 +1626,6 @@ static void parse_program(char *p) chain_node(OC_PRINT); } cn->r.n = mainseq.last; - } else /* if (tclass & TC_GRPSTART) */ { debug_printf_parse("%s: TC_GRPSTART(?)\n", __func__); rollback_token(); @@ -1877,13 +1886,10 @@ static void handle_special(var *v) split_f0(); mk_splitter(getvar_s(v), &fsplitter); - } else if (v == intvar[RS]) { mk_splitter(getvar_s(v), &rsplitter); - } else if (v == intvar[IGNORECASE]) { icase = istrue(v); - } else { /* $n */ n = getvar_i(intvar[NF]); setvar_i(intvar[NF], n > v-Fields ? n : v-Fields+1); @@ -3200,7 +3206,6 @@ int awk_main(int argc, char **argv) *s1 = '='; } } - opt_complementary = OPTCOMPLSTR_AWK; opt = getopt32(argv, OPTSTR_AWK, &opt_F, &list_v, &list_f, IF_FEATURE_AWK_GNU_EXTENSIONS(&list_e,) NULL); argv += optind; argc -= optind; diff --git a/editors/diff.c b/editors/diff.c index 1961de6..b275a21 100644 --- a/editors/diff.c +++ b/editors/diff.c @@ -125,6 +125,7 @@ //usage: "\n -w Ignore all whitespace" #include "libbb.h" +#include "common_bufsiz.h" #if 0 # define dbg_error_msg(...) bb_error_msg(__VA_ARGS__) @@ -363,7 +364,7 @@ static void stone(const int *a, int n, const int *b, int *J, int pref) } struct line { - /* 'serial' is not used in the begining, so we reuse it + /* 'serial' is not used in the beginning, so we reuse it * to store line offsets, thus reducing memory pressure */ union { @@ -433,7 +434,7 @@ static void fetch(FILE_and_pos_t *ft, const off_t *ix, int a, int b, int ch) for (j = 0, col = 0; j < ix[i] - ix[i - 1]; j++) { int c = fgetc(ft->ft_fp); if (c == EOF) { - printf("\n\\ No newline at end of file\n"); + puts("\n\\ No newline at end of file"); return; } ft->ft_pos++; @@ -658,8 +659,8 @@ static bool diff(FILE* fp[2], char *file[2]) } for (j = 0; j < 2; j++) - for (k = v[j].a; k < v[j].b; k++) - nonempty |= (ix[j][k+1] - ix[j][k] != 1); + for (k = v[j].a; k <= v[j].b; k++) + nonempty |= (ix[j][k] - ix[j][k - 1] != 1); vec = xrealloc_vector(vec, 6, ++idx); memcpy(vec[idx], v, sizeof(v)); @@ -692,7 +693,7 @@ static bool diff(FILE* fp[2], char *file[2]) continue; printf(",%d", (a < b) ? b - a + 1 : 0); } - printf(" @@\n"); + puts(" @@"); /* * Output changes in "unified" diff format--the old and new lines * are printed together. @@ -747,13 +748,15 @@ static int diffreg(char *file[2]) unlink(name); if (bb_copyfd_eof(fd, fd_tmp) < 0) xfunc_die(); - if (fd) /* Prevents closing of stdin */ + if (fd != STDIN_FILENO) close(fd); fd = fd_tmp; + xlseek(fd, 0, SEEK_SET); } fp[i] = fdopen(fd, "r"); } + setup_common_bufsiz(); while (1) { const size_t sz = COMMON_BUFSIZE / 2; char *const buf0 = bb_common_bufsiz1; @@ -986,11 +989,11 @@ int diff_main(int argc UNUSED_PARAM, char **argv) INIT_G(); /* exactly 2 params; collect multiple -L