Introduce afs_error(). The callbacks of some afs commands employ the normal ->pbpout para buffer to send an error message to the client on failure. These messages are therefore tagged with the OUTPUT sideband designator just as regular command output. The receiving client writes such messages to stdout, so applications which call para_client have no other way than parsing the output to guess whether it is normal command output or an error message. This commit improves on this by providing a public helper in afs.c to format and send an error message that is tagged with the ERROR sideband designator and thus gets written to stderr on the client side. All afs callbacks which currently use ->pbout for error messages are converted to call the new helper.
afs: Replace ->init of afs tables by table operations. This is simpler, avoids the run-time initialization, and allows us to mark the instances of the operations structures constant. Improve the documentation a bit while at it.
attribute.c: Remove struct addatt_event_data(). It is passed to afs_event() to tell the table event handlers the name and bit number of the newly added attribute. However, the only table which does not ignore attribute add events is the mood table, and this just reloads the current mood without even looking at the information passed.
attribute.c: De-doxify static functions. Because static functions don't need doxygen comments. The existing comments for attribute_close() and attribute_open() did not contain useful information, so remove these,
com_addatt(): Fix memory leak. We miss to free the lopsub parse result on exit. Found by valgrind.
Shorten copyright notice. The GPLv2 line does not add any additional information, so drop it. This leaves a single line of legalese text for most files, which is about the amount of screen real estate it deserves. This patch was created with the following script (plus some manual fixups): awk '{ if (NR <= 5) { gs = gensub(/.*Copyright.* ([0-9]+).*Andre Noll.*/, "\\1", "g") if (gs != $0) year = gs next } if (NR == 6 && year != "") printf("/* Copyright (C) %s Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */\n", year) print }'
doxygen: Add \ref to references. This way doxygen issues a warning if the file/function/structure no longer exists and a stale reference remains.
server: Convert com_addatt() to lopsub. Another simple command without options which is easy to convert. The only thing worth noting is that we now fail the command early if more than 64 arguments are given when previously we only checked that at least one argument is given.
server: Convert com_rmatt() to lopsub. No change to the action handler, remove_attribute(), necessary.
server: Convert com_mvatt() to lopsub. We need to cast the obj->data pointer to a non-constant type because the osl library functions expect void *, which results in a warning without the cast.
server: Convert com_lsatt() to lopsub. This is the first afs subcommand which needs to pass a pattern list to its callback. The new send_lls_callback_request() provides this functionality. It serializes the parse result into a buffer and passes this buffer to the callback. Since there are non-lopsub commands which also pass a pattern list, action_if_pattern_matches() is patched to receive the pattern list either from the serialized parse result or in the old way via pmd->data. To achieve this, a parse result pointer is added to struct pattern_match_data. If this pointer is not NULL, we are dealing with a subcommand that has been converted. Since the ls subcommand has not been converted yet, lopsub will regard "ls" as a uniqe abbreviation of the lsatt command, which breaks t0004. To work around this, we deactivate prefix matching by only accepting exact matches in run_command(). This workaround can be removed after com_ls() has been converted.
server: Convert non-afs commands to lopsub. Currently the server commands are divided into two group: those commands which are handled by the server process and those which communicate with the afs process. This commit converts the commands of the former group and the corresponding completers for para_client to the lopsub suite format while the afs commands will be converted in subsequent commits. After this change para_server needs to be linked with -llopsub. To this aim the options and help texts of of the server commands are transferred from server.cmd to the new server_cmd.suite.m4, enabling long-style options in the progress. Moreover, an introduction is added at the beginning of the list of server commands which describes how server commands are executed. Command permissions are now handled by making use of the aux_info feature of lopsub. To keep those commands working which do not have any permission bit set, we need to add a new identifier NO_PERMISSION_REQUIRED to enum server_command_permissions of user_list.h. The value of this identifier is zero of course. Naturally the bulk of the change takes place in command.c where all server commands are implemented. The command handlers are modified to take a pointer to a struct lls_parse result as an additional argument. A new helper, send_errctx(), is introduced to avoid code duplication. Since command.h now refers to a lopsub parse result, all files which include command.h, including those which implement only afs commands, need to include the system header lopsub.h. To keep afs commands working, some compatibility code in run_command() is added. This will go away after all commands have been converted. A couple of macros in command.h ease the handling of the long symbolic constants exposed by the generated lopsub header file. Although only the non-afs commands are converted, the change allows for a couple of cleanups: * The E_BAD_COMMAND error code is no longer needed and has been removed. * cmd_perms_itohuman() has become unused and is removed. * The server_cmds[] array is empty and can be removed, along with the loop in send_list_of_commands() which iterated over the array. The patch also adjusts tests t0004 and t0005 since the help output format changed slightly, breaking the expectations of these tests.
attribute: Avoid shifting 32 bit integers. att_logical_or() is called from com_check() to set up a bitmask where a bit is set if and only if it corresponds to an existing attribute. Doing "1 << i" is wrong in this context because the constant "1" is a (signed) 32 bit quantity and we need to be able to shift by more than 31 bits for the attribute mask. Fix this by using an uint64_t variable instead.
Merge branch 'refs/heads/t/command_handler_cleanups' Cooking for about two months. * refs/heads/t/command_handler_cleanups: (39 commits) com_addatt(): Return negative on errors com_rm(): In force mode, don't complain if no paths matched. aft: Unify handling of hash and path duplicates. afs: Provide pbout para_buffer for each callback. afs: Make afs callbacks more flexible. afs: Rename callback_function to afs_callback. com_check(): Add attribute checking. Let afs_event() return int. playlist_check_callback(): Return negative on errors mood_check_callback(): Return negative on errors com_mvblob(): Return negative on errors com_addblob(): Return negative on errors com_rmblob(): Return negative on errors, cleanup com_catblob(): Return negative on errors com_lsblob(): Return negative on errors rmatt: Cleanup callback. com_rmatt(): Return negative on errors com_mvatt(): Return negative on errors com_lsatt(): Return negative on errors com_init(): Return negative on errors ...
attribute.c: Remove pointless condition in attribute_open(). ret is known to be negative at this point.
com_addatt(): Return negative on errors
Merge branch 'maint' * maint: lsatt: Fix sort order. server: Avoid segfault in com_sender().
lsatt: Fix sort order. The -i option had the opposite effect of what the documentation says. That is, lsatt -i sorted the attribute list by name while the default was to sort by id. This patch reverts the logic in com_lsatt() to let the implementation match the documentation.
afs: Provide pbout para_buffer for each callback. Most afs callbacks define a para_buffer to pass output from the callback to the command handler. Hence the code which defines and initializes the para_buffer is duplicated many times. This commit gets rid of the duplication by moving the initialization to the common call_callback(). The para_buffer becomes part of struct afs_callback_arg, a pointer to which is passed to every callback. The buffer is also flushed and freed in call_callback() so that the callbacks don't need to care about it any more. This also allows to make flush_and_free_pb() static since only a single caller in afs.c remains. This change simplifies the callbacks considerably. The callbacks of the rm, setatt, lsatt, lsblob and touch commands don't even need their own "action_data" structure any more since it was only necessary to pass the para_buffer to the ->action method.
afs: Make afs callbacks more flexible. Currently we pass the information for callbacks (an int and a pointer to an osl_object) as separate arguments. If additional information must be passed to some callbacks, every callback must be modified to match the new prototype, even those which won't use the new argument. This commit introduces struct afs_callback_arg which contains the two callback arguments and changes all callbacks to receive a pointer to such a structure. This is an equivalent transformation with no visible change in semantics. With this commit in place it is easy to provide additional information by simply extending struct afs_callback as appropriate.