From 8d18b4c24b776fe62c39ad9ce72e1e57ac0aa3ea Mon Sep 17 00:00:00 2001
From: Eugene Gorodinsky <eugene2k@users.noreply.github.com>
Date: Tue, 16 Apr 2019 13:28:08 +0300
Subject: [PATCH 1/5] Fix meson.build to work properly with '-Ddatabase=false'

---
 NEWS               | 1 +
 meson.build        | 4 +++-
 src/db/meson.build | 5 +++++
 3 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index e0d567722..542905467 100644
--- a/NEWS
+++ b/NEWS
@@ -4,6 +4,7 @@ ver 0.21.8 (not yet released)
   - httpd: fix use-after-free bug
 * fix Bonjour bug
 * fix build failure with GCC 9
+* fix build failure with -Ddatabase=false
 * systemd: add user socket unit
 
 ver 0.21.7 (2019/04/03)
diff --git a/meson.build b/meson.build
index 466d1149d..40fe2e182 100644
--- a/meson.build
+++ b/meson.build
@@ -367,8 +367,10 @@ basic_dep = declare_dependency(
 
 if enable_database
   subdir('src/storage')
-  subdir('src/db')
+else
+  storage_glue_dep = dependency('', required: false)
 endif
+subdir('src/db')
 
 if neighbor_glue_dep.found()
   sources += 'src/command/NeighborCommands.cxx'
diff --git a/src/db/meson.build b/src/db/meson.build
index 3ad0be246..4f2b32f8e 100644
--- a/src/db/meson.build
+++ b/src/db/meson.build
@@ -9,6 +9,11 @@ db_api_dep = declare_dependency(
   link_with: db_api,
 )
 
+if not enable_database
+  db_glue_dep = db_api_dep
+  subdir_done()
+endif
+
 subdir('plugins')
 
 db_glue_sources = [

From d6dbf64efb9f6e678ad67647d42ed120fc581c37 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Thu, 18 Apr 2019 09:20:12 +0200
Subject: [PATCH 2/5] CommandLine: fix another build failure with
 -Ddatabase=false

Split several printf() calls to make it easier to deal with all those
#ifdefs.
---
 src/CommandLine.cxx | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/CommandLine.cxx b/src/CommandLine.cxx
index b820e396b..5ede49580 100644
--- a/src/CommandLine.cxx
+++ b/src/CommandLine.cxx
@@ -108,17 +108,17 @@ static constexpr Domain cmdline_domain("cmdline");
 gcc_noreturn
 static void version(void)
 {
-	printf("Music Player Daemon " VERSION " (%s)\n"
+	printf("Music Player Daemon " VERSION " (%s)"
 	       "\n"
 	       "Copyright 2003-2007 Warren Dukes <warren.dukes@gmail.com>\n"
 	       "Copyright 2008-2018 Max Kellermann <max.kellermann@gmail.com>\n"
 	       "This is free software; see the source for copying conditions.  There is NO\n"
-	       "warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
+	       "warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
+	       GIT_VERSION);
 
 #ifdef ENABLE_DATABASE
-	       "\n"
-	       "Database plugins:\n",
-	       GIT_VERSION);
+	printf("\n"
+	       "Database plugins:\n");
 
 	for (auto i = database_plugins; *i != nullptr; ++i)
 		printf(" %s", (*i)->name);
@@ -129,18 +129,18 @@ static void version(void)
 	for (auto i = storage_plugins; *i != nullptr; ++i)
 		printf(" %s", (*i)->name);
 
-	printf("\n"
+	printf("\n");
 #endif
 
 #ifdef ENABLE_NEIGHBOR_PLUGINS
-	       "\n"
+	printf("\n"
 	       "Neighbor plugins:\n");
 	for (auto i = neighbor_plugins; *i != nullptr; ++i)
 		printf(" %s", (*i)->name);
 
-	printf("\n"
 #endif
 
+	printf("\n"
 	       "\n"
 	       "Decoders plugins:\n");
 

From f5b4606c096f388efaf154227b99ae33c7accfd8 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 16 Apr 2019 11:36:17 +0200
Subject: [PATCH 3/5] .travis.yml: switch to another PPA for a newer ninja
 version

Fixes Travis failure with Meson 0.50:

 ERROR: Could not detect Ninja v1.5 or newer
---
 .travis.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/.travis.yml b/.travis.yml
index b0f9bc831..99df7d698 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,7 +9,7 @@ matrix:
           sources:
             - ubuntu-toolchain-r-test
             - sourceline: 'ppa:mhier/libboost-latest'
-            - sourceline: 'ppa:saiarcot895/chromium-dev' # for ninja-build
+            - sourceline: 'ppa:mstipicevic/ninja-build-1-7-2'
             - sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson)
           packages:
             - g++-6
@@ -34,7 +34,7 @@ matrix:
           sources:
             - ubuntu-toolchain-r-test
             - sourceline: 'ppa:mhier/libboost-latest'
-            - sourceline: 'ppa:saiarcot895/chromium-dev' # for ninja-build
+            - sourceline: 'ppa:mstipicevic/ninja-build-1-7-2'
             - sourceline: 'ppa:deadsnakes/ppa' # for Python 3.7 (required by Meson)
           packages:
             - g++-8

From 7d814cc899111583c9ddfc3aa17d38f8a15796e0 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Tue, 16 Apr 2019 20:07:48 +0200
Subject: [PATCH 4/5] neighbor/smbclient: fix double smbc_closedir() call

There is already one call in ReadServers(), which is the correct place
to do it.
---
 src/neighbor/plugins/SmbclientNeighborPlugin.cxx | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
index 4ed196bef..d6b426f74 100644
--- a/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
+++ b/src/neighbor/plugins/SmbclientNeighborPlugin.cxx
@@ -150,8 +150,6 @@ ReadServers(NeighborExplorer::List &list, int fd)
 	smbc_dirent *e;
 	while ((e = smbc_readdir(fd)) != nullptr)
 		ReadEntry(list, *e);
-
-	smbc_closedir(fd);
 }
 
 static void

From ead3dc6a92b7631e65ccd4df8e514e8b431c71c6 Mon Sep 17 00:00:00 2001
From: Max Kellermann <max@musicpd.org>
Date: Thu, 18 Apr 2019 10:03:15 +0200
Subject: [PATCH 5/5] LocateUri: pass URI plugin kind, optionally disables
 plugin verify

Commit b3a458338a7c8ff3c230ee33d85e973d3dbc056a added a LocateUri()
call to several playlist commands, which applied InputPlugin URI
scheme verification to playlist URIs.  This broke the SoundCloud
playlist plugin which uses "soundcloud://" URIs for which no input
plugin exists.

This commit allows the caller to specify the kind of plugin which
shall be used to verify the URI.  Right now, only "input" is
implemented; "storage" uses the "input" verification for now; and
"playlist" has no verification at all (for now).

Closes https://github.com/MusicPlayerDaemon/MPD/issues/528
---
 NEWS                             |  2 ++
 src/LocateUri.cxx                | 23 ++++++++++++++++++-----
 src/LocateUri.hxx                |  9 ++++++++-
 src/SongLoader.cxx               |  3 ++-
 src/command/FileCommands.cxx     |  4 ++--
 src/command/OtherCommands.cxx    |  4 ++--
 src/command/PlaylistCommands.cxx |  9 ++++++---
 src/command/QueueCommands.cxx    |  3 ++-
 8 files changed, 42 insertions(+), 15 deletions(-)

diff --git a/NEWS b/NEWS
index 542905467..c0c91d028 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,8 @@ ver 0.21.8 (not yet released)
 * output
   - httpd: add missing mutex lock
   - httpd: fix use-after-free bug
+* playlist
+  - soundcloud: fix "Unsupported URI scheme" (0.21.6 regression)
 * fix Bonjour bug
 * fix build failure with GCC 9
 * fix build failure with -Ddatabase=false
diff --git a/src/LocateUri.cxx b/src/LocateUri.cxx
index dba43b0de..7d82f5436 100644
--- a/src/LocateUri.cxx
+++ b/src/LocateUri.cxx
@@ -55,14 +55,26 @@ LocateFileUri(const char *uri, const Client *client
 }
 
 static LocatedUri
-LocateAbsoluteUri(const char *uri
+LocateAbsoluteUri(UriPluginKind kind, const char *uri
 #ifdef ENABLE_DATABASE
 		  , const Storage *storage
 #endif
 		  )
 {
-	if (!uri_supported_scheme(uri))
-		throw std::runtime_error("Unsupported URI scheme");
+	switch (kind) {
+	case UriPluginKind::INPUT:
+	case UriPluginKind::STORAGE: // TODO: separate check for storage plugins
+		if (!uri_supported_scheme(uri))
+			throw std::runtime_error("Unsupported URI scheme");
+		break;
+
+	case UriPluginKind::PLAYLIST:
+		/* for now, no validation for playlist URIs; this is
+		   more complicated because there are three ways to
+		   identify which plugin to use: URI scheme, filename
+		   suffix and MIME type */
+		break;
+	}
 
 #ifdef ENABLE_DATABASE
 	if (storage != nullptr) {
@@ -76,7 +88,8 @@ LocateAbsoluteUri(const char *uri
 }
 
 LocatedUri
-LocateUri(const char *uri, const Client *client
+LocateUri(UriPluginKind kind,
+	  const char *uri, const Client *client
 #ifdef ENABLE_DATABASE
 	  , const Storage *storage
 #endif
@@ -100,7 +113,7 @@ LocateUri(const char *uri, const Client *client
 #endif
 				     );
 	else if (uri_has_scheme(uri))
-		return LocateAbsoluteUri(uri
+		return LocateAbsoluteUri(kind, uri
 #ifdef ENABLE_DATABASE
 					 , storage
 #endif
diff --git a/src/LocateUri.hxx b/src/LocateUri.hxx
index 953671d79..c0bf8ec2f 100644
--- a/src/LocateUri.hxx
+++ b/src/LocateUri.hxx
@@ -41,6 +41,12 @@ class Client;
 class Storage;
 #endif
 
+enum class UriPluginKind {
+	INPUT,
+	STORAGE,
+	PLAYLIST,
+};
+
 struct LocatedUri {
 	enum class Type {
 		/**
@@ -84,7 +90,8 @@ struct LocatedUri {
  * that feature is disabled if this parameter is nullptr
  */
 LocatedUri
-LocateUri(const char *uri, const Client *client
+LocateUri(UriPluginKind kind,
+	  const char *uri, const Client *client
 #ifdef ENABLE_DATABASE
 	  , const Storage *storage
 #endif
diff --git a/src/SongLoader.cxx b/src/SongLoader.cxx
index ad96ecfec..fee94f8b3 100644
--- a/src/SongLoader.cxx
+++ b/src/SongLoader.cxx
@@ -94,7 +94,8 @@ SongLoader::LoadSong(const char *uri_utf8) const
 	assert(uri_utf8 != nullptr);
 #endif
 
-	const auto located_uri = LocateUri(uri_utf8, client
+	const auto located_uri = LocateUri(UriPluginKind::INPUT,
+					   uri_utf8, client
 #ifdef ENABLE_DATABASE
 					   , storage
 #endif
diff --git a/src/command/FileCommands.cxx b/src/command/FileCommands.cxx
index c0e88abff..448da2caf 100644
--- a/src/command/FileCommands.cxx
+++ b/src/command/FileCommands.cxx
@@ -218,7 +218,7 @@ handle_read_comments(Client &client, Request args, Response &r)
 
 	const char *const uri = args.front();
 
-	const auto located_uri = LocateUri(uri, &client
+	const auto located_uri = LocateUri(UriPluginKind::INPUT, uri, &client
 #ifdef ENABLE_DATABASE
 					   , nullptr
 #endif
@@ -331,7 +331,7 @@ handle_album_art(Client &client, Request args, Response &r)
 	const char *uri = args.front();
 	size_t offset = args.ParseUnsigned(1);
 
-	const auto located_uri = LocateUri(uri, &client
+	const auto located_uri = LocateUri(UriPluginKind::INPUT, uri, &client
 #ifdef ENABLE_DATABASE
 					   , nullptr
 #endif
diff --git a/src/command/OtherCommands.cxx b/src/command/OtherCommands.cxx
index 5228868d9..f441c73e0 100644
--- a/src/command/OtherCommands.cxx
+++ b/src/command/OtherCommands.cxx
@@ -99,7 +99,7 @@ handle_listfiles(Client &client, Request args, Response &r)
 	/* default is root directory */
 	const auto uri = args.GetOptional(0, "");
 
-	const auto located_uri = LocateUri(uri, &client
+	const auto located_uri = LocateUri(UriPluginKind::STORAGE, uri, &client
 #ifdef ENABLE_DATABASE
 					   , nullptr
 #endif
@@ -219,7 +219,7 @@ handle_lsinfo(Client &client, Request args, Response &r)
 		   compatibility, work around this here */
 		uri = "";
 
-	const auto located_uri = LocateUri(uri, &client
+	const auto located_uri = LocateUri(UriPluginKind::INPUT, uri, &client
 #ifdef ENABLE_DATABASE
 					   , nullptr
 #endif
diff --git a/src/command/PlaylistCommands.cxx b/src/command/PlaylistCommands.cxx
index 89b64ff6f..2914ea82b 100644
--- a/src/command/PlaylistCommands.cxx
+++ b/src/command/PlaylistCommands.cxx
@@ -69,7 +69,8 @@ handle_save(Client &client, Request args, gcc_unused Response &r)
 CommandResult
 handle_load(Client &client, Request args, gcc_unused Response &r)
 {
-	const auto uri = LocateUri(args.front(), &client
+	const auto uri = LocateUri(UriPluginKind::PLAYLIST, args.front(),
+				   &client
 #ifdef ENABLE_DATABASE
 					   , nullptr
 #endif
@@ -99,7 +100,8 @@ handle_load(Client &client, Request args, gcc_unused Response &r)
 CommandResult
 handle_listplaylist(Client &client, Request args, Response &r)
 {
-	const auto name = LocateUri(args.front(), &client
+	const auto name = LocateUri(UriPluginKind::PLAYLIST, args.front(),
+				    &client
 #ifdef ENABLE_DATABASE
 					   , nullptr
 #endif
@@ -115,7 +117,8 @@ handle_listplaylist(Client &client, Request args, Response &r)
 CommandResult
 handle_listplaylistinfo(Client &client, Request args, Response &r)
 {
-	const auto name = LocateUri(args.front(), &client
+	const auto name = LocateUri(UriPluginKind::PLAYLIST, args.front(),
+				    &client
 #ifdef ENABLE_DATABASE
 					   , nullptr
 #endif
diff --git a/src/command/QueueCommands.cxx b/src/command/QueueCommands.cxx
index 3c3e32e2f..c0bb8c95b 100644
--- a/src/command/QueueCommands.cxx
+++ b/src/command/QueueCommands.cxx
@@ -83,7 +83,8 @@ handle_add(Client &client, Request args, Response &r)
 		   here */
 		uri = "";
 
-	const auto located_uri = LocateUri(uri, &client
+	const auto located_uri = LocateUri(UriPluginKind::INPUT, uri,
+					   &client
 #ifdef ENABLE_DATABASE
 					   , nullptr
 #endif