| Commit message (Collapse) | Author | Age |
| |
|
|
|
| |
Replace doxygen comments of structures and static functions in aft.c by
ordinary C comments.
|
| |\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
AFS socket cookie replacement
-----------------------------
A small but rather intrusive patch set which touches the guts of the afs
callback mechanism.
* t/socket-cookie:
afs: Avoid the void * argument of send_lls_callback_request().
Kill afs socket cookie and afs_client_list.
afs: Improve error handling of afs_signal_post_monitor().
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We now create a per-command socket pair in the command handler and use the
permanent server-afs socket to pass one end of the pair from the command
handler to the afs process.
With this approach only the command handlers can possibly talk to the
afs process, so we don't need to worry about malicious or bogus connections
arriving at the local socket.
Consequently, we may remove the socket cookie and employ blocking I/O for the
shared memory identifiers that are transferred through the per-command socket.
Connections are now dispatched in one go, obviating the need to keep track
of connected clients. So remove struct afs_client and the client list.
|
| |/
|
|
|
|
|
|
| |
Due to the missing condition, if the user runs touch or cpsi on an audio file
which is not the current file, the audio file selector replaces the current
status items by those of the file on which the touch/cpsi subcommand operated.
Gimme that brown bag.
|
| |\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Switch to SPDX licence identifiers
A single patch which replaces the first comment line of most .c and .h files
containing the copyright notice by standardized SPDX (Software/System Package
Data Exchange) nomenclature.
* t/spdx:
Switch to SPDX identifiers.
|
| | |
| |
| |
| |
| |
| |
| |
| | |
Generated with
sed -i 's|Copyright.*Andre Noll.*|SPDX-License-Identifier: GPL-2.0 */|g' *.c *.h
followed by manually tweaking the result a bit. No license change intended.
|
| |\ \
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
Provide --init as a replacement for com_init()
This change does not need a deprecation period because initialization is
only necessary for new instances.
* t/init:
afs: Simplify table open functions.
server: Replace the init subcommand by --init.
|
| | |/
| |
| |
| |
| |
| | |
With the init subcommand gone, it's now a fatal error if at least one table
cannot be opened. So remove the silly "table does not exist, but continue
so that the user can create it" dance we currently do.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
If the audio format info structure of an audio file changes, we have to
generate an AFSI_CHANGE event no matter whether or not the file is the
current file. For example, when the user runs touch --set-attribute to make a
non-current file admissible, the file must be added to the score table so that
it will eventually be streamed. Currently, we only generate the event if the
afsi of the current audio file was modified. Fortunately, this is easy to fix.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
This iterates over all audio files to check if the attribute to be removed
is still set in the on-disk afs_info structure of the audio file. If at
least one such audio file is detected, the rmatt subcommand aborts.
With this new behaviour, the existing loop in aft_event_handler() which
clears the corresponding bit from each on-disk afs_info can be removed. This
was the only event handler that looked at the bit number passed, so we may
as well pass NULL instead.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Currently code outside of score.c needs to deal with two types of osl table
rows: rows of the audio file table and rows of the score table. This foils
type safety because the row pointers to different tables have the same type.
We currently expose score rows to functions outside of score.c because the
code in aft.c loops over the score table, and the osl loop callback receives
a pointer to the current row as its first argument.
This commit implements the static call_callback() in score.c, used as the
osl callback, to avoid exposing the score row. The new function decodes the
cells of the row to obtain the aft row and the score. These two values are
then passed to the callback function passed to score_loop().
|
| | |
| |
| |
| |
| | |
This function never fails. The single condition under which it used to return
negative is never true, so assert() that this is the case.
|
| | | |
|
| | |
| |
| |
| |
| |
| | |
Return the bit number directly, avoiding the result pointer argument for
the bit number. Remove the pointless "one" variable in one of the callers,
the touch callback, while at it.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The public get_attribute_bitmap() is defined in attribute.c and called from
the ls callback to print an attribute string such as xx--x, indicating which
attribute bits are set/unset. This function should instead be part of aft.c
where the ls subcommand is implemented, so move it there and make it static.
The ls command needs to know the highest used attribute number to limit the
output width of the attribute string. This number is currently maintained in
a global variable of attribute.c. Provide the public attr_get_max_bitnum()
helper to make it available to aft.c.
It is easier to compute the value when it is needed than to maintain the value
in a global variable. This is not performance critical anyway, since the ls
command calls the function only once (rather than once per audio file listed).
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
Rather than looking up each bit number in the attribute table, we now loop
over all existing attributes and check whether the corresponding bit is on
in the given attribute bitmask. This should be more efficient.
Switch to para buffers and drop the delimiter argument since the only user,
the callback of the ls subcommand, passes a constant value.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Currently both the audio file table and the attribute table implement a
check function. The latter first computes the bitmask which corresponds
to the defined attributes, then passes the resulting 64-bit integer to
aft_check_attributes(), which loops over all rows. The loop callback
de-serializes the afs_info structure of the row and checks the attributes
of the row against the bitmask.
This patch removes the check function of the attribute table as
well as aft_check_attributes(). The replacement is the new public
attr_get_defined_mask() in attribute.c.
To make this work, the check function of the audio file table is modified
to call the new function, then iterate over all rows as before, passing the
mask to the existing loop callback. The loop callback is extended to perform
the same check that aft_check_attributes() did before.
This simplifies the code, and should perform better because we now de-serialize
the afs_info struct only once per audio file rather than twice.
As a result, the --attributes option of the check command has become unused.
So we deprecate this option.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Currently the ->load() selector method takes a char ** argument, and both
implementations allocate either an error message or an info string and return a
pointer to it through this argument.
There are four callers: Besides the ls and select callbacks, there is
afs_init() to load the initial mood or playlist and afs_signal_post_monitor(),
which reloads the current mood/playlist.
The two command handlers pass any error messages to the client, the other
two callers of ->load() call PARA_XXX_LOG to log errors. Only the select
callback produces output on stdout, and only if select was run with --verbose.
To improve in this error-prone approach we pass two arguments instead:
a para_buffer pointer for stdout and the afs callback argument pointer for
error messages. If the para_buffer pointer is NULL, no info string will be
allocated. If the callback argument pointer is NULL, errors will be logged
with PARA_ERROR_LOG().
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
We support "-" as the argument to the select subcommand as a shortcut for the
name of the previously loaded mood or playlist. However, ls --admissible=-
fails. This is inconsistent, so patch the ls subcommand to support this
as well.
Since the name of the previous mood or playlist is currently only known to
afs.c, we have to declare previous_mop in afs.h and make it non-static in
afs.c. Do the same with current_mop for consistency.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Currently mood.c and playlist.c contain similar public functions. For example,
there is mood_load() and playlist_load(), mood_loop() and playlist_loop().
Introduce struct selector_ops which contains methods such as ->load()
and loop(). We define two instances of the new structure, one for the mood
selector and one for the playlist selector. The structures can be constant,
but need to be public. The methods can be static.
The score table is now regarded as owned by the mood or playlist. It is no
longer listed in afs_tables[] and afs_table_operations can go away.
We don't need the global score_table variable anymore because all public
functions of score.c now take a pointer to the table to operate on. Similarly,
current_mood and current_playlist can be removed.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Only the events generated by functions outside of aft.c need to be handled
there. Self-generated events should be handled before the actual event is
raised so that the corresponding event handler can ignore the event.
This patch moves the code that deals with self-generated events out of
the aft event handler to just before the afs_event() is called. The afsi
change event is generated multiple times and the code is a bit longer,
so we introduce afsi_change() for that.
This removes a few lines more than it adds, and it gets us proper type
checking by avoiding the void * argument of the event handler.
|
| | |
| |
| |
| |
| | |
The event handlers only look at the aft row, so we may simply pass a pointer
to the row instead of a pointer to struct afsi_change_event_data.
|
| | |
| |
| |
| |
| | |
It contains only an 8 bit integer, so we may as well just pass a pointer to
uint8_t instead.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
Only the event handler of the audio file table uses the para_buffer to send
the "clearing bit" message on ATTRIBUTE_REMOVE events. It does so without
NULL-checking the para_buffer pointer first, which is dubious but not a bug
because the only source of ATTRIBUTE_REMOVE is the callback of the rmatt
command, which passes non-NULL. We can simply omit the message, and remove
the para_buffer argument from afs_event() and from all event handlers.
|
| | |
| |
| |
| |
| |
| | |
We don't need to check the current aft row because make_status_items() does
that for us. It also decodes the audio format handler information from the
row, so there is no point in doing this twice.
|
| |/
|
|
|
|
|
| |
This osl function fails only if the table pointer is NULL, which can never
happen here because the table was opened successfully. Add an assertion
to aft_open() which terminates the afs process if this impossible case
actually happens.
|
| |
|
|
|
|
| |
The "parser_friendly" parameter is used as a boolean, so don't declare it
as int. The function passes a reference to the bool via the callback method,
so the callback, afs_stat_callback(), needs to be adjusted as well.
|
| |\
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Remove com_setatt()
The setatt subcommand with its weird syntax was deprecated in 0.7.5 (2025-08)
in favor of touch --set-attribute and touch --unset-attribute. Good riddance!
* refs/heads/t/rm_setatt:
Remove the setatt server subcommand.
|
| | |
| |
| |
| |
| | |
The subcommand was deprecated in paraslash-0.7.5, when the touch subcommand
grew equivalent functionality.
|
| |/
|
|
| |
Both -l=c and -l=m are deprecated since paraslash-0.7.4, released on 2025-01-08.
|
| |
|
|
|
|
|
|
|
| |
This reverts commit da656fc87b1fe1de4f111223a46bbe007caa5941.
Looks like we do need this: If, for example, an image is renamed, the status
items need to reflect this, but the commit being reverted prevents that.
Fixes: da656fc87b1fe1de4f111223a46bbe007caa5941
|
| |
|
|
|
|
|
| |
The condition in aft.c which is removed by this commit can no longer be
true with the v0.7 database format. Hence afd->max_chunk_size always mirrors
afd->afhi.max_chunk_size, so we can remove the former and adjust the single
location in vss.c which still references it.
|
| |\
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
The series first drops the para_upgrade_db executable because it is no longer
needed. This removes the penultimate user of the sha1 infrastructure. The
remaining commits deal with the last user: the handshake between para_client
and para_server. Since paraslash-0.7.0, client and server employ sha256
by default, but fall back to sha1 in order to stay compatible to old 0.6.x
versions. After this series, server and client always employ sha256 as the
hash algorithm, breaking compatibility with 0.6.x clients. As a result,
the sha1 hash algorithm is no longer used anywhere, so the corresponding
infrastructure is no longer needed. This gets rid of a fair amount of code.
* refs/heads/t/rm_sha1:
Rename hash2 -> hash.
Remove sha1.
Remove para_upgrade_db.
aft: Compare the full hash, not just the first 20 bytes.
|
| | |
| |
| |
| |
| | |
Now that sha1 is no longer supported, the hash2 naming has become meaningless.
Rename it back to "hash".
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
In 0.7.0 the hash algorithm for the hash column of the audio file table
changed from the 20 byte sha1 to the 32 byte sha256. However, the audio file
selector kept calling hash_compare() as the comparator, which looks only at
the first 20 bytes of the buffers passed.
This omission is clearly a bug, but given that we still accept old clients
which only know about sha1, it's benign because the truncated sha256 should
not be worse than sha1. Fix the bug anyway.
Fixes: 126b950f1bd70d1e5c200bc4157bbbb2798fc838
|
| | |
| |
| |
| |
| | |
All seven implementations of ->get_file_info() ignore the fd argument.
The public compute_afhi() and the static get_file_info() don't need it either.
|
| | |
| |
| |
| |
| |
| |
| | |
Currently we initialize this pointer variable by creating a copy of the memory
mapped osl object on the heap, and leak this copy on exit. We may avoid the
copy since we may as well look up the path again in make_status_items(). This
is cheap because we already know the row of the audio file table at this point.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| | |
This function calls get_audio_file_path_of_row() although the path is already
known at this point. Moreover, since the function is called twice to produce
the human-readable and the parser-friendly status items, we perform identical
work in each call. We can easily avoid a system call by calling stat(2)
only once in the caller, The mtime string is also computed twice, so move
the computation into the caller as well.
|
| | |
| |
| |
| |
| | |
The users outside of error.h may as well call osl(), which leaves only
a single caller in error.h. Open-code the macro there and remove it.
|
| | |
| |
| |
| |
| |
| |
| |
| | |
make_status_items() accesses the audio format handler information via
status_item_ls_data.afhi, which was set when the current audio file was
loaded. However, the pointers of the ahfi structure might have become stale
if the server reloads the afs tables in between, for example when SIGHUP
was received. This may lead to a crash or worse.
|
| | |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
On errors that occur after status_item_ls_data->path has been initialized, we
return without setting ->path to NULL. This is bad because a subsequent event
could call make_status_items(), which then proceeds using the invalid path.
This commit adds a few labels to improve the error handling and to clean
up properly in all cases. A side effect of this change is that on certain
errors where we used to fail we now continue, trying the next best file as
long as there are entries left in the score table.
|
| | |
| |
| |
| | |
There is no reason to go into this much detail.
|
| | |
| |
| |
| |
| |
| |
| | |
If a file whose path does not match any known ending is attempted to be
added, we silently ignore the file even if --verbose is given. This happens
for example, if the audio format handler for the given file was not compiled
in. Make this case more obvious by sending a message if --verbose is given.
|
| | |
| |
| |
| |
| |
| |
| | |
Currently we allocate the hash pointer of the global status_item_ls_data
structure once at first use. We can avoid the allocation by having it point
to the global current_hash[]. This way it always contains an up-to-date value,
so we no longer need to re-lookup the hash in aft_close().
|
| | |
| |
| |
| |
| | |
The current status items are unaffected by any blob operations, so this code
is completely unnecessary.
|
| |\ \
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
A single patch which deprecates the setatt server subcommand. This subcommand
fails, for example, if the name of an audio file happens to end in '+' or
'-'. The replacement for setatt is the touch subcommand, which gained two
options to set or unset attributes.
* refs/heads/t/deprecate_setatt:
server: Deprecate setatt in favor of touch.
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
This adds --set-attribute and --unset-attribute to the touch subcommand,
re-implementing the features of the setatt command with a saner syntax.
We augment the change_atts_data structure using pre-computed values for
verbose and dry-run mode and pass a pointer to this structure rather than
the general callback arg pointer. The existing setatt subcommand neither
sets nor consults the two new booleans.
The touch completer of para_client is updated to complete the two new options,
executing the lsatt subcommand to get the attribute names. The manual and
the test suite also need minor adjustments.
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The aft event handler needs to know the bit number of the attribute which is
being removed in order to clear the bit in the afs info structure of each row
of the audio file table. The handler does not need to know the attribute's
name, though, and remove_attribute() already prints it, so remove this field
from the event data structure.
|
| | | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | | |
The playlist event handler handles afsi change events by moving the affected
entry to the end of the playlist. This is the right thing to do if the
event was triggered by virtual streaming system streaming a new file. It is
incorrect, however, if the event was triggered by a subcommand such as touch.
This commit introduces the new afs event type VSS_NEW_AUDIO_FILE to distinguish
between the two different use cases. The audio file table event handler
ignores the VSS_NEW_AUDIO_FILE event while the playlist event handler ignores
the AFSI_CHANGE event. The moods event handler treats both events equally,
Get rid of a pointless static one-liner function in playlist.c while at it.
|
| | |/
|/|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| | |
Each time a new audio file is opened for streaming, we update the numplayed
and lastplayed fields of its afs info entry of the audio file table, then
update the global afsi and ahfi structures, then trigger an AFSI_CHANGE event,
which calls all table event handlers. The event handlers receive as arguments
a pointer to the old afsi and a pointer to the already modified aft row.
The AFSI_CHANGE event handler of the audio file table gets called in the
situation described above, and also via the touch and cpsi subcommands,
because these also change the afsi info structure and therefore trigger
AFSI_CHANGE events as well. The handler checks whether the affected audio
file is the current audio file, and if it is, extracts the modified afsi
from the audio file table into the global afsi structure.
The problem is that in case of the above "next audio file" scenario, the
old afsi pointer points to the global afsi structure, which gets updated
by the aft event handler. Therefore the event handlers which happen to run
after the event handler of the audio file table see the already updated afsi
through the old_afsi pointer.
Since the audio file table happens to be the first table of the 7-element
afs_tables[] array iterated by afs_event(), all six other event handlers see
the incorrect afsi. However, only the moods event handler looks at the old afsi
to update the mean and quadratic variation of the lastplayed and numplayed
values of the afs statistics. Due to the bug described above, the old and
new lastplayed and numplayed values coincide, and therefore the statistics
update is a no-op. In practice, at least for moods with many admissible files,
the values will only be slightly off, so the bug is rather benign.
Fix this by renaming the on-stack new_afsi to old_afsi, adjusting
initializations accordingly, and passing a pointer to this instance instead.
|