return inode_num;
}
+/* Creates a special file on disk. Returns the inode number of the new file */
+u32 make_special(const char *path)
+{
+ struct ext4_inode *inode;
+ struct stat s;
+ u32 inode_num;
+
+ if (stat(path, &s)) {
+ error("failed to stat file\n");
+ return EXT4_ALLOCATE_FAILED;
+ }
+
+ inode_num = allocate_inode(info);
+ if (inode_num == EXT4_ALLOCATE_FAILED) {
+ error("failed to allocate inode\n");
+ return EXT4_ALLOCATE_FAILED;
+ }
+
+ inode = get_inode(inode_num);
+ if (inode == NULL) {
+ error("failed to get inode %u", inode_num);
+ return EXT4_ALLOCATE_FAILED;
+ }
+
+ inode->i_mode = s.st_mode & S_IFMT;
+ inode->i_links_count = 1;
+ inode->i_flags |= aux_info.default_i_flags;
+
+ ((u8 *)inode->i_block)[0] = major(s.st_rdev);
+ ((u8 *)inode->i_block)[1] = minor(s.st_rdev);
+
+ return inode_num;
+}
+
int inode_set_permissions(u32 inode_num, u16 mode, u16 uid, u16 gid, u32 mtime)
{
struct ext4_inode *inode = get_inode(inode_num);
u32 dirs);
u32 make_file(const char *filename, u64 len);
u32 make_link(const char *link);
+u32 make_special(const char *path);
int inode_set_permissions(u32 inode_num, u16 mode, u16 uid, u16 gid, u32 mtime);
int inode_set_selinux(u32 inode_num, const char *secon);
int inode_set_capabilities(u32 inode_num, uint64_t capabilities);
/* TODO: Not implemented:
Allocating blocks in the same block group as the file inode
Hash or binary tree directories
- Special files: sockets, devices, fifos
*/
static int filter_dot(const struct dirent *d)
free(subdir_dir_path);
} else if (dentries[i].file_type == EXT4_FT_SYMLINK) {
entry_inode = make_link(dentries[i].link);
+ } else if (dentries[i].file_type == EXT4_FT_CHRDEV ||
+ dentries[i].file_type == EXT4_FT_BLKDEV ||
+ dentries[i].file_type == EXT4_FT_SOCK ||
+ dentries[i].file_type == EXT4_FT_FIFO) {
+ entry_inode = make_special(dentries[i].full_path);
} else {
error("unknown file type on %s", dentries[i].path);
entry_inode = 0;