Compare commits

..

45 Commits

Author SHA1 Message Date
Max Kellermann
18628bf89e release v0.22.9 2021-06-23 20:56:13 +02:00
Yetangitu
2052b461af Fix android build error when confronted with package versions ending in +revision_information
The script seems to assume package version numbers always end in numeric versions with an optional alpha-suffix. Alas, were it only so simple... Sometimes the package is called fizzbang-1.2.3+release_info in which case the build fails. No more!

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1177
2021-06-23 20:53:46 +02:00
Max Kellermann
5019bdcd52 TagAny: invoke ScanGenericTags() on remote files
This fixes reading ID3 tags on remote files with the commands
"readcomments" and "readpicture".

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1180
2021-06-23 20:49:30 +02:00
Naglis Jonaitis
8be0bcbdb9 doc/plugins.rst: mention default libsamplerate type 2021-06-23 15:51:31 +02:00
Naglis Jonaitis
af72a22ed8 doc/user.rst: document restore_paused 2021-06-23 15:50:41 +02:00
Naglis Jonaitis
6ed9668fea doc, README.md: update IRC server name/URL 2021-06-23 15:48:42 +02:00
Max Kellermann
175d2c6d29 Main: use AtScopeExit() to call ZeroconfDeinit()
Make sure that ZeroconfDeinit() gets called even if startup fails with
an exception.  Fixes an assertion failure because an Avahi TimerEvent
is still active.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1192
2021-06-22 20:31:45 +02:00
Max Kellermann
ab487b9a99 Android: use startForegroundService() in Android 8+
Fixes the error:

 IllegalStateException: Not allowed to start service Intent { cmp=org.musicpd/.Main (has extras) }: app is in background
