Merge branch 'v0.22.x'

This commit is contained in:
Max Kellermann
2021-05-17 19:33:15 +02:00
18 changed files with 314 additions and 102 deletions

View File

@@ -423,6 +423,10 @@ CurlInputStream::InitEasy()
request->SetOption(CURLOPT_MAXREDIRS, 5L);
request->SetOption(CURLOPT_FAILONERROR, 1L);
/* this option eliminates the probe request when
username/password are specified */
request->SetOption(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
if (proxy != nullptr)
request->SetOption(CURLOPT_PROXY, proxy);

View File

@@ -1,19 +1,20 @@
diff -ur curl-7.63.0.orig/lib/url.c curl-7.63.0/lib/url.c
--- curl-7.63.0.orig/lib/url.c 2019-01-21 10:15:51.368019445 +0100
+++ curl-7.63.0/lib/url.c 2019-01-21 10:19:16.307523984 +0100
@@ -3057,6 +3057,7 @@
Index: curl-7.71.1/lib/url.c
===================================================================
--- curl-7.71.1.orig/lib/url.c
+++ curl-7.71.1/lib/url.c
@@ -2871,6 +2871,7 @@
}
conn->bits.netrc = FALSE;
+#ifndef __BIONIC__
if(data->set.use_netrc != CURL_NETRC_IGNORED &&
(!*userp || !**userp || !*passwdp || !**passwdp)) {
if(data->set.use_netrc && !data->set.str[STRING_USERNAME]) {
bool netrc_user_changed = FALSE;
@@ -3090,6 +3091,7 @@
}
bool netrc_passwd_changed = FALSE;
@@ -2895,6 +2896,7 @@
conn->bits.user_passwd = TRUE; /* enable user+password */
}
}
+#endif
/* for updated strings, we update them in the URL */
if(user_changed) {
if(*userp) {

182
src/lib/jack/Dynamic.hxx Normal file
View File

@@ -0,0 +1,182 @@
/*
* Copyright 2003-2021 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 "system/Error.hxx"
/* sorry for this horrible piece of code - there's no elegant way to
load DLLs at runtime */
#ifdef __GNUC__
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wcast-function-type"
#endif
using jack_set_error_function_t = std::add_pointer_t<decltype(jack_set_error_function)>;
static jack_set_error_function_t _jack_set_error_function;
using jack_set_info_function_t = std::add_pointer_t<decltype(jack_set_info_function)>;
static jack_set_info_function_t _jack_set_info_function;
using jack_client_open_t = std::add_pointer_t<decltype(jack_client_open)>;
static jack_client_open_t _jack_client_open;
using jack_client_close_t = std::add_pointer_t<decltype(jack_client_close)>;
static jack_client_close_t _jack_client_close;
using jack_connect_t = std::add_pointer_t<decltype(jack_connect)>;
static jack_connect_t _jack_connect;
using jack_activate_t = std::add_pointer_t<decltype(jack_activate)>;
static jack_activate_t _jack_activate;
using jack_deactivate_t = std::add_pointer_t<decltype(jack_deactivate)>;
static jack_deactivate_t _jack_deactivate;
using jack_get_sample_rate_t = std::add_pointer_t<decltype(jack_get_sample_rate)>;
static jack_get_sample_rate_t _jack_get_sample_rate;
using jack_set_process_callback_t = std::add_pointer_t<decltype(jack_set_process_callback)>;
static jack_set_process_callback_t _jack_set_process_callback;
using jack_on_info_shutdown_t = std::add_pointer_t<decltype(jack_on_info_shutdown)>;
static jack_on_info_shutdown_t _jack_on_info_shutdown;
using jack_free_t = std::add_pointer_t<decltype(jack_free)>;
static jack_free_t _jack_free;
using jack_get_ports_t = std::add_pointer_t<decltype(jack_get_ports)>;
static jack_get_ports_t _jack_get_ports;
using jack_port_register_t = std::add_pointer_t<decltype(jack_port_register)>;
static jack_port_register_t _jack_port_register;
using jack_port_name_t = std::add_pointer_t<decltype(jack_port_name)>;
static jack_port_name_t _jack_port_name;
using jack_port_get_buffer_t = std::add_pointer_t<decltype(jack_port_get_buffer)>;
static jack_port_get_buffer_t _jack_port_get_buffer;
using jack_ringbuffer_create_t = std::add_pointer_t<decltype(jack_ringbuffer_create)>;
static jack_ringbuffer_create_t _jack_ringbuffer_create;
using jack_ringbuffer_free_t = std::add_pointer_t<decltype(jack_ringbuffer_free)>;
static jack_ringbuffer_free_t _jack_ringbuffer_free;
using jack_ringbuffer_get_write_vector_t = std::add_pointer_t<decltype(jack_ringbuffer_get_write_vector)>;
static jack_ringbuffer_get_write_vector_t _jack_ringbuffer_get_write_vector;
using jack_ringbuffer_write_advance_t = std::add_pointer_t<decltype(jack_ringbuffer_write_advance)>;
static jack_ringbuffer_write_advance_t _jack_ringbuffer_write_advance;
using jack_ringbuffer_read_space_t = std::add_pointer_t<decltype(jack_ringbuffer_read_space)>;
static jack_ringbuffer_read_space_t _jack_ringbuffer_read_space;
using jack_ringbuffer_read_t = std::add_pointer_t<decltype(jack_ringbuffer_read)>;
static jack_ringbuffer_read_t _jack_ringbuffer_read;
using jack_ringbuffer_read_advance_t = std::add_pointer_t<decltype(jack_ringbuffer_read_advance)>;
static jack_ringbuffer_read_advance_t _jack_ringbuffer_read_advance;
using jack_ringbuffer_reset_t = std::add_pointer_t<decltype(jack_ringbuffer_reset)>;
static jack_ringbuffer_reset_t _jack_ringbuffer_reset;
template<typename T>
static void
GetFunction(HMODULE h, const char *name, T &result)
{
auto f = GetProcAddress(h, name);
if (f == nullptr)
throw FormatRuntimeError("No such libjack function: %s", name);
result = reinterpret_cast<T>(f);
}
static void
LoadJackLibrary()
{
#ifdef _WIN64
#define LIBJACK "libjack64"
#else
#define LIBJACK "libjack"
#endif
auto libjack = LoadLibraryA(LIBJACK);
if (!libjack)
throw FormatLastError("Failed to load " LIBJACK ".dll");
GetFunction(libjack, "jack_set_error_function", _jack_set_error_function);
GetFunction(libjack, "jack_set_info_function", _jack_set_info_function);
GetFunction(libjack, "jack_client_open", _jack_client_open);
GetFunction(libjack, "jack_client_close", _jack_client_close);
GetFunction(libjack, "jack_connect", _jack_connect);
GetFunction(libjack, "jack_activate", _jack_activate);
GetFunction(libjack, "jack_deactivate", _jack_deactivate);
GetFunction(libjack, "jack_free", _jack_free);
GetFunction(libjack, "jack_get_sample_rate", _jack_get_sample_rate);
GetFunction(libjack, "jack_set_process_callback", _jack_set_process_callback);
GetFunction(libjack, "jack_on_info_shutdown", _jack_on_info_shutdown);
GetFunction(libjack, "jack_get_ports", _jack_get_ports);
GetFunction(libjack, "jack_port_register", _jack_port_register);
GetFunction(libjack, "jack_port_name", _jack_port_name);
GetFunction(libjack, "jack_port_get_buffer", _jack_port_get_buffer);
GetFunction(libjack, "jack_ringbuffer_create", _jack_ringbuffer_create);
GetFunction(libjack, "jack_ringbuffer_free", _jack_ringbuffer_free);
GetFunction(libjack, "jack_ringbuffer_get_write_vector", _jack_ringbuffer_get_write_vector);
GetFunction(libjack, "jack_ringbuffer_write_advance", _jack_ringbuffer_write_advance);
GetFunction(libjack, "jack_ringbuffer_read_space", _jack_ringbuffer_read_space);
GetFunction(libjack, "jack_ringbuffer_read", _jack_ringbuffer_read);
GetFunction(libjack, "jack_ringbuffer_read_advance", _jack_ringbuffer_read_advance);
GetFunction(libjack, "jack_ringbuffer_reset", _jack_ringbuffer_reset);
}
#define jack_set_error_function _jack_set_error_function
#define jack_set_info_function _jack_set_info_function
#define jack_client_open _jack_client_open
#define jack_client_close _jack_client_close
#define jack_connect _jack_connect
#define jack_activate _jack_activate
#define jack_deactivate _jack_deactivate
#define jack_free _jack_free
#define jack_get_sample_rate _jack_get_sample_rate
#define jack_set_process_callback _jack_set_process_callback
#define jack_on_info_shutdown _jack_on_info_shutdown
#define jack_get_ports _jack_get_ports
#define jack_port_register _jack_port_register
#define jack_port_name _jack_port_name
#define jack_port_get_buffer _jack_port_get_buffer
#define jack_ringbuffer_create _jack_ringbuffer_create
#define jack_ringbuffer_free _jack_ringbuffer_free
#define jack_ringbuffer_get_write_vector _jack_ringbuffer_get_write_vector
#define jack_ringbuffer_write_advance _jack_ringbuffer_write_advance
#define jack_ringbuffer_read_space _jack_ringbuffer_read_space
#define jack_ringbuffer_read _jack_ringbuffer_read
#define jack_ringbuffer_read_advance _jack_ringbuffer_read_advance
#define jack_ringbuffer_reset _jack_ringbuffer_reset
#ifdef __GNUC__
#pragma GCC diagnostic pop
#endif

View File

@@ -118,7 +118,7 @@ AudioOutputControl::GetLogName() const noexcept
{
assert(!IsDummy());
return output->GetLogName();
return output ? output->GetLogName() : name.c_str();
}
Mixer *
@@ -364,7 +364,7 @@ AudioOutputControl::LockPlay() noexcept
void
AudioOutputControl::LockPauseAsync() noexcept
{
if (output->mixer != nullptr && !output->SupportsPause())
if (output && output->mixer != nullptr && !output->SupportsPause())
/* the device has no pause mode: close the mixer,
unless its "global" flag is set (checked by
mixer_auto_close()) */

View File

@@ -44,6 +44,10 @@ static constexpr unsigned MAX_PORTS = 16;
static constexpr size_t jack_sample_size = sizeof(jack_default_audio_sample_t);
#ifdef DYNAMIC_JACK
#include "lib/jack/Dynamic.hxx"
#endif // _WIN32
class JackOutput final : public AudioOutput {
/**
* libjack options passed to jack_client_open().
@@ -463,6 +467,10 @@ JackOutput::Disable() noexcept
static AudioOutput *
mpd_jack_init(EventLoop &, const ConfigBlock &block)
{
#ifdef DYNAMIC_JACK
LoadJackLibrary();
#endif
jack_set_error_function(mpd_jack_error);
#ifdef HAVE_JACK_SET_INFO_FUNCTION

View File

@@ -262,6 +262,10 @@ public:
request.SetOption(CURLOPT_FOLLOWLOCATION, 1L);
request.SetOption(CURLOPT_MAXREDIRS, 1L);
/* this option eliminates the probe request when
username/password are specified */
request.SetOption(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
request_headers.Append(StringFormat<40>("depth: %u", depth));
request_headers.Append("content-type: text/xml");

View File

@@ -114,10 +114,7 @@ tag_pool_get_item(TagType type, StringView value) noexcept
auto slot_p = tag_value_slot_p(type, value);
for (auto slot = *slot_p; slot != nullptr; slot = slot->next) {
if (slot->item.type == type &&
/* strncmp() only works if there are no null
bytes, which FixTagString() has already ensured
at this point */
strncmp(value.data, slot->item.value, value.size) == 0 &&
value.Equals(slot->item.value) &&
slot->ref < TagPoolSlot::MAX_REF) {
assert(slot->ref > 0);
++slot->ref;