Compare commits

..

28 Commits

Author SHA1 Message Date
Max Kellermann
8534f2d1e2 release v0.18.22 2015-01-14 23:04:49 +01:00
Max Kellermann
665031467a db/proxy, output/shout: fix implicit nullptr/bool conversion
Return false on error, not nullptr.
2014-12-26 13:50:54 +01:00
Max Kellermann
df33171107 db/{simple,proxy}, ...: add "override" keywords
Fixes -Winconsistent-missing-override (clang 3.6).
2014-12-26 13:47:04 +01:00
Max Kellermann
53f4044890 util/{ASCII,UriUtil}, ...: work around -Wtautological-pointer-compare
New in clang 3.6.
2014-12-26 13:43:32 +01:00
Max Kellermann
a5049136ff DatabaseGlue: convert nullptr check to assertion 2014-12-26 13:43:32 +01:00
Max Kellermann
705b3c6b63 util/ASCII: fix indent 2014-12-26 13:37:38 +01:00
Max Kellermann
6b4ac66962 Compiler.h: add macro CLANG_CHECK_VERSION() 2014-12-26 13:31:03 +01:00
Max Kellermann
0964b06240 Compiler.h: add macro GCC_OLDER_THAN() 2014-12-26 13:30:44 +01:00
Max Kellermann
92eeca3ba7 util/Manual: reimplement GCC_CHECK_VERSION() using GCC_MAKE_VERSION() 2014-12-26 13:30:22 +01:00
Max Kellermann
2a86554ac4 Compiler.h: add macro GCC_MAKE_VERSION() 2014-12-26 13:30:11 +01:00
Max Kellermann
805caa30ce configure.ac: prepare for 0.18.22 2014-12-26 13:23:04 +01:00
Max Kellermann
acb798e544 release v0.18.21 2014-12-17 19:13:47 +01:00
k44
773de38bd9 playlist/embcue: fix filename suffix detection
The definition of the playlist_plugin struct member of the embcue
plugin was incorrect.
2014-12-16 18:43:05 +01:00
Max Kellermann
fa4beeee75 decoder/ffmpeg: detect and fix negative time stamps
Works around assertion failure due to something that appears to be a
(minor) FFmpeg bug.
2014-12-15 00:40:46 +01:00
Max Kellermann
d8351772d3 configure.ac: prepare for 0.18.21 2014-12-15 00:39:52 +01:00
Max Kellermann
1b5f33a435 release v0.18.20 2014-12-08 14:57:17 +01:00
Max Kellermann
41b4a63f2b decoder/ffmpeg: support FFmpeg 2.5
Version 2.5 fixed an API oddity, however it broke API compatibility,
at least with C++.  Disable the workaround when a libavformat version
is detected that is recent enough.
2014-12-08 14:25:34 +01:00
Max Kellermann
d8fc2db910 thread/Id: drop "::" prefix before pthread function names
The "::" to explicitly refer to the global namespace appeared like a
good idea in C++, but it breaks with C libraries that implement
standard functions using macros (e.g. musl).
2014-12-08 14:17:17 +01:00
Max Kellermann
dc11dea7cc configure.ac: prepare for 0.18.20 2014-12-08 14:13:20 +01:00
Max Kellermann
04f627c2af release v0.18.19 2014-11-26 19:58:48 +01:00
Max Kellermann
a254f5a3a8 archive/zzip: fix inverted error handler
Set the Error when zzip_seek()==-1 and not on success.  Fixes a crash
after seeking.
2014-11-24 22:08:50 +01:00
Max Kellermann
143c735f96 configure.ac: prepare for 0.18.19 2014-11-24 22:08:50 +01:00
Max Kellermann
7aa2104596 release v0.18.18 2014-11-18 21:34:03 +01:00
Max Kellermann
c8b93d6573 Client: assume uid==0 is local socket
A negative uid value means it's not a "local socket" (PF_LOCAL).
uid==0 means user "root" connected.
2014-11-18 20:56:27 +01:00
Max Kellermann
3f5f96ac91 event/ServerSocket: fix get_remote_uid() error value
Must return -1 on error, not 0.  0 is root.
2014-11-18 20:53:59 +01:00
Florent Le Coz
7e7b403043 Construct a Null AllocatedPath if the filename conversion into UTF8 failed 2014-11-11 17:15:19 +01:00
Max Kellermann
c64ad78c7b decoder/ffmpeg: support opus 2014-11-10 18:00:30 +01:00
Max Kellermann
4a043a915f configure.ac: prepare for 0.18.1 2014-11-10 17:59:06 +01:00
1104 changed files with 24127 additions and 51736 deletions
.gitignoreAUTHORSINSTALLMakefile.amNEWSUPGRADING
android
autogen.shconfigure.ac
doc
m4
mpd.service.inmpd.svg
src
ArchiveDomain.cxxArchiveDomain.hxxArchiveFile.hxxArchiveList.cxxArchiveList.hxxArchiveLookup.cxxArchiveLookup.hxxArchivePlugin.cxxArchivePlugin.hxxArchiveVisitor.hxxAudioConfig.cxxAudioConfig.hxxAudioFormat.cxxAudioFormat.hxxAudioParser.cxxAudioParser.hxxAvahiPoll.cxxAvahiPoll.hxxCheckAudioFormat.cxxCheckAudioFormat.hxxChrono.hxxClient.cxxClient.hxxClientEvent.cxxClientExpire.cxxClientFile.cxxClientFile.hxxClientGlobal.cxxClientIdle.cxxClientInternal.hxxClientList.cxxClientList.hxxClientMessage.cxxClientMessage.hxxClientNew.cxxClientProcess.cxxClientRead.cxxClientSubscribe.cxxClientWrite.cxxCommandLine.cxxCommandLine.hxxCompiler.hConfigData.cxxConfigData.hxxConfigDefaults.hxxConfigError.cxxConfigError.hxxConfigFile.cxxConfigFile.hxxConfigGlobal.cxxConfigGlobal.hxxConfigOption.hxxConfigParser.cxxConfigParser.hxxConfigPath.cxxConfigPath.hxxConfigTemplates.cxxConfigTemplates.hxxCrossFade.cxxCrossFade.hxxDaemon.cxxDaemon.hxxDatabaseError.cxxDatabaseError.hxxDatabaseGlue.cxxDatabaseGlue.hxxDatabaseHelpers.cxxDatabaseHelpers.hxxDatabaseLock.cxxDatabaseLock.hxxDatabasePlaylist.cxxDatabasePlaylist.hxxDatabasePlugin.hxxDatabasePrint.cxxDatabasePrint.hxxDatabaseQueue.cxxDatabaseQueue.hxxDatabaseRegistry.cxxDatabaseRegistry.hxxDatabaseSave.cxxDatabaseSave.hxxDatabaseSelection.cxxDatabaseSelection.hxxDatabaseSimple.hxxDatabaseVisitor.hxxDecoderAPI.cxxDecoderAPI.hxxDecoderBuffer.cxxDecoderBuffer.hxxDecoderCommand.hxxDecoderControl.cxxDecoderControl.hxxDecoderError.cxxDecoderError.hxxDecoderInternal.cxxDecoderInternal.hxxDecoderList.cxxDecoderList.hxxDecoderPlugin.cxxDecoderPlugin.hxxDecoderPrint.cxxDecoderPrint.hxxDecoderThread.cxxDecoderThread.hxxDespotifyUtils.cxxDespotifyUtils.hxxDetachedSong.cxxDetachedSong.hxxDirectory.cxxDirectory.hxxDirectorySave.cxxDirectorySave.hxxEncoderAPI.hxxEncoderList.cxxEncoderList.hxxEncoderPlugin.hxxExcludeList.cxxExcludeList.hxxFilterConfig.cxxFilterConfig.hxxFilterInternal.hxxFilterPlugin.cxxFilterPlugin.hxxFilterRegistry.cxxFilterRegistry.hxxGlobalEvents.cxxGlobalEvents.hxxIOThread.cxxIOThread.hxxIcyMetaDataParser.cxxIcyMetaDataParser.hxxIcyMetaDataServer.cxxIcyMetaDataServer.hxxIdTable.hxxIdle.cxxIdle.hxxInotifyDomain.cxxInotifyDomain.hxxInotifyQueue.cxxInotifyQueue.hxxInotifySource.cxxInotifySource.hxxInotifyUpdate.cxxInotifyUpdate.hxxInputInit.cxxInputInit.hxxInputPlugin.hxxInputRegistry.cxxInputRegistry.hxxInputStream.cxxInputStream.hxxInstance.cxxInstance.hxxListen.cxxListen.hxxLog.cxxLog.hxxLogBackend.cxxLogBackend.hxxLogInit.cxxLogInit.hxxLogLevel.hxxLogV.hxxMain.cxxMain.hxxMapper.cxxMapper.hxxMemorySongEnumerator.cxxMemorySongEnumerator.hxxMixRampInfo.hxxMixerAll.cxxMixerAll.hxxMixerControl.cxxMixerControl.hxxMixerInternal.hxxMixerList.hxxMixerPlugin.hxxMixerType.cxxMixerType.hxxMusicBuffer.cxxMusicBuffer.hxxMusicChunk.cxxMusicChunk.hxxMusicPipe.cxxMusicPipe.hxxOutputAPI.hxxOutputAll.cxxOutputAll.hxxOutputCommand.cxxOutputCommand.hxxOutputControl.cxxOutputControl.hxxOutputError.cxxOutputError.hxxOutputFinish.cxxOutputInit.cxxOutputInternal.hxxOutputList.cxxOutputList.hxxOutputPlugin.cxxOutputPlugin.hxxOutputPrint.cxxOutputPrint.hxxOutputState.cxxOutputState.hxxOutputThread.cxxOutputThread.hxxPage.cxxPage.hxxPartition.cxxPartition.hxxPermission.cxxPermission.hxxPlayerControl.cxxPlayerControl.hxxPlayerListener.hxxPlayerThread.cxxPlayerThread.hxxPlaylist.cxxPlaylist.hxxPlaylistAny.cxxPlaylistAny.hxxPlaylistControl.cxxPlaylistDatabase.cxxPlaylistDatabase.hxxPlaylistEdit.cxxPlaylistError.cxxPlaylistError.hxxPlaylistFile.cxxPlaylistFile.hxxPlaylistGlobal.cxxPlaylistGlobal.hxxPlaylistInfo.hxxPlaylistMapper.cxxPlaylistMapper.hxxPlaylistPlugin.hxxPlaylistPrint.cxxPlaylistPrint.hxxPlaylistQueue.cxxPlaylistQueue.hxxPlaylistRegistry.cxxPlaylistRegistry.hxxPlaylistSave.cxxPlaylistSave.hxxPlaylistSong.cxxPlaylistSong.hxxPlaylistState.cxxPlaylistState.hxxPlaylistUpdate.cxxPlaylistVector.cxxPlaylistVector.hxxQueue.cxxQueue.hxxQueuePrint.cxxQueuePrint.hxxQueueSave.cxxQueueSave.hxxReplayGainConfig.cxxReplayGainConfig.hxxReplayGainInfo.cxxReplayGainInfo.hxxSignalHandlers.cxxSignalHandlers.hxxSong.cxxSong.hxxSongEnumerator.hxxSongFilter.cxxSongFilter.hxxSongLoader.cxxSongLoader.hxxSongPointer.hxxSongPrint.cxxSongPrint.hxxSongSave.cxxSongSave.hxxSongSort.cxxSongSort.hxxSongSticker.cxxSongSticker.hxxSongUpdate.cxxStateFile.cxxStateFile.hxxStats.cxxStats.hxxStickerDatabase.cxxStickerDatabase.hxxStickerPrint.cxxStickerPrint.hxxTagFile.cxxTagFile.hxxTagPrint.cxxTagPrint.hxxTagSave.cxxTagSave.hxxTagStream.cxxTagStream.hxxTextFile.cxxTextFile.hxxTextInputStream.cxxTextInputStream.hxxTimePrint.cxxTimePrint.hxxTimer.cxxTimer.hxxUpdateArchive.cxxUpdateArchive.hxxUpdateContainer.cxxUpdateContainer.hxxUpdateDatabase.cxxUpdateDatabase.hxxUpdateDomain.cxxUpdateDomain.hxxUpdateGlue.cxxUpdateGlue.hxxUpdateIO.cxxUpdateIO.hxxUpdateInternal.hxxUpdateQueue.cxxUpdateQueue.hxxUpdateRemove.cxxUpdateRemove.hxxUpdateSong.cxxUpdateSong.hxxUpdateWalk.cxxUpdateWalk.hxxVolume.cxxVolume.hxxZeroconfAvahi.cxxZeroconfAvahi.hxxZeroconfBonjour.cxxZeroconfBonjour.hxxZeroconfGlue.cxxZeroconfGlue.hxxZeroconfInternal.hxx
android
archive
check.h
client
command
cue
db
decoder
AdPlugDecoderPlugin.cxxAdPlugDecoderPlugin.hAudiofileDecoderPlugin.cxxAudiofileDecoderPlugin.hxxDecoderBuffer.cxxDecoderBuffer.hxxDsdLib.cxxDsdLib.hxxDsdiffDecoderPlugin.cxxDsdiffDecoderPlugin.hxxDsfDecoderPlugin.cxxDsfDecoderPlugin.hxxFaadDecoderPlugin.cxxFaadDecoderPlugin.hxxFfmpegDecoderPlugin.cxxFfmpegDecoderPlugin.hxxFfmpegMetaData.cxxFfmpegMetaData.hxxFlacCommon.cxxFlacCommon.hxxFlacDecoderPlugin.cxxFlacDecoderPlugin.hFlacDomain.cxxFlacDomain.hxxFlacIOHandle.cxxFlacIOHandle.hxxFlacInput.cxxFlacInput.hxxFlacMetadata.cxxFlacMetadata.hxxFlacPcm.cxxFlacPcm.hxxFluidsynthDecoderPlugin.cxxFluidsynthDecoderPlugin.hxxGmeDecoderPlugin.cxxGmeDecoderPlugin.hxxMadDecoderPlugin.cxxMadDecoderPlugin.hxxMikmodDecoderPlugin.cxxMikmodDecoderPlugin.hxxModplugDecoderPlugin.cxxModplugDecoderPlugin.hxxMpcdecDecoderPlugin.cxxMpcdecDecoderPlugin.hxxMpg123DecoderPlugin.cxxMpg123DecoderPlugin.hxxOggCodec.cxxOggCodec.hxxOggFind.cxxOggFind.hxxOggSyncState.hxxOggUtil.cxxOggUtil.hxxOpusDecoderPlugin.cxxOpusDecoderPlugin.hOpusDomain.cxxOpusDomain.hxxOpusHead.cxxOpusHead.hxxOpusReader.hxxOpusTags.cxxOpusTags.hxxPcmDecoderPlugin.cxxPcmDecoderPlugin.hxxSidplayDecoderPlugin.cxxSidplayDecoderPlugin.hxxSndfileDecoderPlugin.cxxSndfileDecoderPlugin.hxxVorbisComments.cxxVorbisComments.hxxVorbisDecoderPlugin.cxxVorbisDecoderPlugin.hVorbisDomain.cxxVorbisDomain.hxxWavpackDecoderPlugin.cxxWavpackDecoderPlugin.hxxWildmidiDecoderPlugin.cxxWildmidiDecoderPlugin.hxxXiphTags.cxxXiphTags.hxx
plugins
encoder
event
filter
fs
gerror.h
input
java
lib
ls.cxxls.hxx
mixer
neighbor
notify.cxxnotify.hxxopen.h
output
pcm
playlist
poison.h
protocol
queue
storage
system
tag
thread
unix
util
win32
systemd
test
valgrind.suppressions

133
.gitignore vendored

