enum playlist_result playlist_append_file(struct playlist *playlist, const char *path, int uid, unsigned *added_id) { int ret; struct stat st; struct song *song; if (uid < 0) { g_debug("unauthenticated client: %d", uid); return PLAYLIST_RESULT_DENIED; } ret = stat(path, &st); if (ret < 0) return PLAYLIST_RESULT_ERRNO; if (st.st_uid != (uid_t)uid && (st.st_mode & 0444) != 0444) { g_debug("client is not owner: %d (%o)", st.st_uid, st.st_mode); return PLAYLIST_RESULT_DENIED; } song = song_file_load(path, NULL); if (song == NULL) return PLAYLIST_RESULT_NO_SUCH_SONG; return playlist_append_song(playlist, song, added_id); }
enum playlist_result playlist_append_file(struct playlist *playlist, struct player_control *pc, const char *path, int uid, unsigned *added_id) { int ret; struct stat st; struct song *song; if (uid <= 0) /* unauthenticated client */ return PLAYLIST_RESULT_DENIED; ret = stat(path, &st); if (ret < 0) return PLAYLIST_RESULT_ERRNO; if (st.st_uid != (uid_t)uid && (st.st_mode & 0444) != 0444) /* client is not owner */ return PLAYLIST_RESULT_DENIED; song = song_file_load(path, NULL); if (song == NULL) return PLAYLIST_RESULT_NO_SUCH_SONG; return playlist_append_song(playlist, pc, song, added_id); }
static void update_regular_file(struct directory *directory, const char *name, const struct stat *st) { const char *suffix = uri_get_suffix(name); const struct decoder_plugin* plugin; #ifdef ENABLE_ARCHIVE const struct archive_plugin *archive; #endif if (suffix == NULL) return; if ((plugin = decoder_plugin_from_suffix(suffix, false)) != NULL) { struct song* song = songvec_find(&directory->songs, name); if (!(song != NULL && st->st_mtime == song->mtime && !walk_discard) && plugin->container_scan != NULL) { if (update_container_file(directory, name, st, plugin)) { if (song != NULL) delete_song(directory, song); return; } } if (song == NULL) { song = song_file_load(name, directory); if (song == NULL) { g_debug("ignoring unrecognized file %s/%s", directory_get_path(directory), name); return; } songvec_add(&directory->songs, song); modified = true; g_message("added %s/%s", directory_get_path(directory), name); } else if (st->st_mtime != song->mtime || walk_discard) { g_message("updating %s/%s", directory_get_path(directory), name); if (!song_file_update(song)) { g_debug("deleting unrecognized file %s/%s", directory_get_path(directory), name); delete_song(directory, song); } modified = true; } #ifdef ENABLE_ARCHIVE } else if ((archive = archive_plugin_from_suffix(suffix))) { update_archive_file(directory, name, st, archive); #endif } }
static struct song * playlist_check_load_song(const struct song *song, const char *uri, bool secure) { struct song *dest; if (uri_has_scheme(uri)) { dest = song_remote_new(uri); } else if (g_path_is_absolute(uri) && secure) { dest = song_file_load(uri, NULL); if (dest == NULL) return NULL; } else { dest = db_get_song(uri); if (dest == NULL) /* not found in database */ return NULL; } return apply_song_metadata(dest, song); }
static void update_archive_tree(struct directory *directory, char *name) { struct directory *subdir; struct song *song; char *tmp; tmp = strchr(name, '/'); if (tmp) { *tmp = 0; //add dir is not there already if ((subdir = dirvec_find(&directory->children, name)) == NULL) { //create new directory subdir = make_subdir(directory, name); subdir->device = DEVICE_INARCHIVE; } //create directories first update_archive_tree(subdir, tmp+1); } else { if (strlen(name) == 0) { g_warning("archive returned directory only"); return; } //add file song = songvec_find(&directory->songs, name); if (song == NULL) { song = song_file_load(name, directory); if (song != NULL) { songvec_add(&directory->songs, song); modified = true; g_message("added %s/%s", directory_get_path(directory), name); } } } }
static void update_song_file2(struct directory *directory, const char *name, const struct stat *st, const struct decoder_plugin *plugin) { db_lock(); struct song *song = directory_get_song(directory, name); db_unlock(); if (!directory_child_access(directory, name, R_OK)) { g_warning("no read permissions on %s/%s", directory_get_path(directory), name); if (song != NULL) { db_lock(); delete_song(directory, song); db_unlock(); } return; } if (!(song != NULL && st->st_mtime == song->mtime && !walk_discard) && update_container_file(directory, name, st, plugin)) { if (song != NULL) { db_lock(); delete_song(directory, song); db_unlock(); } return; } if (song == NULL) { g_debug("reading %s/%s", directory_get_path(directory), name); song = song_file_load(name, directory); if (song == NULL) { g_debug("ignoring unrecognized file %s/%s", directory_get_path(directory), name); return; } db_lock(); directory_add_song(directory, song); db_unlock(); modified = true; g_message("added %s/%s", directory_get_path(directory), name); } else if (st->st_mtime != song->mtime || walk_discard) { g_message("updating %s/%s", directory_get_path(directory), name); if (!song_file_update(song)) { g_debug("deleting unrecognized file %s/%s", directory_get_path(directory), name); db_lock(); delete_song(directory, song); db_unlock(); } modified = true; } }
struct song * playlist_check_translate_song(struct song *song, const char *base_uri, bool secure) { struct song *dest; if (song_in_database(song)) /* already ok */ return song; char *uri = song->uri; if (uri_has_scheme(uri)) { if (uri_supported_scheme(uri)) /* valid remote song */ return song; else { /* unsupported remote song */ song_free(song); return NULL; } } if (base_uri != NULL && strcmp(base_uri, ".") == 0) /* g_path_get_dirname() returns "." when there is no directory name in the given path; clear that now, because it would break the database lookup functions */ base_uri = NULL; if (g_path_is_absolute(uri)) { /* XXX fs_charset vs utf8? */ const char *prefix = mapper_get_music_directory(); if (prefix != NULL && g_str_has_prefix(uri, prefix) && uri[strlen(prefix)] == '/') uri += strlen(prefix) + 1; else if (!secure) { /* local files must be relative to the music directory when "secure" is enabled */ song_free(song); return NULL; } base_uri = NULL; } if (base_uri != NULL) uri = g_build_filename(base_uri, uri, NULL); else uri = g_strdup(uri); if (uri_has_scheme(uri)) { dest = song_remote_new(uri); g_free(uri); } else if (g_path_is_absolute(uri) && secure) { dest = song_file_load(uri, NULL); if (dest == NULL) { song_free(song); return NULL; } } else { dest = db_get_song(uri); g_free(uri); if (dest == NULL) { /* not found in database */ song_free(song); return dest; } } dest = apply_song_metadata(dest, song); song_free(song); return dest; }