Пример #1
0
errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name, 
		      ext2_ino_t ino, int flags)
{
	errcode_t	retval;
	struct link_struct ls;

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	if (!(fs->flags & EXT2_FLAG_RW))
		return EXT2_ET_RO_FILSYS;

	ls.name = name;
	ls.namelen = name ? strlen(name) : 0;
	ls.inode = ino;
	ls.flags = flags;
	ls.done = 0;
	ls.sb = fs->super;

	retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
				    0, link_proc, &ls);
	if (retval)
		return retval;

	return (ls.done) ? 0 : EXT2_ET_DIR_NO_SPACE;
}
Пример #2
0
static void rdump_inode(ext2_ino_t ino, struct ext2_inode *inode,
			const char *name, const char *dumproot)
{
	char *fullname;

	/* There are more efficient ways to do this, but this method
	 * requires only minimal debugging. */
	fullname = malloc(strlen(dumproot) + strlen(name) + 2);
	if (!fullname) {
		com_err("rdump", errno, "while allocating memory");
		return;
	}
	sprintf(fullname, "%s/%s", dumproot, name);

	if (LINUX_S_ISLNK(inode->i_mode))
		rdump_symlink(ino, inode, fullname);
	else if (LINUX_S_ISREG(inode->i_mode)) {
		int fd;
		fd = open(fullname, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRWXU);
		if (fd == -1) {
			com_err("rdump", errno, "while opening %s", fullname);
			goto errout;
		}
		dump_file("rdump", ino, fd, 1, fullname);
		if (close(fd) != 0) {
			com_err("rdump", errno, "while closing %s", fullname);
			goto errout;
		}
	}
	else if (LINUX_S_ISDIR(inode->i_mode) && strcmp(name, ".") && strcmp(name, "..")) {
		errcode_t retval;

		/* Create the directory with 0700 permissions, because we
		 * expect to have to create entries it.  Then fix its perms
		 * once we've done the traversal. */
		if (name[0] && mkdir(fullname, S_IRWXU) == -1) {
			com_err("rdump", errno, "while making directory %s", fullname);
			goto errout;
		}

		retval = ext2fs_dir_iterate(current_fs, ino, 0, 0,
					    rdump_dirent, (void *) fullname);
		if (retval)
			com_err("rdump", retval, "while dumping %s", fullname);

		fix_perms("rdump", inode, -1, fullname);
	}
	/* else do nothing (don't dump device files, sockets, fifos, etc.) */

errout:
	free(fullname);
}
Пример #3
0
errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
		      ext2_ino_t ino, int flags)
{
	errcode_t		retval;
	struct link_struct	ls;
	struct ext2_inode	inode;

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	if (!(fs->flags & EXT2_FLAG_RW))
		return EXT2_ET_RO_FILSYS;

	ls.fs = fs;
	ls.name = name;
	ls.namelen = name ? strlen(name) : 0;
	ls.inode = ino;
	ls.flags = flags;
	ls.done = 0;
	ls.sb = fs->super;
	ls.blocksize = fs->blocksize;
	ls.err = 0;

	retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
				    0, link_proc, &ls);
	if (retval)
		return retval;
	if (ls.err)
		return ls.err;

	if (!ls.done)
		return EXT2_ET_DIR_NO_SPACE;

	if ((retval = ext2fs_read_inode(fs, dir, &inode)) != 0)
		return retval;

	/*
	 * If this function changes to preserve the htree, remove the
	 * two hunks in link_proc that shove checksum tails into the
	 * former dx_root/dx_node blocks.
	 */
	if (inode.i_flags & EXT2_INDEX_FL) {
		inode.i_flags &= ~EXT2_INDEX_FL;
		if ((retval = ext2fs_write_inode(fs, dir, &inode)) != 0)
			return retval;
	}

	return 0;
}
Пример #4
0
errcode_t ext2fs_link(ext2_filsys fs, ext2_ino_t dir, const char *name,
		      ext2_ino_t ino, int flags)
{
	errcode_t		retval;
	struct link_struct	ls;
	struct ext2_inode	inode;

	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);

	if (!(fs->flags & EXT2_FLAG_RW))
		return EXT2_ET_RO_FILSYS;

	ls.fs = fs;
	ls.name = name;
	ls.namelen = name ? strlen(name) : 0;
	ls.inode = ino;
	ls.flags = flags;
	ls.done = 0;
	ls.sb = fs->super;
	ls.blocksize = fs->blocksize;
	ls.err = 0;

	retval = ext2fs_dir_iterate(fs, dir, DIRENT_FLAG_INCLUDE_EMPTY,
				    0, link_proc, &ls);
	if (retval)
		return retval;
	if (ls.err)
		return ls.err;

	if (!ls.done)
		return EXT2_ET_DIR_NO_SPACE;

	if ((retval = ext2fs_read_inode(fs, dir, &inode)) != 0)
		return retval;

	if (inode.i_flags & EXT2_INDEX_FL) {
		inode.i_flags &= ~EXT2_INDEX_FL;
		if ((retval = ext2fs_write_inode(fs, dir, &inode)) != 0)
			return retval;
	}

	return 0;
}
Пример #5
0
DIR_ITER *ext2_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path)
{
    ext2_log_trace("dirState %p, path %s\n", dirState, path);

    if(!dirState)
    {
        r->_errno = EINVAL;
        return NULL;
    }

    ext2_dir_state* dir = STATE(dirState);

    if(!dir)
    {
        r->_errno = EINVAL;
        return NULL;
    }

    // Get the volume descriptor for this path
    dir->vd = ext2GetVolume(path);
    if (!dir->vd) {
        r->_errno = ENODEV;
        return NULL;
    }

    // Lock
    ext2Lock(dir->vd);

    // Find the directory
    dir->ni = ext2OpenEntry(dir->vd, path);
    if (!dir->ni) {
        ext2Unlock(dir->vd);
        r->_errno = ENOENT;
        return NULL;
    }

    // Ensure that this directory is indeed a directory
    if (!LINUX_S_ISDIR(dir->ni->ni.i_mode)) {
        ext2CloseEntry(dir->vd, dir->ni);
        ext2Unlock(dir->vd);
        r->_errno = ENOTDIR;
        return NULL;
    }

    // Read the directory
    dir->first = dir->current = NULL;
    if (ext2fs_dir_iterate(dir->vd->fs, dir->ni->ino, 0, 0, DirIterateCallback, dirState) != EXT2_ET_OK) {
        ext2CloseDir(dir);
        ext2Unlock(dir->vd);
        r->_errno = errno;
        return NULL;
    }

    // Move to the first entry in the directory
    dir->current = dir->first;

    // Update directory times
    ext2UpdateTimes(dir->vd, dir->ni, EXT2_UPDATE_ATIME);

    // Insert the directory into the double-linked FILO list of open directories
    if (dir->vd->firstOpenDir) {
        dir->nextOpenDir = dir->vd->firstOpenDir;
        dir->vd->firstOpenDir->prevOpenDir = dir;
    } else {
        dir->nextOpenDir = NULL;
    }
    dir->prevOpenDir = NULL;
    dir->vd->cwd_ni = dir->ni;
    dir->vd->firstOpenDir = dir;
    dir->vd->openDirCount++;

    // Unlock
    ext2Unlock(dir->vd);

    return dirState;
}