[Forensics-changes] [SCM] Tool to help recover deleted files on ext3 filesystems branch, debian, updated. debian/0.9.0-1-11-g79fcffe
Rich Ercolani
rercola at acm.jhu.edu
Mon Nov 3 03:46:31 UTC 2008
The following commit has been merged in the debian branch:
commit 01510e491a778f70396601c2ee24102248c9dce9
Author: Rich Ercolani <rercola at acm.jhu.edu>
Date: Sun Nov 2 22:44:13 2008 -0500
Merging upstream version 0.10.0
diff --git a/Makefile.in b/Makefile.in
index c852228..19f1241 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -85,8 +85,6 @@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CWD_FLAGS = @CWD_FLAGS@
CWD_LIBS = @CWD_LIBS@
-CWD_R_FLAGS = @CWD_R_FLAGS@
-CWD_R_LIBS = @CWD_R_LIBS@
CW_DEBUG_FLAGS = @CW_DEBUG_FLAGS@
CW_OPTIMISE_FLAGS = @CW_OPTIMISE_FLAGS@
CW_STRIPPED_CXXFLAGS = @CW_STRIPPED_CXXFLAGS@
diff --git a/aclocal.m4 b/aclocal.m4
index 9dd73eb..aaf5a16 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -927,7 +927,7 @@ AC_DEFUN([CW_AUTOMACROS], [dnl
dnl Check cwautomacros version.
minver=$1
test -n "$minver" || minver=0
-if test 20081012 -lt $minver; then
+if test 20080607 -lt $minver; then
AC_MSG_ERROR([cwautomacros version $minver or later is required.])
fi
dnl Detect unexpanded macros.
@@ -1020,12 +1020,8 @@ touch $1/timestamp-$2
# AC_ARG_ENABLE(debugging, [ --enable-debugging enable debugging code.])
# Where OPTIONNAME is [debugging] and WANTED is [$enable_debugging].
#
-# THREADED can be [yes], [no] or [both] when the application is
-# threaded, non-threaded or when both are needed respectively.
-# If THREADED is set to [both] then CWD_FLAGS and CWD_LIBS
-# are set as appropriate for the non-threaded case and
-# CWD_R_FLAGS and CWD_R_LIBS are set as appropriate for
-# the threaded case.
+# THREADED can be [yes] or [no] when the application is threaded
+# or non-threaded respectively.
#
# This macro tests for the usability of libcwd and sets the macro
# `cw_used_libcwd' to "yes" when it is detected, "no" otherwise.
@@ -1053,22 +1049,11 @@ else
AC_LINK_IFELSE([AC_LANG_CALL([], [__libcwd_version])], [cw_cv_lib_libcwd=yes], [cw_cv_lib_libcwd=no])
LIBS="$cw_save_LIBS"
AC_LANG_RESTORE])
- if test "$3" = "both"; then
- AC_CACHE_CHECK([if libcwd_r is available], cw_cv_lib_libcwd_r,
-[ # Check if we have libcwd_r
- AC_LANG_SAVE
- AC_LANG_CPLUSPLUS
- cw_save_LIBS="$LIBS"
- LIBS="$LIBS `pkg-config --libs libcwd_r`"
- AC_LINK_IFELSE([AC_LANG_CALL([], [__libcwd_version])], [cw_cv_lib_libcwd_r=yes], [cw_cv_lib_libcwd_r=no])
- LIBS="$cw_save_LIBS"
- AC_LANG_RESTORE])
- fi
cw_use_libcwd="$cw_wanted"
test -n "$cw_use_libcwd" || cw_use_libcwd=auto
test "$cw_use_libcwd" = "auto" && cw_use_libcwd=$cw_cv_lib_libcwd
if test "$cw_use_libcwd" = "yes"; then
- if test "$cw_cv_lib_libcwd" = "no" -o "$3" = "both" -a x"$cw_cv_lib_libcwd_r" = x"no"; then
+ if test "$cw_cv_lib_libcwd" = "no"; then
m4_default([$5], [dnl
AC_MSG_ERROR([
--enable-$1: You need to have libcwd installed to enable this.
@@ -1076,19 +1061,9 @@ else
PKG_CONFIG_PATH=/opt/install/lib/pkgconfig LD_LIBRARY_PATH=/opt/install/lib ./configure])])
else
cw_used_libcwd=yes
- if test "$3" = "both"; then
- m4_default([$4], [dnl
- CWD_FLAGS="`pkg-config --cflags libcwd`"
- CWD_LIBS="`pkg-config --libs libcwd`"
- CWD_R_FLAGS="`pkg-config --cflags libcwd_r`"
- CWD_R_LIBS="`pkg-config --libs libcwd_r`"])
- AC_SUBST(CWD_R_FLAGS)
- AC_SUBST(CWD_R_LIBS)
- else
- m4_default([$4], [dnl
- CWD_FLAGS="`pkg-config --cflags lib$cw_libname`"
- CWD_LIBS="`pkg-config --libs lib$cw_libname`"])
- fi
+ m4_default([$4], [dnl
+ CWD_FLAGS="`pkg-config --cflags lib$cw_libname`"
+ CWD_LIBS="`pkg-config --libs lib$cw_libname`"])
AC_SUBST(CWD_FLAGS)
AC_SUBST(CWD_LIBS)
fi
@@ -1259,7 +1234,7 @@ esac
# Handle cw_config_libcwd.
# Check if we have libcwd, $cw_config_libcwd can be "yes", "no" or "".
if test -z "$cw_used_libcwd"; then
-CW_LIB_LIBCWD([libcwd], [$cw_config_libcwd], [both])
+CW_LIB_LIBCWD([libcwd], [$cw_config_libcwd], [no])
fi
USE_LIBCWD="$cw_used_libcwd"
AC_SUBST([USE_LIBCWD])
diff --git a/config.guess b/config.guess
index 278f9e9..f32079a 100755
--- a/config.guess
+++ b/config.guess
@@ -1,10 +1,10 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2007-07-22'
+timestamp='2008-01-23'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -56,8 +56,8 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -532,7 +532,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
- *:AIX:*:[45])
+ *:AIX:*:[456])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@@ -799,6 +799,9 @@ EOF
EM64T | authenticamd)
echo x86_64-unknown-interix${UNAME_RELEASE}
exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
esac ;;
[345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
echo i${UNAME_MACHINE}-pc-mks
@@ -833,7 +836,14 @@ EOF
echo ${UNAME_MACHINE}-pc-minix
exit ;;
arm*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-gnueabi
+ fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
@@ -954,8 +964,8 @@ EOF
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
exit ;;
- xtensa:Linux:*:*)
- echo xtensa-unknown-linux-gnu
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-gnu
exit ;;
i*86:Linux:*:*)
# The BFD linker knows what the default object file format is, so
@@ -1474,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize
the operating system you are using. It is advised that you
download the most up to date version of the config scripts from
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
and
- http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
If the version you run ($0) is already up to date, please
send the following data and any information you think might be
diff --git a/config.sub b/config.sub
index 1761d8b..6759825 100755
--- a/config.sub
+++ b/config.sub
@@ -1,10 +1,10 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation,
-# Inc.
+# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+# Free Software Foundation, Inc.
-timestamp='2007-06-28'
+timestamp='2008-01-16'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
@@ -72,8 +72,8 @@ Report bugs and patches to <config-patches at gnu.org>."
version="\
GNU config.sub ($timestamp)
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005
-Free Software Foundation, Inc.
+Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@@ -369,10 +369,14 @@ case $basic_machine in
| v850-* | v850e-* | vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa-* \
+ | xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-*)
;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
# Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS.
386bsd)
@@ -443,6 +447,14 @@ case $basic_machine in
basic_machine=ns32k-sequent
os=-dynix
;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
c90)
basic_machine=c90-cray
os=-unicos
@@ -668,6 +680,14 @@ case $basic_machine in
basic_machine=m68k-isi
os=-sysv
;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
m88k-omron*)
basic_machine=m88k-omron
;;
@@ -813,6 +833,14 @@ case $basic_machine in
basic_machine=i860-intel
os=-osf
;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
pbd)
basic_machine=sparc-tti
;;
@@ -1021,6 +1049,10 @@ case $basic_machine in
basic_machine=tic6x-unknown
os=-coff
;;
+ tile*)
+ basic_machine=tile-unknown
+ os=-linux-gnu
+ ;;
tx39)
basic_machine=mipstx39-unknown
;;
diff --git a/configure b/configure
index 7d8bc3f..975719d 100755
--- a/configure
+++ b/configure
@@ -1,7 +1,7 @@
#! /bin/sh
# From configure.ac Revision: 7 .
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for ext3grep 0.10.0.
+# Generated by GNU Autoconf 2.61 for ext3grep 0.9.0.
#
# Report bugs to <carlo at alinoe.com>.
#
@@ -575,8 +575,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='ext3grep'
PACKAGE_TARNAME='ext3grep'
-PACKAGE_VERSION='0.10.0'
-PACKAGE_STRING='ext3grep 0.10.0'
+PACKAGE_VERSION='0.9.0'
+PACKAGE_STRING='ext3grep 0.9.0'
PACKAGE_BUGREPORT='carlo at alinoe.com'
ac_unique_file="src/ext3grep.cc"
@@ -713,8 +713,6 @@ host
host_cpu
host_vendor
host_os
-CWD_R_FLAGS
-CWD_R_LIBS
CWD_FLAGS
CWD_LIBS
USE_LIBCWD
@@ -1256,7 +1254,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures ext3grep 0.10.0 to adapt to many kinds of systems.
+\`configure' configures ext3grep 0.9.0 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1326,7 +1324,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of ext3grep 0.10.0:";;
+ short | recursive ) echo "Configuration of ext3grep 0.9.0:";;
esac
cat <<\_ACEOF
@@ -1422,7 +1420,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-ext3grep configure 0.10.0
+ext3grep configure 0.9.0
generated by GNU Autoconf 2.61
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1436,7 +1434,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by ext3grep $as_me 0.10.0, which was
+It was created by ext3grep $as_me 0.9.0, which was
generated by GNU Autoconf 2.61. Invocation command line was
$ $0 $@
@@ -2133,7 +2131,7 @@ fi
# Define the identity of the package.
PACKAGE='ext3grep'
- VERSION='0.10.0'
+ VERSION='0.9.0'
cat >>confdefs.h <<_ACEOF
@@ -2305,7 +2303,7 @@ fi
minver=20080318
test -n "$minver" || minver=0
-if test 20081012 -lt $minver; then
+if test 20080607 -lt $minver; then
{ { echo "$as_me:$LINENO: error: cwautomacros version $minver or later is required." >&5
echo "$as_me: error: cwautomacros version $minver or later is required." >&2;}
{ (exit 1); exit 1; }; }
@@ -5158,7 +5156,7 @@ if test x"$cw_wanted" = x"no"; then
cw_used_libcwd=no
else
cw_libname=cwd
- test "both" = "yes" && cw_libname=cwd_r
+ test "no" = "yes" && cw_libname=cwd_r
{ echo "$as_me:$LINENO: checking if libcwd is available" >&5
echo $ECHO_N "checking if libcwd is available... $ECHO_C" >&6; }
if test "${cw_cv_lib_libcwd+set}" = set; then
@@ -5234,88 +5232,11 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
fi
{ echo "$as_me:$LINENO: result: $cw_cv_lib_libcwd" >&5
echo "${ECHO_T}$cw_cv_lib_libcwd" >&6; }
- if test "both" = "both"; then
- { echo "$as_me:$LINENO: checking if libcwd_r is available" >&5
-echo $ECHO_N "checking if libcwd_r is available... $ECHO_C" >&6; }
-if test "${cw_cv_lib_libcwd_r+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- # Check if we have libcwd_r
-
- ac_ext=cpp
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
- cw_save_LIBS="$LIBS"
- LIBS="$LIBS `pkg-config --libs libcwd_r`"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
-/* Override any GCC internal prototype to avoid an error.
- Use char because int might match the return type of a GCC
- builtin and then its argument prototype would still apply. */
-#ifdef __cplusplus
-extern "C"
-#endif
-char __libcwd_version ();
-int
-main ()
-{
-return __libcwd_version ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
- *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
- *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
- (eval "$ac_link") 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && {
- test -z "$ac_cxx_werror_flag" ||
- test ! -s conftest.err
- } && test -s conftest$ac_exeext &&
- $as_test_x conftest$ac_exeext; then
- cw_cv_lib_libcwd_r=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- cw_cv_lib_libcwd_r=no
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
- conftest$ac_exeext conftest.$ac_ext
- LIBS="$cw_save_LIBS"
- ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-fi
-{ echo "$as_me:$LINENO: result: $cw_cv_lib_libcwd_r" >&5
-echo "${ECHO_T}$cw_cv_lib_libcwd_r" >&6; }
- fi
cw_use_libcwd="$cw_wanted"
test -n "$cw_use_libcwd" || cw_use_libcwd=auto
test "$cw_use_libcwd" = "auto" && cw_use_libcwd=$cw_cv_lib_libcwd
if test "$cw_use_libcwd" = "yes"; then
- if test "$cw_cv_lib_libcwd" = "no" -o "both" = "both" -a x"$cw_cv_lib_libcwd_r" = x"no"; then
+ if test "$cw_cv_lib_libcwd" = "no"; then
{ { echo "$as_me:$LINENO: error:
--enable-libcwd: You need to have libcwd installed to enable this.
Or perhaps you need to add its location to PKG_CONFIG_PATH and LD_LIBRARY_PATH, for example:
@@ -5327,17 +5248,8 @@ echo "$as_me: error:
{ (exit 1); exit 1; }; }
else
cw_used_libcwd=yes
- if test "both" = "both"; then
- CWD_FLAGS="`pkg-config --cflags libcwd`"
- CWD_LIBS="`pkg-config --libs libcwd`"
- CWD_R_FLAGS="`pkg-config --cflags libcwd_r`"
- CWD_R_LIBS="`pkg-config --libs libcwd_r`"
-
-
- else
- CWD_FLAGS="`pkg-config --cflags lib$cw_libname`"
- CWD_LIBS="`pkg-config --libs lib$cw_libname`"
- fi
+ CWD_FLAGS="`pkg-config --cflags lib$cw_libname`"
+ CWD_LIBS="`pkg-config --libs lib$cw_libname`"
fi
@@ -6639,7 +6551,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by ext3grep $as_me 0.10.0, which was
+This file was extended by ext3grep $as_me 0.9.0, which was
generated by GNU Autoconf 2.61. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -6692,7 +6604,7 @@ Report bugs to <bug-autoconf at gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-ext3grep config.status 0.10.0
+ext3grep config.status 0.9.0
configured by $0, generated by GNU Autoconf 2.61,
with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
@@ -7011,8 +6923,6 @@ _ACEOF
ac_delim='%!_!# '
for ac_last_try in false false false false false :; do
cat >conf$$subs.sed <<_ACEOF
-CWD_R_FLAGS!$CWD_R_FLAGS$ac_delim
-CWD_R_LIBS!$CWD_R_LIBS$ac_delim
CWD_FLAGS!$CWD_FLAGS$ac_delim
CWD_LIBS!$CWD_LIBS$ac_delim
USE_LIBCWD!$USE_LIBCWD$ac_delim
@@ -7040,7 +6950,7 @@ LIBOBJS!$LIBOBJS$ac_delim
LTLIBOBJS!$LTLIBOBJS$ac_delim
_ACEOF
- if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 27; then
+ if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 25; then
break
elif $ac_last_try; then
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
diff --git a/configure.ac b/configure.ac
index b18c728..73b1035 100644
--- a/configure.ac
+++ b/configure.ac
@@ -5,7 +5,7 @@ dnl CW_VERSION_MINOR : Increment when major changes have occured.
dnl CW_VERSION_REVISION : Increment every public release; or set to 0 when CW_VERSION_MINOR was incremented.
define(CW_VERSION_MAJOR, 0)
-define(CW_VERSION_MINOR, 10)
+define(CW_VERSION_MINOR, 9)
define(CW_VERSION_REVISION, 0)
define(CW_PACKAGE_NAME, [ext3grep])
diff --git a/debian/changelog b/debian/changelog
index 1aa5a1e..1634d5b 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,10 +1,3 @@
-ext3grep (0.10.0-1) unstable; urgency=low
-
- [ Rich Ercolani ]
- * Merging upstream version 0.10.0.
-
- -- Rich Ercolani <rercola at acm.jhu.edu> Sun, 02 Nov 2008 22:29:19 -0500
-
ext3grep (0.9.0-1) unstable; urgency=low
[ Daniel Baumann ]
diff --git a/debian/manpage/ext3grep.8 b/debian/manpage/ext3grep.8
index f2cd6db..182a0f7 100644
--- a/debian/manpage/ext3grep.8
+++ b/debian/manpage/ext3grep.8
@@ -1,10 +1,10 @@
-.TH EXT3GREP 8 "2008-10-03" "0.9.0" "recover files on ext3 filesystems"
+.TH EXT3GREP 8 "2008-09-14" "0.8.0" "recover files on ext3 filesystems"
.SH NAME
ext3grep \- ext3 file recovery tool
.SH SYNOPSIS
-\fBext3grep\fR [\fIOPTIONS\fR] [--] \fIFILE\fR \&...
+\fBext3grep\fR [\fIOPTIONS\fR] \fIFILE\fR \&...
.SH DESCRIPTION
ext3grep is a simple tool intended to aid anyone who accidentally deletes a file on an ext3 filesystem, only to find that they wanted it shortly thereafter.
@@ -19,13 +19,9 @@ Print directories, one line per entry. See the \fBFILTERS\fR section for details
.IP "\fB\-\-accept\fR \fIFILE\fR" 4
Accepts 'file' as a legal filename. Can be used multiple times. If you change any \fB\-\-accept\fR you must remove BOTH stage* files!
.IP "\fB\-\-journal\fR" 4
-Print ext3's journal.
+Prints the contents of the journal.
.IP "\fB\-\-show\-path\-inodes\fR" 4
Show the inode of each directory component in paths.
-.IP "\fB\-\-version\fR, \fB\-[vV]\fR" 4
-Prints the version information and exits successfully.
-.IP "\fB\-\-help\fR," 4
-Prints a help message and exits successfully.
.PP
.SS "Filters:"
.IP "\fB\-\-group\fR \fIgid\fR" 4
@@ -76,14 +72,16 @@ Return allocated inode table entries that are zeroed.
Print a table for directory path \fIdir\fR of directory block numbers found and the inodes used for each file.
.IP "\fB\-\-show\-journal\-inodes\fR \fIinode_num\fR" 4
Show copies of inode \fIinode_num\fR still in the journal.
-.IP "\fB\-\-restore\-inode\fR \fIinode_num\fR" 4
-Restore the files with known inode number \fIinode_num\fR. The restored files are created in ./RESTORED_FILES/ with their inode number as the extension (e.g. inode.12345)
.IP "\fB\-\-restore\-file\fR \fIpath\fR" 4
Will restore file \fIpath\fR. \fIpath\fR is relative to root of the partition and does not start with a '/' (it must be one of the paths returned by \fB\-\-dump\-names\fR). The restored directory, file or symbolic link is created in the current directory as ./\fIpath\fR.
.IP "\fB\-\-restore\-all\fR" 4
As \fB\-\-restore\-file\fR but attempts to restore everything. The use of \fB\-\-after\fR is highly recommended because the attempt to restore very old files will only result in them being hard linked to a more recently deleted file and as such pollute the output.
.IP "\fB\-\-show\-hardlinks\fR" 4
Show all inodes that are shared by two or more files.
+.IP "\fB\-\-version\fR, \fB\-[vV]\fR" 4
+Prints the version information and exits.
+.IP "\fB\-\-help\fR," 4
+Prints a help message and exits.
.SH EXAMPLES
\fBRestoring all files from the ext3 partition/file /backup/sda1:\fR
@@ -104,15 +102,11 @@ Do not attempt to use ext3grep for recovery from a mounted filesystem. Ever.
.PP
No, not even then.
.PP
-ext3grep sometimes runs out of memory on 32-bit architectures and crashes. It is highly recommended that you run ext3grep in a 64-bit environment when dealing with large filesystems, though this is seen as a bug.
+ext3grep sometimes runs out of memory spare on 32-bit architectures and crashes. It is highly recommended that you run ext3grep in a 64-bit environment when dealing with large filesystems, though this is seen as a bug.
.PP
-ext3grep cannot recover files if there are no remnants of them, or if there are no entries in the journal dating to before the file was deleted.
+ext3grep cannot recover files if there are no remnants of them.
.PP
Some files that ext3grep recovers may have trailing null bytes - just scrape them off like the burnt bits on toast.
-.PP
-Recovery from big-endian filesystems, or on big-endian filesystems, will not work.
-You can try it - but it won't work.
-
.SH SEE ALSO
\fIdebugfs\fR(8)
diff --git a/src/Makefile.in b/src/Makefile.in
index c6a7576..c9aef55 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -148,8 +148,6 @@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CWD_FLAGS = @CWD_FLAGS@
CWD_LIBS = @CWD_LIBS@
-CWD_R_FLAGS = @CWD_R_FLAGS@
-CWD_R_LIBS = @CWD_R_LIBS@
CW_DEBUG_FLAGS = @CW_DEBUG_FLAGS@
CW_OPTIMISE_FLAGS = @CW_OPTIMISE_FLAGS@
CW_STRIPPED_CXXFLAGS = @CW_STRIPPED_CXXFLAGS@
diff --git a/src/custom.cc b/src/custom.cc
index 1c69ecf..287ee0c 100644
--- a/src/custom.cc
+++ b/src/custom.cc
@@ -43,59 +43,10 @@
#include "init_consts.h"
#include "print_inode_to.h"
-// The first part of this file was written and used for custom job:
-// recovering emails on a 40 GB partition that had no information
-// left in the journal and had been mounted for a week since the deletion.
+// This file was written and used for custom job: recovering emails
+// on a 40 GB partition that had no information left in the journal
+// and had been mounted for a week since the deletion.
// In the end, 85% of the emails were recovered.
-//
-// The second part of this file was written and used for another
-// custom job: recovering a vmware flat file of 322 GB.
-// In the end, 100% was recovered.
-
-bool is_double_indirect_block(unsigned char* block_ptr)
-{
- static unsigned char block_buf[EXT3_MAX_BLOCK_SIZE];
- std::cout << "Calling is_indirect_block(*)..." << std::endl;
- if (!is_indirect_block(block_ptr), true)
- return false;
- uint32_t* p = reinterpret_cast<uint32_t*>(block_ptr);
- do
- {
- unsigned char* indirect_block_ptr = get_block(*p, block_buf);
- std::cout << "Calling is_indirect_block(" << *p << ")..." << std::endl;
- std::cout << "Group: " << block_to_group(super_block, *p) << "; block: " << *p << std::endl;
- if (!is_indirect_block(indirect_block_ptr), true)
- return false;
- }
- while (*++p);
- return true;
-}
-
-bool is_tripple_indirect_block(unsigned char* block_ptr)
-{
- static unsigned char block_buf[EXT3_MAX_BLOCK_SIZE];
- std::cout << "Calling is_indirect_block(*)..." << std::endl;
- if (!is_indirect_block(block_ptr), true)
- return false;
- uint32_t* p = reinterpret_cast<uint32_t*>(block_ptr);
- bool res = true;
- do
- {
- unsigned char* indirect_block_ptr = get_block(*p, block_buf);
- std::cout << "Calling is_double_indirect_block(" << *p << ")..." << std::endl;
- std::cout << "Group: " << block_to_group(super_block, *p) << "; block: " << *p << std::endl;
- if (!is_double_indirect_block(indirect_block_ptr))
- {
- res = false;
- std::cout << "FAILED! But continue anyway..." << std::endl;
- //return false;
- }
- }
- while (*++p);
- return res;
-}
-
-#if 0
// This must be set to the full email address (I obfuscated it before
// committing this to SVN for obvious reasons).
@@ -337,6 +288,8 @@ block_size_pairs_st block_size_pairs[block_size_pairs_size] = {
{ 6141983, 2494271 }
};
+#if 1
+
struct Data {
bool one_block; // Set if the block ends on zeroes.
bool sent; // Set if the headers have a line containing "SquirrelMail authenticated user EMAILADDRESS".
@@ -425,6 +378,38 @@ int get_block_size(unsigned char* block_ptr)
return size;
}
+bool is_double_indirect_block(unsigned char* block_ptr)
+{
+ static unsigned char block_buf[EXT3_MAX_BLOCK_SIZE];
+ if (!is_indirect_block(block_ptr))
+ return false;
+ uint32_t* p = reinterpret_cast<uint32_t*>(block_ptr);
+ do
+ {
+ unsigned char* indirect_block_ptr = get_block(*p, block_buf);
+ if (!is_indirect_block(indirect_block_ptr))
+ return false;
+ }
+ while (*++p);
+ return true;
+}
+
+bool is_tripple_indirect_block(unsigned char* block_ptr)
+{
+ static unsigned char block_buf[EXT3_MAX_BLOCK_SIZE];
+ if (!is_indirect_block(block_ptr))
+ return false;
+ uint32_t* p = reinterpret_cast<uint32_t*>(block_ptr);
+ do
+ {
+ unsigned char* indirect_block_ptr = get_block(*p, block_buf);
+ if (!is_double_indirect_block(indirect_block_ptr))
+ return false;
+ }
+ while (*++p);
+ return true;
+}
+
enum answer_t {
contiguous,
not_contiguous,
@@ -1198,7 +1183,7 @@ void custom(void)
continue;
InodePointer inode(get_inode(inode_number));
// Skip inodes with size 0 (whatever).
- if (inode->size() == 0) // Files with size 0 exist, of course.
+ if (inode->size() == 0)
continue;
// Skip symlinks.
if (is_symlink(inode))
@@ -1222,697 +1207,3 @@ void custom(void)
}
#endif
-//-----------------------------------------------------------------------------
-//
-// The code of the second custom job starts here.
-//
-// This code was written and used to successfully recover a 322 GB vmware file,
-// containing an ext3 filesystem with all emails and websites of all clients
-// of a small webhosting company. Work hours: 80. Recovery: 100%.
-
-// This table contained blocks changed by running fsck.
-int fsckd_blocks[] = {
- 0 // Deleted to save space in this demonstration code.
-};
-
-union block_t {
- struct data_st {
- int file_block_offset;
- int sequence_number;
- } data;
- unsigned char raw[4096];
-};
-static block_t buf;
-
-void custom_action(int block_nr, int file_block_nr, void*)
-{
- static int last_file_block_nr = -1;
- if (file_block_nr != -1)
- {
- if (file_block_nr != ++last_file_block_nr)
- {
- std::cout << "SKIPPED " << (file_block_nr - last_file_block_nr) << " BLOCKS, file blocks " << last_file_block_nr << " up till and including " << (file_block_nr - 1) << "!" << std::endl;
- last_file_block_nr = file_block_nr;
- }
- get_block(block_nr, buf.raw);
- std::cout << "buf.data.file_block_offset = " << buf.data.file_block_offset << "; file_block_nr = " << file_block_nr << std::endl;
- assert(buf.data.file_block_offset == file_block_nr);
- }
- assert(block_nr);
- if (block_nr == 167575554 || (block_nr >= 167606272 && block_nr <= 167606300))
- {
- std::cout << "USING BLOCK " << block_nr << "OVERWRITTEN BY FOREMOST!" << std::endl;
- //assert(false);
- }
- for (unsigned int i = 0; i < sizeof(fsckd_blocks) / sizeof(fsckd_blocks[0]); ++i)
- {
- if (fsckd_blocks[i] == block_nr)
- {
- std::cout << "USING FSCK-ED BLOCK "<< block_nr << "!" << std::endl;
- //assert(false);
- }
- }
- std::cout << "File block nr: " << file_block_nr << "; block: " << block_nr << std::endl;
-}
-
-struct block_color {
- int blocknr;
- block_color(int bn) : blocknr(bn) { }
- friend std::ostream& operator<<(std::ostream& os, block_color const& bc)
- {
- int group = block_to_group(super_block, bc.blocknr);
- int first_block = group_to_block(super_block, group);
- int last_block = first_block + 32767;
- if ((group & 1) == 1)
- os << "\e[31m";
- else
- os << "\e[34m";
- os << bc.blocknr << "\e[0m";
- if (bc.blocknr == first_block)
- os << '^';
- else if (bc.blocknr == last_block)
- os << '$';
- return os;
- }
-};
-
-class Range {
- private:
- bool first;
- int last_blocknr;
- int current_begin;
- std::vector<std::pair<int, int> > v;
-
- public:
- Range(void) : first(true) { }
-
- Range& operator+=(int blocknr)
- {
- if (first)
- {
- first = false;
- current_begin = blocknr;
- }
- else
- {
- assert(blocknr > last_blocknr);
- if (blocknr != last_blocknr + 1)
- {
- v.push_back(std::pair<int, int>(current_begin, last_blocknr));
- current_begin = blocknr;
- }
- }
- last_blocknr = blocknr;
- return *this;
- }
-
- friend std::ostream& operator<<(std::ostream& os, Range const& range)
- {
- for (std::vector<std::pair<int, int> >::const_iterator iter = range.v.begin(); iter != range.v.end(); ++iter)
- if (iter->first != iter->second)
- os << '[' << block_color(iter->first) << " - " << block_color(iter->second) <<
- " (" << (iter->second - iter->first + 1) << ")]";
- else
- os << '[' << block_color(iter->first) << ']';
- if (!range.first)
- {
- if (range.current_begin != range.last_blocknr)
- os << '[' << block_color(range.current_begin) << " - " << block_color(range.last_blocknr) <<
- " (" << (range.last_blocknr - range.current_begin + 1) << ")]";
- else
- os << '[' << block_color(range.current_begin) << ']';
- }
- return os;
- }
-};
-
-bool has_at_least_n_increasing_block_numbers(int n, unsigned char* block_buf)
-{
- __le32* p = reinterpret_cast<__le32*>(block_buf);
- __le32 last_block = 0;
- int total = 0;
- for (int i = 0; i < 1024; ++i)
- {
- if (p[i])
- {
- if (p[i] < last_block)
- return false;
- if (p[i] == last_block + 1)
- ++total;
- last_block = p[i];
- }
- }
- return total >= n;
-}
-
-// This function guesses what is the first valid Indirect Block in group 'group'.
-// Later I found a smarter way to do this by looking at the block bitmap updates
-// in the journal-- but this worked too.
-int first_indirect_block(int group, size_t& size)
-{
- std::cout << "Entering first_indirect_block(" << group << ")\n";
- static unsigned char block_buf[4096];
- int first_block = group_to_block(super_block, group);
- std::cout << "first_block = " << first_block << '\n';
- int group_end = first_block + blocks_per_group(super_block);
- std::cout << "group_end = " << group_end << '\n';
- int freq[1025];
- std::memset(freq, 0, sizeof(freq));
- for (int b = first_block; b < group_end; ++b)
- {
- get_block(b, block_buf);
- if (is_indirect_block(block_buf) && has_at_least_n_increasing_block_numbers(32, block_buf))
- {
- //std::cout << "Found indirect block at " << b << '\n';
- freq[(b - first_block - 514) % 1025] += 1; // 514 = bitmaps + inode table. 1025 = indirect block + its 1024 data blocks.
- }
- }
- int best = 0;
- int fbest = 0;
- int total = 0;
- std::vector<std::pair<int, int> > candidates;
- for (int i = 0; i < 1025; ++i)
- {
- if (freq[i])
- {
- if (freq[i] > 1)
- {
- std::cout << i << " (" << freq[i] << "), ";
- candidates.push_back(std::pair<int, int>(i, freq[i]));
- }
- total += freq[i];
- if (freq[i] > fbest)
- {
- fbest = freq[i];
- best = i;
- }
- }
- }
- std::cout << '\n';
- std::cout << '\t' << "total: " << total << std::endl;
- assert(!candidates.empty());
- size = candidates.size();
- if (size > 2)
- {
- std::cout << "FAILURE FOR GROUP " << group << ": indirect blocks are scattered! Returning -1.\n";
- return -1;
- }
- if (size == 2)
- {
- int jump = 1;
- if (group == 5146)
- jump = 2; // Special case, because this group contains the double indirect block.
- int diff = candidates[1].first - candidates[0].first;
- int sum = fbest;
- if (diff == jump)
- {
- std::cout << "Choosing smallest of two\n";
- best = candidates[0].first;
- sum = candidates[0].second + candidates[1].second;
- }
- if (sum < 30)
- {
- std::cout << "WARNING: LOW INDIRECT BLOCK COUNT! There is a not insignificant chance that the heuristics fail in this case!\n";
- }
- }
- else if (best > 0 && freq[best - 1] == 1)
- {
- size_t prev_size;
- int prev_first_indirect_block = first_indirect_block(group - 1, prev_size);
- // Turn it into the real block number.
- prev_first_indirect_block += group_to_block(super_block, group - 1) + 514;
- // Do the same for 'best - 1'.
- int next_first_indirect_block = group_to_block(super_block, group) + 514 + best - 1;
- // Use this heuristic magical formula to test if it's likely that in fact
- // we have a pair with sizes (1, 30).
- if ((prev_first_indirect_block + 520) % 1025 == next_first_indirect_block % 1025 && prev_size == 1)
- {
- std::cout << "Decrementing best!\n";
- --best;
- }
- }
- std::cout << "Leaving first_indirect_block() (returning " << best << ")\n";
- return best;
-}
-
-int first_indirect_block(int group)
-{
- size_t dummy;
- return first_indirect_block(group, dummy);
-}
-
-int fib_table1[] = {
- 190, 742, 269, 821, 348, 900, 427, 979, 506, 33, 585, 112, 664, 191, 743, 270,
- // ... lots of numbers deleted to save space in the demonstration code.
- 456, 1008, 535, 62
-};
-
-// WARNING: This table was HAND EDITTED (after generation).
-int fib_table2[] = {
- 570, 91, 644, 170, 722, 248, 800, 321, 873, 400, 952, 479, 6, 558, 85, 637,
- // ... lots of numbers deleted to save space in the demonstration code.
- 198, 750, 277, 829, 356, 908, 435, 987, 514, 41, 593, 120, 672
-};
-
-// Manually recovered Tripple Indirect Block.
-int tib_table[] = {
- 168649904, 169716665, 170782906, 171849661, 172915902, 173982663, 175049424, 176115659,
- 177182420, 178248661, 179315416, 180381657, 181448418, 182514659, 117359, 1189230,
- 2256495, 3324280, 4392059, 5458300, 6525061, 7591302, 8659087, 9725322,
- 30015342, 31082103, 32151318, 33217553, 34284314, 35350549, 36417310, 37483551,
- 38550306, 39617067, 40683308, 41750069, 42816304, 43883065, 44949306, 46016067,
- 47082302, 48149063, 49215304, 50282065, 51348820, 52415061, 53481822, 54548057,
- 55614818, 56681059, 57747820, 58814061, 59880816, 60947057, 62013818, 63080573,
- 64146814, 65213575, 66279816, 67346571, 68412812, 69479573, 70545808, 71612569,
- 72680349, 73746590, 74813351, 75879586, 76946347, 78012588, 79080373, 80146614,
- 81213375, 82279616
-};
-
-__le32 const dib_169716665[/*1024*/] = {
- /* 1024 block numbers deleted to save space */
-};
-
-__le32 const dib_39617067[/*1024*/] = {
- /* 1024 block numbers deleted to save space */
-};
-
-__le32 const dib_49215304[/*1024*/] = {
- /* 1024 block numbers deleted to save space */
-};
-
-__le32 const dib_56681059[/*1024*/] = {
- /* 1024 block numbers deleted to save space */
-};
-
-__le32 const dib_66279816[/*1024*/] = {
- /* 1024 block numbers deleted to save space */
-};
-
-// The function 'first_indirect_block' is rather slow.
-// Therefore it was once used to generate fib_table1 and fib_table2,
-// and this function uses the table.
-int first_indirect_block_table(int group)
-{
- if (5147 <= group && group <= 5598)
- return fib_table1[group - 5147];
- else if (2 <= group && group <= 2510)
- {
- int res = fib_table2[group - 2];
- if (res == -1)
- {
- std::cout << "FAILURE for group " << group << "\n\t";
- first_indirect_block(group);
- std::cout << std::endl;
- }
- assert(res != -1);
- return res;
- }
-
- int res = first_indirect_block(group);
- std::cout << "MISSING: first_indirect_block_table(" << group << ") = " << res << std::endl;
- assert(res != -1);
- return res;
-}
-
-// Given the block number of an (single) 'Indirect Block', return the next Indirect block
-// using the following heuristics: The next indirect block immediately follows the
-// last data block, which all immediately followed the last Indirect block; hence:
-// the next Indirect block is the current one plus 1025, UNLESS we reach the end
-// of a group. Then the next indirect block is retrieved from a table, which was
-// generated by determining what was the statistically most likely offset of such
-// equally spaced indirect blocks in the next group.
-__le32 next_indirect_block(__le32 current_indirect_block, bool need_restoring)
-{
- // Special cases that the heuristics fail for:
- if (current_indirect_block == 183467615)
- return 183469160;
- if (current_indirect_block == 183499910)
- return 36375;
- if (current_indirect_block == 10517828)
- return 10519373;
- if (current_indirect_block == 10523473)
- return 10537013;
- if (current_indirect_block == 10537013)
- return 29726800;
- if (current_indirect_block == 29754995)
- return 29778002;
- if (current_indirect_block == 32048904)
- return 32052383;
- int current_group = block_to_group(super_block, current_indirect_block);
- int next_group = block_to_group(super_block, current_indirect_block + 1025);
- if (current_group != next_group)
- {
- int group_start = group_to_block(super_block, current_group);
- int group_end = group_start + blocks_per_group(super_block);
- int left = group_end - current_indirect_block - 1;
- std::cout << "left = " << left << std::endl;
-
- int next_group_start = group_to_block(super_block, next_group);
- std::cout << "next_group_start = " << next_group_start << std::endl;
- int fib = need_restoring ? first_indirect_block(next_group) : first_indirect_block_table(next_group);
- std::cout << "Returning " << next_group_start + fib + 514 << std::endl;
- return next_group_start + fib + 514;
- }
- return current_indirect_block + 1025;
-}
-
-// Return true if this block is wiped (contains only zeroes).
-bool all_zeroes(__le32* indirect_block_buf)
-{
- for(int i = 0; i < 1024; ++i)
- {
- if (indirect_block_buf[i])
- return false;
- }
- return true;
-}
-
-// Retriece a Double Indirect Block.
-void get_dib(int block_number, __le32* buf)
-{
- // These blocks were wiped during deletion.
- if (block_number == 169716665)
- memcpy(buf, dib_169716665, sizeof(dib_169716665));
- else if (block_number == 39617067)
- memcpy(buf, dib_39617067, sizeof(dib_39617067));
- else if (block_number == 49215304)
- memcpy(buf, dib_49215304, sizeof(dib_49215304));
- else if (block_number == 56681059)
- memcpy(buf, dib_56681059, sizeof(dib_56681059));
- else if (block_number == 66279816)
- memcpy(buf, dib_66279816, sizeof(dib_66279816));
- else
- // The rest is still intact.
- get_block(block_number, (unsigned char*)buf);
-}
-
-void generate_sib(int sib_number, __le32* buf, __le32 next_indirect_block)
-{
- int sib_group = block_to_group(super_block, sib_number);
- int next_group_start = group_to_block(super_block, sib_group + 1);
- if (sib_group == 5599) // Last group?
- next_group_start = 183500446; // Byte-past-the-end in this group (fake a new group start).
- int block_number = sib_number;
- for (int k = 0; k < 1024; ++k)
- {
- ++block_number;
- if (block_number == next_group_start)
- {
- int next_block_number = next_indirect_block - (1024 - k);
-#if 0 // Not a gamble anymore. See skip6check.
- if (sib_number == 183499910) // The only special case (manualy checked to be ok too)
- {
- std::cout << "Gambling that data block " << next_block_number << " follows " << (block_number - 1) << std::endl;
- int group = block_to_group(super_block, next_block_number);
- int next_group_start = group_to_block(super_block, group);
- std::cout << " number of skipped blocks at the start of group " << group << ": " << (next_block_number - next_group_start - 514) << std::endl;
- }
-#endif
- block_number = next_block_number;
- }
- buf[k] = block_number;
- }
-}
-
-// This function retrieves a Single (normal) Indirect Block 'block_number').
-void get_sib(int block_number, __le32* buf, __le32 next_indirect_block)
-{
- // These blocks were wiped during deletion.
- if (block_number == 169868396 || block_number == 181632444 || block_number == 183499910 || block_number == 1900225 ||
- block_number == 3801011 || block_number == 5668471 || block_number == 34111044 || block_number == 36011825 ||
- block_number == 37879292 || block_number == 39780073 || block_number == 41680859 || block_number == 43548320 ||
- block_number == 45449107 || block_number == 47316568 || block_number == 49249650 || block_number == 51117110 ||
- block_number == 53017897 || block_number == 54918678 || block_number == 56819465 || block_number == 58720251 ||
- block_number == 60620007 || block_number == 62520788 || block_number == 64421575 || block_number == 66386952 ||
- block_number == 80608995 || block_number == 82509782)
- generate_sib(block_number, buf, next_indirect_block);
- else
- // The rest is still intact.
- get_block(block_number, (unsigned char*)buf);
-}
-
-#define DO_ACTUAL_RECOVERY 0
-
-#if DO_ACTUAL_RECOVERY
-int outfd;
-#endif
-int count = 0;
-
-struct timeval& operator-=(struct timeval& t1, struct timeval const& t2)
-{
- t1.tv_sec -= t2.tv_sec;
- if ((t1.tv_usec -= t2.tv_usec) < 0)
- {
- t1.tv_usec += 1000000;
- --t1.tv_sec;
- }
- return t1;
-}
-
-static char const zeroes[4096] = { 0, };
-struct timeval start_time;
-struct timeval current_time;
-int const total_blocks = 78643200;
-int remaining_blocks = total_blocks;
-
-// This function is called for every data block.
-void process_data_block(int block_number)
-{
-#if DO_ACTUAL_RECOVERY
- assert(block_number);
- // If the block is a block that was corrupted by running 'foremost' after deletion,
- // and before umounting, then gamble it originally only contained zeroes because
- // many blocks before and after this region turn out to contain zeroes.
- if (block_number == 167575554 || (block_number >= 167606272 && block_number <= 167606300))
- {
- int len = ::write(outfd, zeroes, 4096);
- assert(len == 4096);
- }
- else
- {
- static unsigned char block_buf[4096];
- get_block(block_number, block_buf);
- int len = ::write(outfd, (char*)block_buf, 4096);
- assert(len == 4096);
- }
-#else
- if (block_number == 167575554 || (block_number >= 167606272 && block_number <= 167606300))
- {
- std::cout << "Using foremost block " << block_number << " at file block " << count << '\n';
- }
-#endif
- ++count;
- --remaining_blocks;
- if (remaining_blocks % 10000 == 0)
- {
- gettimeofday(¤t_time, NULL);
- current_time -= start_time;
- double seconds = current_time.tv_sec + current_time.tv_usec * 1e-6;
- double blocks_per_second = (total_blocks - remaining_blocks) / seconds;
- std::cout << "Speed: " << (blocks_per_second * 4.096e-3) << " MB/s. ";
- double remaining_minutes = remaining_blocks / blocks_per_second / 60;
- std::cout << "ETA: " << std::fixed << remaining_minutes << " minutes." << std::endl;
- }
-}
-
-void custom(void)
-{
-#if 0
- // This code was used to do many/various quick queries.
- std::cout << block_to_group(super_block, 182514659) << '\n';
- //std::cout << group_to_block(super_block, block_to_group(super_block, 2589192)) << '\n';
- //first_indirect_block(5184);
- return;
-#endif
- //init_journal();
-#if 1
- // This code was used to do the final recovery.
-#if DO_ACTUAL_RECOVERY
- outfd = ::open("/home/carlo/RECOVERED.MOSES-DRIVE-322GB.VDMK-flat.vmdk", O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0644);
-#endif
- gettimeofday(&start_time, NULL);
- int blocknrs[] = { 163021314, 163021315, 163021316, 163021317, 163021318, 163021319, 163054082, 163054083, 163054084, 163054085, 163054086, 163054087 };
- for (int i = 0; i < (int)(sizeof(blocknrs) / sizeof(int)); ++i)
- {
- process_data_block(blocknrs[i]);
- }
- static __le32 sib_buf[1024];
- get_block(167582637, (unsigned char*)sib_buf);
- for (int k = 0; k < 1024; ++k)
- {
- process_data_block(sib_buf[k]);
- }
- static __le32 dib_buf[1024];
- get_block(167583662, (unsigned char*)dib_buf);
- for (int i = 0; i < 1024; ++i)
- {
- assert(dib_buf[i]);
- get_block(dib_buf[i], (unsigned char*)sib_buf);
- for (int k = 0; k < 1024; ++k)
- {
- process_data_block(sib_buf[k]);
- }
- }
- for (unsigned int j = 0; j < sizeof(tib_table) / sizeof(*tib_table); ++j)
- {
- bool saw_zeroes = false;
- int block_number = tib_table[j];
- get_dib(block_number, dib_buf);
- assert(is_indirect_block((unsigned char*)dib_buf));
- for (int i = 0; i < 1024; ++i)
- {
- if (!dib_buf[i])
- continue;
- __le32 next_indirect_block;
- if (i < 1023)
- next_indirect_block = dib_buf[i + 1];
- else
- next_indirect_block = tib_table[j + 1];
- get_sib(dib_buf[i], sib_buf, next_indirect_block);
- if (all_zeroes(sib_buf))
- {
-#if 0
- std::cout << block_number << " --> " << dib_buf[i] << " == ZEROES!\n";
- saw_zeroes = true;
-#else
- assert(false);
-#endif
- }
- else
- {
- assert(is_indirect_block((unsigned char*)sib_buf, true));
- if (sib_buf[0] != dib_buf[i] + 1)
- {
- assert(dib_buf[i] + 1 == (__le32)group_to_block(super_block, block_to_group(super_block, sib_buf[0])));
- }
- process_data_block(sib_buf[0]);
- for (int k = 1; k < 1024; ++k)
- {
- if (dib_buf[i] == 83344321 && sib_buf[k] == 0)
- continue;
- if (sib_buf[k] != sib_buf[k - 1] + 1)
- {
- if (sib_buf[k - 1] != (__le32)group_to_block(super_block, block_to_group(super_block, sib_buf[k])) - 1)
- {
- std::cout << block_number << " --> " << dib_buf[i] << " --> " << sib_buf[k] <<
- " fails hypothesis. It is the previous entry plus " << (sib_buf[k] - sib_buf[k - 1]) << " instead of plus 1.\n";
- }
- }
- process_data_block(sib_buf[k]);
- }
- if (dib_buf[i] == 83344321)
- continue;
- if (sib_buf[1023] + 1 != next_indirect_block)
- {
- int current_group = block_to_group(super_block, sib_buf[1023]);
- int next_group = block_to_group(super_block, sib_buf[1023] + 1);
- assert(current_group == next_group - 1);
- }
- }
- }
- if (!saw_zeroes)
- std::cout << block_number << " OK" << std::endl;
- }
- std::cout << "Total number of blocks: " << count << std::endl;
-#if DO_ACTUAL_RECOVERY
- ::close(outfd);
-#endif
-#endif
-#if 0
- // This code was used to see if the file that had to be recovered used sparse data
- // (zero block numbers, meaning a block with only zeroes) and whether or not
- // blocks where used that were corrupted AFTER the deletion of this file (the
- // so called 'foremost' blocks).
- Inode inode;
- int inode_nr = 34818; // 81362958
- get_undeleted_inode_type res = get_undeleted_inode(inode_nr, inode);
- //assert(res == ui_journal_inode);
- iterate_over_all_blocks_of(inode, inode_nr, custom_action, NULL, direct_bit|indirect_bit, false);
-#endif
-#if 0
- // This was used to create fib_table2 (and fib_table1 with different loop parameters).
- // However, fib_table2 was hand editted at a few places after that.
- std::vector<int> v;
- for (int group = 2; group <= 2510; ++group)
- {
- int res = first_indirect_block(group);
- v.push_back(res);
- }
- int count = 0;
- for (std::vector<int>::iterator iter = v.begin(); iter != v.end(); ++iter)
- {
- if (count % 16 == 0)
- std::cout << ",\n ";
- else
- std::cout << ", ";
- std::cout << *iter;
- ++count;
- }
- std::cout << std::endl;
- return;
-#endif
-#if 0
- // This code either tests the heuristic code to generate double indirect blocks,
- // by comparing what it would do with the actual data of existing blocks,
- // or it generates such a block; used to generate tables dib_169716665, dib_39617067 etc.
- for (unsigned int j = 0; j < sizeof(tib_table) / sizeof(*tib_table); ++j)
- {
- int block_number = tib_table[j];
- bool need_restoring =
- (block_number == 169716665 || block_number == 39617067 || block_number == 49215304 ||
- block_number == 56681059 || block_number == 66279816);
- // Toggle this to test the heuristic code, or to generate the missing double indirect blocks.
- if (!need_restoring)
- continue;
- __le32 predicted_indirect_block = block_number + 1;
- std::cout << block_color(block_number) << ": Double indirect block.\n";
- __le32 double_block_buf[1024];
- __le32 indirect_block_buf[1024];
- get_block(block_number, (unsigned char*)double_block_buf);
- for (int i = 0; i < 1024; ++i)
- {
- if (!need_restoring || double_block_buf[i])
- {
- std::cout << '\t' << block_color(double_block_buf[i]) << ": Indirect block.\n";
- get_block(double_block_buf[i], (unsigned char*)indirect_block_buf);
- if (all_zeroes(indirect_block_buf))
- {
- std::cout << "\t\tZEROES\n";
- assert(double_block_buf[i] == predicted_indirect_block);
- }
- else
- {
- assert(is_indirect_block((unsigned char*)indirect_block_buf));
- if (double_block_buf[i] != predicted_indirect_block)
- {
- unsigned char buf[4096];
- get_block(predicted_indirect_block, buf);
- assert(!is_indirect_block(buf));
- predicted_indirect_block += 1025;
- }
- assert(double_block_buf[i] == predicted_indirect_block);
- Range range;
- for (int j = 0; j < 1024; ++j)
- range += indirect_block_buf[j];
- std::cout << "\t\t" << range << '\n';
- }
- }
- else
- {
- std::cout << "\tPredicted indirect block: " << predicted_indirect_block << '\n';
- get_block(predicted_indirect_block, (unsigned char*)indirect_block_buf);
- if (all_zeroes(indirect_block_buf))
- {
- std::cout << "\t\tZEROES\n";
- }
- else
- {
- assert(is_indirect_block((unsigned char*)indirect_block_buf));
- }
- }
- predicted_indirect_block = next_indirect_block(predicted_indirect_block, need_restoring);
- }
- }
-#endif
-}
-
diff --git a/src/directories.cc b/src/directories.cc
index c4af13a..5d4f6ca 100644
--- a/src/directories.cc
+++ b/src/directories.cc
@@ -205,7 +205,7 @@ void iterate_over_directory_action(int blocknr, void* data)
iterate_over_directory(idata->block_buf, blocknr, idata->action, idata->parent, idata->data);
}
-void iterate_over_existing_directory_action(int blocknr, int, void* data)
+void iterate_over_existing_directory_action(int blocknr, void* data)
{
iterate_data_st* idata = reinterpret_cast<iterate_data_st*>(data);
unsigned char block_buf[EXT3_MAX_BLOCK_SIZE];
diff --git a/src/dump_hex_to.cc b/src/dump_hex_to.cc
index b2fa4ea..fcbc4dd 100644
--- a/src/dump_hex_to.cc
+++ b/src/dump_hex_to.cc
@@ -32,11 +32,11 @@
// dump_hex_to
//
-void dump_hex_to(std::ostream& os, unsigned char const* buf, size_t size, size_t addr_offset)
+void dump_hex_to(std::ostream& os, unsigned char const* buf, size_t size)
{
for (size_t addr = 0; addr < size; addr += 16)
{
- os << std::hex << std::setfill('0') << std::setw(4) << (addr + addr_offset) << " |";
+ os << std::hex << std::setfill('0') << std::setw(4) << addr << " |";
int offset;
for (offset = 0; offset < 16 && addr + offset < size; ++offset)
os << ' ' << std::hex << std::setfill('0') << std::setw(2) << (int)buf[addr + offset];
diff --git a/src/ext3grep.cc b/src/ext3grep.cc
index 93bd06f..bc1fad3 100644
--- a/src/ext3grep.cc
+++ b/src/ext3grep.cc
@@ -230,7 +230,7 @@ void run_program(void)
if (commandline_print)
{
std::cout << "\nHex dump of inode " << commandline_inode << ":\n";
- dump_hex_to(std::cout, (unsigned char const*)&(*inode), inode_size_);
+ dump_hex_to(std::cout, (unsigned char const*)&inode, inode_size_);
std::cout << '\n';
}
unsigned int bit = commandline_inode - 1 - commandline_group * inodes_per_group_;
@@ -387,28 +387,9 @@ void run_program(void)
else
{
std::cout << "Block " << commandline_block << " is Unallocated.\n";
- // If this assertion fails, then it is possible that this DATA block looks like an inode,
- // most likely because the data itself is an ext3 filesystem. For example an ext3 image.
- // If that is possible, then just comment this assertion out.
- //ASSERT(!is_inode(commandline_block)); // All inode blocks are allocated.
+ ASSERT(!is_inode(commandline_block)); // All inode blocks are allocated.
ASSERT(!journal); // All journal blocks are allocated.
}
- if (is_indirect_block(block))
- {
- std::cout << "Block " << commandline_block << " appears to be an (double/tripple) indirect block.\n";
- if (commandline_print)
- {
- std::cout << "It contains the following block numbers:\n";
- __le32* block_numbers = reinterpret_cast<__le32*>(block);
- for (int i = 0; i < block_size_ >> 2; ++i)
- {
- std::cout << ' ' << std::setw(9) << std::setfill(' ') << block_numbers[i];
- if ((i + 1) % 10 == 0)
- std::cout << '\n';
- }
- std::cout << '\n';
- }
- }
}
else
{
diff --git a/src/forward_declarations.h b/src/forward_declarations.h
index ec78ef7..3efeb8a 100644
--- a/src/forward_declarations.h
+++ b/src/forward_declarations.h
@@ -35,12 +35,12 @@
struct Parent;
class DirectoryBlockStats;
void decode_commandline_options(int& argc, char**& argv);
-void dump_hex_to(std::ostream& os, unsigned char const* buf, size_t size, size_t addr_offset = 0);
+void dump_hex_to(std::ostream& os, unsigned char const* buf, size_t size);
void print_block_to(std::ostream& os, unsigned char* block);
void iterate_over_directory(unsigned char* block, int blocknr,
bool (*action)(ext3_dir_entry_2 const&, Inode const&, bool, bool, bool, bool, bool, bool, Parent*, void*), Parent* parent, void* data);
void iterate_over_directory_action(int blocknr, void* data);
-void iterate_over_existing_directory_action(int blocknr, int, void* data);
+void iterate_over_existing_directory_action(int blocknr, void* data);
void iterate_over_journal(
bool (*action_tag)(uint32_t block, uint32_t sequence, journal_block_tag_t*, void* data),
bool (*action_revoke)(uint32_t block, uint32_t sequence, journal_revoke_header_t*, void* data),
diff --git a/src/indirect_blocks.cc b/src/indirect_blocks.cc
index eb9053d..ff07ec0 100644
--- a/src/indirect_blocks.cc
+++ b/src/indirect_blocks.cc
@@ -38,11 +38,7 @@
// - Only use an array on the stack if the block numbers are less than the
// size of one group apart (instead of allocating and clearing 32 MB on
// the stack every time).
-// - Use return value of std::set<>::insert instead of calling std::set<>::count.
-//
-// 2008-10-13 Carlo Wood <carlo at alinoe.com>
-// * (is_indirect_block):
-// - SKIPZEROES must be 0: zeroes a completely legal in any indirect block.
+// - Use return value of std::set<>::insert intead of calling std::set<>::count.
#ifndef USE_PCH
#include "sys.h"
@@ -60,7 +56,7 @@
// Indirect blocks
//
-void find_block_action(int blocknr, int, void* ptr)
+void find_block_action(int blocknr, void* ptr)
{
find_block_data_st& data(*reinterpret_cast<find_block_data_st*>(ptr));
if (blocknr == data.block_looking_for)
@@ -68,10 +64,10 @@ void find_block_action(int blocknr, int, void* ptr)
}
#ifdef CPPGRAPH
-void iterate_over_all_blocks_of__with__find_block_action(void) { find_block_action(0, 0, NULL); }
+void iterate_over_all_blocks_of__with__find_block_action(void) { find_block_action(0, NULL); }
#endif
-void print_directory_action(int blocknr, int, void*)
+void print_directory_action(int blocknr, void*)
{
static bool using_static_buffer = false;
ASSERT(!using_static_buffer);
@@ -85,10 +81,10 @@ void print_directory_action(int blocknr, int, void*)
}
#ifdef CPPGRAPH
-void iterate_over_all_blocks_of__with__print_directory_action(void) { print_directory_action(0, 0, NULL); }
+void iterate_over_all_blocks_of__with__print_directory_action(void) { print_directory_action(0, NULL); }
#endif
-bool iterate_over_all_blocks_of_indirect_block(int block, int& file_block_nr, void (*action)(int, int, void*), void* data, unsigned int indirect_mask, bool diagnose)
+bool iterate_over_all_blocks_of_indirect_block(int block, void (*action)(int, void*), void* data, unsigned int, bool diagnose)
{
if (diagnose)
std::cout << "Processing indirect block " << block << ": " << std::flush;
@@ -97,7 +93,7 @@ bool iterate_over_all_blocks_of_indirect_block(int block, int& file_block_nr, vo
unsigned int i = 0;
while (i < block_size_ / sizeof(__le32))
{
- if (block_ptr[i] || (indirect_mask & hole_bit))
+ if (block_ptr[i])
{
if (!is_block_number(block_ptr[i]))
{
@@ -106,10 +102,9 @@ bool iterate_over_all_blocks_of_indirect_block(int block, int& file_block_nr, vo
break;
}
if (!diagnose)
- action(block_ptr[i], file_block_nr, data);
+ action(block_ptr[i], data);
}
++i;
- ++file_block_nr;
}
bool result = (i < block_size_ / sizeof(__le32));
if (diagnose && !result)
@@ -117,17 +112,16 @@ bool iterate_over_all_blocks_of_indirect_block(int block, int& file_block_nr, vo
return result;
}
-bool iterate_over_all_blocks_of_double_indirect_block(int block, int& file_block_nr, void (*action)(int, int, void*), void* data, unsigned int indirect_mask, bool diagnose)
+bool iterate_over_all_blocks_of_double_indirect_block(int block, void (*action)(int, void*), void* data, unsigned int indirect_mask, bool diagnose)
{
if (diagnose)
std::cout << "Start processing double indirect block " << block << '.' << std::endl;
unsigned char block_buf[EXT3_MAX_BLOCK_SIZE];
__le32* block_ptr = (__le32*)get_block(block, block_buf);
unsigned int i = 0;
- unsigned int const limit = block_size_ >> 2;
- while (i < limit)
+ while (i < block_size_ / sizeof(__le32))
{
- if (block_ptr[i] || (indirect_mask & hole_bit))
+ if (block_ptr[i])
{
if (!is_block_number(block_ptr[i]))
{
@@ -136,17 +130,11 @@ bool iterate_over_all_blocks_of_double_indirect_block(int block, int& file_block
break;
}
if ((indirect_mask & indirect_bit) && !diagnose)
- action(block_ptr[i], -1, data);
+ action(block_ptr[i], data);
if ((indirect_mask & direct_bit))
- {
- if (iterate_over_all_blocks_of_indirect_block(block_ptr[i], file_block_nr, action, data, indirect_mask, diagnose))
+ if (iterate_over_all_blocks_of_indirect_block(block_ptr[i], action, data, indirect_mask, diagnose))
break;
- }
- else
- file_block_nr += limit;
}
- else
- file_block_nr += limit;
++i;
}
if (diagnose)
@@ -154,17 +142,16 @@ bool iterate_over_all_blocks_of_double_indirect_block(int block, int& file_block
return i < block_size_ / sizeof(__le32);
}
-bool iterate_over_all_blocks_of_tripple_indirect_block(int block, int& file_block_nr, void (*action)(int, int, void*), void* data, unsigned int indirect_mask, bool diagnose)
+bool iterate_over_all_blocks_of_tripple_indirect_block(int block, void (*action)(int, void*), void* data, unsigned int indirect_mask, bool diagnose)
{
if (diagnose)
std::cout << "Start processing tripple indirect block " << block << '.' << std::endl;
unsigned char block_buf[EXT3_MAX_BLOCK_SIZE];
__le32* block_ptr = (__le32*)get_block(block, block_buf);
unsigned int i = 0;
- unsigned int const limit = block_size_ >> 2;
- while (i < limit)
+ while (i < block_size_ / sizeof(__le32))
{
- if (block_ptr[i] || (indirect_mask & hole_bit))
+ if (block_ptr[i])
{
if (!is_block_number(block_ptr[i]))
{
@@ -173,45 +160,37 @@ bool iterate_over_all_blocks_of_tripple_indirect_block(int block, int& file_bloc
break;
}
if ((indirect_mask & indirect_bit) && !diagnose)
- action(block_ptr[i], -1, data);
- if (iterate_over_all_blocks_of_double_indirect_block(block_ptr[i], file_block_nr, action, data, indirect_mask, diagnose))
+ action(block_ptr[i], data);
+ if (iterate_over_all_blocks_of_double_indirect_block(block_ptr[i], action, data, indirect_mask, diagnose))
break;
}
- else
- file_block_nr += limit * limit;
++i;
}
if (diagnose)
std::cout << "End processing tripple indirect block " << block << '.' << std::endl;
- return i < limit;
+ return i < block_size_ / sizeof(__le32);
}
// Returns true if an indirect block was encountered that doesn't look like an indirect block anymore.
-bool iterate_over_all_blocks_of(Inode const& inode, int inode_number, void (*action)(int, int, void*), void* data, unsigned int indirect_mask, bool diagnose)
+bool iterate_over_all_blocks_of(Inode const& inode, int inode_number, void (*action)(int, void*), void* data, unsigned int indirect_mask, bool diagnose)
{
if (is_symlink(inode) && inode.blocks() == 0)
return false; // Block pointers contain text.
__le32 const* block_ptr = inode.block();
if (diagnose)
std::cout << "Processing direct blocks..." << std::flush;
- int file_block_nr = 0;
- unsigned int const limit = block_size_ >> 2;
if ((indirect_mask & direct_bit))
- {
- for (int i = 0; i < EXT3_NDIR_BLOCKS; ++i, ++file_block_nr)
- if (block_ptr[i] || (indirect_mask & hole_bit))
+ for (int i = 0; i < EXT3_NDIR_BLOCKS; ++i)
+ if (block_ptr[i])
{
if (diagnose)
std::cout << ' ' << block_ptr[i] << std::flush;
else
- action(block_ptr[i], file_block_nr, data);
+ action(block_ptr[i], data);
}
- }
- else
- file_block_nr += EXT3_NDIR_BLOCKS;
if (diagnose)
std::cout << std::endl;
- if (block_ptr[EXT3_IND_BLOCK] || (indirect_mask & hole_bit))
+ if (block_ptr[EXT3_IND_BLOCK])
{
if (!is_block_number(block_ptr[EXT3_IND_BLOCK]))
{
@@ -224,16 +203,12 @@ bool iterate_over_all_blocks_of(Inode const& inode, int inode_number, void (*act
return true;
}
if ((indirect_mask & indirect_bit) && !diagnose)
- action(block_ptr[EXT3_IND_BLOCK], -1, data);
+ action(block_ptr[EXT3_IND_BLOCK], data);
if ((indirect_mask & direct_bit))
- {
- if (iterate_over_all_blocks_of_indirect_block(block_ptr[EXT3_IND_BLOCK], file_block_nr, action, data, indirect_mask, diagnose))
- return true;
- }
+ if (iterate_over_all_blocks_of_indirect_block(block_ptr[EXT3_IND_BLOCK], action, data, indirect_mask, diagnose))
+ return true;
}
- else
- file_block_nr += limit;
- if (block_ptr[EXT3_DIND_BLOCK] || (indirect_mask & hole_bit))
+ if (block_ptr[EXT3_DIND_BLOCK])
{
if (!is_block_number(block_ptr[EXT3_DIND_BLOCK]))
{
@@ -246,13 +221,11 @@ bool iterate_over_all_blocks_of(Inode const& inode, int inode_number, void (*act
return true;
}
if ((indirect_mask & indirect_bit) && !diagnose)
- action(block_ptr[EXT3_DIND_BLOCK], -1, data);
- if (iterate_over_all_blocks_of_double_indirect_block(block_ptr[EXT3_DIND_BLOCK], file_block_nr, action, data, indirect_mask, diagnose))
+ action(block_ptr[EXT3_DIND_BLOCK], data);
+ if (iterate_over_all_blocks_of_double_indirect_block(block_ptr[EXT3_DIND_BLOCK], action, data, indirect_mask, diagnose))
return true;
}
- else
- file_block_nr += limit * limit;
- if (block_ptr[EXT3_TIND_BLOCK] || (indirect_mask & hole_bit))
+ if (block_ptr[EXT3_TIND_BLOCK])
{
if (!is_block_number(block_ptr[EXT3_TIND_BLOCK]))
{
@@ -265,8 +238,8 @@ bool iterate_over_all_blocks_of(Inode const& inode, int inode_number, void (*act
return true;
}
if ((indirect_mask & indirect_bit) && !diagnose)
- action(block_ptr[EXT3_TIND_BLOCK], -1, data);
- if (iterate_over_all_blocks_of_tripple_indirect_block(block_ptr[EXT3_TIND_BLOCK], file_block_nr, action, data, indirect_mask, diagnose))
+ action(block_ptr[EXT3_TIND_BLOCK], data);
+ if (iterate_over_all_blocks_of_tripple_indirect_block(block_ptr[EXT3_TIND_BLOCK], action, data, indirect_mask, diagnose))
return true;
}
return false;
@@ -275,10 +248,8 @@ bool iterate_over_all_blocks_of(Inode const& inode, int inode_number, void (*act
// See header file for description.
// Define this to return false if any [bi] is zero, otherwise
// only false is returned when the first block is zero.
-
-// This must be 0.
-#define SKIPZEROES 0
-bool is_indirect_block(unsigned char* block_ptr, bool verbose)
+#define SKIPZEROES 1
+bool is_indirect_block(unsigned char* block_ptr)
{
// Number of 32-bit values per block.
int const values_per_block = block_size_ / sizeof(__le32);
@@ -301,18 +272,13 @@ bool is_indirect_block(unsigned char* block_ptr, bool verbose)
#if SKIPZEROES
if (hasZero)
{
- if (verbose)
- std::cout << "Found non-zero after zero!" << std::endl;
- // There already was 0, now it is not 0 --- this might be an indirect block of a file with 'holes'.
- // However, fail and return false.
+ // There already was 0, now it is not 0 --- this is not an indirect block
return false;
}
#endif
if (!is_data_block_number(v))
{
// This is not a valid block pointer.
- if (verbose)
- std::cout << "Invalid block pointer!" << std::endl;
return false;
}
@@ -331,20 +297,7 @@ bool is_indirect_block(unsigned char* block_ptr, bool verbose)
}
if (vmax == 0)
- {
- if (verbose)
- {
- std::cout << "Block with only zeroes!" << std::endl;
- std::cout << std::flush;
- std::cerr << "WARNING: is_indirect_block() was called for a block with ONLY zeroes. "
- "The correct return value depends on where we were called from. This is not "
- "implemented yet!" << std::endl;
- }
- // This should return 'true' if we're called from is_double_indirect_block or is_tripple_indirect_block:
- // it should not lead to failure namely. In any case, we can definitely not be sure we return the
- // correct value; a block with only zeroes can theoretically be anything.
return false; // Only zeroes.
- }
// Maximum number of bytes to allocate in an array.
uint32_t const max_array_size = blocks_per_group(super_block);
@@ -363,8 +316,6 @@ bool is_indirect_block(unsigned char* block_ptr, bool verbose)
if (t[v - vmin])
{
// Value already present!
- if (verbose)
- std::cout << "Duplicated values!" << std::endl;
return false;
}
t[v - vmin] = 1;
@@ -384,11 +335,7 @@ bool is_indirect_block(unsigned char* block_ptr, bool verbose)
if (!v)
break;
if (!bvSet.insert(v).second) // Was already inserted?
- {
- if (verbose)
- std::cout << "Duplicated values!" << std::endl;
return false;
- }
}
return true;
}
diff --git a/src/indirect_blocks.h b/src/indirect_blocks.h
index 3958edc..9c66a8d 100644
--- a/src/indirect_blocks.h
+++ b/src/indirect_blocks.h
@@ -40,18 +40,17 @@
// Constants used with iterate_over_all_blocks_of
unsigned int const direct_bit = 1; // Call action() for real blocks.
unsigned int const indirect_bit = 2; // Call action() for (double/tripple) indirect blocks.
-unsigned int const hole_bit = 4; // Call action() for holes (blocknr will be 0).
-void print_directory_action(int blocknr, int file_block_nr, void*);
-bool iterate_over_all_blocks_of(Inode const& inode, int inode_number, void (*action)(int, int, void*), void* data = NULL, unsigned int indirect_mask = direct_bit, bool diagnose = false);
-void find_block_action(int blocknr, int file_block_nr, void* ptr);
+void print_directory_action(int blocknr, void*);
+bool iterate_over_all_blocks_of(Inode const& inode, int inode_number, void (*action)(int, void*), void* data = NULL, unsigned int indirect_mask = direct_bit, bool diagnose = false);
+void find_block_action(int blocknr, void* ptr);
struct find_block_data_st {
bool found_block;
int block_looking_for;
};
-inline bool iterate_over_all_blocks_of(InodePointer inode, int inode_number, void (*action)(int, int, void*), void* data = NULL,
+inline bool iterate_over_all_blocks_of(InodePointer inode, int inode_number, void (*action)(int, void*), void* data = NULL,
unsigned int indirect_mask = direct_bit, bool diagnose = false)
{
// inode is dereferenced here in good faith that no reference to it is kept (since there are no structs or classes that do so).
@@ -78,6 +77,6 @@ inline bool iterate_over_all_blocks_of(InodePointer inode, int inode_number, voi
* - [bi] are all different.
* - [bi] != 0 for all i.
*/
-bool is_indirect_block(unsigned char* block_ptr, bool verbose = false);
+bool is_indirect_block(unsigned char* block_ptr);
#endif // INDIRECT_BLOCKS_H
diff --git a/src/inode_refers_to.cc b/src/inode_refers_to.cc
index b827530..6a54253 100644
--- a/src/inode_refers_to.cc
+++ b/src/inode_refers_to.cc
@@ -34,7 +34,7 @@ struct inode_refers_to_st
bool found;
};
-void inode_refers_to_action(int blocknr, int, void* ptr)
+void inode_refers_to_action(int blocknr, void* ptr)
{
inode_refers_to_st& data(*reinterpret_cast<inode_refers_to_st*>(ptr));
if (blocknr == data.block_number)
@@ -42,7 +42,7 @@ void inode_refers_to_action(int blocknr, int, void* ptr)
}
#ifdef CPPGRAPH
-void iterate_over_all_blocks_of__with__inode_refers_to_action(void) { inode_refers_to_action(0, 0, NULL); }
+void iterate_over_all_blocks_of__with__inode_refers_to_action(void) { inode_refers_to_action(0, NULL); }
#endif
bool inode_refers_to(Inode const& inode, int inode_number, int block_number)
diff --git a/src/journal.cc b/src/journal.cc
index 891b021..2d85a7a 100644
--- a/src/journal.cc
+++ b/src/journal.cc
@@ -314,7 +314,7 @@ static int min_journal_block;
static int max_journal_block; // One more than largest block belonging to the journal.
static bitmap_t* is_indirect_block_in_journal_bitmap = NULL;
-void find_blocknr_range_action(int blocknr, int, void*)
+void find_blocknr_range_action(int blocknr, void*)
{
if (blocknr > largest_block_nr)
largest_block_nr = blocknr;
@@ -323,30 +323,30 @@ void find_blocknr_range_action(int blocknr, int, void*)
}
#ifdef CPPGRAPH
-void iterate_over_all_blocks_of__with__find_blocknr_range_action(void) { find_blocknr_range_action(0, 0, NULL); }
+void iterate_over_all_blocks_of__with__find_blocknr_range_action(void) { find_blocknr_range_action(0, NULL); }
#endif
-void fill_journal_bitmap_action(int blocknr, int, void*)
+void fill_journal_bitmap_action(int blocknr, void*)
{
bitmap_ptr bmp = get_bitmap_mask(blocknr - min_journal_block);
journal_block_bitmap[bmp.index] |= bmp.mask;
}
#ifdef CPPGRAPH
-void iterate_over_all_blocks_of__with__fill_journal_bitmap_action(void) { fill_journal_bitmap_action(0, 0, NULL); }
+void iterate_over_all_blocks_of__with__fill_journal_bitmap_action(void) { fill_journal_bitmap_action(0, NULL); }
#endif
-void indirect_journal_block_action(int blocknr, int, void*)
+void indirect_journal_block_action(int blocknr, void*)
{
bitmap_ptr bmp = get_bitmap_mask(blocknr - min_journal_block);
is_indirect_block_in_journal_bitmap[bmp.index] |= bmp.mask;
}
#ifdef CPPGRAPH
-void iterate_over_all_blocks_of__with__indirect_journal_block_action(void) { indirect_journal_block_action(0, 0, NULL); }
+void iterate_over_all_blocks_of__with__indirect_journal_block_action(void) { indirect_journal_block_action(0, NULL); }
#endif
-void directory_inode_action(int blocknr, int, void* data)
+void directory_inode_action(int blocknr, void* data)
{
int inode_number = *reinterpret_cast<int*>(data);
block_to_dir_inode_map_type::iterator iter = block_to_dir_inode_map.find(blocknr);
@@ -357,7 +357,7 @@ void directory_inode_action(int blocknr, int, void* data)
}
#ifdef CPPGRAPH
-void iterate_over_all_blocks_of__with__directory_inode_action(void) { directory_inode_action(0, 0, NULL); }
+void iterate_over_all_blocks_of__with__directory_inode_action(void) { directory_inode_action(0, NULL); }
#endif
void init_journal(void)
@@ -501,7 +501,7 @@ void init_journal(void)
// Normally a lasttime != 0 should do. But I ran into a case where the supposedly inode block
// didn't contain inodes at all, but block numbers?! Therefore, check that lasttime > inode_count_,
// which will be the case in 99.999% of the cases for a real time_t.
- if ((uint32_t)lasttime > inode_count_ && (__le32_to_cpu(lasttime) < (uint32_t)oldtime || oldtime == 0))
+ if (lasttime > inode_count_ && (__le32_to_cpu(lasttime) < oldtime || oldtime == 0))
oldtime = __le32_to_cpu(lasttime);
}
}
diff --git a/src/locate.cc b/src/locate.cc
index 2b8f705..573d8a5 100644
--- a/src/locate.cc
+++ b/src/locate.cc
@@ -168,6 +168,7 @@ std::string parent_directory(int
// You can set test_blocknr and uncomment the #if 0'd code below to debug your regular expressions.
static struct { char const* regexp; char const* path; } table[] = {
//#ifdef CARLO_WOODS_CASE This should be automatic now.
+// { "^(.*-BNC|ircproxy-.*|EFnet|UnderNet|FreeNode .*|OFTC|NETWORK|GimpNet|AS-....)-.*\\.log$", "carlo/.xchat2/xchatlogs" },
// { "^([0-9]{10}-[0-9]{3,5}-[0-9]+|11c0a8020[0-9]{28})\\.ms$", "carlo/k3b/temp" },
// { "^1[12][0-9]{11}_(AutoSpeedSearchHistory|SpeedMan|seltrace|thread|alerts|debug)_[12]\\.log$", "carlo/.azureus/logs/save" },
// { "^opr0[0-9][0-9A-Z]{3}\\.(js|ico|htm|gif|png|html|jpeg|xml|flv|css|swf|jpg)$", "lost+found" },
diff --git a/src/ostream_operators.cc b/src/ostream_operators.cc
index be1d5b0..0aa81a9 100644
--- a/src/ostream_operators.cc
+++ b/src/ostream_operators.cc
@@ -243,17 +243,13 @@ std::ostream& operator<<(std::ostream& os, journal_revoke_header_t const& journa
count /= sizeof(__be32);
__be32 const* ptr = reinterpret_cast<__be32 const*>((unsigned char const*)&journal_revoke_header + sizeof(journal_revoke_header_t));
int c = 0;
- if (count > 0)
- std::cout << "Revoked blocks:\n";
for (uint32_t b = 0; b < count; ++b)
{
- std::cout << std::setfill(' ') << std::setw(9) << be2le(ptr[b]);
+ std::cout << std::setfill(' ') << std::setw(8) << be2le(ptr[b]);
++c;
c &= 7;
if (c == 0)
std::cout << '\n';
- else
- std::cout << ' ';
}
return os;
}
diff --git a/src/print_inode_to.cc b/src/print_inode_to.cc
index ef5f2af..66e8a3e 100644
--- a/src/print_inode_to.cc
+++ b/src/print_inode_to.cc
@@ -93,22 +93,15 @@ void print_inode_to(std::ostream& os, Inode const& inode)
if ((inode.mode() & 0xf000) != 0xa000 || inode.blocks() != 0) // Not an inline symlink?
{
os << "\nDirect Blocks:";
- long sb = (inode.size() + block_size_ - 1) / block_size_; // Size in blocks.
for (int n = 0; n < EXT3_NDIR_BLOCKS; ++n)
- {
- os << ' ' << inode.block()[n];
- --sb;
- if (sb <= 0)
- break;
- }
+ if (inode.block()[n])
+ os << ' ' << inode.block()[n];
os << '\n';
- if (sb > 0)
+ if (inode.block()[EXT3_IND_BLOCK])
os << "Indirect Block: " << inode.block()[EXT3_IND_BLOCK] << '\n';
- sb -= block_size_ >> 2;
- if (sb > 0)
+ if (inode.block()[EXT3_DIND_BLOCK])
os << "Double Indirect Block: " << inode.block()[EXT3_DIND_BLOCK] << '\n';
- sb -= (block_size_ >> 2) * (block_size_ >> 2);
- if (sb > 0)
+ if (inode.block()[EXT3_TIND_BLOCK])
os << "Tripple Indirect Block: " << inode.block()[EXT3_TIND_BLOCK] << '\n';
}
else
diff --git a/src/printing.cc b/src/printing.cc
index c862258..a09bc5e 100644
--- a/src/printing.cc
+++ b/src/printing.cc
@@ -37,24 +37,7 @@
void print_block_to(std::ostream& os, unsigned char* block)
{
- unsigned char buf[16];
- size_t offset = 0;
- bool last_was_star = false;
- for (unsigned char* p = block; p < block + block_size_; p += 16, offset += 16)
- {
- if (offset > 0 && offset + 16 < block_size_ && memcmp(buf, p, 16) == 0)
- {
- if (!last_was_star)
- {
- os << " *\n";
- last_was_star = true;
- }
- continue;
- }
- dump_hex_to(os, p, 16, offset);
- memcpy(buf, p, 16);
- last_was_star = false;
- }
+ dump_hex_to(os, block, block_size_);
}
void print_restrictions(void)
diff --git a/src/restore.cc b/src/restore.cc
index 585c51f..9222c30 100644
--- a/src/restore.cc
+++ b/src/restore.cc
@@ -46,10 +46,17 @@
#include "print_symlink.h"
#ifdef CPPGRAPH
-void iterate_over_all_blocks_of__with__restore_file_action(void) { restore_file_action(0, 0, NULL); }
+void iterate_over_all_blocks_of__with__restore_file_action(void) { restore_file_action(0, NULL); }
#endif
-get_undeleted_inode_type get_undeleted_inode(int inodenr, Inode& inode, int* sequence)
+enum get_undeleted_inode_type {
+ ui_no_inode,
+ ui_real_inode,
+ ui_journal_inode,
+ ui_inode_too_old
+};
+
+get_undeleted_inode_type get_undeleted_inode(int inodenr, Inode& inode, int* sequence = NULL)
{
InodePointer real_inode(get_inode(inodenr));
if (!real_inode->is_deleted())
@@ -78,46 +85,25 @@ get_undeleted_inode_type get_undeleted_inode(int inodenr, Inode& inode, int* seq
extern "C" int lutimes (char const*, struct timeval const [2]);
struct Data {
- int out;
+ std::ostream& out;
off_t remaining_size;
- int expected_file_block_nr;
- Data(int out_, off_t remaining_size_) : out(out_), remaining_size(remaining_size_), expected_file_block_nr(0) { }
+ Data(std::ostream& out_, off_t remaining_size_) : out(out_), remaining_size(remaining_size_) { }
};
-void restore_file_action(int blocknr, int file_block_nr, void* ptr)
+void restore_file_action(int blocknr, void* ptr)
{
Data& data(*reinterpret_cast<Data*>(ptr));
static unsigned char block_buf[EXT3_MAX_BLOCK_SIZE];
int len;
- if (data.expected_file_block_nr != file_block_nr)
- {
- ASSERT(data.expected_file_block_nr != -1); // It's set to -1 below when we reached the end of the file.
- off64_t pos = ((off64_t) file_block_nr) * block_size_;
- if (lseek64(data.out, pos, SEEK_SET) == (off_t) -1)
- {
- int error = errno;
- std::cout << std::flush;
- std::cerr << progname << "restore_file_action: could not lseek64 to position " << pos << ": " << strerror(error) << std::endl;
- exit(EXIT_FAILURE);
- }
- data.expected_file_block_nr = file_block_nr;
- }
-
get_block(blocknr, block_buf);
if (data.remaining_size > block_size_)
- {
len = block_size_;
- data.expected_file_block_nr += block_size_;
- }
else
- {
len = data.remaining_size;
- data.expected_file_block_nr = -1; // This was the last block.
- }
- int res = ::write(data.out, (char const*)block_buf, len);
- ASSERT(res == len);
+ data.out.write((char const*)block_buf, len);
+ ASSERT(data.out.good());
data.remaining_size -= len;
}
@@ -185,12 +171,6 @@ void restore_inode(int inodenr, InodePointer real_inode, std::string const& outf
std::cerr << progname << ": could not create directory " << outputdir_outfile << ": " << strerror(error) << std::endl;
exit(EXIT_FAILURE);
}
- if (chmod(outputdir_outfile.c_str(), mode) == -1)
- {
- int error = errno;
- std::cout << "WARNING: failed to set mode on directory " << outputdir_outfile << std::endl;
- std::cerr << progname << ": chmod: " << strerror(error) << std::endl;
- }
struct utimbuf ub;
ub.actime = real_inode->atime();
ub.modtime = real_inode->mtime();
@@ -215,9 +195,9 @@ void restore_inode(int inodenr, InodePointer real_inode, std::string const& outf
ASSERT(!inode.is_deleted());
if (is_regular_file(inode))
{
- int out;
- out = ::open(outputdir_outfile.c_str(), O_WRONLY|O_CREAT|O_TRUNC|O_LARGEFILE, 0777);
- if (out == -1)
+ std::ofstream out;
+ out.open(outputdir_outfile.c_str());
+ if (!out)
{
std::cout << "Failed to open \"" << outputdir_outfile << "\".\n";
return;
@@ -229,7 +209,8 @@ void restore_inode(int inodenr, InodePointer real_inode, std::string const& outf
iterate_over_all_blocks_of__with__restore_file_action();
#endif
bool reused_or_corrupted_indirect_block8 = iterate_over_all_blocks_of(inode, inodenr, restore_file_action, &data);
- ::close(out);
+ ASSERT(out.good());
+ out.close();
if (reused_or_corrupted_indirect_block8)
{
std::cout << "WARNING: Failed to restore " << outfile << ": encountered a reused or corrupted (double/triple) indirect block!\n";
diff --git a/src/restore.h b/src/restore.h
index 65b51c2..e7e83a6 100644
--- a/src/restore.h
+++ b/src/restore.h
@@ -35,13 +35,4 @@ std::string const outputdir = "RESTORED_FILES/";
void restore_inode(int inodenr, InodePointer real_inode, std::string const& outfile);
-enum get_undeleted_inode_type {
- ui_no_inode,
- ui_real_inode,
- ui_journal_inode,
- ui_inode_too_old
-};
-
-get_undeleted_inode_type get_undeleted_inode(int inodenr, Inode& inode, int* sequence = NULL);
-
#endif // RESTORE_H
diff --git a/src/revision.cc b/src/revision.cc
index 9acbe03..f9a2b11 100644
--- a/src/revision.cc
+++ b/src/revision.cc
@@ -1 +1 @@
-char const* svn_revision = "Revision: 121";
+char const* svn_revision = "Revision: 115";
diff --git a/src/sys.h.in b/src/sys.h.in
index 11fbc8d..47763a3 100644
--- a/src/sys.h.in
+++ b/src/sys.h.in
@@ -30,9 +30,6 @@
#include "config.h"
#endif
-// This is needed for lseek64.
-#define _LARGEFILE64_SOURCE
-
#ifdef CWDEBUG
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
--
Tool to help recover deleted files on ext3 filesystems
More information about the forensics-changes
mailing list