#include "music.h" #include struct directory *music_root = NULL; gboolean music_init(const gchar *path) { music_root = g_new0(struct directory, 1); music_root->path = g_strdup(path); g_debug("added music root %s", path); return 1; } gboolean music_scan(struct directory *directory) { GError *error = NULL; GDir *dir = g_dir_open(directory->path, 0, &error); if(dir == NULL) { g_error("%s", error->message); g_error_free(error); return 0; } const gchar *entry; while((entry = g_dir_read_name(dir)) != NULL) { struct stat st; gchar *fullpath = g_build_filename(directory->path, entry, NULL); if(fullpath == NULL) { g_error("g_build_filename returned NULL"); } if(g_stat(fullpath, &st) < 0) { g_warning("g_stat failed on %s", fullpath); } if(S_ISREG(st.st_mode)) { struct file *f = g_new0(struct file, 1); f->name = g_strdup(entry); if(directory->files == NULL) { directory->files = f; } else { struct file *last = directory->files; while(last->next) last = last->next; last->next = f; } g_debug("added file %s to %s", entry, directory->path); } else if(S_ISDIR(st.st_mode)) { struct directory *d = g_new0(struct directory, 1); d->path = g_build_filename(directory->path, entry, NULL); if(directory->sub == NULL) { directory->sub = d; } else { struct directory *last = directory->sub; while(last->next) last = last->next; last->next = d; } g_debug("added subdir %s to %s", entry, directory->path); g_debug("recursing into %s", entry); music_scan(d); } } g_dir_close(dir); return 1; } gboolean music_scan_root() { g_assert(music_root != NULL); return music_scan(music_root); } static struct directory *music_find_dir_rec(struct directory *root, const gchar *path) { if(g_strcmp0(root->path, path) == 0) return root; for(struct directory *d = root->sub; d; d = d->next) { if(g_strcmp0(d->path, path) == 0) { return d; } struct directory *temp = music_find_dir_rec(d, path); if(temp) { return temp; } } return NULL; } struct directory *music_find_dir(const gchar *path) { return music_find_dir_rec(music_root, path); } static void music_do_free(struct directory *root) { struct directory *node; g_assert(root != NULL); for(node = root->sub; node; node = node->next) { music_do_free(node); } for(node = root->next; node; node = node->next) { music_do_free(node); } for(struct file *f = root->files; f; f = f->next) { g_free(f->name); g_free(f); } g_free(root->path); g_free(root); } void music_free() { g_assert(music_root != NULL); music_do_free(music_root); music_root = NULL; }