summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/block.c3
-rw-r--r--src/block.h1
-rw-r--r--src/ext4magic.832
-rw-r--r--src/ext4magic.c81
-rw-r--r--src/ext4magic.h1
-rw-r--r--src/file_type.c7
-rw-r--r--src/hard_link_stack.c6
-rw-r--r--src/imap_search.c2
-rw-r--r--src/inode.c6
-rw-r--r--src/inode.h6
-rw-r--r--src/journal.c4
-rw-r--r--src/journal.h4
-rw-r--r--src/lookup_local.c5
-rw-r--r--src/magic.h4
-rw-r--r--src/magic_block_scan.c228
-rw-r--r--src/recover.c29
-rw-r--r--src/util.c85
-rw-r--r--src/util.h10
18 files changed, 354 insertions, 160 deletions
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;
diff --git a/src/util.c b/src/util.c
index 95e5045..c76ab95 100644
--- a/src/util.c
+++ b/src/util.c
@@ -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;
diff --git a/src/util.h b/src/util.h
index 03263c8..4149ec3 100644
--- a/src/util.h
+++ b/src/util.h
@@ -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