Пример #1
0
int
main(int argc, char **argv)
{
	puts("Copyright (c) 2001-2010 pinc Software.");

	if (argc < 2 || !strcmp(argv[1], "--help")) {
		char *filename = strrchr(argv[0],'/');
		fprintf(stderr,"usage: %s [-srib] <device> [allocation_group start]\n"
				"\t-s\tdump superblock\n"
				"\t-r\tdump root node\n"
				"       the following options need the allocation_group/start "
					"parameters:\n"
				"\t-i\tdump inode\n"
				"\t-b\tdump b+tree\n"
				"\t-v\tvalidate b+tree\n"
				"\t-h\thexdump\n"
				"\t-o\tshow disk offsets\n",
				filename ? filename + 1 : argv[0]);
		return -1;
	}

	bool dumpRootNode = false;
	bool dumpInode = false;
	bool dumpSuperBlock = false;
	bool dumpBTree = false;
	bool validateBTree = false;
	bool dumpHex = false;
	bool showOffsets = false;

	while (*++argv) {
		char *arg = *argv;
		if (*arg == '-') {
			while (*++arg && isalpha(*arg)) {
				switch (*arg) {
					case 's':
						dumpSuperBlock = true;
						break;
					case 'r':
						dumpRootNode = true;
						break;
					case 'i':
						dumpInode = true;
						break;
					case 'b':
						dumpBTree = true;
						break;
					case 'v':
						validateBTree = true;
						break;
					case 'h':
						dumpHex = true;
						break;
					case 'o':
						showOffsets = true;
						break;
				}
			}
		} else
			break;
	}

	Disk disk(argv[0]);
	if (disk.InitCheck() < B_OK)
	{
		fprintf(stderr, "Could not open device or file: %s\n", strerror(disk.InitCheck()));
		return -1;
	}
	putchar('\n');

	if (!dumpSuperBlock && !dumpRootNode && !dumpInode && !dumpBTree
		&& !dumpHex) {
		printf("  Name:\t\t\t\"%s\"\n", disk.SuperBlock()->name);
		printf("    (disk is %s)\n\n",
			disk.ValidateSuperBlock() == B_OK ? "valid" : "invalid!!");
		printf("  Block Size:\t\t%" B_PRIu32 " bytes\n", disk.BlockSize());
		printf("  Number of Blocks:\t%12" B_PRIdOFF "\t%10g MB\n",
			disk.NumBlocks(), disk.NumBlocks() * disk.BlockSize()
				/ (1024.0*1024));
		if (disk.BlockBitmap() != NULL) {
			printf("  Used Blocks:\t\t%12" B_PRIdOFF "\t%10g MB\n",
				disk.BlockBitmap()->UsedBlocks(),
				disk.BlockBitmap()->UsedBlocks() * disk.BlockSize()
					/ (1024.0*1024));
			printf("  Free Blocks:\t\t%12" B_PRIdOFF "\t%10g MB\n",
				disk.BlockBitmap()->FreeBlocks(),
				disk.BlockBitmap()->FreeBlocks() * disk.BlockSize()
					/ (1024.0*1024));
		}
		int32 size
			= (disk.AllocationGroups() * disk.SuperBlock()->blocks_per_ag);
		printf("  Bitmap Size:\t\t%" B_PRIu32 " bytes (%" B_PRId32 " blocks, %"
			B_PRId32 " per allocation group)\n", disk.BlockSize() * size, size,
			disk.SuperBlock()->blocks_per_ag);
		printf("  Allocation Groups:\t%" B_PRIu32 "\n\n",
			disk.AllocationGroups());
		dump_block_run("  Log:\t\t\t", disk.Log());
		printf("    (was %s)\n\n", disk.SuperBlock()->flags == SUPER_BLOCK_CLEAN
			? "cleanly unmounted" : "not unmounted cleanly!");
		dump_block_run("  Root Directory:\t", disk.Root());
		putchar('\n');
	} else if (dumpSuperBlock) {
		dump_super_block(disk.SuperBlock());
		putchar('\n');
	}

	if (disk.ValidateSuperBlock() < B_OK) {
		fprintf(stderr, "The disk's superblock is corrupt (or it's not a BFS "
			"device)!\n");
		return 0;
	}

	if (dumpRootNode) {
		bfs_inode inode;
		if (disk.ReadAt(disk.ToOffset(disk.Root()), (void *)&inode,
				sizeof(bfs_inode)) < B_OK) {
			fprintf(stderr,"Could not read root node from disk!\n");
		} else {
			puts("Root node:\n-----------------------------------------");
			dump_inode(NULL, &inode, showOffsets);
			dump_indirect_stream(disk, &inode, showOffsets);
			putchar('\n');
		}
	}

	char buffer[disk.BlockSize()];
	bfs_inode* bfsInode = (bfs_inode*)buffer;
	block_run run;
	Inode *inode = NULL;

	if (dumpInode || dumpBTree || dumpHex || validateBTree) {
		// Set the block_run to the right value (as specified on the command
		// line)
		if (!argv[1]) {
			fprintf(stderr, "The -i/b/f options need the allocation group and "
				"starting offset (or the block number) of the node to dump!\n");
			return -1;
		}
		run = parseBlockRun(disk, argv[1], argv[2]);

		if (disk.ReadAt(disk.ToOffset(run), buffer, disk.BlockSize()) <= 0) {
			fprintf(stderr,"Could not read node from disk!\n");
			return -1;
		}

		inode = Inode::Factory(&disk, bfsInode, false);
		if (inode == NULL || inode->InitCheck() < B_OK) {
			fprintf(stderr,"Not a valid inode!\n");
			delete inode;
			inode = NULL;
		}
	}

	if (dumpInode) {
		printf("Inode at block %" B_PRIdOFF ":\n------------------------------"
			"-----------\n", disk.ToBlock(run));
		dump_inode(inode, bfsInode, showOffsets);
		dump_indirect_stream(disk, bfsInode, showOffsets);
		dump_double_indirect_stream(disk, bfsInode, showOffsets);
		dump_small_data(inode);
		putchar('\n');
	}

	if (dumpBTree && inode != NULL) {
		printf("B+Tree at block %" B_PRIdOFF ":\n-----------------------------"
			"------------\n", disk.ToBlock(run));
		if (inode->IsDirectory() || inode->IsAttributeDirectory()) {
			dump_bplustree(disk, (Directory *)inode, inode->Size(), dumpHex);
			putchar('\n');
		} else
			fprintf(stderr, "Inode is not a directory!\n");
	}

	if (validateBTree && inode != NULL) {
		printf("Validating B+Tree at block %" B_PRIdOFF ":\n------------------"
			"-----------------------\n", disk.ToBlock(run));
		if (inode->IsDirectory() || inode->IsAttributeDirectory()) {
			BPlusTree *tree;
			if (((Directory *)inode)->GetTree(&tree) == B_OK) {
				if (tree->Validate(true) < B_OK)
					puts("B+Tree is corrupt!");
				else
					puts("B+Tree seems to be okay.");
			}
		} else
			fprintf(stderr, "Inode is not a directory!\n");
	}

	if (dumpHex) {
		printf("Hexdump from inode at block %" B_PRIdOFF ":\n-----------------"
			"------------------------\n", disk.ToBlock(run));
		dump_block(buffer, disk.BlockSize());
		putchar('\n');
	}

	delete inode;

	return 0;
}
Пример #2
0
// recover Datafile
int recover_file( char* des_dir,char* pathname, char* filename, struct ext2_inode *inode, ext2_ino_t inode_nr, int flag){
	int rec_error = 255;
	char err_string[9];
	int retval =-1;
	int hardlink = 0;
	char i = 0;
	char *buf=NULL;
	struct privat priv;
	struct stat  filestat;
	char *helpname = NULL;
	char *recovername = NULL;
	char *linkname = NULL;
	char *p1;
	unsigned long long i_size;
	struct utimbuf   touchtime;
	mode_t i_mode;
	int major, minor, type;

#ifdef DEBUG
	printf("RECOVER : INODE=%ld FILENAME=%s/%s\n",inode_nr, pathname,filename);
	dump_inode(stdout, "",inode_nr, (struct ext2_inode *)inode, 0);
#endif	
	
	if (!(inode->i_mode & LINUX_S_IFMT)) //no type flag - no recover
		return 1;

	p1 = pathname;
	while   (*p1 == '/') p1++;
	helpname = malloc(strlen(des_dir) + 15);
	recovername = malloc(strlen(des_dir) + strlen(pathname) + strlen(filename) +10);
	if (helpname && recovername){	
		strcpy(helpname,des_dir);
		strcat(helpname,"/");
		strcpy(recovername,helpname);
		strcat(recovername,p1);
		if (strlen(p1)) 
			strcat(recovername,"/");
		strcat(recovername,filename);
		while (!(stat(recovername, &filestat)) && (i<5)){
			strcat(recovername,"#");
			i++;
		}

		p1 = strchr(helpname,0);
		sprintf(p1,"#%u#",inode_nr);
		unlink (helpname);

		priv.flag = flag;

//FIXME: hardlink
		if (inode->i_links_count > 1){
			p1 = check_link_stack(inode_nr, inode->i_generation);
			if (p1) {
				//hardlink found
				if (! stat(p1, &filestat)){
					retval = check_dir(recovername);
					if (retval)
						fprintf(stderr,"Unknown error at target directory by file: %s\ntrying to continue normal\n", recovername);
					else {
						if (! link(p1,recovername)){
							if (match_link_stack(inode_nr, inode->i_generation))
								rec_error  -= CREATE_ERROR ;
							goto out;
						}
						else{	
							rec_error  -= CREATE_ERROR ;
						}
					}
				}
			}
			else{
				//flag as hardlink
				hardlink = 1;
			}
		}

	
		switch (inode->i_mode  & LINUX_S_IFMT){
//regular File;
		case LINUX_S_IFREG :
			priv.fd = open(helpname, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRWXU);
			if (! priv.fd ){ 
				fprintf(stderr,"Error: open File %s for writing\n",helpname);
				retval = errno;
				goto errout;
			}
			buf=malloc(current_fs->blocksize);
			if (buf) {
				priv.buf = buf;
				priv.error = 0;
				// iterate Data Blocks and if not allocated, write to file
				retval = local_block_iterate3 ( current_fs, *inode, BLOCK_FLAG_DATA_ONLY, NULL, write_block, &priv );
#ifdef DEBUG
				printf("\n");
#endif
				if (retval || priv.error){
					// error or blocks allocated , we delete the tempfile and goto out
					close(priv.fd);
					unlink(helpname);
					retval = -1;
					goto errout;
				}
				else{
				i_size = (unsigned long long)(inode->i_size | ((unsigned long long)inode->i_size_high << 32));
					retval = ftruncate(priv.fd,i_size);
					if (retval){
						rec_error -= SEEK_ERROR ;	
					}
				}
		
			}
			else {
				fprintf(stderr,"ERROR: can no allocate memory\n");
				retval = -1;
				close(priv.fd);
				goto errout;
 			}
			close(priv.fd);
		 break;

//symbolic link	
		case LINUX_S_IFLNK :
			  if (ext2fs_inode_data_blocks(current_fs,inode)){
				buf = malloc(current_fs->blocksize + 1); 
				if (buf) {
					memset(buf,0,current_fs->blocksize + 1);
					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");
					retval = -1;
					goto errout;
	 			}
			}
			else {
				int i;
			
				if((! inode->i_size) || (inode->i_size >= 60)) 
					goto errout; 
				buf = malloc(inode->i_size + 1);
				linkname = (char*) &(inode->i_block[0]);
				for (i = 0; i < inode->i_size ; i++){
					*(buf+i) = (char) *linkname;
					linkname++;
				}		 
				*(buf+i) = 0;
			}
			linkname = buf;
			retval = symlink(linkname, helpname);
			if (retval){
				rec_error  -= (CREATE_ERROR + SEEK_ERROR);
			}
		break;

//block or char device
		case LINUX_S_IFBLK :
		case LINUX_S_IFCHR :
			type = (LINUX_S_ISBLK(inode->i_mode)) ? S_IFBLK : S_IFCHR ; 

        	        if (inode->i_block[0]) {
                	        major = (inode->i_block[0] >> 8) & 255;
                        	minor = inode->i_block[0] & 255;
                	} else {
Пример #3
0
/*
 * dump_jbd_metadata()
 *
 */
void dump_jbd_metadata(FILE *out, enum ocfs2_block_type type, char *buf,
                       uint64_t blknum)
{
    struct ocfs2_dir_block_trailer *trailer;
    struct ocfs2_xattr_block *xb;
    struct ocfs2_xattr_header *xh;
    struct ocfs2_refcount_block *rb;
    struct ocfs2_dx_root_block *dx_root;
    struct ocfs2_dx_leaf *dx_leaf;
    struct ocfs2_dinode *di;
    struct ocfs2_extent_block *eb;

    fprintf(out, "\tBlock %"PRIu64": ", blknum);
    switch (type) {
    case OCFS2_BLOCK_INODE:
    case OCFS2_BLOCK_SUPERBLOCK:
        fprintf(out, "Inode\n");
        di = (struct ocfs2_dinode *)buf;
        ocfs2_swap_inode_to_cpu(gbls.fs, di);
        dump_inode(out, di);
        if (di->i_flags & OCFS2_LOCAL_ALLOC_FL)
            dump_local_alloc(out, &(di->id2.i_lab));
        else if (di->i_flags & OCFS2_CHAIN_FL)
            dump_chain_list(out, &(di->id2.i_chain));
        else if (S_ISLNK(di->i_mode) && !di->i_clusters)
            dump_fast_symlink(out, (char *)di->id2.i_symlink);
        else if (di->i_flags & OCFS2_DEALLOC_FL)
            dump_truncate_log(out, &(di->id2.i_dealloc));
        else if (!(di->i_dyn_features & OCFS2_INLINE_DATA_FL))
            dump_extent_list(out, &(di->id2.i_list));
        fprintf(out, "\n");
        break;
    case OCFS2_BLOCK_EXTENT_BLOCK:
        fprintf(out, "Extent\n");
        eb = (struct ocfs2_extent_block *)buf;
        ocfs2_swap_extent_block_to_cpu(gbls.fs, eb);
        dump_extent_block(out, eb);
        dump_extent_list(out, &(eb->h_list));
        fprintf(out, "\n");
        break;
    case OCFS2_BLOCK_GROUP_DESCRIPTOR:
        fprintf(out, "Group\n");
        ocfs2_swap_group_desc_to_cpu(gbls.fs,
                                     (struct ocfs2_group_desc *)buf);
        dump_group_descriptor(out, (struct ocfs2_group_desc *)buf, 0);
        fprintf(out, "\n");
        break;
    case OCFS2_BLOCK_DIR_BLOCK:
        fprintf(out, "Dirblock\n");
        /*
         * We know there's a trailer, because that's how it
         * was detected
         */
        ocfs2_swap_dir_entries_to_cpu(buf,
                                      ocfs2_dir_trailer_blk_off(gbls.fs));
        trailer = ocfs2_dir_trailer_from_block(gbls.fs, buf);
        ocfs2_swap_dir_trailer(trailer);
        dump_dir_block(out, buf);
        fprintf(out, "\n");
        break;
    case OCFS2_BLOCK_XATTR:
        fprintf(out, "Xattr\n");
        xb = (struct ocfs2_xattr_block *)buf;
        ocfs2_swap_xattr_block_to_cpu(gbls.fs, xb);
        if (!(xb->xb_flags & OCFS2_XATTR_INDEXED)) {
            xh = &xb->xb_attrs.xb_header;
            dump_xattr(out, xh);
        }
        fprintf(out, "\n");
        break;
    case OCFS2_BLOCK_REFCOUNT:
        fprintf(out, "Refcount\n");
        rb = (struct ocfs2_refcount_block *)buf;
        ocfs2_swap_refcount_block_to_cpu(gbls.fs, rb);
        dump_refcount_block(out, rb);
        fprintf(out, "\n");
        break;
    case OCFS2_BLOCK_DXROOT:
        fprintf(out, "DxRoot\n");
        dx_root = (struct ocfs2_dx_root_block *)buf;
        ocfs2_swap_dx_root_to_cpu(gbls.fs, dx_root);
        dump_dx_root(out, dx_root);
        fprintf(out, "\n");
        break;
    case OCFS2_BLOCK_DXLEAF:
        fprintf(out, "DxLeaf\n");
        dx_leaf = (struct ocfs2_dx_leaf *)buf;
        ocfs2_swap_dx_leaf_to_cpu(dx_leaf);
        dump_dx_leaf(out, dx_leaf);
        fprintf(out, "\n");
        break;
    default:
        fprintf(out, "TODO\n\n");
        break;
    }

    return ;
}