diff options
Diffstat (limited to 'src/Mapper.cxx')
-rw-r--r-- | src/Mapper.cxx | 187 |
1 files changed, 25 insertions, 162 deletions
diff --git a/src/Mapper.cxx b/src/Mapper.cxx index cbe45daa0..7baad9459 100644 --- a/src/Mapper.cxx +++ b/src/Mapper.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -23,36 +23,18 @@ #include "config.h" #include "Mapper.hxx" -#include "Directory.hxx" -#include "Song.hxx" #include "fs/AllocatedPath.hxx" #include "fs/Traits.hxx" #include "fs/Charset.hxx" -#include "fs/FileSystem.hxx" -#include "fs/DirectoryReader.hxx" -#include "util/Domain.hxx" -#include "Log.hxx" +#include "fs/CheckFile.hxx" -#include <assert.h> -#include <string.h> -#include <sys/stat.h> -#include <unistd.h> -#include <errno.h> -#include <dirent.h> - -static constexpr Domain mapper_domain("mapper"); - -/** - * The absolute path of the music directory encoded in UTF-8. - */ -static std::string music_dir_utf8; -static size_t music_dir_utf8_length; +#ifdef ENABLE_DATABASE +#include "storage/StorageInterface.hxx" +#include "Instance.hxx" +#include "Main.hxx" +#endif -/** - * The absolute path of the music directory encoded in the filesystem - * character set. - */ -static AllocatedPath music_dir_fs = AllocatedPath::Null(); +#include <assert.h> /** * The absolute path of the playlist directory encoded in the @@ -61,67 +43,18 @@ static AllocatedPath music_dir_fs = AllocatedPath::Null(); static AllocatedPath playlist_dir_fs = AllocatedPath::Null(); static void -check_directory(const char *path_utf8, const AllocatedPath &path_fs) -{ - struct stat st; - if (!StatFile(path_fs, st)) { - FormatErrno(mapper_domain, - "Failed to stat directory \"%s\"", - path_utf8); - return; - } - - if (!S_ISDIR(st.st_mode)) { - FormatError(mapper_domain, - "Not a directory: %s", path_utf8); - return; - } - -#ifndef WIN32 - const auto x = AllocatedPath::Build(path_fs, "."); - if (!StatFile(x, st) && errno == EACCES) - FormatError(mapper_domain, - "No permission to traverse (\"execute\") directory: %s", - path_utf8); -#endif - - const DirectoryReader reader(path_fs); - if (reader.HasFailed() && errno == EACCES) - FormatError(mapper_domain, - "No permission to read directory: %s", path_utf8); -} - -static void -mapper_set_music_dir(AllocatedPath &&path) -{ - assert(!path.IsNull()); - - music_dir_fs = std::move(path); - music_dir_fs.ChopSeparators(); - - music_dir_utf8 = music_dir_fs.ToUTF8(); - music_dir_utf8_length = music_dir_utf8.length(); - - check_directory(music_dir_utf8.c_str(), music_dir_fs); -} - -static void mapper_set_playlist_dir(AllocatedPath &&path) { assert(!path.IsNull()); playlist_dir_fs = std::move(path); - const auto utf8 = playlist_dir_fs.ToUTF8(); - check_directory(utf8.c_str(), playlist_dir_fs); + CheckDirectoryReadable(playlist_dir_fs); } void -mapper_init(AllocatedPath &&_music_dir, AllocatedPath &&_playlist_dir) +mapper_init(AllocatedPath &&_playlist_dir) { - if (!_music_dir.IsNull()) - mapper_set_music_dir(std::move(_music_dir)); - if (!_playlist_dir.IsNull()) mapper_set_playlist_dir(std::move(_playlist_dir)); } @@ -130,30 +63,7 @@ void mapper_finish(void) { } -const char * -mapper_get_music_directory_utf8(void) -{ - return music_dir_utf8.empty() - ? nullptr - : music_dir_utf8.c_str(); -} - -const AllocatedPath & -mapper_get_music_directory_fs(void) -{ - return music_dir_fs; -} - -const char * -map_to_relative_path(const char *path_utf8) -{ - return !music_dir_utf8.empty() && - memcmp(path_utf8, music_dir_utf8.c_str(), - music_dir_utf8_length) == 0 && - PathTraits::IsSeparatorUTF8(path_utf8[music_dir_utf8_length]) - ? path_utf8 + music_dir_utf8_length + 1 - : path_utf8; -} +#ifdef ENABLE_DATABASE AllocatedPath map_uri_fs(const char *uri) @@ -161,6 +71,10 @@ map_uri_fs(const char *uri) assert(uri != nullptr); assert(*uri != '/'); + if (instance->storage == nullptr) + return AllocatedPath::Null(); + + const auto music_dir_fs = instance->storage->MapFS(""); if (music_dir_fs.IsNull()) return AllocatedPath::Null(); @@ -171,70 +85,17 @@ map_uri_fs(const char *uri) return AllocatedPath::Build(music_dir_fs, uri_fs); } -AllocatedPath -map_directory_fs(const Directory &directory) -{ - assert(!music_dir_fs.IsNull()); - - if (directory.IsRoot()) - return music_dir_fs; - - return map_uri_fs(directory.GetPath()); -} - -AllocatedPath -map_directory_child_fs(const Directory &directory, const char *name) -{ - assert(!music_dir_fs.IsNull()); - - /* check for invalid or unauthorized base names */ - if (*name == 0 || strchr(name, '/') != nullptr || - strcmp(name, ".") == 0 || strcmp(name, "..") == 0) - return AllocatedPath::Null(); - - const auto parent_fs = map_directory_fs(directory); - if (parent_fs.IsNull()) - return AllocatedPath::Null(); - - const auto name_fs = AllocatedPath::FromUTF8(name); - if (name_fs.IsNull()) - return AllocatedPath::Null(); - - return AllocatedPath::Build(parent_fs, name_fs); -} - -/** - * Map a song object that was created by song_dup_detached(). It does - * not have a real parent directory, only the dummy object - * #detached_root. - */ -static AllocatedPath -map_detached_song_fs(const char *uri_utf8) -{ - auto uri_fs = AllocatedPath::FromUTF8(uri_utf8); - if (uri_fs.IsNull()) - return uri_fs; - - return AllocatedPath::Build(music_dir_fs, uri_fs); -} - -AllocatedPath -map_song_fs(const Song &song) -{ - assert(song.IsFile()); - - if (song.IsInDatabase()) - return song.IsDetached() - ? map_detached_song_fs(song.uri) - : map_directory_child_fs(*song.parent, song.uri); - else - return AllocatedPath::FromUTF8(song.uri); -} - std::string map_fs_to_utf8(const char *path_fs) { - if (PathTraits::IsSeparatorFS(path_fs[0])) { + if (PathTraitsFS::IsSeparator(path_fs[0])) { + if (instance->storage == nullptr) + return std::string(); + + const auto music_dir_fs = instance->storage->MapFS(""); + if (music_dir_fs.IsNull()) + return std::string(); + path_fs = music_dir_fs.RelativeFS(path_fs); if (path_fs == nullptr || *path_fs == 0) return std::string(); @@ -243,6 +104,8 @@ map_fs_to_utf8(const char *path_fs) return PathToUTF8(path_fs); } +#endif + const AllocatedPath & map_spl_path(void) { |