@@ -6,76 +6,75 @@
*.lo
*.o
*.exe
*~
.#*
.stgit*
.deps
.dirstamp
Makefile
Makefile.in
aclocal.m4
autom4te.cache
compile
config.guess
config.h
config.h.in
config.log
config.mk
config.status
config.sub
config_detected.h
config_detected.mk
configure
configure.lineno
depcomp
depmode
install-sh
libtool
ltmain.sh
missing
mkinstalldirs
/test-driver
mpd
mpd.service
stamp-h1
tags
/Makefile
/Makefile.in
/aclocal.m4
/autom4te.cache
/config.h
/config.h.in
/config.log
/config.mk
/config.status
/config_detected.h
/config_detected.mk
/configure
/configure.lineno
/depmode
/libtool
/ltmain.sh
/mkinstalldirs
/build
/src/mpd
/systemd/mpd.service
/stamp-h1
/src/dsd2pcm/dsd2pcm
/src/win32/mpd_win32_rc.rc
/doc/doxygen.conf
/doc/protocol.html
/doc/protocol
/doc/user
/doc/developer
/doc/sticker
/doc/api
/test/software_volume
/test/run_convert
/test/run_decoder
/test/read_tags
/test/run_filter
/test/run_encoder
/test/run_output
/test/read_conf
/test/run_input
/test/read_mixer
/test/dump_playlist
/test/run_normalize
/test/tmp
/test/run_inotify
/test/test_queue_priority
/test/test_protocol
/test/run_ntp_server
/test/run_resolver
/test/run_tcp_connect
/test/test_pcm
/test/dump_rva2
/test/dump_text_file
/test/test_util
/test/test_byte_reverse
/test/test_mixramp
/test/test_vorbis_encoder
/test/DumpDatabase
*~
.#*
.stgit*
src/dsd2pcm/dsd2pcm
src/win32/mpd_win32_rc.rc
doc/doxygen.conf
doc/protocol.html
doc/protocol
doc/user
doc/developer
doc/sticker
doc/api
test/software_volume
test/run_convert
test/run_decoder
test/read_tags
test/run_filter
test/run_encoder
test/run_output
test/read_conf
test/run_input
test/read_mixer
test/dump_playlist
test/run_normalize
test/tmp
test/run_inotify
test/test_queue_priority
test/test_protocol
test/run_ntp_server
test/run_resolver
test/run_tcp_connect
test/test_pcm
test/dump_rva2
test/dump_text_file
test/test_util
test/test_byte_reverse
test/test_mixramp
test/test_vorbis_encoder
test/DumpDatabase
/*.tar.gz
/*.tar.bz2

@@ -1,5 +1,5 @@
Music Player Daemon - http://www.musicpd.org
Copyright (C) 2003-2014 The Music Player Daemon Project
Copyright (C) 2003-2013 The Music Player Daemon Project
The following people have contributed code to MPD:

@@ -16,8 +16,6 @@ gcc 4.6 or later - http://gcc.gnu.org/
clang 3.2 or later - http://clang.llvm.org/
Any other C++11 compliant compiler should also work.
Boost 1.46 - http://www.boost.org/
GLib 2.28 - http://www.gtk.org/
General-purpose utility library.
@@ -119,9 +117,6 @@ For AdLib playback.
despotify - https://github.com/SimonKagstrom/despotify
For Spotify playback.
MP4v2 - https://code.google.com/p/mp4v2/
For MP4 playback. You will need FAAD2.
Optional Miscellaneous Dependencies
-----------------------------------

File diff suppressed because it is too large Load Diff

118
NEWS

@@ -1,107 +1,26 @@
ver 0.19.2 (2014/11/02)
* input
- curl: fix redirected streams
ver 0.18.22 (2014/01/14)
* fix clang 3.6 warnings
ver 0.18.21 (2014/12/17)
* playlist
- don't allow empty playlist name
- m3u: don't ignore unterminated last line
- m3u: recognize the file suffix ".m3u8"
- embcue: fix filename suffix detection
* decoder
- ignore URI query string for plugin detection
- faad: remove workaround for ancient libfaad2 ABI bug
- ffmpeg: recognize MIME type audio/aacp
- mad: fix negative replay gain values
* output
- fix memory leak after filter initialization error
- fall back to PCM if given DSD sample rate is not supported
* fix assertion failure on unsupported PCM conversion
* auto-disable plugins that require GLib when --disable-glib is used
- ffmpeg: fix time stamp underflow
ver 0.19.1 (2014/10/19)
* input
- mms: fix deadlock bug
* playlist
- extm3u: fix Extended M3U detection
- m3u, extm3u, cue: fix truncated lines
* fix build failure on Mac OS X
* add missing file systemd/mpd.socket to tarball
ver 0.18.20 (2014/12/08)
* decoder
- ffmpeg: support FFmpeg 2.5
* fix build failure with musl
ver 0.19 (2014/10/10)
* protocol
- new commands "addtagid", "cleartagid", "listfiles", "listmounts",
"listneighbors", "mount", "rangeid", "unmount"
- "lsinfo" and "readcomments" allowed for remote files
- "listneighbors" lists file servers on the local network
- "playlistadd" supports file:///
- "idle" with unrecognized event name fails
- "list" on album artist falls back to the artist tag
- "list" and "count" allow grouping
- new "search"/"find" filter "modified-since"
- "seek*" allows fractional position
- close connection after syntax error
* database
- proxy: forward "idle" events
- proxy: forward the "update" command
- proxy: copy "Last-Modified" from remote directories
- simple: compress the database file using gzip
- upnp: new plugin
- cancel the update on shutdown
* storage
- music_directory can point to a remote file server
- nfs: new plugin
- smbclient: new plugin
* playlist
- cue: fix bogus duration of the last track
- cue: restore CUE tracks from state file
- soundcloud: use https instead of http
- soundcloud: add default API key
ver 0.18.19 (2014/11/26)
* archive
- read tags from songs in an archive
* input
- alsa: new input plugin
- curl: options "verify_peer" and "verify_host"
- ffmpeg: update offset after seeking
- ffmpeg: improved error messages
- mms: non-blocking I/O
- nfs: new input plugin
- smbclient: new input plugin
* filter
- volume: improved software volume dithering
* decoder:
- vorbis, flac, opus: honor DESCRIPTION= tag in Xiph-based files as a comment to the song
- audiofile: support scanning remote files
- audiofile: log libaudiofile errors
- dsdiff, dsf: report bit rate
- dsdiff, dsf: implement seeking
- dsf: support DSD512
- dsf: support multi-channel files
- dsf: fix big-endian bugs
- dsf: fix noise at end of malformed file
- mpg123: support ID3v2, ReplayGain and MixRamp
- sndfile: support scanning remote files
- sndfile: support tags "comment", "album", "track", "genre"
- sndfile: native floating point playback
- sndfile: optimized 16 bit playback
- mp4v2: support playback of MP4 files.
* encoder:
- shine: new encoder plugin
* output
- alsa: support native DSD playback
- alsa: rename "DSD over USB" to "DoP"
- osx: fix hang after (un)plugging headphones
* threads:
- the update thread runs at "idle" priority
- the output thread runs at "real-time" priority
- increase kernel timer slack on Linux
- name each thread (for debugging)
* configuration
- allow playlist directory without music directory
- use XDG to auto-detect "music_directory" and "db_file"
* add tags "AlbumSort", "MUSICBRAINZ_RELEASETRACKID"
* disable global Latin-1 fallback for tag values
* new resampler option using libsoxr
* ARM NEON optimizations
* install systemd unit for socket activation
* Android port
- zzip: fix crash after seeking
ver 0.18.18 (2014/11/18)
* decoder
- ffmpeg: support opus
* fix crash on failed filename charset conversion
* fix local socket detection from uid=0 (root)
ver 0.18.17 (2014/11/02)
* playlist
@@ -132,7 +51,6 @@ ver 0.18.14 (2014/09/11)
ver 0.18.13 (2014/08/31)
* protocol
- don't change song on "seekcur" in random mode
* decoder
- dsdiff, dsf: fix endless loop on malformed file
- ffmpeg: support ffmpeg/libav version 11

92
UPGRADING Normal file

@@ -0,0 +1,92 @@
Music Player Daemon (MPD) - UPGRADING
Upgrading to 0.14
-----------------
The filesystem character set is determined by GLib, if it is not
configured. GLib has an affinity towards UTF-8, while older MPD
versions used to choose ISO-Latin-1.
Upgrading to 0.13.0
-------------------
JACK, Avahi, and libsamplerate have been added as optional dependencies.
FLAC/OggFLAC now supports the 1.1.3 API, and libmikmod 3.2.0 betas are
supported as well.
New mpd.conf parameters include zeroconf_name, samplerate_converter, and
gapless_mp3_playback. See the mpd.conf man page or updated mpconf.example for
more information on these parameters.
Support for the ID3v2 "Original Artist/Performer" tag has been added. Your
MP3s will need to be rescanned for these tags to be included in the database.
This can be done by running mpd --create-db.
Upgrading to 0.12.0
-------------------
The ao_driver and ao_driver_options config parameters have been removed and
replaced with the audio_output config section. You will have to update your
config file to use this instead. See the mpd.conf man page or the new
mpdconf.example for details on specifying audio_output sections.
The db_file parameter is no longer optional. If you did not specify it in your
old config file then you will have to add it in order to run 0.12.0.
Support for OggFLAC and Musepack audio files has been added. Additionally,
scanning of MP3 files has been improved. To make use of these updates it is
highly recommended that you run mpd --create-db to recreate your entire
database.
Upgrading to 0.11.0
-------------------
The database format has changed a little bit, but in a backward compatible way.
This means that if you upgrade to 0.11.0 from 0.10.x, you do not need to make
any changes. However, if you downgrade back to 0.10.x, then you will need
to recreate your db.
The default port for MPD is now 6600, so update your mpd and client
configurations appropriately.
Upgrading to 0.10.0
-------------------
All information is now stored in the db in UTF-8 format, and the character
set used for the filesystem is stored in the db. Thus, it is highly
recommended that you recreate the db. To do so, run mpd with the
"--create-db" command line option. Also, note that the filesystem
character set will be determined from your current locale settings.
If your locale settings are not the same as those used for the filesystem,
then use the config file parameter "filesystem_charset" to specify the
correct character set (this maybe necessary if you create the db with root).
Upgrading to 0.9.3
------------------
Wave support was added, so to have your wave files added, update the db (mpc
update).
Also, song lengths are now stored in the db. To get this stuff
added to the db, you will need to recreate the db from scratch. To do this,
run mpd with the "--create-db" commandline option.
Upgrading to 0.9.0
------------------
The "stop_on_error" config parameter was removed, so be sure to remove this
parameter from your config file.
Upgrading to 0.8.x
------------------
If you have FLACs, then to have them added to your list of available music,
just use "update".
Upgrading from 0.5.x to 0.6.x
-----------------------------
If you have not compiled MPD with "make ogg", then nothing is needed.
If you compiled with "make ogg", just use "update" (available via the phpMp
interface) to add your OGGs to MPD's list of available music.

1
android/.gitignore vendored

@@ -1 +0,0 @@
/build

@@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.musicpd"
android:installLocation="auto"
android:versionCode="7"
android:versionName="0.19.1">
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="17"/>
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name"
android:launchMode="singleInstance">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

@@ -1,433 +0,0 @@
#!/usr/bin/env python3
import os, os.path
import sys, shutil, subprocess
import urllib.request
import hashlib
import re
if len(sys.argv) < 3:
print("Usage: build.py SDK_PATH NDK_PATH [configure_args...]", file=sys.stderr)
sys.exit(1)
sdk_path = sys.argv[1]
ndk_path = sys.argv[2]
configure_args = sys.argv[3:]
if not os.path.isfile(os.path.join(sdk_path, 'tools', 'android')):
print("SDK not found in", ndk_path, file=sys.stderr)
sys.exit(1)
if not os.path.isdir(ndk_path):
print("NDK not found in", ndk_path, file=sys.stderr)
sys.exit(1)
# the path to the MPD sources
mpd_path = os.path.dirname(os.path.dirname(sys.argv[0]))
# output directories
lib_path = os.path.abspath('lib')
tarball_path = lib_path
src_path = os.path.join(lib_path, 'src')
build_path = os.path.join(lib_path, 'build')
root_path = os.path.join(lib_path, 'root')
# build host configuration
build_arch = 'linux-x86_64'
# redirect pkg-config to use our root directory instead of the default
# one on the build host
os.environ['PKG_CONFIG_LIBDIR'] = os.path.join(root_path, 'lib/pkgconfig')
# select the NDK compiler
gcc_version = '4.8'
llvm_version = '3.3'
# select the NDK target
ndk_arch = 'arm'
host_arch = 'arm-linux-androideabi'
android_abi = 'armeabi-v7a'
ndk_platform = 'android-14'
# set up the NDK toolchain
gcc_toolchain = os.path.join(ndk_path, 'toolchains', host_arch + '-' + gcc_version, 'prebuilt', build_arch)
llvm_toolchain = os.path.join(ndk_path, 'toolchains', 'llvm-' + llvm_version, 'prebuilt', build_arch)
ndk_platform_path = os.path.join(ndk_path, 'platforms', ndk_platform)
target_root = os.path.join(ndk_platform_path, 'arch-' + ndk_arch)
llvm_triple = 'armv7-none-linux-androideabi'
def select_toolchain(use_cxx, use_clang):
global cc, cxx, ar, strip, cflags, cxxflags, cppflags, ldflags, libs
target_arch = '-march=armv7-a -mfloat-abi=softfp'
if use_clang:
cc = os.path.join(llvm_toolchain, 'bin/clang')
cxx = os.path.join(llvm_toolchain, 'bin/clang++')
target_arch += ' -target ' + llvm_triple + ' -integrated-as -gcc-toolchain ' + gcc_toolchain
else:
cc = os.path.join(gcc_toolchain, 'bin', host_arch + '-gcc')
cxx = os.path.join(gcc_toolchain, 'bin', host_arch + '-g++')
ar = os.path.join(gcc_toolchain, 'bin', host_arch + '-ar')
strip = os.path.join(gcc_toolchain, 'bin', host_arch + '-strip')
libstdcxx_path = os.path.join(ndk_path, 'sources/cxx-stl/gnu-libstdc++', gcc_version)
libstdcxx_cppflags = '-isystem ' + os.path.join(libstdcxx_path, 'include') + ' -isystem ' + os.path.join(libstdcxx_path, 'libs', android_abi, 'include')
if use_clang:
libstdcxx_cppflags += ' -D__STRICT_ANSI__'
libstdcxx_ldadd = os.path.join(libstdcxx_path, 'libs', android_abi, 'libgnustl_static.a')
cflags = '-Os -g ' + target_arch
cxxflags = '-Os -g ' + target_arch
cppflags = '--sysroot=' + target_root + ' -I' + root_path + '/include'
ldflags = '--sysroot=' + target_root + ' -L' + root_path + '/lib'
libs = ''
if use_cxx:
libs += ' ' + libstdcxx_ldadd
cppflags += ' ' + libstdcxx_cppflags
def file_md5(path):
"""Calculate the MD5 checksum of a file and return it in hexadecimal notation."""
with open(path, 'rb') as f:
m = hashlib.md5()
while True:
data = f.read(65536)
if len(data) == 0:
# end of file
return m.hexdigest()
m.update(data)
def download_tarball(url, md5):
"""Download a tarball, verify its MD5 checksum and return the local path."""
global tarball_path
os.makedirs(tarball_path, exist_ok=True)
path = os.path.join(tarball_path, os.path.basename(url))
try:
calculated_md5 = file_md5(path)
if md5 == calculated_md5: return path
os.unlink(path)
except FileNotFoundError:
pass
tmp_path = path + '.tmp'
print("download", url)
urllib.request.urlretrieve(url, tmp_path)
calculated_md5 = file_md5(tmp_path)
if calculated_md5 != md5:
os.unlink(tmp_path)
raise "MD5 mismatch"
os.rename(tmp_path, path)
return path
class Project:
def __init__(self, url, md5, installed, name=None, version=None,
base=None,
use_cxx=False, use_clang=False):
if base is None:
basename = os.path.basename(url)
m = re.match(r'^(.+)\.(tar(\.(gz|bz2|xz|lzma))?|zip)$', basename)
if not m: raise
self.base = m.group(1)
else:
self.base = base
if name is None or version is None:
m = re.match(r'^([-\w]+)-(\d[\d.]*[a-z]?)$', self.base)
if name is None: name = m.group(1)
if version is None: version = m.group(2)
self.name = name
self.version = version
self.url = url
self.md5 = md5
self.installed = installed
self.use_cxx = use_cxx
self.use_clang = use_clang
def download(self):
return download_tarball(self.url, self.md5)
def is_installed(self):
global root_path
tarball = self.download()
installed = os.path.join(root_path, self.installed)
tarball_mtime = os.path.getmtime(tarball)
try:
return os.path.getmtime(installed) >= tarball_mtime
except FileNotFoundError:
return False
def unpack(self):
global src_path
tarball = self.download()
path = os.path.join(src_path, self.base)
try:
shutil.rmtree(path)
except FileNotFoundError:
pass
os.makedirs(src_path, exist_ok=True)
subprocess.check_call(['/bin/tar', 'xfC', tarball, src_path])
return path
def make_build_path(self):
path = os.path.join(build_path, self.base)
try:
shutil.rmtree(path)
except FileNotFoundError:
pass
os.makedirs(path, exist_ok=True)
return path
class AutotoolsProject(Project):
def __init__(self, url, md5, installed, configure_args=[],
autogen=False,
cppflags='',
**kwargs):
Project.__init__(self, url, md5, installed, **kwargs)
self.configure_args = configure_args
self.autogen = autogen
self.cppflags = cppflags
def build(self):
src = self.unpack()
if self.autogen:
subprocess.check_call(['/usr/bin/aclocal'], cwd=src)
subprocess.check_call(['/usr/bin/automake', '--add-missing', '--force-missing', '--foreign'], cwd=src)
subprocess.check_call(['/usr/bin/autoconf'], cwd=src)
subprocess.check_call(['/usr/bin/libtoolize', '--force'], cwd=src)
build = self.make_build_path()
select_toolchain(use_cxx=self.use_cxx, use_clang=self.use_clang)
configure = [
os.path.join(src, 'configure'),
'CC=' + cc,
'CXX=' + cxx,
'CFLAGS=' + cflags,
'CXXFLAGS=' + cxxflags,
'CPPFLAGS=' + cppflags + ' ' + self.cppflags,
'LDFLAGS=' + ldflags,
'LIBS=' + libs,
'AR=' + ar,
'STRIP=' + strip,
'--host=' + host_arch,
'--prefix=' + root_path,
'--with-sysroot=' + target_root,
'--enable-silent-rules',
] + self.configure_args
subprocess.check_call(configure, cwd=build)
subprocess.check_call(['/usr/bin/make', '--quiet', '-j12'], cwd=build)
subprocess.check_call(['/usr/bin/make', '--quiet', 'install'], cwd=build)
class FfmpegProject(Project):
def __init__(self, url, md5, installed, configure_args=[],
cppflags='',
**kwargs):
Project.__init__(self, url, md5, installed, **kwargs)
self.configure_args = configure_args
self.cppflags = cppflags
def build(self):
src = self.unpack()
build = self.make_build_path()
select_toolchain(use_cxx=self.use_cxx, use_clang=self.use_clang)
configure = [
os.path.join(src, 'configure'),
'--cc=' + cc,
'--cxx=' + cxx,
'--extra-cflags=' + cflags + ' ' + cppflags + ' ' + self.cppflags,
'--extra-cxxflags=' + cxxflags + ' ' + cppflags + ' ' + self.cppflags,
'--extra-ldflags=' + ldflags,
'--extra-libs=' + libs,
'--ar=' + ar,
'--enable-cross-compile',
'--target-os=linux',
'--arch=' + ndk_arch,
'--cpu=cortex-a8',
'--prefix=' + root_path,
] + self.configure_args
subprocess.check_call(configure, cwd=build)
subprocess.check_call(['/usr/bin/make', '--quiet', '-j12'], cwd=build)
subprocess.check_call(['/usr/bin/make', '--quiet', 'install'], cwd=build)
class BoostProject(Project):
def __init__(self, url, md5, installed,
**kwargs):
m = re.match(r'.*/boost_(\d+)_(\d+)_(\d+)\.tar\.bz2$', url)
version = "%s.%s.%s" % (m.group(1), m.group(2), m.group(3))
Project.__init__(self, url, md5, installed,
name='boost', version=version,
**kwargs)
def build(self):
src = self.unpack()
# install the headers manually; don't build any library
# (because right now, we only use header-only libraries)
includedir = os.path.join(root_path, 'include')
for dirpath, dirnames, filenames in os.walk(os.path.join(src, 'boost')):
relpath = dirpath[len(src)+1:]
destdir = os.path.join(includedir, relpath)
try:
os.mkdir(destdir)
except:
pass
for name in filenames:
if name[-4:] == '.hpp':
shutil.copyfile(os.path.join(dirpath, name),
os.path.join(destdir, name))
# a list of third-party libraries to be used by MPD on Android
thirdparty_libs = [
AutotoolsProject(
'http://downloads.xiph.org/releases/ogg/libogg-1.3.2.tar.xz',
'5c3a34309d8b98640827e5d0991a4015',
'lib/libogg.a',
['--disable-shared', '--enable-static'],
),
AutotoolsProject(
'http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.4.tar.xz',
'55f2288055e44754275a17c9a2497391',
'lib/libvorbis.a',
['--disable-shared', '--enable-static'],
),
AutotoolsProject(
'http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz',
'c5a8cf7c0b066759542bc4ca46817ac6',
'lib/libopus.a',
['--disable-shared', '--enable-static'],
use_clang=True,
),
AutotoolsProject(
'https://svn.xiph.org/releases/flac/flac-1.3.0.tar.xz',
'13b5c214cee8373464d3d65dee362cdd',
'lib/libFLAC.a',
[
'--disable-shared', '--enable-static',
'--disable-xmms-plugin', '--disable-cpplibs',
],
use_clang=True,
),
AutotoolsProject(
'ftp://ftp.mars.org/pub/mpeg/libid3tag-0.15.1b.tar.gz',
'e5808ad997ba32c498803822078748c3',
'lib/libid3tag.a',
['--disable-shared', '--enable-static'],
autogen=True,
),
AutotoolsProject(
'ftp://ftp.mars.org/pub/mpeg/libmad-0.15.1b.tar.gz',
'1be543bc30c56fb6bea1d7bf6a64e66c',
'lib/libmad.a',
['--disable-shared', '--enable-static'],
autogen=True,
),
FfmpegProject(
'http://www.ffmpeg.org/releases/ffmpeg-2.2.3.tar.bz2',
'dbb5b6b69bd010916f17df0ae596e0b1',
'lib/libavcodec.a',
[
'--disable-shared', '--enable-static',
'--enable-gpl',
'--enable-small',
'--disable-pthreads',
'--disable-runtime-cpudetect',
'--disable-programs',
'--disable-doc',
'--disable-avdevice',
'--disable-swresample',
'--disable-swscale',
'--disable-postproc',
'--disable-avfilter',
'--disable-network',
'--disable-encoders',
'--disable-protocols',
'--disable-outdevs',
'--disable-filters',
],
),
AutotoolsProject(
'http://curl.haxx.se/download/curl-7.37.0.tar.lzma',
'54bfd1eb5214f604186d6f5ac61c7781',
'lib/libcurl.a',
[
'--disable-shared', '--enable-static',
'--disable-debug',
'--enable-http',
'--enable-ipv6',
'--disable-ftp', '--disable-file',
'--disable-ldap', '--disable-ldaps',
'--disable-rtsp', '--disable-proxy', '--disable-dict', '--disable-telnet',
'--disable-tftp', '--disable-pop3', '--disable-imap', '--disable-smtp',
'--disable-gopher',
'--disable-manual',
'--disable-threaded-resolver', '--disable-verbose', '--disable-sspi',
'--disable-crypto-auth', '--disable-ntlm-wb', '--disable-tls-srp', '--disable-cookies',
'--without-ssl', '--without-gnutls', '--without-nss', '--without-libssh2',
],
use_clang=True,
),
BoostProject(
'http://netcologne.dl.sourceforge.net/project/boost/boost/1.55.0/boost_1_55_0.tar.bz2',
'd6eef4b4cacb2183f2bf265a5a03a354',
'include/boost/version.hpp',
),
]
# build the third-party libraries
for x in thirdparty_libs:
if not x.is_installed():
x.build()
# configure and build MPD
select_toolchain(use_cxx=True, use_clang=True)
configure = [
os.path.join(mpd_path, 'configure'),
'CC=' + cc,
'CXX=' + cxx,
'CFLAGS=' + cflags,
'CXXFLAGS=' + cxxflags,
'CPPFLAGS=' + cppflags,
'LDFLAGS=' + ldflags,
'LIBS=' + libs,
'AR=' + ar,
'STRIP=' + strip,
'--host=' + host_arch,
'--prefix=' + root_path,
'--with-sysroot=' + target_root,
'--with-android-sdk=' + sdk_path,
'--enable-silent-rules',
'--disable-glib',
'--disable-icu',
# disabled for now because these features require GLib:
'--disable-httpd-output',
'--disable-vorbis-encoder',
] + configure_args
subprocess.check_call(configure)
subprocess.check_call(['/usr/bin/make', '--quiet', '-j12'])

@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="mpd_rules">
<!-- setting these two properties works around a bug in Android
SDK's build.xml, which deletes all .class files every time -->
<property name="build.last.is.packaging.debug" value="true" />
<property name="build.is.packaging.debug" value="true" />
<target name="compile-jni-classes"
depends="-set-debug-mode,-compile"/>
</project>

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MPD</string>
</resources>

@@ -1,30 +0,0 @@
/*
* 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.
*/
package org.musicpd;
import android.content.Context;
/**
* Bridge to native code.
*/
public class Bridge {
public static native void run(Context context);
public static native void shutdown();
}

@@ -1,39 +0,0 @@
/*
* 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.
*/
package org.musicpd;
import android.util.Log;
public class Loader {
private static final String TAG = "MPD";
public static boolean loaded = false;
public static String error;
static {
try {
System.loadLibrary("mpd");
loaded = true;
} catch (UnsatisfiedLinkError e) {
Log.e(TAG, e.getMessage());
error = e.getMessage();
}
}
}

@@ -1,75 +0,0 @@
/*
* 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.
*/
package org.musicpd;
import android.app.Activity;
import android.os.Bundle;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.widget.TextView;
import android.util.Log;
public class Main extends Activity implements Runnable {
private static final String TAG = "MPD";
Thread thread;
TextView textView;
final Handler quitHandler = new Handler() {
public void handleMessage(Message msg) {
textView.setText("Music Player Daemon has quit");
// TODO: what now? restart?
}
};
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!Loader.loaded) {
TextView tv = new TextView(this);
tv.setText("Failed to load the native MPD libary.\n" +
"Report this problem to us, and include the following information:\n" +
"ABI=" + Build.CPU_ABI + "\n" +
"PRODUCT=" + Build.PRODUCT + "\n" +
"FINGERPRINT=" + Build.FINGERPRINT + "\n" +
"error=" + Loader.error);
setContentView(tv);
return;
}
if (thread == null || !thread.isAlive()) {
thread = new Thread(this, "NativeMain");
thread.start();
}
textView = new TextView(this);
textView.setText("Music Player Daemon is running"
+ "\nCAUTION: this version is EXPERIMENTAL!");
setContentView(textView);
}
@Override public void run() {
Bridge.run(this);
quitHandler.sendMessage(quitHandler.obtainMessage());
}
}

@@ -1,11 +1,137 @@
#!/bin/sh
# Run this to set up the build system: configure, makefiles, etc.
# (at one point this was based on the version in enlightenment's cvs)
set -e
package="mpd"
rm -rf config.cache build
mkdir build
olddir="`pwd`"
srcdir="`dirname $0`"
test -z "$srcdir" && srcdir=.
cd "$srcdir"
DIE=
AM_VERSIONGREP="sed -e s/.*[^0-9\.]\([0-9]\.[0-9][0-9]*\).*/\1/"
AC_VERSIONGREP="sed -e s/.*[^0-9\.]\([0-9]\.[0-9][0-9]\).*/\1/"
VERSIONMKINT="sed -e s/[^0-9]//"
if test -n "$AM_FORCE_VERSION"
then
AM_VERSIONS="$AM_FORCE_VERSION"
else
AM_VERSIONS='1.11'
fi
if test -n "$AC_FORCE_VERSION"
then
AC_VERSIONS="$AC_FORCE_VERSION"
else
AC_VERSIONS='2.60 2.61'
fi
aclocal -I m4 $ACLOCAL_FLAGS
autoheader
automake --add-missing $AUTOMAKE_FLAGS
autoconf
versioned_bins ()
{
bin="$1"
needed_int=`echo $VERNEEDED | $VERSIONMKINT`
for i in $VERSIONS
do
i_int=`echo $i | $VERSIONMKINT`
if test $i_int -ge $needed_int
then
echo $bin-$i $bin$i $bin-$i_int $bin$i_int
fi
done
echo $bin
}
for c in autoconf autoheader automake aclocal
do
uc=`echo $c | tr '[:lower:]' '[:upper:]'`
eval "val=`echo '$'$uc`"
if test -n "$val"
then
echo "$uc=$val in environment, will not attempt to auto-detect"
continue
fi
case "$c" in
autoconf|autoheader)
VERNEEDED=`fgrep AC_PREREQ configure.ac | $AC_VERSIONGREP`
VERSIONS="$AC_VERSIONS"
pkg=autoconf
;;
automake|aclocal)
VERNEEDED=`fgrep AUTOMAKE_OPTIONS Makefile.am | $AM_VERSIONGREP`
VERSIONS="$AM_VERSIONS"
pkg=automake
;;
esac
printf "checking for $c ... "
for x in `versioned_bins $c`; do
($x --version < /dev/null > /dev/null 2>&1) > /dev/null 2>&1
if test $? -eq 0
then
echo $x
eval $uc=$x
break
fi
done
eval "val=`echo '$'$uc`"
if test -z "$val"
then
if test $c = $pkg
then
DIE="$DIE $c=$VERNEEDED"
else
DIE="$DIE $c($pkg)=$VERNEEDED"
fi
fi
done
if test -n "$DIE"
then
echo "You must have the following installed to compile $package:"
for i in $DIE
do
printf ' '
echo $i | sed -e 's/(/ (from /' -e 's/=\(.*\)/ (>= \1)/'
done
echo "Download the appropriate package(s) for your system,"
echo "or get the source from one of the GNU ftp sites"
echo "listed in http://www.gnu.org/order/ftp.html"
exit 1
fi
echo "Generating configuration files for $package, please wait...."
ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
# /usr/share/aclocal is most likely included by default, already...
ac_local_paths='
/usr/local/share/aclocal
/sw/share/aclocal
/usr/pkg/share/aclocal
/opt/share/aclocal
/usr/gnu/share/aclocal
'
for i in $ac_local_paths; do
if test -d "$i"; then
ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I $i"
# we probably only want one of these...
break
fi
done
echo " $ACLOCAL $ACLOCAL_FLAGS"
$ACLOCAL $ACLOCAL_FLAGS || exit 1
echo " $AUTOHEADER"
$AUTOHEADER || exit 1
echo " $AUTOMAKE --add-missing $AUTOMAKE_FLAGS"
$AUTOMAKE --add-missing $AUTOMAKE_FLAGS || exit 1
echo " $AUTOCONF"
$AUTOCONF || exit 1
cd "$olddir"
if test x$NOCONFIGURE = x; then
"$srcdir"/configure "$@" || exit 1
fi

