diff --git a/Makefile.am b/Makefile.am index cb7dafa1b..2e5d8b613 100644 --- a/Makefile.am +++ b/Makefile.am @@ -410,6 +410,7 @@ libfs_a_SOURCES = \ src/fs/TextFile.cxx src/fs/TextFile.hxx \ src/fs/FileSystem.cxx src/fs/FileSystem.hxx \ src/fs/StandardDirectory.cxx src/fs/StandardDirectory.hxx \ + src/fs/CheckFile.cxx src/fs/CheckFile.hxx \ src/fs/DirectoryReader.hxx # Storage library diff --git a/src/Mapper.cxx b/src/Mapper.cxx index e6d7c3900..be58b49c9 100644 --- a/src/Mapper.cxx +++ b/src/Mapper.cxx @@ -26,16 +26,9 @@ #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 -#include -#include - -static constexpr Domain mapper_domain("mapper"); #ifdef ENABLE_DATABASE @@ -53,37 +46,6 @@ 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); -} - #ifdef ENABLE_DATABASE static void @@ -93,9 +55,7 @@ mapper_set_music_dir(AllocatedPath &&path) music_dir_fs = std::move(path); - const auto music_dir_utf8 = music_dir_fs.ToUTF8(); - - check_directory(music_dir_utf8.c_str(), music_dir_fs); + CheckDirectoryReadable(music_dir_fs); } #endif @@ -107,8 +67,7 @@ mapper_set_playlist_dir(AllocatedPath &&path) 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 diff --git a/src/fs/CheckFile.cxx b/src/fs/CheckFile.cxx new file mode 100644 index 000000000..a35443674 --- /dev/null +++ b/src/fs/CheckFile.cxx @@ -0,0 +1,62 @@ +/* + * 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 + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "CheckFile.hxx" +#include "Log.hxx" +#include "config/ConfigError.hxx" +#include "FileSystem.hxx" +#include "Path.hxx" +#include "AllocatedPath.hxx" +#include "DirectoryReader.hxx" + +#include +#include + +void +CheckDirectoryReadable(Path path_fs) +{ + struct stat st; + if (!StatFile(path_fs, st)) { + FormatErrno(config_domain, + "Failed to stat directory \"%s\"", + path_fs.c_str()); + return; + } + + if (!S_ISDIR(st.st_mode)) { + FormatError(config_domain, + "Not a directory: %s", path_fs.c_str()); + return; + } + +#ifndef WIN32 + const auto x = AllocatedPath::Build(path_fs, "."); + if (!StatFile(x, st) && errno == EACCES) + FormatError(config_domain, + "No permission to traverse (\"execute\") directory: %s", + path_fs.c_str()); +#endif + + const DirectoryReader reader(path_fs); + if (reader.HasFailed() && errno == EACCES) + FormatError(config_domain, + "No permission to read directory: %s", path_fs.c_str()); + +} diff --git a/src/fs/CheckFile.hxx b/src/fs/CheckFile.hxx new file mode 100644 index 000000000..00559647d --- /dev/null +++ b/src/fs/CheckFile.hxx @@ -0,0 +1,34 @@ +/* + * 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 + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef MPD_FS_CHECK_FILE_HXX +#define MPD_FS_CHECK_FILE_HXX + +#include "check.h" + +class Path; + +/** + * Check whether the directory is readable and usable. Logs a warning + * if there is a problem. + */ +void +CheckDirectoryReadable(Path path_fs); + +#endif