#include #include #include #include #include #include #include #include #include "main.h" #include "disk.h" static int test_str_fname( char *d, int l ) { int i; for(i=0;iinode==0) || (de->inode > nr_inodes) ) return(0); if( de->rec_len < de->name_len + 8 ) return(0); if( !test_str_fname(de->name,de->name_len) ) return(0); // if( de->file_type!=0 ) return(0); /* !!! */ de= (struct ext2_dir_entry_2*)(((char*)de)+de->rec_len); } if( ((char*)de) != d+blocksize ) return(0); return(1); } static __u32 test_dir_firstblock( char *d, __u32 *parent ) { struct ext2_dir_entry_2 *de=(struct ext2_dir_entry_2*)d; int inode; if( de->name_len==1 && de->name[0]=='.' ) { inode=de->inode; if( parent==NULL ) return(inode); de= (struct ext2_dir_entry_2*)(((char*)de)+de->rec_len); if( de->name_len==2 && de->name[0]=='.' && de->name[1]=='.' ) { *parent=de->inode; return(inode); } } return(0); } struct mem_dir_s *mem_dirs_first=NULL, *mem_dirs=NULL, *mem_root_dir_first=NULL; int find_dirs(int fd) { struct mem_dir_s * p; char buf[16*blocksize]; int l,i, nr_dirs = 0, nr_dirs_first = 0; unsigned long long pos=0; progressbar_init("Finding directories"); lseek(fd, 0l, SEEK_SET); while ((l=read(fd, buf, sizeof(buf))) > 0) { progressbar_display( ((float)pos/((float)fs_size/100.)) , nr_dirs+nr_dirs_first); for (i=0;i<16;i++) if (test_dir_block(buf+(i*blocksize))) { p = (struct mem_dir_s *)malloc(sizeof(struct mem_dir_s)+blocksize); if (!p) { perror("Directory data loss; increase memory and/or swap"); continue; } memcpy(&(p->data),buf+(i*blocksize),blocksize); p->inode=NULL; p->ok=0; p->need_to_write=0; p->block=i+pos/blocksize; p->to_block=p->block; if( is_inode_table(p->block) ) { fprintf(stderr,"\nError: Directory inside inode table!!!\n"); p->to_block=0; } if( (p->inode_nr=test_dir_firstblock(buf+(i*blocksize),&(p->parent_nr)))==0 ) { p->parent_nr=0; p->next = mem_dirs; mem_dirs = p; nr_dirs++; } else { p->next=mem_dirs_first; mem_dirs_first=p; nr_dirs_first++; if( p->inode_nr==p->parent_nr && mem_root_dir_first==NULL && p->to_block>0 ) { mem_root_dir_first=p; fprintf(stderr,"\nOK: Root dir found at block 0x%08x !\n",p->block); } } } pos+=l; } progressbar_display( ((float)pos/((float)fs_size/100.)) , nr_dirs+nr_dirs_first); progressbar_stop(); return nr_dirs_first; } /* ----------------- */ int is_in_dir( char *d, __u32 inum ) { struct ext2_dir_entry_2 *de=(struct ext2_dir_entry_2*)d; while( ((char*)de) < d+blocksize ) { if( (de->inode==inum) ) return(1); de= (struct ext2_dir_entry_2*)(((char*)de)+de->rec_len); } return(0); }