示例#1
0
static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
			     ext2_ino_t inode, int link_count,
			     char *buf, ext2_ino_t *res_inode)
{
	char *pathname;
	char *buffer = 0;
	errcode_t retval;
	struct ext2_inode ei;
	blk64_t blk;

#ifdef NAMEI_DEBUG
	printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
	       root, dir, inode, link_count);

#endif
	retval = ext2fs_read_inode (fs, inode, &ei);
	if (retval) return retval;
	if (!LINUX_S_ISLNK (ei.i_mode)) {
		*res_inode = inode;
		return 0;
	}
	if (link_count++ >= EXT2FS_MAX_NESTED_LINKS)
		return EXT2_ET_SYMLINK_LOOP;

	if (ext2fs_inode_data_blocks(fs,&ei)) {
		retval = ext2fs_bmap2(fs, inode, &ei, NULL, 0, 0, NULL, &blk);
		if (retval)
			return retval;

		retval = ext2fs_get_mem(fs->blocksize, &buffer);
		if (retval)
			return retval;

		retval = io_channel_read_blk64(fs->io, blk, 1, buffer);
		if (retval) {
			ext2fs_free_mem(&buffer);
			return retval;
		}
		pathname = buffer;
	} else
		pathname = (char *)&(ei.i_block[0]);
	retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
			    link_count, buf, res_inode);
	if (buffer)
		ext2fs_free_mem(&buffer);
	return retval;
}
示例#2
0
static errcode_t follow_link(ext2_filsys fs, ext2_ino_t root, ext2_ino_t dir,
			     ext2_ino_t inode, int link_count,
			     char *buf, ext2_ino_t *res_inode)
{
	char *pathname;
	char *buffer = 0;
	errcode_t retval;
	struct ext2_inode ei;

#ifdef NAMEI_DEBUG
	printf("follow_link: root=%lu, dir=%lu, inode=%lu, lc=%d\n",
	       root, dir, inode, link_count);

#endif
	retval = ext2fs_read_inode (fs, inode, &ei);
	if (retval) return retval;
	if (!LINUX_S_ISLNK (ei.i_mode)) {
		*res_inode = inode;
		return 0;
	}
	if (link_count++ > 5) {
		return EXT2_ET_SYMLINK_LOOP;
	}
	/* FIXME-64: Actually, this is FIXME EXTENTS */
	if (ext2fs_inode_data_blocks(fs,&ei)) {
		retval = ext2fs_get_mem(fs->blocksize, &buffer);
		if (retval)
			return retval;
		retval = io_channel_read_blk(fs->io, ei.i_block[0], 1, buffer);
		if (retval) {
			ext2fs_free_mem(&buffer);
			return retval;
		}
		pathname = buffer;
	} else
		pathname = (char *)&(ei.i_block[0]);
	retval = open_namei(fs, root, dir, pathname, ei.i_size, 1,
			    link_count, buf, res_inode);
	if (buffer)
		ext2fs_free_mem(&buffer);
	return retval;
}
示例#3
0
void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
			    struct ext2_inode_large *f, int hostorder,
			    int bufsize)
{
	unsigned i, has_data_blocks, extra_isize, attr_magic;
	int has_extents = 0;
	int islnk = 0;
	__u32 *eaf, *eat;

	if (hostorder && LINUX_S_ISLNK(f->i_mode))
		islnk = 1;
	t->i_mode = ext2fs_swab16(f->i_mode);
	if (!hostorder && LINUX_S_ISLNK(t->i_mode))
		islnk = 1;
	t->i_uid = ext2fs_swab16(f->i_uid);
	t->i_size = ext2fs_swab32(f->i_size);
	t->i_atime = ext2fs_swab32(f->i_atime);
	t->i_ctime = ext2fs_swab32(f->i_ctime);
	t->i_mtime = ext2fs_swab32(f->i_mtime);
	t->i_dtime = ext2fs_swab32(f->i_dtime);
	t->i_gid = ext2fs_swab16(f->i_gid);
	t->i_links_count = ext2fs_swab16(f->i_links_count);
	t->i_file_acl = ext2fs_swab32(f->i_file_acl);
	if (hostorder)
		has_data_blocks = ext2fs_inode_data_blocks(fs,
					   (struct ext2_inode *) f);
	t->i_blocks = ext2fs_swab32(f->i_blocks);
	if (!hostorder)
		has_data_blocks = ext2fs_inode_data_blocks(fs,
					   (struct ext2_inode *) t);
	if (hostorder && (f->i_flags & EXT4_EXTENTS_FL))
		has_extents = 1;
	t->i_flags = ext2fs_swab32(f->i_flags);
	if (!hostorder && (t->i_flags & EXT4_EXTENTS_FL))
		has_extents = 1;
	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
	
	if (!has_extents && (!islnk || has_data_blocks)) {
		for (i = 0; i < EXT2_N_BLOCKS; i++)
			t->i_block[i] = ext2fs_swab32(f->i_block[i]);
	} else if (t != f) {
		for (i = 0; i < EXT2_N_BLOCKS; i++)
			t->i_block[i] = f->i_block[i];
	}
	t->i_generation = ext2fs_swab32(f->i_generation);
	t->i_faddr = ext2fs_swab32(f->i_faddr);

	switch (fs->super->s_creator_os) {
	case EXT2_OS_LINUX:
		t->osd1.linux1.l_i_version =
			ext2fs_swab32(f->osd1.linux1.l_i_version);
		t->osd2.linux2.l_i_blocks_hi =
			ext2fs_swab16(f->osd2.linux2.l_i_blocks_hi);
		t->osd2.linux2.l_i_file_acl_high =
			ext2fs_swab16(f->osd2.linux2.l_i_file_acl_high);
		t->osd2.linux2.l_i_uid_high =
		  ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
		t->osd2.linux2.l_i_gid_high =
		  ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
		t->osd2.linux2.l_i_reserved2 =
			ext2fs_swab32(f->osd2.linux2.l_i_reserved2);
		break;
	case EXT2_OS_HURD:
		t->osd1.hurd1.h_i_translator =
		  ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
		t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
		t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
		t->osd2.hurd2.h_i_mode_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
		t->osd2.hurd2.h_i_uid_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
		t->osd2.hurd2.h_i_gid_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
		t->osd2.hurd2.h_i_author =
		  ext2fs_swab32 (f->osd2.hurd2.h_i_author);
		break;
	default:
		break;
	}

	if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
		return; 

	if (hostorder)
		extra_isize = f->i_extra_isize;
	t->i_extra_isize = ext2fs_swab16(f->i_extra_isize);
	if (!hostorder)
		extra_isize = t->i_extra_isize;
	if (extra_isize > EXT2_INODE_SIZE(fs->super) -
				sizeof(struct ext2_inode)) {
		
		return;
	}

	i = sizeof(struct ext2_inode) + extra_isize + sizeof(__u32);
	if (bufsize < (int) i)
		return; 

	eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) +
					extra_isize);

	attr_magic = *eaf;
	if (!hostorder)
		attr_magic = ext2fs_swab32(attr_magic);

	if (attr_magic != EXT2_EXT_ATTR_MAGIC)
		return; 

	eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) +
					extra_isize);
	*eat = ext2fs_swab32(*eaf);

	
	ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
			     bufsize - sizeof(struct ext2_inode) -
			     extra_isize - sizeof(__u32), 0);

}
示例#4
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 {
示例#5
0
void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
			    struct ext2_inode_large *f, int hostorder,
			    int bufsize)
{
	unsigned i;
	int islnk = 0;
	__u32 *eaf, *eat;

	if (hostorder && LINUX_S_ISLNK(f->i_mode))
		islnk = 1;
	t->i_mode = ext2fs_swab16(f->i_mode);
	if (!hostorder && LINUX_S_ISLNK(t->i_mode))
		islnk = 1;
	t->i_uid = ext2fs_swab16(f->i_uid);
	t->i_size = ext2fs_swab32(f->i_size);
	t->i_atime = ext2fs_swab32(f->i_atime);
	t->i_ctime = ext2fs_swab32(f->i_ctime);
	t->i_mtime = ext2fs_swab32(f->i_mtime);
	t->i_dtime = ext2fs_swab32(f->i_dtime);
	t->i_gid = ext2fs_swab16(f->i_gid);
	t->i_links_count = ext2fs_swab16(f->i_links_count);
	t->i_blocks = ext2fs_swab32(f->i_blocks);
	t->i_flags = ext2fs_swab32(f->i_flags);
	t->i_file_acl = ext2fs_swab32(f->i_file_acl);
	t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
	if (!islnk || ext2fs_inode_data_blocks(fs, (struct ext2_inode *)t)) {
		for (i = 0; i < EXT2_N_BLOCKS; i++)
			t->i_block[i] = ext2fs_swab32(f->i_block[i]);
	} else if (t != f) {
		for (i = 0; i < EXT2_N_BLOCKS; i++)
			t->i_block[i] = f->i_block[i];
	}
	t->i_generation = ext2fs_swab32(f->i_generation);
	t->i_faddr = ext2fs_swab32(f->i_faddr);

	switch (fs->super->s_creator_os) {
	case EXT2_OS_LINUX:
		t->osd1.linux1.l_i_reserved1 =
			ext2fs_swab32(f->osd1.linux1.l_i_reserved1);
		t->osd2.linux2.l_i_frag = f->osd2.linux2.l_i_frag;
		t->osd2.linux2.l_i_fsize = f->osd2.linux2.l_i_fsize;
		t->osd2.linux2.i_pad1 = ext2fs_swab16(f->osd2.linux2.i_pad1);
		t->osd2.linux2.l_i_uid_high =
		  ext2fs_swab16 (f->osd2.linux2.l_i_uid_high);
		t->osd2.linux2.l_i_gid_high =
		  ext2fs_swab16 (f->osd2.linux2.l_i_gid_high);
		t->osd2.linux2.l_i_reserved2 =
			ext2fs_swab32(f->osd2.linux2.l_i_reserved2);
		break;
	case EXT2_OS_HURD:
		t->osd1.hurd1.h_i_translator =
		  ext2fs_swab32 (f->osd1.hurd1.h_i_translator);
		t->osd2.hurd2.h_i_frag = f->osd2.hurd2.h_i_frag;
		t->osd2.hurd2.h_i_fsize = f->osd2.hurd2.h_i_fsize;
		t->osd2.hurd2.h_i_mode_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_mode_high);
		t->osd2.hurd2.h_i_uid_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_uid_high);
		t->osd2.hurd2.h_i_gid_high =
		  ext2fs_swab16 (f->osd2.hurd2.h_i_gid_high);
		t->osd2.hurd2.h_i_author =
		  ext2fs_swab32 (f->osd2.hurd2.h_i_author);
		break;
	case EXT2_OS_MASIX:
		t->osd1.masix1.m_i_reserved1 =
			ext2fs_swab32(f->osd1.masix1.m_i_reserved1);
		t->osd2.masix2.m_i_frag = f->osd2.masix2.m_i_frag;
		t->osd2.masix2.m_i_fsize = f->osd2.masix2.m_i_fsize;
		t->osd2.masix2.m_pad1 = ext2fs_swab16(f->osd2.masix2.m_pad1);
		t->osd2.masix2.m_i_reserved2[0] =
			ext2fs_swab32(f->osd2.masix2.m_i_reserved2[0]);
		t->osd2.masix2.m_i_reserved2[1] =
			ext2fs_swab32(f->osd2.masix2.m_i_reserved2[1]);
		break;
	}

	if (bufsize < (int) (sizeof(struct ext2_inode) + sizeof(__u16)))
		return; /* no i_extra_isize field */

	t->i_extra_isize = ext2fs_swab16(f->i_extra_isize);
	if (t->i_extra_isize > EXT2_INODE_SIZE(fs->super) -
				sizeof(struct ext2_inode)) {
		/* this is error case: i_extra_size is too large */
		return;
	}

	i = sizeof(struct ext2_inode) + t->i_extra_isize + sizeof(__u32);
	if (bufsize < (int) i)
		return; /* no space for EA magic */

	eaf = (__u32 *) (((char *) f) + sizeof(struct ext2_inode) +
					f->i_extra_isize);

	if (ext2fs_swab32(*eaf) != EXT2_EXT_ATTR_MAGIC)
		return; /* it seems no magic here */

	eat = (__u32 *) (((char *) t) + sizeof(struct ext2_inode) +
					f->i_extra_isize);
	*eat = ext2fs_swab32(*eaf);

	/* convert EA(s) */
	ext2fs_swap_ext_attr((char *) (eat + 1), (char *) (eaf + 1),
			     bufsize - sizeof(struct ext2_inode) -
			     t->i_extra_isize - sizeof(__u32), 0);

}
示例#6
0
int op_readlink (const char *path, char *buf, size_t size)
{
	int rt;
	size_t s;
	errcode_t rc;
	ext2_ino_t ino;
	char *b = NULL;
	char *pathname;
	struct ext2_inode inode;
	ext2_filsys e2fs;
	FUSE_EXT2_LOCK;
	e2fs	= current_ext2fs();
	
	debugf("enter");
	debugf("path = %s", path);

	rt = do_readinode(e2fs, path, &ino, &inode);
	if (rt) {
		debugf("do_readinode(%s, &ino, &inode); failed", path);
		goto err;
	}
	
	if (!LINUX_S_ISLNK(inode.i_mode)) {
		debugf("%s is not a link", path);
		rt = -EINVAL;
		goto err;
	}
	
	if (ext2fs_inode_data_blocks(e2fs, &inode)) {
		rc = ext2fs_get_mem(EXT2_BLOCK_SIZE(e2fs->super), &b);
		if (rc) {
			debugf("ext2fs_get_mem(EXT2_BLOCK_SIZE(e2fs->super), &b); failed");
			rt = -ENOMEM;
			goto err;
		}
		rc = io_channel_read_blk(e2fs->io, inode.i_block[0], 1, b);
		if (rc) {
			ext2fs_free_mem(&b);
			debugf("io_channel_read_blk(e2fs->io, inode.i_block[0], 1, b); failed");
			rt = -EIO;
			goto err;
		}
		pathname = b;
	} else {
		pathname = (char *) &(inode.i_block[0]);
	}
	
	debugf("pathname: %s", pathname);
	
	s = (size < strlen(pathname) + 1) ? size : strlen(pathname) + 1;
	snprintf(buf, s, "%s", pathname);
	
	if (b) {
		ext2fs_free_mem(&b);
	}

	debugf("leave");
	FUSE_EXT2_UNLOCK;
	return 0;
err:
	FUSE_EXT2_UNLOCK;
	return rt;
}