diff options
author | robi <robi> | 2010-09-24 02:03:00 +0000 |
---|---|---|
committer | robi <robi> | 2010-09-24 02:03:00 +0000 |
commit | 2761a6bac18b775c6ddd5dcdc83ade0ce6e4944c (patch) | |
tree | 62226f1e1439c8c1e7241722fe86bfcb2e728528 | |
parent | 2a7afdee4772f99afdc404bcafea2b70df1bead0 (diff) |
magic functions
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | INSTALL | 121 | ||||
-rwxr-xr-x | configure | 683 | ||||
-rw-r--r-- | configure.in | 24 | ||||
-rw-r--r-- | src/block.c | 3 | ||||
-rw-r--r-- | src/block.h | 1 | ||||
-rw-r--r-- | src/ext4magic.8 | 32 | ||||
-rw-r--r-- | src/ext4magic.c | 81 | ||||
-rw-r--r-- | src/ext4magic.h | 1 | ||||
-rw-r--r-- | src/file_type.c | 7 | ||||
-rw-r--r-- | src/hard_link_stack.c | 6 | ||||
-rw-r--r-- | src/imap_search.c | 2 | ||||
-rw-r--r-- | src/inode.c | 6 | ||||
-rw-r--r-- | src/inode.h | 6 | ||||
-rw-r--r-- | src/journal.c | 4 | ||||
-rw-r--r-- | src/journal.h | 4 | ||||
-rw-r--r-- | src/lookup_local.c | 5 | ||||
-rw-r--r-- | src/magic.h | 4 | ||||
-rw-r--r-- | src/magic_block_scan.c | 228 | ||||
-rw-r--r-- | src/recover.c | 29 | ||||
-rw-r--r-- | src/util.c | 85 | ||||
-rw-r--r-- | src/util.h | 10 |
22 files changed, 1116 insertions, 232 deletions
@@ -1,3 +1,9 @@ +0.2.0-pv0 BUG: #017447 ; #017453 + enable the first version of the magic-funktions for ext3 + new Options "-M" and "-n" + check header und library in configure + + 0.1.4 BUG: #17387 symlink not restored BUG: #17423 undeleted directory not found BUG: #17425 run-time error "segmentation fault" at the beginning of a directory @@ -10,6 +10,23 @@ It works only on Linux (with a few limitations also Big-Endian-CPUs) Other UNIX operating systems will not compile. + +In versions ext4magic > 0.1.4 you need the package of the Linux command "file". +If you get the following error: +"error: The library libmagic.so not found, install the package "file" to build ext4magic" +and "file" is installed, generate a symlink to the existing version on your computer. + +# cd /usr/lib +# ln -s libmagic.so.1 libmagic.so +# ls -l /usr/lib/libmagic* +lrwxrwxrwx 1 root root 13 Sep 23 01:40 /usr/lib/libmagic.so -> libmagic.so.1 +lrwxrwxrwx 1 root root 17 Aug 28 16:09 /usr/lib/libmagic.so.1 -> libmagic.so.1.0.0 +-rwxr-xr-x 1 root root 116720 Oct 24 2009 /usr/lib/libmagic.so.1.0.0 + + + + + First check your current version of libext2fs with the following command # /sbin/fsck.ext3 -V @@ -19,11 +36,12 @@ if Version >= 1.41.9 Install the following devel packages: There are possibley different names according your Linux distribution -openSuse debian ------------------------------------------------- -libext2fs-devel e2fslibs-dev -libuuid-devel uuid-dev -libblkid-devel libblkid-dev +openSuse debian Fedora +---------------------------------------------------------------------- +libext2fs-devel e2fslibs-dev e2fsprogs-devel +libuuid-devel uuid-dev libuuid-devel +libblkid-devel libblkid-dev libblkid-devel + then # ./configure @@ -59,7 +77,7 @@ ext4magic is so linked to the newer library. You can see different version of li -Install HOWTO extendet german version +Installations HOWTO deutsch Installation von ext4magic ============================ @@ -82,6 +100,28 @@ nicht schon vorhanden, vorher installiert werden. gcc make +In ext4magic > 0.1.4 wird zusätzlich noch das Paket des Linux Befehls "file" benötigt. +Bei einigen Distributionen erhalten sie trotz installierten Paketes "file" bei configure +folgende Fehlermedlung: +"error: The library libmagic.so not found, install the package "file" to build ext4magic" + +in diesem Fall wechseln sie in das Verzeichnis /usr/lib und erzeugen dort einen Symlink libmagic.so +auf die dort vorhandene Version dieser Library. Folgender Konsollog zeigt das Vorgehen. + +# ls -l /usr/lib/libmagic* +lrwxrwxrwx 1 root root 17 Aug 28 16:09 /usr/lib/libmagic.so.1 -> libmagic.so.1.0.0 +-rwxr-xr-x 1 root root 116720 Oct 24 2009 /usr/lib/libmagic.so.1.0.0 +# cd /usr/lib +# ln -s libmagic.so.1 libmagic.so +# ls -l /usr/lib/libmagic* +lrwxrwxrwx 1 root root 13 Sep 23 01:40 /usr/lib/libmagic.so -> libmagic.so.1 +lrwxrwxrwx 1 root root 17 Aug 28 16:09 /usr/lib/libmagic.so.1 -> libmagic.so.1.0.0 +-rwxr-xr-x 1 root root 116720 Oct 24 2009 /usr/lib/libmagic.so.1.0.0 + + + + + Was weiter benötigt wird, ist abhängig von der Version einer auf ihrem System verwendeten Library. Auf dieser Library basieren die Befehle zum Erstellen und Verwalten der ext2/3/4 Filesysteme @@ -98,12 +138,15 @@ Die Version kann mit folgendem Befehl ermittet werden. Using EXT2FS Library version 1.41.9, 22-Aug-2009 weiter werden jetzt einige Devel-Pakete benötigt, diese können in den einzelnen Distributionen -unterschiedliche Namen tragen. Hier als Beispiel der Vergleich der Paketnamen bei -openSuse (erste Spalte) und Debian basierenden Systemen (zweite Spalte). +unterschiedliche Namen tragen. Hier als Beispiel der Vergleich der Paketnamen +zwischen einigen Distributionen + +openSuse debian Fedora +---------------------------------------------------------------------- +libext2fs-devel e2fslibs-dev e2fsprogs-devel +libuuid-devel uuid-dev libuuid-devel +libblkid-devel libblkid-dev libblkid-devel -libext2fs-devel e2fslibs-dev -libuuid-devel uuid-dev -libblkid-devel libblkid-dev Das ext4magic Archiv downloaden und entpacken und in das so entstehende Verzeichnis wechseln @@ -164,50 +207,10 @@ ext4magic angelegt wird. Nutzen sie die selbe Shell in der die EXT2LIB Variable # ./configure CFLAGS="-I$EXT2LIB" LDFLAGS="-L$EXT2LIB" LIBS="-luuid -lcom_err -lpthread" # make -sollten bei make trotzdem in den letzen Zeilen Ausgaben noch "ERROR" Meldungen erhalten die durch den -Befehl "ld" verursacht werden, versuchen sie bitte noch folgende Umgehung des Problems - -..................................... -im Unterverzeichnis src/ von ext4magic gibt es eine Datei Namens Makefile.in - Diese mit einem Editor -(hier im Beispiel mit vi ) öffnen und folgenden Abschnitt suchen. - - # vi src/Makefile.in - ..... - ..... - # library search path. - ext4magic_CFLAGS = -O2 -g -D_FILE_OFFSET_BITS=64 - ext4magic_LDFLAGS = -lext2fs -le2p -luuid -lblkid - noinst_HEADERS = block.h dir_list.h ext2fsP.h ext4magic.h hard_link_stack.h \ - inode.h jfs_compat.h jfs_user.h journal.h kernel-jbd.h ring_buf.h util.h - ..... - ..... - - -an den Anfang der Zeile die mit "ext4magic_LDFLAGS =" beginnt, ein '#' setzen - - # ext4magic_LDFLAGS = -lext2fs -le2p -luuid -lblkid - -und die Datei speichern. Danach configure mit folgenden Optionen ausführen, wir benötigen die -gleiche Shell in der wir vorhin die Variable EXT2LIB angelegt haben. Die gesamte Befehlszeile -am besten von hier per copy & paste übernehmen. (ist eine zusammenhängende Zeile auch wenn sie -bei ihnen eventuell in der Anzeige umgebrochen ist) - - - # ./configure LDFLAGS="$EXT2LIB/libext2fs.a $EXT2LIB/libcom_err.a $EXT2LIB/libe2p.a $EXT2LIB/libblkid.a $EXT2LIB/libuuid.a -lpthread" CFLAGS="-I $EXT2LIB" - -danach normal mit "make" compilieren - - -ist make ohne Error durchgelaufen, kann gegebenenfalls mit Root-Rechten und "make install" ext4magic -noch unterhalb von /usr/local/sbin/ installiert werden. - - -Sie erhalten so ein ext4magic Programm das auf einer anderen libext2fs Version beruht, als ihre Admintools auf dem -Rechner. Sie können damit auch ext4 Filesysteme untersuchen und auch gelöschte oder überschriebene Daten daraus -wiederherstellen, auch wenn das Betriebssystem auf dem Rechner ext4 nicht unterstützt. -Die unterschiedlichen Versionen sehen sie zB. im Vergleich der Ausgabe folgender Befehle: +Die Verwendung der unterschiedlichen Versionen von libext2fs sehen sie zB. im Vergleich +der Ausgabe folgender Befehle: # ext4magic -V x @@ -219,22 +222,28 @@ Die unterschiedlichen Versionen sehen sie zB. im Vergleich der Ausgabe folgender e2fsck 1.39 (29-May-2006) Benutze EXT2FS Library version 1.39, 29-May-2006 + + Sollten sie ext4magic installiert haben und dennoch nicht als root aufrufen können, liegt es wahrscheinlich an der PATH Variable. In vielen Distributionen ist /usr/local/sbin default entweder gar nicht in der PATH-Variable, oder nur wenn sie bei der Anmeldung -als root wirklich eine Loginshell durchlaufen haben. In diesem Fall wechseln mit dem Befehl +als root wirklich eine Loginshell durchlaufen haben. Sollte obwohl sie als root ausgeführt ext4magic nicht gefunden werden, +wechseln mit dem Befehl # su - noch einmal zu root. Dabei wird eine Loginshell durchlaufen und die PATH-Variable auch auf diese lokalen Systemverwalter Programme gesetzt. +Sollte es auch jetzt nicht funktionieren, überprüfen sie ihre PATH Variable des Users root. Hier sollte "/usr/local/sbin" mit +aufgeführt sein. Das selbe was eben bei der PATH-Variable gesagt wurde, könnte sich ähnlich auch bei der MANPATH Variable darstellen. Sollten sie die -Manpage von ext4magic obwohl sie das Programm installiert haben, nicht aufrufen können. Überprüfen sie die MANPATH Variable. +Manpage von ext4magic, obwohl sie das Programm installiert haben, nicht aufrufen können. Überprüfen sie die MANPATH Variable. Sollten sie ext4magic nicht installieren, können sie dennoch die Manpage auch ohne Installation anschauen. Aus dem Verzeichnis -in dem sie configure und make ausführen, starten sie folgenden Befehl um die Manpage zu lesen. +in dem sie configure und make ausführen, starten sie einen der folgenden Befehl um die Manpage zu lesen: # nroff -man src/ext4magic.8 | more + # man -l src/ext4magic.8 ----------------------------------------------------------------------------- @@ -903,6 +903,7 @@ enable_fast_install with_gnu_ld enable_libtool_lock enable_debug +enable_debug_magic enable_file_attr ' ac_precious_vars='build_alias @@ -1550,6 +1551,7 @@ Optional Features: optimize for fast installation [default=yes] --disable-libtool-lock avoid locking (might break parallel builds) --enable-debug Turn on debugging + --enable-debug-magic Turn on debugging magic-scan-engine --enable-file-attr enable restore of file attribute Optional Packages: @@ -2492,7 +2494,7 @@ fi # Define the identity of the package. PACKAGE=ext4magic - VERSION=0.1.4 + VERSION=0.2.0-pv0 cat >>confdefs.h <<_ACEOF @@ -4363,13 +4365,13 @@ if test "${lt_cv_nm_interface+set}" = set; then else lt_cv_nm_interface="BSD nm" echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:4366: $ac_compile\"" >&5) + (eval echo "\"\$as_me:4368: $ac_compile\"" >&5) (eval "$ac_compile" 2>conftest.err) cat conftest.err >&5 - (eval echo "\"\$as_me:4369: $NM \\\"conftest.$ac_objext\\\"\"" >&5) + (eval echo "\"\$as_me:4371: $NM \\\"conftest.$ac_objext\\\"\"" >&5) (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) cat conftest.err >&5 - (eval echo "\"\$as_me:4372: output\"" >&5) + (eval echo "\"\$as_me:4374: output\"" >&5) cat conftest.out >&5 if $GREP 'External.*some_variable' conftest.out > /dev/null; then lt_cv_nm_interface="MS dumpbin" @@ -5575,7 +5577,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 5578 "configure"' > conftest.$ac_ext + echo '#line 5580 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -7428,11 +7430,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7431: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7433: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7435: \$? = $ac_status" >&5 + echo "$as_me:7437: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7767,11 +7769,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7770: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7772: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7774: \$? = $ac_status" >&5 + echo "$as_me:7776: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -7872,11 +7874,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7875: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7877: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7879: \$? = $ac_status" >&5 + echo "$as_me:7881: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -7927,11 +7929,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7930: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7932: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7934: \$? = $ac_status" >&5 + echo "$as_me:7936: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -10727,7 +10729,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10730 "configure" +#line 10732 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -10823,7 +10825,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <<_LT_EOF -#line 10826 "configure" +#line 10828 "configure" #include "confdefs.h" #if HAVE_DLFCN_H @@ -11050,11 +11052,662 @@ CC="$lt_save_CC" # Only expand once: + +fail=0 +if test "${ac_cv_header_ext2fs_ext2fs_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for ext2fs/ext2fs.h" >&5 +$as_echo_n "checking for ext2fs/ext2fs.h... " >&6; } +if test "${ac_cv_header_ext2fs_ext2fs_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_ext2fs_ext2fs_h" >&5 +$as_echo "$ac_cv_header_ext2fs_ext2fs_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking ext2fs/ext2fs.h usability" >&5 +$as_echo_n "checking ext2fs/ext2fs.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <ext2fs/ext2fs.h> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking ext2fs/ext2fs.h presence" >&5 +$as_echo_n "checking ext2fs/ext2fs.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <ext2fs/ext2fs.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: ext2fs/ext2fs.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: ext2fs/ext2fs.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: ext2fs/ext2fs.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: ext2fs/ext2fs.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: ext2fs/ext2fs.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: ext2fs/ext2fs.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: ext2fs/ext2fs.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: ext2fs/ext2fs.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: ext2fs/ext2fs.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: ext2fs/ext2fs.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: ext2fs/ext2fs.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: ext2fs/ext2fs.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: ext2fs/ext2fs.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: ext2fs/ext2fs.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: ext2fs/ext2fs.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: ext2fs/ext2fs.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for ext2fs/ext2fs.h" >&5 +$as_echo_n "checking for ext2fs/ext2fs.h... " >&6; } +if test "${ac_cv_header_ext2fs_ext2fs_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_ext2fs_ext2fs_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_ext2fs_ext2fs_h" >&5 +$as_echo "$ac_cv_header_ext2fs_ext2fs_h" >&6; } + +fi +if test "x$ac_cv_header_ext2fs_ext2fs_h" = x""yes; then + : +else + fail=1 +fi + + +if test "${ac_cv_header_blkid_blkid_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for blkid/blkid.h" >&5 +$as_echo_n "checking for blkid/blkid.h... " >&6; } +if test "${ac_cv_header_blkid_blkid_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_blkid_blkid_h" >&5 +$as_echo "$ac_cv_header_blkid_blkid_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking blkid/blkid.h usability" >&5 +$as_echo_n "checking blkid/blkid.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <blkid/blkid.h> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking blkid/blkid.h presence" >&5 +$as_echo_n "checking blkid/blkid.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <blkid/blkid.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: blkid/blkid.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: blkid/blkid.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: blkid/blkid.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: blkid/blkid.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: blkid/blkid.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: blkid/blkid.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: blkid/blkid.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: blkid/blkid.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: blkid/blkid.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: blkid/blkid.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: blkid/blkid.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: blkid/blkid.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: blkid/blkid.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: blkid/blkid.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: blkid/blkid.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: blkid/blkid.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for blkid/blkid.h" >&5 +$as_echo_n "checking for blkid/blkid.h... " >&6; } +if test "${ac_cv_header_blkid_blkid_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_blkid_blkid_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_blkid_blkid_h" >&5 +$as_echo "$ac_cv_header_blkid_blkid_h" >&6; } + +fi +if test "x$ac_cv_header_blkid_blkid_h" = x""yes; then + : +else + fail=1 +fi + + +if test "${ac_cv_header_e2p_e2p_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for e2p/e2p.h" >&5 +$as_echo_n "checking for e2p/e2p.h... " >&6; } +if test "${ac_cv_header_e2p_e2p_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_e2p_e2p_h" >&5 +$as_echo "$ac_cv_header_e2p_e2p_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking e2p/e2p.h usability" >&5 +$as_echo_n "checking e2p/e2p.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <e2p/e2p.h> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking e2p/e2p.h presence" >&5 +$as_echo_n "checking e2p/e2p.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <e2p/e2p.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: e2p/e2p.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: e2p/e2p.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: e2p/e2p.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: e2p/e2p.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: e2p/e2p.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: e2p/e2p.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: e2p/e2p.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: e2p/e2p.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: e2p/e2p.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: e2p/e2p.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: e2p/e2p.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: e2p/e2p.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: e2p/e2p.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: e2p/e2p.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: e2p/e2p.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: e2p/e2p.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for e2p/e2p.h" >&5 +$as_echo_n "checking for e2p/e2p.h... " >&6; } +if test "${ac_cv_header_e2p_e2p_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_e2p_e2p_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_e2p_e2p_h" >&5 +$as_echo "$ac_cv_header_e2p_e2p_h" >&6; } + +fi +if test "x$ac_cv_header_e2p_e2p_h" = x""yes; then + : +else + fail=1 +fi + + +if test "${ac_cv_header_uuid_uuid_h+set}" = set; then + { $as_echo "$as_me:$LINENO: checking for uuid/uuid.h" >&5 +$as_echo_n "checking for uuid/uuid.h... " >&6; } +if test "${ac_cv_header_uuid_uuid_h+set}" = set; then + $as_echo_n "(cached) " >&6 +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_uuid_uuid_h" >&5 +$as_echo "$ac_cv_header_uuid_uuid_h" >&6; } +else + # Is the header compilable? +{ $as_echo "$as_me:$LINENO: checking uuid/uuid.h usability" >&5 +$as_echo_n "checking uuid/uuid.h usability... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <uuid/uuid.h> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_header_compiler=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } + +# Is the header present? +{ $as_echo "$as_me:$LINENO: checking uuid/uuid.h presence" >&5 +$as_echo_n "checking uuid/uuid.h presence... " >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <uuid/uuid.h> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } >/dev/null && { + test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || + test ! -s conftest.err + }; then + ac_header_preproc=yes +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { $as_echo "$as_me:$LINENO: WARNING: uuid/uuid.h: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: uuid/uuid.h: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: uuid/uuid.h: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: uuid/uuid.h: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { $as_echo "$as_me:$LINENO: WARNING: uuid/uuid.h: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: uuid/uuid.h: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: uuid/uuid.h: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: uuid/uuid.h: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: uuid/uuid.h: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: uuid/uuid.h: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: uuid/uuid.h: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: uuid/uuid.h: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: uuid/uuid.h: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: uuid/uuid.h: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: uuid/uuid.h: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: uuid/uuid.h: in the future, the compiler will take precedence" >&2;} + + ;; +esac +{ $as_echo "$as_me:$LINENO: checking for uuid/uuid.h" >&5 +$as_echo_n "checking for uuid/uuid.h... " >&6; } +if test "${ac_cv_header_uuid_uuid_h+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_cv_header_uuid_uuid_h=$ac_header_preproc +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_uuid_uuid_h" >&5 +$as_echo "$ac_cv_header_uuid_uuid_h" >&6; } + +fi +if test "x$ac_cv_header_uuid_uuid_h" = x""yes; then + : +else + fail=1 +fi + + +test $fail = 1 && +{ { $as_echo "$as_me:$LINENO: error: You must install the develop packages \"ext2fs , blkid , e2p , uuid\" to build ext4magic" >&5 +$as_echo "$as_me: error: You must install the develop packages \"ext2fs , blkid , e2p , uuid\" to build ext4magic" >&2;} + { (exit 1); exit 1; }; } + +if pkg-config --exists 'ext2fs < 1.41.9' ; then +{ { $as_echo "$as_me:$LINENO: error: You must have ext2fs version >= 1.41.9 to build ext4magic" >&5 +$as_echo "$as_me: error: You must have ext2fs version >= 1.41.9 to build ext4magic" >&2;} + { (exit 1); exit 1; }; } +fi + +fail=0 +{ $as_echo "$as_me:$LINENO: checking for library containing magic_buffer" >&5 +$as_echo_n "checking for library containing magic_buffer... " >&6; } +if test "${ac_cv_search_magic_buffer+set}" = set; then + $as_echo_n "(cached) " >&6 +else + ac_func_search_save_LIBS=$LIBS +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 magic_buffer (); +int +main () +{ +return magic_buffer (); + ; + return 0; +} +_ACEOF +for ac_lib in '' magic; do + if test -z "$ac_lib"; then + ac_res="none required" + else + ac_res=-l$ac_lib + LIBS="-l$ac_lib $ac_func_search_save_LIBS" + fi + 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 ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$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 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + ac_cv_search_magic_buffer=$ac_res +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -rf conftest.dSYM +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext + if test "${ac_cv_search_magic_buffer+set}" = set; then + break +fi +done +if test "${ac_cv_search_magic_buffer+set}" = set; then + : +else + ac_cv_search_magic_buffer=no +fi +rm conftest.$ac_ext +LIBS=$ac_func_search_save_LIBS +fi +{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_magic_buffer" >&5 +$as_echo "$ac_cv_search_magic_buffer" >&6; } +ac_res=$ac_cv_search_magic_buffer +if test "$ac_res" != no; then + test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" + +else + fail=1 +fi + +test $fail = 1 && +{ { $as_echo "$as_me:$LINENO: error: The library libmagic.so not found, install the package \"file\" to build ext4magic" >&5 +$as_echo "$as_me: error: The library libmagic.so not found, install the package \"file\" to build ext4magic" >&2;} + { (exit 1); exit 1; }; } + + + # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then enableval=$enable_debug; if test "$GCC" = "yes"; then CPPFLAGS="$CPPFLAGS -DDEBUG"; fi fi +# Check whether --enable-debug-magic was given. +if test "${enable_debug_magic+set}" = set; then + enableval=$enable_debug_magic; if test "$GCC" = "yes"; then CPPFLAGS="$CPPFLAGS -DDEBUG_MAGIC_SCAN"; fi +fi + # Check whether --enable-file-attr was given. if test "${enable_file_attr+set}" = set; then enableval=$enable_file_attr; if test "$GCC" = "yes"; then CPPFLAGS="$CPPFLAGS -DFILE_ATTR"; fi diff --git a/configure.in b/configure.in index 33b332e..84d5571 100644 --- a/configure.in +++ b/configure.in @@ -1,13 +1,35 @@ AC_INIT(configure.in) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(ext4magic, 0.1.4) +AM_INIT_AUTOMAKE(ext4magic, 0.2.0-pv0) AC_LANG_C AC_PROG_CC AM_PROG_LIBTOOL + +fail=0 +AC_CHECK_HEADER([ext2fs/ext2fs.h],[],[fail=1]) +AC_CHECK_HEADER([blkid/blkid.h],[],[fail=1]) +AC_CHECK_HEADER([e2p/e2p.h],[],[fail=1]) +AC_CHECK_HEADER([uuid/uuid.h],[],[fail=1]) +test $fail = 1 && +AC_MSG_ERROR([You must install the develop packages "ext2fs , blkid , e2p , uuid" to build ext4magic]) + +if pkg-config --exists 'ext2fs < 1.41.9' ; then +AC_MSG_ERROR([You must have ext2fs version >= 1.41.9 to build ext4magic]) +fi + +fail=0 +AC_SEARCH_LIBS([magic_buffer], [magic], [], [fail=1]) +test $fail = 1 && +AC_MSG_ERROR([The library libmagic.so not found, install the package "file" to build ext4magic]) + + + AC_ARG_ENABLE(debug,[ --enable-debug Turn on debugging ], [if test "$GCC" = "yes"; then CPPFLAGS="$CPPFLAGS -DDEBUG"; fi]) +AC_ARG_ENABLE(debug-magic,[ --enable-debug-magic Turn on debugging magic-scan-engine ], + [if test "$GCC" = "yes"; then CPPFLAGS="$CPPFLAGS -DDEBUG_MAGIC_SCAN"; fi]) AC_ARG_ENABLE(file-attr,[ --enable-file-attr enable restore of file attribute ], [if test "$GCC" = "yes"; then CPPFLAGS="$CPPFLAGS -DFILE_ATTR"; fi]) diff --git a/src/block.c b/src/block.c index b1db943..66bad23 100644 --- a/src/block.c +++ b/src/block.c @@ -27,7 +27,6 @@ #endif -//#include <ext2fs/ext2fs.h> #include "ext2fsP.h" #include "block.h" #include "journal.h" @@ -56,7 +55,7 @@ struct block_context { //#ifdef BLOCK_FLAG_READ_ONLY -#include <ext2fs/ext3_extents.h> +//#include <ext2fs/ext3_extents.h> struct extent_path { char *buf; int entries; diff --git a/src/block.h b/src/block.h index 9145664..97098c9 100644 --- a/src/block.h +++ b/src/block.h @@ -1,6 +1,5 @@ #ifndef BLOCK_H #define BLOCK_H - #include <ext2fs/ext2fs.h> diff --git a/src/ext4magic.8 b/src/ext4magic.8 index f9b05da..076f1a0 100644 --- a/src/ext4magic.8 +++ b/src/ext4magic.8 @@ -1,7 +1,13 @@ -.TH ext4magic 8 "Jul 2010" "version 0.1.3" "Administrations Tool" +.TH ext4magic 8 "Sep 2010" "version 0.2.0" "Administrations Tool" .SH NAME ext4magic \- allows to recover deleted files on ext3/4 filesystems .SH SYNOPSIS +.B ext4magic \-M +[\-j <journal_file>] [\-d <target_dir>] <filesystem> + +.B ext4magic \-m +[\-j <journal_file>] [\-d <target_dir>] <filesystem> + .B ext4magic [\-S|\-J|\-H|\-V|\-T] [\-x] [\-j <journal_file>] [\-B n|\-I n|\-f <file_name>|\-i <input_list>] [\-t n|[[\-a n][\-b n]]] [\-d <target_dir>] [\-R|\-r|\-L|\-l] [\-Q] <filesystem> @@ -30,6 +36,24 @@ Direct use of the Journal of a currently read-write open filesystem produce read .SH OPTIONS .B +Magic Options: (new and experimental) +These options are for a mulit-stage recover especially for file restore after delete the file system. These functions are currently only available for ext3. +Umount the file system directly after an accidentally destroy and use these options with a copy of this file system. These functions are not adequately tested in this version and can include a lot of bugs. + +.TP +.B +\-M +Try to recover all files. This option should be used if the entire Filessytem was deleted. +.TP +.B +\-m +Try to recover only all deleted files. Use this option with a partially deleted Filesystem. + + + + +.PP +.B Information Options: These options generate generic status information from the filesystem and the Journal. @@ -488,6 +512,12 @@ try to restore all files deleted last 24 hours. Write in directory "./RECOVERDIR .B + # ext4magic /dev/sda3 -M -d /home/recover + +try the new experimental multi-stage recover of all files after the filesystem is deleted with a "rm -rf *" . Write the files to "/home/recover". + + +.B # ext4magic /dev/sda3 -RQ -f user1/Dokuments -a 1274210280 -b 1274211280 -d /mnt/testrecover try to restore the directory tree "user1/Dokuments/". The "-b" timestamp you must set just before deleting files, the "-a" timestamp prevents found old file versions. This will only work well, if you've there created or deleted files bevor the "-b" timestamp. Write in directory "/mnt/testrecover/" diff --git a/src/ext4magic.c b/src/ext4magic.c index 34b3c24..50029c0 100644 --- a/src/ext4magic.c +++ b/src/ext4magic.c @@ -247,7 +247,7 @@ errout: //subfunction for main void print_modus_error(){ - char message0[] = "Warning: only input of one modus allowed [ -R | -r | -L | -l | -H ]\n"; + char message0[] = "Invalide parameter : only input of one modus allowed [ -M | -m | -R | -r | -L | -l | -H ]\n"; fprintf(stderr,"%s",message0); } @@ -258,8 +258,11 @@ int main(int argc, char *argv[]){ char* progname = argv[0]; int retval, exitval; char defaultdir[] = "RECOVERDIR" ; +time_t help_time; //FIXME : usage is not correct -const char *usage = "ext4magic [-S|-J|-H|-V|-T] [-x] [-j <journal_file>] [-B n|-I n|-f <file_name>|-i <input_list>] [-t n|[[-a n][-b n]]] [-d <target_dir>] [-R|-r|-L|-l] [-Q] <filesystem>"; +const char *usage = "\next4magic -M [-j <journal_file>] [-d <target_dir>] <filesystem> \n\ +ext4magic -m [-j <journal_file>] [-d <target_dir>] <filesystem> \n\ +ext4magic [-S|-J|-H|-V|-T] [-x] [-j <journal_file>] [-B n|-I n|-f <file_name>|-i <input_list>] [-t n|[[-a n][-b n]]] [-d <target_dir>] [-R|-r|-L|-l] [-Q] <filesystem>"; int c; int open_flags = EXT2_FLAG_SOFTSUPP_FEATURES; int exit_status = 0 ; @@ -293,21 +296,43 @@ if ( argc < 3 ) return EXIT_FAILURE; } - { + // set default Time from "now -1 day" to "now" - time_t help_time; - time( &help_time ); - t_before = (__u32) help_time; - t_after = t_before - 86400 ; - } + +time( &help_time ); +t_before = (__u32) help_time; +t_after = t_before - 86400 ; + // decode arguments -while ((c = getopt (argc, argv, "TJRLlrQSxi:t:j:f:Vd:B:b:a:I:H")) != EOF) { +while ((c = getopt (argc, argv, "TJRMLlmrQSxi:t:j:f:Vd:B:b:a:I:H")) != EOF) { switch (c) { case 'M': //not active, still in development + if(mode & RECOVER_INODE){ + print_modus_error(); + exitval = EXIT_FAILURE ; + goto errout; + } + mode |= RECOVER_INODE; + mode |= READ_JOURNAL; + recovermodus = RECOV_ALL ; + magicscan = 1; + break; + + case 'm': + //not active, still in development + if(mode & RECOVER_INODE){ + print_modus_error(); + exitval = EXIT_FAILURE ; + goto errout; + } + mode |= RECOVER_INODE; + mode |= READ_JOURNAL; + recovermodus = RECOV_DEL ; magicscan = 1; break; + case 'S': mode |= PRINT_SUPERBLOCK ; break; @@ -315,7 +340,8 @@ while ((c = getopt (argc, argv, "TJRLlrQSxi:t:j:f:Vd:B:b:a:I:H")) != EOF) { case 'H': if(mode & RECOVER_INODE){ print_modus_error(); - break; + exitval = EXIT_FAILURE ; + goto errout; } mode |= RECOVER_INODE; mode |= PRINT_HISTOGRAM ; @@ -324,7 +350,8 @@ while ((c = getopt (argc, argv, "TJRLlrQSxi:t:j:f:Vd:B:b:a:I:H")) != EOF) { case 'R': if(mode & RECOVER_INODE){ print_modus_error(); - break; + exitval = EXIT_FAILURE ; + goto errout; } mode |= RECOVER_INODE; mode |= READ_JOURNAL; @@ -334,7 +361,8 @@ while ((c = getopt (argc, argv, "TJRLlrQSxi:t:j:f:Vd:B:b:a:I:H")) != EOF) { case 'r': if(mode & RECOVER_INODE){ print_modus_error(); - break; + exitval = EXIT_FAILURE ; + goto errout; } mode |= RECOVER_INODE; mode |= READ_JOURNAL; @@ -344,7 +372,8 @@ while ((c = getopt (argc, argv, "TJRLlrQSxi:t:j:f:Vd:B:b:a:I:H")) != EOF) { case 'L': if(mode & RECOVER_INODE){ print_modus_error(); - break; + exitval = EXIT_FAILURE ; + goto errout; } mode |= RECOVER_INODE; mode |= READ_JOURNAL; @@ -354,7 +383,8 @@ while ((c = getopt (argc, argv, "TJRLlrQSxi:t:j:f:Vd:B:b:a:I:H")) != EOF) { case 'l': if(mode & RECOVER_INODE){ print_modus_error(); - break; + exitval = EXIT_FAILURE ; + goto errout; } mode |= RECOVER_INODE; mode |= READ_JOURNAL; @@ -572,8 +602,16 @@ while ((c = getopt (argc, argv, "TJRLlrQSxi:t:j:f:Vd:B:b:a:I:H")) != EOF) { // check any parameter an options // check time option if (magicscan){ - printf("Warning: Activate magic scan, may be some command line options ignored\n"); + printf("Warning: Activate magic scan function, may be some command line options ignored\n"); + mode &= MASK_MAGIC_SCAN; + inode_nr = EXT2_ROOT_INO; + t_before = (__u32) help_time; + if ((!(mode & INPUT_TIME)) || (t_after == t_before - 86400)){ + t_after = get_last_delete_time(current_fs); + mode |= INPUT_TIME; } +} + if (mode & INPUT_TIME){ @@ -888,7 +926,10 @@ if ((mode & COMMAND_INODE) && (mode & RECOVER_INODE)) // I think imap is no longer needed from here, free the allocated memory ext2fs_free_inode_bitmap(imap); imap = NULL; - magic_block_scan(des_dir, t_after); + if (!(current_fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS)) + magic_block_scan3(des_dir, t_after); + else + printf("The MAGIC Funktion is currently only for ext3 filesystems available\n"); } clear_dir_list(dir); } @@ -953,9 +994,9 @@ exitval = EXIT_SUCCESS; errout: if (current_fs) { -//FIXME in development -/* if (d_bmap){ - struct ext2fs_struct_loc_generic_bitmap *d_bmap; +/*//FIXME in development + if (bmap){ + struct ext2fs_struct_loc_generic_bitmap *d_bmap = bmap ; blockhex(stdout,(void*)d_bmap->bitmap,0,current_fs->super->s_blocks_count >> 3); }*/ if (imap) ext2fs_free_inode_bitmap(imap); @@ -970,6 +1011,8 @@ errout: } if (pathname) free(pathname); clear_link_stack(); + if (! exitval) + printf("ext4magic : EXIT_SUCCESS\n"); return exitval; } //------------------------------------------------------------------------------------------------------------------------------- diff --git a/src/ext4magic.h b/src/ext4magic.h index 31442f4..3ec5e4d 100644 --- a/src/ext4magic.h +++ b/src/ext4magic.h @@ -35,6 +35,7 @@ #define RECOVER_INODE 0x2000 #define RECOVER_LIST 0x4000 +#define MASK_MAGIC_SCAN 0x3100 // journal status flags #define JOURNAL_OPEN 0 #define JOURNAL_CLOSE 1 diff --git a/src/file_type.c b/src/file_type.c index 1f880f4..1e02cb9 100644 --- a/src/file_type.c +++ b/src/file_type.c @@ -34,9 +34,12 @@ #define ext4magic_be64_to_cpu(x) ext2fs_swab64((x)) #endif -extern ext2_filsys current_fs ; +//#define DEBUG_MAGIC_SCAN + +extern ext2_filsys current_fs ; +// index of the files corresponding magic result strings int ident_file(struct found_data_t *new, __u32 *scan, char *magic_buf, char *buf){ //Please do not modify the following lines. @@ -121,7 +124,9 @@ int ident_file(struct found_data_t *new, __u32 *scan, char *magic_buf, char *buf p_search++; } if(!flag) minor=255; +#ifdef DEBUG_MAGIC_SCAN printf("major : %d minor : %d\n", major,minor); +#endif *scan = (major <<8)| minor; return 1; } diff --git a/src/hard_link_stack.c b/src/hard_link_stack.c index b7df7ed..fde1609 100644 --- a/src/hard_link_stack.c +++ b/src/hard_link_stack.c @@ -61,7 +61,7 @@ errout: } - +// subfunction for check_find_dir() use in stage 2 of magical recover int rename_hardlink_path(char *old, char *neu){ char *newname; char *endname; @@ -81,7 +81,6 @@ int rename_hardlink_path(char *old, char *neu){ //#ifdef DEBUG fprintf(stderr,"HL-DB change %s -> %s\n",old,neu); //#endif - } head.pointer = head.pointer->next; } @@ -108,6 +107,7 @@ char* check_link_stack(ext2_ino_t inode_nr, __u32 generation){ } + static void del_link_stack(struct link_entry* entry){ if(entry->name) free(entry->name); @@ -127,6 +127,7 @@ static void del_link_stack(struct link_entry* entry){ } + int match_link_stack(ext2_ino_t inode_nr, __u32 generation){ int retval = 1; if ((head.pointer->inode_nr == inode_nr) && (head.pointer->generation == generation)){ @@ -139,6 +140,7 @@ return retval; } + void clear_link_stack(){ int d_count = 0 ; diff --git a/src/imap_search.c b/src/imap_search.c index b86ebb9..421ec9d 100644 --- a/src/imap_search.c +++ b/src/imap_search.c @@ -31,7 +31,6 @@ extern ext2_filsys current_fs; - // search inode by use imap (step1: flag 1 = only directory ; step2: flag 0 = only file) static void search_imap_inode(char* des_dir, __u32 t_after, __u32 t_before, int flag) { @@ -204,4 +203,3 @@ void imap_search(char* des_dir, __u32 t_after, __u32 t_before){ return; } - diff --git a/src/inode.c b/src/inode.c index 87c07ba..bd098aa 100644 --- a/src/inode.c +++ b/src/inode.c @@ -896,7 +896,7 @@ return retval; - +//create a new inode struct ext2_inode_large* new_inode(){ struct ext2_inode_large *inode; __u32 a_time; @@ -919,7 +919,7 @@ return inode; } - +//add a block to inode int inode_add_block(struct ext2_inode_large* inode , blk_t blk , __u32 size) { int i = 0 ; unsigned long long i_size; @@ -949,7 +949,7 @@ return 1; } - +//add the ext3 indirect Blocks to the inode blk_t inode_add_meta_block(struct ext2_inode_large* inode , blk_t blk, blk_t *last, char *buf ){ blk_t b_blk,block_count, next; blk_t count=0; diff --git a/src/inode.h b/src/inode.h index e3406f4..bcc0089 100644 --- a/src/inode.h +++ b/src/inode.h @@ -66,8 +66,10 @@ int read_journal_inode( ext2_ino_t, struct ext2_inode*, __u32);// get the first int read_time_match_inode( ext2_ino_t, struct ext2_inode*, __u32);// get the first Journal Inode by time_stamp struct ring_buf* get_j_inode_list(struct ext2_super_block*, ext2_ino_t);//fill all inode found in the Journal in the inode-ringbuffer -struct ext2_inode_large* new_inode(); -int inode_add_block(struct ext2_inode_large* , blk_t , __u32); +//functions for the magic scanner +struct ext2_inode_large* new_inode(); //create a new inode +int inode_add_block(struct ext2_inode_large* , blk_t , __u32); //add a block to inode +blk_t inode_add_meta_block(struct ext2_inode_large*, blk_t, blk_t*, char* ); //add the ext3 indirect Blocks to the inode #endif diff --git a/src/journal.c b/src/journal.c index 07006fc..e26d66b 100644 --- a/src/journal.c +++ b/src/journal.c @@ -834,7 +834,7 @@ return sum; -//create and init the the journal block bitmap +//create and init the journal block bitmap //return the count of all blockbitmap copies or 0 int init_block_bitmap_list(ext2fs_block_bitmap *d_bmap, __u32 t_after){ __u32 t; @@ -906,8 +906,6 @@ int next_block_bitmap(ext2fs_block_bitmap d_bmap){ if (jbbm.pointer->transaction < jbbm.first_trans) return 0; -// printf(" Transaction: %u ; Minimum ist %u \n", jbbm.pointer->transaction,jbbm.first_trans); - fs_bitmap = (struct ext2fs_struct_loc_generic_bitmap*) current_fs->block_map; df_bitmap = (struct ext2fs_struct_loc_generic_bitmap*) d_bmap; ext2fs_clear_block_bitmap(d_bmap); diff --git a/src/journal.h b/src/journal.h index 9a05fbc..3f3648a 100644 --- a/src/journal.h +++ b/src/journal.h @@ -29,6 +29,7 @@ typedef struct journal_descriptor_tag_s __u32 transaction; /* Transaction Sequence*/ } journal_descriptor_tag_t; + //struct for cache the block bitmap data typedef struct journal_bitmap_tag_s { @@ -38,6 +39,8 @@ typedef struct journal_bitmap_tag_s } journal_bitmap_tag_t; + +//head struct for collect the Block Bitmaps of Journal struct j_bitmap_list_t { int count; @@ -53,6 +56,7 @@ struct j_bitmap_list_t }; + void dump_journal_superblock( void); //print journal superblock extern int journal_open(char* , int );// open an extract the blocklist from journal extern int journal_close(void); // close the journal (last function in main() if the journal open) diff --git a/src/lookup_local.c b/src/lookup_local.c index b281507..9f7075c 100644 --- a/src/lookup_local.c +++ b/src/lookup_local.c @@ -26,7 +26,7 @@ #endif #include <ext2fs/ext2fs.h> -#include <ext2fs/ext2_io.h> +//#include <ext2fs/ext2_io.h> #include "ext2fsP.h" #include <ctype.h> #include <time.h> @@ -484,10 +484,7 @@ void list_dir2(ext2_ino_t ino, struct ext2_inode *inode) } - - //-------------------------------------------------- -// // local sub function // load dir-index in a dir_list struct dir_list_head_t* get_dir3(struct ext2_inode* d_inode,ext2_ino_t path_ino, ext2_ino_t ino, diff --git a/src/magic.h b/src/magic.h index a664e9a..f97122b 100644 --- a/src/magic.h +++ b/src/magic.h @@ -24,6 +24,10 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ + +// this is a copie from file-5.03. (Please do not change here.) +// We need this because not all Distibution have a DEVEL packages for libmagic. + #ifndef _MAGIC_H #define _MAGIC_H diff --git a/src/magic_block_scan.c b/src/magic_block_scan.c index 7080bf6..b1e6599 100644 --- a/src/magic_block_scan.c +++ b/src/magic_block_scan.c @@ -33,13 +33,13 @@ #define MAX_RANGE 16 - +//#define DEBUG_MAGIC_SCAN extern ext2_filsys current_fs ; ext2fs_block_bitmap d_bmap = NULL ; -__u32 get_block_len(char *buf){ +static __u32 get_block_len(char *buf){ int len = current_fs->blocksize -1; while ((len >= 0) && (!(*(buf + len)))) @@ -49,7 +49,7 @@ __u32 get_block_len(char *buf){ -struct found_data_t* free_file_data(struct found_data_t* old){ +static struct found_data_t* free_file_data(struct found_data_t* old){ if(old->inode) free(old->inode); if(old->scan_result) free(old->scan_result); if(old->name) free(old->name); @@ -60,7 +60,7 @@ struct found_data_t* free_file_data(struct found_data_t* old){ -struct found_data_t* new_file_data(blk_t blk,__u32 scan,char *magic_buf, char* buf, __u32 *f){ +static struct found_data_t* new_file_data(blk_t blk,__u32 scan,char *magic_buf, char* buf, __u32 *f){ struct found_data_t *new; int str_len; __u32 name_len; @@ -107,7 +107,7 @@ return new; -struct found_data_t* recover_file_data(char *des_dir, struct found_data_t* this, __u32 *follow){ +static struct found_data_t* recover_file_data(char *des_dir, struct found_data_t* this, __u32 *follow){ recover_file(des_dir,"MAGIC_3",this->name,(struct ext2_inode*)this->inode, 0 , 1); free_file_data(this); *follow = 0; @@ -117,8 +117,10 @@ struct found_data_t* recover_file_data(char *des_dir, struct found_data_t* this, -struct found_data_t* forget_file_data(struct found_data_t* this, __u32 *p_follow){ +static struct found_data_t* forget_file_data(struct found_data_t* this, __u32 *p_follow){ +#ifdef DEBUG_MAGIC_SCAN printf("TRASH : %s : leng %lu : begin %lu\n", this->name, this->inode->i_size , this->first); +#endif free_file_data(this); *p_follow = 0; return NULL; @@ -127,7 +129,7 @@ struct found_data_t* forget_file_data(struct found_data_t* this, __u32 *p_follow -__u32 add_file_data(struct found_data_t* this, blk_t blk, __u32 scan ,__u32 *f){ +static __u32 add_file_data(struct found_data_t* this, blk_t blk, __u32 scan ,__u32 *f){ __u32 retval = 0; if (inode_add_block(this->inode , blk , current_fs->blocksize)){ @@ -140,7 +142,7 @@ return *f ; -int file_data_correct_size(struct found_data_t* this, int size){ +static int file_data_correct_size(struct found_data_t* this, int size){ unsigned long long i_size; int flag=0; @@ -156,7 +158,7 @@ int file_data_correct_size(struct found_data_t* this, int size){ -int check_file_data_end(struct found_data_t* this,char *buf){ +static int check_file_data_end(struct found_data_t* this,char *buf){ int size; int ret = 0; @@ -172,7 +174,7 @@ int check_file_data_end(struct found_data_t* this,char *buf){ //????? -int check_data_passage(char *a_buf, char *b_buf){ +static int check_data_passage(char *a_buf, char *b_buf){ int i, blocksize; int sum[4][2]; @@ -181,63 +183,18 @@ int check_data_passage(char *a_buf, char *b_buf){ } -//FIXME obsolete: must switch to FLAG=1 of func() of the filetype -int check_file_data_possible(struct found_data_t* this, __u32 scan ,char *buf){ + +static int check_file_data_possible(struct found_data_t* this, __u32 scan ,char *buf){ int ret = 0; int size ; ret = this->func(buf, &size ,scan ,1 , this); -/* switch (this->scan & M_IS_FILE){ -// case (M_TXT | M_APPLI) : - case M_TXT : - if (scan & M_TXT) ret = 1; - break; - case M_VIDEO : - case M_AUDIO : - case M_IMAGE : - if (!(scan & M_IS_META)) ret = 1; - break; - case M_APPLI : - if (!(scan & M_IS_META)) ret = 1; - break; - } - - if (!(this->scan & M_IS_FILE)) - ret = 1; */ return ret; } -int add_ext3_file_meta_data(struct found_data_t* this, char *buf, blk_t blk){ - blk_t next_meta; - blk_t last_data = 0; - next_meta = inode_add_meta_block(this->inode , blk, &last_data, buf ); - this->last = last_data; - - if (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta)))){ - io_channel_read_blk ( current_fs->io, next_meta, 1, buf ); - - if (check_meta3_block(buf, blk, get_block_len(buf))){ - next_meta = inode_add_meta_block(this->inode , next_meta , &last_data, buf ); - this->last = last_data; - - if (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta)))){ - io_channel_read_blk ( current_fs->io, next_meta, 1, buf ); - - if (check_meta3_block(buf, blk, get_block_len(buf))){ - next_meta = inode_add_meta_block(this->inode , next_meta , &last_data, buf ); - this->last = last_data; - } - } - } - } -return (next_meta) ? 0 : 1 ; -} - - - -int check_indirect_meta3(char *block_buf){ +static int check_indirect_meta3(char *block_buf){ blk_t *pb_block; blk_t last; int i = current_fs->blocksize/sizeof(blk_t); @@ -262,7 +219,7 @@ int check_indirect_meta3(char *block_buf){ -int check_meta3_block(char *block_buf, blk_t blk, __u32 size){ +static int check_meta3_block(char *block_buf, blk_t blk, __u32 size){ blk_t block, *pb_block; int i,j ; @@ -293,7 +250,7 @@ int check_meta3_block(char *block_buf, blk_t blk, __u32 size){ -int check_meta4_block(char *block_buf, blk_t blk, __u32 size){ +static int check_meta4_block(char *block_buf, blk_t blk, __u32 size){ __u16 *p_h16; __u16 h16; @@ -313,7 +270,7 @@ int check_meta4_block(char *block_buf, blk_t blk, __u32 size){ -int check_dir_block(char *block_buf, blk_t blk, __u32 size){ +static int check_dir_block(char *block_buf, blk_t blk, __u32 size){ struct ext2_dir_entry_2 *dir_entry; ext2_ino_t inode_nr; __u16 len; @@ -340,6 +297,60 @@ int check_dir_block(char *block_buf, blk_t blk, __u32 size){ } + +static int check_acl_block(char *block_buf, blk_t blk, __u32 size){ + __u32 *p32; + int i; + + p32 = (__u32*)block_buf; + if ((!(*p32)) || (ext2fs_le32_to_cpu(*p32) & (~ 0xEA030000))) + return 0; + p32 += 2; + if ((!(*p32)) || (ext2fs_le32_to_cpu(*p32) > 0xff)) + return 0; + p32++; + if (! (*p32)) + return 0; + p32++; + for (i = 0; i<4; i++){ + if (*p32) + return 0; + p32++; + } + return (size > (current_fs->blocksize-32)) ? 1 : 0; +} + + + + +static int add_ext3_file_meta_data(struct found_data_t* this, char *buf, blk_t blk){ + blk_t next_meta; + blk_t last_data = 0; + next_meta = inode_add_meta_block(this->inode , blk, &last_data, buf ); + this->last = last_data; + + if (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta)))){ + io_channel_read_blk ( current_fs->io, next_meta, 1, buf ); + + if (check_meta3_block(buf, blk, get_block_len(buf))){ + next_meta = inode_add_meta_block(this->inode , next_meta , &last_data, buf ); + this->last = last_data; + + if (next_meta > 10 && (ext2fs_test_block_bitmap ( d_bmap, next_meta) && (! ext2fs_test_block_bitmap( bmap, next_meta)))){ + io_channel_read_blk ( current_fs->io, next_meta, 1, buf ); + + if (check_meta3_block(buf, blk, get_block_len(buf))){ + next_meta = inode_add_meta_block(this->inode , next_meta , &last_data, buf ); + this->last = last_data; + } + } + } + } +return (next_meta) ? 0 : 1 ; +} + + + // skip not of interest blocks : return 1 if skiped static int skip_block(blk_t *p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_bmap ){ struct ext2fs_struct_loc_generic_bitmap *p_bmap; @@ -359,7 +370,7 @@ return flag; //magic scanner -int magic_check_block(char* buf,magic_t cookie , magic_t cookie_f, char *magic_buf, __u32 size, blk_t blk){ +static int magic_check_block(char* buf,magic_t cookie , magic_t cookie_f, char *magic_buf, __u32 size, blk_t blk){ //int count = size-1; int count = current_fs->blocksize -1 ; int *i , len; @@ -372,10 +383,10 @@ int magic_check_block(char* buf,magic_t cookie , magic_t cookie_f, char *magic_b strncpy(text,magic_buffer(cookie_f,buf , size),99); strncpy(magic_buf, magic_buffer(cookie , buf , size),99); while (count >= 0 && (*(buf+count) == 0)) count-- ; - +#ifdef DEBUG_MAGIC_SCAN printf("Scan Result : %s %d\n", magic_buf , count+1) ; printf("RESULT : %s \n",text); - +#endif if (!strncmp(text,"data",4)){ if (count == -1) { @@ -409,6 +420,10 @@ int magic_check_block(char* buf,magic_t cookie , magic_t cookie_f, char *magic_b retval = M_DIR ; goto out; } + if (check_acl_block(buf, blk, count+1)){ + retval = M_ACL ; + goto out ; + } } if (retval & M_DATA) @@ -489,9 +504,10 @@ int magic_check_block(char* buf,magic_t cookie , magic_t cookie_f, char *magic_b out: +#ifdef DEBUG_MAGIC_SCAN printf("BLOCK_SCAN : 0x%08x\n",retval & 0xffffe000); blockhex(stdout,buf,0,(count < (64)) ? count : 64 ); - +#endif retval |= (count+1); return retval; @@ -500,7 +516,7 @@ out: -struct found_data_t* soft_border(char *des_dir, char *buf, struct found_data_t* file_data, __u32* follow, blk_t blk){ +static struct found_data_t* soft_border(char *des_dir, char *buf, struct found_data_t* file_data, __u32* follow, blk_t blk){ if ( check_file_data_end(file_data, buf )) file_data = recover_file_data(des_dir, file_data, follow); else{ @@ -511,14 +527,16 @@ return file_data; } -int get_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_bmap, char* buf){ +static int get_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_bmap, char* buf){ blk_t begin; blk_t end; int count=1; for (begin = *p_blk; begin < ds_bmap->real_end ; begin++){ - if((!(begin & 0x7)) && skip_block(&begin, ds_bmap)) + if((!(begin & 0x7)) && skip_block(&begin, ds_bmap)){ +#ifdef DEBUG_MAGIC_SCAN printf("jump to %d \n",begin); - +#endif + } if (ext2fs_test_block_bitmap ( d_bmap, begin) && (! ext2fs_test_block_bitmap( bmap, begin))) break; } @@ -526,7 +544,7 @@ int get_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_bmap, ch if (begin >= ds_bmap->real_end) return 0; - for (end = begin,count=1 ; count < MAX_RANGE ; ){ + for (end = begin,count=1 ; ((count < MAX_RANGE) && (end < ds_bmap->real_end)); ){ if (ext2fs_test_block_bitmap(d_bmap, end+1) && (! ext2fs_test_block_bitmap( bmap, end+1))){ end++; count++; @@ -544,15 +562,19 @@ return count; -int get_full_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_bmap, char* buf, blk_t* p_flag){ +static int get_full_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_bmap, char* buf, blk_t* p_flag){ blk_t begin; blk_t end; int count=0; int i; + errcode_t x; + for (begin = *p_blk; begin < ds_bmap->real_end ; begin++){ - if((!(begin & 0x7)) && skip_block(&begin, ds_bmap)) + if((!(begin & 0x7)) && skip_block(&begin, ds_bmap)){ +#ifdef DEBUG_MAGIC_SCAN printf("jump to %d \n",begin); - +#endif + } if (ext2fs_test_block_bitmap ( d_bmap, begin) && (! ext2fs_test_block_bitmap( bmap, begin))) break; } @@ -573,27 +595,29 @@ int get_full_range(blk_t* p_blk ,struct ext2fs_struct_loc_generic_bitmap *ds_bma else { if (i){ if (io_channel_read_blk ( current_fs->io, begin , i, buf )){ - fprintf(stderr,"ERROR: while read block %10u + %d\n",begin,count); + fprintf(stderr,"ERROR: while read block %10u + %d\n",begin,i); return 0; } + buf += (current_fs->blocksize *i); + begin = 0; + i = 0; } end++; - buf += (current_fs->blocksize *i); - begin = 0; - i = 0; } } *(p_blk+1) = end; - if (io_channel_read_blk ( current_fs->io, begin , i, buf )){ - fprintf(stderr,"ERROR: while read block %10u + %d\n",begin,count); - return 0; + if (i){ + if (io_channel_read_blk ( current_fs->io, begin , i, buf )){ + fprintf(stderr,"ERROR: while read block %10u + %d %ld\n",begin,i,count-1); + return 0; + } } return count-1; } -blk_t block_backward(blk_t blk , int count){ +static blk_t block_backward(blk_t blk , int count){ int i=count; while (i && blk){ if (ext2fs_test_block_bitmap(d_bmap, blk) && (! ext2fs_test_block_bitmap( bmap, blk))) @@ -606,8 +630,8 @@ blk_t block_backward(blk_t blk , int count){ -//magic_block_scan_main -int magic_block_scan(char* des_dir, __u32 t_after){ +//main of the magic_scan_engine for ext3 +int magic_block_scan3(char* des_dir, __u32 t_after){ magic_t cookie = 0; magic_t cookie_f = 0; struct ext2fs_struct_loc_generic_bitmap *ds_bmap; @@ -623,6 +647,7 @@ int blocksize, ds_retval,count,i,ret; __u32 scan,follow, size; +printf("MAGIC-3 :Start ext3-magic-scan search. Please wait, this may take a long time\n"); blocksize = current_fs->blocksize ; count = 0; blk[0] = 0; @@ -652,15 +677,19 @@ while (ds_retval){ count = get_range(blk ,ds_bmap, buf); while (count){ +#ifdef DEBUG_MAGIC_SCAN printf(" %d %d %d\n", blk[0],blk[1],count); +#endif for (i = 0; i< ((count>12) ? MAX_RANGE - 12 : count) ;i++){ scan = magic_check_block(buf+(i*blocksize), cookie, cookie_f , magic_buf , blocksize * ((count >=9) ? 9 : count) ,blk[0]+i); if(scan & (M_DATA | M_BLANK | M_IS_META)){ if (scan & (M_ACL | M_EXT4_META | M_DIR)) ext2fs_mark_generic_bitmap(bmap, blk[0]+i); continue; - } + } +#ifdef DEBUG_MAGIC_SCAN printf("SCAN %d : %09x : %s\n",blk[0]+i,scan,magic_buf); +#endif if (((count -i) > 12) && (ext2fs_le32_to_cpu(*(__u32*)(buf +((i+12)*blocksize))) == blk[0] + i +1 + 12)){ follow = 0; file_data = new_file_data(blk[0]+i,scan,magic_buf,buf+(i*blocksize),&follow); @@ -682,8 +711,6 @@ while (ds_retval){ else{ // no matches // In the first step we are taking nothing - -// printf(" %d not matches %d == %d \n\n\n", blk[0]+i, ext2fs_le32_to_cpu(*(buf +((i+12)*blocksize))), blk[0] + i + 12+1); } } blk[0] += (i)?i:1; @@ -694,15 +721,30 @@ while (ds_retval){ fragment_flag = 0; count = get_full_range(blk ,ds_bmap, buf,flag); while (count){ +#ifdef DEBUG_MAGIC_SCAN printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d - %d\n",flag[0],flag[1],flag[2],flag[3],flag[4],flag[5],flag[6],flag[7],flag[8],flag[9],flag[10],flag[11],flag[12],flag[13],flag[14],flag[15],count); - +#endif for (i = 0; i< ((count>12) ? MAX_RANGE - 12 : count) ;i++){ follow = 0; scan = magic_check_block(buf+(i*blocksize), cookie, cookie_f , magic_buf , blocksize ,blk[0]+i); if(scan & (M_DATA | M_BLANK | M_IS_META)){ - continue; - } + if ((!fragment_flag) && (scan & M_EXT3_META) && (check_indirect_meta3(buf+(i*blocksize)))){ +#ifdef DEBUG_MAGIC_SCAN + printf("try a fragment recover for metablock %ld\n",flag[i]); +#endif + blk[1] = block_backward(flag[i] , 12); + if (blk[1]){ + blk[0] = blk[1]; + fragment_flag = flag[i]; + goto load_new; + } + } + else + continue; + } +#ifdef DEBUG_MAGIC_SCAN printf("SCAN %d : %09x : %s\n",blk[0]+i,scan,magic_buf); +#endif if (((count -i) > 12) && (ext2fs_le32_to_cpu(*(__u32*)(buf +((i+12)*blocksize))) == flag[12+i]+1)){ file_data = new_file_data(flag[i],scan,magic_buf,buf+(i*blocksize),&follow); for(j=i; j<(12+i);j++) @@ -737,7 +779,9 @@ while (ds_retval){ j--; file_data = soft_border(des_dir,buf+(j*blocksize), file_data, &follow, flag[j]); if ((!fragment_flag) && (scan & M_EXT3_META) && (check_indirect_meta3(buf+((j+1)*blocksize)))){ +#ifdef DEBUG_MAGIC_SCAN printf("try a fragment recover for metablock %ld\n",flag[j]+1); +#endif blk[1] = block_backward(flag[j] , 12); if (blk[1]){ blk[0] = blk[1]; @@ -756,14 +800,18 @@ while (ds_retval){ file_data = recover_file_data(des_dir, file_data, &follow); } else{ - file_data = forget_file_data(file_data, &follow); + file_data = forget_file_data(file_data, &follow); +#ifdef DEBUG_MAGIC_SCAN printf("Don't recover this file, current block %d \n",blk); +#endif } break; } } if (follow){ +#ifdef DEBUG_MAGIC_SCAN printf("stop no file-end\n"); +#endif file_data = soft_border(des_dir,buf+((j-1)*blocksize), file_data, &follow, flag[j-1]); i = j - 11; } diff --git a/src/recover.c b/src/recover.c index 1a53d8e..eba48f5 100644 --- a/src/recover.c +++ b/src/recover.c @@ -67,13 +67,13 @@ struct privat { char flag; int error;}; + struct alloc_stat{ __u32 allocated; __u32 not_allocated;}; - // recover files from a "double quotes" listfile void recover_list(char *des_dir, char *input_file,__u32 t_after, __u32 t_before, int flag){ FILE *f; @@ -564,33 +564,6 @@ return retval; -/* -//FIXME: If we ever need this function, we rewrite this -int create_all_dir(char* des_dir,char* pathname, ext2_ino_t ino_nr ){ - char *fullname; - char *p1; - int retval; - - if (ino_nr == EXT2_ROOT_INO) - return 0; - - fullname = malloc(strlen(des_dir) + strlen(pathname) + 3); - if (fullname){ - p1 = pathname; - while (*p1 == '/') p1++; - strcpy(fullname,des_dir); - strcat(fullname,"/"); - strcat(fullname,p1); - retval = mkdir(fullname,S_IRWXU); - if (retval && (errno != EEXIST)) - fprintf(stderr,"Error: mkdir %s\n", fullname); - free(fullname); - } -return retval; -} -*/ - - //set all attributes for directory void set_dir_attributes(char* des_dir,char* pathname,struct ext2_inode *inode){ char *fullname; @@ -26,7 +26,7 @@ /* ext3/4 libraries */ #include <ext2fs/ext2fs.h> -#include <ext2fs/ext2_io.h> +//#include <ext2fs/ext2_io.h> #include <e2p/e2p.h> #include "util.h" @@ -264,6 +264,89 @@ return; } + +// search for a time before the last big delete job +__u32 get_last_delete_time(ext2_filsys fs) +{ +struct ext2_group_desc *gdp; +char *buf= NULL; +int zero_flag, x , retval; +__u32 blocksize , inodesize , inode_max , inode_per_group, block_count; +__u16 inode_per_block , inode_block_group, group; +blk_t block_nr; +__u32 i, c_time, d_time; +__u32 last = 0; +__u32 first; +int flag; + +struct ext2_inode_large *inode; + +blocksize = fs->blocksize; +inodesize = fs->super->s_inode_size; +inode_max = fs->super->s_inodes_count; +inode_per_group = fs->super->s_inodes_per_group; +buf = malloc(blocksize); + +inode_per_block = blocksize / inodesize; +inode_block_group = inode_per_group / inode_per_block; + +for (flag=0;flag<2;flag++){ + for (group = 0 ; group < fs->group_desc_count ; group++){ + gdp = &fs->group_desc[group]; + zero_flag = 0; + + // NEXT GROUP IF INODE NOT INIT + if (gdp->bg_flags & (EXT2_BG_INODE_UNINIT)) continue; + + // SET ZERO-FLAG IF FREE INODES == INODE/GROUP for fast ext3 + if (gdp->bg_free_inodes_count == inode_per_group) zero_flag = 1; + + for (block_nr = gdp->bg_inode_table , block_count = 0 ; + block_nr < (gdp->bg_inode_table + inode_block_group); block_nr++, block_count++) { + + // break if the first block only zero inode + if ((block_count ==1) && (zero_flag == (inode_per_block + 1))) break; + + if ( read_block ( fs , &block_nr , buf)) + return 0; + + for (i = (group * inode_per_group)+(block_count * inode_per_block) + 1 ,x = 0; + x < inode_per_block ; i++ , x++){ + + if (i >= inode_max) break; + inode = (struct ext2_inode_large*) (buf + (x*inodesize)); + c_time = ext2fs_le32_to_cpu(inode->i_ctime); + if (! c_time) { + if(zero_flag) zero_flag++ ; + continue; + } + d_time = ext2fs_le32_to_cpu(inode->i_dtime); + if (flag){ + if ((d_time > (last-300)) && (d_time < first)) + first = d_time; + } + else{ + if (d_time > last){ + last = d_time; + } + } + } + } + } +first = last; +} + + if(buf) { + free(buf); + buf = NULL; + } +return first - 1 ; +} + + + + + // add inodenumber in a collectlist void add_coll_list(ext2_ino_t ino_nr ){ ext2_ino_t *pointer; @@ -173,7 +173,15 @@ void imap_search(char* , __u32, __u32 ); // search inode by imap (step1 + step2) int check_find_dir(char*, ext2_ino_t, char*, char*); //check if the directory always recovert; then move + +//public function file_type.c +int ident_file(struct found_data_t*, __u32*, char*, char*); // index of the files corresponding magic result strings +void get_file_property(struct found_data_t*); //set the file properties and the extension + + + //public functions magic_block_scan.c -//void magic_block_scan(char* , __u32); +int magic_block_scan3(char*, __u32);//main of the magic_scan_engine for ext3 + #endif |