@@ -1,25 +1,20 @@
AC_PREREQ(2.60)
AC_INIT(mpd, 0.19.2, musicpd-dev-team@lists.sourceforge.net)
AC_INIT(mpd, 0.18.22, mpd-devel@musicpd.org)
VERSION_MAJOR=0
VERSION_MINOR=19
VERSION_REVISION=2
VERSION_MINOR=18
VERSION_REVISION=22
VERSION_EXTRA=0
AC_CONFIG_SRCDIR([src/Main.cxx])
AC_CONFIG_AUX_DIR(build)
AM_INIT_AUTOMAKE([foreign 1.11 dist-xz subdir-objects])
AM_SILENT_RULES
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_MACRO_DIR([m4])
AC_DEFINE(PROTOCOL_VERSION, "0.19.0", [The MPD protocol version])
AC_DEFINE(PROTOCOL_VERSION, "0.18.0", [The MPD protocol version])
GIT_COMMIT=`GIT_DIR="$srcdir/.git" git describe --dirty --always 2>/dev/null`
if test x$GIT_COMMIT != x; then
AC_DEFINE_UNQUOTED(GIT_COMMIT, ["$GIT_COMMIT"], [The current git commit])
fi
dnl ---------------------------------------------------------------------------
dnl Programs
@@ -70,31 +65,9 @@ dnl OS Specific Defaults
dnl ---------------------------------------------------------------------------
AC_CANONICAL_HOST
host_is_unix=yes
host_is_linux=no
host_is_android=no
host_is_darwin=no
host_is_solaris=no
host_is_windows=no
linux_auto=no
case "$host_os" in
linux-android*)
host_is_android=yes
host_is_linux=yes
linux_auto=auto
AM_CPPFLAGS="$AM_CPPFLAGS -DANDROID"
;;
linux*)
host_is_linux=yes
linux_auto=auto
dnl allow using all glibc features
CPPFLAGS="$CPPFLAGS -D_GNU_SOURCE"
;;
mingw32* | windows*)
AC_CONFIG_FILES([
src/win32/mpd_win32_rc.rc
@@ -103,21 +76,14 @@ mingw32* | windows*)
AM_CPPFLAGS="$AM_CPPFLAGS -DWIN32_LEAN_AND_MEAN"
AM_CPPFLAGS="$AM_CPPFLAGS -DWINVER=0x0600 -D_WIN32_WINNT=0x0600"
LIBS="$LIBS -lws2_32"
host_is_windows=yes
host_is_unix=no
HAVE_WINDOWS=1
;;
darwin*)
host_is_darwin=yes
;;
solaris*)
host_is_solaris=yes
;;
esac
AM_CONDITIONAL([ANDROID], [test x$host_is_android = xyes])
AM_CONDITIONAL([HAVE_WINDOWS], [test x$host_is_windows = xyes])
AM_CONDITIONAL([HAVE_WINDOWS], [test x$HAVE_WINDOWS = x1])
if test -z "$prefix" || test "x$prefix" = xNONE; then
local_lib=
@@ -155,27 +121,6 @@ if test -z "$prefix" || test "x$prefix" = xNONE; then
done
fi
dnl ---------------------------------------------------------------------------
dnl Android
dnl ---------------------------------------------------------------------------
AC_ARG_WITH([android-sdk],
AS_HELP_STRING([--with-android-sdk=DIR],
[Directory for Android SDK]),
[], [with_android_sdk=no])
if test x$host_is_android = xyes; then
if test x$with_android_sdk = xno; then
AC_MSG_ERROR([Android build requires option --with-android-sdk=DIR])
fi
if ! test -x $with_android_sdk/tools/android; then
AC_MSG_ERROR([Android SDK not found in $with_android_sdk])
fi
fi
AC_SUBST(ANDROID_SDK, [$with_android_sdk])
dnl ---------------------------------------------------------------------------
dnl Language Checks
dnl ---------------------------------------------------------------------------
@@ -192,8 +137,7 @@ fi
dnl ---------------------------------------------------------------------------
dnl Header/Library Checks
dnl ---------------------------------------------------------------------------
AC_SEARCH_LIBS([clock_gettime], [rt])
AC_CHECK_FUNCS(daemon fork)
AC_SEARCH_LIBS([syslog], [bsd socket inet],
[AC_DEFINE(HAVE_SYSLOG, 1, [Define if syslog() is available])])
@@ -201,16 +145,10 @@ AC_SEARCH_LIBS([syslog], [bsd socket inet],
AC_SEARCH_LIBS([socket], [socket])
AC_SEARCH_LIBS([gethostbyname], [nsl])
if test x$host_is_linux = xyes; then
AC_CHECK_FUNCS(pipe2 accept4)
fi
AC_CHECK_FUNCS(getpwnam_r getpwuid_r)
if test x$host_is_linux = xyes; then
MPD_OPTIONAL_FUNC(eventfd, eventfd, USE_EVENTFD)
MPD_OPTIONAL_FUNC(signalfd, signalfd, USE_SIGNALFD)
fi
AC_CHECK_FUNCS(pipe2 accept4)
MPD_OPTIONAL_FUNC(eventfd, eventfd, USE_EVENTFD)
MPD_OPTIONAL_FUNC(signalfd, signalfd, USE_SIGNALFD)
MPD_OPTIONAL_FUNC(epoll, epoll_create1, USE_EPOLL)
AC_SEARCH_LIBS([exp], [m],,
[AC_MSG_ERROR([exp() not found])])
@@ -218,96 +156,14 @@ AC_SEARCH_LIBS([exp], [m],,
AC_CHECK_HEADERS(locale.h)
AC_CHECK_HEADERS(valgrind/memcheck.h)
AC_CHECK_HEADERS([sys/prctl.h], AC_CHECK_FUNCS([prctl]))
AX_PTHREAD
LIBS="$PTHREAD_LIBS $LIBS"
AM_CFLAGS="$AM_CFLAGS $PTHREAD_CFLAGS"
AM_CXXFLAGS="$AM_CXXFLAGS $PTHREAD_CFLAGS"
AC_CHECK_LIB([pthread], [pthread_setname_np],
[have_pthread_setname_np=yes],
[have_pthread_setname_np=no])
if test x$have_pthread_setname_np = xyes; then
AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [Is pthread_setname_np() available?])
fi
dnl ---------------------------------------------------------------------------
dnl Event loop selection
dnl ---------------------------------------------------------------------------
MPD_OPTIONAL_FUNC_NODEF(poll, poll)
if test x$host_is_linux = xyes; then
MPD_OPTIONAL_FUNC_NODEF(epoll, epoll_create1)
fi
AC_ARG_WITH(pollmethod,
AS_HELP_STRING(
[--with-pollmethod=@<:@epoll|poll|winselect|auto@:>@],
[specify poll method for internal event loop (default=auto)]),,
[with_pollmethod=auto])
if test "x$with_pollmethod" = xauto; then
if test "x$enable_epoll" = xyes; then
with_pollmethod=epoll
elif test "x$enable_poll" = xyes; then
with_pollmethod=poll
elif test "x$host_is_windows" = xyes; then
with_pollmethod=winselect
else
AC_MSG_ERROR([no poll method is available for your platform])
fi
fi
case "$with_pollmethod" in
epoll)
AC_DEFINE(USE_EPOLL, 1, [Define to poll sockets with epoll])
;;
poll)
AC_DEFINE(USE_POLL, 1, [Define to poll sockets with poll])
;;
winselect)
AC_DEFINE(USE_WINSELECT, 1,
[Define to poll sockets with Windows select])
;;
*)
AC_MSG_ERROR([unknown pollmethod option: $with_pollmethod])
esac
dnl ---------------------------------------------------------------------------
dnl Allow tools to be specifically built
dnl ---------------------------------------------------------------------------
AC_ARG_ENABLE(database,
AS_HELP_STRING([--enable-database],
[enable support for the music database]),,
enable_database=yes)
AM_CONDITIONAL(ENABLE_DATABASE, test x$enable_database = xyes)
if test x$enable_database = xyes; then
database_auto=auto
AC_DEFINE(ENABLE_DATABASE, 1, [Define to enable the music database])
else
database_auto=no
fi
AC_ARG_ENABLE(libmpdclient,
AS_HELP_STRING([--enable-libmpdclient],
[enable support for the MPD client]),,
enable_libmpdclient=auto)
MPD_DEPENDS([enable_libmpdclient], [enable_database],
[Cannot use --enable-libmpdclient with --disable-database])
AC_ARG_ENABLE(expat,
AS_HELP_STRING([--enable-expat],
[enable the expat XML parser]),,
enable_expat=auto)
AC_ARG_ENABLE(upnp,
AS_HELP_STRING([--enable-upnp],
[enable UPnP client support (default: auto)]),,
enable_upnp=auto)
MPD_DEPENDS([enable_upnp], [enable_database],
[Cannot use --enable-upnp with --disable-database])
AC_ARG_ENABLE(adplug,
AS_HELP_STRING([--enable-adplug],
@@ -316,7 +172,7 @@ AC_ARG_ENABLE(adplug,
AC_ARG_ENABLE(alsa,
AS_HELP_STRING([--enable-alsa], [enable ALSA support]),,
[enable_alsa=$linux_auto])
[enable_alsa=auto])
AC_ARG_ENABLE(roar,
AS_HELP_STRING([--enable-roar],
@@ -327,19 +183,12 @@ AC_ARG_ENABLE(ao,
AS_HELP_STRING([--enable-ao],
[enable support for libao]),,
enable_ao=auto)
MPD_DEPENDS([enable_ao], [enable_glib],
[Cannot use --enable-ao with --disable-glib])
AC_ARG_ENABLE(audiofile,
AS_HELP_STRING([--enable-audiofile],
[enable audiofile support (WAV and others)]),,
enable_audiofile=auto)
AC_ARG_ENABLE(zlib,
AS_HELP_STRING([--enable-zlib],
[enable zlib support (default: auto)]),,
enable_zlib=auto)
AC_ARG_ENABLE(bzip2,
AS_HELP_STRING([--enable-bzip2],
[enable bzip2 archive support (default: auto)]),,
@@ -349,24 +198,12 @@ AC_ARG_ENABLE(cdio-paranoia,
AS_HELP_STRING([--enable-cdio-paranoia],
[enable support for audio CD support]),,
enable_cdio_paranoia=auto)
MPD_DEPENDS([enable_cdio_paranoia], [enable_glib],
[Cannot use --enable-cdio-paranoia with --disable-glib])
AC_ARG_ENABLE(curl,
AS_HELP_STRING([--enable-curl],
[enable support for libcurl HTTP streaming (default: auto)]),,
[enable_curl=auto])
AC_ARG_ENABLE(smbclient,
AS_HELP_STRING([--enable-smbclient],
[enable support for libsmbclient (default: auto)]),,
[enable_smbclient=auto])
AC_ARG_ENABLE(nfs,
AS_HELP_STRING([--enable-nfs],
[enable support for libnfs (default: auto)]),,
[enable_nfs=auto])
AC_ARG_ENABLE(debug,
AS_HELP_STRING([--enable-debug],
[enable debugging (default: disabled)]),,
@@ -406,15 +243,11 @@ AC_ARG_ENABLE(gme,
AS_HELP_STRING([--enable-gme],
[enable Blargg's game music emulator plugin]),,
enable_gme=auto)
MPD_DEPENDS([enable_gme], [enable_glib],
[Cannot use --enable-gme with --disable-glib])
AC_ARG_ENABLE(httpd-output,
AS_HELP_STRING([--enable-httpd-output],
[enables the HTTP server output]),,
[enable_httpd_output=auto])
MPD_DEPENDS([enable_httpd_output], [enable_glib],
[Cannot use --enable-httpd-output with --disable-glib])
AC_ARG_ENABLE(id3,
AS_HELP_STRING([--enable-id3],
@@ -440,8 +273,6 @@ AC_ARG_ENABLE(jack,
AS_HELP_STRING([--enable-jack],
[enable jack support]),,
enable_jack=auto)
MPD_DEPENDS([enable_jack], [enable_glib],
[Cannot use --enable-jack with --disable-glib])
AC_SYS_LARGEFILE
@@ -454,8 +285,6 @@ AC_ARG_ENABLE(soundcloud,
AS_HELP_STRING([--enable-soundcloud],
[enable support for soundcloud.com]),,
[enable_soundcloud=auto])
MPD_DEPENDS([enable_soundcloud], [enable_glib],
[Cannot use --enable-soundcloud with --disable-glib])
AC_ARG_ENABLE(lame-encoder,
AS_HELP_STRING([--enable-lame-encoder],
@@ -471,11 +300,6 @@ AC_ARG_ENABLE(lsr,
[enable libsamplerate support]),,
enable_lsr=auto)
AC_ARG_ENABLE(soxr,
AS_HELP_STRING([--enable-soxr],
[enable the libsoxr resampler]),,
enable_soxr=auto)
AC_ARG_ENABLE(mad,
AS_HELP_STRING([--enable-mad],
[enable libmad mp3 decoder plugin]),,
@@ -496,11 +320,6 @@ AC_ARG_ENABLE(modplug,
[enable modplug decoder plugin]),,
enable_modplug=auto)
AC_ARG_ENABLE(mp4v2,
AS_HELP_STRING([--enable-mp4v2],
[enable libmp4v2 decoder plugin]),,
enable_mp4v2=auto)
AC_ARG_ENABLE(mpc,
AS_HELP_STRING([--enable-mpc],
[disable musepack (MPC) support (default: auto)]),,
@@ -550,13 +369,7 @@ AC_ARG_ENABLE(sidplay,
AS_HELP_STRING([--enable-sidplay],
[enable C64 SID support via libsidplay2]),,
enable_sidplay=auto)
MPD_DEPENDS([enable_sidplay], [enable_glib],
[Cannot use --enable-sidplay with --disable-glib])
AC_ARG_ENABLE(shine-encoder,
AS_HELP_STRING([--enable-shine-encoder],
[enables shine encoder]),,
[enable_shine_encoder=auto])
AC_ARG_ENABLE(shout,
AS_HELP_STRING([--enable-shout],
@@ -571,19 +384,17 @@ AC_ARG_ENABLE(sndfile,
AC_ARG_ENABLE(solaris_output,
AS_HELP_STRING([--enable-solaris-output],
[enables the Solaris /dev/audio output]),,
[enable_solaris_output=$host_is_solaris])
[enable_solaris_output=auto])
AC_ARG_ENABLE(sqlite,
AS_HELP_STRING([--enable-sqlite],
[enable support for the SQLite database]),,
[enable_sqlite=$database_auto])
MPD_DEPENDS([enable_sqlite], [enable_glib],
[Cannot use --enable-sqlite with --disable-glib])
[enable_sqlite=auto])
AC_ARG_ENABLE(systemd-daemon,
AS_HELP_STRING([--enable-systemd-daemon],
[use the systemd daemon library (default=auto)]),,
[enable_systemd_daemon=$linux_auto])
[enable_systemd_daemon=auto])
AC_ARG_ENABLE(tcp,
AS_HELP_STRING([--disable-tcp],
@@ -608,7 +419,7 @@ AC_ARG_ENABLE(twolame-encoder,
AC_ARG_ENABLE(un,
AS_HELP_STRING([--disable-un],
[disable support for clients connecting via unix domain sockets (default: enable)]),,
[enable_un=$host_is_unix])
[enable_un=yes])
AC_ARG_ENABLE(vorbis,
AS_HELP_STRING([--enable-vorbis],
@@ -619,8 +430,6 @@ AC_ARG_ENABLE(vorbis-encoder,
AS_HELP_STRING([--enable-vorbis-encoder],
[enable the Ogg Vorbis encoder]),,
[enable_vorbis_encoder=auto])
MPD_DEPENDS([enable_vorbis_encoder], [enable_glib],
[Cannot use --enable-vorbis-encoder with --disable-glib])
AC_ARG_ENABLE(wave-encoder,
AS_HELP_STRING([--enable-wave-encoder],
@@ -631,8 +440,6 @@ AC_ARG_ENABLE(wavpack,
AS_HELP_STRING([--enable-wavpack],
[enable WavPack support]),,
enable_wavpack=auto)
MPD_DEPENDS([enable_wavpack], [enable_glib],
[Cannot use --enable-wavpack with --disable-glib])
AC_ARG_ENABLE(werror,
AS_HELP_STRING([--enable-werror],
@@ -668,58 +475,13 @@ AC_ARG_WITH(tremor-includes,
dnl ---------------------------------------------------------------------------
dnl Mandatory Libraries
dnl ---------------------------------------------------------------------------
no_exceptions=yes
AX_BOOST_BASE([1.46],, [AC_MSG_ERROR([Boost not found])])
dnl Don't disable exceptions on Boost older than 1.54, because
dnl Boost.Intrusive supports this compiler mode only since 1.54;
dnl see https://svn.boost.org/trac/boost/ticket/7849
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION < 105400
#error detected Boost older than 1.54
#endif
]])],, [no_exceptions=no])
AC_LANG_POP([C++])
CPPFLAGS="$CPPFLAGS_SAVED"
AC_ARG_ENABLE(icu,
AS_HELP_STRING([--enable-icu],
[enable libicu for Unicode (default: enabled)]),,
enable_icu=yes)
if test x$enable_icu = xyes; then
PKG_CHECK_MODULES([ICU], [icu-i18n],,
[AC_MSG_ERROR([libicu not found])])
AC_DEFINE(HAVE_ICU, 1, [Define if libicu is used])
fi
AM_CONDITIONAL(HAVE_ICU, test x$enable_icu = xyes)
AC_ARG_ENABLE(glib,
AS_HELP_STRING([--enable-glib],
[enable GLib usage (default: enabled)]),,
enable_glib=yes)
if test x$enable_glib = xyes; then
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.28 gthread-2.0],,
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.28 gthread-2.0],,
[AC_MSG_ERROR([GLib 2.28 is required])])
if test x$GCC = xyes; then
# suppress warnings in the GLib headers
GLIB_CFLAGS=`echo $GLIB_CFLAGS |sed -e 's,-I/,-isystem /,g'`
fi
AC_DEFINE(HAVE_GLIB, 1, [Define if GLib is used])
if test x$GCC = xyes; then
# suppress warnings in the GLib headers
GLIB_CFLAGS=`echo $GLIB_CFLAGS |sed -e 's,-I/,-isystem /,g'`
fi
AM_CONDITIONAL(HAVE_GLIB, test x$enable_glib = xyes)
dnl ---------------------------------------------------------------------------
dnl Protocol Options
@@ -757,6 +519,12 @@ if test x$enable_tcp = xyes; then
AC_DEFINE(HAVE_TCP, 1, [Define if TCP socket support is enabled])
fi
case "$host_os" in
mingw* | windows* | cygwin*)
enable_un=no
;;
esac
if test x$enable_un = xyes; then
AC_DEFINE(HAVE_UN, 1, [Define if unix domain socket support is enabled])
STRUCT_UCRED
@@ -797,15 +565,6 @@ fi
AM_CONDITIONAL(HAVE_LIBMPDCLIENT, test x$enable_libmpdclient = xyes)
dnl -------------------------------- expat --------------------------------
MPD_AUTO_PKG(expat, EXPAT, [expat],
[expat XML parser], [expat not found])
if test x$enable_expat = xyes; then
AC_DEFINE(HAVE_EXPAT, 1, [Define to use the expat XML parser])
fi
AM_CONDITIONAL(HAVE_EXPAT, test x$enable_expat = xyes)
dnl --------------------------------- inotify ---------------------------------
AC_CHECK_FUNCS(inotify_init inotify_init1)
@@ -885,7 +644,7 @@ avahi)
;;
esac
MPD_AUTO_PKG(avahi, AVAHI, [avahi-client dbus-1],
MPD_AUTO_PKG(avahi, AVAHI, [avahi-client],
[avahi client library], [avahi-client not found])
if test x$enable_avahi = xyes; then
AC_DEFINE([HAVE_AVAHI], 1, [Define to enable Avahi Zeroconf support])
@@ -938,22 +697,21 @@ dnl Converter Plugins
dnl ---------------------------------------------------------------------------
dnl ------------------------------ libsamplerate ------------------------------
MPD_AUTO_PKG(lsr, SAMPLERATE, [samplerate >= 0.1.3],
MPD_AUTO_PKG(lsr, SAMPLERATE, [samplerate >= 0.0.15],
[libsamplerate resampling], [libsamplerate not found])
if test x$enable_lsr = xyes; then
AC_DEFINE([HAVE_LIBSAMPLERATE], 1,
[Define to enable libsamplerate])
fi
AM_CONDITIONAL(HAVE_LIBSAMPLERATE, test x$enable_lsr = xyes)
dnl ------------------------------ libsoxr ------------------------------------
MPD_AUTO_PKG(soxr, SOXR, [soxr],
[libsoxr resampler], [libsoxr not found])
if test x$enable_soxr = xyes; then
AC_DEFINE([HAVE_SOXR], 1, [Define to enable libsoxr])
if test x$enable_lsr = xyes; then
PKG_CHECK_MODULES([SAMPLERATE_013],
[samplerate >= 0.1.3],,
[AC_DEFINE([HAVE_LIBSAMPLERATE_NOINT], 1,
[libsamplerate doesn't provide src_int_to_float_array() (<0.1.3)])])
fi
AM_CONDITIONAL(HAVE_SOXR, test x$enable_soxr = xyes)
AM_CONDITIONAL(HAVE_LIBSAMPLERATE, test x$enable_lsr = xyes)
dnl ---------------------------------------------------------------------------
dnl Input Plugins
@@ -967,23 +725,6 @@ if test x$enable_curl = xyes; then
fi
AM_CONDITIONAL(ENABLE_CURL, test x$enable_curl = xyes)
dnl ----------------------------------- smbclient -----------------------------
MPD_AUTO_PKG_LIB(smbclient, SMBCLIENT, [smbclient >= 0.2],
[smbclient], [smbc_init], [-lsmbclient], [],
[smbclient input plugin], [libsmbclient not found])
if test x$enable_smbclient = xyes; then
AC_DEFINE(ENABLE_SMBCLIENT, 1, [Define when libsmbclient is used])
fi
AM_CONDITIONAL(ENABLE_SMBCLIENT, test x$enable_smbclient = xyes)
dnl ----------------------------------- NFS -----------------------------
MPD_AUTO_PKG(nfs, NFS, [libnfs],
[NFS input plugin], [libnfs not found])
if test x$enable_nfs = xyes; then
AC_DEFINE(ENABLE_NFS, 1, [Define when libnfs is used])
fi
AM_CONDITIONAL(ENABLE_NFS, test x$enable_nfs = xyes)
dnl --------------------------------- Despotify ---------------------------------
MPD_AUTO_PKG(despotify, DESPOTIFY, [despotify],
[Despotify support], [despotify not found])
@@ -1027,30 +768,6 @@ if test x$enable_mms = xyes; then
fi
AM_CONDITIONAL(ENABLE_MMS, test x$enable_mms = xyes)
dnl ---------------------------------------------------------------------------
dnl Neighbor Plugins
dnl ---------------------------------------------------------------------------
AC_ARG_ENABLE(neighbor-plugins,
AS_HELP_STRING([--enable-neighbor-plugins],
[enable support for neighbor discovery (default: auto)]),,
[enable_neighbor_plugins=auto])
if test x$enable_neighbor_plugins = xauto; then
if test x$enable_smbclient = xyes; then
enable_neighbor_plugins=yes
fi
if test x$enable_upnp = xyes; then
enable_neighbor_plugins=yes
fi
fi
if test x$enable_neighbor_plugins = xyes; then
AC_DEFINE(ENABLE_NEIGHBOR_PLUGINS, 1,
[Define to enable support for neighbor discovery])
fi
AM_CONDITIONAL(ENABLE_NEIGHBOR_PLUGINS, test x$enable_neighbor_plugins = xyes)
dnl ---------------------------------------------------------------------------
dnl Archive Plugins
dnl ---------------------------------------------------------------------------
@@ -1070,16 +787,6 @@ fi
AM_CONDITIONAL(ENABLE_ISO9660_TEST, test x$MKISOFS != xno)
dnl ---------------------------------- zlib ---------------------------------
MPD_AUTO_PKG(zlib, ZLIB, [zlib],
[zlib support], [zlib not found])
AM_CONDITIONAL(HAVE_ZLIB, test x$enable_zlib = xyes)
if test x$enable_zlib = xyes; then
AC_DEFINE(HAVE_ZLIB, 1, [Define to enable zlib support])
fi
dnl ---------------------------------- libbz2 ---------------------------------
MPD_AUTO_LIB(bzip2, BZ2, bz2, BZ2_bzDecompressInit, [-lbz2], [],
@@ -1096,24 +803,6 @@ fi
AM_CONDITIONAL(ENABLE_BZIP2_TEST, test x$BZIP2 != xno)
dnl ---------------------------------- libupnp ---------------------------------
if test x$enable_expat = xno; then
if test x$enable_upnp = xauto; then
AC_MSG_WARN([expat disabled -- disabling UPnP])
enable_upnp=no
elif test x$enable_upnp = xyes; then
AC_MSG_ERROR([expat disabled -- required for UPnP])
fi
fi
MPD_AUTO_PKG(upnp, UPNP, [libupnp],
[UPnP client support], [libupnp not found])
if test x$enable_upnp = xyes; then
AC_DEFINE(HAVE_LIBUPNP, 1, [Define when libupnp is used])
fi
AM_CONDITIONAL(HAVE_LIBUPNP, test x$enable_upnp = xyes)
dnl --------------------------------- libzzip ---------------------------------
MPD_AUTO_PKG(zzip, ZZIP, [zziplib >= 0.13],
[libzzip archive library], [libzzip not found])
@@ -1264,24 +953,6 @@ if test x$enable_modplug = xyes; then
fi
AM_CONDITIONAL(HAVE_MODPLUG, test x$enable_modplug = xyes)
dnl -------------------------------- libmp4v2 ---------------------------------
if test x$enable_aac = xyes; then
MPD_AUTO_LIB(mp4v2, MP4V2, mp4v2, MP4Create, [-lmp4v2], [],
[mp4v2], [libmp4v2 not found])
if test x$enable_mp4v2 = xyes; then
AC_DEFINE(HAVE_MP4V2, 1, [Define to use libmp4v2 for MP4 decoding])
fi
else
if test x$enable_mp4v2 = xyes; then
AC_MSG_ERROR([MP4V2 requires AAC!])
fi
enable_mp4v2=no
fi
AM_CONDITIONAL(HAVE_MP4V2, test x$enable_mp4v2 = xyes)
dnl -------------------------------- libopus ----------------------------------
MPD_AUTO_PKG(opus, OPUS, [opus ogg],
[opus decoder plugin], [libopus not found])
@@ -1448,7 +1119,6 @@ else
enable_vorbis_encoder=no
enable_lame_encoder=no
enable_twolame_encoder=no
enable_shine_encoder=no
enable_wave_encoder=no
enable_flac_encoder=no
fi
@@ -1460,17 +1130,6 @@ if test x$enable_flac_encoder = xyes; then
fi
AM_CONDITIONAL(ENABLE_FLAC_ENCODER, test x$enable_flac_encoder = xyes)
dnl ------------------------------- Shine Encoder ------------------------------
MPD_AUTO_PKG(shine_encoder, SHINE, [shine >= 3.1],
[shine encoder], [libshine not found])
if test x$enable_shine_encoder = xyes; then
AC_DEFINE(ENABLE_SHINE_ENCODER, 1,
[Define to enable the shine encoder plugin])
fi
AM_CONDITIONAL(ENABLE_SHINE_ENCODER, test x$enable_shine_encoder = xyes)
dnl ---------------------------- Ogg Vorbis Encoder ---------------------------
MPD_AUTO_PKG(vorbis_encoder, VORBISENC, [vorbisenc vorbis ogg],
[Ogg Vorbis encoder], [libvorbisenc not found])
@@ -1514,7 +1173,6 @@ if test x$enable_vorbis_encoder != xno ||
test x$enable_lame_encoder != xno ||
test x$enable_twolame_encoder != xno ||
test x$enable_flac_encoder != xno ||
test x$enable_shine_encoder != xno ||
test x$enable_wave_encoder != xno; then
# at least one encoder plugin is enabled
enable_encoder=yes
@@ -1710,6 +1368,18 @@ AM_CONDITIONAL(HAVE_SHOUT, test x$enable_shout = xyes)
dnl --------------------------------- Solaris ---------------------------------
if test x$enable_solaris_output = xauto; then
case "$host_os" in
solaris*)
enable_solaris_output=yes
;;
*)
enable_solaris_output=no
;;
esac
fi
if test x$enable_solaris_output = xyes; then
AC_DEFINE(ENABLE_SOLARIS_OUTPUT, 1, [Define to enable Solaris /dev/audio support])
fi
@@ -1718,13 +1388,17 @@ AM_CONDITIONAL(ENABLE_SOLARIS_OUTPUT, test x$enable_solaris_output = xyes)
dnl --------------------------------- WinMM ---------------------------------
if test "x$host_is_windows" = xyes; then
AC_DEFINE(ENABLE_WINMM_OUTPUT, 1, [Define to enable WinMM support])
enable_winmm_output=yes
LIBS="$LIBS -lwinmm"
else
enable_winmm_output=no
fi
case "$host_os" in
mingw32* | windows*)
AC_DEFINE(ENABLE_WINMM_OUTPUT, 1, [Define to enable WinMM support])
enable_winmm_output=yes
LIBS="$LIBS -lwinmm"
;;
*)
enable_winmm_output=no
;;
esac
AM_CONDITIONAL(ENABLE_WINMM_OUTPUT, test x$enable_winmm_output = xyes)
@@ -1733,11 +1407,8 @@ dnl Documentation
dnl ---------------------------------------------------------------------------
if test x$enable_documentation = xyes; then
AC_PATH_PROG(XMLTO, xmlto)
if test x$XMLTO = x; then
AC_MSG_ERROR([xmlto not found])
fi
AC_SUBST(XMLTO)
AM_CONDITIONAL(HAVE_XMLTO, test x$XMLTO != x)
AC_PATH_PROG(DOXYGEN, doxygen)
if test x$DOXYGEN = x; then
@@ -1745,6 +1416,8 @@ if test x$enable_documentation = xyes; then
fi
AC_SUBST(DOXYGEN)
else
AM_CONDITIONAL(HAVE_XMLTO, false)
fi
AM_CONDITIONAL(ENABLE_DOCUMENTATION, test x$enable_documentation = xyes)
@@ -1779,12 +1452,8 @@ AC_LANG_PUSH([C++])
AX_APPEND_COMPILE_FLAGS([-fvisibility=hidden])
AX_APPEND_COMPILE_FLAGS([-fno-threadsafe-statics])
AX_APPEND_COMPILE_FLAGS([-fmerge-all-constants])
if test x$no_exceptions = xyes; then
AX_APPEND_COMPILE_FLAGS([-fno-exceptions])
AX_APPEND_COMPILE_FLAGS([-fno-rtti])
fi
AX_APPEND_COMPILE_FLAGS([-fno-exceptions])
AX_APPEND_COMPILE_FLAGS([-fno-rtti])
AX_APPEND_COMPILE_FLAGS([-ffast-math])
AX_APPEND_COMPILE_FLAGS([-ftree-vectorize])
AC_LANG_POP
@@ -1851,10 +1520,6 @@ results(ipv6, "IPv6")
results(tcp, "TCP")
results(un,[UNIX Domain Sockets])
printf '\nStorage support:\n\t'
results(nfs, [NFS])
results(smbclient, [SMB])
printf '\nFile format support:\n\t'
results(aac, [AAC])
results(adplug, [AdPlug])
@@ -1868,7 +1533,6 @@ printf '\n\t'
results(sndfile, [libsndfile])
results(mikmod, [MikMod])
results(modplug, [MODPLUG])
results(mp4v2, [MP4V2])
results(mad, [MAD])
results(mpg123, [MPG123])
results(mpc, [Musepack])
@@ -1882,7 +1546,6 @@ results(wildmidi, [WildMidi])
printf '\nOther features:\n\t'
results(lsr, [libsamplerate])
results(soxr, [libsoxr])
results(libmpdclient, [libmpdclient])
results(inotify, [inotify])
results(sqlite, [SQLite])
@@ -1916,7 +1579,6 @@ if
printf '\nStreaming encoder support:\n\t'
results(flac_encoder, [FLAC])
results(lame_encoder, [LAME])
results(shine_encoder, [Shine])
results(vorbis_encoder, [Ogg Vorbis])
results(opus, [Opus])
results(twolame_encoder, [TwoLAME])
@@ -1926,15 +1588,11 @@ fi
printf '\nStreaming support:\n\t'
results(cdio_paranoia, [CDIO_PARANOIA])
results(curl,[CURL])
results(smbclient,[SMBCLIENT])
results(despotify,[Despotify])
results(soundcloud,[Soundcloud])
printf '\n\t'
results(mms,[MMS])
printf '\nEvent loop:\n\t'
printf $with_pollmethod
printf '\n\n##########################################\n\n'
echo 'Generating files needed for compilation'
@@ -1944,7 +1602,7 @@ dnl Generate files
dnl ---------------------------------------------------------------------------
AC_CONFIG_FILES(Makefile)
AC_CONFIG_FILES(doc/doxygen.conf)
AC_CONFIG_FILES(systemd/mpd.service)
AC_CONFIG_FILES(mpd.service)
AC_OUTPUT
echo 'MPD is ready for compilation, type "make" to begin.'

@@ -10,7 +10,7 @@
<para>
This is a guide for those who wish to hack on the MPD source
code. MPD is an open project, and we are always happy about
contributions. So far, more than 150 people have contributed
contributions. So far, more than 50 people have contributed
patches.
</para>
@@ -155,53 +155,7 @@ foo(const char *abc, int xyz)
<para>
Send your patches to the mailing list:
<email>mpd-devel@musicpd.org</email> (<ulink
url="http://mailman.blarg.de/listinfo/mpd-devel">subscribe
here</ulink>)
mpd-devel@musicpd.org
</para>
<para>
<command>git pull</command> requests are preferred. Regular
contributors can get <ulink
url="http://git.musicpd.org/account-policy.html">an account on
git.musicpd.org</ulink>, but any public git repository will do.
</para>
</chapter>
<chapter>
<title>Development Tools</title>
<section>
<title>Clang Static Analyzer</title>
<para>
The <ulink url="http://clang-analyzer.llvm.org/">clang static
analyzer</ulink> is a tool that helps find bugs. To run it on
the MPD code base, install LLVM and clang. Configure MPD to
use clang:
</para>
<programlisting>./configure --enable-debug CXX=clang++ CC=clang ...</programlisting>
<para>
It is recommended to use <option>--enable-debug</option>,
because the analyzer takes advantage of
<function>assert()</function> calls, which are only enabled in
the debug build.
</para>
<para>
Now run the analyzer:
</para>
<programlisting>scan-build --use-c++=clang++ --use-cc=clang make</programlisting>
<para>
The options <option>--use-c++</option> and
<option>--use-cc</option> are necessary because it invokes
<command>cc</command> for actually compiling the sources by
default. That breaks, because MPD requires a C99 compiler.
</para>
</section>
</chapter>
</book>

@@ -136,6 +136,53 @@ for the format of this parameter. Multiple audio_output sections may be
specified. If no audio_output section is specified, then MPD will scan for a
usable audio output.
.TP
.B audio_output_format <sample_rate:bits:channels>
This specifies the sample rate, bits per sample, and number of channels of
audio that is sent to each audio output. Note that audio outputs may specify
their own audio format which will be used for actual output to the audio
device. An example is "44100:16:2" for 44100Hz, 16 bits, and 2 channels. The
default is to use the audio format of the input file.
Any of the three attributes may be an asterisk to specify that this
attribute should not be enforced
.TP
.B samplerate_converter <integer or prefix>
This specifies the libsamplerate converter to use. The supplied value should
either be an integer or a prefix of the name of a converter. The default is
"Fastest Sinc Interpolator".
At the time of this writing, the following converters are available:
.RS
.TP
Best Sinc Interpolator (0)
Band limited sinc interpolation, best quality, 97dB SNR, 96% BW.
.TP
Medium Sinc Interpolator (1)
Band limited sinc interpolation, medium quality, 97dB SNR, 90% BW.
.TP
Fastest Sinc Interpolator (2)
Band limited sinc interpolation, fastest, 97dB SNR, 80% BW.
.TP
ZOH Interpolator (3)
Zero order hold interpolator, very fast, very poor quality with audible
distortions.
.TP
Linear Interpolator (4)
Linear interpolator, very fast, poor quality.
.TP
internal
Poor quality, no floating point operations. This is the default (and
only choice) if MPD was compiled without libsamplerate.
.RE
.IP
For an up-to-date list of available converters, please see the libsamplerate
documentation (available online at <\fBhttp://www.mega\-nerd.com/SRC/\fP>).
.TP
.B replaygain <off or album or track or auto>
If specified, mpd will adjust the volume of songs played using ReplayGain tags
(see <\fBhttp://www.replaygain.org/\fP>). Setting this to "album" will adjust
@@ -151,6 +198,39 @@ This is the gain (in dB) applied to songs with ReplayGain tags.
.B volume_normalization <yes or no>
If yes, mpd will normalize the volume of songs as they play. The default is no.
.TP
.B audio_buffer_size <size in KiB>
This specifies the size of the audio buffer in kibibytes. The default is 4096,
large enough for nearly 12 seconds of CD-quality audio.
.TP
.B buffer_before_play <0-100%>
This specifies how much of the audio buffer should be filled before playing a
song. Try increasing this if you hear skipping when manually changing songs.
The default is 10%, a little over 1 second of CD-quality audio with the default
buffer size.
.TP
.B http_proxy_host <hostname>
This setting is deprecated. Use the "proxy" setting in the "curl"
input block. See MPD user manual for details.
.TP
.B connection_timeout <seconds>
If a client does not send any new data in this time period, the connection is
closed. The default is 60.
.TP
.B max_connections <number>
This specifies the maximum number of clients that can be connected to mpd. The
default is 5.
.TP
.B max_playlist_length <number>
This specifies the maximum number of songs that can be in the playlist. The
default is 16384.
.TP
.B max_command_list_size <size in KiB>
This specifies the maximum size a command list can be. The default is 2048.
.TP
.B max_output_buffer_size <size in KiB>
This specifies the maximum size of the output buffer to a client. The default
is 8192.
.TP
.B filesystem_charset <charset>
This specifies the character set used for the filesystem. A list of supported
character sets can be obtained by running "iconv \-l". The default is
@@ -180,8 +260,7 @@ clients. Note that you must recreate (not update) your database for changes to
this parameter to take effect. Possible values are artist, album, title,
track, name, genre, date, composer, performer, comment, disc,
musicbrainz_artistid, musicbrainz_albumid, musicbrainz_albumartistid,
musicbrainz_releasetrackid, musicbrainz_trackid. Multiple tags may be specified
as a comma separated list.
musicbrainz_trackid. Multiple tags may be specified as a comma separated list.
An example value is "artist,album,title,track". The special value "none" may
be used alone to disable all metadata. The default is to use all known tag
types except for comments and those starting with "musicbrainz".

@@ -373,6 +373,38 @@ input {
#
###############################################################################
# MPD Internal Buffering ######################################################
#
# This setting adjusts the size of internal decoded audio buffering. Changing
# this may have undesired effects. Don't change this if you don't know what you
# are doing.
#
#audio_buffer_size "4096"
#
# This setting controls the percentage of the buffer which is filled before
# beginning to play. Increasing this reduces the chance of audio file skipping,
# at the cost of increased time prior to audio playback.
#
#buffer_before_play "10%"
#
###############################################################################
# Resource Limitations ########################################################
#
# These settings are various limitations to prevent MPD from using too many
# resources. Generally, these settings should be minimized to prevent security
# risks, depending on the operating resources.
#
#connection_timeout "60"
#max_connections "10"
#max_playlist_length "16384"
#max_command_list_size "2048"
#max_output_buffer_size "8192"
#
###############################################################################
# Character Encoding ##########################################################
#
# If file or directory names do not display correctly for your locale then you

@@ -4,18 +4,18 @@
<book>
<title>The Music Player Daemon protocol</title>
<chapter id="syntax">
<chapter>
<title>General protocol syntax</title>
<section>
<title>Protocol overview</title>
<para>
The <application>MPD</application> command protocol exchanges
line-based text records between client and server over TCP.
Once the client is connected to the server, they conduct a
conversation until the client closes the connection. The
conversation flow is always initiated by the client.
The MPD command protocol exchanges line-based text records
between client and server over TCP. Once the client is
connected to the server, they conduct a conversation until the
client closes the connection. The conversation flow is always
initiated by the client.
</para>
<para>
@@ -38,7 +38,7 @@
</para>
</section>
<section id="request_syntax">
<section>
<title>Requests</title>
<cmdsynopsis>
@@ -70,7 +70,7 @@
</para>
</section>
<section id="response_syntax">
<section>
<title>Responses</title>
<para>
@@ -79,7 +79,7 @@
denote the end of command execution.
</para>
<section id="failure_response_syntax">
<section>
<title>Failure responses</title>
<para>
@@ -188,7 +188,7 @@
</para>
</section>
<section id="range_syntax">
<section>
<title>Ranges</title>
<para>
@@ -203,21 +203,21 @@
</section>
</chapter>
<chapter id="recipes">
<chapter>
<title>Recipes</title>
<section id="queuing_recipe">
<section>
<title>Queuing</title>
<para>
Often, users run <application>MPD</application> with "<link
Often, users run MPD with "<link
linkend="command_random">random</link>" enabled, but want to
be able to insert songs "before" the rest of the playlist.
That is commonly called "queuing".
</para>
<para>
<application>MPD</application> implements this by allowing the client to specify a
MPD implements this by allowing the client to specify a
"priority" for each song in the playlist (commands <link
linkend="command_prio"><command>prio</command></link> and
<link
@@ -227,25 +227,24 @@
</para>
<para>
In "random" mode, <application>MPD</application> maintains an
internal randomized sequence of songs. In this sequence,
songs with a higher priority come first, and all songs with
the same priority are shuffled (by default, all songs are
shuffled, because all have the same priority "0"). When you
increase the priority of a song, it is moved to the front of
the sequence according to its new priority, but always after
the current one. A song that has been played already (it's
"before" the current song in that sequence) will only be
scheduled for repeated playback if its priority has become
bigger than the priority of the current song. Decreasing the
priority of a song will moved it farther to the end of the
sequence. Changing the priority of the current song has no
effect on the sequence.
In "random" mode, MPD maintains an internal randomized
sequence of songs. In this sequence, songs with a higher
priority come first, and all songs with the same priority are
shuffled (by default, all songs are shuffled, because all have
the same priority "0"). When you increase the priority of a
song, it is moved to the front of the sequence according to
its new priority, but always after the current one. A song
that has been played already (it's "before" the current song
in that sequence) will only be scheduled for repeated playback
if its priority has become bigger than the priority of the
current song. Decreasing the priority of a song will moved it
farther to the end of the sequence. Changing the priority of
the current song has no effect on the sequence.
</para>
</section>
</chapter>
<chapter id="command_reference">
<chapter>
<title>Command reference</title>
<note>
@@ -256,12 +255,12 @@
commands using song ids should be used instead of the commands
that manipulate and control playback based on playlist
position. Using song ids is a safer method when multiple
clients are interacting with <application>MPD</application>.
clients are interacting with MPD.
</para>
</note>
<section id="status_commands">
<title>Querying <application>MPD</application>'s status</title>
<section>
<title>Querying MPD's status</title>
<variablelist>
<varlistentry id="command_clearerror">
@@ -299,14 +298,12 @@
</term>
<listitem>
<para>
<footnote id="since_0_14"><simpara>Introduced with
<application>MPD</application> 0.14</simpara></footnote>
<footnote id="since_0_14"><simpara>Introduced with MPD 0.14</simpara></footnote>
Waits until there is a noteworthy change in one or more
of <application>MPD</application>'s subsystems. As soon
as there is one, it lists all changed systems in a line
in the format <returnvalue>changed:
SUBSYSTEM</returnvalue>, where SUBSYSTEM is one of the
following:
of MPD's subsystems. As soon as there is one, it lists
all changed systems in a line in the format
<returnvalue>changed: SUBSYSTEM</returnvalue>, where
SUBSYSTEM is one of the following:
</para>
<itemizedlist>
<listitem>
@@ -388,15 +385,14 @@
to wait for events as long as mpd runs. The
<command>idle</command> command can be canceled by
sending the command <command>noidle</command> (no other
commands are allowed). <application>MPD</application>
will then leave <command>idle</command> mode and print
results immediately; might be empty at this time.
commands are allowed). MPD will then leave
<command>idle</command> mode and print results
immediately; might be empty at this time.
</para>
<para>
If the optional <varname>SUBSYSTEMS</varname> argument
is used, <application>MPD</application> will only send
notifications when something changed in one of the
specified subsytems.
If the optional <varname>SUBSYSTEMS</varname> argument is used,
MPD will only send notifications when something changed in
one of the specified subsytems.
</para>
</listitem>
</varlistentry>
@@ -433,7 +429,7 @@
<listitem>
<para>
<varname>single</varname>:
<footnote id="since_0_15"><simpara>Introduced with <application>MPD</application> 0.15</simpara></footnote>
<footnote id="since_0_15"><simpara>Introduced with MPD 0.15</simpara></footnote>
<returnvalue>0 or 1</returnvalue>
</para>
</listitem>
@@ -508,7 +504,7 @@
<listitem>
<para>
<varname>elapsed</varname>:
<footnote id="since_0_16"><simpara>Introduced with <application>MPD</application> 0.16</simpara></footnote>
<footnote id="since_0_16"><simpara>Introduced with MPD 0.16</simpara></footnote>
<returnvalue>
Total time elapsed within the current song, but
with higher resolution.
@@ -616,7 +612,7 @@
</variablelist>
</section>
<section id="playback_option_commands">
<section>
<title>Playback options</title>
<variablelist>
@@ -749,7 +745,7 @@
<parameter>album</parameter>,
<parameter>auto</parameter><footnote
id="replay_gain_auto_since_0_16">
<simpara>added in <application>MPD</application> 0.16</simpara>
<simpara>added in MPD 0.16</simpara>
</footnote>.
</para>
<para>
@@ -799,7 +795,7 @@
</variablelist>
</section>
<section id="playback_commands">
<section>
<title>Controlling playback</title>
<variablelist>
@@ -886,8 +882,8 @@
<listitem>
<para>
Seeks to the position <varname>TIME</varname> (in
seconds; fractions allowed) of entry
<varname>SONGPOS</varname> in the playlist.
seconds) of entry <varname>SONGPOS</varname> in the
playlist.
</para>
</listitem>
</varlistentry>
@@ -902,8 +898,7 @@
<listitem>
<para>
Seeks to the position <varname>TIME</varname> (in
seconds; fractions allowed) of song
<varname>SONGID</varname>.
seconds) of song <varname>SONGID</varname>.
</para>
</listitem>
</varlistentry>
@@ -917,10 +912,9 @@
</term>
<listitem>
<para>
Seeks to the position <varname>TIME</varname> (in
seconds; fractions allowed) within the current song. If
prefixed by '+' or '-', then the time is relative to the
current playing position.
Seeks to the position <varname>TIME</varname> within the
current song. If prefixed by '+' or '-', then the time
is relative to the current playing position.
</para>
</listitem>
</varlistentry>
@@ -940,7 +934,7 @@
</variablelist>
</section>
<section id="queue">
<section>
<title>The current playlist</title>
<variablelist>
@@ -1041,7 +1035,7 @@ OK
at <varname>START:END</varname> to <varname>TO</varname>
in the playlist.
<footnote id="range_since_0_15">
<simpara>Ranges are supported since <application>MPD</application> 0.15</simpara>
<simpara>Ranges are supported since MPD 0.15</simpara>
</footnote>
</para>
</listitem>
@@ -1224,28 +1218,6 @@ OK
</listitem>
</varlistentry>
<varlistentry id="command_rangeid">
<term>
<cmdsynopsis>
<command>rangeid</command>
<arg choice="req"><replaceable>ID</replaceable></arg>
<arg choice="req"><replaceable>START:END</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
<footnote id="since_0_19"><simpara>Since <application>MPD</application>
0.19</simpara></footnote> Specifies the portion of the
song that shall be played. <varname>START</varname> and
<varname>END</varname> are offsets in seconds
(fractional seconds allowed); both are optional.
Omitting both (i.e. sending just ":") means "remove the
range, play everything". A song that is currently
playing cannot be manipulated this way.
</para>
</listitem>
</varlistentry>
<varlistentry id="command_shuffle">
<term>
<cmdsynopsis>
@@ -1291,48 +1263,10 @@ OK
</para>
</listitem>
</varlistentry>
<varlistentry id="command_addtagid">
<term>
<cmdsynopsis>
<command>addtagid</command>
<arg choice="req"><replaceable>SONGID</replaceable></arg>
<arg choice="req"><replaceable>TAG</replaceable></arg>
<arg choice="req"><replaceable>VALUE</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Adds a tag to the specified song. Editing song tags is
only possible for remote songs. This change is
volatile: it may be overwritten by tags received from
the server, and the data is gone when the song gets
removed from the queue.
</para>
</listitem>
</varlistentry>
<varlistentry id="command_cleartagid">
<term>
<cmdsynopsis>
<command>cleartagid</command>
<arg choice="req"><replaceable>SONGID</replaceable></arg>
<arg choice="opt"><replaceable>TAG</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Removes tags from the specified song. If
<varname>TAG</varname> is not specified, then all tag
values will be removed. Editing song tags is only
possible for remote songs.
</para>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="playlist_files">
<section>
<title>Stored playlists</title>
<para>
@@ -1522,19 +1456,16 @@ OK
</variablelist>
</section>
<section id="database">
<section>
<title>The music database</title>
<variablelist>
<varlistentry id="command_count">
<term>
<cmdsynopsis>
<command>count</command>
<arg choice="req"><replaceable>TAG</replaceable></arg>
<arg choice="req"><replaceable>NEEDLE</replaceable></arg>
<arg choice="opt">group</arg>
<arg choice="opt"><replaceable>GROUPTYPE</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
@@ -1542,15 +1473,8 @@ OK
Counts the number of songs and their total playtime in
the db matching <varname>TAG</varname> exactly.
</para>
<para>
The <parameter>group</parameter> keyword may be used to
group the results by a tag. The following prints
per-artist counts:
</para>
<programlisting>count group artist</programlisting>
</listitem>
</varlistentry>
<varlistentry id="command_find">
<term>
<cmdsynopsis>
@@ -1564,43 +1488,15 @@ OK
<para>
Finds songs in the db that are exactly
<varname>WHAT</varname>. <varname>TYPE</varname> can
be any tag supported by <application>MPD</application>, or one of the special
parameters:
</para>
be any tag supported by MPD, or one of the three special
parameters<parameter>file</parameter> to search by
<itemizedlist>
<listitem>
<para>
<parameter>any</parameter> checks all tag values
</para>
</listitem>
<listitem>
<para>
<parameter>file</parameter> checks the full path
(relative to the music directory)
</para>
</listitem>
<listitem>
<para>
<parameter>base</parameter> restricts the search to
songs in the given directory (also relative to the
music directory)
</para>
</listitem>
<listitem>
<para>
<parameter>modified-since</parameter> compares the
file's time stamp with the given value (ISO 8601 or
UNIX time stamp)
</para>
</listitem>
</itemizedlist>
<para>
<varname>WHAT</varname> is what to find.
full path (relative to the music directory),
<parameter>in</parameter> to restrict the search to
songs in the given directory (also relative to the music
directory) and
<parameter>any</parameter> to match against all
available tags. <varname>WHAT</varname> is what to find.
</para>
</listitem>
</varlistentry>
@@ -1621,43 +1517,27 @@ OK
</para>
</listitem>
</varlistentry>
<varlistentry id="command_list">
<term>
<cmdsynopsis>
<command>list</command>
<arg choice="req"><replaceable>TYPE</replaceable></arg>
<arg choice="opt"><replaceable>FILTERTYPE</replaceable></arg>
<arg choice="opt"><replaceable>FILTERWHAT</replaceable></arg>
<arg choice="opt"><replaceable>...</replaceable></arg>
<arg choice="opt">group</arg>
<arg choice="opt"><replaceable>GROUPTYPE</replaceable></arg>
<arg choice="opt"><replaceable>...</replaceable></arg>
<arg><replaceable>ARTIST</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Lists unique tags values of the specified type.
<varname>TYPE</varname> can be any tag supported by
<application>MPD</application> or
Lists all tags of the specified type.
<varname>TYPE</varname> can be any tag supported by MPD or
<parameter>file</parameter>.
</para>
<para>
Additional arguments may specify a filter like the one
in the <link
linkend="command_find"><command>find</command>
command</link>.
<varname>ARTIST</varname> is an optional parameter when
type is album, this specifies to list albums by an
artist.
</para>
<para>
The <parameter>group</parameter> keyword may be used
(repeatedly) to group the results by one or more tags.
The following example lists all album names,
grouped by their respective (album) artist:
</para>
<programlisting>list album group albumartist</programlisting>
</listitem>
</varlistentry>
<varlistentry id="command_listall">
<term>
<cmdsynopsis>
@@ -1670,14 +1550,6 @@ OK
Lists all songs and directories in
<varname>URI</varname>.
</para>
<para>
Do not use this command. Do not manage a client-side
copy of <application>MPD</application>'s database. That
is fragile and adds huge overhead. It will break with
large databases. Instead, query
<application>MPD</application> whenever you need
something.
</para>
</listitem>
</varlistentry>
<varlistentry id="command_listallinfo">
@@ -1693,40 +1565,6 @@ OK
returns metadata info in the same format as
<command>lsinfo</command>.
</para>
<para>
Do not use this command. Do not manage a client-side
copy of <application>MPD</application>'s database. That
is fragile and adds huge overhead. It will break with
large databases. Instead, query
<application>MPD</application> whenever you need
something.
</para>
</listitem>
</varlistentry>
<varlistentry id="command_listfiles">
<term>
<cmdsynopsis>
<command>listfiles</command>
<arg><replaceable>URI</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Lists the contents of the directory
<varname>URI</varname>, including files are not
recognized by <application>MPD</application>.
<varname>URI</varname> can be a path relative to the
music directory or an URI understood by one of the
storage plugins. The response contains at least one
line for each directory entry with the prefix "file: "
or "directory: ", and may be followed by file attributes
such as "Last-Modified" and "size".
</para>
<para>
For example, "smb://SERVER" returns a list of all shares
on the given SMB/CIFS server; "nfs://servername/path"
obtains a directory listing from the NFS server.
</para>
</listitem>
</varlistentry>
<varlistentry id="command_lsinfo">
@@ -1746,10 +1584,6 @@ OK
the list of stored playlists. This behavior is
deprecated; use "listplaylists" instead.
</para>
<para>
This command may be used to list metadata of remote
files (e.g. URI beginning with "http://" or "smb://").
</para>
<para>
Clients that are connected via UNIX domain socket may
use this command to read the tags of an arbitrary local
@@ -1771,10 +1605,6 @@ OK
to the music directory or a URL in the form
"file:///foo/bar.ogg".
</para>
<para>
This command may be used to list metadata of remote
files (e.g. URI beginning with "http://" or "smb://").
</para>
<para>
The response consists of lines in the form "KEY: VALUE".
Comments with suspicious characters (e.g. newlines) are
@@ -1892,131 +1722,22 @@ OK
</variablelist>
</section>
<section id="mount">
<title>Mounts and neighbors</title>
<para>
A "storage" provides access to files in a directory tree. The
most basic storage plugin is the "local" storage plugin which
accesses the local file system, and there are plugins to
access NFS and SMB servers.
</para>
<para>
Multiple storages can be "mounted" together, similar to the
<application>mount</application> command on many operating
systems, but without cooperation from the kernel. No
superuser privileges are necessary, beause this mapping exists
only inside the <application>MPD</application> process
</para>
<variablelist>
<varlistentry id="command_mount">
<term>
<cmdsynopsis>
<command>mount</command>
<arg choice="req"><replaceable>PATH</replaceable></arg>
<arg choice="req"><replaceable>URI</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Mount the specified remote storage URI at the given
path. Example:
</para>
<programlisting>mount foo nfs://192.168.1.4/export/mp3</programlisting>
</listitem>
</varlistentry>
<varlistentry id="command_umount">
<term>
<cmdsynopsis>
<command>unmount</command>
<arg choice="req"><replaceable>PATH</replaceable></arg>
</cmdsynopsis>
</term>
<listitem>
<para>
Unmounts the specified path. Example:
</para>
<programlisting>unmount foo</programlisting>
</listitem>
</varlistentry>
<varlistentry id="command_listmounts">
<term>
<cmdsynopsis>
<command>listmounts</command>
</cmdsynopsis>
</term>
<listitem>
<para>
Queries a list of all mounts. By default, this contains
just the configured <varname>music_directory</varname>.
Example:
</para>
<programlisting>listmounts
mount:
storage: /home/foo/music
mount: foo
storage: nfs://192.168.1.4/export/mp3
OK
</programlisting>
</listitem>
</varlistentry>
<varlistentry id="command_listneighbors">
<term>
<cmdsynopsis>
<command>listneighbors</command>
</cmdsynopsis>
</term>
<listitem>
<para>
Queries a list of "neighbors" (e.g. accessible file
servers on the local net). Items on that list may be
used with the <link
linkend="command_mount"><command>mount</command></link>
command. Example:
</para>
<programlisting>listneighbors
neighbor: smb://FOO
name: FOO (Samba 4.1.11-Debian)
OK
</programlisting>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="stickers">
<section>
<title>Stickers</title>
<para>
"Stickers"<footnoteref linkend="since_0_15"/> are pieces of
information attached to existing
<application>MPD</application> objects (e.g. song files,
information attached to existing MPD objects (e.g. song files,
directories, albums). Clients can create arbitrary name/value
pairs. <application>MPD</application> itself does not assume
any special meaning in them.
pairs. MPD itself does not assume any special meaning in
them.
</para>
<para>
The goal is to allow clients to share additional (possibly
dynamic) information about songs, which is neither stored on
the client (not available to other clients), nor stored in the
song files (<application>MPD</application> has no write
access).
song files (MPD has no write access).
</para>
<para>
@@ -2121,7 +1842,7 @@ OK
</variablelist>
</section>
<section id="connection_commands">
<section>
<title>Connection settings</title>
<variablelist>
@@ -2133,8 +1854,7 @@ OK
</term>
<listitem>
<para>
Closes the connection to <application>MPD</application>.
<application>MPD</application> will try to send the
Closes the connection to MPD. MPD will try to send the
remaining output buffer before it actually closes the
connection, but that cannot be guaranteed. This command
will not generate a response.
@@ -2149,7 +1869,7 @@ OK
</term>
<listitem>
<para>
Kills <application>MPD</application>.
Kills MPD.
</para>
</listitem>
</varlistentry>
@@ -2183,7 +1903,7 @@ OK
</variablelist>
</section>
<section id="output_commands">
<section>
<title>Audio output devices</title>
<variablelist>
@@ -2237,38 +1957,12 @@ OK
<para>
Shows information about all outputs.
</para>
<screen>
outputid: 0
outputname: My ALSA Device
outputenabled: 0
OK
</screen>
<para>
Return information:
</para>
<itemizedlist>
<listitem>
<para>
<varname>outputid</varname>: ID of the output. May change between executions
</para>
</listitem>
<listitem>
<para>
<varname>outputname</varname>: Name of the output. It can be any.
</para>
</listitem>
<listitem>
<para>
<varname>outputenabled</varname>: Status of the output. 0 if disabled, 1 if enabled.
</para>
</listitem>
</itemizedlist>
</listitem>
</varlistentry>
</variablelist>
</section>
<section id="reflection_commands">
<section>
<title>Reflection</title>
<variablelist>
@@ -2384,7 +2078,7 @@ suffix: mpc</programlisting>
</variablelist>
</section>
<section id="client_to_client">
<section>
<title>Client to client</title>
<para>

File diff suppressed because it is too large Load Diff

@@ -54,12 +54,10 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 4
#serial 2
AC_DEFUN([AX_APPEND_COMPILE_FLAGS],
[AX_REQUIRE_DEFINED([AX_CHECK_COMPILE_FLAG])
AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
for flag in $1; do
[for flag in $1; do
AX_CHECK_COMPILE_FLAG([$flag], [AX_APPEND_FLAG([$flag], [$2])], [], [$3])
done
])dnl AX_APPEND_COMPILE_FLAGS

@@ -52,12 +52,10 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 4
#serial 2
AC_DEFUN([AX_APPEND_LINK_FLAGS],
[AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
AX_REQUIRE_DEFINED([AX_APPEND_FLAG])
for flag in $1; do
[for flag in $1; do
AX_CHECK_LINK_FLAG([$flag], [AX_APPEND_FLAG([$flag], [m4_default([$2], [LDFLAGS])])], [], [$3])
done
])dnl AX_APPEND_LINK_FLAGS

@@ -1,272 +0,0 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_boost_base.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_BOOST_BASE([MINIMUM-VERSION], [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
#
# DESCRIPTION
#
# Test for the Boost C++ libraries of a particular version (or newer)
#
# If no path to the installed boost library is given the macro searchs
# under /usr, /usr/local, /opt and /opt/local and evaluates the
# $BOOST_ROOT environment variable. Further documentation is available at
# <http://randspringer.de/boost/index.html>.
#
# This macro calls:
#
# AC_SUBST(BOOST_CPPFLAGS) / AC_SUBST(BOOST_LDFLAGS)
#
# And sets:
#
# HAVE_BOOST
#
# LICENSE
#
# Copyright (c) 2008 Thomas Porschberg <thomas@randspringer.de>
# Copyright (c) 2009 Peter Adolphs
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 23
AC_DEFUN([AX_BOOST_BASE],
[
AC_ARG_WITH([boost],
[AS_HELP_STRING([--with-boost@<:@=ARG@:>@],
[use Boost library from a standard location (ARG=yes),
from the specified location (ARG=<path>),
or disable it (ARG=no)
@<:@ARG=yes@:>@ ])],
[
if test "$withval" = "no"; then
want_boost="no"
elif test "$withval" = "yes"; then
want_boost="yes"
ac_boost_path=""
else
want_boost="yes"
ac_boost_path="$withval"
fi
],
[want_boost="yes"])
AC_ARG_WITH([boost-libdir],
AS_HELP_STRING([--with-boost-libdir=LIB_DIR],
[Force given directory for boost libraries. Note that this will override library path detection, so use this parameter only if default library detection fails and you know exactly where your boost libraries are located.]),
[
if test -d "$withval"
then
ac_boost_lib_path="$withval"
else
AC_MSG_ERROR(--with-boost-libdir expected directory name)
fi
],
[ac_boost_lib_path=""]
)
if test "x$want_boost" = "xyes"; then
boost_lib_version_req=ifelse([$1], ,1.20.0,$1)
boost_lib_version_req_shorten=`expr $boost_lib_version_req : '\([[0-9]]*\.[[0-9]]*\)'`
boost_lib_version_req_major=`expr $boost_lib_version_req : '\([[0-9]]*\)'`
boost_lib_version_req_minor=`expr $boost_lib_version_req : '[[0-9]]*\.\([[0-9]]*\)'`
boost_lib_version_req_sub_minor=`expr $boost_lib_version_req : '[[0-9]]*\.[[0-9]]*\.\([[0-9]]*\)'`
if test "x$boost_lib_version_req_sub_minor" = "x" ; then
boost_lib_version_req_sub_minor="0"
fi
WANT_BOOST_VERSION=`expr $boost_lib_version_req_major \* 100000 \+ $boost_lib_version_req_minor \* 100 \+ $boost_lib_version_req_sub_minor`
AC_MSG_CHECKING(for boostlib >= $boost_lib_version_req)
succeeded=no
dnl On 64-bit systems check for system libraries in both lib64 and lib.
dnl The former is specified by FHS, but e.g. Debian does not adhere to
dnl this (as it rises problems for generic multi-arch support).
dnl The last entry in the list is chosen by default when no libraries
dnl are found, e.g. when only header-only libraries are installed!
libsubdirs="lib"
ax_arch=`uname -m`
case $ax_arch in
x86_64|ppc64|s390x|sparc64|aarch64)
libsubdirs="lib64 lib lib64"
;;
esac
dnl allow for real multi-arch paths e.g. /usr/lib/x86_64-linux-gnu. Give
dnl them priority over the other paths since, if libs are found there, they
dnl are almost assuredly the ones desired.
AC_REQUIRE([AC_CANONICAL_HOST])
libsubdirs="lib/${host_cpu}-${host_os} $libsubdirs"
case ${host_cpu} in
i?86)
libsubdirs="lib/i386-${host_os} $libsubdirs"
;;
esac
dnl first we check the system location for boost libraries
dnl this location ist chosen if boost libraries are installed with the --layout=system option
dnl or if you install boost with RPM
if test "$ac_boost_path" != ""; then
BOOST_CPPFLAGS="-I$ac_boost_path/include"
for ac_boost_path_tmp in $libsubdirs; do
if test -d "$ac_boost_path"/"$ac_boost_path_tmp" ; then
BOOST_LDFLAGS="-L$ac_boost_path/$ac_boost_path_tmp"
break
fi
done
elif test "$cross_compiling" != yes; then
for ac_boost_path_tmp in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path_tmp/include/boost" && test -r "$ac_boost_path_tmp/include/boost"; then
for libsubdir in $libsubdirs ; do
if ls "$ac_boost_path_tmp/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
done
BOOST_LDFLAGS="-L$ac_boost_path_tmp/$libsubdir"
BOOST_CPPFLAGS="-I$ac_boost_path_tmp/include"
break;
fi
done
fi
dnl overwrite ld flags if we have required special directory with
dnl --with-boost-libdir parameter
if test "$ac_boost_lib_path" != ""; then
BOOST_LDFLAGS="-L$ac_boost_lib_path"
fi
CPPFLAGS_SAVED="$CPPFLAGS"
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS_SAVED="$LDFLAGS"
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_REQUIRE([AC_PROG_CXX])
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION >= $WANT_BOOST_VERSION
// Everything is okay
#else
# error Boost version is too old
#endif
]])],[
AC_MSG_RESULT(yes)
succeeded=yes
found_system=yes
],[
])
AC_LANG_POP([C++])
dnl if we found no boost with system layout we search for boost libraries
dnl built and installed without the --layout=system option or for a staged(not installed) version
if test "x$succeeded" != "xyes"; then
_version=0
if test "$ac_boost_path" != ""; then
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
V_CHECK=`expr $_version_tmp \> $_version`
if test "$V_CHECK" = "1" ; then
_version=$_version_tmp
fi
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$ac_boost_path/include/boost-$VERSION_UNDERSCORE"
done
fi
else
if test "$cross_compiling" != yes; then
for ac_boost_path in /usr /usr/local /opt /opt/local ; do
if test -d "$ac_boost_path" && test -r "$ac_boost_path"; then
for i in `ls -d $ac_boost_path/include/boost-* 2>/dev/null`; do
_version_tmp=`echo $i | sed "s#$ac_boost_path##" | sed 's/\/include\/boost-//' | sed 's/_/./'`
V_CHECK=`expr $_version_tmp \> $_version`
if test "$V_CHECK" = "1" ; then
_version=$_version_tmp
best_path=$ac_boost_path
fi
done
fi
done
VERSION_UNDERSCORE=`echo $_version | sed 's/\./_/'`
BOOST_CPPFLAGS="-I$best_path/include/boost-$VERSION_UNDERSCORE"
if test "$ac_boost_lib_path" = ""; then
for libsubdir in $libsubdirs ; do
if ls "$best_path/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
done
BOOST_LDFLAGS="-L$best_path/$libsubdir"
fi
fi
if test "x$BOOST_ROOT" != "x"; then
for libsubdir in $libsubdirs ; do
if ls "$BOOST_ROOT/stage/$libsubdir/libboost_"* >/dev/null 2>&1 ; then break; fi
done
if test -d "$BOOST_ROOT" && test -r "$BOOST_ROOT" && test -d "$BOOST_ROOT/stage/$libsubdir" && test -r "$BOOST_ROOT/stage/$libsubdir"; then
version_dir=`expr //$BOOST_ROOT : '.*/\(.*\)'`
stage_version=`echo $version_dir | sed 's/boost_//' | sed 's/_/./g'`
stage_version_shorten=`expr $stage_version : '\([[0-9]]*\.[[0-9]]*\)'`
V_CHECK=`expr $stage_version_shorten \>\= $_version`
if test "$V_CHECK" = "1" -a "$ac_boost_lib_path" = "" ; then
AC_MSG_NOTICE(We will use a staged boost library from $BOOST_ROOT)
BOOST_CPPFLAGS="-I$BOOST_ROOT"
BOOST_LDFLAGS="-L$BOOST_ROOT/stage/$libsubdir"
fi
fi
fi
fi
CPPFLAGS="$CPPFLAGS $BOOST_CPPFLAGS"
export CPPFLAGS
LDFLAGS="$LDFLAGS $BOOST_LDFLAGS"
export LDFLAGS
AC_LANG_PUSH(C++)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
@%:@include <boost/version.hpp>
]], [[
#if BOOST_VERSION >= $WANT_BOOST_VERSION
// Everything is okay
#else
# error Boost version is too old
#endif
]])],[
AC_MSG_RESULT(yes)
succeeded=yes
found_system=yes
],[
])
AC_LANG_POP([C++])
fi
if test "$succeeded" != "yes" ; then
if test "$_version" = "0" ; then
AC_MSG_NOTICE([[We could not detect the boost libraries (version $boost_lib_version_req_shorten or higher). If you have a staged boost library (still not installed) please specify \$BOOST_ROOT in your environment and do not give a PATH to --with-boost option. If you are sure you have boost installed, then check your version number looking in <boost/version.hpp>. See http://randspringer.de/boost for more documentation.]])
else
AC_MSG_NOTICE([Your boost libraries seems to old (version $_version).])
fi
# execute ACTION-IF-NOT-FOUND (if present):
ifelse([$3], , :, [$3])
else
AC_SUBST(BOOST_CPPFLAGS)
AC_SUBST(BOOST_LDFLAGS)
AC_DEFINE(HAVE_BOOST,,[define if the Boost library is available])
# execute ACTION-IF-FOUND (if present):
ifelse([$2], , :, [$2])
fi
CPPFLAGS="$CPPFLAGS_SAVED"
LDFLAGS="$LDFLAGS_SAVED"
fi
])

@@ -4,7 +4,7 @@
#
# SYNOPSIS
#
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
#
# DESCRIPTION
#
@@ -19,8 +19,6 @@
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
# force the compiler to issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
#
@@ -55,7 +53,7 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 3
#serial 2
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[AC_PREREQ(2.59)dnl for _AC_LANG_PREFIX
@@ -63,7 +61,7 @@ AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])

@@ -4,7 +4,7 @@
#
# SYNOPSIS
#
# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
# AX_CHECK_LINK_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS])
#
# DESCRIPTION
#
@@ -19,8 +19,6 @@
# EXTRA-FLAGS FLAG". This can for example be used to force the linker to
# issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_LINK_IFELSE.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,COMPILE}_FLAG.
#
@@ -55,14 +53,14 @@
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 3
#serial 2
AC_DEFUN([AX_CHECK_LINK_FLAG],
[AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_ldflags_$4_$1])dnl
AC_CACHE_CHECK([whether the linker accepts $1], CACHEVAR, [
ax_check_save_flags=$LDFLAGS
LDFLAGS="$LDFLAGS $4 $1"
AC_LINK_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
AC_LINK_IFELSE([AC_LANG_PROGRAM()],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
LDFLAGS=$ax_check_save_flags])

@@ -1,332 +0,0 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
#
# DESCRIPTION
#
# This macro figures out how to build C programs using POSIX threads. It
# sets the PTHREAD_LIBS output variable to the threads library and linker
# flags, and the PTHREAD_CFLAGS output variable to any special C compiler
# flags that are needed. (The user can also force certain compiler
# flags/libs to be tested by setting these environment variables.)
#
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise). (This
# is necessary on AIX to use the special cc_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these flags,
# but also link it with them as well. e.g. you should link with
# $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
#
# If you are only building threads programs, you may wish to use these
# variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
# PTHREAD_PRIO_INHERIT symbol is defined when compiling with
# PTHREAD_CFLAGS.
#
# ACTION-IF-FOUND is a list of shell commands to run if a threads library
# is found, and ACTION-IF-NOT-FOUND is a list of commands to run it if it
# is not found. If ACTION-IF-FOUND is not specified, the default action
# will define HAVE_PTHREAD.
#
# Please let the authors know if this macro fails on any platform, or if
# you have any other suggestions or comments. This macro was based on work
# by SGJ on autoconf scripts for FFTW (http://www.fftw.org/) (with help
# from M. Frigo), as well as ac_pthread and hb_pthread macros posted by
# Alejandro Forero Cuervo to the autoconf macro repository. We are also
# grateful for the helpful feedback of numerous users.
#
# Updated for Autoconf 2.68 by Daniel Richard G.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.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 3 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, see <http://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 21
AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
AC_DEFUN([AX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_PUSH([C])
ax_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC([pthread_join], [ax_pthread_ok=yes])
AC_MSG_RESULT([$ax_pthread_ok])
if test x"$ax_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
ax_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case ${host_os} in
solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
;;
darwin*)
ax_pthread_flags="-pthread $ax_pthread_flags"
;;
esac
# Clang doesn't consider unrecognized options an error unless we specify
# -Werror. We throw in some extra Clang-specific options to ensure that
# this doesn't happen for GCC, which also accepts -Werror.
AC_MSG_CHECKING([if compiler needs -Werror to reject unknown flags])
save_CFLAGS="$CFLAGS"
ax_pthread_extra_flags="-Werror"
CFLAGS="$CFLAGS $ax_pthread_extra_flags -Wunknown-warning-option -Wsizeof-array-argument"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([int foo(void);],[foo()])],
[AC_MSG_RESULT([yes])],
[ax_pthread_extra_flags=
AC_MSG_RESULT([no])])
CFLAGS="$save_CFLAGS"
if test x"$ax_pthread_ok" = xno; then
for flag in $ax_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
if test x"$ax_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS $ax_pthread_extra_flags"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
static void routine(void *a) { a = 0; }
static void *start_routine(void *a) { return a; }],
[pthread_t th; pthread_attr_t attr;
pthread_create(&th, 0, start_routine, 0);
pthread_join(th, 0);
pthread_attr_init(&attr);
pthread_cleanup_push(routine, 0);
pthread_cleanup_pop(0) /* ; */])],
[ax_pthread_ok=yes],
[])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT([$ax_pthread_ok])
if test "x$ax_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$ax_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
[int attr = $attr; return attr /* ; */])],
[attr_name=$attr; break],
[])
done
AC_MSG_RESULT([$attr_name])
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE], [$attr_name],
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case ${host_os} in
aix* | freebsd* | darwin*) flag="-D_THREAD_SAFE";;
osf* | hpux*) flag="-D_REENTRANT";;
solaris*)
if test "$GCC" = "yes"; then
flag="-D_REENTRANT"
else
# TODO: What about Clang on Solaris?
flag="-mt -D_REENTRANT"
fi
;;
esac
AC_MSG_RESULT([$flag])
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
[ax_cv_PTHREAD_PRIO_INHERIT], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
[[int i = PTHREAD_PRIO_INHERIT;]])],
[ax_cv_PTHREAD_PRIO_INHERIT=yes],
[ax_cv_PTHREAD_PRIO_INHERIT=no])
])
AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
[AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: compile with *_r variant
if test "x$GCC" != xyes; then
case $host_os in
aix*)
AS_CASE(["x/$CC"],
[x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
[#handle absolute path differently from PATH based program lookup
AS_CASE(["x$CC"],
[x/*],
[AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])],
[AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])])])
;;
esac
fi
fi
test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
AC_SUBST([PTHREAD_LIBS])
AC_SUBST([PTHREAD_CFLAGS])
AC_SUBST([PTHREAD_CC])
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$ax_pthread_ok" = xyes; then
ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
:
else
ax_pthread_ok=no
$2
fi
AC_LANG_POP
])dnl AX_PTHREAD

@@ -1,37 +0,0 @@
# ===========================================================================
# http://www.gnu.org/software/autoconf-archive/ax_require_defined.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_REQUIRE_DEFINED(MACRO)
#
# DESCRIPTION
#
# AX_REQUIRE_DEFINED is a simple helper for making sure other macros have
# been defined and thus are available for use. This avoids random issues
# where a macro isn't expanded. Instead the configure script emits a
# non-fatal:
#
# ./configure: line 1673: AX_CFLAGS_WARN_ALL: command not found
#
# It's like AC_REQUIRE except it doesn't expand the required macro.
#
# Here's an example:
#
# AX_REQUIRE_DEFINED([AX_CHECK_LINK_FLAG])
#
# LICENSE
#
# Copyright (c) 2014 Mike Frysinger <vapier@gentoo.org>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 1
AC_DEFUN([AX_REQUIRE_DEFINED], [dnl
m4_ifndef([$1], [m4_fatal([macro ]$1[ is not defined; is a m4 file missing?])])
])dnl AX_REQUIRE_DEFINED

@@ -1,9 +0,0 @@
AC_DEFUN([MPD_DEPENDS], [
if test x$$2 = xno; then
if test x$$1 = xauto; then
$1=no
elif test x$$1 = xyes; then
AC_MSG_ERROR([$3])
fi
fi
])

@@ -10,16 +10,3 @@ AC_DEFUN([MPD_OPTIONAL_FUNC], [
[AC_CHECK_FUNC([$2],
[AC_DEFINE([$3], 1, [Define to use $1])],)])
])
dnl MPD_OPTIONAL_FUNC_NODEF(name, func)
dnl
dnl Allow the user to enable or disable the use of a function.
dnl Works similar to MPD_OPTIONAL_FUNC, however MPD_OPTIONAL_FUNC_NODEF
dnl does not invoke AC_DEFINE when function is enabled. Shell variable
dnl enable_$name is set to "yes" instead.
AC_DEFUN([MPD_OPTIONAL_FUNC_NODEF], [
AC_ARG_ENABLE([$1],
AS_HELP_STRING([--enable-$1],
[use the function "$1" (default: auto)]),,
[AC_CHECK_FUNC([$2], [enable_$1=yes],)])
])

117
m4/pkg.m4

@@ -1,5 +1,4 @@
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 1 (pkg-config-0.24)
#
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
#
@@ -26,12 +25,8 @@
# ----------------------------------
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])dnl
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
fi
@@ -44,6 +39,7 @@ if test -n "$PKG_CONFIG"; then
AC_MSG_RESULT([no])
PKG_CONFIG=""
fi
fi[]dnl
])# PKG_PROG_PKG_CONFIG
@@ -52,32 +48,34 @@ fi[]dnl
# Check to see whether a particular set of modules exists. Similar
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
#
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
# only at the first occurence in configure.ac, so if the first place
# it's called might be skipped (such as if it is within an "if", you
# have to call PKG_CHECK_EXISTS manually
#
# Similar to PKG_CHECK_MODULES, make sure that the first instance of
# this or PKG_CHECK_MODULES is called, or make sure to call
# PKG_CHECK_EXISTS manually
# --------------------------------------------------------------
AC_DEFUN([PKG_CHECK_EXISTS],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
if test -n "$PKG_CONFIG" && \
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
m4_default([$2], [:])
m4_ifval([$2], [$2], [:])
m4_ifvaln([$3], [else
$3])dnl
fi])
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
# ---------------------------------------------
m4_define([_PKG_CONFIG],
[if test -n "$$1"; then
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes ],
[pkg_failed=yes])
else
pkg_failed=untried
[if test -n "$PKG_CONFIG"; then
if test -n "$$1"; then
pkg_cv_[]$1="$$1"
else
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
[pkg_failed=yes])
fi
else
pkg_failed=untried
fi[]dnl
])# _PKG_CONFIG
@@ -119,17 +117,16 @@ and $1[]_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.])
if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --errors-to-stdout --print-errors "$2"`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
$1[]_PKG_ERRORS=`$PKG_CONFIG --errors-to-stdout --print-errors "$2"`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
m4_default([$4], [AC_MSG_ERROR(
ifelse([$4], , [AC_MSG_ERROR(dnl
[Package requirements ($2) were not met:
$$1_PKG_ERRORS
@@ -137,78 +134,24 @@ $$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])[]dnl
])
_PKG_TEXT
])],
[AC_MSG_RESULT([no])
$4])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
m4_default([$4], [AC_MSG_FAILURE(
ifelse([$4], , [AC_MSG_FAILURE(dnl
[The pkg-config script could not be found or is too old. Make sure it
is in your PATH or set the PKG_CONFIG environment variable to the full
path to pkg-config.
_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
To get pkg-config, see <http://www.freedesktop.org/software/pkgconfig>.])],
[$4])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
AC_MSG_RESULT([yes])
$3
ifelse([$3], , :, [$3])
fi[]dnl
])# PKG_CHECK_MODULES
# PKG_INSTALLDIR(DIRECTORY)
# -------------------------
# Substitutes the variable pkgconfigdir as the location where a module
# should install pkg-config .pc files. By default the directory is
# $libdir/pkgconfig, but the default can be changed by passing
# DIRECTORY. The user can override through the --with-pkgconfigdir
# parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
[with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_INSTALLDIR
# PKG_NOARCH_INSTALLDIR(DIRECTORY)
# -------------------------
# Substitutes the variable noarch_pkgconfigdir as the location where a
# module should install arch-independent pkg-config .pc files. By
# default the directory is $datadir/pkgconfig, but the default can be
# changed by passing DIRECTORY. The user can override through the
# --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
[with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_NOARCH_INSTALLDIR
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# -------------------------------------------
# Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])# PKG_CHECK_VAR

@@ -1,4 +1,5 @@
# Check if "struct ucred" is available.
# Check if "struct ucred" is available. If not, try harder with
# _GNU_SOURCE.
#
# Author: Max Kellermann <max@duempel.org>
@@ -9,6 +10,19 @@ AC_DEFUN([STRUCT_UCRED],[
[struct ucred cred;],
mpd_cv_have_struct_ucred=yes,
mpd_cv_have_struct_ucred=no)
if test x$mpd_cv_have_struct_ucred = xno; then
# glibc 2.8 forces _GNU_SOURCE on us
AC_TRY_COMPILE(
[#define _GNU_SOURCE
#include <sys/socket.h>],
[struct ucred cred;],
mpd_cv_have_struct_ucred=yes,
mpd_cv_have_struct_ucred=no)
if test x$mpd_cv_have_struct_ucred = xyes; then
# :(
CFLAGS="$CFLAGS -D_GNU_SOURCE"
fi
fi
])
AC_MSG_RESULT($mpd_cv_have_struct_ucred)

9
mpd.service.in Normal file

@@ -0,0 +1,9 @@
[Unit]
Description=Music Player Daemon
After=network.target sound.target
[Service]
ExecStart=@prefix@/bin/mpd --no-daemon
[Install]
WantedBy=multi-user.target

857
mpd.svg

@@ -1,857 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Sodipodi ("http://www.sodipodi.com/") -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.0"
x="0"
y="0"
width="128"
height="128"
id="svg1"
sodipodi:version="0.32"
sodipodi:docname="mpd.svg"
inkscape:version="0.47pre4 r22446"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-test5.png"
inkscape:export-xdpi="76.799988"
inkscape:export-ydpi="76.799988">
<sodipodi:namedview
id="base"
inkscape:zoom="2.6884788"
inkscape:cx="71.610485"
inkscape:cy="61.484977"
inkscape:window-width="1680"
inkscape:window-height="994"
inkscape:window-x="0"
inkscape:window-y="0"
showguides="true"
inkscape:guide-bbox="true"
showgrid="false"
inkscape:window-maximized="1"
inkscape:current-layer="svg1" />
<defs
id="defs3">
<inkscape:perspective
sodipodi:type="inkscape:persp3d"
inkscape:vp_x="0 : 80 : 1"
inkscape:vp_y="0 : 1000 : 0"
inkscape:vp_z="160 : 80 : 1"
inkscape:persp3d-origin="80 : 53.333333 : 1"
id="perspective118" />
<linearGradient
id="linearGradient919">
<stop
style="stop-color:#000000;stop-opacity:0.86092716;"
offset="0.0000000"
id="stop920" />
<stop
style="stop-color:#ffffff;stop-opacity:0.0000000;"
offset="1.0000000"
id="stop921" />
</linearGradient>
<linearGradient
id="linearGradient1068">
<stop
offset="0.0000000"
style="stop-color:#d2d2d2;stop-opacity:1.0000000;"
id="stop1070" />
<stop
offset="1.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;"
id="stop1069" />
</linearGradient>
<linearGradient
id="linearGradient1065">
<stop
offset="0.0000000"
style="stop-color:#ffffff;stop-opacity:1.0000000;"
id="stop1067" />
<stop
offset="1.0000000"
style="stop-color:#c2bfbf;stop-opacity:0.99607843;"
id="stop1066" />
</linearGradient>
<linearGradient
id="linearGradient1060">
<stop
offset="0.0000000"
style="stop-color:#878787;stop-opacity:1.0000000;"
id="stop1063" />
<stop
offset="1.0000000"
style="stop-color:#000000;stop-opacity:0.99607843;"
id="stop1061" />
</linearGradient>
<linearGradient
id="linearGradient645">
<stop
style="stop-color:#aca597;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop646" />
<stop
style="stop-color:#ffffff;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop647" />
</linearGradient>
<linearGradient
id="linearGradient593">
<stop
style="stop-color:#478acf;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop594" />
<stop
style="stop-color:#65c6f7;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop595" />
</linearGradient>
<linearGradient
id="linearGradient574">
<stop
style="stop-color:#85ad92;stop-opacity:1.0000;"
offset="0"
id="stop575" />
<stop
style="stop-color:#559db2;stop-opacity:0.7725;"
offset="1"
id="stop576" />
</linearGradient>
<linearGradient
id="linearGradient570">
<stop
style="stop-color:#999999;stop-opacity:0.7176;"
offset="0"
id="stop571" />
<stop
style="stop-color:#ffffff;stop-opacity:0.3725;"
offset="1"
id="stop572" />
</linearGradient>
<linearGradient
id="linearGradient573"
xlink:href="#linearGradient1068"
x1="40.458553"
y1="389.65582"
x2="36.063946"
y2="357.28375"
gradientTransform="matrix(2.3025192,0,0,0.29683004,-0.91913426,-1.5117091)"
gradientUnits="userSpaceOnUse" />
<linearGradient
id="linearGradient1213"
xlink:href="#linearGradient1068"
x1="123.71407"
y1="141.41566"
x2="98.353867"
y2="113.41083"
gradientTransform="matrix(0.91680324,0,0,0.74547827,-0.91913426,-1.5117091)"
gradientUnits="userSpaceOnUse" />
<radialGradient
id="radialGradient581"
xlink:href="#linearGradient919"
cx="0.095785439"
cy="0.16814159"
r="1.5409589"
fx="0.095785439"
fy="0.16814159" />
<linearGradient
id="linearGradient580"
xlink:href="#linearGradient1068"
x1="132.0352"
y1="135.68469"
x2="119.62381"
y2="111.07157"
gradientTransform="matrix(0.90170536,0,0,0.75796032,-0.91913426,-1.5117091)"
gradientUnits="userSpaceOnUse" />
<linearGradient
xlink:href="#linearGradient1060"
id="linearGradient901"
x1="0.93491787"
y1="0.92044502"
x2="-0.052546836"
y2="0.20347559" />
<linearGradient
xlink:href="#linearGradient593"
id="linearGradient902" />
<linearGradient
xlink:href="#linearGradient1068"
id="linearGradient916"
x1="0.14831461"
y1="-1.6875"
x2="0.43370786"
y2="1.8125" />
<defs
id="defs890">
<linearGradient
id="linearGradient922"
x1="0"
y1="0.5"
x2="1"
y2="0.5"
gradientUnits="objectBoundingBox"
spreadMethod="pad"
xlink:href="#linearGradient1065" />
<linearGradient
id="linearGradient908"
x1="0"
y1="0.5"
x2="1"
y2="0.5"
gradientUnits="objectBoundingBox"
spreadMethod="pad"
xlink:href="#linearGradient1060" />
<linearGradient
id="linearGradient894"
x1="0"
y1="0.5"
x2="1"
y2="0.5"
gradientUnits="objectBoundingBox"
spreadMethod="pad"
xlink:href="#linearGradient1068" />
<linearGradient
xlink:href="#linearGradient894"
id="linearGradient897"
x1="0.5955056"
y1="-0.33587787"
x2="0.61348313"
y2="1.1908396" />
<linearGradient
xlink:href="#linearGradient894"
id="linearGradient898"
x1="0.96449792"
y1="1.0278323"
x2="0.46738392"
y2="0.21800731" />
<linearGradient
xlink:href="#linearGradient908"
id="linearGradient907"
x1="0.57078654"
y1="2.3770492"
x2="0.33258426"
y2="0.49180329" />
<linearGradient
xlink:href="#linearGradient922"
id="linearGradient921"
x1="0.47058824"
y1="0.15384616"
x2="0.46547315"
y2="0.98380566" />
<linearGradient
xlink:href="#linearGradient922"
id="linearGradient948" />
<defs
id="defs987">
<linearGradient
id="linearGradient855"
x1="0"
y1="0.5"
x2="1"
y2="0.5"
gradientUnits="objectBoundingBox"
spreadMethod="pad"
xlink:href="#linearGradient908" />
<linearGradient
id="linearGradient1188"
x1="0"
y1="0.5"
x2="1"
y2="0.5"
gradientUnits="objectBoundingBox"
spreadMethod="pad"
xlink:href="#linearGradient922" />
<linearGradient
id="linearGradient831">
<stop
style="stop-color:#94897f;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop832" />
<stop
style="stop-color:#fff5fe;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop833" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient1188"
id="linearGradient834"
x1="0.87550199"
y1="0.34817815"
x2="-0.29317269"
y2="0.93522269"
gradientUnits="objectBoundingBox"
spreadMethod="pad" />
<radialGradient
xlink:href="#linearGradient1188"
id="radialGradient835"
r="0.55628061"
fy="0.28125"
fx="0.59090906"
cy="0.28125"
cx="0.59090906"
spreadMethod="pad" />
<linearGradient
xlink:href="#linearGradient1188"
id="linearGradient893"
x1="0.12793733"
y1="0.76923078"
x2="0.49608356"
y2="0.70850199" />
<linearGradient
xlink:href="#linearGradient855"
id="linearGradient625"
x1="0.035955057"
y1="1.0276498"
x2="0.053932585"
y2="-0.359447" />
<linearGradient
xlink:href="#linearGradient1188"
id="linearGradient627"
x1="1.2826855"
y1="0.12550607"
x2="-0.15547703"
y2="0.96356273" />
<radialGradient
xlink:href="#linearGradient1188"
id="radialGradient628"
r="1.5982224"
fy="0.4866707"
fx="0.36789617"
cy="0.4866707"
cx="0.36789617"
gradientTransform="scale(0.877379,1.139758)" />
<linearGradient
xlink:href="#linearGradient1188"
id="linearGradient628"
x1="0.76923078"
y1="0.14979757"
x2="0.41909814"
y2="0.73279351" />
</defs>
<sodipodi:namedview
id="namedview898"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.4732669"
inkscape:cx="50.051177"
inkscape:cy="18.096983"
inkscape:window-width="1022"
inkscape:window-height="670"
showguides="false"
snaptoguides="false"
showgrid="false"
snaptogrid="false"
inkscape:window-x="0"
inkscape:window-y="25">
<sodipodi:guide
orientation="vertical"
position="28.705556"
id="guide879" />
<sodipodi:guide
orientation="horizontal"
position="30.130655"
id="guide880" />
</sodipodi:namedview>
</defs>
<sodipodi:namedview
id="namedview1003"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.3368738"
inkscape:cx="24.541029"
inkscape:cy="14.368596"
inkscape:window-width="640"
inkscape:window-height="499"
showguides="true"
snaptoguides="true"
inkscape:window-x="138"
inkscape:window-y="169" />
<linearGradient
xlink:href="#linearGradient1060"
id="linearGradient1304"
x1="-0.20218579"
y1="0.21681416"
x2="0.67759562"
y2="0.57522124" />
<linearGradient
xlink:href="#linearGradient1065"
id="linearGradient1322"
x1="0.32404181"
y1="0.77876109"
x2="0.24041812"
y2="0.26548672" />
<defs
id="defs989">
<linearGradient
id="linearGradient850">
<stop
style="stop-color:#eed680;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop852" />
<stop
style="stop-color:#dfb546;stop-opacity:1.0000000;"
offset="0.68035328"
id="stop858" />
<stop
style="stop-color:#d8a429;stop-opacity:1.0000000;"
offset="0.77277374"
id="stop859" />
<stop
style="stop-color:#d1940c;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop857" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient850"
id="linearGradient569"
x1="0.11875"
y1="0.12612613"
x2="0.59375"
y2="0.66066068"
spreadMethod="pad" />
<linearGradient
id="linearGradient839">
<stop
style="stop-color:#46a046;stop-opacity:1.0000000;"
offset="0.0000000"
id="stop840" />
<stop
style="stop-color:#df421e;stop-opacity:1.0000000;"
offset="0.39364964"
id="stop841" />
<stop
style="stop-color:#ada7c8;stop-opacity:1.0000000;"
offset="0.72036445"
id="stop842" />
<stop
style="stop-color:#eed680;stop-opacity:1.0000000;"
offset="1.0000000"
id="stop843" />
</linearGradient>
<linearGradient
xlink:href="#linearGradient839"
id="linearGradient836"
x1="1.3267924e-17"
y1="0.5"
x2="1"
y2="0.5" />
<defs
id="defs604">
<linearGradient
id="linearGradient622">
<stop
style="stop-color:#f8e29d;stop-opacity:0.4471;"
offset="0"
id="stop623" />
<stop
style="stop-color:#272d2d;stop-opacity:0.4784;"
offset="1"
id="stop624" />
</linearGradient>
<linearGradient
id="linearGradient617">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop618" />
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="1"
id="stop619" />
</linearGradient>
<linearGradient
id="linearGradient613">
<stop
style="stop-color:#ffffff;stop-opacity:0.6235;"
offset="0"
id="stop614" />
<stop
style="stop-color:#5d6567;stop-opacity:1;"
offset="1"
id="stop615" />
</linearGradient>
<linearGradient
id="linearGradient607">
<stop
style="stop-color:#d7d5d5;stop-opacity:1;"
offset="0"
id="stop608" />
<stop
style="stop-color:#000000;stop-opacity:0.4039;"
offset="1"
id="stop609" />
</linearGradient>
<radialGradient
xlink:href="#linearGradient607"
id="radialGradient610"
cx="1.4287461"
cy="0.75323397"
r="0.85534656"
fx="1.4287461"
fy="0.75323397"
gradientTransform="matrix(1,2.268336e-6,-1.975559e-5,1,5.713033e-8,3.856326e-8)" />
<linearGradient
xlink:href="#linearGradient617"
id="linearGradient612"
x1="7.7024956"
y1="-2.0263922"
x2="62.759903"
y2="56.137772"
gradientTransform="scale(0.9953779,1.0046436)"
gradientUnits="userSpaceOnUse" />
<radialGradient
xlink:href="#linearGradient613"
id="radialGradient616"
cx="58.70882"
cy="53.831562"
r="43.551846"
fx="58.70882"
fy="53.831562"
gradientTransform="scale(0.99517298,1.0048504)"
gradientUnits="userSpaceOnUse" />
<linearGradient
xlink:href="#linearGradient617"
id="linearGradient621" />
<linearGradient
xlink:href="#linearGradient617"
id="linearGradient626"
x1="72.060211"
y1="55.161442"
x2="32.409"
y2="12.126946"
gradientTransform="matrix(0.995134,-1.068631e-5,-1.31398e-7,1.00489,0,0)"
gradientUnits="userSpaceOnUse" />
<linearGradient
xlink:href="#linearGradient607"
id="linearGradient687"
x1="67.707405"
y1="49.314793"
x2="-10.031048"
y2="4.6068792"
gradientTransform="scale(0.99522839,1.0047945)"
gradientUnits="userSpaceOnUse" />
<linearGradient
xlink:href="#linearGradient617"
id="linearGradient742"
x1="-7.4378386"
y1="25.923714"
x2="18.009745"
y2="10.089797"
gradientTransform="scale(0.889853,1.123781)" />
</defs>
<sodipodi:namedview
id="namedview889"
showguides="true"
snaptoguides="true"
inkscape:zoom="7.5625000"
inkscape:cx="24.000000"
inkscape:cy="24.000000"
inkscape:window-width="640"
inkscape:window-height="496"
inkscape:window-x="0"
inkscape:window-y="26" />
</defs>
<sodipodi:namedview
id="namedview1023"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="3.5521067"
inkscape:cx="66.459318"
inkscape:cy="62.629296"
inkscape:window-width="1150"
inkscape:window-height="752"
showgrid="true"
snaptogrid="true"
inkscape:window-x="0"
inkscape:window-y="29">
<inkscape:grid
id="GridFromPre046Settings"
type="xygrid"
originx="0px"
originy="0px"
spacingx="1.0000000mm"
spacingy="1.0000000mm"
color="#0000ff"
empcolor="#0000ff"
opacity="0.2"
empopacity="0.4"
empspacing="5" />
</sodipodi:namedview>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1068"
id="linearGradient2924"
x1="41.673889"
y1="320.40921"
x2="36.082947"
y2="279.22458"
gradientTransform="matrix(2.3376099,0,0,0.29237422,-0.91913426,-1.5117091)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1068"
id="linearGradient2926"
x1="134.95444"
y1="108.16693"
x2="102.05431"
y2="71.835884"
gradientTransform="matrix(0.91680324,0,0,0.74547824,-0.91913426,-1.5117091)"
gradientUnits="userSpaceOnUse" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1068"
id="linearGradient2928"
x1="145.32188"
y1="101.97199"
x2="129.22044"
y2="70.041069"
gradientTransform="matrix(0.90170536,0,0,0.75796032,-0.91913426,-1.5117091)"
gradientUnits="userSpaceOnUse" />
</defs>
<rect
style="fill-opacity:0.47154475;fill-rule:evenodd;stroke-width:3pt"
id="rect918"
width="48.72493"
height="42.16835"
ry="0.74231374"
x="67.536102"
y="66.474693"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="0.7811048" />
<rect
style="fill-opacity:0.47154475;fill-rule:evenodd;stroke-width:3pt"
id="rect1006"
width="63.211483"
height="54.705563"
ry="0.74231374"
x="64.47226"
y="30.558294"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="0.7811048" />
<rect
style="fill:#000000;fill-opacity:0.47058824;fill-rule:evenodd"
id="rect1005"
width="57.843418"
height="9.0050545"
ry="0.62889248"
x="65.398254"
y="82.153206"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="0.66175652" />
<rect
style="fill:url(#linearGradient2924);fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.82671446"
id="rect1007"
width="54.910637"
height="6.1445785"
ry="0.42912331"
x="64.622299"
y="82.282539"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="0.44939452" />
<rect
width="57.905403"
height="47.084496"
ry="1.7822117"
x="63.784973"
y="32.456562"
style="font-size:12px;fill:url(#linearGradient2926);fill-rule:evenodd;stroke:#000000;stroke-width:0"
id="rect1009"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="1.6336281" />
<rect
style="fill:#000000;fill-opacity:0.47058824;fill-rule:evenodd"
id="rect971"
width="44.58709"
height="6.9413123"
ry="0.62889248"
x="68.249886"
y="106.24529"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="0.66175652" />
<rect
width="64.637024"
height="54.068516"
ry="1.4120796"
x="59.853096"
y="28.740753"
style="font-size:12px;fill:url(#linearGradient2928);fill-rule:evenodd;stroke:#000000;stroke-width:1.65869105"
id="rect1008"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="1.3970968" />
<rect
width="51.129478"
height="39.964478"
ry="0.5422883"
x="66.358932"
y="34.89621"
style="font-size:12px;fill:#00b4ed;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.79054338;stroke-linejoin:round"
id="rect976"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="0.5422883" />
<metadata
id="metadata982">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work>
</rdf:RDF>
</metadata>
<rect
width="44.634872"
height="36.293858"
ry="1.7822117"
x="67.006332"
y="67.937927"
style="font-size:12px;fill:url(#linearGradient1213);fill-rule:evenodd;stroke:#000000;stroke-width:0"
id="rect575"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="1.633628" />
<path
sodipodi:type="arc"
style="font-size:12px;fill:#444040;fill-opacity:0.47058824;fill-rule:evenodd"
id="path672"
d="m 68.473,57.85183 a 23.629898,3.2222576 0 1 1 -47.259797,0 23.629898,3.2222576 0 1 1 47.259797,0 z"
sodipodi:cx="44.843102"
sodipodi:cy="57.85183"
sodipodi:rx="23.629898"
sodipodi:ry="3.2222576"
transform="matrix(1.4221482,0,-0.30247168,1.9834766,9.6201687,-10.428817)"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big2.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998" />
<path
sodipodi:type="arc"
style="font-size:12px;fill:#4e4d4b;fill-rule:evenodd;stroke:#000000;stroke-width:2.30019999;stroke-opacity:0.9565"
id="path625"
d="m 58.291138,27.531645 a 19.367088,19.556963 0 1 1 -38.734177,0 19.367088,19.556963 0 1 1 38.734177,0 z"
sodipodi:cx="38.924049"
sodipodi:cy="27.531645"
sodipodi:rx="19.367088"
sodipodi:ry="19.556963"
transform="matrix(-1.0172416,-0.47376693,-0.5523759,1.3286212,116.84611,57.272851)"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big2.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998" />
<path
sodipodi:type="arc"
style="font-size:12px;fill:url(#linearGradient612);fill-rule:evenodd;stroke:#000000;stroke-width:2.06100011;stroke-opacity:0.9565"
id="path605"
d="m 58.291138,27.531645 a 19.367088,19.556963 0 1 1 -38.734177,0 19.367088,19.556963 0 1 1 38.734177,0 z"
sodipodi:cx="38.924049"
sodipodi:cy="27.531645"
sodipodi:rx="19.367088"
sodipodi:ry="19.556963"
transform="matrix(-1.4321234,-0.79696518,-1.1299666,2.2349846,128.07685,29.383033)"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big2.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998" />
<path
sodipodi:type="arc"
style="font-size:12px;fill:url(#radialGradient616);fill-rule:evenodd;stroke:#000000;stroke-width:0.317;stroke-opacity:0.97829997"
id="path606"
d="m 58.291138,27.531645 a 19.367088,19.556963 0 1 1 -38.734177,0 19.367088,19.556963 0 1 1 38.734177,0 z"
sodipodi:cx="38.924049"
sodipodi:cy="27.531645"
sodipodi:rx="19.367088"
sodipodi:ry="19.556963"
transform="matrix(-1.1546358,-0.69851175,-0.95634664,1.9588777,108.06887,31.115628)"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big2.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998" />
<path
sodipodi:type="arc"
style="font-size:12px;fill-rule:evenodd;stroke-width:1.63499999"
id="path686"
d="m 58.291138,27.531645 a 19.367088,19.556963 0 1 1 -38.734177,0 19.367088,19.556963 0 1 1 38.734177,0 z"
sodipodi:cx="38.924049"
sodipodi:cy="27.531645"
sodipodi:rx="19.367088"
sodipodi:ry="19.556963"
transform="matrix(-0.39495459,-0.4546194,-0.52881207,0.94219495,73.198184,52.427791)"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big2.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998" />
<path
sodipodi:type="arc"
style="font-size:12px;fill:url(#linearGradient687);fill-rule:evenodd;stroke:#3f3b3b;stroke-width:0.77380002"
id="path611"
d="m 58.291138,27.531645 a 19.367088,19.556963 0 1 1 -38.734177,0 19.367088,19.556963 0 1 1 38.734177,0 z"
sodipodi:cx="38.924049"
sodipodi:cy="27.531645"
sodipodi:rx="19.367088"
sodipodi:ry="19.556963"
transform="matrix(-0.36949013,-0.40957751,-0.49471918,0.84885391,70.248021,52.066881)"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big2.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998" />
<rect
style="fill:url(#linearGradient573);fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:0.82671446"
id="rect934"
width="42.326431"
height="4.7363882"
ry="0.42912331"
x="67.651756"
y="106.34497"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="0.44939449" />
<rect
width="49.823761"
height="41.677303"
ry="1.4120796"
x="63.975548"
y="65.073692"
style="font-size:12px;fill:url(#linearGradient580);fill-rule:evenodd;stroke:#000000;stroke-width:1.27855873;stroke-opacity:1"
id="rect562"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="1.3970969" />
<rect
width="39.411831"
height="30.805574"
ry="0.5422883"
x="68.990387"
y="70.097008"
style="font-size:12px;fill:#003d88;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.61407685;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:0.93023257"
id="rect975"
inkscape:export-filename="/cowserver/documents/httpd/vhosts/images/mpd-big7.png"
inkscape:export-xdpi="721.66998"
inkscape:export-ydpi="721.66998"
rx="0.5422883" />
</svg>

Before

(image error) Size: 27 KiB

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -23,15 +23,12 @@
class Mutex;
class Cond;
class Error;
struct ArchivePlugin;
class ArchiveVisitor;
class InputStream;
class ArchiveFile {
public:
const ArchivePlugin &plugin;
const struct archive_plugin &plugin;
ArchiveFile(const ArchivePlugin &_plugin)
ArchiveFile(const struct archive_plugin &_plugin)
:plugin(_plugin) {}
protected:

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -21,14 +21,14 @@
#include "ArchiveList.hxx"
#include "ArchivePlugin.hxx"
#include "util/StringUtil.hxx"
#include "plugins/Bzip2ArchivePlugin.hxx"
#include "plugins/Iso9660ArchivePlugin.hxx"
#include "plugins/ZzipArchivePlugin.hxx"
#include "archive/Bzip2ArchivePlugin.hxx"
#include "archive/Iso9660ArchivePlugin.hxx"
#include "archive/ZzipArchivePlugin.hxx"
#include "util/Macros.hxx"
#include <string.h>
const ArchivePlugin *const archive_plugins[] = {
const struct archive_plugin *const archive_plugins[] = {
#ifdef HAVE_BZ2
&bz2_archive_plugin,
#endif
@@ -48,7 +48,7 @@ static bool archive_plugins_enabled[ARRAY_SIZE(archive_plugins) - 1];
archive_plugins_for_each(plugin) \
if (archive_plugins_enabled[archive_plugin_iterator - archive_plugins])
const ArchivePlugin *
const struct archive_plugin *
archive_plugin_from_suffix(const char *suffix)
{
if (suffix == nullptr)
@@ -62,7 +62,7 @@ archive_plugin_from_suffix(const char *suffix)
return nullptr;
}
const ArchivePlugin *
const struct archive_plugin *
archive_plugin_from_name(const char *name)
{
archive_plugins_for_each_enabled(plugin)
@@ -75,7 +75,7 @@ archive_plugin_from_name(const char *name)
void archive_plugin_init_all(void)
{
for (unsigned i = 0; archive_plugins[i] != nullptr; ++i) {
const ArchivePlugin *plugin = archive_plugins[i];
const struct archive_plugin *plugin = archive_plugins[i];
if (plugin->init == nullptr || archive_plugins[i]->init())
archive_plugins_enabled[i] = true;
}

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,22 +20,22 @@
#ifndef MPD_ARCHIVE_LIST_HXX
#define MPD_ARCHIVE_LIST_HXX
struct ArchivePlugin;
struct archive_plugin;
extern const ArchivePlugin *const archive_plugins[];
extern const struct archive_plugin *const archive_plugins[];
#define archive_plugins_for_each(plugin) \
for (const ArchivePlugin *plugin, \
for (const struct archive_plugin *plugin, \
*const*archive_plugin_iterator = &archive_plugins[0]; \
(plugin = *archive_plugin_iterator) != nullptr; \
++archive_plugin_iterator)
/* interface for using plugins */
const ArchivePlugin *
const struct archive_plugin *
archive_plugin_from_suffix(const char *suffix);
const ArchivePlugin *
const struct archive_plugin *
archive_plugin_from_name(const char *name);
/* this is where we "load" all the "plugins" ;-) */

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -24,6 +24,7 @@
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include <errno.h>
gcc_pure

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,18 +20,17 @@
#include "config.h"
#include "ArchivePlugin.hxx"
#include "ArchiveFile.hxx"
#include "fs/Path.hxx"
#include "util/Error.hxx"
#include <assert.h>
ArchiveFile *
archive_file_open(const ArchivePlugin *plugin, Path path,
archive_file_open(const struct archive_plugin *plugin, const char *path,
Error &error)
{
assert(plugin != nullptr);
assert(plugin->open != nullptr);
assert(!path.IsNull());
assert(path != nullptr);
ArchiveFile *file = plugin->open(path, error);
assert((file == nullptr) == error.IsDefined());

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,11 +20,12 @@
#ifndef MPD_ARCHIVE_PLUGIN_HXX
#define MPD_ARCHIVE_PLUGIN_HXX
struct InputStream;
class ArchiveFile;
class Path;
class ArchiveVisitor;
class Error;
struct ArchivePlugin {
struct archive_plugin {
const char *name;
/**
@@ -45,7 +46,7 @@ struct ArchivePlugin {
* returns pointer to handle used is all operations with this archive
* or nullptr when opening fails
*/
ArchiveFile *(*open)(Path path_fs, Error &error);
ArchiveFile *(*open)(const char *path_fs, Error &error);
/**
* suffixes handled by this plugin.
@@ -55,7 +56,7 @@ struct ArchivePlugin {
};
ArchiveFile *
archive_file_open(const ArchivePlugin *plugin, Path path,
archive_file_open(const struct archive_plugin *plugin, const char *path,
Error &error);
#endif

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -21,9 +21,9 @@
#include "AudioConfig.hxx"
#include "AudioFormat.hxx"
#include "AudioParser.hxx"
#include "config/ConfigData.hxx"
#include "config/ConfigGlobal.hxx"
#include "config/ConfigOption.hxx"
#include "ConfigData.hxx"
#include "ConfigGlobal.hxx"
#include "ConfigOption.hxx"
#include "util/Error.hxx"
#include "system/FatalError.hxx"

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,6 +19,7 @@
#include "config.h"
#include "AvahiPoll.hxx"
#include "event/Loop.hxx"
#include "event/SocketMonitor.hxx"
#include "event/TimeoutMonitor.hxx"
@@ -57,6 +58,10 @@ public:
Schedule(FromAvahiWatchEvent(_event));
}
~AvahiWatch() {
Steal();
}
static void WatchUpdate(AvahiWatch *w, AvahiWatchEvent event) {
w->Schedule(FromAvahiWatchEvent(event));
}

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,226 +0,0 @@
/*
* 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_CHRONO_HXX
#define MPD_CHRONO_HXX
#include "Compiler.h"
#include <chrono>
#include <utility>
#include <cstdint>
#if defined(__GNUC__) && !GCC_CHECK_VERSION(4,7) && !defined(__clang__)
/* std::chrono::duration operators are "constexpr" since gcc 4.7 */
#define chrono_constexpr gcc_pure
#else
#define chrono_constexpr constexpr
#endif
/**
* A time stamp within a song. Granularity is 1 millisecond and the
* maximum value is about 49 days.
*/
class SongTime : public std::chrono::duration<std::uint32_t, std::milli> {
typedef std::chrono::duration<std::uint32_t, std::milli> Base;
typedef Base::rep rep;
public:
SongTime() = default;
template<typename T>
explicit constexpr SongTime(T t):Base(t) {}
static constexpr SongTime zero() {
return SongTime(Base::zero());
}
static constexpr SongTime FromS(unsigned s) {
return SongTime(rep(s) * 1000);
}
static constexpr SongTime FromS(float s) {
return SongTime(rep(s * 1000));
}
static constexpr SongTime FromS(double s) {
return SongTime(rep(s * 1000));
}
static constexpr SongTime FromMS(rep ms) {
return SongTime(ms);
}
constexpr rep ToS() const {
return count() / rep(1000);
}
constexpr rep RoundS() const {
return (count() + 500) / rep(1000);
}
constexpr rep ToMS() const {
return count();
}
template<typename T=rep>
constexpr T ToScale(unsigned scale) const {
return count() * T(scale) / 1000;
}
/**
* Convert a scalar value with the given scale to a #SongTime
* instance.
*
* @param value the input value
* @param scale the value's scale in Hz
*/
template<typename T=rep>
static constexpr SongTime FromScale(T value, unsigned scale) {
return SongTime(value * T(1000) / T(scale));
}
constexpr double ToDoubleS() const {
return double(count()) / 1000.;
};
constexpr bool IsZero() const {
return count() == 0;
}
constexpr bool IsPositive() const {
return count() > 0;
}
chrono_constexpr SongTime operator+(const SongTime &other) const {
return SongTime(*(const Base *)this + (const Base &)other);
}
chrono_constexpr SongTime operator-(const SongTime &other) const {
return SongTime(*(const Base *)this - (const Base &)other);
}
};
/**
* A variant of #SongTime that is based on a signed integer. It can
* be used for relative values.
*/
class SignedSongTime : public std::chrono::duration<std::int32_t, std::milli> {
typedef std::chrono::duration<std::int32_t, std::milli> Base;
typedef Base::rep rep;
public:
SignedSongTime() = default;
template<typename T>
explicit constexpr SignedSongTime(T t):Base(t) {}
/**
* Allow implicit conversion from SongTime to SignedSongTime.
*/
constexpr SignedSongTime(SongTime t):Base(t) {}
static constexpr SignedSongTime zero() {
return SignedSongTime(Base::zero());
}
/**
* Generate a negative value.
*/
static constexpr SignedSongTime Negative() {
return SignedSongTime(-1);
}
static constexpr SignedSongTime FromS(int s) {
return SignedSongTime(rep(s) * 1000);
}
static constexpr SignedSongTime FromS(unsigned s) {
return SignedSongTime(rep(s) * 1000);
}
static constexpr SignedSongTime FromS(float s) {
return SignedSongTime(rep(s * 1000));
}
static constexpr SignedSongTime FromS(double s) {
return SignedSongTime(rep(s * 1000));
}
static constexpr SignedSongTime FromMS(rep ms) {
return SignedSongTime(ms);
}
constexpr rep ToS() const {
return count() / rep(1000);
}
constexpr rep RoundS() const {
return (count() + 500) / rep(1000);
}
constexpr rep ToMS() const {
return count();
}
template<typename T=rep>
constexpr T ToScale(unsigned scale) const {
return count() * T(scale) / 1000;
}
/**
* Convert a scalar value with the given scale to a
* #SignedSongTime instance.
*
* @param value the input value
* @param scale the value's scale in Hz
*/
template<typename T=rep>
static constexpr SignedSongTime FromScale(T value, unsigned scale) {
return SignedSongTime(value * T(1000) / T(scale));
}
constexpr double ToDoubleS() const {
return double(count()) / 1000.;
};
constexpr bool IsZero() const {
return count() == 0;
}
constexpr bool IsPositive() const {
return count() > 0;
}
constexpr bool IsNegative() const {
return count() < 0;
}
chrono_constexpr SignedSongTime operator+(const SignedSongTime &other) const {
return SignedSongTime(*(const Base *)this + (const Base &)other);
}
chrono_constexpr SignedSongTime operator-(const SignedSongTime &other) const {
return SignedSongTime(*(const Base *)this - (const Base &)other);
}
};
#undef chrono_constexpr
#endif

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,7 +18,7 @@
*/
#include "config.h"
#include "Domain.hxx"
#include "ClientInternal.hxx"
#include "util/Domain.hxx"
const Domain smbclient_domain("smbclient");
const Domain client_domain("client");

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -27,8 +27,6 @@
#include "event/TimeoutMonitor.hxx"
#include "Compiler.h"
#include <boost/intrusive/list.hpp>
#include <set>
#include <string>
#include <list>
@@ -38,25 +36,14 @@
struct sockaddr;
class EventLoop;
class Path;
struct Partition;
class Database;
class Storage;
class Client final
: FullyBufferedSocket, TimeoutMonitor,
public boost::intrusive::list_base_hook<boost::intrusive::link_mode<boost::intrusive::normal_link>> {
class Client final : private FullyBufferedSocket, TimeoutMonitor {
public:
Partition &partition;
struct playlist &playlist;
struct PlayerControl &player_control;
struct Disposer {
void operator()(Client *client) const {
delete client;
}
};
unsigned permission;
/** the uid of the client process, or -1 if unknown */
@@ -95,11 +82,6 @@ public:
Client(EventLoop &loop, Partition &partition,
int fd, int uid, int num);
~Client() {
if (FullyBufferedSocket::IsDefined())
FullyBufferedSocket::Close();
}
bool IsConnected() const {
return FullyBufferedSocket::IsDefined();
}
@@ -127,7 +109,7 @@ public:
* a local (UNIX domain) socket?
*/
bool IsLocal() const {
return uid > 0;
return uid >= 0;
}
unsigned GetPermission() const {
@@ -169,27 +151,6 @@ public:
void UnsubscribeAll();
bool PushMessage(const ClientMessage &msg);
/**
* Is this client allowed to use the specified local file?
*
* Note that this function is vulnerable to timing/symlink attacks.
* We cannot fix this as long as there are plugins that open a file by
* its name, and not by file descriptor / callbacks.
*
* @param path_fs the absolute path name in filesystem encoding
* @return true if access is allowed
*/
bool AllowFile(Path path_fs, Error &error) const;
/**
* Wrapper for Instance::GetDatabase().
*/
gcc_pure
const Database *GetDatabase(Error &error) const;
gcc_pure
const Storage *GetStorage() const;
private:
/* virtual methods from class BufferedSocket */
virtual InputResult OnSocketInput(void *data, size_t length) override;
@@ -204,7 +165,7 @@ void client_manager_init(void);
void
client_new(EventLoop &loop, Partition &partition,
int fd, const sockaddr *sa, size_t sa_length, int uid);
int fd, const struct sockaddr *sa, size_t sa_length, int uid);
/**
* Write a C string to the client.

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -18,30 +18,36 @@
*/
#include "config.h"
#include "ClientFile.hxx"
#include "Client.hxx"
#include "protocol/Ack.hxx"
#include "fs/Path.hxx"
#include "fs/FileSystem.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <unistd.h>
bool
Client::AllowFile(Path path_fs, Error &error) const
client_allow_file(const Client &client, Path path_fs, Error &error)
{
#ifdef WIN32
(void)client;
(void)path_fs;
error.Set(ack_domain, ACK_ERROR_PERMISSION, "Access denied");
return false;
#else
const int uid = client.GetUID();
if (uid >= 0 && (uid_t)uid == geteuid())
/* always allow access if user runs his own MPD
instance */
return true;
if (uid <= 0) {
if (uid < 0) {
/* unauthenticated client */
error.Set(ack_domain, ACK_ERROR_PERMISSION, "Access denied");
return false;

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,22 +17,24 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_INPUT_LOCAL_OPEN_HXX
#define MPD_INPUT_LOCAL_OPEN_HXX
#ifndef MPD_CLIENT_FILE_HXX
#define MPD_CLIENT_FILE_HXX
#include "check.h"
class InputStream;
class Client;
class Path;
class Mutex;
class Cond;
class Error;
/**
* Open a "local" file. This is a wrapper for the input plugins
* "file" and "archive".
* Is this client allowed to use the specified local file?
*
* Note that this function is vulnerable to timing/symlink attacks.
* We cannot fix this as long as there are plugins that open a file by
* its name, and not by file descriptor / callbacks.
*
* @param path_fs the absolute path name in filesystem encoding
* @return true if access is allowed
*/
InputStream *
OpenLocalInputStream(Path path, Mutex &mutex, Cond &cond, Error &error);
bool
client_allow_file(const Client &client, Path path_fs, Error &error);
#endif

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,8 @@
#include "config.h"
#include "ClientInternal.hxx"
#include "config/ConfigGlobal.hxx"
#include "ClientList.hxx"
#include "ConfigGlobal.hxx"
#define CLIENT_TIMEOUT_DEFAULT (60)
#define CLIENT_MAX_COMMAND_LIST_DEFAULT (2048*1024)

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -28,15 +28,22 @@
void
ClientList::Remove(Client &client)
{
assert(size > 0);
assert(!list.empty());
list.erase(list.iterator_to(client));
auto i = std::find(list.begin(), list.end(), &client);
assert(i != list.end());
list.erase(i);
--size;
}
void
ClientList::CloseAll()
{
list.clear_and_dispose(Client::Disposer());
while (!list.empty())
list.front()->Close();
assert(size == 0);
}
void
@@ -44,6 +51,6 @@ ClientList::IdleAdd(unsigned flags)
{
assert(flags != 0);
for (auto &client : list)
client.IdleAdd(flags);
for (const auto &client : list)
client->IdleAdd(flags);
}

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,39 +20,38 @@
#ifndef MPD_CLIENT_LIST_HXX
#define MPD_CLIENT_LIST_HXX
#include "Client.hxx"
#include <list>
class Client;
class ClientList {
typedef boost::intrusive::list<Client,
boost::intrusive::constant_time_size<true>> List;
const unsigned max_size;
List list;
unsigned size;
std::list<Client *> list;
public:
ClientList(unsigned _max_size)
:max_size(_max_size) {}
:max_size(_max_size), size(0) {}
~ClientList() {
CloseAll();
}
List::iterator begin() {
std::list<Client *>::iterator begin() {
return list.begin();
}
List::iterator end() {
std::list<Client *>::iterator end() {
return list.end();
}
bool IsFull() const {
return list.size() >= max_size;
return size >= max_size;
}
void Add(Client &client) {
list.push_front(client);
list.push_front(&client);
++size;
}
void Remove(Client &client);

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -24,12 +24,6 @@
#include <string>
#ifdef WIN32
/* fuck WIN32! */
#include <windows.h>
#undef GetMessage
#endif
/**
* A client-to-client message.
*/

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -28,12 +28,16 @@
#include "util/Error.hxx"
#include "Log.hxx"
#include <glib.h>
#include <assert.h>
#include <sys/types.h>
#ifdef WIN32
#include <winsock2.h>
#else
#include <sys/socket.h>
#endif
#include <unistd.h>
#ifdef HAVE_LIBWRAP
#include <tcpd.h>
@@ -61,14 +65,15 @@ client_new(EventLoop &loop, Partition &partition,
int fd, const struct sockaddr *sa, size_t sa_length, int uid)
{
static unsigned int next_client_num;
const auto remote = sockaddr_to_string(sa, sa_length);
char *remote;
assert(fd >= 0);
#ifdef HAVE_LIBWRAP
if (sa->sa_family != AF_UNIX) {
// TODO: shall we obtain the program name from argv[0]?
const char *progname = "mpd";
char *hostaddr = sockaddr_to_string(sa, sa_length,
IgnoreError());
const char *progname = g_get_prgname();
struct request_info req;
request_init(&req, RQ_FILE, fd, RQ_DAEMON, progname, 0);
@@ -79,11 +84,14 @@ client_new(EventLoop &loop, Partition &partition,
/* tcp wrappers says no */
FormatWarning(client_domain,
"libwrap refused connection (libwrap=%s) from %s",
progname, remote.c_str());
progname, hostaddr);
g_free(hostaddr);
close_socket(fd);
return;
}
g_free(hostaddr);
}
#endif /* HAVE_WRAP */
@@ -101,8 +109,9 @@ client_new(EventLoop &loop, Partition &partition,
client_list.Add(*client);
FormatInfo(client_domain, "[%u] opened from %s",
client->num, remote.c_str());
remote = sockaddr_to_string(sa, sa_length, IgnoreError());
FormatInfo(client_domain, "[%u] opened from %s", client->num, remote);
g_free(remote);
}
void

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,11 +19,11 @@
#include "config.h"
#include "ClientInternal.hxx"
#include "Partition.hxx"
#include "Instance.hxx"
#include "Main.hxx"
#include "event/Loop.hxx"
#include "util/StringUtil.hxx"
#include "util/CharUtil.hxx"
#include <assert.h>
#include <string.h>
BufferedSocket::InputResult
@@ -39,10 +39,11 @@ Client::OnSocketInput(void *data, size_t length)
BufferedSocket::ConsumeInput(newline + 1 - p);
/* skip whitespace at the end of the line */
char *end = StripRight(p, newline);
while (newline > p && IsWhitespaceOrNull(newline[-1]))
--newline;
/* terminate the string at the end of the line */
*end = 0;
*newline = 0;
CommandResult result = client_process_line(*this, p);
switch (result) {
@@ -53,7 +54,7 @@ Client::OnSocketInput(void *data, size_t length)
case CommandResult::KILL:
Close();
partition.instance.event_loop->Break();
main_loop->Break();
return InputResult::CLOSED;
case CommandResult::FINISH:

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,6 +22,11 @@
#include "Idle.hxx"
#include <assert.h>
#include <string.h>
bool Unsubscribe(const char *channel);
void UnsubscribeAll();
bool PushMessage(const ClientMessage &msg);
Client::SubscribeResult
Client::Subscribe(const char *channel)

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -22,115 +22,57 @@
#include "ls.hxx"
#include "LogInit.hxx"
#include "Log.hxx"
#include "config/ConfigGlobal.hxx"
#include "decoder/DecoderList.hxx"
#include "decoder/DecoderPlugin.hxx"
#include "output/Registry.hxx"
#include "output/OutputPlugin.hxx"
#include "input/Registry.hxx"
#include "input/InputPlugin.hxx"
#include "playlist/PlaylistRegistry.hxx"
#include "playlist/PlaylistPlugin.hxx"
#include "ConfigGlobal.hxx"
#include "DecoderList.hxx"
#include "DecoderPlugin.hxx"
#include "OutputList.hxx"
#include "OutputPlugin.hxx"
#include "InputRegistry.hxx"
#include "InputPlugin.hxx"
#include "PlaylistRegistry.hxx"
#include "PlaylistPlugin.hxx"
#include "fs/AllocatedPath.hxx"
#include "fs/Traits.hxx"
#include "fs/FileSystem.hxx"
#include "fs/StandardDirectory.hxx"
#include "util/Error.hxx"
#include "util/Domain.hxx"
#include "util/OptionDef.hxx"
#include "util/OptionParser.hxx"
#ifdef ENABLE_DATABASE
#include "db/Registry.hxx"
#include "db/DatabasePlugin.hxx"
#include "storage/Registry.hxx"
#include "storage/StoragePlugin.hxx"
#endif
#ifdef ENABLE_NEIGHBOR_PLUGINS
#include "neighbor/Registry.hxx"
#include "neighbor/NeighborPlugin.hxx"
#endif
#include "system/FatalError.hxx"
#ifdef ENABLE_ENCODER
#include "encoder/EncoderList.hxx"
#include "encoder/EncoderPlugin.hxx"
#include "EncoderList.hxx"
#include "EncoderPlugin.hxx"
#endif
#ifdef ENABLE_ARCHIVE
#include "archive/ArchiveList.hxx"
#include "archive/ArchivePlugin.hxx"
#include "ArchiveList.hxx"
#include "ArchivePlugin.hxx"
#endif
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef WIN32
#define CONFIG_FILE_LOCATION "mpd\\mpd.conf"
#define APP_CONFIG_FILE_LOCATION "conf\\mpd.conf"
#define CONFIG_FILE_LOCATION "\\mpd\\mpd.conf"
#else
#define USER_CONFIG_FILE_LOCATION1 ".mpdconf"
#define USER_CONFIG_FILE_LOCATION2 ".mpd/mpd.conf"
#define USER_CONFIG_FILE_LOCATION_XDG "mpd/mpd.conf"
#endif
static constexpr OptionDef opt_kill(
"kill", "kill the currently running mpd session");
static constexpr OptionDef opt_no_config(
"no-config", "don't read from config");
static constexpr OptionDef opt_no_daemon(
"no-daemon", "don't detach from console");
static constexpr OptionDef opt_stdout(
"stdout", nullptr); // hidden, compatibility with old versions
static constexpr OptionDef opt_stderr(
"stderr", "print messages to stderr");
static constexpr OptionDef opt_verbose(
"verbose", 'v', "verbose logging");
static constexpr OptionDef opt_version(
"version", 'V', "print version number");
static constexpr OptionDef opt_help(
"help", 'h', "show help options");
static constexpr OptionDef opt_help_alt(
nullptr, '?', nullptr); // hidden, standard alias for --help
static constexpr Domain cmdline_domain("cmdline");
gcc_noreturn
static void version(void)
{
puts("Music Player Daemon " VERSION
#ifdef GIT_COMMIT
" (" GIT_COMMIT ")"
#endif
"\n"
puts("Music Player Daemon " VERSION "\n"
"\n"
"Copyright (C) 2003-2007 Warren Dukes <warren.dukes@gmail.com>\n"
"Copyright (C) 2008-2014 Max Kellermann <max@duempel.org>\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");
#ifdef ENABLE_DATABASE
puts("\n"
"Database plugins:");
for (auto i = database_plugins; *i != nullptr; ++i)
printf(" %s", (*i)->name);
puts("\n\n"
"Storage plugins:");
for (auto i = storage_plugins; *i != nullptr; ++i)
printf(" %s", (*i)->name);
#endif
#ifdef ENABLE_NEIGHBOR_PLUGINS
puts("\n\n"
"Neighbor plugins:");
for (auto i = neighbor_plugins; *i != nullptr; ++i)
printf(" %s", (*i)->name);
#endif
puts("\n\n"
"warranty; not even MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n"
"Decoders plugins:");
decoder_plugins_for_each([](const DecoderPlugin &plugin){
@@ -190,165 +132,122 @@ static void version(void)
exit(EXIT_SUCCESS);
}
static void PrintOption(const OptionDef &opt)
static const char *summary =
"Music Player Daemon - a daemon for playing music.";
gcc_pure
static AllocatedPath
PathBuildChecked(const AllocatedPath &a, PathTraits::const_pointer b)
{
if (opt.HasShortOption())
printf(" -%c, --%-12s%s\n",
opt.GetShortOption(),
opt.GetLongOption(),
opt.GetDescription());
else
printf(" --%-16s%s\n",
opt.GetLongOption(),
opt.GetDescription());
}
if (a.IsNull())
return AllocatedPath::Null();
gcc_noreturn
static void help(void)
{
puts("Usage:\n"
" mpd [OPTION...] [path/to/mpd.conf]\n"
"\n"
"Music Player Daemon - a daemon for playing music.\n"
"\n"
"Options:");
PrintOption(opt_help);
PrintOption(opt_kill);
PrintOption(opt_no_config);
PrintOption(opt_no_daemon);
PrintOption(opt_stderr);
PrintOption(opt_verbose);
PrintOption(opt_version);
exit(EXIT_SUCCESS);
}
class ConfigLoader
{
Error &error;
bool result;
public:
ConfigLoader(Error &_error) : error(_error), result(false) { }
bool GetResult() const { return result; }
bool TryFile(const Path path);
bool TryFile(const AllocatedPath &base_path,
PathTraitsFS::const_pointer path);
};
bool ConfigLoader::TryFile(Path path)
{
if (FileExists(path)) {
result = ReadConfigFile(path, error);
return true;
}
return false;
}
bool ConfigLoader::TryFile(const AllocatedPath &base_path,
PathTraitsFS::const_pointer path)
{
if (base_path.IsNull())
return false;
auto full_path = AllocatedPath::Build(base_path, path);
return TryFile(full_path);
return AllocatedPath::Build(a, b);
}
bool
parse_cmdline(int argc, char **argv, struct options *options,
Error &error)
{
bool use_config_file = true;
GOptionContext *context;
bool ret;
static gboolean option_version,
option_no_daemon,
option_no_config;
const GOptionEntry entries[] = {
{ "kill", 0, 0, G_OPTION_ARG_NONE, &options->kill,
"kill the currently running mpd session", nullptr },
{ "no-config", 0, 0, G_OPTION_ARG_NONE, &option_no_config,
"don't read from config", nullptr },
{ "no-daemon", 0, 0, G_OPTION_ARG_NONE, &option_no_daemon,
"don't detach from console", nullptr },
{ "stdout", 0, 0, G_OPTION_ARG_NONE, &options->log_stderr,
nullptr, nullptr },
{ "stderr", 0, 0, G_OPTION_ARG_NONE, &options->log_stderr,
"print messages to stderr", nullptr },
{ "verbose", 'v', 0, G_OPTION_ARG_NONE, &options->verbose,
"verbose logging", nullptr },
{ "version", 'V', 0, G_OPTION_ARG_NONE, &option_version,
"print version number", nullptr },
{ nullptr, 0, 0, G_OPTION_ARG_NONE, nullptr, nullptr, nullptr }
};
options->kill = false;
options->daemon = true;
options->log_stderr = false;
options->verbose = false;
// First pass: handle command line options
OptionParser parser(argc, argv);
while (parser.HasEntries()) {
if (!parser.ParseNext())
continue;
if (parser.CheckOption(opt_kill)) {
options->kill = true;
continue;
}
if (parser.CheckOption(opt_no_config)) {
use_config_file = false;
continue;
}
if (parser.CheckOption(opt_no_daemon)) {
options->daemon = false;
continue;
}
if (parser.CheckOption(opt_stderr, opt_stdout)) {
options->log_stderr = true;
continue;
}
if (parser.CheckOption(opt_verbose)) {
options->verbose = true;
continue;
}
if (parser.CheckOption(opt_version))
version();
if (parser.CheckOption(opt_help, opt_help_alt))
help();
context = g_option_context_new("[path/to/mpd.conf]");
g_option_context_add_main_entries(context, entries, nullptr);
error.Format(cmdline_domain, "invalid option: %s",
parser.GetOption());
return false;
}
g_option_context_set_summary(context, summary);
GError *gerror = nullptr;
ret = g_option_context_parse(context, &argc, &argv, &gerror);
g_option_context_free(context);
if (!ret)
FatalError("option parsing failed", gerror);
if (option_version)
version();
/* initialize the logging library, so the configuration file
parser can use it already */
log_early_init(options->verbose);
if (!use_config_file) {
options->daemon = !option_no_daemon;
if (option_no_config) {
LogDebug(cmdline_domain,
"Ignoring config, using daemon defaults");
return true;
}
} else if (argc <= 1) {
/* default configuration file path */
// Second pass: find non-option parameters (i.e. config file)
const char *config_file = nullptr;
for (int i = 1; i < argc; ++i) {
if (OptionParser::IsOption(argv[i]))
continue;
if (config_file == nullptr) {
config_file = argv[i];
continue;
#ifdef WIN32
AllocatedPath path = PathBuildChecked(AllocatedPath::FromUTF8(g_get_user_config_dir()),
CONFIG_FILE_LOCATION);
if (!path.IsNull() && FileExists(path))
return ReadConfigFile(path, error);
const char *const*system_config_dirs =
g_get_system_config_dirs();
for (unsigned i = 0; system_config_dirs[i] != nullptr; ++i) {
path = PathBuildChecked(AllocatedPath::FromUTF8(system_config_dirs[i]),
CONFIG_FILE_LOCATION);
if (!path.IsNull() && FileExists(path))
return ReadConfigFile(path, error);
}
#else
AllocatedPath path = PathBuildChecked(AllocatedPath::FromUTF8(g_get_user_config_dir()),
USER_CONFIG_FILE_LOCATION_XDG);
if (!path.IsNull() && FileExists(path))
return ReadConfigFile(path, error);
path = PathBuildChecked(AllocatedPath::FromUTF8(g_get_home_dir()),
USER_CONFIG_FILE_LOCATION1);
if (!path.IsNull() && FileExists(path))
return ReadConfigFile(path, error);
path = PathBuildChecked(AllocatedPath::FromUTF8(g_get_home_dir()),
USER_CONFIG_FILE_LOCATION2);
if (!path.IsNull() && FileExists(path))
return ReadConfigFile(path, error);
path = AllocatedPath::FromUTF8(SYSTEM_CONFIG_FILE_LOCATION);
if (!path.IsNull() && FileExists(path))
return ReadConfigFile(path, error);
#endif
error.Set(cmdline_domain, "No configuration file found");
return false;
} else if (argc == 2) {
/* specified configuration file */
return ReadConfigFile(Path::FromFS(argv[1]), error);
} else {
error.Set(cmdline_domain, "too many arguments");
return false;
}
if (config_file != nullptr) {
/* use specified configuration file */
return ReadConfigFile(Path::FromFS(config_file), error);
}
/* use default configuration file path */
ConfigLoader loader(error);
bool found =
#ifdef WIN32
loader.TryFile(GetUserConfigDir(), CONFIG_FILE_LOCATION) ||
loader.TryFile(GetSystemConfigDir(), CONFIG_FILE_LOCATION) ||
loader.TryFile(GetAppBaseDir(), APP_CONFIG_FILE_LOCATION);
#else
loader.TryFile(GetUserConfigDir(),
USER_CONFIG_FILE_LOCATION_XDG) ||
loader.TryFile(GetHomeDir(), USER_CONFIG_FILE_LOCATION1) ||
loader.TryFile(GetHomeDir(), USER_CONFIG_FILE_LOCATION2) ||
loader.TryFile(Path::FromFS(SYSTEM_CONFIG_FILE_LOCATION));
#endif
if (!found) {
error.Set(cmdline_domain, "No configuration file found");
return false;
}
return loader.GetResult();
}

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,13 +20,15 @@
#ifndef MPD_COMMAND_LINE_HXX
#define MPD_COMMAND_LINE_HXX
#include <glib.h>
class Error;
struct options {
bool kill;
bool daemon;
bool log_stderr;
bool verbose;
gboolean kill;
gboolean daemon;
gboolean log_stderr;
gboolean verbose;
};
bool

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,33 +20,45 @@
#ifndef COMPILER_H
#define COMPILER_H
#define GCC_CHECK_VERSION(major, minor) \
(defined(__GNUC__) && \
(__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor))))
#define GCC_MAKE_VERSION(major, minor, patchlevel) ((major) * 10000 + (minor) * 100 + patchlevel)
#ifdef __GNUC__
#define GCC_VERSION (__GNUC__ * 10000 \
+ __GNUC_MINOR__ * 100 \
+ __GNUC_PATCHLEVEL__)
#define GCC_VERSION GCC_MAKE_VERSION(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
#else
#define GCC_VERSION 0
#endif
#define GCC_CHECK_VERSION(major, minor) \
(defined(__GNUC__) && GCC_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
/**
* Are we building with gcc (not clang or any other compiler) and a
* version older than the specified one?
*/
#define GCC_OLDER_THAN(major, minor) \
(defined(__GNUC__) && !defined(__clang__) && \
GCC_VERSION < GCC_MAKE_VERSION(major, minor, 0))
#ifdef __clang__
# define CLANG_VERSION (__clang_major__ * 10000 \
+ __clang_minor__ * 100 \
+ __clang_patchlevel__)
# define CLANG_VERSION GCC_MAKE_VERSION(__clang_major__, __clang_minor__, __clang_patchlevel__)
# if __clang_major__ < 3
# error Sorry, your clang version is too old. You need at least version 3.1.
# endif
#elif defined(__GNUC__)
# if !GCC_CHECK_VERSION(4,6)
# if GCC_OLDER_THAN(4,6)
# error Sorry, your gcc version is too old. You need at least version 4.6.
# endif
#else
# warning Untested compiler. Use at your own risk!
#endif
/**
* Are we building with the specified version of clang or newer?
*/
#define CLANG_CHECK_VERSION(major, minor) \
(defined(__clang__) && \
CLANG_VERSION >= GCC_MAKE_VERSION(major, minor, 0))
#if GCC_CHECK_VERSION(4,0)
/* GCC 4.x */
@@ -141,7 +153,7 @@
#if defined(__cplusplus)
/* support for C++11 "override" was added in gcc 4.7 */
#if !defined(__clang__) && !GCC_CHECK_VERSION(4,7)
#if GCC_OLDER_THAN(4,7)
#define override
#define final
#endif

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -26,6 +26,7 @@
#include "system/FatalError.hxx"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
int
@@ -63,7 +64,7 @@ block_param::GetBoolValue() const
}
config_param::config_param(const char *_value, int _line)
:next(nullptr), value(_value), line(_line), used(false) {}
:next(nullptr), value(_value), line(_line) {}
config_param::~config_param()
{

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,6 +19,7 @@
#include "config.h"
#include "ConfigFile.hxx"
#include "ConfigError.hxx"
#include "ConfigData.hxx"
#include "ConfigTemplates.hxx"
#include "util/Tokenizer.hxx"
@@ -31,7 +32,9 @@
#include "Log.hxx"
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#define MAX_STRING_SIZE MPD_PATH_MAX+80
@@ -96,7 +99,7 @@ config_read_block(FILE *fp, int *count, char *string, Error &error)
}
(*count)++;
line = StripLeft(line);
line = strchug_fast(line);
if (*line == 0 || *line == CONF_COMMENT)
continue;
@@ -104,7 +107,7 @@ config_read_block(FILE *fp, int *count, char *string, Error &error)
/* end of this block; return from the function
(and from this "while" loop) */
line = StripLeft(line + 1);
line = strchug_fast(line + 1);
if (*line != 0 && *line != CONF_COMMENT) {
delete ret;
error.Format(config_file_domain,
@@ -155,7 +158,7 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, Error &error)
count++;
line = StripLeft(string);
line = strchug_fast(string);
if (*line == 0 || *line == CONF_COMMENT)
continue;
@@ -205,7 +208,7 @@ ReadConfigFile(ConfigData &config_data, FILE *fp, Error &error)
return false;
}
line = StripLeft(tokenizer.Rest() + 1);
line = strchug_fast(tokenizer.Rest() + 1);
if (*line != 0 && *line != CONF_COMMENT) {
error.Format(config_file_domain,
"line %i: Unknown tokens after '{'",

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -30,6 +30,8 @@
#include "system/FatalError.hxx"
#include "Log.hxx"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
static ConfigData config_data;
@@ -74,32 +76,17 @@ void config_global_check(void)
Check(p);
}
const config_param *
config_get_param(ConfigOption option)
const struct config_param *
config_get_next_param(ConfigOption option, const struct config_param * last)
{
config_param *param = config_data.params[unsigned(option)];
config_param *param = last != nullptr
? last->next
: config_data.params[unsigned(option)];
if (param != nullptr)
param->used = true;
return param;
}
const config_param *
config_find_block(ConfigOption option, const char *key, const char *value)
{
for (const config_param *param = config_get_param(option);
param != nullptr; param = param->next) {
const char *value2 = param->GetBlockValue(key);
if (value2 == nullptr)
FormatFatalError("block without '%s' name in line %d",
key, param->line);
if (strcmp(value2, value) == 0)
return param;
}
return nullptr;
}
const char *
config_get_string(ConfigOption option, const char *default_value)
{

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -26,7 +26,6 @@
class Error;
class Path;
class AllocatedPath;
struct config_param;
void config_global_init(void);
void config_global_finish(void);
@@ -40,20 +39,19 @@ void config_global_check(void);
bool
ReadConfigFile(Path path, Error &error);
/* don't free the returned value
set _last_ to nullptr to get first entry */
gcc_pure
const config_param *
config_get_param(enum ConfigOption option);
const struct config_param *
config_get_next_param(enum ConfigOption option,
const struct config_param *last);
/**
* Find a block with a matching attribute.
*
* @param option the blocks to search
* @param key the attribute name
* @param value the expected attribute value
*/
gcc_pure
const config_param *
config_find_block(ConfigOption option, const char *key, const char *value);
static inline const struct config_param *
config_get_param(enum ConfigOption option)
{
return config_get_next_param(option, nullptr);
}
/* Note on gcc_pure: Some of the functions declared pure are not
really pure in strict sense. They have side effect such that they

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -32,7 +32,6 @@ enum ConfigOption {
CONF_LOG_FILE,
CONF_PID_FILE,
CONF_STATE_FILE,
CONF_STATE_FILE_INTERVAL,
CONF_RESTORE_PAUSED,
CONF_USER,
CONF_GROUP,
@@ -78,7 +77,6 @@ enum ConfigOption {
CONF_DESPOTIFY_HIGH_BITRATE,
CONF_AUDIO_FILTER,
CONF_DATABASE,
CONF_NEIGHBORS,
CONF_MAX
};

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -22,10 +22,11 @@
#include "fs/AllocatedPath.hxx"
#include "fs/Traits.hxx"
#include "fs/Domain.hxx"
#include "fs/StandardDirectory.hxx"
#include "util/Error.hxx"
#include "ConfigGlobal.hxx"
#include <glib.h>
#include <assert.h>
#include <string.h>
@@ -38,14 +39,14 @@
static AllocatedPath
GetHome(const char *user, Error &error)
{
AllocatedPath result = GetHomeDir(user);
if (result.IsNull()) {
passwd *pw = getpwnam(user);
if (pw == nullptr) {
error.Format(path_domain,
"no such user: %s", user);
return AllocatedPath::Null();
}
return result;
return AllocatedPath::FromFS(pw->pw_dir);
}
/**
@@ -54,14 +55,14 @@ GetHome(const char *user, Error &error)
static AllocatedPath
GetHome(Error &error)
{
AllocatedPath result = GetHomeDir();
if (result.IsNull()) {
const char *home = g_get_home_dir();
if (home == nullptr) {
error.Set(path_domain,
"problems getting home for current user");
return AllocatedPath::Null();
}
return result;
return AllocatedPath::FromUTF8(home, error);
}
/**
@@ -118,7 +119,7 @@ ParsePath(const char *path, Error &error)
return AllocatedPath::Null();
return AllocatedPath::Build(home, path2);
} else if (!PathTraitsUTF8::IsAbsolute(path)) {
} else if (!PathTraits::IsAbsoluteUTF8(path)) {
error.Format(path_domain,
"not an absolute path: %s", path);
return AllocatedPath::Null();

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -32,7 +32,6 @@ const ConfigTemplate config_templates[] = {
{ "log_file", false, false },
{ "pid_file", false, false },
{ "state_file", false, false },
{ "state_file_interval", false, false },
{ "restore_paused", false, false },
{ "user", false, false },
{ "group", false, false },
@@ -78,7 +77,6 @@ const ConfigTemplate config_templates[] = {
{ "despotify_high_bitrate", false, false },
{ "filter", true, true },
{ "database", false, true },
{ "neighbors", true, true },
};
static constexpr unsigned n_config_templates =

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -20,6 +20,8 @@
#ifndef MPD_CONFIG_TEMPLATES_HXX
#define MPD_CONFIG_TEMPLATES_HXX
#include "ConfigOption.hxx"
struct ConfigTemplate {
const char *const name;
const bool repeatable;

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -19,7 +19,6 @@
#include "config.h"
#include "CrossFade.hxx"
#include "Chrono.hxx"
#include "MusicChunk.hxx"
#include "AudioFormat.hxx"
#include "util/NumberParser.hxx"
@@ -27,6 +26,8 @@
#include "Log.hxx"
#include <assert.h>
#include <string.h>
#include <stdlib.h>
static constexpr Domain cross_fade_domain("cross_fade");
@@ -86,7 +87,7 @@ mixramp_interpolate(const char *ramp_list, float required_db)
}
unsigned
CrossFadeSettings::Calculate(SignedSongTime total_time,
CrossFadeSettings::Calculate(float total_time,
float replay_gain_db, float replay_gain_prev_db,
const char *mixramp_start, const char *mixramp_prev_end,
const AudioFormat af,
@@ -96,8 +97,7 @@ CrossFadeSettings::Calculate(SignedSongTime total_time,
unsigned int chunks = 0;
float chunks_f;
if (total_time.IsNegative() ||
duration < 0 || duration >= total_time.ToDoubleS() ||
if (duration < 0 || duration >= total_time ||
/* we can't crossfade when the audio formats are different */
af != old_format)
return 0;

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -23,7 +23,6 @@
#include "Compiler.h"
struct AudioFormat;
class SignedSongTime;
struct CrossFadeSettings {
/**
@@ -61,7 +60,7 @@ struct CrossFadeSettings {
* should be disabled for this song change
*/
gcc_pure
unsigned Calculate(SignedSongTime total_time,
unsigned Calculate(float total_time,
float replay_gain_db, float replay_gain_prev_db,
const char *mixramp_start,
const char *mixramp_prev_end,

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -23,15 +23,19 @@
#include "fs/AllocatedPath.hxx"
#include "fs/FileSystem.hxx"
#include "util/Domain.hxx"
#include "PidFile.hxx"
#include "Log.hxx"
#include <glib.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#ifndef WIN32
#include <sys/wait.h>
#include <signal.h>
#include <pwd.h>
#include <grp.h>
@@ -56,11 +60,6 @@ static AllocatedPath pidfile = AllocatedPath::Null();
/* whether "group" conf. option was given */
static bool had_group = false;
/**
* The write end of a pipe that is used to notify the parent process
* that initialization has finished and that it should detach.
*/
static int detach_fd = -1;
void
daemonize_kill(void)
@@ -136,93 +135,73 @@ daemonize_set_user(void)
}
}
void
daemonize_begin(bool detach)
static void
daemonize_detach(void)
{
/* release the current working directory */
if (chdir("/") < 0)
FatalError("problems changing to root directory");
if (!detach)
/* the rest of this function deals with detaching the
process */
return;
/* do this before daemonizing so we can fail gracefully if we
can't write to the pid file */
PidFile pidfile2(pidfile);
/* flush all file handles before duplicating the buffers */
fflush(nullptr);
/* create a pipe to synchronize the parent and the child */
#ifdef HAVE_DAEMON
int fds[2];
if (pipe(fds) < 0)
FatalSystemError("pipe() failed");
if (daemon(0, 1))
FatalSystemError("daemon() failed");
/* move to a child process */
#elif defined(HAVE_FORK)
pid_t pid = fork();
if (pid < 0)
/* detach from parent process */
switch (fork()) {
case -1:
FatalSystemError("fork() failed");
if (pid == 0) {
/* in the child process */
pidfile2.Close();
close(fds[0]);
detach_fd = fds[1];
/* detach from the current session */
setsid();
/* continue starting MPD */
return;
case 0:
break;
default:
/* exit the parent process */
_exit(EXIT_SUCCESS);
}
/* in the parent process */
/* release the current working directory */
close(fds[1]);
if (chdir("/") < 0)
FatalError("problems changing to root directory");
int result;
ssize_t nbytes = read(fds[0], &result, sizeof(result));
if (nbytes == (ssize_t)sizeof(result)) {
/* the child process was successful */
pidfile2.Write(pid);
exit(EXIT_SUCCESS);
}
/* detach from the current session */
/* something bad happened in the child process */
setsid();
pidfile2.Delete(pidfile);
#else
FatalError("no support for daemonizing");
#endif
int status;
pid_t pid2 = waitpid(pid, &status, 0);
if (pid2 < 0)
FatalSystemError("waitpid() failed");
if (WIFSIGNALED(status))
FormatFatalError("MPD died from signal %d%s", WTERMSIG(status),
WCOREDUMP(status) ? " (core dumped)" : "");
exit(WEXITSTATUS(status));
LogDebug(daemon_domain, "daemonized");
}
void
daemonize_commit()
daemonize(bool detach)
{
if (detach_fd >= 0) {
/* tell the parent process to let go of us and exit
indicating success */
int result = 0;
write(detach_fd, &result, sizeof(result));
close(detach_fd);
} else
/* the pidfile was not written by the parent because
there is no parent - do it now */
PidFile(pidfile).Write();
FILE *fp = nullptr;
if (!pidfile.IsNull()) {
/* do this before daemon'izing so we can fail gracefully if we can't
* write to the pid file */
LogDebug(daemon_domain, "opening pid file");
fp = FOpen(pidfile, "w+");
if (!fp) {
const std::string utf8 = pidfile.ToUTF8();
FormatFatalSystemError("Failed to create pid file \"%s\"",
pidfile.c_str());
}
}
if (detach)
daemonize_detach();
if (!pidfile.IsNull()) {
LogDebug(daemon_domain, "writing pid file");
fprintf(fp, "%lu\n", (unsigned long)getpid());
fclose(fp);
}
}
void
@@ -236,10 +215,10 @@ daemonize_init(const char *user, const char *group, AllocatedPath &&_pidfile)
user_uid = pwd->pw_uid;
user_gid = pwd->pw_gid;
user_name = strdup(user);
user_name = g_strdup(user);
/* this is needed by libs such as arts */
setenv("HOME", pwd->pw_dir, true);
g_setenv("HOME", pwd->pw_dir, true);
}
if (group) {
@@ -262,7 +241,7 @@ daemonize_finish(void)
pidfile = AllocatedPath::Null();
}
free(user_name);
g_free(user_name);
}
#endif

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -81,19 +81,11 @@ daemonize_set_user(void)
#ifndef WIN32
void
daemonize_begin(bool detach);
daemonize(bool detach);
#else
static inline void
daemonize_begin(bool detach)
daemonize(bool detach)
{ (void)detach; }
#endif
#ifndef WIN32
void
daemonize_commit();
#else
static inline void
daemonize_commit() {}
#endif
#endif

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -30,8 +30,6 @@ enum db_error {
DB_DISABLED,
DB_NOT_FOUND,
DB_CONFLICT,
};
extern const Domain db_domain;

161
src/DatabaseGlue.cxx Normal file

@@ -0,0 +1,161 @@
/*
* Copyright (C) 2003-2013 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 "DatabaseGlue.hxx"
#include "DatabaseSimple.hxx"
#include "DatabaseRegistry.hxx"
#include "DatabaseSave.hxx"
#include "DatabaseError.hxx"
#include "Directory.hxx"
#include "util/Error.hxx"
#include "ConfigData.hxx"
#include "Stats.hxx"
#include "DatabasePlugin.hxx"
#include "db/SimpleDatabasePlugin.hxx"
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <errno.h>
static Database *db;
static bool db_is_open;
static bool is_simple;
bool
DatabaseGlobalInit(const config_param &param, Error &error)
{
assert(db == nullptr);
assert(!db_is_open);
const char *plugin_name =
param.GetBlockValue("plugin", "simple");
is_simple = strcmp(plugin_name, "simple") == 0;
const DatabasePlugin *plugin = GetDatabasePluginByName(plugin_name);
if (plugin == nullptr) {
error.Format(db_domain,
"No such database plugin: %s", plugin_name);
return false;
}
db = plugin->create(param, error);
return db != nullptr;
}
void
DatabaseGlobalDeinit(void)
{
if (db_is_open)
db->Close();
if (db != nullptr)
delete db;
}
const Database *
GetDatabase()
{
assert(db == nullptr || db_is_open);
return db;
}
const Database *
GetDatabase(Error &error)
{
assert(db == nullptr || db_is_open);
if (db == nullptr)
error.Set(db_domain, DB_DISABLED, "No database");
return db;
}
bool
db_is_simple(void)
{
assert(db == nullptr || db_is_open);
return is_simple;
}
Directory *
db_get_root(void)
{
assert(db != nullptr);
assert(db_is_simple());
return ((SimpleDatabase *)db)->GetRoot();
}
Directory *
db_get_directory(const char *name)
{
#if !CLANG_CHECK_VERSION(3,6)
/* disabled on clang due to -Wtautological-pointer-compare */
assert(name != nullptr);
#endif
if (db == nullptr)
return nullptr;
Directory *music_root = db_get_root();
return music_root->LookupDirectory(name);
}
bool
db_save(Error &error)
{
assert(db != nullptr);
assert(db_is_open);
assert(db_is_simple());
return ((SimpleDatabase *)db)->Save(error);
}
bool
DatabaseGlobalOpen(Error &error)
{
assert(db != nullptr);
assert(!db_is_open);
if (!db->Open(error))
return false;
db_is_open = true;
stats_update();
return true;
}
bool
db_exists()
{
assert(db != nullptr);
assert(db_is_open);
assert(db_is_simple());
return ((SimpleDatabase *)db)->GetUpdateStamp() > 0;
}

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2003-2014 The Music Player Daemon Project
* Copyright (C) 2003-2013 The Music Player Daemon Project
* http://www.musicpd.org
*
* This program is free software; you can redistribute it and/or modify
@@ -17,34 +17,43 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPD_DATABASE_SONG_HXX
#define MPD_DATABASE_SONG_HXX
#ifndef MPD_DATABASE_GLUE_HXX
#define MPD_DATABASE_GLUE_HXX
#include "Compiler.h"
struct LightSong;
struct config_param;
class Database;
class Storage;
class DetachedSong;
class Error;
/**
* "Detach" the #Song object, i.e. convert it to a #DetachedSong
* instance.
* Initialize the database library.
*
* @param param the database configuration block
*/
gcc_pure
DetachedSong
DatabaseDetachSong(const Storage &storage, const LightSong &song);
bool
DatabaseGlobalInit(const config_param &param, Error &error);
void
DatabaseGlobalDeinit(void);
bool
DatabaseGlobalOpen(Error &error);
/**
* Look up a song in the database and convert it to a #DetachedSong
* instance. The caller is responsible for freeing it.
*
* @return nullptr on error
* Returns the global #Database instance. May return nullptr if this MPD
* configuration has no database (no music_directory was configured).
*/
gcc_malloc gcc_nonnull_all
DetachedSong *
DatabaseDetachSong(const Database &db, const Storage &storage, const char *uri,
Error &error);
gcc_pure
const Database *
GetDatabase();
/**
* Returns the global #Database instance. May return nullptr if this MPD
* configuration has no database (no music_directory was configured).
*/
gcc_pure
const Database *
GetDatabase(Error &error);
#endif

Some files were not shown because too many files have changed in this diff Show More