void directory_save(FILE *fp, struct directory *directory) { struct dirvec *children = &directory->children; size_t i; if (!directory_is_root(directory)) { fprintf(fp, DIRECTORY_MTIME "%lu\n", (unsigned long)directory->mtime); fprintf(fp, "%s%s\n", DIRECTORY_BEGIN, directory_get_path(directory)); } for (i = 0; i < children->nr; ++i) { struct directory *cur = children->base[i]; char *base = g_path_get_basename(cur->path); fprintf(fp, DIRECTORY_DIR "%s\n", base); g_free(base); directory_save(fp, cur); if (ferror(fp)) return; } songvec_save(fp, &directory->songs); if (!directory_is_root(directory)) fprintf(fp, DIRECTORY_END "%s\n", directory_get_path(directory)); }
const char * directory_get_name(const struct directory *directory) { assert(!directory_is_root(directory)); assert(directory->path != NULL); const char *slash = strrchr(directory->path, '/'); assert((slash == NULL) == directory_is_root(directory->parent)); return slash != NULL ? slash + 1 : directory->path; }
struct directory * directory_new_child(struct directory *parent, const char *name_utf8) { assert(holding_db_lock()); assert(parent != NULL); assert(name_utf8 != NULL); assert(*name_utf8 != 0); char *allocated; const char *path_utf8; if (directory_is_root(parent)) { allocated = NULL; path_utf8 = name_utf8; } else { allocated = g_strconcat(directory_get_path(parent), "/", name_utf8, NULL); path_utf8 = allocated; } struct directory *directory = directory_new(path_utf8, parent); g_free(allocated); list_add_tail(&directory->siblings, &parent->children); return directory; }
static struct directory * directory_load_subdir(FILE *fp, struct directory *parent, const char *name, GString *buffer, GError **error_r) { struct directory *directory; const char *line; bool success; if (directory_get_child(parent, name) != NULL) { g_set_error(error_r, directory_quark(), 0, "Duplicate subdirectory '%s'", name); return NULL; } if (directory_is_root(parent)) { directory = directory_new(name, parent); } else { char *path = g_strconcat(directory_get_path(parent), "/", name, NULL); directory = directory_new(path, parent); g_free(path); } line = read_text_line(fp, buffer); if (line == NULL) { g_set_error(error_r, directory_quark(), 0, "Unexpected end of file"); directory_free(directory); return NULL; } if (g_str_has_prefix(line, DIRECTORY_MTIME)) { directory->mtime = g_ascii_strtoull(line + sizeof(DIRECTORY_MTIME) - 1, NULL, 10); line = read_text_line(fp, buffer); if (line == NULL) { g_set_error(error_r, directory_quark(), 0, "Unexpected end of file"); directory_free(directory); return NULL; } } if (!g_str_has_prefix(line, DIRECTORY_BEGIN)) { g_set_error(error_r, directory_quark(), 0, "Malformed line: %s", line); directory_free(directory); return NULL; } success = directory_load(fp, directory, buffer, error_r); if (!success) { directory_free(directory); return NULL; } return directory; }
static int printDirectoryInDirectory(struct directory *directory, void *data) { struct client *client = data; if (!directory_is_root(directory)) client_printf(client, "directory: %s\n", directory_get_path(directory)); return 0; }
char * map_directory_fs(const struct directory *directory) { assert(music_dir != NULL); if (directory_is_root(directory)) return g_strdup(music_dir); return map_uri_fs(directory_get_path(directory)); }
static void print_playlist_in_directory(struct client *client, const struct directory *directory, const char *name_utf8) { if (directory_is_root(directory)) client_printf(client, "playlist: %s\n", name_utf8); else client_printf(client, "playlist: %s/%s\n", directory_get_path(directory), name_utf8); }
static bool print_visitor_directory(const struct directory *directory, void *data, G_GNUC_UNUSED GError **error_r) { struct client *client = data; if (!directory_is_root(directory)) client_printf(client, "directory: %s\n", directory_get_path(directory)); return true; }
char * song_get_uri(const struct song *song) { assert(song != NULL); assert(*song->uri); if (!song_in_database(song) || directory_is_root(song->parent)) return g_strdup(song->uri); else return g_strconcat(directory_get_path(song->parent), "/", song->uri, NULL); }
void song_print_url(struct client *client, struct song *song) { if (song_in_database(song) && !directory_is_root(song->parent)) { client_printf(client, "%s%s/%s\n", SONG_FILE, directory_get_path(song->parent), song->url); } else { char *allocated; const char *uri; uri = allocated = uri_remove_auth(song->url); if (uri == NULL) uri = song->url; client_printf(client, "%s%s\n", SONG_FILE, uri); g_free(allocated); } }
static struct directory * make_subdir(struct directory *parent, const char *name) { struct directory *directory; directory = directory_get_child(parent, name); if (directory == NULL) { char *path; if (directory_is_root(parent)) path = NULL; else name = path = g_strconcat(directory_get_path(parent), "/", name, NULL); directory = directory_new_child(parent, name); g_free(path); } return directory; }