summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobi <robi>2010-08-22 19:09:46 +0000
committerrobi <robi>2010-08-22 19:09:46 +0000
commite66d5f9b85fd816571fe4a780f05fc0ad0b8256f (patch)
tree73c4c5a2fa73417bde86f777ba4dd0903f3947ac
parent8f27364faf5c58eebce6616be246afaeff734a14 (diff)
magic functions Part1 (inactive)
-rw-r--r--src/Makefile.am4
-rw-r--r--src/Makefile.in22
-rw-r--r--src/block.c50
-rw-r--r--src/ext4magic.c81
-rw-r--r--src/hard_link_stack.c31
-rw-r--r--src/imap_search.c186
-rw-r--r--src/inode.c3
-rw-r--r--src/lookup_local.c26
-rw-r--r--src/recover.c30
-rw-r--r--src/util.c67
-rw-r--r--src/util.h25
11 files changed, 445 insertions, 80 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 40c7242..77e1a61 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
sbin_PROGRAMS = ext4magic
-ext4magic_SOURCES = block.c dir_list.c ext4magic.c \
- hard_link_stack.c inode.c journal.c lookup_local.c recover.c ring_buf.c util.c
+ext4magic_SOURCES = block.c dir_list.c ext4magic.c hard_link_stack.c \
+ imap_search.c inode.c journal.c lookup_local.c recover.c ring_buf.c util.c
# set the include path found by configure
INCLUDES= $(all_includes)
diff --git a/src/Makefile.in b/src/Makefile.in
index 7391b9f..fdf3af9 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -51,7 +51,8 @@ am__installdirs = "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"
PROGRAMS = $(sbin_PROGRAMS)
am_ext4magic_OBJECTS = ext4magic-block.$(OBJEXT) \
ext4magic-dir_list.$(OBJEXT) ext4magic-ext4magic.$(OBJEXT) \
- ext4magic-hard_link_stack.$(OBJEXT) ext4magic-inode.$(OBJEXT) \
+ ext4magic-hard_link_stack.$(OBJEXT) \
+ ext4magic-imap_search.$(OBJEXT) ext4magic-inode.$(OBJEXT) \
ext4magic-journal.$(OBJEXT) ext4magic-lookup_local.$(OBJEXT) \
ext4magic-recover.$(OBJEXT) ext4magic-ring_buf.$(OBJEXT) \
ext4magic-util.$(OBJEXT)
@@ -213,8 +214,8 @@ target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
-ext4magic_SOURCES = block.c dir_list.c ext4magic.c \
- hard_link_stack.c inode.c journal.c lookup_local.c recover.c ring_buf.c util.c
+ext4magic_SOURCES = block.c dir_list.c ext4magic.c hard_link_stack.c \
+ imap_search.c inode.c journal.c lookup_local.c recover.c ring_buf.c util.c
# set the include path found by configure
@@ -318,6 +319,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext4magic-dir_list.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext4magic-ext4magic.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext4magic-hard_link_stack.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext4magic-imap_search.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext4magic-inode.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext4magic-journal.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext4magic-lookup_local.Po@am__quote@
@@ -402,6 +404,20 @@ ext4magic-hard_link_stack.obj: hard_link_stack.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ext4magic_CFLAGS) $(CFLAGS) -c -o ext4magic-hard_link_stack.obj `if test -f 'hard_link_stack.c'; then $(CYGPATH_W) 'hard_link_stack.c'; else $(CYGPATH_W) '$(srcdir)/hard_link_stack.c'; fi`
+ext4magic-imap_search.o: imap_search.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ext4magic_CFLAGS) $(CFLAGS) -MT ext4magic-imap_search.o -MD -MP -MF $(DEPDIR)/ext4magic-imap_search.Tpo -c -o ext4magic-imap_search.o `test -f 'imap_search.c' || echo '$(srcdir)/'`imap_search.c
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ext4magic-imap_search.Tpo $(DEPDIR)/ext4magic-imap_search.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='imap_search.c' object='ext4magic-imap_search.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ext4magic_CFLAGS) $(CFLAGS) -c -o ext4magic-imap_search.o `test -f 'imap_search.c' || echo '$(srcdir)/'`imap_search.c
+
+ext4magic-imap_search.obj: imap_search.c
+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ext4magic_CFLAGS) $(CFLAGS) -MT ext4magic-imap_search.obj -MD -MP -MF $(DEPDIR)/ext4magic-imap_search.Tpo -c -o ext4magic-imap_search.obj `if test -f 'imap_search.c'; then $(CYGPATH_W) 'imap_search.c'; else $(CYGPATH_W) '$(srcdir)/imap_search.c'; fi`
+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ext4magic-imap_search.Tpo $(DEPDIR)/ext4magic-imap_search.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='imap_search.c' object='ext4magic-imap_search.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ext4magic_CFLAGS) $(CFLAGS) -c -o ext4magic-imap_search.obj `if test -f 'imap_search.c'; then $(CYGPATH_W) 'imap_search.c'; else $(CYGPATH_W) '$(srcdir)/imap_search.c'; fi`
+
ext4magic-inode.o: inode.c
@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(ext4magic_CFLAGS) $(CFLAGS) -MT ext4magic-inode.o -MD -MP -MF $(DEPDIR)/ext4magic-inode.Tpo -c -o ext4magic-inode.o `test -f 'inode.c' || echo '$(srcdir)/'`inode.c
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/ext4magic-inode.Tpo $(DEPDIR)/ext4magic-inode.Po
diff --git a/src/block.c b/src/block.c
index fd60df7..28a43fd 100644
--- a/src/block.c
+++ b/src/block.c
@@ -26,10 +26,14 @@
#define EXT2_FLAT_INCLUDES 0
#endif
+
//#include <ext2fs/ext2fs.h>
#include "ext2fsP.h"
#include "block.h"
+
+extern ext2fs_block_bitmap bmap ;
+
struct block_context {
ext2_filsys fs;
int (*func)(ext2_filsys fs,
@@ -174,6 +178,37 @@ errcode_t local_ext2fs_extent_open(ext2_filsys fs, struct ext2_inode inode,
}
+static int mark_extent_block(ext2_filsys fs, char *extent_block ){
+ struct ext3_extent_header *eh;
+ struct ext3_extent_idx *idx;
+ int i, ret;
+ blk_t index_bl;
+ char *buf = NULL;
+
+ eh = (struct ext3_extent_header*) extent_block;
+ if (eh->eh_magic != ext2fs_cpu_to_le16(EXT3_EXT_MAGIC))
+ return 1;
+ if (ext2fs_le16_to_cpu(eh->eh_depth)) {
+ for (i = 1; ((i <= ext2fs_le16_to_cpu(eh->eh_entries)) && (i <= ext2fs_le16_to_cpu(eh->eh_max))); i++){
+ idx = (struct ext3_extent_idx*) &(extent_block[12 * i]);
+ index_bl = ext2fs_le32_to_cpu(idx->ei_leaf);
+ if (index_bl && index_bl <= fs->super->s_blocks_count ){
+ if (bmap){
+ ext2fs_mark_generic_bitmap(bmap, index_bl);
+ buf = malloc(fs->blocksize);
+ if (buf){
+ ret = read_block (fs, &index_bl, buf );
+ if (!ret)
+ ret = mark_extent_block(fs,buf);
+ free(buf);
+ }
+ }
+ }
+ }
+ }
+return ret;
+}
+
#define check_for_ro_violation_return(ctx, ret) \
@@ -226,7 +261,9 @@ static int block_iterate_ind(blk_t *ind_block, blk_t ref_block,
ret |= BLOCK_ERROR;
return ret;
}
-
+ if (bmap)
+ ext2fs_mark_generic_bitmap(bmap, *ind_block);
+
block_nr = (blk_t *) ctx->ind_buf;
offset = 0;
if (ctx->flags & BLOCK_FLAG_APPEND) {
@@ -305,7 +342,9 @@ static int block_iterate_dind(blk_t *dind_block, blk_t ref_block,
ret |= BLOCK_ERROR;
return ret;
}
-
+ if (bmap)
+ ext2fs_mark_generic_bitmap(bmap, *dind_block);
+
block_nr = (blk_t *) ctx->dind_buf;
offset = 0;
if (ctx->flags & BLOCK_FLAG_APPEND) {
@@ -386,6 +425,8 @@ static int block_iterate_tind(blk_t *tind_block, blk_t ref_block,
ret |= BLOCK_ERROR;
return ret;
}
+ if (bmap)
+ ext2fs_mark_generic_bitmap(bmap, *tind_block);
block_nr = (blk_t *) ctx->tind_buf;
offset = 0;
@@ -592,6 +633,8 @@ errcode_t local_block_iterate3(ext2_filsys fs,
break;
}
}
+ if (bmap)
+ mark_extent_block(fs, (char*) inode.i_block);
extent_errout:
local_ext2fs_extent_free(handle);
@@ -628,8 +671,9 @@ errcode_t local_block_iterate3(ext2_filsys fs,
if (inode.i_block[EXT2_TIND_BLOCK] || (flags & BLOCK_FLAG_APPEND)) {
ret |= block_iterate_tind(&inode.i_block[EXT2_TIND_BLOCK],
0, EXT2_TIND_BLOCK, &ctx);
- if (ret & BLOCK_ABORT)
+ if (ret & BLOCK_ABORT){
goto abort_exit;
+ }
}
abort_exit:
diff --git a/src/ext4magic.c b/src/ext4magic.c
index 0d44db8..607f6bd 100644
--- a/src/ext4magic.c
+++ b/src/ext4magic.c
@@ -58,9 +58,10 @@ extern char *optarg;
-ext2_filsys current_fs = NULL;
-ext2_ino_t root, cwd;
-
+ext2_filsys current_fs = NULL;
+ext2_ino_t root, cwd;
+ext2fs_inode_bitmap imap = NULL ;
+ext2fs_block_bitmap bmap = NULL ;
//print Versions an CPU-endian-type
@@ -158,7 +159,7 @@ void show_super_stats(int header_only)
//open and init the Filesystem, use in main()
static void open_filesystem(char *device, int open_flags, blk_t superblock,
- blk_t blocksize, int catastrophic,
+ blk_t blocksize, int magicscan,
char *data_filename)
{
int retval;
@@ -184,8 +185,7 @@ static void open_filesystem(char *device, int open_flags, blk_t superblock,
}
}
- if (catastrophic && (open_flags & EXT2_FLAG_RW)) {
- fprintf(stderr,"opening read-only because of catastrophic mode\n");
+ if (open_flags & EXT2_FLAG_RW) {
open_flags &= ~EXT2_FLAG_RW;
}
@@ -198,20 +198,31 @@ static void open_filesystem(char *device, int open_flags, blk_t superblock,
}
- if (catastrophic)
- fprintf(stderr,"%s catastrophic mode - not reading inode or group bitmaps\n", device);
- else {
- retval = ext2fs_read_inode_bitmap(current_fs);
- if (retval) {
- fprintf(stderr,"%s %d while reading inode bitmap\n", device, retval);
- goto errout;
- }
- retval = ext2fs_read_block_bitmap(current_fs);
- if (retval) {
- fprintf(stderr,"%s %d while reading block bitmap\n",device, retval);
- goto errout;
- }
+ retval = ext2fs_read_inode_bitmap(current_fs);
+ if (retval) {
+ fprintf(stderr,"%s %d while reading inode bitmap\n", device, retval);
+ goto errout;
}
+ retval = ext2fs_read_block_bitmap(current_fs);
+ if (retval) {
+ fprintf(stderr,"%s %d while reading block bitmap\n",device, retval);
+ goto errout;
+ }
+//FIXME
+ if (magicscan){
+// switch on magic scan function
+ if( ext2fs_copy_bitmap(current_fs->inode_map, &imap) || ext2fs_copy_bitmap(current_fs->block_map, &bmap)){
+ fprintf(stderr,"%s Error while copy bitmap\n",device );
+ imap = NULL;
+ bmap = NULL;
+ }else{
+ int i;
+ ext2fs_clear_inode_bitmap(imap);
+ for (i = 1; i < current_fs->super->s_first_ino; i++)
+ ext2fs_mark_generic_bitmap(imap,i); //mark inode 1-8
+ ext2fs_clear_block_bitmap(bmap);
+ }
+ }
if (data_io) {
retval = ext2fs_set_data_io(current_fs, data_io);
@@ -262,7 +273,7 @@ char *input_filename = NULL;
blk_t superblock = 0;
blk_t blocksize = 0;
int transaction_nr = 0;
-//int catastrophic = 0;
+int magicscan = 0;
char *data_filename = 0;
int mode = 0;
ext2_ino_t inode_nr = EXT2_ROOT_INO ;
@@ -294,6 +305,10 @@ if ( argc < 3 )
// decode arguments
while ((c = getopt (argc, argv, "TJRLlrQSxi:t:j:f:Vd:B:b:a:I:H")) != EOF) {
switch (c) {
+ case 'M':
+ //not active, still in development
+ magicscan = 1;
+ break;
case 'S':
mode |= PRINT_SUPERBLOCK ;
break;
@@ -549,7 +564,7 @@ while ((c = getopt (argc, argv, "TJRLlrQSxi:t:j:f:Vd:B:b:a:I:H")) != EOF) {
if (getuid()) mode = 0;
if (optind < argc)
- open_filesystem(argv[optind], open_flags,superblock, blocksize, 0, data_filename);
+ open_filesystem(argv[optind], open_flags,superblock, blocksize, magicscan, data_filename);
#ifdef DEBUG
printf("Operation-mode = %d\n", mode);
#endif
@@ -766,12 +781,16 @@ if (mode & READ_JOURNAL){
fprintf(stderr,"Error: Inode not found for \"%s\"\n",pathname);
fprintf(stderr,"Check the valid PATHNAME \"%s\" and the BEFORE option \"%s\"\n", pathname,time_to_string(t_before));
exitval = EXIT_FAILURE ;
- goto errout;
+ goto journalout;
}
}
else{
if (mode & COMMAND_INODE){
pathname = malloc(20);
+ if (!pathname) {
+ fprintf(stderr,"ERROR: can not allocate memory\n");
+ goto journalout;
+ }
if (inode_nr == EXT2_ROOT_INO)
*pathname = 0;
else
@@ -854,10 +873,14 @@ if ((mode & COMMAND_INODE) && (mode & RECOVER_INODE))
dir = get_dir3(NULL,0, inode_nr , "",pathname, t_after,t_before, recoverquality );
if (dir) {
-//FIXME: recovermodus
lookup_local(des_dir, dir,t_after,t_before, recoverquality | recovermodus );
if (recovermodus & HIST_DIR )
print_coll_list(t_after, t_before, format);
+//Magic step 1 + 2
+ if (imap){
+ search_imap_inode(des_dir, t_after, t_before, 1); //search for lost fragments of directorys
+ search_imap_inode(des_dir, t_after, t_before, 0); //search for lost files
+ }
}
else
printf("Inode %lu is a directory but not found after %lu and before %lu\n",inode_nr,t_after,t_before);
@@ -909,7 +932,7 @@ if ((mode & COMMAND_INODE) && (mode & RECOVER_INODE))
if (i_list) ring_del(i_list);
}
}
-
+journalout:
if(!journal_flag) journal_flag = journal_close();
}// end open Journal
} // end Operation
@@ -922,6 +945,16 @@ exitval = EXIT_SUCCESS;
errout:
if (current_fs) {
+//FIXME in development
+ if (bmap){
+ // struct ext2fs_struct_loc_generic_bitmap *pmap;
+ // pmap=bmap;
+ // blockhex(stdout,(void*)pmap->bitmap,0,current_fs->super->s_blocks_count >> 3);
+ ext2fs_free_block_bitmap(bmap);
+ }
+ if (imap) ext2fs_free_inode_bitmap(imap);
+ imap = NULL;
+ bmap = NULL;
retval = ext2fs_close(current_fs);
if (retval) {
fprintf(stderr, "ext2fs_close\n");
diff --git a/src/hard_link_stack.c b/src/hard_link_stack.c
index 547d259..b7df7ed 100644
--- a/src/hard_link_stack.c
+++ b/src/hard_link_stack.c
@@ -60,6 +60,36 @@ errout:
free(this);
}
+
+
+int rename_hardlink_path(char *old, char *neu){
+ char *newname;
+ char *endname;
+ int size = strlen(old);
+
+ head.pointer = head.begin;
+ while (head.pointer) {
+ if (! strcmp(old,head.pointer->name)){
+ newname=malloc(strlen(neu) + strlen(head.pointer->name) - size +1);
+ if (! newname)
+ return 1;
+ strcpy(newname,neu);
+ endname = head.pointer->name + size;
+ strcat(newname,endname);
+ free(head.pointer->name);
+ head.pointer->name = newname;
+//#ifdef DEBUG
+ fprintf(stderr,"HL-DB change %s -> %s\n",old,neu);
+//#endif
+
+ }
+ head.pointer = head.pointer->next;
+ }
+}
+
+
+
+
char* check_link_stack(ext2_ino_t inode_nr, __u32 generation){
@@ -69,6 +99,7 @@ char* check_link_stack(ext2_ino_t inode_nr, __u32 generation){
break;
head.pointer = head.pointer->next;
}
+
#ifdef DEBUG
if (head.pointer)
printf("HARD_LINK found -> %s\n",head.pointer->name);
diff --git a/src/imap_search.c b/src/imap_search.c
new file mode 100644
index 0000000..3446bec
--- /dev/null
+++ b/src/imap_search.c
@@ -0,0 +1,186 @@
+/*
+* C Implementation: imap_search
+*
+* Description:
+*
+*
+* Author: Roberto Maar <robi@users.berlios.de>, (C) 2010
+*
+* Copyright: See COPYING file that comes with this distribution
+*
+*/
+
+//header util.h
+
+#include "util.h"
+#include "inode.h"
+#include <sys/stat.h>
+#include <errno.h>
+
+extern ext2_filsys current_fs;
+
+
+
+// search inode by use imap (step1: flag 1 = only directory ; step2: flag 0 = only file)
+void search_imap_inode(char* des_dir, __u32 t_after, __u32 t_before, int flag)
+{
+struct ext2_group_desc *gdp;
+struct ext2_inode_large *inode;
+struct dir_list_head_t *dir = NULL;
+struct ring_buf* i_list = NULL;
+r_item* item = NULL;
+int zero_flag, retval, load, x ,i ;
+char *pathname = NULL;
+char *buf= NULL;
+__u32 blocksize, inodesize, inode_max, inode_per_group, block_count;
+__u16 inode_per_block , inode_block_group, group;
+blk_t block_nr;
+__u32 c_time, d_time, mode;
+ext2_ino_t first_block_inode_nr , inode_nr;
+
+
+pathname = malloc(26);
+blocksize = current_fs->blocksize;
+inodesize = current_fs->super->s_inode_size;
+inode_max = current_fs->super->s_inodes_count;
+inode_per_group = current_fs->super->s_inodes_per_group;
+buf = malloc(blocksize);
+
+inode_per_block = blocksize / inodesize;
+inode_block_group = inode_per_group / inode_per_block;
+
+for (group = 0 ; group < current_fs->group_desc_count ; group++){
+ gdp = &current_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;
+
+//FIXME for struct ext4_group_desc 48/64BIT
+ 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;
+//FIXME inode_max ????
+ first_block_inode_nr = (group * inode_per_group) + (block_count * inode_per_block) + 1;
+ load = 0;
+ for (i = 0; i<inode_per_block;i++){
+ if ( ! ext2fs_test_block_bitmap(imap,first_block_inode_nr + i)){
+ load++;
+ break;
+ }
+ }
+
+ if (load){
+ retval = read_block ( current_fs , &block_nr , buf);
+ if (retval) return;
+
+ for (inode_nr = first_block_inode_nr ,x = 0; x < inode_per_block ; inode_nr++ , x++){
+
+ if ( ! ext2fs_test_block_bitmap(imap,inode_nr)){
+
+ inode = (struct ext2_inode_large*) (buf + (x*inodesize));
+ c_time = ext2fs_le32_to_cpu(inode->i_ctime);
+ mode = ext2fs_le32_to_cpu(inode->i_mode);
+ if ((! c_time ) && (!(inode->i_mode & LINUX_S_IFMT)) ) {
+ if(zero_flag) zero_flag++ ;
+ continue;
+ }
+
+ d_time = ext2fs_le32_to_cpu(inode->i_dtime);
+ if ( (! d_time) || d_time <= t_after){
+ ext2fs_mark_generic_bitmap(imap,inode_nr);
+ continue;
+ }
+// 1. magical step
+ if (LINUX_S_ISDIR(mode) && flag ){
+ sprintf(pathname,"<%lu>",inode_nr);
+
+
+ struct dir_list_head_t * dir = NULL;
+ dir = get_dir3(NULL,0, inode_nr , "MAGIC-1",pathname, t_after,t_before, DELETED_OPT);
+ if (dir) {
+ lookup_local(des_dir, dir,t_after,t_before, DELETED_OPT | RECOV_ALL | LOST_DIR_SEARCH );
+ clear_dir_list(dir);
+ }
+
+ }
+
+// 2. magical step
+ if (!flag){
+ i_list = get_j_inode_list(current_fs->super, inode_nr);
+ item = get_undel_inode(i_list,t_after,t_before);
+ ext2fs_mark_generic_bitmap(imap,inode_nr);
+
+ if (item) {
+ if (! LINUX_S_ISDIR(item->inode->i_mode) ) {
+ sprintf(pathname,"<%lu>",inode_nr);
+ recover_file(des_dir,"MAGIC-2", pathname, (struct ext2_inode*)item->inode, inode_nr, 0);
+ }
+ }
+ if (i_list) ring_del(i_list);
+ }
+ }
+ }
+ }
+ }
+}
+ if (pathname)
+ free(pathname);
+
+ if(buf) {
+ free(buf);
+ buf = NULL;
+ }
+return;
+}
+
+
+
+
+//check if the directory always recovert. if, then move to right place
+//return 0 if directory is moved
+//this function is called from lookup_local() during 1. magical step
+int check_find_dir(char *des_dir,ext2_ino_t inode_nr,char *pathname,char *filename){
+char *recovername = NULL;
+char *dirname = NULL;
+struct stat filestat;
+int retval = 0;
+
+recovername = malloc(strlen(des_dir) + strlen(pathname) + 30);
+dirname = malloc(strlen(des_dir) + strlen(pathname) + strlen(filename) +10);
+if (recovername && dirname){
+ sprintf(recovername,"%s/MAGIC-1/<%lu>",des_dir,inode_nr);
+ sprintf(dirname,"%s/%s/%s",des_dir,pathname,filename);
+
+ retval = stat (recovername, &filestat);
+ if ((!retval) && (S_ISDIR(filestat.st_mode))){
+ retval = stat (dirname, &filestat);
+ if (! retval){
+ printf("Warning :can't move %s to %s ;file exist; will recover it again\n",recovername,dirname);
+ retval = 1;
+ }
+ else{
+ if(check_dir(dirname)){
+ fprintf(stderr,"Unknown error at target directory by file: %s\ntrying to continue normal\n", dirname);
+ }else{
+ retval = rename(recovername, dirname);
+ rename_hardlink_path(recovername, dirname);
+ }
+//#ifdef DEBUG
+ printf("move return: %d : ernno %d : %s -> %s\n",retval, errno, recovername, dirname);
+//#endif
+ }
+ }
+ free(recovername);
+ free(dirname);
+
+return retval;
+}
+}
+
+
diff --git a/src/inode.c b/src/inode.c
index 57ca9a1..d25e9ad 100644
--- a/src/inode.c
+++ b/src/inode.c
@@ -110,6 +110,7 @@ static void local_dump_extents(FILE *f, const char *prefix, struct ext2_inode *
unsigned int printed = 0;
errcode_t errcode;
+
errcode = local_ext2fs_extent_open(current_fs, *inode, &handle);
if (errcode)
return;
@@ -487,7 +488,7 @@ void dump_inode(FILE *out, const char *prefix,
} else if (do_dump_blocks && !(inode->i_dtime)) {
if (inode->i_flags & EXT4_EXTENTS_FL)
local_dump_extents(out, prefix, inode,
- DUMP_LEAF_EXTENTS, 0, 0);
+ DUMP_LEAF_EXTENTS|DUMP_EXTENT_TABLE, 8, 8);
else
dump_blocks(out, prefix, inode);
}
diff --git a/src/lookup_local.c b/src/lookup_local.c
index 76d9b0a..b281507 100644
--- a/src/lookup_local.c
+++ b/src/lookup_local.c
@@ -308,8 +308,10 @@ static int convert_dir_block(char *buf, int flags){
#endif
if (ctx->errcode)
return BLOCK_ABORT;
-
- while (offset < fs->blocksize) {
+ if (bmap)
+ ext2fs_mark_generic_bitmap(bmap, *blocknr);
+
+ while (offset < fs->blocksize) {
dirent = (struct ext2_dir_entry *) (ctx->buf + offset);
if (ext2fs_get_rec_len(fs, dirent, &rec_len))
return BLOCK_ABORT;
@@ -504,13 +506,17 @@ void list_dir2(ext2_ino_t ino, struct ext2_inode *inode)
if(d_inode) memset(d_inode, 0 , current_fs->super->s_inode_size);
i_list = (struct ring_buf*) get_j_inode_list(current_fs->super, ino);
if (! i_list) return NULL;
-
+//FIXME
+ if (imap){
+ ext2fs_mark_generic_bitmap(imap,ino);
+// printf("mark inode %10u\n",ino);
+ }
item = get_undel_inode(i_list , t_after , t_before);
if ( item && item->inode ) {
inode = (struct ext2_inode*)item->inode;
if(d_inode)
memcpy(d_inode,inode,current_fs->super->s_inode_size);
- if (!ino || (! LINUX_S_ISDIR(inode->i_mode)))
+ if (!ino || (! LINUX_S_ISDIR(inode->i_mode)))
goto errout;
//get dir
@@ -550,6 +556,7 @@ void lookup_local(char* des_dir, struct dir_list_head_t * dir, __u32 t_after , _
r_item *item = NULL;
char c = ' ';
int allocated;
+ int recursion = 0;
if (! dir) {
d_list = get_dir3(NULL, EXT2_ROOT_INO , EXT2_ROOT_INO , "","", t_after,t_before, flag);
@@ -597,11 +604,18 @@ void lookup_local(char* des_dir, struct dir_list_head_t * dir, __u32 t_after , _
dir->pathname,lp->filename,t_after,t_before, flag);
if (d_list){
+//FIXME search for lost dir
+ recursion = 1;
+ if (flag & LOST_DIR_SEARCH)
+ recursion = check_find_dir(des_dir,lp->inode_nr,dir->pathname,lp->filename);
+
//recursion for directory
- lookup_local(des_dir, d_list, t_after, t_before, flag);
+ if(recursion) {
+ lookup_local(des_dir, d_list, t_after, t_before, flag);
#ifdef DEBUG
- printf("<<%s<<\n",dir->pathname);
+ printf("<<%s<<\n",dir->pathname);
#endif
+ }
}
else{
//function for all files apart from dir
diff --git a/src/recover.c b/src/recover.c
index f089a34..1ee390b 100644
--- a/src/recover.c
+++ b/src/recover.c
@@ -174,14 +174,21 @@ static int read_syslink_block ( ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t bloc
errcode_t retval;
int blocksize = fs->blocksize;
- int allocated = ext2fs_test_block_bitmap ( fs->block_map, *blocknr );
- if ( allocated ){
-// fprintf(stderr,"Block %10lu is allocated.\n",*blocknr);
- return (BLOCK_ABORT | BLOCK_ERROR);
+ if (((struct privat*)priv)->flag){
+ int allocated = ext2fs_test_block_bitmap ( fs->block_map, *blocknr );
+ if ( allocated ){
+ ((struct privat*)priv)->error = 1;
+// fprintf(stderr,"Block %10lu is allocated.\n",*blocknr);
+ return (BLOCK_ABORT | BLOCK_ERROR);
+ }
}
retval = io_channel_read_blk ( fs->io, *blocknr, 1, charbuf );
- if (retval)
- { return (BLOCK_ERROR);}
+ if (retval){
+ ((struct privat*)priv)->error = retval;
+ return (BLOCK_ERROR);
+ }
+ if (bmap)
+ ext2fs_mark_generic_bitmap(bmap, *blocknr);
return 0;
}
@@ -214,6 +221,9 @@ static int write_block ( ext2_filsys fs, blk_t *blocknr, e2_blkcnt_t blockcnt,
((struct privat*)priv)->error = BLOCK_ERROR ;
return (BLOCK_ERROR);
}
+ if (bmap)
+ ext2fs_mark_generic_bitmap(bmap, *blocknr);
+
lseek(fd,(unsigned long long )blocksize * blockcnt, SEEK_SET);
nbytes = write(fd, charbuf, blocksize);
@@ -226,8 +236,8 @@ return retval;
}
-//local check if the target directory existent, (recursive function)
-static int check_dir(char* pathname){
+//check if the target directory existent, (recursive function)
+ int check_dir(char* pathname){
char *buffer;
struct stat filestat;
char *p1;
@@ -395,7 +405,11 @@ int recover_file( char* des_dir,char* pathname, char* filename, struct ext2_inod
buf = malloc(current_fs->blocksize);
if (buf) {
priv.buf = buf;
+ priv.error = 0;
+
retval = local_block_iterate3 ( current_fs, *inode, BLOCK_FLAG_DATA_ONLY, NULL, read_syslink_block, &priv );
+ if (retval || priv.error)
+ goto errout;
}
else {
fprintf(stderr,"ERROR: can no allocate memory\n");
diff --git a/src/util.c b/src/util.c
index aa6b41d..16c349e 100644
--- a/src/util.c
+++ b/src/util.c
@@ -217,47 +217,48 @@ void print_coll_list(__u32 t_after, __u32 t_before, int flag){
__u16 crt_found = 0;
int inode_size = EXT2_INODE_SIZE(current_fs->super);
-
- cm = (flag) ? 2*HIST_COUNT : HIST_COUNT ;
-
- struct time_counter hist[(HIST_COUNT * 2)+1];
- for (i = 0 ; i<= cm; i++){
- hist[i].c_count = 0;
- hist[i].d_count = 0;
- hist[i].cr_count = 0;
- hist[i].time = ((t_before - t_after)/ cm * i) + t_after;
- }
- pointer = collect->list;
- for (i = 0; i < collect->count; i++ ,pointer++){
- intern_read_inode_full(*pointer, inode_buf , (inode_size > 256) ? 256 : inode_size );
- c_time = inode->i_ctime;
- d_time = inode->i_dtime;
- cr_time = ((inode_size > EXT2_GOOD_OLD_INODE_SIZE) && (inode->i_extra_isize >= 24)) ? inode->i_crtime : 0 ;
+ if (collect && collect->count){
+ cm = (flag) ? 2*HIST_COUNT : HIST_COUNT ;
+
+ struct time_counter hist[(HIST_COUNT * 2)+1];
+ for (i = 0 ; i<= cm; i++){
+ hist[i].c_count = 0;
+ hist[i].d_count = 0;
+ hist[i].cr_count = 0;
+ hist[i].time = ((t_before - t_after)/ cm * i) + t_after;
+ }
+ pointer = collect->list;
+ for (i = 0; i < collect->count; i++ ,pointer++){
+ intern_read_inode_full(*pointer, inode_buf , (inode_size > 256) ? 256 : inode_size );
+ c_time = inode->i_ctime;
+ d_time = inode->i_dtime;
+ cr_time = ((inode_size > EXT2_GOOD_OLD_INODE_SIZE) && (inode->i_extra_isize >= 24)) ? inode->i_crtime : 0 ;
- for (j=1;j <= cm ; j++){
- if ((d_time < hist[j].time) && (d_time > hist[j-1].time)){
- hist[j].d_count++;
- break;
- }
- if (cr_time){
- if ((cr_time < hist[j].time) && (cr_time > hist[j-1].time)){
+ for (j=1;j <= cm ; j++){
+ if ((d_time < hist[j].time) && (d_time > hist[j-1].time)){
+ hist[j].d_count++;
+ break;
+ }
+ if (cr_time){
+ if ((cr_time < hist[j].time) && (cr_time > hist[j-1].time)){
hist[j].cr_count++;
crt_found = 1;
cr_time = 0 ;
+ }
+ }
+ if ((c_time < hist[j].time) && (c_time > hist[j-1].time)){
+ hist[j].c_count++;
+ break;
}
- }
- if ((c_time < hist[j].time) && (c_time > hist[j-1].time)){
- hist[j].c_count++;
- break;
}
}
- }
- dump_hist(hist, cm, t_after, t_before, crt_found);
- if (collect->list) free(collect->list);
- if (collect){
- free(collect);
- collect = NULL;
+ dump_hist(hist, cm, t_after, t_before, crt_found);
+ if (collect->list) free(collect->list);
+ if (collect){
+ free(collect);
+ collect = NULL;
+ }
}
return;
}
diff --git a/src/util.h b/src/util.h
index 3ead8ff..9551805 100644
--- a/src/util.h
+++ b/src/util.h
@@ -30,6 +30,7 @@
// control flags for recover- and listmodus
#define DOUPLE_QUOTES_LIST 0x0100
+#define LOST_DIR_SEARCH 0x0400
#define LIST_ALL 0x1000
#define LIST_STATUS 0x2000
#define RECOV_DEL 0x4000
@@ -73,7 +74,25 @@ struct inode_nr_collect{
ext2_ino_t count;
ext2_ino_t *list;
};
+
+
+//FIXME
+//struct for generic bitmap (only temporarily for the development)
+struct ext2fs_struct_loc_generic_bitmap {
+ errcode_t magic;
+ ext2_filsys fs;
+ __u32 start, end;
+ __u32 real_end;
+ char * description;
+ char * bitmap;
+ errcode_t base_error_code;
+ __u32 reserved[7];
+};
+
+
#define ALLOC_SIZE 1024
+extern ext2fs_inode_bitmap imap ;
+extern ext2fs_block_bitmap bmap ;
// public functions util.c
void read_all_inode_time(ext2_filsys , __u32 , __u32 , int ); //analyse an print histogram
@@ -102,5 +121,11 @@ void recover_list(char*, char*,__u32, __u32, int); // recover files from a "doub
int recover_file( char* ,char* , char* , struct ext2_inode* , ext2_ino_t, int); //recover all filetypes
int check_file_recover(struct ext2_inode*); // return percentage of not allocated blocks
void set_dir_attributes(char* ,char* ,struct ext2_inode*); //set owner,file mode bits an timestamps for directory
+int check_dir(char*);//check if the target directory existent
+
+
+//public functions imap_search.c
+void search_imap_inode(char* , __u32, __u32, int); // search inode by imap (step1 + step2)
+int check_find_dir(char*, ext2_ino_t, char*, char*); //check if the directory always recovert; then move
#endif