diff options
author | robi <robi> | 2010-08-22 19:09:46 +0000 |
---|---|---|
committer | robi <robi> | 2010-08-22 19:09:46 +0000 |
commit | e66d5f9b85fd816571fe4a780f05fc0ad0b8256f (patch) | |
tree | 73c4c5a2fa73417bde86f777ba4dd0903f3947ac /src | |
parent | 8f27364faf5c58eebce6616be246afaeff734a14 (diff) |
magic functions Part1 (inactive)
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/Makefile.in | 22 | ||||
-rw-r--r-- | src/block.c | 50 | ||||
-rw-r--r-- | src/ext4magic.c | 81 | ||||
-rw-r--r-- | src/hard_link_stack.c | 31 | ||||
-rw-r--r-- | src/imap_search.c | 186 | ||||
-rw-r--r-- | src/inode.c | 3 | ||||
-rw-r--r-- | src/lookup_local.c | 26 | ||||
-rw-r--r-- | src/recover.c | 30 | ||||
-rw-r--r-- | src/util.c | 67 | ||||
-rw-r--r-- | src/util.h | 25 |
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 = ¤t_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"); @@ -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; } @@ -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 |