Building & Installing pianod
You will need a C++11 or better compiler. C++ dependencies may need to be compiled with the same compiler; see note under troubleshooting.
- libffmpeg, gstreamer or AVFoundation (macOS/OS X 10.7+)
- libao or libsdl for use with ffmpeg
- gcrypt (Optional, for Pandora)
- cURL (Optional, for Pandora)
- gnutls, mbed TLS, LibreSSL, macOS/SecureTransport, or OpenSSL (to support TLS in cURL, and for secure pianod connections)
- mbed TLS (Optional, alternative to gcrypt/gnutls for Pandora).
- json-c (Optional, for Pandora)
- taglib (Recommended for filesystem/local file source with ffmpeg; C++)
- zlib, gzstream (Optional, for compressing data files)
- libpiano, rapidxml, etc. (Included; see COPYING for license information.)
- UTF-8 console/locale for best results
libav support has been deprecated. Older versions will work, and new versions may even compile. However, similar-but-different APIs makes libav hazardous and it may not work correctly. The divergence of APIs coupled with poor documentation and support has lead to discontinuing support.
All dependencies can be downloaded and set up manually, but most systems have package managers that streamline this process. On macOS/OS X, see MacPorts; on Ubuntu or Debian, see apt-get; Gentoo, emerge; Fedora and RedHat, RPM; FreeBSD, try pkg or pkg_add. For other Linux distributions, check Wikipedia’s list to determine the packaging system used.
|cURL w/ TLS support||Required||No||No|
† Provides better results than ffmpeg and gstreamer metadata readers; does not improve on AVFoundation. AVFoundation is found on macOS 10.7+.
|Clang (Apple LLVM)||≤ 3.8||≥ 6.0|
|gcc (GNU compiler collection)||< 4.8||≥ 4.8.4|
†† Viability of other compilers is unknown.
If you have all of the dependencies listed above, use:
./configure && make
If you’d like to use the unit test to verify it works:
You can run the software directly from the source directory now:
./src/pianod -c "$PWD/html"
To install it issue:
sudo make install
On startup, pianod reads your
~/.config/pianod2/startscript. A sample is found in
the contrib directory.
Automatic Build Configuration
If you let
configure make the choices, you will get
the best supported set of features with the least redundancy:
- Communication: Line and HTTP ports, and HTTPS support is available.
- Media engine: gstreamer, ifnotfound ffmpeg, ifnotfound AVFoundation.
- Audio output: One audio output scheme.
- For ffmpeg: libavdevices and libao, ifnotfound libsdl.
- For AVFoundation, whatever it provides.
- All sources, subject to dependencies. For AVFoundation, only filesystem is supported.
- File compression will be used, if available.
Manual Build Configuration
Configuring the build has some options:
- When enabled, configure expects a media engine and at least one output or it fails with an error. Disabling sanity reduces this to a warning.
- When enabled, turns on assertions (self-checks in the software), some additional logging and debug compile (-g). These enlarge and slow the code down slightly, but make debugging much, much easier.
- When enabled (and it also needs to be enabled with a
command-line switch), pianod will allow login with system usernames
and passwords, creating pianod accounts on-demand when necessary.
passwdto force a validation method.
- When included, pianod stores persisted data in compressed form. If omitted, compression is used if required libraries are available at configuration time.
- When included, new connections are validated with
hosts_access(5). If omitted, access control is used if support is available at configuration time.
- Chooses a media engine package. Packages may be:
avfoundation(macOS/OS X), or
- Forces inclusion or exclusion of TLS support, or chooses a
specific TLS package to use. Packages may be:
- Forces inclusion or exclusion taglib for reading ID3 data for the filesystem source. If omitted, taglib is included if the ffmpeg media engine is in use and the library is available at configuration time.
- Forces inclusion or exclusion of Pandora. If omitted, Pandora is included if its dependencies are available.
- Forces inclusion or exclusion of the tone generator. The tone generator has a 1KHz and 440Hz tones which could be used for setting levels, and is helpful for troubleshooting and testing, but generally it’s not needed. If omitted, the tone generator is included if either libao or libsdl outputs are available. It is not compatible with AVFoundation for output.
- Forces inclusion or exclusion of the filesystem source, which uses media on a local disk or mounted network filesystem.
- Forces inclusion or exclusion of libao or libsdl, two different output libraries. Both work with all sources for ffmpeg, or for the tone generator when using AVFoundation. However, libsdl does not support crossfading. Automatic configuration chooses one; you may choose more, or 0 if you disable sanity.
- The third output library. On Linux, there is a good chance you
will need to
room reconfigure driver alsa id experimental. Test this with the console; after confirming it’s what you need, you can add it to your startscript.
macOS (formerly Mac OS X)
You’ll need to install Xcode developer tools found your installation DVD or downloaded from the App store or developer.apple.com. Tools are free. Alternately, on newer macOS versions, open terminal and enter “cc”. A window will pop up allowing you to install the command-line tools, which are much smaller than all of Xcode.
Once the developer tools are installed, you can easily install dependencies using MacPorts. The filesystem source is viable on macOS 10.7+ without any dependencies.
With clang (Apple’s compiler) you will need to set the compiler standard for Objective C:
If ./configure fails because the compiler doesn’t support C++11, you will need to install a C++ compiler. gcc5 has been tested:
sudo port install gcc5 export CC=gcc-mp-5 export CXX=g++-mp-5 ./configure
To install the dependencies:
sudo port -v install libgcrypt gnutls json-c
To use ffmpeg for audio (required on 10.6 or earlier; optional later):
sudo port -v install libao ffmpeg taglib
To create pianod from a tarball, using MacPorts for dependencies, you will also need these environment variables before invoking configure:
export CPPFLAGS=-I/opt/local/include export LDFLAGS=-L/opt/local/lib
The tarball build will install to
If launching as root, use ‘pianod -n pi’ to run pianod as the pi’s starter user.
To open audio devices, a process usually needs to belong to the
usermod --append --groups audio _username_
When launching as root (such as from init.d, systemd or /etc/rc.d files), specify the user to run as:
pianod -r _username_
Messages may vary slightly by system and compiler.
Mixing C++ Compilers
Linking between C++ code built with different compilers can cause woes. I encountered taglib corrupting the stack; build issues were confirmed via a simple test program (just read and get artist). If you run into troubles, rebuild the C++ dependencies yourself using the same C++11 compiler you are building pianod with.
Furthermore, mixing C++ standards creates linking issues. For example, with libraries compiled for Gnu++11 and pianod2 for C++11, they won’t link. I suppose this is preferable to generating a non-working executable, but it can be a nuisance to deal with. The solution is the same: rebuild the dependencies and pianod2 using the identical compiler and standards mode.
/usr/local/include/gcrypt.h:1401: warning: ‘gcry_ac_data_read_cb_t’ is deprecated
- Ignore. There are typically several of these, all from gcrypt.h with the prefix gcry_.
Rare Mac Troubles
pianod and all libraries must be built with the
same architecture. If the dependency libraries are installed but
mismatched, you may override the default with
CFLAGS="-arch x86_64" or
To use transport layer encryption, you must provide certificate
and key files. The script
contrib directory will create the necessary files,
the certificate issued by a bogus CA. The certificate is for the
current hostname, or another host specified as the first
Report bugs to firstname.lastname@example.org
Reporting a crash or hang
Providing useful and accurate information will help track down issues and get them fixed. If nobody reports things, they will stay broken; some bugs only show up on some operating systems or with certain hardware/software configurations. (Although these are written for pianod2, providing the details outlined here will be helpful to most open-source developers.)
First off, don’t rush to report problems; instead, study it and collect details. Vague and unclear reports may not get fixed. So, can you reproduce it? If so, what makes it happen? Does doing it always make it happen, or is it intermittent? Collect a stack dump if you can (see below).
When you’re ready, submit an e-mail to email@example.com with:
- Your notes on what causes it
- A copy of config.log from the pianod build directory (created when you run “./configure” before building pianod).
- Alternately, pianod version (
pianod -v) and build details, operating system, output of
uname -a, and kind of hardware you’re working on
- A diagnostic report or stack dump of the crash or hang
If you’re experiencing crashes, it would be helpful to capture a snapshot of what’s going on. Thankfully, there are tools to do this.
Capturing a Diagnostics on a Mac
On application crash, a Mac automatically captures and logs the
details. Look in
files will be named pianod_year_mo_da_number_hostname.crash. Attach
them to your report.
You can generate a diagnostic report for a stuck process with
kill -ABRT <pid>
If you can’t see the Library folder in your home folder, open
Go→Go to Folder and type in/cut-and-paste
the above folder name. Find the report in there and mail it in.
Building for debugging
If you don’t know how to do this, you may skip this step—but if
you compiled and installed your own software, then building a
debug-friendly variant is straightforward and makes troubleshooting
much easier. Please do it if you can. pianod’s configure script has
an –enable-debug option; simply
make again, and
install if you want to install it.
Capturing a Stack Dump
To capture a stack dump, use gdb, the GNU debugger.
For a hang, attach to an existing process:
ps x | grep pianod 50942 ?? S 8:50.40 /usr/local/bin/pianod gdb -p 50942
For crashes, start pianod from gdb:
gdb /usr/local/bin/pianod _add your normal pianod options here_ run
When pianod crashes, gdb will report this and give you a command prompt. (If you want to capture a hang this way, press control-C when pianod has hung.)
Now, in the gdb console, do the following: (For more on gdb, see the GDB Cheat sheet.)
info args info locals info variables info threads info signals thread apply all where full
Cut-and-paste from the gdb window to your bug report and mail it in.
As with all network server applications,
should be considered a security risk out of paranoia: there may be
undiscovered bugs or exploits in pianod or any of the libraries on
which it is built. To minimize risk should it be compromised,
pianod should be run as a unique, low- or
non-privileged user account.
User passwords are stored using OS-provided, one-way encryption with salt. They cannot be decrypted, although dictionary/brute-force attacks apply as they do to the underlying operating system.
Music service passwords for “remembered” sources, however, are stored in the user data file using a custom symetric encryption algorithm using a per-user key, and are easily decrypted. Users should use a unique password for any music password they register.
For these reasons, limiting access to the user data file (by
chmoding the directory, or running pianod with a 077
umask) is recommended.
The HTTP server does not create files. If a directory is
index.html is provided (or a
404 occurs); directory contents are not listed.
Requests to higher-level directories
are rejected, preventing download of arbitrary data for simple
However, the server follows but does not analyze symbolic
links, so a well-placed symbolic link within the client directory
myexploit -> /) could open a security hole
subsequently used to retrieve arbitrary data. Following a break in,
the client directory should be reviewed (or deleted and
reinstalled) to ensure no such holes have been created by the
Configuration files location
pianod stores several files in a configuration
directory, the configuration of which is set by:
- -d directory command-line option, with
- $XDG_CONFIG_HOME/pianod2 (if XDG_CONFIG_HOME is set)
- $HOME/.config/pianod2 (if HOME is set and running as root)
- $(sysconfdir)/pianod2 (if running as root). sysconfdir is set
at compile time by the configure script; a tarball install will use
/opt/local/etc, MacPorts uses
/etcis common when installing from a package manager.
./pianod2(if not running as root).
pianod2 reads its
startscript, executing the command therein as a
pianod administrator. The file uses the same syntax
and commands as the socket interface. A sample startscript is
provided in the
pianod also has a user data file,
passwd. If the file does not exist, a single user
admin) is created. This
user is persisted, so once you create your own administrator
account be sure to delete
Launching at boot or login
Unlike older UNIX daemons,
pianod does not use
on startup. Supplied sample configuration files expect
pianod to be installed in
if this is not right you will need to revise the files when
pianod is started as root, after establishing
the listener socket,
pianod drops root privileges and
takes on a user persona, by default the user ‘nobody’.
It also adopts the user’s groups. To allow data to be persisted,
the configuration directory is (re)assigned to this user. The user
can be selected via
-n root will
allow pianod to retain root privileges. Using
may be a useful troubleshooting tool, but running any network-based
service as root is risky.
-g option can be used to specify a
comma-separated list of groups instead of nobody’s groups. Some
platforms have a group
which users must belong to be able to open audio ports.
pianod must not be installed setuid. Using
a combination of -d and -n options, a malicious user could
arbitrarily reassign file ownership.
On OS X:
- Included in contrib is an example com.deviousfish.pianod.plist.
- When installing the file, be sure to review the file as there are some file paths and user names in it.
- To launch
pianodupon login of a particular user, install the file in that user’s Library/LaunchAgents directory.
- To launch
pianodat boot, place it in the system’s /Library/LaunchDaemons directory. Edit the file to enable the UserName key, setting it to run as your desired user.
On Linux with
- Included in contrib is pianod.service for systems using systemd(1).
- To launch
pianodat boot, place it in
/usr/local/lib/systemd/systemand put the startscript in
- To launch
pianodat login, install the file in the user’s
.config/systemddirectory [Need verification]. You will want to remove
-i /etc/pianod/startscriptfrom the
[Service]section of the file.
- After installing the file run “systemctl start pianod” to start the daemon and “systemctl enable pianod” to enable it to start on boot.
- The sample expects pianod to be installed in /usr/sbin; set your configure options or modify the start file as needed.
On systems using /etc/init.d scripts:
- Included in contrib is pianod.raspian.init.
- The script is for the Raspbian distribution but can be modified as needed.
- The sample expects pianod to be installed in /usr/sbin; set your configure options or modify the start file as needed.
For systems that use init without /etc/init.d, you’ll need
to edit the inittab file. Add this to
pd:23:respawn:su - username -c /usr/local/bin/pianod
On Windows, you are on your own.
See the pianod(1) manual page for the full list of command line options.