summaryrefslogtreecommitdiff
path: root/src/magic_block_scan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/magic_block_scan.c')
-rw-r--r--src/magic_block_scan.c228
1 files changed, 138 insertions, 90 deletions
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;
}