2021-05-31 20:45:31 +02:00
Max Kellermann
ac59ec34f9 decoder/ffmpeg: fix build failure with FFmpeg 3.4
av_demuxer_iterate() was added in libavformat 58.9.100.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1178
2021-05-31 18:10:06 +02:00
Max Kellermann
82da57b7ce decoder/ffmpeg: suppress -Wunused with libavformat<58.6.100 2021-05-31 16:49:48 +02:00
Max Kellermann
aa6dac9bd2 db/proxy: suppress -Wunused with libmpdclient<2.12 2021-05-31 16:49:08 +02:00
Max Kellermann
a26bf261a9 input/last: call Close() in Open()
Prevents a possible bug which occurs when the caller-provided open()
function throws; then the "uri" field is never set.
2021-05-27 14:04:28 +02:00
Max Kellermann
c692286c67 input/last: clear "uri" field in Close()
Prevent false negative after the stream was closed automatically after
20 seconds.
2021-05-27 14:03:33 +02:00
Max Kellermann
3775766605 NEWS: mention new FFmpeg/ID3v2 tags 2021-05-26 13:07:03 +02:00
Max Kellermann
38e24208f6 decoder/ffmpeg: support the tags "album-sort", "artist-sort" 2021-05-26 13:04:47 +02:00
Max Kellermann
fbaedf2262 decoder/ffmpeg: support the "sort_album" tag
From libavformat/mov.c.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1173
2021-05-26 13:03:47 +02:00
Max Kellermann
8f3341cefb decoder/ffmpeg: add comment 2021-05-26 13:03:41 +02:00
Max Kellermann
4ec4bab3a9 decoder/ffmpeg: remove "year" tag
This mapping was added 11 years ago in commit 766b9fd453, but FFmpeg
doesn't appear to support it.
2021-05-26 13:03:27 +02:00
Max Kellermann
6d567bcd35 decoder/ffmpeg: fix ArtistSort and AlbumArtistSort mapping
These were added 11 years ago in commit 766b9fd453, but I cannot find
any evidence in the FFmpeg repository that these names were ever
supported.  This commit adds the tags as they are currently present in
libavformat/mov.c.
2021-05-26 13:03:26 +02:00
Max Kellermann
363d9f0180 db/update/Walk: load all .mpdignore files of all parent directories
When updating everything, this did work, but if updating only a
subdirectory, the ".mpdignore" in the parents were not used.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/1172
2021-05-25 22:42:44 +02:00
Max Kellermann
db0682a469 db/update/Walk: move code to LoadExcludeList() 2021-05-25 22:38:01 +02:00
Max Kellermann
7a6823dcdf zeroconf/AvahiPoll: the struct timeval is an absolute time point
Fixes broken libavahi-client timeouts.
2021-05-25 22:25:45 +02:00
Max Kellermann
bce144a232 zeroconf/AvahiPoll: move code to Schedule() 2021-05-25 22:23:55 +02:00
Max Kellermann
0cef84cac6 zeroconf/AvahiPoll: rename "timer" to "event" 2021-05-25 22:23:55 +02:00
Max Kellermann
56c0733b42 meson.build: disable -Wsuggest-override with GCC 8 2021-05-25 22:23:55 +02:00
Max Kellermann
0b0acb3981 meson.build: add more C++ warning flags 2021-05-25 22:03:49 +02:00
Max Kellermann
1375dcc4ec meson.build: sort warning options 2021-05-25 21:49:03 +02:00
Max Kellermann
6aeb0e335b meson.build: add comment for -Wno-non-virtual-dtor 2021-05-25 21:48:19 +02:00
Max Kellermann
c1e2537851 meson.build: add comment for clang-only warning options 2021-05-25 21:45:39 +02:00
Max Kellermann
8c690fb737 decoder/mad: move variable declaration into "case" 2021-05-25 21:34:09 +02:00
Max Kellermann
dad1c21b59 zeroconf/avahi: move variable declaration into "case" 2021-05-25 21:34:09 +02:00
Max Kellermann
dd10b2bd61 meson.build: remove warning options implied by -Wall -Wextra 2021-05-25 21:24:44 +02:00
Max Kellermann
48c7c540df meson.build: use add_project_arguments() instead of add_global_arguments()
Don't propagate MPD-specific compiler flags to subprojects.
2021-05-25 21:08:06 +02:00
Max Kellermann
281270cd2a meson.build: remove unused variables common_cflags, common_cxxflags 2021-05-25 21:07:05 +02:00
Max Kellermann
02502514f6 meson.build: require clang 7 (remove bug workaround) 2021-05-25 21:06:55 +02:00
Max Kellermann
1bc02123f9 meson.build: remove "-pedantic", implied by Meson
Meson adds "-Wpedantic" in warning_level 3 (which is MPD's default).
2021-05-25 21:01:15 +02:00
Max Kellermann
3488a47c41 subprojects/sqlite3.wrap: add SQLite wrap 2021-05-25 20:51:03 +02:00
Max Kellermann
fd82d67678 sticker/Database: pass NarrowPath to sqlite3_open()
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1171
2021-05-25 18:45:45 +02:00
Max Kellermann
e66c12105b lib/sqlite/meson.build: add missing external dependency on libsqlite 2021-05-25 18:41:43 +02:00
Namkhai B
dbe12a6b90 util/RuntimeError: Disable format-security for gcc
Fixes building under GCC 11
2021-05-25 18:19:19 +02:00
Philippe Antoine
d3a680cc87 meson: set only sanitizers for fuzzer when unspecified
That is when meson option b_sanitize is not used
2021-05-24 09:03:16 +02:00
Max Kellermann
62fc4d5cf4 increment version number to 0.22.9 2021-05-24 09:03:07 +02:00
Max Kellermann
14465be847 release v0.22.8 2021-05-22 17:33:36 +02:00
Max Kellermann
0e49de867d input/last: add nullptr check to Open(), fixes assertion failure
Closes https://github.com/MusicPlayerDaemon/MPD/issues/1168
2021-05-22 17:33:25 +02:00
Max Kellermann
f2e4529707 increment version number to 0.22.8 2021-05-22 17:32:00 +02:00
25 changed files with 219 additions and 82 deletions

16
NEWS

@@ -1,3 +1,19 @@
ver 0.22.9 (2021/06/23)
* database
- simple: load all .mpdignore files of all parent directories
* tags
- fix "readcomments" and "readpicture" on remote files with ID3 tags
* decoder
- ffmpeg: support the tags "sort_album", "album-sort", "artist-sort"
- ffmpeg: fix build failure with FFmpeg 3.4
* Android
- fix auto-start on boot in Android 8 or later
* Windows
- fix build failure with SQLite
ver 0.22.8 (2021/05/22)
* fix crash bug in "albumart" command (0.22.7 regression)
ver 0.22.7 (2021/05/19)
* protocol
- don't use glibc extension to parse time stamps

@@ -14,7 +14,7 @@ For basic installation instructions
- [Manual](http://www.musicpd.org/doc/user/)
- [Forum](http://forum.musicpd.org/)
- [IRC](irc://chat.freenode.net/#mpd)
- [IRC](ircs://irc.libera.chat:6697/#mpd)
- [Bug tracker](https://github.com/MusicPlayerDaemon/MPD/issues/)
# Developers

@@ -2,8 +2,8 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.musicpd"
android:installLocation="auto"
android:versionCode="55"
android:versionName="0.22.7">
android:versionCode="57"
android:versionName="0.22.9">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29"/>

@@ -414,6 +414,15 @@ public class Main extends Service implements Runnable {
* start Main service without any callback
*/
public static void start(Context context, boolean wakelock) {
context.startService(new Intent(context, Main.class).putExtra("wakelock", wakelock));
Intent intent = new Intent(context, Main.class)
.putExtra("wakelock", wakelock);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
/* in Android 8+, we need to use this method
or else we'll get "IllegalStateException:
app is in background" */
context.startForegroundService(intent);
else
context.startService(intent);
}
}

@@ -38,7 +38,7 @@ author = 'Max Kellermann'
# built documents.
#
# The short X.Y version.
version = '0.22.7'
version = '0.22.9'
# The full version, including alpha/beta/rc tags.
release = version

@@ -715,7 +715,7 @@ A resampler using `libsamplerate <http://www.mega-nerd.com/SRC/>`_ a.k.a. Secret
* - Name
- Description
* - **type**
- The interpolator type. See below for a list of known types.
- The interpolator type. Defaults to :samp:`2`. See below for a list of known types.
The following converter types are provided by libsamplerate:

@@ -55,7 +55,7 @@ and unpack it (or `clone the git repository
In any case, you need:
* a C++17 compiler (e.g. GCC 8 or clang 5)
* a C++17 compiler (e.g. GCC 8 or clang 7)
* `Meson 0.49.0 <http://mesonbuild.com/>`__ and `Ninja
<https://ninja-build.org/>`__
* Boost 1.58
@@ -688,6 +688,8 @@ The State File
- Specify the state file location. The parent directory must be writable by the :program:`MPD` user (+wx).
* - **state_file_interval SECONDS**
- Auto-save the state file this number of seconds after each state change. Defaults to 120 (2 minutes).
* - **restore_paused yes|no**
- If set to :samp:`yes`, then :program:`MPD` is put into pause mode instead of starting playback after startup. Default is :samp:`no`.
The Sticker Database
^^^^^^^^^^^^^^^^^^^^
@@ -1120,7 +1122,7 @@ Support
Getting Help
^^^^^^^^^^^^
The :program:`MPD` project runs a `forum <https://forum.musicpd.org/>`_ and an IRC channel (#mpd on Freenode) for requesting help. Visit the MPD help page for details on how to get help.
The :program:`MPD` project runs a `forum <https://forum.musicpd.org/>`_ and an IRC channel (#mpd on Libera.Chat) for requesting help. Visit the MPD help page for details on how to get help.
Common Problems
^^^^^^^^^^^^^^^

@@ -1,7 +1,7 @@
project(
'mpd',
['c', 'cpp'],
version: '0.22.7',
version: '0.22.9',
meson_version: '>= 0.49.0',
default_options: [
'c_std=c11',
@@ -24,8 +24,8 @@ c_compiler = meson.get_compiler('c')
if compiler.get_id() == 'gcc' and compiler.version().version_compare('<8')
warning('Your GCC version is too old. You need at least version 8.')
elif compiler.get_id() == 'clang' and compiler.version().version_compare('<5')
warning('Your clang version is too old. You need at least version 5.')
elif compiler.get_id() == 'clang' and compiler.version().version_compare('<7')
warning('Your clang version is too old. You need at least version 7.')
endif
version_conf = configuration_data()
@@ -42,57 +42,64 @@ common_cppflags = [
'-D_GNU_SOURCE',
]
common_cflags = [
]
common_cxxflags = [
test_global_common_flags = [
'-fvisibility=hidden',
]
test_common_flags = [
'-Wvla',
'-Wdouble-promotion',
'-fvisibility=hidden',
'-ffast-math',
'-ftree-vectorize',
]
test_global_cxxflags = test_global_common_flags + [
]
test_global_cflags = test_global_common_flags + [
]
test_cxxflags = test_common_flags + [
'-fno-threadsafe-statics',
'-fmerge-all-constants',
'-Wmissing-declarations',
'-Wshadow',
'-Wpointer-arith',
'-Wcast-qual',
'-Wwrite-strings',
'-Wsign-compare',
'-Wcomma',
'-Wcomma-subscript',
'-Wextra-semi',
'-Wmismatched-tags',
'-Wmissing-declarations',
'-Woverloaded-virtual',
'-Wshadow',
'-Wsign-promo',
'-Wunused',
'-Wvolatile',
'-Wvirtual-inheritance',
'-Wwrite-strings',
# a vtable without a dtor is just fine
'-Wno-non-virtual-dtor',
# clang specific warning options:
'-Wcomma',
'-Wheader-hygiene',
'-Winconsistent-missing-destructor-override',
'-Wunreachable-code-break',
'-Wunused',
'-Wunreachable-code-aggressive',
'-Wused-but-marked-unused',
'-Wno-non-virtual-dtor',
]
if compiler.get_id() == 'clang'
# Workaround for clang bug
# https://bugs.llvm.org/show_bug.cgi?id=32611
test_cxxflags += '-funwind-tables'
if compiler.get_id() != 'gcc' or compiler.version().version_compare('>=9')
# The GCC 8 implementation of this flag is buggy: it complains even
# if "final" is present, which implies "override".
test_cxxflags += '-Wsuggest-override'
endif
test_cflags = test_common_flags + [
'-Wcast-qual',
'-Wmissing-prototypes',
'-Wshadow',
'-Wpointer-arith',
'-Wstrict-prototypes',
'-Wcast-qual',
'-Wwrite-strings',
'-pedantic',
]
test_ldflags = [
@@ -104,11 +111,11 @@ test_ldflags = [
]
if get_option('buildtype') != 'debug'
test_cxxflags += [
test_global_cxxflags += [
'-ffunction-sections',
'-fdata-sections',
]
test_cflags += [
test_global_cflags += [
'-ffunction-sections',
'-fdata-sections',
]
@@ -118,15 +125,20 @@ if get_option('buildtype') != 'debug'
endif
if get_option('fuzzer')
fuzzer_flags = ['-fsanitize=fuzzer,address,undefined']
fuzzer_flags = ['-fsanitize=fuzzer']
if get_option('b_sanitize') == 'none'
fuzzer_flags += ['-fsanitize=address,undefined']
endif
add_global_arguments(fuzzer_flags, language: 'cpp')
add_global_arguments(fuzzer_flags, language: 'c')
add_global_link_arguments(fuzzer_flags, language: 'cpp')
endif
add_global_arguments(common_cxxflags + compiler.get_supported_arguments(test_cxxflags), language: 'cpp')
add_global_arguments(common_cflags + c_compiler.get_supported_arguments(test_cflags), language: 'c')
add_global_link_arguments(compiler.get_supported_link_arguments(test_ldflags), language: 'cpp')
add_global_arguments(compiler.get_supported_arguments(test_global_cxxflags), language: 'cpp')
add_global_arguments(c_compiler.get_supported_arguments(test_global_cflags), language: 'c')
add_project_arguments(compiler.get_supported_arguments(test_cxxflags), language: 'cpp')
add_project_arguments(c_compiler.get_supported_arguments(test_cflags), language: 'c')
add_project_link_arguments(compiler.get_supported_link_arguments(test_ldflags), language: 'cpp')
is_linux = host_machine.system() == 'linux'
is_android = get_option('android_ndk') != ''

@@ -20,7 +20,7 @@ class Project:
self.base = base
if name is None or version is None:
m = re.match(r'^([-\w]+)-(\d[\d.]*[a-z]?[\d.]*(?:-alpha\d+)?)$', self.base)
m = re.match(r'^([-\w]+)-(\d[\d.]*[a-z]?[\d.]*(?:-alpha\d+)?)(\+.*)?$', self.base)
if name is None: name = m.group(1)
if version is None: version = m.group(2)

@@ -477,6 +477,7 @@ MainConfigured(const struct options &options, const ConfigData &raw_config)
#endif
ZeroconfInit(raw_config, instance.event_loop);
AtScopeExit() { ZeroconfDeinit(); };
#ifdef ENABLE_DATABASE
if (create_db) {
@@ -537,9 +538,6 @@ MainConfigured(const struct options &options, const ConfigData &raw_config)
instance.state_file->Write();
instance.BeginShutdownUpdate();
ZeroconfDeinit();
instance.BeginShutdownPartitions();
}

@@ -25,6 +25,7 @@
#include "client/Client.hxx"
#include "protocol/Ack.hxx"
#include "fs/AllocatedPath.hxx"
#include "input/InputStream.hxx"
#include "util/Compiler.h"
#include "util/UriExtract.hxx"
#include "LocateUri.hxx"
@@ -32,8 +33,13 @@
static void
TagScanStream(const char *uri, TagHandler &handler)
{
if (!tag_stream_scan(uri, handler))
Mutex mutex;
auto is = InputStream::OpenReady(uri, mutex);
if (!tag_stream_scan(*is, handler))
throw ProtocolError(ACK_ERROR_NO_EXIST, "Failed to load file");
ScanGenericTags(*is, handler);
}
static void

@@ -424,6 +424,7 @@ SendGroup(mpd_connection *connection, TagType group)
return mpd_search_add_group_tag(connection, tag);
#else
(void)connection;
(void)group;
throw std::runtime_error("Grouping requires libmpdclient 2.12");
#endif

@@ -312,6 +312,29 @@ UpdateWalk::SkipSymlink(const Directory *directory,
#endif
}
static void
LoadExcludeListOrThrow(const Storage &storage, const Directory &directory,
ExcludeList &exclude_list)
{
Mutex mutex;
auto is = InputStream::OpenReady(storage.MapUTF8(PathTraitsUTF8::Build(directory.GetPath(),
".mpdignore")).c_str(),
mutex);
exclude_list.Load(std::move(is));
}
static void
LoadExcludeListOrLog(const Storage &storage, const Directory &directory,
ExcludeList &exclude_list) noexcept
{
try {
LoadExcludeListOrThrow(storage, directory, exclude_list);
} catch (...) {
if (!IsFileNotFound(std::current_exception()))
LogError(std::current_exception());
}
}
bool
UpdateWalk::UpdateDirectory(Directory &directory,
const ExcludeList &exclude_list,
@@ -331,17 +354,7 @@ UpdateWalk::UpdateDirectory(Directory &directory,
}
ExcludeList child_exclude_list(exclude_list);
try {
Mutex mutex;
auto is = InputStream::OpenReady(storage.MapUTF8(PathTraitsUTF8::Build(directory.GetPath(),
".mpdignore")).c_str(),
mutex);
child_exclude_list.Load(std::move(is));
} catch (...) {
if (!IsFileNotFound(std::current_exception()))
LogError(std::current_exception());
}
LoadExcludeListOrLog(storage, directory, child_exclude_list);
if (!child_exclude_list.IsEmpty())
RemoveExcludedFromDirectory(directory, child_exclude_list);
@@ -445,6 +458,28 @@ UpdateWalk::DirectoryMakeUriParentChecked(Directory &root,
return directory;
}
static void
LoadExcludeLists(std::forward_list<ExcludeList> &lists,
const Storage &storage, const Directory &directory) noexcept
{
assert(!lists.empty());
if (!directory.IsRoot())
LoadExcludeLists(lists, storage, *directory.parent);
lists.emplace_front();
LoadExcludeListOrLog(storage, directory, lists.front());
}
static auto
LoadExcludeLists(const Storage &storage, const Directory &directory) noexcept
{
std::forward_list<ExcludeList> lists;
lists.emplace_front();
LoadExcludeLists(lists, storage, directory);
return lists;
}
inline void
UpdateWalk::UpdateUri(Directory &root, const char *uri) noexcept
try {
@@ -465,9 +500,8 @@ try {
return;
}
ExcludeList exclude_list;
UpdateDirectoryChild(*parent, exclude_list, name, info);
const auto exclude_lists = LoadExcludeLists(storage, *parent);
UpdateDirectoryChild(*parent, exclude_lists.front(), name, info);
} catch (...) {
LogError(std::current_exception());
}

@@ -470,6 +470,7 @@ IsSeekable(const AVFormatContext &format_context) noexcept
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58, 6, 100)
return (format_context.ctx_flags & AVFMTCTX_UNSEEKABLE) != 0;
#else
(void)format_context;
return false;
#endif
}
@@ -658,6 +659,8 @@ ffmpeg_scan_stream(InputStream &is, TagHandler &handler)
return FfmpegScanStream(*f, handler);
}
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58, 9, 100)
static void
ffmpeg_uri_decode(DecoderClient &client, const char *uri)
{
@@ -689,6 +692,8 @@ ffmpeg_protocols() noexcept
return protocols;
}
#endif
/**
* A list of extensions found for the formats supported by ffmpeg.
* This list is current as of 02-23-09; To find out if there are more
@@ -812,6 +817,8 @@ static const char *const ffmpeg_mime_types[] = {
constexpr DecoderPlugin ffmpeg_decoder_plugin =
DecoderPlugin("ffmpeg", ffmpeg_decode, ffmpeg_scan_stream)
.WithInit(ffmpeg_init, ffmpeg_finish)
#if LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT(58, 9, 100)
.WithProtocols(ffmpeg_protocols, ffmpeg_uri_decode)
#endif
.WithSuffixes(ffmpeg_suffixes)
.WithMimeTypes(ffmpeg_mime_types);

@@ -30,11 +30,22 @@ extern "C" {
#include <libavutil/dict.h>
}
/**
* FFmpeg specific tag name mappings, as supported by
* libavformat/id3v2.c, libavformat/mov.c and others.
*/
static constexpr struct tag_table ffmpeg_tags[] = {
{ "year", TAG_DATE },
{ "author-sort", TAG_ARTIST_SORT },
/* from libavformat/id3v2.c, libavformat/mov.c */
{ "album_artist", TAG_ALBUM_ARTIST },
{ "album_artist-sort", TAG_ALBUM_ARTIST_SORT },
/* from libavformat/id3v2.c */
{ "album-sort", TAG_ALBUM_SORT },
{ "artist-sort", TAG_ARTIST_SORT },
/* from libavformat/mov.c */
{ "sort_album_artist", TAG_ALBUM_ARTIST_SORT },
{ "sort_album", TAG_ALBUM_SORT },
{ "sort_artist", TAG_ARTIST_SORT },
/* sentinel */
{ nullptr, TAG_NUM_OF_ITEM_TYPES }

@@ -889,8 +889,6 @@ inline bool
MadDecoder::HandleCurrentFrame() noexcept
{
switch (mute_frame) {
DecoderCommand cmd;
case MadDecoderMuteFrame::SKIP:
mute_frame = MadDecoderMuteFrame::NONE;
break;
@@ -899,8 +897,8 @@ MadDecoder::HandleCurrentFrame() noexcept
mute_frame = MadDecoderMuteFrame::NONE;
UpdateTimerNextFrame();
break;
case MadDecoderMuteFrame::NONE:
cmd = SynthAndSubmit();
case MadDecoderMuteFrame::NONE: {
const auto cmd = SynthAndSubmit();
UpdateTimerNextFrame();
if (cmd == DecoderCommand::SEEK) {
assert(input_stream.IsSeekable());
@@ -922,6 +920,7 @@ MadDecoder::HandleCurrentFrame() noexcept
} else if (cmd != DecoderCommand::NONE)
return false;
}
}
return true;
}

@@ -32,6 +32,7 @@ LastInputStream::~LastInputStream() noexcept = default;
void
LastInputStream::Close() noexcept
{
uri.clear();
is.reset();
close_timer.Cancel();
}

@@ -64,12 +64,12 @@ public:
return is.get();
}
is.reset();
close_timer.Cancel();
Close();
is = open(new_uri, mutex);
uri = std::forward<U>(new_uri);
ScheduleClose();
if (is)
ScheduleClose();
return is.get();
}

@@ -1,5 +1,7 @@
if enable_database
sqlite_dep = dependency('sqlite3', version: '>= 3.7.3', required: get_option('sqlite'))
sqlite_dep = dependency('sqlite3', version: '>= 3.7.3',
fallback: ['sqlite3', 'sqlite3_dep'],
required: get_option('sqlite'))
else
sqlite_dep = dependency('', required: false)
endif
@@ -21,4 +23,7 @@ sqlite = static_library(
sqlite_dep = declare_dependency(
link_with: sqlite,
dependencies: [
sqlite_dep,
],
)

@@ -21,6 +21,7 @@
#include "Sticker.hxx"
#include "lib/sqlite/Util.hxx"
#include "fs/Path.hxx"
#include "fs/NarrowPath.hxx"
#include "Idle.hxx"
#include "util/StringCompare.hxx"
#include "util/ScopeExit.hxx"
@@ -82,7 +83,7 @@ static const char sticker_sql_create[] =
"";
StickerDatabase::StickerDatabase(Path path)
:db(path.c_str())
:db(NarrowPath(path))
{
assert(!path.IsNull());

@@ -35,7 +35,7 @@
#include <stdio.h>
#ifdef __clang__
#if defined(__clang__) || defined(__GNUC__)
#pragma GCC diagnostic push
// TODO: fix this warning properly
#pragma GCC diagnostic ignored "-Wformat-security"
@@ -59,7 +59,7 @@ FormatInvalidArgument(const char *fmt, Args&&... args) noexcept
return std::invalid_argument(buffer);
}
#ifdef __clang__
#if defined(__clang__) || defined(__GNUC__)
#pragma GCC diagnostic pop
#endif

@@ -78,7 +78,7 @@ private:
};
struct AvahiTimeout final {
TimerEvent timer;
TimerEvent event;
const AvahiTimeoutCallback callback;
void *const userdata;
@@ -87,17 +87,17 @@ public:
AvahiTimeout(const struct timeval *tv,
AvahiTimeoutCallback _callback, void *_userdata,
EventLoop &_loop)
:timer(_loop, BIND_THIS_METHOD(OnTimeout)),
:event(_loop, BIND_THIS_METHOD(OnTimeout)),
callback(_callback), userdata(_userdata) {
if (tv != nullptr)
timer.Schedule(ToSteadyClockDuration(*tv));
Schedule(*tv);
}
static void TimeoutUpdate(AvahiTimeout *t, const struct timeval *tv) {
if (tv != nullptr)
t->timer.Schedule(ToSteadyClockDuration(*tv));
t->Schedule(*tv);
else
t->timer.Cancel();
t->event.Cancel();
}
static void TimeoutFree(AvahiTimeout *t) {
@@ -105,6 +105,30 @@ public:
}
private:
[[gnu::pure]]
Event::Duration AbsoluteToDuration(const struct timeval &tv) noexcept {
if (tv.tv_sec == 0)
/* schedule immediately */
return {};
struct timeval now;
if (gettimeofday(&now, nullptr) < 0)
/* shouldn't ever fail, but if it does, do
something reasonable */
return std::chrono::seconds(1);
auto d = ToSteadyClockDuration(tv)
- ToSteadyClockDuration(now);
if (d.count() < 0)
return {};
return d;
}
void Schedule(const struct timeval &tv) noexcept {
event.Schedule(AbsoluteToDuration(tv));
}
void OnTimeout() noexcept {
callback(this, userdata);
}

@@ -157,8 +157,6 @@ MyAvahiClientCallback(AvahiClient *c, AvahiClientState state,
FormatDebug(avahi_domain, "Client changed to state %d", state);
switch (state) {
int reason;
case AVAHI_CLIENT_S_RUNNING:
LogDebug(avahi_domain, "Client is RUNNING");
@@ -169,8 +167,8 @@ MyAvahiClientCallback(AvahiClient *c, AvahiClientState state,
break;
case AVAHI_CLIENT_FAILURE:
reason = avahi_client_errno(c);
if (reason == AVAHI_ERR_DISCONNECTED) {
if (int reason = avahi_client_errno(c);
reason == AVAHI_ERR_DISCONNECTED) {
LogNotice(avahi_domain,
"Client Disconnected, will reconnect shortly");
if (avahi_group != nullptr) {

@@ -1,3 +1,4 @@
/packagecache/
/googletest-*/
/sqlite-*/

12
subprojects/sqlite3.wrap Normal file

@@ -0,0 +1,12 @@
[wrap-file]
directory = sqlite-amalgamation-3340100
source_url = https://www.sqlite.org/2021/sqlite-amalgamation-3340100.zip
source_filename = sqlite-amalgamation-3340100.zip
source_hash = e0b1c0345fe4338b936e17da8e1bd88366cd210e576834546977f040c12a8f68
patch_url = https://wrapdb.mesonbuild.com/v1/projects/sqlite3/3.34.1/1/get_zip
patch_filename = sqlite3-3.34.1-1-wrap.zip
patch_hash = cba9e47bdb4c02f88fadaae8deab357218d32562c6b86ce7ba0c72f107044360
[provide]
sqlite3 = sqlite3_dep