diff --git a/INSTALL.md b/INSTALL.md
index b5d795b9..dbe9146a 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -45,7 +45,7 @@ __Optional dependencies__:
__Notes__:
* `libstb-dev` can be replaced by `libgraphicsmagick++1-dev` (the latter will likely use more RAM)
-You also need _Wt4_, which is not packaged on _Debian_. See [installation instructions](https://www.webtoolkit.eu/wt/doc/reference/html/InstallationUnix.html).
+You also need _Wt4_, which is not packaged on _Debian_. See [installation instructions](https://www.webtoolkit.eu/wt/doc/reference/html/InstallationUnix.html).
### Build
Get the latest stable release and build it:
```sh
@@ -99,9 +99,9 @@ systemctl restart lms
# Deployment
__Note__: don't forget to give the _lms_ user read access to the music directory you want to scan.
## Configuration
-_LMS_ uses a configuration file, installed by default in `/etc/lms.conf`. It is recommended to edit this file and change relevant settings (listen address, listen port, working directory, Subsonic API activation, deployment path, ...).
-All other settings are set using the web interface (user management, scan settings, transcode settings, ...).
-If a setting is not present in the configuration file, a hardcoded default value is used (the same as in the [default configuration file](conf/lms.conf))
+_LMS_ uses a configuration file installed by default at `/etc/lms.conf`. It is recommended to edit this file and adjust the relevant settings like the working directory, Wt resources path, listen address, listen port, etc.
+All other settings are configured through the web interface (user management, scan settings, transcode settings, etc.).
+If a setting is not present in the configuration file, a hardcoded default value is used (the same as in the [default configuration file](conf/lms.conf)).
## Authentication backends
You can define which authentication backend to be used thanks to the `authentication-backend` option:
* `internal` (default): _LMS_ uses an internal database to store users and their associated passwords (salted and hashed using [Bcrypt](https://en.wikipedia.org/wiki/Bcrypt)). Only the admin user can create, edit or remove other users.
diff --git a/src/lms/main.cpp b/src/lms/main.cpp
index 61890196..51f81923 100644
--- a/src/lms/main.cpp
+++ b/src/lms/main.cpp
@@ -17,6 +17,7 @@
* along with LMS. If not, see .
*/
+#include
#include
#include
@@ -110,19 +111,58 @@ namespace lms
throw core::LmsException{ "Invalid config value for 'jukebox-audio-backend'" };
}
- std::vector generateWtConfig(std::string execPath)
+ std::error_code checkDirectoryAccessible(const std::filesystem::path& dir)
+ {
+ std::error_code ec;
+
+ const std::filesystem::file_status status{ std::filesystem::status(dir, ec) };
+ if (ec)
+ return ec;
+
+ if (status.type() != std::filesystem::file_type::directory)
+ return std::make_error_code(std::errc::not_a_directory);
+
+ const std::filesystem::directory_iterator it{ dir, ec };
+ if (ec)
+ return ec;
+
+ if (it != std::filesystem::directory_iterator{})
+ {
+ it->status(ec);
+ if (ec)
+ return ec;
+ }
+
+ return {};
+ }
+
+ std::vector generateWtConfig(const std::string& execPath)
{
core::IConfig& config{ *core::Service::get() };
std::vector args;
- const std::filesystem::path wtConfigPath{ config.getPath("working-dir", "/var/lms") / "wt_config.xml" };
+ const std::filesystem::path workingDirectoryPath{ config.getPath("working-dir", "/var/lms") };
+ const std::filesystem::path wtConfigPath{ workingDirectoryPath / "wt_config.xml" };
const std::filesystem::path wtResourcesPath{ config.getPath("wt-resources", "/usr/share/Wt/resources") };
+ const std::filesystem::path appRootPath{ config.getString("approot", "/usr/share/lms/approot") };
+
+ auto checkDirectoryExists{ [](const std::filesystem::path& directory, std::string_view settingName) {
+ std::string error;
+
+ const std::error_code ec{ checkDirectoryAccessible(directory) };
+ if (ec)
+ throw core::LmsException{ "Cannot access directory '" + directory.string() + "' specified in setting '" + std::string{ settingName } + "': " + ec.message() };
+ } };
+
+ checkDirectoryExists(workingDirectoryPath, "working-dir");
+ checkDirectoryExists(wtResourcesPath, "wt-resources");
+ checkDirectoryExists(appRootPath, "approot");
args.push_back(execPath);
args.push_back("--config=" + wtConfigPath.string());
args.push_back("--docroot=" + std::string{ config.getString("docroot", "/usr/share/lms/docroot/;/resources,/css,/images,/js,/favicon.ico") });
- args.push_back("--approot=" + std::string{ config.getString("approot", "/usr/share/lms/approot") });
+ args.push_back("--approot=" + appRootPath.string());
args.push_back("--deploy-path=" + std::string{ config.getString("deploy-path", "/") });
if (!wtResourcesPath.empty())
args.push_back("--resources-dir=" + wtResourcesPath.string());