static bool simple_db_visit(struct db *_db, const struct db_selection *selection, const struct db_visitor *visitor, void *ctx, GError **error_r) { const struct simple_db *db = (const struct simple_db *)_db; const struct directory *directory = simple_db_lookup_directory(db, selection->uri); if (directory == NULL) { struct song *song; if (visitor->song != NULL && (song = simple_db_get_song(_db, selection->uri, NULL)) != NULL) return visitor->song(song, ctx, error_r); g_set_error(error_r, db_quark(), DB_NOT_FOUND, "No such directory"); return false; } if (selection->recursive && visitor->directory != NULL && !visitor->directory(directory, ctx, error_r)) return false; return directory_walk(directory, selection->recursive, visitor, ctx, error_r); }
int directory_walk(struct directory *directory, int (*forEachSong)(struct song *, void *), int (*forEachDir)(struct directory *, void *), void *data) { struct dirvec *dv = &directory->children; int err = 0; size_t j; if (forEachDir && (err = forEachDir(directory, data)) < 0) return err; if (forEachSong) { err = songvec_for_each(&directory->songs, forEachSong, data); if (err < 0) return err; } for (j = 0; err >= 0 && j < dv->nr; ++j) err = directory_walk(dv->base[j], forEachSong, forEachDir, data); return err; }
static void directory_walk(struct minix_superblock *sb, unsigned long address) { unsigned long offset = 0; struct minix_dentry dentry; struct minix_inode inode; unsigned long inode_tbl_bass = get_inode_table_address(*sb); int i; while (1) { // read first entry. read_dentry(&dentry, address, offset); if (dentry.inode == 0) break; read_inode(dentry.inode, &inode, inode_tbl_bass); printf("inode:0x%x name %s\n", dentry.inode, dentry.name); printf("i_mode: 0x%x(0x%x)\n", inode.i_mode, get_file_type(&inode)); printf("i_nlinks: 0x%x\n", inode.i_nlinks); printf("uid: 0x%x\n", inode.i_uid); printf("gid: 0x%x\n", inode.i_gid); printf("i_size: 0x%x\n", inode.i_size); printf("i_atime: 0x%x\n", inode.i_atime); printf("i_mtime: 0x%x\n", inode.i_mtime); printf("i_ctime: 0x%x\n", inode.i_ctime); for (i = 0; i < NR_I_ZONE; i++) { if (inode.i_zone[i]) printf("zone[%d]: 0x%x(0x%x)\n", i, inode.i_zone[i], get_data_zone(inode.i_zone[i])); } if ((get_file_type(&inode) == I_FT_DIR) && (strcmp(dentry.name, ".")) && (strcmp(dentry.name, ".."))) directory_walk(sb, get_data_zone(inode.i_zone[0])); offset += sizeof(dentry) - 1; } }
bool directory_walk(const struct directory *directory, bool recursive, const struct db_visitor *visitor, void *ctx, GError **error_r) { assert(directory != NULL); assert(visitor != NULL); assert(error_r == NULL || *error_r == NULL); if (visitor->song != NULL) { const struct songvec *sv = &directory->songs; for (size_t i = 0; i < sv->nr; ++i) if (!visitor->song(sv->base[i], ctx, error_r)) return false; } if (visitor->playlist != NULL) { const struct playlist_vector *pv = &directory->playlists; for (const struct playlist_metadata *i = pv->head; i != NULL; i = i->next) if (!visitor->playlist(i, ctx, error_r)) return false; } const struct dirvec *dv = &directory->children; for (size_t i = 0; i < dv->nr; ++i) { struct directory *child = dv->base[i]; if (visitor->directory != NULL && !visitor->directory(child, ctx, error_r)) return false; if (recursive && !directory_walk(child, recursive, visitor, ctx, error_r)) return false; } return true; }
int main(int argc, char **argv) { struct minix_superblock sb; unsigned long size = 0; size = get_file_size(); file_system = map2memory(size); assert(file_system != NULL); read_superblock(&sb); print_superblock(&sb); printf("first data zone is 0x%x\n", get_first_data_zone(sb)); directory_walk(&sb, get_first_data_zone(sb)); find_file_test(&sb); read_file_test(&sb); munmap(file_system, size); return 0; }