Andre Noll [Fri, 28 Jul 2017 21:13:52 +0000 (23:13 +0200)]
Improve documentation of signal_init_or_die().
Prefix the reference to para_install_sighandler() with \ref to make
sure doxygen warns if the reference becomes stale, and fix the man
section of exit(): it is not a system call (but _exit() is).
Andre Noll [Sun, 30 Jul 2017 21:11:38 +0000 (23:11 +0200)]
stdin/stdout: Only set nonblock flags for non-tty fds.
Although the ->post_select methods of all paraslash executables perform
I/O only when select(2) reports that the file descriptor is ready,
we set the O_NONBLOCK flag for all monitored fds. This is considered
good practice because, in general, it might happen that a subsequent
read(2) call blocks even if select(2) indicates that the fd is ready
for reading. For example, an fd corresponding to a TCP socket might
be flagged as ready for reading if a network packet with incorrect
checksum has arrived, but a subsequent read(2) blocks until the packet
has been retransmitted.
However, stdin and stdout often correspond to a terminal device where
the above scenario won't happen. Moreover, for terminals it's essential
to reset the O_NONBLOCK flag to the old value on exit because the
shell refers to the same file description and thus shares the file
status flags, including O_NONBLOCK. Many terminal applications, for
example dialog(1), expect stdout to be set to blocking mode and fail
in arcane ways if O_NONBLOCK is set.
When the stdin and stdout tasks are about to exit, they reset the
file status flags back to the original values. However if "para_client
stat" is killed with SIGINT, SIGTERM or SIGKILL, or put to sleep with
SIGSTOP, the O_NONBLOCK flag remains set because para_client does not
handle signals at all. para_recv, para_filter and para_write suffer
from the same issue. Adding signal handling to these programs would
not help in the SIGSTOP case because this signal can not be caught.
This patch modifies stdin.c and stdout.c to no longer set O_NONBLOCK
for fd 0 and fd 1 if these fds are associated with a terminal
device. This is much easier and should do the job as well.
Andre Noll [Wed, 26 Jul 2017 18:45:27 +0000 (20:45 +0200)]
udp sender: Send EOF package only once.
We already have the per target ->sent_fec_eof flag, but we only set it
after the EOF packet was sent *successfully*. It's pointless to send
the packet more than once, so this patch modifies udp_close_target() to
set the flag regardless of whether the write(2) call succeeded.
Andre Noll [Mon, 24 Jul 2017 22:18:50 +0000 (00:18 +0200)]
server: Fix segfault in com_sender().
Commit 1709cc8f (server: Convert non-afs commands to lopsub) from
one year ago dropped the terminating NULL pointer from the array
of sender commands, presumably because the array size is declared
as the NUM_SENDER_CMDS enum constant, and this constant can be used
to iterate over all sender subcommands.
However, the loop in check_sender_args() of command.c does not
terminate the loop after NUM_SENDER_CMDS elements but only when it
encounters a NULL pointer. Hence, without the terminating NULL, the
code reads beyond the end of the array. The resulting invalid memory
access causes the command handler process to segfault.
Fix this by changing the termination condition of the loop to check
the loop variable against NUM_SENDER_CMDS.
Andre Noll [Mon, 24 Jul 2017 20:41:40 +0000 (22:41 +0200)]
mood.c: Fix documentation of int_sqrt().
As pointed out by Peter Zijlstra on lkml, int_sqrt() is not
rough nor any approximation; it calculates the exact value of
floor(sqrt()). Document this.
Andre Noll [Mon, 24 Jul 2017 20:10:42 +0000 (22:10 +0200)]
mood: Speed up int_sqrt().
Following a recent discussion on lkml, the choice of the initial
value for the square root is sub-optimal. The change introduced
in this commit was proposed by Peter Zijlstra who also measured a
significant speed improvement for both the hot and the cold cache case.
The speed improvements for the hot-cache case were confirmed on a
32 bit system by running a simple test program which calculates the
square root of 10000000 random numbers. With the new initial value,
the running time went down by 23%. This matters because when a new
mood is loaded, int_sqrt() is called four times per admissible file.
The new initial value is computed in terms of the position of the
most significant bit set in the given argument to int_sqrt(). While
ffs(3) (find first set bit) is in POSIX.1‐2008, there is no fls(3)
(find last set bit), so we have to introduce our own implementation.
We chose an open-coded version because this turned out to be faster
than reversing the bits and calling ffs(3).
Andre Noll [Mon, 24 Jul 2017 20:29:01 +0000 (22:29 +0200)]
mood: Add notice about int_sqrt().
While the algorithm probably predates Linux, the implementation was
copied from the Linux source tree in 2007. The commit which introduced
the function back then (f6f50d03, "Merge the new afs code.") should
have mentioned this.
De-doxify the function as it is static and hence not part of the html
generated by doxygen.
Andre Noll [Mon, 24 Jul 2017 15:26:44 +0000 (17:26 +0200)]
vss: Avoid use after free in vss_send().
In vss_send() we increment the current slice number for the fec
client after fc->send_fec() has sent a slice. This results in a use
after free in case of a write error because ->send_fec() frees the
fec client structure on write errors. Valgrind complains about this
with the splat below.
To avoid this, the fc pointer must not be dereferenced after
->send_fec() has been called. This patch increases the current slice
number *before* the call to ->send_fec(). This works because the fec
clients do not care about this number.
The bug was introduced eight years ago in commit 625c5cd (Add forward
error correction code to the udp sender/receiver).
==8615== Invalid read of size 1
==8615== at 0x805022B: vss_send (vss.c:1051)
==8615== by 0x805022B: vss_post_select (vss.c:1168)
==8615== by 0x8061DC7: call_post_select (sched.c:84)
==8615== by 0x8061DC7: sched_post_select (sched.c:110)
==8615== by 0x8061DC7: schedule (sched.c:163)
==8615== by 0x804CBFD: main (server.c:607)
==8615== Address 0x4670168 is 80 bytes inside a block of size 116 free'd
==8615== at 0x402D221: free (vg_replace_malloc.c:530)
==8615== by 0x8062D7C: udp_delete_target (udp_send.c:80)
==8615== by 0x80630DC: udp_send_fec (udp_send.c:305)
==8615== by 0x805022A: vss_send (vss.c:1049)
==8615== by 0x805022A: vss_post_select (vss.c:1168)
==8615== by 0x8061DC7: call_post_select (sched.c:84)
==8615== by 0x8061DC7: sched_post_select (sched.c:110)
==8615== by 0x8061DC7: schedule (sched.c:163)
==8615== by 0x804CBFD: main (server.c:607)
==8615== Block was alloc'd at
==8615== at 0x402C1F0: malloc (vg_replace_malloc.c:299)
==8615== by 0x8052D7E: para_malloc (string.c:67)
==8615== by 0x8052FBD: para_calloc (string.c:90)
==8615== by 0x804F48F: vss_add_fec_client (vss.c:686)
==8615== by 0x8063433: udp_com_add (udp_send.c:342)
==8615== by 0x8063688: udp_init_target_list (udp_send.c:395)
==8615== by 0x806371D: udp_send_init (udp_send.c:442)
==8615== by 0x805062A: init_vss_task (vss.c:1195)
==8615== by 0x804CA57: server_init (server.c:537)
==8615== by 0x804CA57: main (server.c:605)
Andre Noll [Mon, 17 Jul 2017 21:07:06 +0000 (23:07 +0200)]
opus_afh: Use custom header API to strip comment packet.
Currently we define the header of an ogg/opus file as the first two ogg
pages. This is problematic for two reasons: (a) the metadata packet
(ogg packet #2) may be arbitrary large and should not be sent over
the network as it is not needed for decoding the audio stream, and (b)
the second ogg page may contain, in addition to the metadata packet,
opus encoded audio packets which should not be part of the header.
This patch employs the recently added custom header API to avoid both
problems in the same way the ogg/vorbis audio format handler does:
we create a custom header which contains the unmodified ID header
packet and a dummy metadata packet.
Andre Noll [Mon, 17 Jul 2017 23:02:50 +0000 (01:02 +0200)]
ogg: Abstract out custom header code.
The ogg/vorbis audio format handler employs the callback mechanism of
oac_get_file_info() to replace the metadata packet of an ogg/vorbis
stream by a fixed sized dummy packet. The same approach should also be
used for the ogg/opus audio format handler because ogg/opus metadata
can be arbitrary large too.
As a preparation for modifying the ogg/opus audio format
handler to skip the metadata header in this way, this commit
makes the infrastructure available to all audio format handlers
which employ the ogg container format by providing a public
interface in ogg_afh_common.c. The central data structure is struct
oac_custom_header, which replaces the former vorbis_get_header_data
structure. The layout of the new structure is only known to
ogg_afh_common.c. Users of this API need to call the accessor functions
declared in ogg_afh_common.h.
Only the ogg/vorbis audio format handler is converted to the new API.
A subsequent patch will make the ogg/opus audio format handler the
second user.
Andre Noll [Fri, 21 Jul 2017 17:45:31 +0000 (19:45 +0200)]
Merge branch 'refs/heads/t/doxygen'
This series contains an update of Doxyfile to a newer doxygen version
and an overhaul of the source code documentation. Several stale
references have been fixed. Other parts of the documentation have
been improved.
Cooking for almost a month.
* refs/heads/t/doxygen:
aft.c: Trivial spelling/whitespace fixes.
afh: Expand documentation of init function declarations.
filter: Remove duplicate documentation of filter_get().
doxygen: Improve documentation of struct receiver.
doxygen: Add \ref to references.
Improve documentation of mm.c and mm.h.
doxygen: Don't refer to Black Hats Manual.
doxygen: Don't refer to libosl functions.
doxygen: Trivial cleanups.
doxygen: Remove some stale doxygen references.
recv: Explain user data mechanism.
Update to doxygen-1.8.11.
The merge resulted in a few conflicts which were easy to resolve.
Andre Noll [Fri, 14 Jul 2017 15:11:32 +0000 (17:11 +0200)]
Define status items in para.h.
The only reason the status item enum and string array are defined in
configure.ac is that upper case identifiers and lower case strings
are not easy to do in cpp as it lacks toupper().
However, configure.ac is not the right place for defining C language
constructs as the configure script should only check for installed
packages.
This commit moves the definition of the status item enum and array to
para.h and modifies all users to use lower case for the item names.
This was automated with a script which essentially did
upper=${i^^}
sed -i "s/\<SI_$upper/SI_$i/g" $files
for each status item $i. Care has been taken to leave the order of
the status items unchanged. This is important because the item numbers
must be considered part of the API between server and client.
Andre Noll [Tue, 11 Jul 2017 17:33:31 +0000 (19:33 +0200)]
aft.c: Improve documentation of get_afhi_of_row().
It is not obvious that the function initializes the afh_info structure
so that its members point to memory-mapped data. This comment adds
some clarifying comments.
Andre Noll [Thu, 6 Jul 2017 18:46:29 +0000 (20:46 +0200)]
mood.c: Rename compute_mood_score().
The main purpose of this function is to determine whether the
audio file is admissible with respect to the given mood. So
row_is_admissible() is more to the point.
Andre Noll [Sun, 16 Jul 2017 14:21:07 +0000 (16:21 +0200)]
server: Avoid NULL pointer dereference in make_status_items().
The previous patch (Update status items on blob events) modified the
aft event handler to call make_status_items() on certain blob events
because the event could have rendered the current status information
stale.
However, if no audio file is open at the time the event occurs,
make_status_items() triggers a segfault because the ->path and ->hash
members of status_item_ls_data are NULL in this case.
This patch avoids the problem by returning early from
make_status_items() if ->path is NULL.
Andre Noll [Fri, 14 Jul 2017 13:39:28 +0000 (15:39 +0200)]
manual: libosl is optional.
Even without libosl, the build succeeds (only para_server won't be
built). Hence libosl should be listed as optional software. This
commit moves the item out of the list of mandatory packages.
Andre Noll [Sat, 8 Jul 2017 16:53:11 +0000 (18:53 +0200)]
build: Run lopsubgen with absolute path.
The configure script detects the location of the lopsubgen executable,
but we never use this information and rely on the shell to find the
executable in $PATH when the recipes in m4/lls/makefile are run.
This should not matter much, but it is inconsistent to how we deal
with m4. Moreover, using the LOPSUBGEN autoconf variable in the
recipes allows the user to override the path at build time.
Andre Noll [Sat, 8 Jul 2017 16:36:03 +0000 (18:36 +0200)]
build: Fix check for lopsub.
If the lopsub library is not installed, HAVE_LOPSUB should be set to
"no". The current code in configure.ac gets this wrong, causing the
configure script to succeed even if the library is not installed.
Andre Noll [Sat, 8 Jul 2017 16:43:00 +0000 (18:43 +0200)]
build: Improve lopsub error diagnostics.
The configure script checks for the lopsubgen executable, the lopsub.h
header file and the liblopsub.a library. If the executable is not
found, we print a short error while a long error message with download
instructions is shown if the header file or the library is missing.
In the common failure case none of the three files is installed,
in which case we print the short message because the check for the
executable comes first. This is unfortunate.
This commit moves the check for the executable to the lopsub section
of configure.ac and prints the long error message if any of the three
files is missing.
Andre Noll [Fri, 14 Jul 2017 12:50:43 +0000 (14:50 +0200)]
Merge branch 'refs/heads/t/manual'
A couple of patches which merge the contents of the overview.pdf file
into the user manual. After this, the documentation no longer depends
on dia.
Cooking for six weeks.
* refs/heads/t/manual:
manual: Expand description of para_play.
manual: Omit level 3 headers from table of contents.
manual: Combine overview.pdf and the user manual.
manual: Remove text about permissions of /var/paraslash.
manual: Correct format of para_client help output.
manual: Add lopsub installation instructions to quick start.
Andre Noll [Thu, 13 Jul 2017 15:21:13 +0000 (17:21 +0200)]
Merge branch 'maint'
A single important fix for the error subsystem. The merge conflicted
because master removed the E_AAC_AFH_INIT error code while maint
still has it. The conflict was trivial to resolve.
* refs/heads/maint:
Let error codes start out at index 1.
Andre Noll [Sat, 8 Jul 2017 20:55:11 +0000 (22:55 +0200)]
Let error codes start out at index 1.
When the error code facility was simplified one year ago in commit a775408 (Simplify the error subsystem, get rid of error2.[ch]) we
introduced a simple enum for all error codes, but missed the fact
that this approach assigns the first error code the value zero.
Hence, when the AAC decoder returns this error code, it will not be
recognized as an error because we generally check for negative return
values only.
This patch introduces an unused dummy error code so that the real
error codes start at index 1.
Andre Noll [Wed, 14 Jun 2017 17:24:45 +0000 (19:24 +0200)]
wma: Remove _XOPEN_SOURCE define from wmadec_filter.c.
It has been there since day one of the wma decoder with no indication
why it is needed. The code compiles fine without it on all supported
platforms, so get rid of it.
Andre Noll [Sun, 11 Jun 2017 14:10:40 +0000 (16:10 +0200)]
wma: Drop unused argument from wma_decode_superframe().
The function depends on the caller not passing a smaller value than
the packet size - WMA_FRAME_SKIP, and only uses this many input
bytes anyway. So we may get rid of the input size argument.
Andre Noll [Sun, 11 Jun 2017 13:59:17 +0000 (15:59 +0200)]
wma: Remove pointless/incorrect sanity checks.
In wma_decode_superframe() we check the size of the input buffer twice.
Both checks are redundant because the input queue size of the wmadec
filter node already makes sure we never pass a smaller value. The
second check is in fact wrong, because pwd->ahi.packet_size -
WMA_FRAME_SKIP would be the correct limit to check.
Andre Noll [Tue, 6 Jun 2017 07:29:37 +0000 (09:29 +0200)]
wma: Simplify get_vlc().
The "bits" argument of the function is implicitly given by the vlc
structure and may thus be omitted from the call. For this to work we
must pass a pointer to struct vlc instead of only the table, which
further simplifies wmadec_filter.c.
Andre Noll [Mon, 5 Jun 2017 14:52:37 +0000 (16:52 +0200)]
wma: Make bitstream API more robust.
The ->buffer_end field of struct getbit_context is set but never
used. In fact, we never check bounds and happily read beyond the
supplied data buffer.
Fix this by replacing the field by ->num_bits, an integer which
is initialized in init_get_bits() to the number of bits available.
All functions which read the bitstream are modified to check bounds.
Andre Noll [Tue, 13 Jun 2017 19:48:18 +0000 (21:48 +0200)]
filter: Remove duplicate documentation of filter_get().
This public function is documented both in filter.h and in
filter_common.c. Get rid of the comment in the header file as this
is incomplete and causes a doxygen warning.
Andre Noll [Tue, 30 May 2017 19:11:09 +0000 (21:11 +0200)]
doxygen: Improve documentation of struct receiver.
The documentation still referred to the former gengetopt related
->conf pointer and also had some language and punctuation issues. The
new text should fix this, and is more to the point.
Andre Noll [Tue, 16 May 2017 21:09:33 +0000 (23:09 +0200)]
doxygen: Remove some stale doxygen references.
When we switched to lopsub, the callback request functions became
unused and were removed. At the same time, all command handlers were
made static, so they are no longer part of the doxygen documentation
and we shouldn't refer to them any more.
Also struct slot_info and the server_uptime variable have been made
private to their respective files audiod and time.c. Tthe latter was
in fact replaced by a timeval struct long ago.
The http and udp receivers don't have an init function any more, and
get_chunk_table_of_row() was removed ten years ago in commit 54a480ae.
Most references of the source code documentation will be annotated
with \ref in a subsequent commit to avoid this kind of documentation
bug in the future.
Andre Noll [Tue, 16 May 2017 21:16:44 +0000 (23:16 +0200)]
recv: Explain user data mechanism.
This is not obvious, so it deserves a comment in recv_init(). The
patch also adds a reference to each of the four instances of struct
receiver, reducing the number of doxygen warnings when EXTRACT_ALL
is set to NO in Doxyfile.
Andre Noll [Mon, 17 Apr 2017 19:13:59 +0000 (21:13 +0200)]
Update status items on blob events.
If the image or the lyrics blob for the current audio file changes,
e.g. because the user executed the mvimg command, para_gui still
reports the old value because blob events don't trigger a status item
update.
This patch teaches aft_event_handler() to honor such events. We keep
it simple and update the items on every add/remove/rename event.
Andre Noll [Sun, 11 Jun 2017 10:13:22 +0000 (12:13 +0200)]
net.c: Silence clang warning.
clang-3.8.0 on FreeBSD complains about a recent change to net.c:
net.c:606:33: warning: missing field 'ss_family' initializer [-Wmissing-field-initializers]
struct sockaddr_storage ss = {0};
^
This line was introduced in commit 63128eea (net: Always initialize
struct sockaddr_storage) to avoid a warning from the static analyzer
of clang. Setting .ss_family initializes all struct members, which
makes both the analyzer and the compiler happy again.
Andre Noll [Tue, 13 Jun 2017 20:33:26 +0000 (22:33 +0200)]
filter: Handle bad filter numbers gracefully.
This modifies filter_get() to return NULL if an invalid filter number
is given, rather than aborting the process. This way applications
can loop over all filters without having to include filter_cmd.lsg.h.
filter_name(), which also receives a filter number, has no such
sanity check and could possibly access uninitialized memory if an
invalid argument was passed. This commit adds the check and makes the
function return NULL in this case, just like filter_get(). Moreover,
the function lacked documentation, so let's add it now.
Andre Noll [Tue, 13 Jun 2017 20:09:01 +0000 (22:09 +0200)]
audiod: Fix off-by-one bug in init_default_filters().
Filter numbers are one-based because zero is the number of the
(non-existing) supercommand of the filter_cmd suite. The loop in
init_default_filters() gets this wrong.
This bites only if no filter is given for at least one audio format.
Fortunately, the bug was easy to find because it triggers an assertion
in filter_get() which checks that the given number is at least one.
Andre Noll [Tue, 16 May 2017 20:21:12 +0000 (22:21 +0200)]
recv_common.c: Fix doxygen warning in recv_init().
In the doxygen comment of this function, one argument name was prefixed
with a backslash by mistake. Old doxygen versions did not complain
about this, but doxygen-1.8.11 does:
warning: unexpected token in comment block while parsing the argument of command param
Andre Noll [Mon, 1 May 2017 16:28:52 +0000 (18:28 +0200)]
manual: Expand description of para_play.
The text did not contain any characteristic features. Let's at least
mention that all audio formats are supported and that the command
line interface was designed to not suck.
Andre Noll [Sat, 29 Apr 2017 19:51:49 +0000 (21:51 +0200)]
manual: Omit level 3 headers from table of contents.
The table of contents was rather large because it contained too much
detail. This commit converts all level 3 headings to inline html which
has no visible effect except that the headings no longer appear in
the table of contents.
Andre Noll [Sat, 29 Apr 2017 02:33:17 +0000 (04:33 +0200)]
manual: Combine overview.pdf and the user manual.
The figures of the overview.pdf file look rather odd although they
used to look better when they were created four years ago. Apparently,
the dia command line tool which creates the pdf from the .dia source
file has changed and now messes up the lines which connect the parts
of the figure.
This commit re-implements four out of the five figures of the overview
file as ascii art in manual.md, removes overview.dia, and modifies
the documentation web page to no longer refer to the dia version.
The text of the overview file has been merged with the manual and
got improved a bit.
Andre Noll [Tue, 16 May 2017 20:08:19 +0000 (22:08 +0200)]
doxygen: Avoid segfault.
After an upgrade to Ubuntu-16.04, the new doxygen version 1.8.11
started to segfault. It turned out that this can be circumvented
by disabling USE_HTAGS so that doxygen will use its built-in source
browser instead of the htags tool of GNU global.
However, the html which is generated by the built-in source browser
the source code is unreadable because leading tab characters are not
shown, so indentation is messed up.
This patch deactivates the source browser for now, getting rid of
all source code in the generated output.
Andre Noll [Sat, 6 May 2017 15:40:38 +0000 (17:40 +0200)]
client: Silence a gcc-7.1,0 warning.
This version of gcc complains because a case statement in
client_pre_select() may fall through. The fallthrough is intentional,
however, and this is annotated with a comment. gcc-7 scans the comments
in a switch statement and suppresses the warning if it recognizes
a comment which says that fallthrough is intended. But for this to
happen, we must spell it correctly, and without whitespace.
After this commit, gcc-7 compiles the tree with no warnings.
Andre Noll [Sat, 29 Apr 2017 14:54:03 +0000 (16:54 +0200)]
Remove unused error code MPI_PRINT.
This had been removed already in commit eab41e87 (gcrypt: Remove
open-coded OAEP padding) but it was brought back by mistake in commit 9264932e (Merge branch 'refs/heads/t/dynamic_chunks').
Andre Noll [Thu, 27 Apr 2017 18:39:32 +0000 (20:39 +0200)]
Merge branch 'refs/heads/t/lopsub'
The bulk of the changes in this release is the conversion of all
command line parsers from gengetopt to lopsub.
The series also contains a few cleanups that have become possible
due to the switch from gengetopt to lopsub.
The patches towards the end of the series rename para_fade to
para_mixer.
Naturally, the merge conflicted rather heavily against the other
topic branches that have been merged since the lopsub branch was
started. Conflicting files:
The resolutions for these conflicts were recorded with git rerere
and have been tested for quite some time.
Cooking for three weeks.
* refs/heads/t/lopsub: (74 commits)
audioc: Avoid double free in audioc_i9e_line_handler().
audiod: Avoid uninitialized memory access.
Simplify mixer setup.
mixer: Implement non-linear time scale for fading.
mixer: Allow arbitrary relative time for sleep subcommand.
Convert para_fade to subcommands, rename it to para_mixer.
build: Create .dep files only during compilation.
build: Simplify definition of $m4_lls_deps.
build: Rename command list variables.
build: Combine $(CFLAGS) and $(STRICT_CFLAGS).
build: Let .d files depend only on .c.
build: Don't create phony targets for dependencies.
build: Remove duplicate dependency.
build: Remove cmdline_dir and friends.
build: Remove some unused variables from Makefile.real.
build: Remove m4/gengetopt.
Remove gengetopt and help2man checks from configure.ac.
Remove man_util.bash.
Remove ggo.c and ggo.h.
manual: Do not mention gengetopt and help2man any more.
...