char *ext4fs_read_symlink(struct ext2fs_node *node) { char *symlink; struct ext2fs_node *diro = node; int status, ret; if (!diro->inode_read) { ret = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); if (ret) return NULL; } symlink = zalloc(__le32_to_cpu(diro->inode.size) + 1); if (!symlink) return 0; if (__le32_to_cpu(diro->inode.size) <= 60) { strncpy(symlink, diro->inode.b.symlink, __le32_to_cpu(diro->inode.size)); } else { status = ext4fs_read_file(diro, 0, __le32_to_cpu(diro->inode.size), symlink); if (status == 0) { free(symlink); return NULL; } } symlink[__le32_to_cpu(diro->inode.size)] = '\0'; return symlink; }
static struct dirent *ext_readdir(struct device_d *dev, DIR *dir) { struct ext4fs_dir *ext4_dir = dir->priv; struct ext2_dirent dirent; struct ext2fs_node *diro = ext4_dir->dirnode; int ret; char *filename; if (ext4_dir->fpos >= __le32_to_cpu(diro->inode.size)) return NULL; ret = ext4fs_read_file(diro, ext4_dir->fpos, sizeof(struct ext2_dirent), (char *) &dirent); if (ret < 0) return NULL; if (dirent.namelen == 0) return NULL; filename = xzalloc(dirent.namelen + 1); ret = ext4fs_read_file(diro, ext4_dir->fpos + sizeof(struct ext2_dirent), dirent.namelen, filename); if (ret < 0) { free(filename); return NULL; } filename[dirent.namelen] = '\0'; ext4_dir->fpos += __le16_to_cpu(dirent.direntlen); strcpy(dir->d.d_name, filename); free(filename); return &dir->d; }
int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, struct ext2fs_node **fnode, int *ftype) { unsigned int fpos = 0; int status, ret; struct ext2fs_node *diro = (struct ext2fs_node *) dir; struct ext_filesystem *fs = dir->data->fs; if (name != NULL) dev_dbg(fs->dev, "Iterate dir %s\n", name); if (!diro->inode_read) { ret = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); if (ret) return ret; } /* Search the file. */ while (fpos < __le32_to_cpu(diro->inode.size)) { struct ext2_dirent dirent; status = ext4fs_read_file(diro, fpos, sizeof(struct ext2_dirent), (char *) &dirent); if (status < 1) return -EINVAL; if (dirent.namelen != 0) { char filename[dirent.namelen + 1]; struct ext2fs_node *fdiro; int type = FILETYPE_UNKNOWN; status = ext4fs_read_file(diro, fpos + sizeof(struct ext2_dirent), dirent.namelen, filename); if (status < 1) return -EINVAL; fdiro = zalloc(sizeof(struct ext2fs_node)); if (!fdiro) return -ENOMEM; fdiro->data = diro->data; fdiro->ino = __le32_to_cpu(dirent.inode); filename[dirent.namelen] = '\0'; if (dirent.filetype != FILETYPE_UNKNOWN) { fdiro->inode_read = 0; if (dirent.filetype == FILETYPE_DIRECTORY) type = FILETYPE_DIRECTORY; else if (dirent.filetype == FILETYPE_SYMLINK) type = FILETYPE_SYMLINK; else if (dirent.filetype == FILETYPE_REG) type = FILETYPE_REG; } else { ret = ext4fs_read_inode(diro->data, __le32_to_cpu (dirent.inode), &fdiro->inode); if (ret) { free(fdiro); return ret; } fdiro->inode_read = 1; if ((__le16_to_cpu(fdiro->inode.mode) & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) { type = FILETYPE_DIRECTORY; } else if ((__le16_to_cpu(fdiro->inode.mode) & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) { type = FILETYPE_SYMLINK; } else if ((__le16_to_cpu(fdiro->inode.mode) & FILETYPE_INO_MASK) == FILETYPE_INO_REG) { type = FILETYPE_REG; } } dev_dbg(fs->dev, "iterate >%s<\n", filename); if (strcmp(filename, name) == 0) { *ftype = type; *fnode = fdiro; return 0; } free(fdiro); } fpos += __le16_to_cpu(dirent.direntlen); } return -ENOENT; }
static int ext_read(struct device_d *_dev, FILE *f, void *buf, size_t insize) { return ext4fs_read_file(f->inode, f->pos, insize, buf); }
int ext4fs_iterate_dir(struct ext2fs_node *dir, char *name, struct ext2fs_node **fnode, int *ftype) { unsigned int fpos = 0; int status; struct ext2fs_node *diro = (struct ext2fs_node *)dir; #ifdef DEBUG if (name != NULL) printf("Iterate dir %s\n", name); #endif /* of DEBUG */ if (!diro->inode_read) { status = ext4fs_read_inode(diro->data, diro->ino, &diro->inode); if (status == 0) return 0; } /* Search the file. */ while (fpos < __le32_to_cpu(diro->inode.size)) { struct ext2_dirent dirent; status = ext4fs_read_file(diro, fpos, sizeof(struct ext2_dirent), (char *)&dirent); if (status < 1) return 0; if (dirent.namelen != 0) { char filename[dirent.namelen + 1]; struct ext2fs_node *fdiro; int type = FILETYPE_UNKNOWN; status = ext4fs_read_file(diro, fpos + sizeof(struct ext2_dirent), dirent.namelen, filename); if (status < 1) return 0; fdiro = zalloc(sizeof(struct ext2fs_node)); if (!fdiro) return 0; fdiro->data = diro->data; fdiro->ino = __le32_to_cpu(dirent.inode); filename[dirent.namelen] = '\0'; if (dirent.filetype != FILETYPE_UNKNOWN) { fdiro->inode_read = 0; if (dirent.filetype == FILETYPE_DIRECTORY) type = FILETYPE_DIRECTORY; else if (dirent.filetype == FILETYPE_SYMLINK) type = FILETYPE_SYMLINK; else if (dirent.filetype == FILETYPE_REG) type = FILETYPE_REG; } else { status = ext4fs_read_inode(diro->data, __le32_to_cpu (dirent.inode), &fdiro->inode); if (status == 0) { free(fdiro); return 0; } fdiro->inode_read = 1; if ((__le16_to_cpu(fdiro->inode.mode) & FILETYPE_INO_MASK) == FILETYPE_INO_DIRECTORY) { type = FILETYPE_DIRECTORY; } else if ((__le16_to_cpu(fdiro->inode.mode) & FILETYPE_INO_MASK) == FILETYPE_INO_SYMLINK) { type = FILETYPE_SYMLINK; } else if ((__le16_to_cpu(fdiro->inode.mode) & FILETYPE_INO_MASK) == FILETYPE_INO_REG) { type = FILETYPE_REG; } } #ifdef DEBUG printf("iterate >%s<\n", filename); #endif /* of DEBUG */ if ((name != NULL) && (fnode != NULL) && (ftype != NULL)) { if (strcmp(filename, name) == 0) { *ftype = type; *fnode = fdiro; return 1; } } else { if (fdiro->inode_read == 0) { status = ext4fs_read_inode(diro->data, __le32_to_cpu( dirent.inode), &fdiro->inode); if (status == 0) { free(fdiro); return 0; } fdiro->inode_read = 1; } switch (type) { case FILETYPE_DIRECTORY: printf("<DIR> "); break; case FILETYPE_SYMLINK: printf("<SYM> "); break; case FILETYPE_REG: printf(" "); break; default: printf("< ? > "); break; } printf("%10d %s\n", __le32_to_cpu(fdiro->inode.size), filename); } free(fdiro); } fpos += __le16_to_cpu(dirent.direntlen); } return 0; }